Shi, Steven via llvm-dev
2019-Jan-29 06:03 UTC
[llvm-dev] lld write wrong symbol value in .data section if enable -pie
Hi Rui, A quick question: Does lld-link only work with clang-cl with windows-msvc option? Can lld-link work with clang with linux-gnu option? Thanks Steven Shi Intel\SSG\FID\Firmware Infrastructure From: Shi, Steven Sent: Tuesday, January 29, 2019 1:32 PM To: 'Rui Ueyama' <ruiu at google.com> Cc: llvm-dev at lists.llvm.org Subject: RE: lld write wrong symbol value in .data section if enable -pie> It seems to me that it is a great opportunity to simplify build processI agree and we’re investigating the various options with lld. Uefi build has been existed for ~20 years and support multiple compilers, arches and OSes. If the lld can really cover all build features and meet Uefi various requirements, I believe we use it as default linker to make build simple. Thanks Steven Shi Intel\SSG\FID\Firmware Infrastructure From: Rui Ueyama [mailto:ruiu at google.com] Sent: Tuesday, January 29, 2019 1:08 PM To: Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> Cc: llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> Subject: Re: lld write wrong symbol value in .data section if enable -pie I know nothing about your project, so bear with me if my reply is pointless... I'm still wondering if just using lld-link is (at least in theory) the best option for you guys. Before lld, I believe creating UEFI applications was tricky; I've heard of a story of creating it by transplanting a ELF text segment to an empty PE file using objcopy. But now lld is there. It is always a cross-linker, so however you built lld, it is always capable of creating UEFI applications on any host. Doesn't that mean you could remove all hacks such as converting ELF to COFF, creating PE/COFF executables using linker scripts, or doing LTO just to not emit certain types of relocations that the existing tools cannot handle, no? It seems to me that it is a great opportunity to simplify build process, but maybe I'm missing something... On Mon, Jan 28, 2019 at 6:56 PM Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> wrote: Hi Rui,> but why don't you use lld-link (lld for Windows target) instead of ld.lld (lld for Unix target) to create UEFI applications?I need support both PE/COFF and ELF format tools. I’m also working on the lld-link enabling (clang-cl + lld-link) in both Linux and windows. The ld.lld enabling (clang + ld.lld) is for ELF format native users. E.g. https://ci.linaro.org/view/leg-ci/job/leg-virt-tianocore-edk2-upstream/configure. Uefi firmware have many open source developers who like ELF format toolchains … Yes, Uefi firmware application/driver are PE/COFF format. So for ELF format object file, we have a tool to convert ELF to COFF: https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/GenFw. Our convert tool cannot handle complex relocation types, like GOT based. That’s why we use the symbol hidden visibility, LTO and other options to let gcc/clang not emit complex relocation. Thanks Steven Shi Intel\SSG\FID\Firmware Infrastructure From: Rui Ueyama [mailto:ruiu at google.com<mailto:ruiu at google.com>] Sent: Tuesday, January 29, 2019 12:38 AM To: Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> Cc: llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> Subject: Re: lld write wrong symbol value in .data section if enable -pie Hi Steven, This is not a direct answer or suggestion for your problem, but why don't you use lld-link (lld for Windows target) instead of ld.lld (lld for Unix target) to create UEFI applications? A quick google search showed me that UEFI applications are in PE/COFF format, and I can even find people who successfully created UEFI applications using lld-link. Looks like that's much more straightforward way than hacking ld.lld with linker scripts. On Mon, Jan 28, 2019 at 7:35 AM Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> wrote: Hi Rui, I still fail to enable the lld in my Uefi firmware build to replace ld, and I found it is related to the wrong symbol values in the .data section, which are pointed by R_X86_64_64 relocation entries. I need your advices. My firmware uses a linker script https://github.com/tianocore/edk2/blob/master/BaseTools/Scripts/GccBase.lds to do the linking. We use position independent code with hidden visibility to inform the compiler that symbol references are never resolved at runtime. My problem is I found after the lld linking with –pie enabled, the symbol values in .data section, which have the R_X86_64_64 relocation entries, are all 0. In other word, I found the S in below R_X86_64_64 calculation is 0. Name: R_X86_64_64 1 word64 S + A Below is an example to compare the lld and ld, sorry about the verbose. 1. Firstly, I use lld to link a HelloWorld module with -pie enabled: "/home/jshi19/llvm/releaseinstall/bin/ld.lld" -pie -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll -u _ModuleEntryPoint -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0 -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../.. -L/home/jshi19/llvm/releaseinstall/bin/../lib -L/lib -L/usr/lib -q --gc-sections -z max-page-size=0x40 --entry _ModuleEntryPoint -Map /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.map --whole-archive -O0 -melf_x86_64 --oformat elf64-x86-64 --start-group @/home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/static_library_files.lst --end-group --defsym=PECOFF_HEADER_SIZE=0x228 --script=/home/jshi19/wksp_efi/lgao4/edk2/BaseTools/Scripts/GccBase.lds 2. Then, I check the R_X86_64_64 relocation entries in .rela.data section, and find their target offsets $ readelf -r /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll Relocation section '.rela.data' at offset 0x5b7e8 contains 41 entries: Offset Info Type Sym. Value Sym. Name + Addend … … 000000005040 00d600000001 R_X86_64_64 0000000000003130 TestFunction1 + 0 000000005048 00d700000001 R_X86_64_64 0000000000003150 TestFunction2 + 0 3. Next, I check the symbol values in .data section which are targeted by above R_X86_64_64 relocatons $ readelf -x2 HelloWorld.dll Hex dump of section '.data': NOTE: This section has relocations against it, but these have NOT been applied to this dump. … … 0x00005030 00000000 00000000 00000000 00000000 ................ 0x00005040 00000000 00000000 00000000 00000000 ................ 0x00005050 4ebe7903 06d77d43 b037edb8 2fb772a4 N.y...}C.7../.r. 0x00005060 00000000 00000000 00000000 00000000 ................ … … You can see the offset 0x5040 and 0x5048 symbol value are all 0, which is not correct. But if I remove the -pie option in the above step 1 lld link command, the 0x5040 and 0x5048 symbol values are correct. $ readelf -x2 HelloWorld.dll Hex dump of section '.data': NOTE: This section has relocations against it, but these have NOT been applied to this dump. … … 0x00005030 04420000 00000000 00000000 00000000 .B.............. 0x00005040 30310000 00000000 50310000 00000000 01......P1...... 0x00005050 4ebe7903 06d77d43 b037edb8 2fb772a4 N.y...}C.7../.r. 0x00005060 00000000 00000000 00000000 00000000 ................ … … And if I replace lld with ld but still use exact same link options with –pie enabled, the R_X86_64_64 symbol values are correct. 1. Link again with ld and same link options: ld -pie -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll -u _ModuleEntryPoint -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0 -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../.. -L/home/jshi19/llvm/releaseinstall/bin/../lib -L/lib -L/usr/lib -q --gc-sections -z max-page-size=0x40 --entry _ModuleEntryPoint -Map /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.map --whole-archive -O0 -melf_x86_64 --oformat elf64-x86-64 --start-group @/home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/static_library_files.lst --end-group --defsym=PECOFF_HEADER_SIZE=0x228 --script=/home/jshi19/wksp_efi/lgao4/edk2/BaseTools/Scripts/GccBase.lds 2. Then, check the .rela.data section R_X86_64_64 relocation entries: … … 000000004f40 00a400000001 R_X86_64_64 0000000000003130 TestFunction1 + 0 000000004f48 009a00000001 R_X86_64_64 0000000000003150 TestFunction2 + 0 … … 3. Check the R_X86_64_64 targeting symbol values in .data section … … 0x00004f30 f3410000 00000000 00000000 00000000 .A.............. 0x00004f40 30310000 00000000 50310000 00000000 01......P1...... 0x00004f50 00000000 00000000 00000000 00000000 ................ … … You can see the offset 0x4f40 and 0x4f48 symbol value are not 0, which is correct. Appreciate if you could give me some advices on how to let lld output correct symbol values when enable pie. Thanks Steven -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190129/2eea58c5/attachment-0001.html>
Rui Ueyama via llvm-dev
2019-Jan-29 17:15 UTC
[llvm-dev] lld write wrong symbol value in .data section if enable -pie
lld-link is command-line compatible with MSVC link.exe, so it takes Windows-style linker options. It doesn't take Unix-style linker options. You are also expected to invoke lld-link directly instead of using the compiler driver (i.e. clang or cc) because that's how the linker is supposed to be used on Windows. I *believe* you should use clang-cl to create COFF object files and then link them using the following command $ lld-link -subsystem:efi_application -nodefaultlib -dll -WX -entry:efi_main -out:yourapp.exe *.obj but I may be wrong because I've never tested this myself. (By the way, what is linux-gnu option?) On Mon, Jan 28, 2019 at 10:03 PM Shi, Steven <steven.shi at intel.com> wrote:> Hi Rui, > > A quick question: Does lld-link only work with clang-cl with windows-msvc > option? Can lld-link work with clang with linux-gnu option? > > > > > > Thanks > > > > *Steven Shi* > > *Intel\SSG\FID\Firmware Infrastructure* > > > > *From:* Shi, Steven > *Sent:* Tuesday, January 29, 2019 1:32 PM > *To:* 'Rui Ueyama' <ruiu at google.com> > *Cc:* llvm-dev at lists.llvm.org > *Subject:* RE: lld write wrong symbol value in .data section if enable > -pie > > > > > It seems to me that it is a great opportunity to simplify build process > > I agree and we’re investigating the various options with lld. Uefi build > has been existed for ~20 years and support multiple compilers, arches and > OSes. If the lld can really cover all build features and meet Uefi various > requirements, I believe we use it as default linker to make build simple. > > > > > > Thanks > > > > *Steven Shi* > > *Intel\SSG\FID\Firmware Infrastructure* > > > > *From:* Rui Ueyama [mailto:ruiu at google.com <ruiu at google.com>] > *Sent:* Tuesday, January 29, 2019 1:08 PM > *To:* Shi, Steven <steven.shi at intel.com> > *Cc:* llvm-dev at lists.llvm.org > *Subject:* Re: lld write wrong symbol value in .data section if enable > -pie > > > > I know nothing about your project, so bear with me if my reply is > pointless... > > > > I'm still wondering if just using lld-link is (at least in theory) the > best option for you guys. Before lld, I believe creating UEFI applications > was tricky; I've heard of a story of creating it by transplanting a ELF > text segment to an empty PE file using objcopy. > > > > But now lld is there. It is always a cross-linker, so however you built > lld, it is always capable of creating UEFI applications on any host. > Doesn't that mean you could remove all hacks such as converting ELF to > COFF, creating PE/COFF executables using linker scripts, or doing LTO just > to not emit certain types of relocations that the existing tools cannot > handle, no? It seems to me that it is a great opportunity to simplify build > process, but maybe I'm missing something... > > > > On Mon, Jan 28, 2019 at 6:56 PM Shi, Steven <steven.shi at intel.com> wrote: > > Hi Rui, > > > > > but why don't you use lld-link (lld for Windows target) instead of > ld.lld (lld for Unix target) to create UEFI applications? > > I need support both PE/COFF and ELF format tools. I’m also working on the > lld-link enabling (clang-cl + lld-link) in both Linux and windows. The > ld.lld enabling (clang + ld.lld) is for ELF format native users. E.g. > https://ci.linaro.org/view/leg-ci/job/leg-virt-tianocore-edk2-upstream/configure. > Uefi firmware have many open source developers who like ELF format > toolchains … > > > > Yes, Uefi firmware application/driver are PE/COFF format. So for ELF > format object file, we have a tool to convert ELF to COFF: > https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/GenFw. > Our convert tool cannot handle complex relocation types, like GOT based. > That’s why we use the symbol hidden visibility, LTO and other options to > let gcc/clang not emit complex relocation. > > > > > > > > Thanks > > > > *Steven Shi* > > *Intel\SSG\FID\Firmware Infrastructure* > > > > *From:* Rui Ueyama [mailto:ruiu at google.com] > *Sent:* Tuesday, January 29, 2019 12:38 AM > *To:* Shi, Steven <steven.shi at intel.com> > *Cc:* llvm-dev at lists.llvm.org > *Subject:* Re: lld write wrong symbol value in .data section if enable > -pie > > > > Hi Steven, > > > > This is not a direct answer or suggestion for your problem, but why don't > you use lld-link (lld for Windows target) instead of ld.lld (lld for Unix > target) to create UEFI applications? A quick google search showed me that > UEFI applications are in PE/COFF format, and I can even find people who > successfully created UEFI applications using lld-link. Looks like that's > much more straightforward way than hacking ld.lld with linker scripts. > > > > On Mon, Jan 28, 2019 at 7:35 AM Shi, Steven <steven.shi at intel.com> wrote: > > Hi Rui, > > I still fail to enable the lld in my Uefi firmware build to replace ld, > and I found it is related to the wrong symbol values in the .data section, > which are pointed by R_X86_64_64 relocation entries. I need your advices. > > > > My firmware uses a linker script > https://github.com/tianocore/edk2/blob/master/BaseTools/Scripts/GccBase.lds > to do the linking. We use position independent code with hidden visibility > to inform the compiler that symbol references are never resolved at > runtime. My problem is I found after the lld linking with –pie enabled, the > symbol values in .data section, which have the R_X86_64_64 relocation > entries, are all 0. In other word, I found the S in below R_X86_64_64 > calculation is 0. > > > > Name: R_X86_64_64 > > 1 > > *word64 * > > S + A > > > > Below is an example to compare the lld and ld, sorry about the verbose. > > 1. Firstly, I use lld to link a HelloWorld module with -pie enabled: > > "/home/jshi19/llvm/releaseinstall/bin/ld.lld" -pie -z relro > --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker > /lib64/ld-linux-x86-64.so.2 -o > /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll > -u _ModuleEntryPoint -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0 > -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu > -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu > -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../.. > -L/home/jshi19/llvm/releaseinstall/bin/../lib -L/lib -L/usr/lib -q > --gc-sections -z max-page-size=0x40 --entry _ModuleEntryPoint -Map > /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.map > --whole-archive -O0 -melf_x86_64 --oformat elf64-x86-64 --start-group > @/home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/static_library_files.lst > --end-group --defsym=PECOFF_HEADER_SIZE=0x228 > --script=/home/jshi19/wksp_efi/lgao4/edk2/BaseTools/Scripts/GccBase.lds > > > > 2. Then, I check the R_X86_64_64 relocation entries in .rela.data > section, and find their target offsets > > $ readelf -r > /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll > > Relocation section '.rela.data' at offset 0x5b7e8 contains 41 entries: > > Offset Info Type Sym. Value Sym. Name + > Addend > > … … > > 000000005040 00d600000001 R_X86_64_64 0000000000003130 > TestFunction1 + 0 > > 000000005048 00d700000001 R_X86_64_64 0000000000003150 > TestFunction2 + 0 > > > > 3. Next, I check the symbol values in .data section which are > targeted by above R_X86_64_64 relocatons > > $ readelf -x2 HelloWorld.dll > > > Hex dump of section '.data': > > NOTE: This section has relocations against it, but these have NOT been > applied to this dump. > > … … > > 0x00005030 00000000 00000000 00000000 00000000 ................ > > 0x00005040 00000000 00000000 00000000 00000000 ................ > > 0x00005050 4ebe7903 06d77d43 b037edb8 2fb772a4 N.y...}C.7../.r. > > 0x00005060 00000000 00000000 00000000 00000000 ................ > > … … > > You can see the offset 0x5040 and 0x5048 symbol value are all 0, which is > not correct. > > > > But if I remove the -pie option in the above step 1 lld link command, the > 0x5040 and 0x5048 symbol values are correct. > > $ readelf -x2 HelloWorld.dll > > > Hex dump of section '.data': > > NOTE: This section has relocations against it, but these have NOT been > applied to this dump. > > … … > > 0x00005030 04420000 00000000 00000000 00000000 .B.............. > > 0x00005040 30310000 00000000 50310000 00000000 01......P1...... > > 0x00005050 4ebe7903 06d77d43 b037edb8 2fb772a4 N.y...}C.7../.r. > > 0x00005060 00000000 00000000 00000000 00000000 ................ > > … … > > > > And if I replace lld with ld but still use exact same link options with > –pie enabled, the R_X86_64_64 symbol values are correct. > > 1. Link again with ld and same link options: > > ld -pie -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 > -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o > /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll > -u _ModuleEntryPoint -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0 > -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu > -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu > -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../.. > -L/home/jshi19/llvm/releaseinstall/bin/../lib -L/lib -L/usr/lib -q > --gc-sections -z max-page-size=0x40 --entry _ModuleEntryPoint -Map > /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.map > --whole-archive -O0 -melf_x86_64 --oformat elf64-x86-64 --start-group > @/home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/static_library_files.lst > --end-group --defsym=PECOFF_HEADER_SIZE=0x228 > --script=/home/jshi19/wksp_efi/lgao4/edk2/BaseTools/Scripts/GccBase.lds > > > > 2. Then, check the .rela.data section R_X86_64_64 relocation > entries: > > … … > > 000000004f40 00a400000001 R_X86_64_64 0000000000003130 > TestFunction1 + 0 > > 000000004f48 009a00000001 R_X86_64_64 0000000000003150 > TestFunction2 + 0 > > … … > > 3. Check the R_X86_64_64 targeting symbol values in .data section > > … … > > 0x00004f30 f3410000 00000000 00000000 00000000 .A.............. > > 0x00004f40 30310000 00000000 50310000 00000000 01......P1...... > > 0x00004f50 00000000 00000000 00000000 00000000 ................ > > … … > > You can see the offset 0x4f40 and 0x4f48 symbol value are not 0, which is > correct. > > > > Appreciate if you could give me some advices on how to let lld output > correct symbol values when enable pie. > > > > > > Thanks > > Steven > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190129/917522dc/attachment-0001.html>
Shi, Steven via llvm-dev
2019-Jan-30 01:42 UTC
[llvm-dev] lld write wrong symbol value in .data section if enable -pie
> I *believe* you should use clang-cl to create COFF object files and then link them using the following command >$ lld-link -subsystem:efi_application -nodefaultlib -dll -WX -entry:efi_main -out:yourapp.exe *.objWill try the clang-cl as your suggestion. Actually, I already tried the clang + lld-link in windows. I directly used Linux-style CC options for clang in windows, but set target as 'x86_64-pc-windows-msvc' and used the Windows-style option for lld-link. Everything works for 32bits uefi code build, but for 64bits code the clang cannot support –pie option with 'x86_64-pc-windows-msvc' target and build fail as below: clang: error: unsupported option '-fpie' for target 'x86_64-pc-windows-msvc' So, it looks only the clang-cl + lld-link is the correct toolchain for COFF format native build. Then, I have a question: if I can only use the clang-cl for COFF format native build, does it mean I cannot use Linux debugging tools for dwarf debug info, e.g. GDB?> By the way, what is linux-gnu option?I mean the option which is fit for *-pc-linux-gnu target. Thanks Steven Shi Intel\SSG\FID\Firmware Infrastructure From: Rui Ueyama [mailto:ruiu at google.com] Sent: Wednesday, January 30, 2019 1:15 AM To: Shi, Steven <steven.shi at intel.com> Cc: llvm-dev at lists.llvm.org Subject: Re: lld write wrong symbol value in .data section if enable -pie lld-link is command-line compatible with MSVC link.exe, so it takes Windows-style linker options. It doesn't take Unix-style linker options. You are also expected to invoke lld-link directly instead of using the compiler driver (i.e. clang or cc) because that's how the linker is supposed to be used on Windows. I *believe* you should use clang-cl to create COFF object files and then link them using the following command $ lld-link -subsystem:efi_application -nodefaultlib -dll -WX -entry:efi_main -out:yourapp.exe *.obj but I may be wrong because I've never tested this myself. (By the way, what is linux-gnu option?) On Mon, Jan 28, 2019 at 10:03 PM Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> wrote: Hi Rui, A quick question: Does lld-link only work with clang-cl with windows-msvc option? Can lld-link work with clang with linux-gnu option? Thanks Steven Shi Intel\SSG\FID\Firmware Infrastructure From: Shi, Steven Sent: Tuesday, January 29, 2019 1:32 PM To: 'Rui Ueyama' <ruiu at google.com<mailto:ruiu at google.com>> Cc: llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> Subject: RE: lld write wrong symbol value in .data section if enable -pie> It seems to me that it is a great opportunity to simplify build processI agree and we’re investigating the various options with lld. Uefi build has been existed for ~20 years and support multiple compilers, arches and OSes. If the lld can really cover all build features and meet Uefi various requirements, I believe we use it as default linker to make build simple. Thanks Steven Shi Intel\SSG\FID\Firmware Infrastructure From: Rui Ueyama [mailto:ruiu at google.com] Sent: Tuesday, January 29, 2019 1:08 PM To: Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> Cc: llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> Subject: Re: lld write wrong symbol value in .data section if enable -pie I know nothing about your project, so bear with me if my reply is pointless... I'm still wondering if just using lld-link is (at least in theory) the best option for you guys. Before lld, I believe creating UEFI applications was tricky; I've heard of a story of creating it by transplanting a ELF text segment to an empty PE file using objcopy. But now lld is there. It is always a cross-linker, so however you built lld, it is always capable of creating UEFI applications on any host. Doesn't that mean you could remove all hacks such as converting ELF to COFF, creating PE/COFF executables using linker scripts, or doing LTO just to not emit certain types of relocations that the existing tools cannot handle, no? It seems to me that it is a great opportunity to simplify build process, but maybe I'm missing something... On Mon, Jan 28, 2019 at 6:56 PM Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> wrote: Hi Rui,> but why don't you use lld-link (lld for Windows target) instead of ld.lld (lld for Unix target) to create UEFI applications?I need support both PE/COFF and ELF format tools. I’m also working on the lld-link enabling (clang-cl + lld-link) in both Linux and windows. The ld.lld enabling (clang + ld.lld) is for ELF format native users. E.g. https://ci.linaro.org/view/leg-ci/job/leg-virt-tianocore-edk2-upstream/configure. Uefi firmware have many open source developers who like ELF format toolchains … Yes, Uefi firmware application/driver are PE/COFF format. So for ELF format object file, we have a tool to convert ELF to COFF: https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/GenFw. Our convert tool cannot handle complex relocation types, like GOT based. That’s why we use the symbol hidden visibility, LTO and other options to let gcc/clang not emit complex relocation. Thanks Steven Shi Intel\SSG\FID\Firmware Infrastructure From: Rui Ueyama [mailto:ruiu at google.com<mailto:ruiu at google.com>] Sent: Tuesday, January 29, 2019 12:38 AM To: Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> Cc: llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> Subject: Re: lld write wrong symbol value in .data section if enable -pie Hi Steven, This is not a direct answer or suggestion for your problem, but why don't you use lld-link (lld for Windows target) instead of ld.lld (lld for Unix target) to create UEFI applications? A quick google search showed me that UEFI applications are in PE/COFF format, and I can even find people who successfully created UEFI applications using lld-link. Looks like that's much more straightforward way than hacking ld.lld with linker scripts. On Mon, Jan 28, 2019 at 7:35 AM Shi, Steven <steven.shi at intel.com<mailto:steven.shi at intel.com>> wrote: Hi Rui, I still fail to enable the lld in my Uefi firmware build to replace ld, and I found it is related to the wrong symbol values in the .data section, which are pointed by R_X86_64_64 relocation entries. I need your advices. My firmware uses a linker script https://github.com/tianocore/edk2/blob/master/BaseTools/Scripts/GccBase.lds to do the linking. We use position independent code with hidden visibility to inform the compiler that symbol references are never resolved at runtime. My problem is I found after the lld linking with –pie enabled, the symbol values in .data section, which have the R_X86_64_64 relocation entries, are all 0. In other word, I found the S in below R_X86_64_64 calculation is 0. Name: R_X86_64_64 1 word64 S + A Below is an example to compare the lld and ld, sorry about the verbose. 1. Firstly, I use lld to link a HelloWorld module with -pie enabled: "/home/jshi19/llvm/releaseinstall/bin/ld.lld" -pie -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll -u _ModuleEntryPoint -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0 -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../.. -L/home/jshi19/llvm/releaseinstall/bin/../lib -L/lib -L/usr/lib -q --gc-sections -z max-page-size=0x40 --entry _ModuleEntryPoint -Map /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.map --whole-archive -O0 -melf_x86_64 --oformat elf64-x86-64 --start-group @/home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/static_library_files.lst --end-group --defsym=PECOFF_HEADER_SIZE=0x228 --script=/home/jshi19/wksp_efi/lgao4/edk2/BaseTools/Scripts/GccBase.lds 2. Then, I check the R_X86_64_64 relocation entries in .rela.data section, and find their target offsets $ readelf -r /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll Relocation section '.rela.data' at offset 0x5b7e8 contains 41 entries: Offset Info Type Sym. Value Sym. Name + Addend … … 000000005040 00d600000001 R_X86_64_64 0000000000003130 TestFunction1 + 0 000000005048 00d700000001 R_X86_64_64 0000000000003150 TestFunction2 + 0 3. Next, I check the symbol values in .data section which are targeted by above R_X86_64_64 relocatons $ readelf -x2 HelloWorld.dll Hex dump of section '.data': NOTE: This section has relocations against it, but these have NOT been applied to this dump. … … 0x00005030 00000000 00000000 00000000 00000000 ................ 0x00005040 00000000 00000000 00000000 00000000 ................ 0x00005050 4ebe7903 06d77d43 b037edb8 2fb772a4 N.y...}C.7../.r. 0x00005060 00000000 00000000 00000000 00000000 ................ … … You can see the offset 0x5040 and 0x5048 symbol value are all 0, which is not correct. But if I remove the -pie option in the above step 1 lld link command, the 0x5040 and 0x5048 symbol values are correct. $ readelf -x2 HelloWorld.dll Hex dump of section '.data': NOTE: This section has relocations against it, but these have NOT been applied to this dump. … … 0x00005030 04420000 00000000 00000000 00000000 .B.............. 0x00005040 30310000 00000000 50310000 00000000 01......P1...... 0x00005050 4ebe7903 06d77d43 b037edb8 2fb772a4 N.y...}C.7../.r. 0x00005060 00000000 00000000 00000000 00000000 ................ … … And if I replace lld with ld but still use exact same link options with –pie enabled, the R_X86_64_64 symbol values are correct. 1. Link again with ld and same link options: ld -pie -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll -u _ModuleEntryPoint -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0 -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../.. -L/home/jshi19/llvm/releaseinstall/bin/../lib -L/lib -L/usr/lib -q --gc-sections -z max-page-size=0x40 --entry _ModuleEntryPoint -Map /home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/DEBUG/HelloWorld.map --whole-archive -O0 -melf_x86_64 --oformat elf64-x86-64 --start-group @/home/jshi19/wksp_efi/lgao4/edk2/Build/OvmfX64/NOOPT_CLANG38/X64/MdeModulePkg/Application/HelloWorld/HelloWorld/OUTPUT/static_library_files.lst --end-group --defsym=PECOFF_HEADER_SIZE=0x228 --script=/home/jshi19/wksp_efi/lgao4/edk2/BaseTools/Scripts/GccBase.lds 2. Then, check the .rela.data section R_X86_64_64 relocation entries: … … 000000004f40 00a400000001 R_X86_64_64 0000000000003130 TestFunction1 + 0 000000004f48 009a00000001 R_X86_64_64 0000000000003150 TestFunction2 + 0 … … 3. Check the R_X86_64_64 targeting symbol values in .data section … … 0x00004f30 f3410000 00000000 00000000 00000000 .A.............. 0x00004f40 30310000 00000000 50310000 00000000 01......P1...... 0x00004f50 00000000 00000000 00000000 00000000 ................ … … You can see the offset 0x4f40 and 0x4f48 symbol value are not 0, which is correct. Appreciate if you could give me some advices on how to let lld output correct symbol values when enable pie. Thanks Steven -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190130/797f5a2a/attachment-0001.html>