[x86-64 psABI] RFC: Extend x86-64 PLT entry to support MPX
H.J. Lu
hjl.tools@gmail.com
Thu Jul 25 17:24:00 GMT 2013
On Wed, Jul 24, 2013 at 5:23 PM, Ian Lance Taylor <iant@google.com> wrote:
>> * The foo@plt pseudo-symbols that e.g. objdump will display are based on
>> the BFD backend knowing the size of PLT entries. Arguably this ought
>> to look at sh_entsize of .plt instead of using baked-in knowledge, but
>> it doesn't.
>
> This seems fixable. Of course, we could also keep the PLT the same
> length by changing it. The current PLT entries are
>
> jmpq *GOT(sym)
> pushq offset
> jmpq plt0
>
> The linker or dynamic linker initializes *GOT(sym) to point to the
> second instruction in this sequence. So we can keep the PLT at 16
> bytes by simply changing it to jump somewhere else.
>
> bnd jmpq *GOT(sym)
> .skip 9
>
> We have the linker or dynamic linker fill in *GOT(sym) to point to the
> second PLT table. When the dynamic linker is involved, we use another
> DT tag to point to the second PLT. The offsets are consistent: there
> is one entry in each PLT table, so the dynamic linker can compute the
> right value. Then in the second PLT we have the sequence
>
> pushq offset
> bnd jmpq plt0
>
> That gives the dynamic linker the offset that it needs to update
> *GOT(sym) to point to the runtime symbol value. So we get slightly
> worse instruction cache handling the first time a function is called,
> but after that we are the same as before. And PLT entries are the
> same size as always so everything is simpler.
>
> The special DT tag will tell the dynamic linker to apply the special
> processing. No attribute is needed to change behaviour. The issue
> then is: a program linked in this way will not work with an old
> dynamic linker, because the old dynamic linker will not initialize
> GOT(sym) to the right value. That is a problem for any scheme, so I
> think that is OK. But if that is a concern, we could actually handle
> by generating two PLTs. One conventional PLT, and another as I just
> outlined. The linker branches to the new PLT, and initializes
> GOT(sym) to point to the old PLT. The dynamic linker spots this
> because it recognizes the new DT tags, and cunningly rewrites the GOT
> to point to the new PLT. Cost is an extra jump the first time a
> function is called when using the old dynamic linker.
>
I don't like the complexity. I believe extending PLT entry to
32 byte works with the old ld.so. If we are willing to have
mixed PLT entry, we merge 2 16-byte PLT entries into one
super 32-byte PLT entry so that we can have
jmpq *name@GOTPCREL(%rip)
pushq $index
jmpq PLT0
bnd jmpq *name@GOTPCREL(%rip)
pushq $index
bnd jmpq PLT0
nop paddings
jmpq *name@GOTPCREL(%rip)
pushq $index
jmpq PLT0
We can also have new link-time relocations for branches with BND
prefix and only create the super PLT entries when needed. Of course,.
unwind info may be incorrect for both approach if we don't find a way
to fix it.
--
H.J.
More information about the Binutils
mailing list