[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