(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

Reply via email to