<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - lld sets LMA to VMA for aarch64elf although previous section uses "AT" keyword"
href="https://bugs.llvm.org/show_bug.cgi?id=45313">45313</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>lld sets LMA to VMA for aarch64elf although previous section uses "AT" keyword
</td>
</tr>
<tr>
<th>Product</th>
<td>lld
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>ELF
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>alex.bereza@huawei.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org, smithp352@googlemail.com
</td>
</tr></table>
<p>
<div>
<pre>Hello,
I believe to have found a problem with LLD 11.0.0
(<a href="https://github.com/llvm/llvm-project.git">https://github.com/llvm/llvm-project.git</a>
73cea83a6f5ab521edf3cccfc603534776d691ec) built from upstream. LLD seems to not
determine VMA AND LMA correctly in some cases. I compared the behavior with LLD
9.0.0 and GNU ld, which both don't seem to have the problem that I describe
next.
When using a custom linker script, the following rules should be used to
determine VMA and LMA according to GNU ld manual:
>From GNU ld manual section 3.6.8.2 Output Section LMA:
<span class="quote">> If neither AT nor AT> is specified for an allocatable section, the linker will use the following
> heuristic to determine the load address:
> • If the section has a specific VMA address, then this is used as the LMA address as
> well.
> • If the section is not allocatable then its LMA is set to its VMA.
> • Otherwise if a memory region can be found that is compatible with the current section,
> and this region contains at least one section, then the LMA is set so the difference
> between the VMA and LMA is the same as the difference between the VMA and LMA
> of the last section in the located region.
> • If no memory regions have been declared then a default region that covers the entire
> address space is used in the previous step
> • If no suitable region could be found, or there was no previous section then the LMA is
> set equal to the VMA.</span >
It seems that these rules are not correctly applied in the following minimal
example:
test.c:
```c
int data = 1;
char *rodata = "rodata";
int bss;
void test(void) {
volatile int i = 0;
i++;
}
```
linkerscript.ld:
```
ENTRY(test)
SECTIONS {
. = 0x40080000;
start = .;
.text (0xffff000000000000) : AT (start) {
*(.text)
}
.data : { *(.data*) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata*) }
}
```
Compile using the following command, clang or GCC, doesn't matter:
clang --target=aarch64v8m-none-elf -ffreestanding -nostdlib -c test.c
or
aarch64-linux-gnu-gcc -ffreestanding -nostdlib -c test.c
clang version 9.0.0-2 (tags/RELEASE_900/final)
aarch64-linux-gnu-gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008
Link using the following command for ld.lld:
ld.lld -nostdlib -m aarch64elf -T kernel.ld test.o
llvm-objdump -h output using LLD 11.0.0
(<a href="https://github.com/llvm/llvm-project.git">https://github.com/llvm/llvm-project.git</a>
73cea83a6f5ab521edf3cccfc603534776d691ec) built from upstream for linking:
```
a.out: file format ELF64-aarch64-little
Sections:
Idx Name Size VMA LMA Type
0 00000000 0000000000000000 0000000000000000
1 .text 0000001c ffff000000000000 0000000040080000 TEXT
2 .data 00000010 ffff000000000020 ffff000000000020 DATA
3 .bss 00000004 ffff000000000030 ffff000000000030 BSS
4 .rodata 00000007 ffff000000000034 ffff000000000034 DATA
5 .<a href="show_bug.cgi?id=45313#c00000097">comment 00000097</a> 0000000000000000 0000000000000000
6 .symtab 00000108 0000000000000000 0000000000000000
7 .shstrtab 0000003d 0000000000000000 0000000000000000
8 .strtab 00000037 0000000000000000 0000000000000000
```
llvm-objdump -h output using LLD 9.0.0 (compatible with GNU linkers) installed
via Ubuntu 19.10 package manager:
```
a.out: file format ELF64-aarch64-little
Sections:
Idx Name Size VMA LMA Type
0 00000000 0000000000000000 0000000000000000
1 .text 0000001c ffff000000000000 0000000040080000 TEXT
2 .data 00000010 ffff000000000020 0000000040080020 DATA
3 .bss 00000004 ffff000000000030 0000000040080030 BSS
4 .rodata 00000007 ffff000000000034 0000000040080034 DATA
5 .<a href="show_bug.cgi?id=45313#c00000042">comment 00000042</a> 0000000000000000 0000000000000000
6 .symtab 00000108 0000000000000000 0000000000000000
7 .shstrtab 0000003d 0000000000000000 0000000000000000
8 .strtab 00000037 0000000000000000 0000000000000000
```
The same output can be observed using GNU linker aarch64-linux-gnu-ld installed
via Ubuntu 19.10 package manager.
As you can see when using LLD 11.0.0, the LMA for .data .bss .rodata is equal
to its VMA. With GNU ld and LLD 9.0.0 this is not the case, but instead the LMA
of .data .bss and .rodata is determined by the difference between VMA and LMA
of the previous .text section.
The closest bug that I could find is <a class="bz_bug_link
bz_status_NEW "
title="NEW - LMA/VMA issue on ARMv7 bare metal"
href="show_bug.cgi?id=38776">Bug 38776</a>, but it appears to me it is not
exactly the same.
Thank you for looking into this issue.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>