Skip to content

Commit 097ddd3

Browse files
authored
[BOLT] Fix relocations handling (#100890)
After porting BOLT to RISCV some of the relocations were broken on both AArch64 and X86. On AArch64 the example of broken relocations would be GOT, during handling them, we should replace the symbol to __BOLT_got_zero in order to address GOT entry, not the symbol that addresses this entry. This is done further in code, so it is too early to add rel here. On X86 it is a mistake to add relocations without addend. This is the exact problem that is raised on #97937. Due to different code generation I had to use gcc-generated yaml test, since with clang I wasn't able to reproduce problem. Added tests for both architectures and made the problematic condition riscV-specific.
1 parent 25acc16 commit 097ddd3

File tree

5 files changed

+369
-1
lines changed

5 files changed

+369
-1
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2612,7 +2612,7 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
26122612
Expected<StringRef> SectionName = Section->getName();
26132613
if (SectionName && !SectionName->empty())
26142614
ReferencedSection = BC->getUniqueSectionByName(*SectionName);
2615-
} else if (ReferencedSymbol && ContainingBF &&
2615+
} else if (BC->isRISCV() && ReferencedSymbol && ContainingBF &&
26162616
(cantFail(Symbol.getFlags()) & SymbolRef::SF_Absolute)) {
26172617
// This might be a relocation for an ABS symbols like __global_pointer$ on
26182618
// RISC-V
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
SECTIONS
2+
{
3+
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
4+
.note.gnu.build-id (0x400400):
5+
{
6+
build_id_note = ABSOLUTE(.);
7+
*(.note.gnu.build-id)
8+
}
9+
}

bolt/test/AArch64/build_id.c

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This test checks that referencing build_id through GOT table
2+
// would result in GOT access after disassembly, not directly
3+
// to build_id address.
4+
5+
// RUN: %clang %cflags -fuse-ld=lld -Wl,-T,%S/Inputs/build_id.ldscript -Wl,-q \
6+
// RUN: -Wl,--no-relax -Wl,--build-id=sha1 %s -o %t.exe
7+
// RUN: llvm-bolt -print-disasm --print-only=get_build_id %t.exe -o %t.bolt | \
8+
// RUN: FileCheck %s
9+
10+
// CHECK: adrp [[REG:x[0-28]+]], __BOLT_got_zero
11+
// CHECK: ldr x{{.*}}, [[[REG]], :lo12:__BOLT_got_zero{{.*}}]
12+
13+
struct build_id_note {
14+
char pad[16];
15+
char hash[20];
16+
};
17+
18+
extern const struct build_id_note build_id_note;
19+
20+
__attribute__((noinline)) char get_build_id() { return build_id_note.hash[0]; }
21+
22+
int main() {
23+
get_build_id();
24+
return 0;
25+
}

bolt/test/X86/Inputs/build_id.yaml

+326
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
--- !ELF
2+
FileHeader:
3+
Class: ELFCLASS64
4+
Data: ELFDATA2LSB
5+
Type: ET_EXEC
6+
Machine: EM_X86_64
7+
Entry: 0x4010A0
8+
ProgramHeaders:
9+
- Type: PT_PHDR
10+
Flags: [ PF_R ]
11+
VAddr: 0x400040
12+
Align: 0x8
13+
Offset: 0x40
14+
- Type: PT_INTERP
15+
Flags: [ PF_R ]
16+
FirstSec: .interp
17+
LastSec: .interp
18+
VAddr: 0x400444
19+
Offset: 0x444
20+
- Type: PT_LOAD
21+
Flags: [ PF_X, PF_R ]
22+
FirstSec: .init
23+
LastSec: .fini
24+
VAddr: 0x401000
25+
Align: 0x1000
26+
Offset: 0x1000
27+
- Type: PT_LOAD
28+
Flags: [ PF_R ]
29+
FirstSec: .rodata
30+
LastSec: .rodata
31+
VAddr: 0x402000
32+
Align: 0x1000
33+
Offset: 0x2000
34+
- Type: PT_LOAD
35+
Flags: [ PF_W, PF_R ]
36+
FirstSec: .init_array
37+
LastSec: .bss
38+
VAddr: 0x403DD8
39+
Align: 0x1000
40+
Offset: 0x2DD8
41+
- Type: PT_DYNAMIC
42+
Flags: [ PF_W, PF_R ]
43+
FirstSec: .dynamic
44+
LastSec: .dynamic
45+
VAddr: 0x403DE8
46+
Align: 0x8
47+
Offset: 0x2DE8
48+
- Type: PT_NOTE
49+
Flags: [ PF_R ]
50+
FirstSec: .note.gnu.build-id
51+
LastSec: .note.ABI-tag
52+
VAddr: 0x400400
53+
Align: 0x4
54+
Offset: 0x400
55+
Sections:
56+
- Name: .note.gnu.build-id
57+
Type: SHT_NOTE
58+
Flags: [ SHF_ALLOC ]
59+
Address: 0x400400
60+
AddressAlign: 0x4
61+
Offset: 0x400
62+
Notes:
63+
- Name: GNU
64+
Desc: 3C34F7D1612996940C48F98DC272543BC3C9C956
65+
Type: NT_PRPSINFO
66+
- Name: .note.ABI-tag
67+
Type: SHT_NOTE
68+
Flags: [ SHF_ALLOC ]
69+
Address: 0x400424
70+
AddressAlign: 0x4
71+
Notes:
72+
- Name: GNU
73+
Desc: '00000000030000000200000000000000'
74+
Type: NT_VERSION
75+
- Name: .interp
76+
Type: SHT_PROGBITS
77+
Flags: [ SHF_ALLOC ]
78+
Address: 0x400444
79+
AddressAlign: 0x1
80+
Content: 2F6C696236342F6C642D6C696E75782D7838362D36342E736F2E3200
81+
- Name: .gnu.hash
82+
Type: SHT_GNU_HASH
83+
Flags: [ SHF_ALLOC ]
84+
Address: 0x400460
85+
Link: .dynsym
86+
AddressAlign: 0x8
87+
Header:
88+
SymNdx: 0x7
89+
Shift2: 0x6
90+
BloomFilter: [ 0x810000 ]
91+
HashBuckets: [ 0x7, 0x0 ]
92+
HashValues: [ 0x6DCE65D1 ]
93+
- Name: .dynsym
94+
Type: SHT_DYNSYM
95+
Flags: [ SHF_ALLOC ]
96+
Address: 0x400488
97+
Link: .dynstr
98+
AddressAlign: 0x8
99+
- Name: .dynstr
100+
Type: SHT_STRTAB
101+
Flags: [ SHF_ALLOC ]
102+
Address: 0x400548
103+
AddressAlign: 0x1
104+
- Name: .gnu.version
105+
Type: SHT_GNU_versym
106+
Flags: [ SHF_ALLOC ]
107+
Address: 0x4005F2
108+
Link: .dynsym
109+
AddressAlign: 0x2
110+
Entries: [ 0, 2, 3, 1, 1, 4, 1, 2 ]
111+
- Name: .gnu.version_r
112+
Type: SHT_GNU_verneed
113+
Flags: [ SHF_ALLOC ]
114+
Address: 0x400608
115+
Link: .dynstr
116+
AddressAlign: 0x8
117+
Dependencies:
118+
- Version: 1
119+
File: libc.so.6
120+
Entries:
121+
- Name: GLIBC_2.3.4
122+
Hash: 157882740
123+
Flags: 0
124+
Other: 4
125+
- Name: GLIBC_2.34
126+
Hash: 110530996
127+
Flags: 0
128+
Other: 3
129+
- Name: GLIBC_2.2.5
130+
Hash: 157882997
131+
Flags: 0
132+
Other: 2
133+
- Name: .init
134+
Type: SHT_PROGBITS
135+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
136+
Address: 0x401000
137+
AddressAlign: 0x4
138+
Offset: 0x1000
139+
Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3
140+
- Name: .plt.sec
141+
Type: SHT_PROGBITS
142+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
143+
Address: 0x401060
144+
AddressAlign: 0x10
145+
EntSize: 0x10
146+
Content: F30F1EFAF2FF25AD2F00000F1F440000F30F1EFAF2FF25A52F00000F1F440000
147+
- Name: .text
148+
Type: SHT_PROGBITS
149+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
150+
Address: 0x401080
151+
AddressAlign: 0x10
152+
Content: F30F1EFA4883EC0831C0E80101000031C04883C408C3662E0F1F840000000000F30F1EFA31ED4989D15E4889E24883E4F050544531C031C9488D3DC1FFFFFFFF15132F0000F4662E0F1F840000000000488D3D612F0000488D055A2F00004839F87415488B05F62E00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D312F0000488D352A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05C52E00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803DED2E000000752B5548833DA22E0000004889E5740C488B3DCE2E0000E8E9FEFFFFE864FFFFFFC605C52E0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFF0F1F8000000000F30F1EFA415455488D2D660E000053488D1D6AF2FFFF4C8D6314660F1F4400000FB6134889EEBF0100000031C04883C301E8AAFEFFFF4C39E375E55BBF0A0000005D415CE987FEFFFF
153+
- Name: .fini
154+
Type: SHT_PROGBITS
155+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
156+
Address: 0x4011DC
157+
AddressAlign: 0x4
158+
Content: F30F1EFA4883EC084883C408C3
159+
- Name: .rodata
160+
Type: SHT_PROGBITS
161+
Flags: [ SHF_ALLOC ]
162+
Address: 0x402000
163+
AddressAlign: 0x4
164+
Offset: 0x2000
165+
Content: '0100020025303268687800'
166+
- Name: .init_array
167+
Type: SHT_INIT_ARRAY
168+
Flags: [ SHF_WRITE, SHF_ALLOC ]
169+
Address: 0x403DD8
170+
AddressAlign: 0x8
171+
EntSize: 0x8
172+
Offset: 0x2DD8
173+
Content: '8011400000000000'
174+
- Name: .fini_array
175+
Type: SHT_FINI_ARRAY
176+
Flags: [ SHF_WRITE, SHF_ALLOC ]
177+
Address: 0x403DE0
178+
AddressAlign: 0x8
179+
EntSize: 0x8
180+
Content: '4011400000000000'
181+
- Name: .dynamic
182+
Type: SHT_DYNAMIC
183+
Flags: [ SHF_WRITE, SHF_ALLOC ]
184+
Address: 0x403DE8
185+
Link: .dynstr
186+
AddressAlign: 0x8
187+
Entries:
188+
- Tag: DT_NEEDED
189+
Value: 0x37
190+
- Tag: DT_INIT
191+
Value: 0x401000
192+
- Tag: DT_FINI
193+
Value: 0x4011DC
194+
- Tag: DT_INIT_ARRAY
195+
Value: 0x403DD8
196+
- Tag: DT_INIT_ARRAYSZ
197+
Value: 0x8
198+
- Tag: DT_FINI_ARRAY
199+
Value: 0x403DE0
200+
- Tag: DT_FINI_ARRAYSZ
201+
Value: 0x8
202+
- Tag: DT_GNU_HASH
203+
Value: 0x400460
204+
- Tag: DT_STRTAB
205+
Value: 0x400548
206+
- Tag: DT_SYMTAB
207+
Value: 0x400488
208+
- Tag: DT_STRSZ
209+
Value: 0xA9
210+
- Tag: DT_SYMENT
211+
Value: 0x18
212+
- Tag: DT_DEBUG
213+
Value: 0x0
214+
- Tag: DT_PLTGOT
215+
Value: 0x404000
216+
- Tag: DT_PLTRELSZ
217+
Value: 0x30
218+
- Tag: DT_PLTREL
219+
Value: 0x7
220+
- Tag: DT_FLAGS
221+
Value: 0x8
222+
- Tag: DT_FLAGS_1
223+
Value: 0x8000001
224+
- Tag: DT_VERNEED
225+
Value: 0x400608
226+
- Tag: DT_VERNEEDNUM
227+
Value: 0x1
228+
- Tag: DT_VERSYM
229+
Value: 0x4005F2
230+
- Tag: DT_RELACOUNT
231+
Value: 0x3
232+
- Tag: DT_NULL
233+
Value: 0x0
234+
- Name: .data
235+
Type: SHT_PROGBITS
236+
Flags: [ SHF_WRITE, SHF_ALLOC ]
237+
Address: 0x404028
238+
AddressAlign: 0x8
239+
Content: '00000000000000003040400000000000'
240+
- Name: .tm_clone_table
241+
Type: SHT_PROGBITS
242+
Flags: [ SHF_WRITE, SHF_ALLOC ]
243+
Address: 0x404038
244+
AddressAlign: 0x8
245+
- Name: .bss
246+
Type: SHT_NOBITS
247+
Flags: [ SHF_WRITE, SHF_ALLOC ]
248+
Address: 0x404038
249+
AddressAlign: 0x1
250+
Size: 0x8
251+
- Name: .rela.text
252+
Type: SHT_RELA
253+
Flags: [ SHF_INFO_LINK ]
254+
Link: .symtab
255+
AddressAlign: 0x8
256+
Info: .text
257+
Relocations:
258+
- Offset: 0x40108B
259+
Symbol: print_build_id
260+
Type: R_X86_64_PLT32
261+
Addend: -4
262+
- Offset: 0x4010BB
263+
Symbol: main
264+
Type: R_X86_64_PC32
265+
Addend: -4
266+
- Offset: 0x4011A2
267+
Symbol: build_id_note
268+
Type: R_X86_64_PC32
269+
Addend: 12
270+
- Type: SectionHeaderTable
271+
Sections:
272+
- Name: .note.gnu.build-id
273+
- Name: .note.ABI-tag
274+
- Name: .interp
275+
- Name: .gnu.hash
276+
- Name: .dynsym
277+
- Name: .dynstr
278+
- Name: .gnu.version
279+
- Name: .gnu.version_r
280+
- Name: .init
281+
- Name: .plt.sec
282+
- Name: .text
283+
- Name: .rela.text
284+
- Name: .fini
285+
- Name: .rodata
286+
- Name: .init_array
287+
- Name: .fini_array
288+
- Name: .dynamic
289+
- Name: .data
290+
- Name: .tm_clone_table
291+
- Name: .bss
292+
- Name: .symtab
293+
- Name: .strtab
294+
- Name: .shstrtab
295+
Symbols:
296+
- Name: print_build_id
297+
Type: STT_FUNC
298+
Section: .text
299+
Binding: STB_GLOBAL
300+
Value: 0x401190
301+
Size: 0x49
302+
- Name: _end
303+
Section: .bss
304+
Binding: STB_GLOBAL
305+
Value: 0x404040
306+
- Name: _start
307+
Type: STT_FUNC
308+
Section: .text
309+
Binding: STB_GLOBAL
310+
Value: 0x4010A0
311+
Size: 0x26
312+
- Name: __bss_start
313+
Section: .bss
314+
Binding: STB_GLOBAL
315+
Value: 0x404038
316+
- Name: main
317+
Type: STT_FUNC
318+
Section: .text
319+
Binding: STB_GLOBAL
320+
Value: 0x401080
321+
Size: 0x16
322+
- Name: build_id_note
323+
Index: SHN_ABS
324+
Binding: STB_GLOBAL
325+
Value: 0x400400
326+
...

bolt/test/X86/build_id.test

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This test checks that relocation addend used to address build_id fields
2+
// is properly disassembled by BOLT.
3+
4+
RUN: yaml2obj %p/Inputs/build_id.yaml &> %t.exe
5+
RUN: llvm-bolt -print-disasm --print-only=print_build_id %t.exe -o %t.bolt | \
6+
RUN: FileCheck %s
7+
8+
CHECK: leaq build_id_note+16(%rip), %rbx

0 commit comments

Comments
 (0)