> On May 31, 2016, at 7:26 AM, Andrew Fish <af...@apple.com> wrote: > >> >> On May 31, 2016, at 1:01 AM, Shi, Steven <steven....@intel.com> wrote: >> >> Hi Andrew, >>> The ELF should be linked at zero so that seems like the bug? It looks like >>> your code is linking at 0x00400000. Is that breaking the code that is >>> converting to PE/COFF? >> [Steven]: No in fact, the start address of ELF shared library does not >> matter. The real running address will be fixed according to relocation >> section info. OK, after I use the GCC same link script, my SecMain.dll is >> also linked at zero now. But the CPU exception failure is exactly same. I >> attached the below new disassemble code and elf sections info file in this >> email. >> readelf -a SecMain.dll > SecMain.dll.elf >> objdump -dS SecMain.dll > SecMain.dll.s >> >> In the new SecMain.dll.s, you will see same two jump instructions which are >> absolute indirect Qword, but given in 32bits RIP-relative addressing. The >> two 32bits RIP-relative address (0x5ea, 0x7c4 in below instructions) are >> relocation address in .text section and need to be fix when load to memory. >> >> 5e7: ff 24 c5 38 7d 00 00 jmpq *0x7d38(,%rax,8) ß there >> is a relocation address in 0x4006e2, [0x5ea] = 0x00007d38 >> 7c1: ff 24 c5 c0 79 00 00 jmpq *0x79c0(,%rax,8)) ß >> there is a relocation address in 0x4004dd, [0x7c4] = 0x000079c0 >> >> In SecMain.dll.elf, you can clearly see the above two relocation address >> type is R_X86_64_32S, which is 32bits signed address(rang is [-2GB, 2GB]), >> not R_X86_64_64. >> Relocation section '.rela.text' at offset 0x202b38 contains 78 entries: >> Offset Info Type >> Sym. Value Sym. Name + Addend >> 0000000005ea 00010000000b R_X86_64_32S 0000000000000240 .text + 7af8 >> 0000000007c4 00010000000b R_X86_64_32S 0000000000000240 .text + 7780 >> >> >> >>> Yes as you can't allocate memory < 4GB in an x86_64 Mac OS X App. >>> My example command line app shows the default is > 4GB from the thread. >>> (lldb) dis -n get_constant -b >>> a.out`get_constant: >>> a.out[0x100000f8c] <+0>: 55 pushq %rbp >>> a.out[0x100000f8d] <+1>: 48 89 e5 movq %rsp, %rbp >>> a.out[0x100000f90] <+4>: 8b 05 6a 00 00 00 movl 0x6a(%rip), %eax >>> a.out[0x100000f96] <+10>: 5d popq %rbp >>> a.out[0x100000f97] <+11>: c3 retq >> >> [Steven]: This is really interesting. Let me ask the Mac OS X >> App default code model in LLVM community. >> >> Thank you! >> >> Steven Shi >> Intel\SSG\STO\UEFI Firmware >> >> Tel: +86 021-61166522 >> iNet: 821-6522 >> >> From: af...@apple.com<mailto:af...@apple.com> [mailto:af...@apple.com] >> Sent: Tuesday, May 31, 2016 11:10 AM >> To: Shi, Steven <steven....@intel.com<mailto:steven....@intel.com>> >> Cc: Kinney, Michael D >> <michael.d.kin...@intel.com<mailto:michael.d.kin...@intel.com>>; Justen, >> Jordan L <jordan.l.jus...@intel.com<mailto:jordan.l.jus...@intel.com>>; >> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org> >> Subject: Re: [edk2] edk2 llvm branch >> >> >> On May 30, 2016, at 6:32 PM, Shi, Steven >> <steven....@intel.com<mailto:steven....@intel.com>> wrote: >> >> Hi Andrew, >> >>> jmpq *.LJTI3_0(,%rcx,8) >>> jmpq 0xfffcdd54(,%rcx,8) >>> >>> It seems like this code is saying go backwards 200K which seems broken in >>> general (How big is your SEC?). So this is likely a code gen bug. >> >> [Steven]: OK, Let me explain the details about how the wrong relocation of >> jmpq *.LJTI3_0(,%rcx,8) --> jmpq 0xfffcdd54(,%rcx,8) could happened >> in small code model. >> >> Firstly, let’s get the SecMain.dll disassemble code and all elf sections >> info with below command. I’ve attached my info file in this email. >> readelf -a SecMain.dll > SecMain.dll.elf >> objdump -dS SecMain.dll > SecMain.dll.s >> >> In SecMain.dll.s, you will see the two jump instructions which are absolute >> indirect Qword, but given in 32bits RIP-relative addressing. The two 32bits >> RIP-relative address (0x4006e2, 0x4004dd in below instructions) are >> relocation address in .text section and need to be fix when load to memory. >> >> 4006df: ff 24 c5 e0 1a 40 00 jmpq >> *0x401ae0(,%rax,8) <-- there is a relocation address in 0x4006e2, >> [0x4006e2] = 0x401ae0 >> 4004da: ff 24 c5 58 1e 40 00 jmpq >> *0x401e58(,%rax,8) <-- there is a relocation address in 0x4004dd, >> [0x4004dd] = 0x401e58 >> >> In SecMain.dll.elf, you can clearly see the above two relocation address >> type is R_X86_64_32S, which is 32bits signed address, not R_X86_64_64. >> Relocation section '.rela.text' at offset 0x202b38 contains 78 entries: >> Offset Info Type >> Sym. Value Sym. Name + Addend >> 0000004006e2 00020000000b R_X86_64_32S 0000000000401ae0 .rodata + 0 >> 0000004004dd 00020000000b R_X86_64_32S 0000000000401ae0 .rodata + 378 >> > > Steven, > > For a 64-bit image you should never end up with R_X86_64_32S. Actually > PE/COFF does not have the concept of a signed relocation in an image. > > It is a little more clear in the PE/COFF specification but there are image > relocations and object relocations. The image relocations are the ones that > end up in the final linked image, and object relocations end up in object > files and are used by the linker to build the final image. > > For example if you look in the ELF Specification (Sys V ABI for AMD64) you > will notice that there are PC relative relocations. A PC relative relocation > would never end up in an image, they just exist to help the linker. The > linker is not going to know the final PC relative offset until all of the > code is constructed, so it is the linkers job to resolve these relocations. > For example if you try to access a global that is defined in another module > the compiler does not know the final PC relative offset when the code is > generated, thus the linker has to fix that up as part of the final link. > > If you turn off LTO what does the code look like? Does it work? This looks > like a linker error, but it is hard to say if it is the compiler or linker at > fault. > > Writing a bug report against LLVM that requires the compiler writer to run > OVFM with a specific custom tool chain is probably never going to get fixed. > You are going to have to write some test code that reproduces the failure and > attach that example to the bug report. >
I see from the llvm mail thread that you need to add the -pie linker flag with the small model did that resolve your issue? Thanks, Andrew Fish > Thanks, > > Andrew Fish > > >> The ELF should be linked at zero so that seems like the bug? It looks like >> your code is linking at 0x00400000. Is that breaking the code that is >> converting to PE/COFF? >> >> >> When our build GenFw tool fix the above two 32bits signed address with Sec >> high address (e.g. 0xfffcdd54), it cause the two address overflow to wrong >> negative values. >> >> Why the compiler use the R_X86_64_32S, not R_X86_64_64, as the relocation >> address type in .text section? It is because the compiler assume the code >> model is small. If we let the compiler know we need large code model, the >> compiler should takes the "safe road" everywhere, using absolute 64-bit >> moves to refer to symbols and generate correct relocation type. This is why >> I need LLVM LTO support large code model. Please to ask apple compiler team >> to help me. >> >> >>> The small model does not restrict the address code can run at, all Mac OS X >>> applications run at addresses > 4 GB for example >> [Steven]: are you sure the small code model Mac OS X >> application can run at address > 4GB ? >> >> >> Yes as you can't allocate memory < 4GB in an x86_64 Mac OS X App. >> >> My example command line app shows the default is > 4GB from the thread. >> >>> (lldb) dis -n get_constant -b >>> a.out`get_constant: >>> a.out[0x100000f8c] <+0>: 55 pushq %rbp >>> a.out[0x100000f8d] <+1>: 48 89 e5 movq %rsp, %rbp >>> a.out[0x100000f90] <+4>: 8b 05 6a 00 00 00 movl 0x6a(%rip), %eax >>> a.out[0x100000f96] <+10>: 5d popq %rbp >>> a.out[0x100000f97] <+11>: c3 retq >> >> Thanks, >> >> Andrew Fish >> >> >> >> Steven Shi >> Intel\SSG\STO\UEFI Firmware >> >> Tel: +86 021-61166522 >> iNet: 821-6522 >> >> >>> -----Original Message----- >>> From: af...@apple.com<mailto:af...@apple.com> [mailto:af...@apple.com] >>> Sent: Tuesday, May 31, 2016 1:26 AM >>> To: Shi, Steven <steven....@intel.com<mailto:steven....@intel.com>> >>> Cc: Kinney, Michael D >>> <michael.d.kin...@intel.com<mailto:michael.d.kin...@intel.com>>; Justen, >>> Jordan L >>> <jordan.l.jus...@intel.com<mailto:jordan.l.jus...@intel.com>>; >>> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org> >>> Subject: Re: [edk2] edk2 llvm branch >>> >>> >>>> On May 29, 2016, at 10:47 PM, Shi, Steven >>>> <steven....@intel.com<mailto:steven....@intel.com>> wrote: >>>> >>>> Hi Andrew, >>>> >>>> I think I root cause the issue that Clang LTO X64 OVMF hang in Sec. It is >>> related to the LLVM LTO has not supported the large code model yet which >>> cause X64 LTO code cannot be loaded to run at high address (larger than >>> 2GB). Please see the detail in below llvm thread discussion. Apple engineer >>> (Mehdi) says ld64 on OS X does not support large code model in LTO either, >>> which means your Xcode LTO tool chain should have the same problem. >>>> >>> >>> Steven, >>> >>> We don't have any issues using Xcode. I think you are confused about >>> needing the large code model. The small model means the program can't be >>> larger than 2GB. The small model does not restrict the address code can run >>> at, all ll Mac OS X applications run at addresses > 4 GB for example. The >>> SEC >>> (like all EFI drivers/applications) is linked at 0x0 (or 0x240 for ELF and >>> Mach-O >>> to make space for the PE/COFF header). The build tools relocate the PE/COFF >>> image to the addresses in the FV so they can execute in place. >>> >>> The small and large models are about PIC (Position Independent Code) and >>> have to do with how big the offset is to the PC (%rip). The small model is a >>> 32-bit offset so you can only go 2GB in any give direction, and that is what >>> limits the size, but it makes each PC relative instruction smaller (saves 4 >>> bytes). >>> >>> For example if you read a global like this the compiler will generate this >>> code. >>> int constant = 0; >>> >>> int get_constant(void) >>> { >>> return constant; >>> } >>> >>> (lldb) dis -n get_constant -b >>> a.out`get_constant: >>> a.out[0x100000f8c] <+0>: 55 pushq %rbp >>> a.out[0x100000f8d] <+1>: 48 89 e5 movq %rsp, %rbp >>> a.out[0x100000f90] <+4>: 8b 05 6a 00 00 00 movl 0x6a(%rip), %eax >>> a.out[0x100000f96] <+10>: 5d popq %rbp >>> a.out[0x100000f97] <+11>: c3 retq >>> >>> At link time the linker will figure out the offset (plus or minus) from the >>> PC >>> required to access the global. In the example above the data section follows >>> the text section so the offset to the global is PC + 0x6a. The small model >>> implies that the %rip relative move is a 32-bit operation and you can see >>> the >>> mov instruction is 6 bytes (2 op codes and a 32-bit offset). This code does >>> not >>> have any issue running near the X86 reset vector just under 4 GB. >>> >>> Your reported issue was a register-indirect absolute JMP instruction which >>> is >>> going to be the same in both models. I think the way this works is %rcx will >>> be PIC (calculated relative to %rip) and the constant is an offset to the >>> jmp >>> table and the table index. >>> >>> jmpq *.LJTI3_0(,%rcx,8) >>> jmpq 0xfffcdd54(,%rcx,8) >>> >>> It seems like this code is saying go backwards 200K which seems broken in >>> general (How big is your SEC?). So this is likely a code gen bug. >>> >>> This almost looks like a PE/COFF relocation was applied in error? Can you >>> look at the SecMain.efi (the one linked at zero) and disassemble that >>> instruction and see what value it contains. You can also dump the PE/COFF >>> and see if that location contains a relocation. This looks like it may be a >>> linker bug? >>> >>> Thanks, >>> >>> Andrew Fish >>> >> <SecMain.dll.elf><SecMain.dll.s> >> >> _______________________________________________ >> edk2-devel mailing list >> edk2-devel@lists.01.org >> https://lists.01.org/mailman/listinfo/edk2-devel > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel