@@ -196,7 +196,6 @@ class LinuxKernelRewriter final : public MetadataRewriter {
196
196
197
197
// / Section containing the Linux exception table.
198
198
ErrorOr<BinarySection &> ExceptionsSection = std::errc::bad_address;
199
- static constexpr size_t EXCEPTION_TABLE_ENTRY_SIZE = 12 ;
200
199
201
200
// / Functions with exception handling code.
202
201
DenseSet<BinaryFunction *> FunctionsWithExceptions;
@@ -225,6 +224,17 @@ class LinuxKernelRewriter final : public MetadataRewriter {
225
224
ErrorOr<BinarySection &> PCIFixupSection = std::errc::bad_address;
226
225
static constexpr size_t PCI_FIXUP_ENTRY_SIZE = 16 ;
227
226
227
+ size_t getExceptionTableEntrySize () {
228
+ switch (BC.TheTriple ->getArch ()) {
229
+ case llvm::Triple::x86_64:
230
+ return 12 ;
231
+ case llvm::Triple::aarch64:
232
+ return 8 ;
233
+ default :
234
+ llvm_unreachable (" Unsupported architecture" );
235
+ }
236
+ }
237
+
228
238
// / Process linux kernel special sections and their relocations.
229
239
void processLKSections ();
230
240
@@ -474,8 +484,8 @@ void LinuxKernelRewriter::processInstructionFixups() {
474
484
continue ;
475
485
476
486
Fixup.Section .addRelocation (Fixup.Offset , &Fixup.Label ,
477
- Fixup.IsPCRelative ? ELF::R_X86_64_PC32
478
- : ELF::R_X86_64_64 ,
487
+ Fixup.IsPCRelative ? Relocation::getPC32 ()
488
+ : Relocation::getAbs64 () ,
479
489
/* Addend*/ 0 );
480
490
}
481
491
}
@@ -998,7 +1008,7 @@ Error LinuxKernelRewriter::rewriteStaticCalls() {
998
1008
StaticCallSection->getAddress () +
999
1009
(Entry.ID - 1 ) * STATIC_CALL_ENTRY_SIZE;
1000
1010
StaticCallSection->addRelocation (EntryOffset, Entry.Label ,
1001
- ELF::R_X86_64_PC32 , /* Addend*/ 0 );
1011
+ Relocation::getPC32 () , /* Addend*/ 0 );
1002
1012
}
1003
1013
1004
1014
return Error::success ();
@@ -1023,7 +1033,8 @@ Error LinuxKernelRewriter::readExceptionTable() {
1023
1033
if (!ExceptionsSection)
1024
1034
return Error::success ();
1025
1035
1026
- if (ExceptionsSection->getSize () % EXCEPTION_TABLE_ENTRY_SIZE)
1036
+ size_t EntrySize = getExceptionTableEntrySize ();
1037
+ if (ExceptionsSection->getSize () % EntrySize)
1027
1038
return createStringError (errc::executable_format_error,
1028
1039
" exception table size error" );
1029
1040
@@ -1038,7 +1049,19 @@ Error LinuxKernelRewriter::readExceptionTable() {
1038
1049
SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1039
1050
const uint64_t FixupAddress =
1040
1051
SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1041
- const uint64_t Data = DE.getU32 (Cursor);
1052
+
1053
+ auto ReadData = [this , &DE, &Cursor]() {
1054
+ switch (BC.TheTriple ->getArch ()) {
1055
+ case llvm::Triple::x86_64:
1056
+ return DE.getU32 (Cursor);
1057
+ case llvm::Triple::aarch64:
1058
+ return 0U ;
1059
+ default :
1060
+ llvm_unreachable (" Unsupported architecture" );
1061
+ }
1062
+ };
1063
+
1064
+ const uint64_t Data = ReadData ();
1042
1065
1043
1066
// Consume the status of the cursor.
1044
1067
if (!Cursor)
@@ -1100,8 +1123,7 @@ Error LinuxKernelRewriter::readExceptionTable() {
1100
1123
}
1101
1124
}
1102
1125
1103
- BC.outs () << " BOLT-INFO: parsed "
1104
- << ExceptionsSection->getSize () / EXCEPTION_TABLE_ENTRY_SIZE
1126
+ BC.outs () << " BOLT-INFO: parsed " << ExceptionsSection->getSize () / EntrySize
1105
1127
<< " exception table entries\n " ;
1106
1128
1107
1129
return Error::success ();
@@ -1305,7 +1327,8 @@ Error LinuxKernelRewriter::rewriteBugTable() {
1305
1327
MCSymbol *Label =
1306
1328
BC.MIB ->getOrCreateInstLabel (Inst, " __BUG_" , BC.Ctx .get ());
1307
1329
const uint64_t EntryOffset = (ID - 1 ) * BUG_TABLE_ENTRY_SIZE;
1308
- BugTableSection->addRelocation (EntryOffset, Label, ELF::R_X86_64_PC32,
1330
+ BugTableSection->addRelocation (EntryOffset, Label,
1331
+ Relocation::getPC32 (),
1309
1332
/* Addend*/ 0 );
1310
1333
}
1311
1334
}
@@ -1315,7 +1338,8 @@ Error LinuxKernelRewriter::rewriteBugTable() {
1315
1338
for (const uint32_t ID : FunctionBugList[&BF]) {
1316
1339
if (!EmittedIDs.count (ID)) {
1317
1340
const uint64_t EntryOffset = (ID - 1 ) * BUG_TABLE_ENTRY_SIZE;
1318
- BugTableSection->addRelocation (EntryOffset, nullptr , ELF::R_X86_64_PC32,
1341
+ BugTableSection->addRelocation (EntryOffset, nullptr ,
1342
+ Relocation::getPC32 (),
1319
1343
/* Addend*/ 0 );
1320
1344
}
1321
1345
}
@@ -1589,6 +1613,41 @@ Error LinuxKernelRewriter::readPCIFixupTable() {
1589
1613
return Error::success ();
1590
1614
}
1591
1615
1616
+ static bool checkStaticKeysJumpInstSize (const BinaryContext &BC, size_t Size) {
1617
+ switch (BC.TheTriple ->getArch ()) {
1618
+ case llvm::Triple::x86_64:
1619
+ return Size == 2 || Size == 5 ;
1620
+ case llvm::Triple::aarch64:
1621
+ return Size == 4 ;
1622
+ default :
1623
+ llvm_unreachable (" Unsupported architecture" );
1624
+ }
1625
+ }
1626
+
1627
+ static bool checkStaticKeysJumpInstSize (const BinaryContext &BC, size_t Size,
1628
+ uint64_t &NumShort, uint64_t &NumLong) {
1629
+ switch (BC.TheTriple ->getArch ()) {
1630
+ case llvm::Triple::x86_64:
1631
+ if (Size == 2 ) {
1632
+ ++NumShort;
1633
+ return true ;
1634
+ }
1635
+ if (Size == 5 ) {
1636
+ ++NumLong;
1637
+ return true ;
1638
+ }
1639
+ return false ;
1640
+ case llvm::Triple::aarch64:
1641
+ if (Size == 4 ) {
1642
+ ++NumLong;
1643
+ return true ;
1644
+ }
1645
+ return false ;
1646
+ default :
1647
+ llvm_unreachable (" Unsupported architecture" );
1648
+ }
1649
+ }
1650
+
1592
1651
// / Runtime code modification used by static keys is the most ubiquitous
1593
1652
// / self-modifying feature of the Linux kernel. The idea is to eliminate the
1594
1653
// / condition check and associated conditional jump on a hot path if that
@@ -1719,7 +1778,7 @@ Error LinuxKernelRewriter::readStaticKeysJumpTable() {
1719
1778
JumpAddress);
1720
1779
1721
1780
const uint64_t Size = BC.computeInstructionSize (*Inst);
1722
- if (Size != 2 && Size != 5 ) {
1781
+ if (! checkStaticKeysJumpInstSize (BC, Size) ) {
1723
1782
return createStringError (
1724
1783
errc::executable_format_error,
1725
1784
" unexpected static keys jump size at address 0x%" PRIx64,
@@ -1805,11 +1864,7 @@ Error LinuxKernelRewriter::rewriteStaticKeysJumpTable() {
1805
1864
const bool IsBranch = Info.Likely ^ Info.InitValue ;
1806
1865
1807
1866
uint32_t Size = *BC.MIB ->getSize (Inst);
1808
- if (Size == 2 )
1809
- ++NumShort;
1810
- else if (Size == 5 )
1811
- ++NumLong;
1812
- else
1867
+ if (!checkStaticKeysJumpInstSize (BC, Size, NumShort, NumLong))
1813
1868
llvm_unreachable (" Wrong size for static keys jump instruction." );
1814
1869
1815
1870
MCInst NewInst;
@@ -1839,10 +1894,10 @@ Error LinuxKernelRewriter::rewriteStaticKeysJumpTable() {
1839
1894
StaticKeysJumpSection->getAddress () +
1840
1895
(EntryID - 1 ) * 16 ;
1841
1896
StaticKeysJumpSection->addRelocation (EntryOffset, Label,
1842
- ELF::R_X86_64_PC32 ,
1897
+ Relocation::getPC32 () ,
1843
1898
/* Addend*/ 0 );
1844
- StaticKeysJumpSection->addRelocation (EntryOffset + 4 , Target,
1845
- ELF::R_X86_64_PC32 , /* Addend*/ 0 );
1899
+ StaticKeysJumpSection->addRelocation (
1900
+ EntryOffset + 4 , Target, Relocation::getPC32 () , /* Addend*/ 0 );
1846
1901
}
1847
1902
}
1848
1903
}
@@ -1915,11 +1970,7 @@ Error LinuxKernelRewriter::updateStaticKeysJumpTablePostEmit() {
1915
1970
}
1916
1971
assert (BC.MIB ->isBranch (Inst) && " Branch instruction expected." );
1917
1972
1918
- if (Size == 2 )
1919
- ++NumShort;
1920
- else if (Size == 5 )
1921
- ++NumLong;
1922
- else
1973
+ if (!checkStaticKeysJumpInstSize (BC, Size, NumShort, NumLong))
1923
1974
llvm_unreachable (" Unexpected size for static keys jump instruction." );
1924
1975
1925
1976
// Check if we need to convert jump instruction into a nop.
0 commit comments