[all-commits] [llvm/llvm-project] 9e37a7: [llvm-objdump][X86] Add @plt symbols for .plt.got
Fangrui Song via All-commits
all-commits at lists.llvm.org
Tue May 16 09:22:35 PDT 2023
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 9e37a7bd1f38fed4e00704d561b3897fe8915c4c
https://github.com/llvm/llvm-project/commit/9e37a7bd1f38fed4e00704d561b3897fe8915c4c
Author: Fangrui Song <i at maskray.me>
Date: 2023-05-16 (Tue, 16 May 2023)
Changed paths:
M llvm/include/llvm/Object/ELFObjectFile.h
M llvm/lib/Object/ELFObjectFile.cpp
M llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
A llvm/test/tools/llvm-objdump/X86/plt-got.test
M llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
M llvm/tools/llvm-objdump/llvm-objdump.cpp
Log Message:
-----------
[llvm-objdump][X86] Add @plt symbols for .plt.got
If a symbol needs both JUMP_SLOT and GLOB_DAT relocations, there is a
minor linker optimization to keep just GLOB_DAT. This optimization
is only implemented by GNU ld's x86 port and mold.
https://maskray.me/blog/2021-08-29-all-about-global-offset-table#combining-.got-and-.got.plt
With the optimizing, the PLT entry is placed in .plt.got and the
associated GOTPLT entry is placed in .got (ld.bfd -z now) or .got.plt (ld.bfd -z lazy).
The relocation is in .rel[a].dyn.
This patch synthesizes `symbol at plt` labels for these .plt.got entries.
Example:
```
cat > a.s <<e
.globl _start; _start:
mov combined0 at gotpcrel(%rip), %rax; mov combined1 at gotpcrel(%rip), %rax
call combined0 at plt; call combined1 at plt
call foo0 at plt; call foo1 at plt
e
cat > b.s <<e
.globl foo0, foo1, combined0, combined1
foo0: foo1: combined0: combined1:
e
gcc -fuse-ld=bfd -shared b.s -o b.so
gcc -fuse-ld=bfd -pie -nostdlib a.s b.so -o a
```
```
Disassembly of section .plt:
0000000000001000 <.plt>:
1000: ff 35 ea 1f 00 00 pushq 0x1fea(%rip) # 0x2ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
1006: ff 25 ec 1f 00 00 jmpq *0x1fec(%rip) # 0x2ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
100c: 0f 1f 40 00 nopl (%rax)
0000000000001010 <foo1 at plt>:
1010: ff 25 ea 1f 00 00 jmpq *0x1fea(%rip) # 0x3000 <_GLOBAL_OFFSET_TABLE_+0x18>
1016: 68 00 00 00 00 pushq $0x0
101b: e9 e0 ff ff ff jmp 0x1000 <.plt>
0000000000001020 <foo0 at plt>:
1020: ff 25 e2 1f 00 00 jmpq *0x1fe2(%rip) # 0x3008 <_GLOBAL_OFFSET_TABLE_+0x20>
1026: 68 01 00 00 00 pushq $0x1
102b: e9 d0 ff ff ff jmp 0x1000 <.plt>
Disassembly of section .plt.got:
0000000000001030 <combined0 at plt>:
1030: ff 25 a2 1f 00 00 jmpq *0x1fa2(%rip) # 0x2fd8 <foo1+0x2fd8>
1036: 66 90 nop
0000000000001038 <combined1 at plt>:
1038: ff 25 a2 1f 00 00 jmpq *0x1fa2(%rip) # 0x2fe0 <foo1+0x2fe0>
103e: 66 90 nop
```
For x86-32, with -z now, if we remove `foo0` and `foo1`, the absence of regular
PLT will cause GNU ld to omit .got.plt, and our code cannot synthesize @plt
labels. This is an extreme corner case that almost never happens in practice (to
trigger the case, ensure every PLT symbol has been taken address). To fix it, we
can get the `_GLOBAL_OFFSET_TABLE_` symbol value, but the complexity is not
worth it.
Close https://github.com/llvm/llvm-project/issues/62537
Reviewed By: bd1976llvm
Differential Revision: https://reviews.llvm.org/D149817
More information about the All-commits
mailing list