RFC: Dynamic tags for Procedure Linkage Table

15 views
Skip to first unread message

H.J. Lu

unread,
Jul 26, 2023, 2:31:37 PM7/26/23
to x86-6...@googlegroups.com
Here is the updated proposal to include the APX 64-bit direct branch
instruction, JMPABS.

H.J.
---
Procedure Linkage Table (PLT) is used to call external functions defined
in executables or shared libraries. For PLT, which satisfies the following
conditions:

1. PLT entries transfer control to external functions via indirect branch
over the corresponding entry in Global Offset Table (GOT) referenced by
R_X86_64_JUMP_SLOT relocation. A PLT entry may look like

jmp *foo@GOTPCREL(%rip)
pushq $foo_relocation_index
jmp .PLT0

or

endbr64
jmp *foo@GOTPCREL(%rip)
nop

2. All such PLT entries have the same layout.
3. The only entry point of a PLT entry is the first byte of the entry.
4. All entries have the same size and are aligned to the entry size.

define dynamic tags:

#define DT_X86_64_PLT (DT_LOPROC + 0)
#define DT_X86_64_PLTSZ (DT_LOPROC + 1)
#define DT_X86_64_PLTENT (DT_LOPROC + 3)

DT_X86_64_PLT: The address of PLT.
DT_X86_64_PLTSZ: The total size, in bytes, of PLT.
DT_X86_64_PLTENT: The size, in bytes, of a PLT entry.

These PLT dynamic tags don't require any special PLT layout treatment.

Since the r_addend field of R_X86_64_JUMP_SLOT relocation is ignored, it
is repurposed to store the offset, in bytes, of the indirect branch in
the corresponding PLT entry.

If dynamic linker is allowed to

1. Change PLT to writable and non-executable.
2. Update PLT entries.
3. Change PLT back to read-only and executable.

scanning R_X86_64_JUMP_SLOT relocations to locate the corresponding PLT
and GOT entries, dynamic linker may change indirect branch in PLT entries
to direct branch when

1. Lazy binding is disabled.
2. The PLT entry can accommodate 32-bit direct branch or the 64-bit
direct branch instruction, JMPABS, is available.
3. The indirect branch address stored in the GOT entry can be reached
by direct branch.

The x86-64 psABI specifies that R_X86_64_JUMP_SLOT should be resolved
to the symbol value. But dynamic linkers in glibc versions older than
2.33 don't ignore r_addend. Non-zero r_addend in R_X86_64_JUMP_SLOT
relocation is incompatible with such dynamic linkers.

Since executables are loaded by kernel and existing glibc doesn't check
the ELF header in executables, linker should add the glibc version 2.33
dependency to executables and shared libraries with non-zero r_addend in
R_X86_64_JUMP_SLOT.
Reply all
Reply to author
Forward
0 new messages