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



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 ?







Steven Shi

Intel\SSG\STO\UEFI Firmware



Tel: +86 021-61166522

iNet: 821-6522





> -----Original Message-----

> From: af...@apple.com [mailto:af...@apple.com]

> Sent: Tuesday, May 31, 2016 1:26 AM

> To: Shi, Steven <steven....@intel.com>

> Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Justen, Jordan L

> <jordan.l.jus...@intel.com>; 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

>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to