@@ -1173,6 +1173,13 @@ bool BinaryFunction::disassemble() {
1173
1173
// basic block.
1174
1174
Labels[0 ] = Ctx->createNamedTempSymbol (" BB0" );
1175
1175
1176
+ // Map offsets in the function to a label that should always point to the
1177
+ // corresponding instruction. This is used for labels that shouldn't point to
1178
+ // the start of a basic block but always to a specific instruction. This is
1179
+ // used, for example, on RISC-V where %pcrel_lo relocations point to the
1180
+ // corresponding %pcrel_hi.
1181
+ LabelsMapType InstructionLabels;
1182
+
1176
1183
uint64_t Size = 0 ; // instruction size
1177
1184
for (uint64_t Offset = 0 ; Offset < getSize (); Offset += Size ) {
1178
1185
MCInst Instruction;
@@ -1329,9 +1336,23 @@ bool BinaryFunction::disassemble() {
1329
1336
ItrE = Relocations.lower_bound (Offset + Size );
1330
1337
Itr != ItrE; ++Itr) {
1331
1338
const Relocation &Relocation = Itr->second ;
1339
+ MCSymbol *Symbol = Relocation.Symbol ;
1340
+
1341
+ if (Relocation::isInstructionReference (Relocation.Type )) {
1342
+ uint64_t RefOffset = Relocation.Value - getAddress ();
1343
+ LabelsMapType::iterator LI = InstructionLabels.find (RefOffset);
1344
+
1345
+ if (LI == InstructionLabels.end ()) {
1346
+ Symbol = BC.Ctx ->createNamedTempSymbol ();
1347
+ InstructionLabels.emplace (RefOffset, Symbol);
1348
+ } else {
1349
+ Symbol = LI->second ;
1350
+ }
1351
+ }
1352
+
1332
1353
int64_t Value = Relocation.Value ;
1333
1354
const bool Result = BC.MIB ->replaceImmWithSymbolRef (
1334
- Instruction, Relocation. Symbol , Relocation.Addend , Ctx.get (), Value,
1355
+ Instruction, Symbol, Relocation.Addend , Ctx.get (), Value,
1335
1356
Relocation.Type );
1336
1357
(void )Result;
1337
1358
assert (Result && " cannot replace immediate with relocation" );
@@ -1366,6 +1387,13 @@ bool BinaryFunction::disassemble() {
1366
1387
addInstruction (Offset, std::move (Instruction));
1367
1388
}
1368
1389
1390
+ for (auto [Offset, Label] : InstructionLabels) {
1391
+ InstrMapType::iterator II = Instructions.find (Offset);
1392
+ assert (II != Instructions.end () && " reference to non-existing instruction" );
1393
+
1394
+ BC.MIB ->setLabel (II->second , Label);
1395
+ }
1396
+
1369
1397
// Reset symbolizer for the disassembler.
1370
1398
BC.SymbolicDisAsm ->setSymbolizer (nullptr );
1371
1399
@@ -1761,7 +1789,8 @@ bool BinaryFunction::postProcessIndirectBranches(
1761
1789
uint64_t LastJT = 0 ;
1762
1790
uint16_t LastJTIndexReg = BC.MIB ->getNoRegister ();
1763
1791
for (BinaryBasicBlock &BB : blocks ()) {
1764
- for (MCInst &Instr : BB) {
1792
+ for (BinaryBasicBlock::iterator II = BB.begin (); II != BB.end (); ++II) {
1793
+ MCInst &Instr = *II;
1765
1794
if (!BC.MIB ->isIndirectBranch (Instr))
1766
1795
continue ;
1767
1796
@@ -1789,7 +1818,7 @@ bool BinaryFunction::postProcessIndirectBranches(
1789
1818
const MCExpr *DispExpr;
1790
1819
MCInst *PCRelBaseInstr;
1791
1820
IndirectBranchType Type = BC.MIB ->analyzeIndirectBranch (
1792
- Instr, BB.begin (), BB. end () , PtrSize, MemLocInstr, BaseRegNum,
1821
+ Instr, BB.begin (), II , PtrSize, MemLocInstr, BaseRegNum,
1793
1822
IndexRegNum, DispValue, DispExpr, PCRelBaseInstr);
1794
1823
if (Type != IndirectBranchType::UNKNOWN || MemLocInstr != nullptr )
1795
1824
continue ;
@@ -4488,7 +4517,7 @@ void BinaryFunction::addRelocation(uint64_t Address, MCSymbol *Symbol,
4488
4517
uint64_t Offset = Address - getAddress ();
4489
4518
LLVM_DEBUG (dbgs () << " BOLT-DEBUG: addRelocation in "
4490
4519
<< formatv (" {0}@{1:x} against {2}\n " , *this , Offset,
4491
- Symbol->getName ()));
4520
+ ( Symbol ? Symbol ->getName () : " <undef> " )));
4492
4521
bool IsCI = BC.isAArch64 () && isInConstantIsland (Address);
4493
4522
std::map<uint64_t , Relocation> &Rels =
4494
4523
IsCI ? Islands->Relocations : Relocations;
0 commit comments