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 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