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

Rafael Espíndola via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 08:46:44 PDT 2016


I was able to link and run the musl  dynamic linker with the patch that
stops setting got[0].

So, Rui, what is your take on this? Should we leave that out of tree until
it is time to try to link glibc's dynamic linker?

Cheers,
Rafael
On May 9, 2016 10:50 AM, "H.J. Lu" <hjl.tools at gmail.com> wrote:

> 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.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160509/cacdc2ef/attachment.html>


More information about the llvm-commits mailing list