Skip to content

Commit 21684e3

Browse files
authored
[BOLT][Linux] Refactor reading of PC-relative addresses. NFCI (#120491)
Fix evaluation order problem identified in #119088.
1 parent 2886576 commit 21684e3

File tree

1 file changed

+97
-95
lines changed

1 file changed

+97
-95
lines changed

bolt/lib/Rewrite/LinuxKernelRewriter.cpp

Lines changed: 97 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,30 @@ inline raw_ostream &operator<<(raw_ostream &OS, const ORCState &E) {
123123

124124
namespace {
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+
126150
class 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() {
14021415
Error 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

Comments
 (0)