@@ -1457,7 +1457,7 @@ Error BinaryFunction::disassemble() {
1457
1457
if (BC.isAArch64 ())
1458
1458
handleAArch64IndirectCall (Instruction, Offset);
1459
1459
}
1460
- } else if (BC.isRISCV ()) {
1460
+ }else if (BC.isRISCV ()) {
1461
1461
// Check if there's a relocation associated with this instruction.
1462
1462
for (auto Itr = Relocations.lower_bound (Offset),
1463
1463
ItrE = Relocations.lower_bound (Offset + Size);
@@ -1466,15 +1466,7 @@ Error BinaryFunction::disassemble() {
1466
1466
MCSymbol *Symbol = Relocation.Symbol ;
1467
1467
1468
1468
if (Relocation::isInstructionReference (Relocation.Type )) {
1469
- uint64_t RefOffset = Relocation.Value - getAddress ();
1470
- LabelsMapType::iterator LI = InstructionLabels.find (RefOffset);
1471
-
1472
- if (LI == InstructionLabels.end ()) {
1473
- Symbol = BC.Ctx ->createNamedTempSymbol ();
1474
- InstructionLabels.emplace (RefOffset, Symbol);
1475
- } else {
1476
- Symbol = LI->second ;
1477
- }
1469
+ continue ;
1478
1470
}
1479
1471
1480
1472
uint64_t Addend = Relocation.Addend ;
@@ -1484,16 +1476,15 @@ Error BinaryFunction::disassemble() {
1484
1476
if (Relocation::isGOT (Relocation.Type )) {
1485
1477
assert (Relocation::isPCRelative (Relocation.Type ) &&
1486
1478
" GOT relocation must be PC-relative on RISC-V" );
1487
- Symbol = BC.registerNameAtAddress (" __BOLT_got_zero" , 0 , 0 , 0 );
1488
- Addend = Relocation.Value + Relocation.Offset + getAddress ();
1479
+ continue ;
1489
1480
}
1490
1481
int64_t Value = Relocation.Value ;
1491
1482
const bool Result = BC.MIB ->replaceImmWithSymbolRef (
1492
1483
Instruction, Symbol, Addend, Ctx.get (), Value, Relocation.Type );
1493
1484
(void )Result;
1494
1485
assert (Result && " cannot replace immediate with relocation" );
1495
1486
}
1496
- }
1487
+ }
1497
1488
1498
1489
add_instruction:
1499
1490
if (getDWARFLineTable ()) {
@@ -1514,14 +1505,97 @@ Error BinaryFunction::disassemble() {
1514
1505
1515
1506
addInstruction (Offset, std::move (Instruction));
1516
1507
}
1508
+ if (BC.isRISCV ()){
1509
+ for (auto CurInstrIt = Instructions.begin (); CurInstrIt != Instructions.end (); ++CurInstrIt) {
1510
+ uint64_t CurOffset = CurInstrIt->first ;
1511
+ if (const size_t DataInCodeSize = getSizeOfDataInCodeAt (CurOffset)) continue ;
1512
+
1513
+ if (MIB->isBranch (CurInstrIt->second ) || MIB->isCall (CurInstrIt->second )) continue ;
1514
+ if (MIB->isPseudo (CurInstrIt->second )) continue ;
1515
+ if (isZeroPaddingAt (CurInstrIt->first )) break ;
1516
+
1517
+ auto NextInstrIt = std::next (CurInstrIt);
1518
+ uint64_t NextOffset = (NextInstrIt != Instructions.end ()) ? NextInstrIt->first : getSize ();
1519
+ for (auto Itr = Relocations.lower_bound (CurOffset),
1520
+ ItrE = Relocations.lower_bound (NextOffset);
1521
+ Itr != ItrE; ++Itr) {
1522
+ Relocation &Relocation = Itr->second ;
1523
+ MCSymbol *Symbol = Relocation.Symbol ;
1524
+
1525
+ if (Relocation::isInstructionReference (Relocation.Type )) {
1526
+ uint64_t RefOffset = Relocation.Value - getAddress ();
1527
+ LabelsMapType::iterator LI = InstructionLabels.find (RefOffset);
1528
+
1529
+ if (LI == InstructionLabels.end ()) {
1530
+ Symbol = BC.Ctx ->createNamedTempSymbol ();
1531
+ InstructionLabels.emplace (RefOffset, Symbol);
1532
+ } else {
1533
+ Symbol = LI->second ;
1534
+ }
1535
+ }
1536
+
1537
+ uint64_t Addend = Relocation.Addend ;
1538
+
1539
+ // For GOT relocations, create a reference against GOT entry ignoring
1540
+ // the relocation symbol.
1541
+ if (Relocation::isGOT (Relocation.Type )) {
1542
+ assert (Relocation::isPCRelative (Relocation.Type ) &&
1543
+ " GOT relocation must be PC-relative on RISC-V" );
1544
+ // For RISC-V, we need to find the next instruction
1545
+ // that matches the current instruction's base register.
1546
+ auto NextInstrIt = std::next (CurInstrIt);
1547
+ unsigned CurReg = BC.MIB ->getBaseReg (CurInstrIt->second );
1548
+ while (NextInstrIt != Instructions.end ()) {
1549
+ MCInst &NextInst = NextInstrIt->second ;
1550
+ unsigned NextReg = BC.MIB ->getBaseReg (NextInst);
1551
+ // some case there exit extra auipc instruction
1552
+ // like auipc+auipc+ld instruction,so we need skip it
1553
+ if (CurReg == NextReg && !BC.MIB ->matchGotAuipcPair (NextInst)) {
1554
+ break ;
1555
+ }
1556
+ if (CurReg == NextReg && BC.MIB ->matchGotAuipcPair (NextInst)){
1557
+
1558
+ int64_t CurImm = 0 ;
1559
+ for (const MCOperand &Op : CurInstrIt->second ) {
1560
+ if (Op.isImm ()) {
1561
+ CurImm = Op.getImm ();
1562
+ break ;
1563
+ }
1564
+ }
1565
+ int64_t NextImm = 0 ;
1566
+ for (const MCOperand &Op : NextInstrIt->second ) {
1567
+ if (Op.isImm ()) {
1568
+ NextImm = Op.getImm ();
1569
+ break ;
1570
+ }
1571
+ }
1572
+ Relocation.Value = (CurImm << 12 ) + NextImm;
1573
+ break ;
1574
+ }
1575
+ NextInstrIt = std::next (NextInstrIt);
1576
+ }
1577
+ Symbol = BC.registerNameAtAddress (" __BOLT_got_zero" , 0 , 0 , 0 );
1578
+ Addend = Relocation.Value + Relocation.Offset + getAddress ();
1579
+
1580
+ }else if (!Relocation::isInstructionReference (Relocation.Type )) {
1581
+ continue ;
1582
+ }
1583
+ int64_t Value = Relocation.Value ;
1584
+ const bool Result = BC.MIB ->replaceImmWithSymbolRef (
1585
+ CurInstrIt->second , Symbol, Addend, Ctx.get (), Value, Relocation.Type );
1586
+ (void )Result;
1587
+ assert (Result && " cannot replace immediate with relocation" );
1588
+
1589
+ }
1590
+ }
1591
+ }
1517
1592
1518
1593
for (auto [Offset, Label] : InstructionLabels) {
1519
1594
InstrMapType::iterator II = Instructions.find (Offset);
1520
1595
assert (II != Instructions.end () && " reference to non-existing instruction" );
1521
1596
1522
1597
BC.MIB ->setInstLabel (II->second , Label);
1523
1598
}
1524
-
1525
1599
// Reset symbolizer for the disassembler.
1526
1600
BC.SymbolicDisAsm ->setSymbolizer (nullptr );
1527
1601
0 commit comments