https://github.com/MaskRay commented:

The title should mention `-z mark-plt`, as otherwise it's vague.


Is this feature actually used in the wild? Or is it just one of hjl's many 
experiments that never see real world adoption?

---

https://maskray.me/blog/2021-09-19-all-about-procedure-linkage-table#x86-plt-rewriting

In 2023-09, GNU ld's x86-64 port [introduced -z 
mark-plt](https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=832ca732b8a96ff9a3e7c4abf24098bf2a59a96d)
 to communicate information to rtld to rewrite eligible indirect jump 
instructions to direct jump instructions.

The linker adds dynamic tags DT_X86_64_PLT/DT_X86_64_PLTSZ/DT_X86_64_PLTENT.
The addend in R_X86_64_JUMP_SLOT relocations are adjusted to indicate the 
offset of the indirect jump instruction.
Since 2024-01, if binutils is configured with --enable-mark-plt, -z mark-plt 
will be the default.

In glibc, when GLIBC_TUNABLES=glibc.cpu.plt_rewrite=1 or 2 is specified, lazy 
PLT binding is disabled, and an object file enables 
DT_X86_64_PLT/DT_X86_64_PLTSZ/DT_X86_64_PLTENT tags, glibc [rewrites eligible 
PLT 
entries](https://sourceware.org/git/?p=glibc.git;a=commit;h=848746e88ec2aa22e8dea25f2110e2b2c59c712e).
 After relocating an object file, x86_64_dynamic_after_reloc (due to the 
ELF_DYNAMIC_AFTER_RELOC hook) calls x86_64_rewrite_plt_in_place, which changes 
the permission of the .plt memory page (MAP_PRIVATE) to PROT_READ|PROT_WRITE, 
rewrites eligible PLT entries, then changes the page to PROT_READ|PROT_EXEC.

For each R_X86_64_JUMP_SLOT relocation, x86_64_rewrite_plt_in_place reads the 
target address from the .got.plt entry, computes the indirect jump address 
using the addend, then checks whether the jump target is reachable with a 
direct JMP instruction. If so, the indirect jump instruction is rewritten to 
jmp $target; otherwise, when GLIBC_TUNABLES=glibc.cpu.plt_rewrite=2 is 
specified on APX processors, the indirect jump instruction is rewritten to 
jmpabs $target (64-bit absolute jump).

The mprotect operations increase private data uses and are incompatible with 
[memory-deny-write-execute](https://git.kernel.org/linus/b507808ebce23561d4ff8c2aa1fb949fe402bc61).
 One primary cost of PLT is the use of an extra instruction cache line. 
Rewriting jump instruction does not eliminate this overhead.

Since the main executable is far away from shared objects in the address space, 
in the absence of APX jmpabs, the PLT rewriting will very likely not occur.

https://github.com/llvm/llvm-project/pull/206002
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to