Skip to content

Commit a28daa7

Browse files
authored
[BOLT][AArch64] Keep relocations for linker-relaxed instructions. NFCI (#129980)
We used to filter out relocations corresponding to NOP+ADR instruction pairs that were a result of linker "relaxation" optimization. However, these relocations will be useful for reversing the linker optimization. Keep the relocations and ignore them while symbolizing ADR instruction operands.
1 parent 6e7e46c commit a28daa7

File tree

2 files changed

+15
-27
lines changed

2 files changed

+15
-27
lines changed

bolt/lib/Core/Relocation.cpp

-23
Original file line numberDiff line numberDiff line change
@@ -271,22 +271,11 @@ static bool skipRelocationProcessAArch64(uint64_t &Type, uint64_t Contents) {
271271
return (Contents & 0xfc000000) == 0x14000000;
272272
};
273273

274-
auto IsAdr = [](uint64_t Contents) -> bool {
275-
// The bits 31-24 are 0b0xx10000
276-
return (Contents & 0x9f000000) == 0x10000000;
277-
};
278-
279274
auto IsAddImm = [](uint64_t Contents) -> bool {
280275
// The bits 30-23 are 0b00100010
281276
return (Contents & 0x7F800000) == 0x11000000;
282277
};
283278

284-
auto IsNop = [](uint64_t Contents) -> bool { return Contents == 0xd503201f; };
285-
286-
// The linker might eliminate the instruction and replace it with NOP, ignore
287-
if (IsNop(Contents))
288-
return true;
289-
290279
// The linker might relax ADRP+LDR instruction sequence for loading symbol
291280
// address from GOT table to ADRP+ADD sequence that would point to the
292281
// binary-local symbol. Change relocation type in order to process it right.
@@ -332,18 +321,6 @@ static bool skipRelocationProcessAArch64(uint64_t &Type, uint64_t Contents) {
332321
}
333322
}
334323

335-
// The linker might relax ADRP+ADD or ADRP+LDR sequences to the ADR+NOP
336-
switch (Type) {
337-
default:
338-
break;
339-
case ELF::R_AARCH64_ADR_PREL_PG_HI21:
340-
case ELF::R_AARCH64_ADD_ABS_LO12_NC:
341-
case ELF::R_AARCH64_ADR_GOT_PAGE:
342-
case ELF::R_AARCH64_LD64_GOT_LO12_NC:
343-
if (IsAdr(Contents))
344-
return true;
345-
}
346-
347324
return false;
348325
}
349326

bolt/lib/Target/AArch64/AArch64MCSymbolizer.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ bool AArch64MCSymbolizer::tryAddingSymbolicOperand(
3131
if (BC.MIB->isBranch(Inst) || BC.MIB->isCall(Inst))
3232
return false;
3333

34-
// TODO: add handling for linker "relaxation". At the moment, relocations
35-
// corresponding to "relaxed" instructions are excluded from BinaryFunction
36-
// relocation list.
37-
3834
const uint64_t InstOffset = InstAddress - Function.getAddress();
3935
const Relocation *Relocation = Function.getRelocationAt(InstOffset);
4036

@@ -49,6 +45,21 @@ bool AArch64MCSymbolizer::tryAddingSymbolicOperand(
4945
BC.MIB->getTargetExprFor(Inst, Expr, *Ctx, RelType)));
5046
};
5147

48+
// The linker can convert ADRP+ADD and ADRP+LDR instruction sequences into
49+
// NOP+ADR. After the conversion, the linker might keep the relocations and
50+
// if we try to symbolize ADR's operand using outdated relocations, we might
51+
// get unexpected results. Hence, we check for the conversion/relaxation, and
52+
// ignore the relocation. The symbolization is done based on the PC-relative
53+
// value of the operand instead.
54+
if (Relocation && BC.MIB->isADR(Inst)) {
55+
if (Relocation->Type == ELF::R_AARCH64_ADD_ABS_LO12_NC ||
56+
Relocation->Type == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
57+
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: ignoring relocation at 0x"
58+
<< Twine::utohexstr(InstAddress) << '\n');
59+
Relocation = nullptr;
60+
}
61+
}
62+
5263
if (Relocation) {
5364
addOperand(Relocation->Symbol, Relocation->Addend, Relocation->Type);
5465
return true;

0 commit comments

Comments
 (0)