Skip to content

Commit 7ada12b

Browse files
maksfbFlightor
authored andcommitted
[BOLT][Linux] Refactor reading of PC-relative addresses. NFCI (#120491)
Fix evaluation order problem identified in llvm/llvm-project#119088.
1 parent 8233a8e commit 7ada12b

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
@@ -153,6 +153,30 @@ inline raw_ostream &operator<<(raw_ostream &OS, const ORCState &E) {
153153

154154
namespace {
155155

156+
/// Extension to DataExtractor that supports reading addresses stored in
157+
/// PC-relative format.
158+
class AddressExtractor : public DataExtractor {
159+
uint64_t DataAddress;
160+
161+
public:
162+
AddressExtractor(StringRef Data, uint64_t DataAddress, bool IsLittleEndian,
163+
uint8_t AddressSize)
164+
: DataExtractor(Data, IsLittleEndian, AddressSize),
165+
DataAddress(DataAddress) {}
166+
167+
/// Extract 32-bit PC-relative address/pointer.
168+
uint64_t getPCRelAddress32(Cursor &C) {
169+
const uint64_t Base = DataAddress + C.tell();
170+
return Base + (int32_t)getU32(C);
171+
}
172+
173+
/// Extract 64-bit PC-relative address/pointer.
174+
uint64_t getPCRelAddress64(Cursor &C) {
175+
const uint64_t Base = DataAddress + C.tell();
176+
return Base + (int64_t)getU64(C);
177+
}
178+
};
179+
156180
class LinuxKernelRewriter final : public MetadataRewriter {
157181
LKVersion LinuxKernelVersion;
158182

@@ -482,13 +506,13 @@ Error LinuxKernelRewriter::processSMPLocks() {
482506
return createStringError(errc::executable_format_error,
483507
"bad size of .smp_locks section");
484508

485-
DataExtractor DE = DataExtractor(SMPLocksSection->getContents(),
486-
BC.AsmInfo->isLittleEndian(),
487-
BC.AsmInfo->getCodePointerSize());
488-
DataExtractor::Cursor Cursor(0);
509+
AddressExtractor AE(SMPLocksSection->getContents(), SectionAddress,
510+
BC.AsmInfo->isLittleEndian(),
511+
BC.AsmInfo->getCodePointerSize());
512+
AddressExtractor::Cursor Cursor(0);
489513
while (Cursor && Cursor.tell() < SectionSize) {
490514
const uint64_t Offset = Cursor.tell();
491-
const uint64_t IP = SectionAddress + Offset + (int32_t)DE.getU32(Cursor);
515+
const uint64_t IP = AE.getPCRelAddress32(Cursor);
492516

493517
// Consume the status of the cursor.
494518
if (!Cursor)
@@ -558,20 +582,17 @@ Error LinuxKernelRewriter::readORCTables() {
558582
return createStringError(errc::executable_format_error,
559583
"ORC entries number mismatch detected");
560584

561-
const uint64_t IPSectionAddress = ORCUnwindIPSection->getAddress();
562-
DataExtractor OrcDE = DataExtractor(ORCUnwindSection->getContents(),
563-
BC.AsmInfo->isLittleEndian(),
564-
BC.AsmInfo->getCodePointerSize());
565-
DataExtractor IPDE = DataExtractor(ORCUnwindIPSection->getContents(),
566-
BC.AsmInfo->isLittleEndian(),
567-
BC.AsmInfo->getCodePointerSize());
585+
DataExtractor OrcDE(ORCUnwindSection->getContents(),
586+
BC.AsmInfo->isLittleEndian(),
587+
BC.AsmInfo->getCodePointerSize());
588+
AddressExtractor IPAE(
589+
ORCUnwindIPSection->getContents(), ORCUnwindIPSection->getAddress(),
590+
BC.AsmInfo->isLittleEndian(), BC.AsmInfo->getCodePointerSize());
568591
DataExtractor::Cursor ORCCursor(0);
569592
DataExtractor::Cursor IPCursor(0);
570593
uint64_t PrevIP = 0;
571594
for (uint32_t Index = 0; Index < NumORCEntries; ++Index) {
572-
const uint64_t IP =
573-
IPSectionAddress + IPCursor.tell() + (int32_t)IPDE.getU32(IPCursor);
574-
595+
const uint64_t IP = IPAE.getPCRelAddress32(IPCursor);
575596
// Consume the status of the cursor.
576597
if (!IPCursor)
577598
return createStringError(errc::executable_format_error,
@@ -915,15 +936,13 @@ Error LinuxKernelRewriter::validateORCTables() {
915936
if (!ORCUnwindIPSection)
916937
return Error::success();
917938

918-
const uint64_t IPSectionAddress = ORCUnwindIPSection->getAddress();
919-
DataExtractor IPDE = DataExtractor(ORCUnwindIPSection->getOutputContents(),
920-
BC.AsmInfo->isLittleEndian(),
921-
BC.AsmInfo->getCodePointerSize());
922-
DataExtractor::Cursor IPCursor(0);
939+
AddressExtractor IPAE(
940+
ORCUnwindIPSection->getOutputContents(), ORCUnwindIPSection->getAddress(),
941+
BC.AsmInfo->isLittleEndian(), BC.AsmInfo->getCodePointerSize());
942+
AddressExtractor::Cursor IPCursor(0);
923943
uint64_t PrevIP = 0;
924944
for (uint32_t Index = 0; Index < NumORCEntries; ++Index) {
925-
const uint64_t IP =
926-
IPSectionAddress + IPCursor.tell() + (int32_t)IPDE.getU32(IPCursor);
945+
const uint64_t IP = IPAE.getPCRelAddress32(IPCursor);
927946
if (!IPCursor)
928947
return createStringError(errc::executable_format_error,
929948
"out of bounds while reading ORC IP table: %s",
@@ -975,16 +994,14 @@ Error LinuxKernelRewriter::readStaticCalls() {
975994
"static call table size error");
976995

977996
const uint64_t SectionAddress = StaticCallSection->getAddress();
978-
DataExtractor DE(StaticCallSection->getContents(),
979-
BC.AsmInfo->isLittleEndian(),
980-
BC.AsmInfo->getCodePointerSize());
981-
DataExtractor::Cursor Cursor(StaticCallTableAddress - SectionAddress);
997+
AddressExtractor AE(StaticCallSection->getContents(), SectionAddress,
998+
BC.AsmInfo->isLittleEndian(),
999+
BC.AsmInfo->getCodePointerSize());
1000+
AddressExtractor::Cursor Cursor(StaticCallTableAddress - SectionAddress);
9821001
uint32_t EntryID = 0;
9831002
while (Cursor && Cursor.tell() < Stop->getAddress() - SectionAddress) {
984-
const uint64_t CallAddress =
985-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
986-
const uint64_t KeyAddress =
987-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1003+
const uint64_t CallAddress = AE.getPCRelAddress32(Cursor);
1004+
const uint64_t KeyAddress = AE.getPCRelAddress32(Cursor);
9881005

9891006
// Consume the status of the cursor.
9901007
if (!Cursor)
@@ -1086,18 +1103,15 @@ Error LinuxKernelRewriter::readExceptionTable() {
10861103
return createStringError(errc::executable_format_error,
10871104
"exception table size error");
10881105

1089-
const uint64_t SectionAddress = ExceptionsSection->getAddress();
1090-
DataExtractor DE(ExceptionsSection->getContents(),
1091-
BC.AsmInfo->isLittleEndian(),
1092-
BC.AsmInfo->getCodePointerSize());
1093-
DataExtractor::Cursor Cursor(0);
1106+
AddressExtractor AE(
1107+
ExceptionsSection->getContents(), ExceptionsSection->getAddress(),
1108+
BC.AsmInfo->isLittleEndian(), BC.AsmInfo->getCodePointerSize());
1109+
AddressExtractor::Cursor Cursor(0);
10941110
uint32_t EntryID = 0;
10951111
while (Cursor && Cursor.tell() < ExceptionsSection->getSize()) {
1096-
const uint64_t InstAddress =
1097-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1098-
const uint64_t FixupAddress =
1099-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1100-
const uint64_t Data = DE.getU32(Cursor);
1112+
const uint64_t InstAddress = AE.getPCRelAddress32(Cursor);
1113+
const uint64_t FixupAddress = AE.getPCRelAddress32(Cursor);
1114+
const uint64_t Data = AE.getU32(Cursor);
11011115

11021116
// Consume the status of the cursor.
11031117
if (!Cursor)
@@ -1193,9 +1207,9 @@ Error LinuxKernelRewriter::readParaInstructions() {
11931207
if (!ParavirtualPatchSection)
11941208
return Error::success();
11951209

1196-
DataExtractor DE = DataExtractor(ParavirtualPatchSection->getContents(),
1197-
BC.AsmInfo->isLittleEndian(),
1198-
BC.AsmInfo->getCodePointerSize());
1210+
DataExtractor DE(ParavirtualPatchSection->getContents(),
1211+
BC.AsmInfo->isLittleEndian(),
1212+
BC.AsmInfo->getCodePointerSize());
11991213
uint32_t EntryID = 0;
12001214
DataExtractor::Cursor Cursor(0);
12011215
while (Cursor && !DE.eof(Cursor)) {
@@ -1294,15 +1308,14 @@ Error LinuxKernelRewriter::readBugTable() {
12941308
return createStringError(errc::executable_format_error,
12951309
"bug table size error");
12961310

1297-
const uint64_t SectionAddress = BugTableSection->getAddress();
1298-
DataExtractor DE(BugTableSection->getContents(), BC.AsmInfo->isLittleEndian(),
1299-
BC.AsmInfo->getCodePointerSize());
1300-
DataExtractor::Cursor Cursor(0);
1311+
AddressExtractor AE(
1312+
BugTableSection->getContents(), BugTableSection->getAddress(),
1313+
BC.AsmInfo->isLittleEndian(), BC.AsmInfo->getCodePointerSize());
1314+
AddressExtractor::Cursor Cursor(0);
13011315
uint32_t EntryID = 0;
13021316
while (Cursor && Cursor.tell() < BugTableSection->getSize()) {
13031317
const uint64_t Pos = Cursor.tell();
1304-
const uint64_t InstAddress =
1305-
SectionAddress + Pos + (int32_t)DE.getU32(Cursor);
1318+
const uint64_t InstAddress = AE.getPCRelAddress32(Cursor);
13061319
Cursor.seek(Pos + BUG_TABLE_ENTRY_SIZE);
13071320

13081321
if (!Cursor)
@@ -1461,23 +1474,20 @@ Error LinuxKernelRewriter::readAltInstructions() {
14611474
Error LinuxKernelRewriter::tryReadAltInstructions(uint32_t AltInstFeatureSize,
14621475
bool AltInstHasPadLen,
14631476
bool ParseOnly) {
1464-
const uint64_t Address = AltInstrSection->getAddress();
1465-
DataExtractor DE = DataExtractor(AltInstrSection->getContents(),
1466-
BC.AsmInfo->isLittleEndian(),
1467-
BC.AsmInfo->getCodePointerSize());
1477+
AddressExtractor AE(
1478+
AltInstrSection->getContents(), AltInstrSection->getAddress(),
1479+
BC.AsmInfo->isLittleEndian(), BC.AsmInfo->getCodePointerSize());
1480+
AddressExtractor::Cursor Cursor(0);
14681481
uint64_t EntryID = 0;
1469-
DataExtractor::Cursor Cursor(0);
1470-
while (Cursor && !DE.eof(Cursor)) {
1471-
const uint64_t OrgInstAddress =
1472-
Address + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1473-
const uint64_t AltInstAddress =
1474-
Address + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1475-
const uint64_t Feature = DE.getUnsigned(Cursor, AltInstFeatureSize);
1476-
const uint8_t OrgSize = DE.getU8(Cursor);
1477-
const uint8_t AltSize = DE.getU8(Cursor);
1482+
while (Cursor && !AE.eof(Cursor)) {
1483+
const uint64_t OrgInstAddress = AE.getPCRelAddress32(Cursor);
1484+
const uint64_t AltInstAddress = AE.getPCRelAddress32(Cursor);
1485+
const uint64_t Feature = AE.getUnsigned(Cursor, AltInstFeatureSize);
1486+
const uint8_t OrgSize = AE.getU8(Cursor);
1487+
const uint8_t AltSize = AE.getU8(Cursor);
14781488

14791489
// Older kernels may have the padlen field.
1480-
const uint8_t PadLen = AltInstHasPadLen ? DE.getU8(Cursor) : 0;
1490+
const uint8_t PadLen = AltInstHasPadLen ? AE.getU8(Cursor) : 0;
14811491

14821492
if (!Cursor)
14831493
return createStringError(
@@ -1596,19 +1606,17 @@ Error LinuxKernelRewriter::readPCIFixupTable() {
15961606
return createStringError(errc::executable_format_error,
15971607
"PCI fixup table size error");
15981608

1599-
const uint64_t Address = PCIFixupSection->getAddress();
1600-
DataExtractor DE = DataExtractor(PCIFixupSection->getContents(),
1601-
BC.AsmInfo->isLittleEndian(),
1602-
BC.AsmInfo->getCodePointerSize());
1609+
AddressExtractor AE(
1610+
PCIFixupSection->getContents(), PCIFixupSection->getAddress(),
1611+
BC.AsmInfo->isLittleEndian(), BC.AsmInfo->getCodePointerSize());
1612+
AddressExtractor::Cursor Cursor(0);
16031613
uint64_t EntryID = 0;
1604-
DataExtractor::Cursor Cursor(0);
1605-
while (Cursor && !DE.eof(Cursor)) {
1606-
const uint16_t Vendor = DE.getU16(Cursor);
1607-
const uint16_t Device = DE.getU16(Cursor);
1608-
const uint32_t Class = DE.getU32(Cursor);
1609-
const uint32_t ClassShift = DE.getU32(Cursor);
1610-
const uint64_t HookAddress =
1611-
Address + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1614+
while (Cursor && !AE.eof(Cursor)) {
1615+
const uint16_t Vendor = AE.getU16(Cursor);
1616+
const uint16_t Device = AE.getU16(Cursor);
1617+
const uint32_t Class = AE.getU32(Cursor);
1618+
const uint32_t ClassShift = AE.getU32(Cursor);
1619+
const uint64_t HookAddress = AE.getPCRelAddress32(Cursor);
16121620

16131621
if (!Cursor)
16141622
return createStringError(errc::executable_format_error,
@@ -1713,18 +1721,15 @@ Error LinuxKernelRewriter::readStaticKeysJumpTable() {
17131721
"static keys jump table size error");
17141722

17151723
const uint64_t SectionAddress = StaticKeysJumpSection->getAddress();
1716-
DataExtractor DE(StaticKeysJumpSection->getContents(),
1717-
BC.AsmInfo->isLittleEndian(),
1718-
BC.AsmInfo->getCodePointerSize());
1719-
DataExtractor::Cursor Cursor(StaticKeysJumpTableAddress - SectionAddress);
1724+
AddressExtractor AE(StaticKeysJumpSection->getContents(), SectionAddress,
1725+
BC.AsmInfo->isLittleEndian(),
1726+
BC.AsmInfo->getCodePointerSize());
1727+
AddressExtractor::Cursor Cursor(StaticKeysJumpTableAddress - SectionAddress);
17201728
uint32_t EntryID = 0;
17211729
while (Cursor && Cursor.tell() < Stop->getAddress() - SectionAddress) {
1722-
const uint64_t JumpAddress =
1723-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1724-
const uint64_t TargetAddress =
1725-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1726-
const uint64_t KeyAddress =
1727-
SectionAddress + Cursor.tell() + (int64_t)DE.getU64(Cursor);
1730+
const uint64_t JumpAddress = AE.getPCRelAddress32(Cursor);
1731+
const uint64_t TargetAddress = AE.getPCRelAddress32(Cursor);
1732+
const uint64_t KeyAddress = AE.getPCRelAddress64(Cursor);
17281733

17291734
// Consume the status of the cursor.
17301735
if (!Cursor)
@@ -1918,21 +1923,18 @@ Error LinuxKernelRewriter::updateStaticKeysJumpTablePostEmit() {
19181923
return Error::success();
19191924

19201925
const uint64_t SectionAddress = StaticKeysJumpSection->getAddress();
1921-
DataExtractor DE(StaticKeysJumpSection->getOutputContents(),
1922-
BC.AsmInfo->isLittleEndian(),
1923-
BC.AsmInfo->getCodePointerSize());
1924-
DataExtractor::Cursor Cursor(StaticKeysJumpTableAddress - SectionAddress);
1926+
AddressExtractor AE(StaticKeysJumpSection->getOutputContents(),
1927+
SectionAddress, BC.AsmInfo->isLittleEndian(),
1928+
BC.AsmInfo->getCodePointerSize());
1929+
AddressExtractor::Cursor Cursor(StaticKeysJumpTableAddress - SectionAddress);
19251930
const BinaryData *Stop = BC.getBinaryDataByName("__stop___jump_table");
19261931
uint32_t EntryID = 0;
19271932
uint64_t NumShort = 0;
19281933
uint64_t NumLong = 0;
19291934
while (Cursor && Cursor.tell() < Stop->getAddress() - SectionAddress) {
1930-
const uint64_t JumpAddress =
1931-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1932-
const uint64_t TargetAddress =
1933-
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1934-
const uint64_t KeyAddress =
1935-
SectionAddress + Cursor.tell() + (int64_t)DE.getU64(Cursor);
1935+
const uint64_t JumpAddress = AE.getPCRelAddress32(Cursor);
1936+
const uint64_t TargetAddress = AE.getPCRelAddress32(Cursor);
1937+
const uint64_t KeyAddress = AE.getPCRelAddress64(Cursor);
19361938

19371939
// Consume the status of the cursor.
19381940
if (!Cursor)

0 commit comments

Comments
 (0)