[llvm-dev] lld write wrong symbol value in .data section if enable -pie

Rui Ueyama via llvm-dev llvm-dev at lists.llvm.org
Tue Jan 29 09:15:23 PST 2019


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>


More information about the llvm-dev mailing list