[llvm-bugs] [Bug 45313] New: lld sets LMA to VMA for aarch64elf although previous section uses "AT" keyword

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Mar 26 05:38:39 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=45313

            Bug ID: 45313
           Summary: lld sets LMA to VMA for aarch64elf although previous
                    section uses "AT" keyword
           Product: lld
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: ELF
          Assignee: unassignedbugs at nondot.org
          Reporter: alex.bereza at huawei.com
                CC: llvm-bugs at lists.llvm.org, smithp352 at googlemail.com

Hello,

I believe to have found a problem with LLD 11.0.0
(https://github.com/llvm/llvm-project.git
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:

>  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.

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
(https://github.com/llvm/llvm-project.git
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 .comment      00000097 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 .comment      00000042 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 Bug 38776, but it appears to me it is not
exactly the same.

Thank you for looking into this issue.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200326/367f3d87/attachment.html>


More information about the llvm-bugs mailing list