[llvm-dev] ld.lld drops relocations

Fāng-ruì Sòng via llvm-dev llvm-dev at lists.llvm.org
Mon Mar 15 15:21:11 PDT 2021


On Mon, Mar 15, 2021 at 3:00 PM David Blaikie <dblaikie at gmail.com> wrote:
>
> +Fangrui Song
>
> On Mon, Mar 15, 2021 at 2:57 PM Tomasz Gajc via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>>
>> Hi,
>>
>> i'm trying to dig issue with building systemd-boot EFI images with llvm/clang and linking with llvm/lld. In general building and linking process works and i get my final objects. Unfortunately these EFI images does not boot system. I noticed that .efi image is missing PE/COFF relocations.
>> When i changed linker to ld.bfd, voila everything is fine and final efi image does boot system and have needed relocs. I tried all the ld.lld options related to relocations, but still no success.
>> Thanks for your help.
>>
>> Below you can find diff between two objdumps.
>>
>> [root at tpg-latitude5490 /]# cat bootx.linkers.diff
>> --- bootx.BFD   2021-03-14 23:33:41.687446710 +0100
>> +++ bootx.LLD   2021-03-14 23:33:58.037519874 +0100
>> @@ -1,11 +1,12 @@
>>
>> -systemd-bootx64.efi.BFD:     file format pei-x86-64
>> -systemd-bootx64.efi.BFD
>> -architecture: i386:x86-64, flags 0x00000133:
>> -HAS_RELOC, EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
>> -start address 0x0000000000003000
>> +systemd-bootx64.efi.LLD:     file format pei-x86-64
>> +systemd-bootx64.efi.LLD
>> +architecture: i386:x86-64, flags 0x00000132:
>> +EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
>> +start address 0x0000000000004000
>>
>> -Characteristics 0x206
>> +Characteristics 0x207
>> +       relocations stripped
>>         executable
>>         line numbers stripped
>>         debugging information removed
>> @@ -14,11 +15,11 @@
>>  Magic                  020b    (PE32+)
>>  MajorLinkerVersion     2
>>  MinorLinkerVersion     36
>> -SizeOfCode             0000000000010000
>> -SizeOfInitializedData  0000000000006000
>> +SizeOfCode             000000000000f600
>> +SizeOfInitializedData  0000000000005e00
>>  SizeOfUninitializedData        0000000000000000
>> -AddressOfEntryPoint    0000000000003000
>> -BaseOfCode             0000000000003000
>> +AddressOfEntryPoint    0000000000004000
>> +BaseOfCode             0000000000004000
>>  ImageBase              0000000000000000
>>  SectionAlignment       00001000
>>  FileAlignment          00000200
>> @@ -29,9 +30,9 @@
>>  MajorSubsystemVersion  0
>>  MinorSubsystemVersion  0
>>  Win32Version           00000000
>> -SizeOfImage            0001c000
>> -SizeOfHeaders          00000400
>> -CheckSum               00022f3d
>> +SizeOfImage            0001b000
>> +SizeOfHeaders          00000370
>> +CheckSum               0001b531
>>  Subsystem              0000000a        (EFI application)
>>  DllCharacteristics     00000000
>>  SizeOfStackReserve     0000000000000000
>> @@ -47,7 +48,7 @@
>>  Entry 2 0000000000000000 00000000 Resource Directory [.rsrc]
>>  Entry 3 0000000000000000 00000000 Exception Directory [.pdata]
>>  Entry 4 0000000000000000 00000000 Security Directory
>> -Entry 5 0000000000013000 0000000a Base Relocation Directory [.reloc]
>> +Entry 5 0000000000000000 00000000 Base Relocation Directory [.reloc]
>>  Entry 6 0000000000000000 00000000 Debug Directory
>>  Entry 7 0000000000000000 00000000 Description Directory
>>  Entry 8 0000000000000000 00000000 Special Directory
>> @@ -59,367 +60,358 @@
>>  Entry e 0000000000000000 00000000 CLR Runtime Header
>>  Entry f 0000000000000000 00000000 Reserved
>>
>> -
>> -PE File Base Relocations (interpreted .reloc section contents)
>> -
>> -Virtual Address: 00004770 Chunk size 10 (0xa) Number of fixups 1
>> -       reloc    0 offset    0 [4770] ABSOLUTE
>> -
>>  Sections:
>>  Idx Name          Size      VMA               LMA               File off  Algn
>> -  0 .text         0000ff20  0000000000003000  0000000000003000  00000400  2**4
>> -                  CONTENTS, ALLOC, LOAD, READONLY, CODE
>> -  1 .reloc        0000000a  0000000000013000  0000000000013000  00010400  2**0
>> +  0 .rela.dyn     00000fa8  0000000000000170  0000000000000170  00000370  2**3
>>                    CONTENTS, ALLOC, LOAD, READONLY, DATA
>> -  2 .data         00004460  0000000000014000  0000000000014000  00010600  2**5
>> +  1 .text         0000f510  0000000000004000  0000000000004000  00001400  2**4
>> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
>> +  2 .data         00004578  0000000000014000  0000000000014000  00010a00  2**5
>>                    CONTENTS, ALLOC, LOAD, DATA
>> -  3 .dynamic      000000f0  0000000000019000  0000000000019000  00014c00  2**3
>> +  3 .dynamic      000000a0  0000000000019000  0000000000019000  00015000  2**3
>>                    CONTENTS, ALLOC, LOAD, DATA
>> -  4 .rela         00000fa8  000000000001a000  000000000001a000  00014e00  2**3
>> -                  CONTENTS, ALLOC, LOAD, READONLY, DATA
>> -  5 .dynsym       000004e0  000000000001b000  000000000001b000  00015e00  2**3
>> +  4 .dynsym       00000450  000000000001a000  000000000001a000  00015200  2**3
>>                    CONTENTS, ALLOC, LOAD, READONLY, DATA
>>
>>
>>
>> 1. [systemd issue] - https://github.com/systemd/systemd/issues/19005
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Is this ld.lld (ELF) or lld-link (PE-COFF)? lld is a crunchgen style
linker which supports multiple binary formats.

I have seen two ways producing an EFI binary. Both are largely underspecified.

* ld.bfd -m $an_elf_emulation => objcopy -I elf64-x86-64 -O
efi-app-x86_64. This converts an ELF binary to a PE-COFF binary in a
largely underspecified way. It is not clearly how objcopy translates
the ELF sections and relocations.
* ld.bfd -m $an_pe_emulation (no objcopy). This should correspond to
lld-link. In lld-link, /fixed causes config->relocatable=false, which
eventually sets the IMAGE_FILE_RELOCS_STRIPPED flag.
  It seems that GNU ld does something a bit differently. bfd/peXXigen.c

 /* For PIE, if there is .reloc, we won't add IMAGE_FILE_RELOCS_STRIPPED.
     But there is no .reloc, we make sure that IMAGE_FILE_RELOCS_STRIPPED
     won't be added.  */
  if (! pe_data (ibfd)->has_reloc_section
      && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
    pe_data (obfd)->dont_strip_reloc = 1;

One may need to debug ld.bfd to understand how it works.


More information about the llvm-dev mailing list