> 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

Reply via email to