@@ -123,6 +123,30 @@ inline raw_ostream &operator<<(raw_ostream &OS, const ORCState &E) {
123123
124124namespace {
125125
126+ // / Extension to DataExtractor that supports reading addresses stored in
127+ // / PC-relative format.
128+ class AddressExtractor : public DataExtractor {
129+ uint64_t DataAddress;
130+
131+ public:
132+ AddressExtractor (StringRef Data, uint64_t DataAddress, bool IsLittleEndian,
133+ uint8_t AddressSize)
134+ : DataExtractor(Data, IsLittleEndian, AddressSize),
135+ DataAddress (DataAddress) {}
136+
137+ // / Extract 32-bit PC-relative address/pointer.
138+ uint64_t getPCRelAddress32 (Cursor &C) {
139+ const uint64_t Base = DataAddress + C.tell ();
140+ return Base + (int32_t )getU32 (C);
141+ }
142+
143+ // / Extract 64-bit PC-relative address/pointer.
144+ uint64_t getPCRelAddress64 (Cursor &C) {
145+ const uint64_t Base = DataAddress + C.tell ();
146+ return Base + (int64_t )getU64 (C);
147+ }
148+ };
149+
126150class LinuxKernelRewriter final : public MetadataRewriter {
127151 // / Information required for updating metadata referencing an instruction.
128152 struct InstructionFixup {
@@ -423,13 +447,13 @@ Error LinuxKernelRewriter::processSMPLocks() {
423447 return createStringError (errc::executable_format_error,
424448 " bad size of .smp_locks section" );
425449
426- DataExtractor DE = DataExtractor (SMPLocksSection->getContents (),
427- BC.AsmInfo ->isLittleEndian (),
428- BC.AsmInfo ->getCodePointerSize ());
429- DataExtractor ::Cursor Cursor (0 );
450+ AddressExtractor AE (SMPLocksSection->getContents (), SectionAddress ,
451+ BC.AsmInfo ->isLittleEndian (),
452+ BC.AsmInfo ->getCodePointerSize ());
453+ AddressExtractor ::Cursor Cursor (0 );
430454 while (Cursor && Cursor.tell () < SectionSize) {
431455 const uint64_t Offset = Cursor.tell ();
432- const uint64_t IP = SectionAddress + Offset + ( int32_t )DE. getU32 (Cursor);
456+ const uint64_t IP = AE. getPCRelAddress32 (Cursor);
433457
434458 // Consume the status of the cursor.
435459 if (!Cursor)
@@ -499,20 +523,17 @@ Error LinuxKernelRewriter::readORCTables() {
499523 return createStringError (errc::executable_format_error,
500524 " ORC entries number mismatch detected" );
501525
502- const uint64_t IPSectionAddress = ORCUnwindIPSection->getAddress ();
503- DataExtractor OrcDE = DataExtractor (ORCUnwindSection->getContents (),
504- BC.AsmInfo ->isLittleEndian (),
505- BC.AsmInfo ->getCodePointerSize ());
506- DataExtractor IPDE = DataExtractor (ORCUnwindIPSection->getContents (),
507- BC.AsmInfo ->isLittleEndian (),
508- BC.AsmInfo ->getCodePointerSize ());
526+ DataExtractor OrcDE (ORCUnwindSection->getContents (),
527+ BC.AsmInfo ->isLittleEndian (),
528+ BC.AsmInfo ->getCodePointerSize ());
529+ AddressExtractor IPAE (
530+ ORCUnwindIPSection->getContents (), ORCUnwindIPSection->getAddress (),
531+ BC.AsmInfo ->isLittleEndian (), BC.AsmInfo ->getCodePointerSize ());
509532 DataExtractor::Cursor ORCCursor (0 );
510533 DataExtractor::Cursor IPCursor (0 );
511534 uint64_t PrevIP = 0 ;
512535 for (uint32_t Index = 0 ; Index < NumORCEntries; ++Index) {
513- const uint64_t IP =
514- IPSectionAddress + IPCursor.tell () + (int32_t )IPDE.getU32 (IPCursor);
515-
536+ const uint64_t IP = IPAE.getPCRelAddress32 (IPCursor);
516537 // Consume the status of the cursor.
517538 if (!IPCursor)
518539 return createStringError (errc::executable_format_error,
@@ -856,15 +877,13 @@ Error LinuxKernelRewriter::validateORCTables() {
856877 if (!ORCUnwindIPSection)
857878 return Error::success ();
858879
859- const uint64_t IPSectionAddress = ORCUnwindIPSection->getAddress ();
860- DataExtractor IPDE = DataExtractor (ORCUnwindIPSection->getOutputContents (),
861- BC.AsmInfo ->isLittleEndian (),
862- BC.AsmInfo ->getCodePointerSize ());
863- DataExtractor::Cursor IPCursor (0 );
880+ AddressExtractor IPAE (
881+ ORCUnwindIPSection->getOutputContents (), ORCUnwindIPSection->getAddress (),
882+ BC.AsmInfo ->isLittleEndian (), BC.AsmInfo ->getCodePointerSize ());
883+ AddressExtractor::Cursor IPCursor (0 );
864884 uint64_t PrevIP = 0 ;
865885 for (uint32_t Index = 0 ; Index < NumORCEntries; ++Index) {
866- const uint64_t IP =
867- IPSectionAddress + IPCursor.tell () + (int32_t )IPDE.getU32 (IPCursor);
886+ const uint64_t IP = IPAE.getPCRelAddress32 (IPCursor);
868887 if (!IPCursor)
869888 return createStringError (errc::executable_format_error,
870889 " out of bounds while reading ORC IP table: %s" ,
@@ -916,16 +935,14 @@ Error LinuxKernelRewriter::readStaticCalls() {
916935 " static call table size error" );
917936
918937 const uint64_t SectionAddress = StaticCallSection->getAddress ();
919- DataExtractor DE (StaticCallSection->getContents (),
920- BC.AsmInfo ->isLittleEndian (),
921- BC.AsmInfo ->getCodePointerSize ());
922- DataExtractor ::Cursor Cursor (StaticCallTableAddress - SectionAddress);
938+ AddressExtractor AE (StaticCallSection->getContents (), SectionAddress ,
939+ BC.AsmInfo ->isLittleEndian (),
940+ BC.AsmInfo ->getCodePointerSize ());
941+ AddressExtractor ::Cursor Cursor (StaticCallTableAddress - SectionAddress);
923942 uint32_t EntryID = 0 ;
924943 while (Cursor && Cursor.tell () < Stop->getAddress () - SectionAddress) {
925- const uint64_t CallAddress =
926- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
927- const uint64_t KeyAddress =
928- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
944+ const uint64_t CallAddress = AE.getPCRelAddress32 (Cursor);
945+ const uint64_t KeyAddress = AE.getPCRelAddress32 (Cursor);
929946
930947 // Consume the status of the cursor.
931948 if (!Cursor)
@@ -1027,18 +1044,15 @@ Error LinuxKernelRewriter::readExceptionTable() {
10271044 return createStringError (errc::executable_format_error,
10281045 " exception table size error" );
10291046
1030- const uint64_t SectionAddress = ExceptionsSection->getAddress ();
1031- DataExtractor DE (ExceptionsSection->getContents (),
1032- BC.AsmInfo ->isLittleEndian (),
1033- BC.AsmInfo ->getCodePointerSize ());
1034- DataExtractor::Cursor Cursor (0 );
1047+ AddressExtractor AE (
1048+ ExceptionsSection->getContents (), ExceptionsSection->getAddress (),
1049+ BC.AsmInfo ->isLittleEndian (), BC.AsmInfo ->getCodePointerSize ());
1050+ AddressExtractor::Cursor Cursor (0 );
10351051 uint32_t EntryID = 0 ;
10361052 while (Cursor && Cursor.tell () < ExceptionsSection->getSize ()) {
1037- const uint64_t InstAddress =
1038- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1039- const uint64_t FixupAddress =
1040- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1041- const uint64_t Data = DE.getU32 (Cursor);
1053+ const uint64_t InstAddress = AE.getPCRelAddress32 (Cursor);
1054+ const uint64_t FixupAddress = AE.getPCRelAddress32 (Cursor);
1055+ const uint64_t Data = AE.getU32 (Cursor);
10421056
10431057 // Consume the status of the cursor.
10441058 if (!Cursor)
@@ -1134,9 +1148,9 @@ Error LinuxKernelRewriter::readParaInstructions() {
11341148 if (!ParavirtualPatchSection)
11351149 return Error::success ();
11361150
1137- DataExtractor DE = DataExtractor (ParavirtualPatchSection->getContents (),
1138- BC.AsmInfo ->isLittleEndian (),
1139- BC.AsmInfo ->getCodePointerSize ());
1151+ DataExtractor DE (ParavirtualPatchSection->getContents (),
1152+ BC.AsmInfo ->isLittleEndian (),
1153+ BC.AsmInfo ->getCodePointerSize ());
11401154 uint32_t EntryID = 0 ;
11411155 DataExtractor::Cursor Cursor (0 );
11421156 while (Cursor && !DE.eof (Cursor)) {
@@ -1235,15 +1249,14 @@ Error LinuxKernelRewriter::readBugTable() {
12351249 return createStringError (errc::executable_format_error,
12361250 " bug table size error" );
12371251
1238- const uint64_t SectionAddress = BugTableSection-> getAddress ();
1239- DataExtractor DE ( BugTableSection->getContents (), BC. AsmInfo -> isLittleEndian (),
1240- BC.AsmInfo ->getCodePointerSize ());
1241- DataExtractor ::Cursor Cursor (0 );
1252+ AddressExtractor AE (
1253+ BugTableSection->getContents (), BugTableSection-> getAddress (),
1254+ BC. AsmInfo -> isLittleEndian (), BC.AsmInfo ->getCodePointerSize ());
1255+ AddressExtractor ::Cursor Cursor (0 );
12421256 uint32_t EntryID = 0 ;
12431257 while (Cursor && Cursor.tell () < BugTableSection->getSize ()) {
12441258 const uint64_t Pos = Cursor.tell ();
1245- const uint64_t InstAddress =
1246- SectionAddress + Pos + (int32_t )DE.getU32 (Cursor);
1259+ const uint64_t InstAddress = AE.getPCRelAddress32 (Cursor);
12471260 Cursor.seek (Pos + BUG_TABLE_ENTRY_SIZE);
12481261
12491262 if (!Cursor)
@@ -1402,23 +1415,20 @@ Error LinuxKernelRewriter::readAltInstructions() {
14021415Error LinuxKernelRewriter::tryReadAltInstructions (uint32_t AltInstFeatureSize,
14031416 bool AltInstHasPadLen,
14041417 bool ParseOnly) {
1405- const uint64_t Address = AltInstrSection-> getAddress ();
1406- DataExtractor DE = DataExtractor ( AltInstrSection->getContents (),
1407- BC.AsmInfo ->isLittleEndian (),
1408- BC. AsmInfo -> getCodePointerSize () );
1418+ AddressExtractor AE (
1419+ AltInstrSection->getContents (), AltInstrSection-> getAddress (),
1420+ BC.AsmInfo ->isLittleEndian (), BC. AsmInfo -> getCodePointerSize ());
1421+ AddressExtractor::Cursor Cursor ( 0 );
14091422 uint64_t EntryID = 0 ;
1410- DataExtractor::Cursor Cursor (0 );
1411- while (Cursor && !DE.eof (Cursor)) {
1412- const uint64_t OrgInstAddress =
1413- Address + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1414- const uint64_t AltInstAddress =
1415- Address + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1416- const uint64_t Feature = DE.getUnsigned (Cursor, AltInstFeatureSize);
1417- const uint8_t OrgSize = DE.getU8 (Cursor);
1418- const uint8_t AltSize = DE.getU8 (Cursor);
1423+ while (Cursor && !AE.eof (Cursor)) {
1424+ const uint64_t OrgInstAddress = AE.getPCRelAddress32 (Cursor);
1425+ const uint64_t AltInstAddress = AE.getPCRelAddress32 (Cursor);
1426+ const uint64_t Feature = AE.getUnsigned (Cursor, AltInstFeatureSize);
1427+ const uint8_t OrgSize = AE.getU8 (Cursor);
1428+ const uint8_t AltSize = AE.getU8 (Cursor);
14191429
14201430 // Older kernels may have the padlen field.
1421- const uint8_t PadLen = AltInstHasPadLen ? DE .getU8 (Cursor) : 0 ;
1431+ const uint8_t PadLen = AltInstHasPadLen ? AE .getU8 (Cursor) : 0 ;
14221432
14231433 if (!Cursor)
14241434 return createStringError (
@@ -1537,19 +1547,17 @@ Error LinuxKernelRewriter::readPCIFixupTable() {
15371547 return createStringError (errc::executable_format_error,
15381548 " PCI fixup table size error" );
15391549
1540- const uint64_t Address = PCIFixupSection-> getAddress ();
1541- DataExtractor DE = DataExtractor ( PCIFixupSection->getContents (),
1542- BC.AsmInfo ->isLittleEndian (),
1543- BC. AsmInfo -> getCodePointerSize () );
1550+ AddressExtractor AE (
1551+ PCIFixupSection->getContents (), PCIFixupSection-> getAddress (),
1552+ BC.AsmInfo ->isLittleEndian (), BC. AsmInfo -> getCodePointerSize ());
1553+ AddressExtractor::Cursor Cursor ( 0 );
15441554 uint64_t EntryID = 0 ;
1545- DataExtractor::Cursor Cursor (0 );
1546- while (Cursor && !DE.eof (Cursor)) {
1547- const uint16_t Vendor = DE.getU16 (Cursor);
1548- const uint16_t Device = DE.getU16 (Cursor);
1549- const uint32_t Class = DE.getU32 (Cursor);
1550- const uint32_t ClassShift = DE.getU32 (Cursor);
1551- const uint64_t HookAddress =
1552- Address + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1555+ while (Cursor && !AE.eof (Cursor)) {
1556+ const uint16_t Vendor = AE.getU16 (Cursor);
1557+ const uint16_t Device = AE.getU16 (Cursor);
1558+ const uint32_t Class = AE.getU32 (Cursor);
1559+ const uint32_t ClassShift = AE.getU32 (Cursor);
1560+ const uint64_t HookAddress = AE.getPCRelAddress32 (Cursor);
15531561
15541562 if (!Cursor)
15551563 return createStringError (errc::executable_format_error,
@@ -1654,18 +1662,15 @@ Error LinuxKernelRewriter::readStaticKeysJumpTable() {
16541662 " static keys jump table size error" );
16551663
16561664 const uint64_t SectionAddress = StaticKeysJumpSection->getAddress ();
1657- DataExtractor DE (StaticKeysJumpSection->getContents (),
1658- BC.AsmInfo ->isLittleEndian (),
1659- BC.AsmInfo ->getCodePointerSize ());
1660- DataExtractor ::Cursor Cursor (StaticKeysJumpTableAddress - SectionAddress);
1665+ AddressExtractor AE (StaticKeysJumpSection->getContents (), SectionAddress ,
1666+ BC.AsmInfo ->isLittleEndian (),
1667+ BC.AsmInfo ->getCodePointerSize ());
1668+ AddressExtractor ::Cursor Cursor (StaticKeysJumpTableAddress - SectionAddress);
16611669 uint32_t EntryID = 0 ;
16621670 while (Cursor && Cursor.tell () < Stop->getAddress () - SectionAddress) {
1663- const uint64_t JumpAddress =
1664- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1665- const uint64_t TargetAddress =
1666- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1667- const uint64_t KeyAddress =
1668- SectionAddress + Cursor.tell () + (int64_t )DE.getU64 (Cursor);
1671+ const uint64_t JumpAddress = AE.getPCRelAddress32 (Cursor);
1672+ const uint64_t TargetAddress = AE.getPCRelAddress32 (Cursor);
1673+ const uint64_t KeyAddress = AE.getPCRelAddress64 (Cursor);
16691674
16701675 // Consume the status of the cursor.
16711676 if (!Cursor)
@@ -1859,21 +1864,18 @@ Error LinuxKernelRewriter::updateStaticKeysJumpTablePostEmit() {
18591864 return Error::success ();
18601865
18611866 const uint64_t SectionAddress = StaticKeysJumpSection->getAddress ();
1862- DataExtractor DE (StaticKeysJumpSection->getOutputContents (),
1863- BC.AsmInfo ->isLittleEndian (),
1864- BC.AsmInfo ->getCodePointerSize ());
1865- DataExtractor ::Cursor Cursor (StaticKeysJumpTableAddress - SectionAddress);
1867+ AddressExtractor AE (StaticKeysJumpSection->getOutputContents (),
1868+ SectionAddress, BC.AsmInfo ->isLittleEndian (),
1869+ BC.AsmInfo ->getCodePointerSize ());
1870+ AddressExtractor ::Cursor Cursor (StaticKeysJumpTableAddress - SectionAddress);
18661871 const BinaryData *Stop = BC.getBinaryDataByName (" __stop___jump_table" );
18671872 uint32_t EntryID = 0 ;
18681873 uint64_t NumShort = 0 ;
18691874 uint64_t NumLong = 0 ;
18701875 while (Cursor && Cursor.tell () < Stop->getAddress () - SectionAddress) {
1871- const uint64_t JumpAddress =
1872- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1873- const uint64_t TargetAddress =
1874- SectionAddress + Cursor.tell () + (int32_t )DE.getU32 (Cursor);
1875- const uint64_t KeyAddress =
1876- SectionAddress + Cursor.tell () + (int64_t )DE.getU64 (Cursor);
1876+ const uint64_t JumpAddress = AE.getPCRelAddress32 (Cursor);
1877+ const uint64_t TargetAddress = AE.getPCRelAddress32 (Cursor);
1878+ const uint64_t KeyAddress = AE.getPCRelAddress64 (Cursor);
18771879
18781880 // Consume the status of the cursor.
18791881 if (!Cursor)
0 commit comments