[BOLT] BOLT reorders .rela.plt without updating PLT stub relocation indices
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Full disclaimer: I used Codex to help me diagnose this issue and create a reproducer. I did, however, try to understand the issue and describe it in my own words to the best of my abilities (with my limited ELF knowledge).
I looked through the open issues and couldn't find one, please excuse me if I missed it.
It seems that BOLT reorders .rela.plt entries without also updating the corresponding PLT stub relocation indices.
```console
$ llvm-bolt --version
LLVM (http://llvm.org/):
LLVM version 22.1.5
$ gcc version 15.2.0 (GCC)
gcc version 15.2.0 (GCC)
Target: x86_64-unknown-linux-gnu
$ clang
clang version 21.1.8
Target: x86_64-unknown-linux-gnu
```
**main.c**
```c
extern int long_name(void);
__attribute__((target_clones("default,avx2")))
int foo(int x) {
return x + 1;
}
int main(void) {
if (foo(1) != 2) {
return 1;
}
if (long_name() != 0) {
return 1;
}
return 0;
}
```
**example.c**
```c
int long_name(void) {
return 0;
}
```
**Build steps**
```bash
gcc -o2 -g -fPIC -shared -o libexample.so example.c
gcc -o2 -g -fno-pie -no-pie -Wl,--emit-relocs -Wl,-rpath,'$ORIGIN' -o repro main.c -L. -lexample
llvm-bolt repro -o repro.bolt
./repro.bolt
```
```
Inconsistency detected by ld.so: dl-runtime.c: 63: _dl_fixup: Assertion `ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT' failed!
```
If we look at the original binary:
```
$ readelf -r --use-dynamic repro
'RELA' relocation section at offset 0x400548 contains 48 bytes:
Offset Info Type Sym. Value Sym. Name + Addend
000000404fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
000000404fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
'PLT' relocation section at offset 0x400578 contains 48 bytes:
Offset Info Type Sym. Value Sym. Name + Addend
000000405008 000300000007 R_X86_64_JUMP_SLO 0000000000000000 long_name + 0
000000405000 000000000025 R_X86_64_IRELATIV 4024e5
```
Compared to the binary created by BOLT:
```
$ readelf -r --use-dynamic repro.bolt
'RELA' relocation section at offset 0x400548 contains 48 bytes:
Offset Info Type Sym. Value Sym. Name + Addend
000000404fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
000000404fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
'PLT' relocation section at offset 0x400578 contains 48 bytes:
Offset Info Type Sym. Value Sym. Name + Addend
000000405000 000000000025 R_X86_64_IRELATIV 8014c0
000000405008 000300000007 R_X86_64_JUMP_SLO 0000000000000000 long_name + 0
```
We see `000000405008` and `000000405000` have been swapped. But if we look at the stubs:
```
$ objdump -d -j .plt repro.bolt
repro.bolt: file format elf64-x86-64
Disassembly of section .plt:
0000000000401020 <.plt>:
401020: ff 35 ca 3f 00 00 push 0x3fca(%rip) # 404ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
401026: ff 25 cc 3f 00 00 jmp *0x3fcc(%rip) # 404ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
40102c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000401030 <*ABS*+0x8014c0@plt>:
401030: ff 25 ca 3f 00 00 jmp *0x3fca(%rip) # 405000 <_GLOBAL_OFFSET_TABLE_+0x18>
401036: 68 01 00 00 00 push $0x1
40103b: e9 e0 ff ff ff jmp 401020 <.plt>
0000000000401040 :
401040: ff 25 c2 3f 00 00 jmp *0x3fc2(%rip) # 405008
401046: 68 00 00 00 00 push $0x0
40104b: e9 d0 ff ff ff jmp 401020 <.plt>
```
We see that `long_name` still pushes index `0` instead of `1`, and vice versa for `foo`.
Running the binary with `LD_BIND_NOW=1 ./repro.bolt` on the other hand works fine.
Contributor guide
Research direction
Start with the main.c and example.c reproducer and run the listed llvm-bolt, readelf, and objdump commands to compare relocation ordering with PLT stub indices. Trace BOLT's handling of .rela.plt and PLT stubs, then verify that lazy binding runs successfully for repro.bolt and that the relocation and pushed indices remain consistent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, linux
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100