[PATCH] D20024: [ELF] - Protect first entries of got.plt with RelRo.

H.J. Lu via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 07:50:28 PDT 2016


On Mon, May 9, 2016 at 7:39 AM, Rafael Espíndola
<rafael.espindola at gmail.com> wrote:
> On 9 May 2016 at 10:20, H.J. Lu <hjl.tools at gmail.com> wrote:
>> On Mon, May 9, 2016 at 7:18 AM, Rafael Espíndola
>> <rafael.espindola at gmail.com> wrote:
>>> On 9 May 2016 at 09:51, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>> On Mon, May 9, 2016 at 6:47 AM, Rafael Espíndola
>>>> <rafael.espindola at gmail.com> wrote:
>>>>>> Since the the link-time address of _DYNAMIC is stored in the first element
>>>>>> of the GOT as specified by the x86-64 psABI, one can use
>>>>>>
>>>>>> movq _GLOBAL_OFFSET_TABLE_(%rip), %rax
>>>>>>
>>>>>> to get the link-time address of _DYNAMIC.
>>>>>
>>>>> Given that this is being done before relocations, what is the
>>>>> difference from just using _DYNAMIC?
>>>>
>>>> It is the link-time address of _DYNAMIC vs the run-time address of
>>>>  _DYNAMIC.
>>>
>>>
>>> Do you know how it is used?
>>
>>   /* Figure out the run-time load address of the dynamic linker itself.  */
>>   bootstrap_map.l_addr = elf_machine_load_address ();
>>
>> /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
>>    first element of the GOT.  This must be inlined in a function which
>>    uses global data.  */
>> static inline ElfW(Addr) __attribute__ ((unused))
>> elf_machine_dynamic (void)
>> {
>>   /* This produces an IP-relative reloc which is resolved at link time. */
>>   extern const ElfW(Addr) _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
>>   return _GLOBAL_OFFSET_TABLE_[0];
>> }
>>
>>
>> /* Return the run-time load address of the shared object.  */
>> static inline ElfW(Addr) __attribute__ ((unused))
>> elf_machine_load_address (void)
>> {
>>   /* Compute the difference between the runtime address of _DYNAMIC as seen
>>      by an IP-relative reference, and the link-time address found in the
>>      special unrelocated first GOT entry.  */
>>   extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
>>   return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic ();
>> }
>
> OK, seems similar to what netbsd does. I am still not sure why. glibc
> just seems to add back elf_machine_dynamic to read the dynamic table,
> but it could do that without subtracting and adding
> elf_machine_dynamic :-)

Different targets have different implementations of elf_machine_load_address
and elf_machine_dynamic.  The generic part of ld.so can't assume anything.
Compiler will optimize it out on x86-64, which wasn't the case before

commit 5f30cfec00f64edfc0ad932bf7065de13966b69d
Author: H.J. Lu <hjl.tools at gmail.com>
Date:   Sun Sep 2 05:22:24 2012 -0700

    Use the first element of GOT for ld.so addresses

      [BZ #14538]
      * sysdeps/x86_64/dl-machine.h (elf_machine_dynamic): Use the
      first element of the GOT.
      (elf_machine_load_address): Return the difference between
      the runtime address of _DYNAMIC and elf_machine_dynamic ().

> In any case, I think this should be sufficient from lld's point of
> view. I will update the patch to document and test it.
>
>
>> Not going to work if a linker doesn't follow the psABI :-).
>
> Sure, I would just be really surprised if this is all that is missing.
>
> Cheers,
> Rafael



-- 
H.J.


More information about the llvm-commits mailing list