This is the mail archive of the
libc-ports@sources.redhat.com
mailing list for the libc-ports project.
Re: aarch64 prelink issue
- From: Marcus Shawcroft <marcus dot shawcroft at linaro dot org>
- To: Mark Salter <msalter at redhat dot com>
- Cc: Richard Henderson <rth at twiddle dot net>, libc-ports <libc-ports at sourceware dot org>
- Date: Wed, 26 Jun 2013 16:36:10 +0100
- Subject: Re: aarch64 prelink issue
- References: <1372092109 dot 3739 dot 13 dot camel at t520 dot redhat dot com> <51C87F49 dot 3070008 at twiddle dot net> <1372250579 dot 3739 dot 42 dot camel at t520 dot redhat dot com>
On 26 June 2013 13:42, Mark Salter <msalter@redhat.com> wrote:
> On Mon, 2013-06-24 at 10:18 -0700, Richard Henderson wrote:
>> Try the x86_64 solution:
>>
>> /* 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];
>>
>> with the extra hidden attribute, this should result in an ADR(P)
>> reference to the _G_O_T_.
>>
>
> This isn't working for aarch64. It doesn't use a PC-relative reference
> and it tries reading from the GOT at the link time absolute address.
It looks to me that Richard's proposal gives the correct sequence in
elf_machine_dynamic():
adrp x0, _GLOBAL_OFFSET_TABLE_
ldr x0, [x0,#:lo12:_GLOBAL_OFFSET_TABLE_]
ret
... but, this exposes an issue in the static linker:
Currently the static linker produces:
.got
<-_GLOBAL_OFFSET_TABLE_
...
.gotplt[0] &_DYNAMIC <--DT_PLTGOT
.gotplt[1] reserved for ld.so (&linkmap)
.gotplt[2] reserved fpr ld.so (resolver)
...
This layout is broken wrt the placement of &_DYNAMIC. The correct
layout should be:
.got[0] &_DYNAMIC <-_GLOBAL_OFFSET_TABLE_
...
.gotplt[0] reserved for ld.so (&linkmap) <--DT_PLTGOT
.gotplt[1] reserved fpr ld.so (resolver)
...
Hence when we use Richard's suggestion we end up picking junk out of .got[0]
I'm still looking at this, but at the moment I think we can fix the
static linker to emit:
.got[0] &_DYNAMIC <-_GLOBAL_OFFSET_TABLE_
...
.gotplt[0] reserved for ld.so (&linkmap) <--DT_PLTGOT
.gotplt[1] reserved for ld.so (resolver)
.gotplt[2] reserved
With this change, I believe that we do not introduce an
incompatibility between existing binaries / .so's and the modified
ld.so because the code within elf_machine_dynamic() is only
instantiated within ld.so and is only used to inspect ld.so's own
image.
The .gotplt[2] entry remains reserved in the new layout to ensure that
an unmodified ld.so can load a binary built using a modified static ld
without clobbering the first real PLT entry.
I'd really appreciate some feedback on the sanity of this proposal.
Thanks
/Marcus