Skip to content

Commit e4cbb77

Browse files
authored
[BOLT][AArch64] Fix symbolization of unoptimized TLS access (#134332)
TLS relocations may not have a valid BOLT symbol associated with them. While symbolizing the operand, we were checking for the symbol value, and since there was no symbol the check resulted in a crash. Handle TLS case while performing operand symbolization on AArch64.
1 parent e2092a4 commit e4cbb77

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,9 +2827,10 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
28272827
if (SymbolAddress == 0)
28282828
ReferencedSymbol = BC->registerNameAtAddress(SymbolName, 0, 0, 0);
28292829

2830-
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: forcing relocation against symbol "
2831-
<< ReferencedSymbol->getName() << " with addend "
2832-
<< Addend << '\n');
2830+
LLVM_DEBUG(
2831+
dbgs() << "BOLT-DEBUG: forcing relocation against symbol "
2832+
<< (ReferencedSymbol ? ReferencedSymbol->getName() : "<none>")
2833+
<< " with addend " << Addend << '\n');
28332834
} else if (ReferencedBF) {
28342835
ReferencedSymbol = ReferencedBF->getSymbol();
28352836
uint64_t RefFunctionOffset = 0;

bolt/lib/Target/AArch64/AArch64MCSymbolizer.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,26 +119,39 @@ AArch64MCSymbolizer::adjustRelocation(const Relocation &Rel,
119119
// The ADRP+LDR sequence was converted into ADRP+ADD. We are looking at the
120120
// second instruction and have to use the relocation type for ADD.
121121
AdjustedRel.Type = ELF::R_AARCH64_ADD_ABS_LO12_NC;
122-
} else {
123-
// For instructions that reference GOT, ignore the referenced symbol and
124-
// use value at the relocation site. FixRelaxationPass will look at
125-
// instruction pairs and will perform necessary adjustments.
122+
return AdjustedRel;
123+
}
124+
125+
// ADRP is a special case since the linker can leave the instruction opcode
126+
// intact and modify only the operand. We are doing our best to detect when
127+
// such conversion has happened without looking at the next instruction.
128+
//
129+
// If we detect that a page referenced by the ADRP cannot belong to GOT, and
130+
// that it matches the symbol from the relocation, then we can be certain
131+
// that the linker converted the GOT reference into the local one. Otherwise,
132+
// we leave the disambiguation resolution to FixRelaxationPass.
133+
//
134+
// Note that ADRP relaxation described above cannot happen for TLS relocation.
135+
// Since TLS relocations may not even have a valid symbol (not supported by
136+
// BOLT), we explicitly exclude them from the check.
137+
if (BC.MIB->isADRP(Inst) && Rel.Addend == 0 && !Relocation::isTLS(Rel.Type)) {
126138
ErrorOr<uint64_t> SymbolValue = BC.getSymbolValue(*Rel.Symbol);
127139
assert(SymbolValue && "Symbol value should be set");
128140
const uint64_t SymbolPageAddr = *SymbolValue & ~0xfffULL;
129141

130-
// Check if defined symbol and GOT are on the same page. If they are not,
131-
// disambiguate the operand.
132-
if (BC.MIB->isADRP(Inst) && Rel.Addend == 0 &&
133-
SymbolPageAddr == Rel.Value &&
142+
if (SymbolPageAddr == Rel.Value &&
134143
!isPageAddressValidForGOT(SymbolPageAddr)) {
135144
AdjustedRel.Type = ELF::R_AARCH64_ADR_PREL_PG_HI21;
136-
} else {
137-
AdjustedRel.Symbol = BC.registerNameAtAddress("__BOLT_got_zero", 0, 0, 0);
138-
AdjustedRel.Addend = Rel.Value;
145+
return AdjustedRel;
139146
}
140147
}
141148

149+
// For instructions that reference GOT, ignore the referenced symbol and
150+
// use value at the relocation site. FixRelaxationPass will look at
151+
// instruction pairs and will perform necessary adjustments.
152+
AdjustedRel.Symbol = BC.registerNameAtAddress("__BOLT_got_zero", 0, 0, 0);
153+
AdjustedRel.Addend = Rel.Value;
154+
142155
return AdjustedRel;
143156
}
144157

bolt/test/AArch64/tls.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,11 @@ int main() {
3434
// RUN: -target aarch64-linux -fuse-ld=lld \
3535
// RUN: -nostdlib
3636
// RUN: llvm-bolt %t_pie.exe -o %t.bolt
37+
38+
// RUN: %clang %cflags -fPIC -shared %s -o %t.so -Wl,-q -fuse-ld=lld
39+
// RUN: llvm-objdump -d -r --disassemble-symbols=main %t.so | FileCheck %s
40+
// RUN: llvm-bolt %t.so -o %t.bolt.so
41+
42+
// Verify that unoptimized TLS access was generated for shared object.
43+
// CHECK: adrp x0
44+
// CHECK-NEXT: R_AARCH64_TLSDESC_ADR_PAGE21 tbssstruct

0 commit comments

Comments
 (0)