(adding back our friends on cc) On 1 August 2016 at 12:36, Shi, Steven <steven....@intel.com> wrote: >> On 1 August 2016 at 12:16, Shi, Steven <steven....@intel.com> wrote: >> >> OK, another example: >> >> >> >> pie.s: >> >> >> >> .globl foo >> >> foo: >> >> pushq n@GOTPCREL(%rip) >> >> popq %rax >> >> ret >> >> >> >> .globl bar >> >> bar: >> >> pushq n@GOTPCREL(%rip) >> >> popq %rax >> >> ret >> >> >> >> .globl n >> >> n: >> >> .quad 0 >> >> >> >> compile and link using >> >> >> >> gcc -c -o pie.o /tmp/pie.s >> >> ld -q -o pie pie.o -e foo >> >> >> >> gives me >> >> >> >> Relocation section '.rela.text' at offset 0x260 contains 2 entries: >> >> Offset Info Type Sym. Value Sym. Name + >> >> Addend >> >> 0000004000b2 000700000009 R_X86_64_GOTPCREL 00000000004000be >> n - >> >> 4 >> >> 0000004000b9 000700000009 R_X86_64_GOTPCREL 00000000004000be >> n - >> >> 4 >> >> >> >> Here, pie is a fully linked binary. >> >> >> > [Steven]: In this example, there are two R_X86_64_GOTPCREL relocation >> address in the .text section need to fix up with same symbol runtime address, >> these two relocation addresses are not same, and every relocation address >> will be fixed up once. I don't see the problem of "Having multiple fixups for >> the same symbol in the .reloc section", and current GenFw code should has >> no problem on this example. >> > >> >> How many times will your code call CoffAddFixup() for the address of n? > [Steven]: My understanding is the n address (6000c8) is not a GOTPCREL > relocation in .text section, but the 4000b2 and 4000b2 are GOTPCREL > relocation in .text section. My CoffAddFixup() will only call twice for > 4000b2 and 4000b2, but not for n address (6000c8). > > Disassembly of section .text: > > 00000000004000b0 <foo>: > 4000b0: ff 35 12 00 20 00 pushq 0x200012(%rip) # 6000c8 > <n+0x200008> > 4000b6: 58 pop %rax > 4000b7: c3 retq > > 00000000004000b8 <bar>: > 4000b8: ff 35 0a 00 20 00 pushq 0x20000a(%rip) # 6000c8 > <n+0x200008> > 4000be: 58 pop %rax > 4000bf: c3 retq > > 00000000004000c0 <n>: > ... >
CoffAddFixup() must be used for absolute symbol references only. These instructions contain relative symbol references, which are recalculated in WriteSections64(). The only absolute symbol reference is the GOT entry for 'n', and your code (in WriteRelocations64()) calculates the address of the GOT entry (which is always in .text BTW) and adds a fixup for it, i.e., + CoffAddFixup( + (UINT32)(UINTN)((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + GoTPcRelPtrOffset), + EFI_IMAGE_REL_BASED_DIR64); This code adds a fixup to the PE/COFF .reloc section for the GOT entry containing the address of 'n', and the instructions perform a IP relative load of the contents of the GOT entry to retrieve the address of 'n'. By adding two fixups, the PE/COFF loader will apply the load offset twice, resulting in an incorrect value. -- Ard. _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel