Skip to content

Commit 5ac268a

Browse files
committed
Merge branch 'main' into add_LIBC_TYPES_HAS_INT128
2 parents dd143c5 + ef1eb03 commit 5ac268a

File tree

1,604 files changed

+39015
-16847
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,604 files changed

+39015
-16847
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @nikic
2828
/llvm/lib/Transforms/InstCombine/ @nikic
2929

30+
/clang/include/clang/Sema/Sema.h @Endilll
3031
/clang/test/CXX/drs/ @Endilll
3132
/clang/www/cxx_dr_status.html @Endilll
3233
/clang/www/make_cxx_dr_status @Endilll

.github/workflows/release-binaries.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ jobs:
3535
prepare:
3636
name: Prepare to build binaries
3737
runs-on: ubuntu-22.04
38+
if: github.repository == 'llvm/llvm-project'
3839
outputs:
3940
release-version: ${{ steps.vars.outputs.release-version }}
4041
flags: ${{ steps.vars.outputs.flags }}
@@ -85,6 +86,7 @@ jobs:
8586
name: "Fill Cache ${{ matrix.os }}"
8687
needs: prepare
8788
runs-on: ${{ matrix.os }}
89+
if: github.repository == 'llvm/llvm-project'
8890
strategy:
8991
matrix:
9092
os:
@@ -119,6 +121,7 @@ jobs:
119121
- prepare
120122
- fill-cache
121123
runs-on: ${{ matrix.target.runs-on }}
124+
if: github.repository == 'llvm/llvm-project'
122125
strategy:
123126
fail-fast: false
124127
matrix:

bolt/lib/Rewrite/LinuxKernelRewriter.cpp

Lines changed: 228 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,21 @@ using namespace bolt;
2727

2828
namespace opts {
2929

30+
static cl::opt<bool>
31+
AltInstHasPadLen("alt-inst-has-padlen",
32+
cl::desc("specify that .altinstructions has padlen field"),
33+
cl::init(false), cl::Hidden, cl::cat(BoltCategory));
34+
35+
static cl::opt<uint32_t>
36+
AltInstFeatureSize("alt-inst-feature-size",
37+
cl::desc("size of feature field in .altinstructions"),
38+
cl::init(2), cl::Hidden, cl::cat(BoltCategory));
39+
40+
static cl::opt<bool>
41+
DumpAltInstructions("dump-alt-instructions",
42+
cl::desc("dump Linux alternative instructions info"),
43+
cl::init(false), cl::Hidden, cl::cat(BoltCategory));
44+
3045
static cl::opt<bool>
3146
DumpExceptions("dump-linux-exceptions",
3247
cl::desc("dump Linux kernel exception table"),
@@ -157,6 +172,15 @@ class LinuxKernelRewriter final : public MetadataRewriter {
157172
/// Alignment of paravirtual patch structures.
158173
static constexpr size_t PARA_PATCH_ALIGN = 8;
159174

175+
/// .altinstructions section.
176+
ErrorOr<BinarySection &> AltInstrSection = std::errc::bad_address;
177+
178+
/// Section containing Linux bug table.
179+
ErrorOr<BinarySection &> BugTableSection = std::errc::bad_address;
180+
181+
/// Size of bug_entry struct.
182+
static constexpr size_t BUG_TABLE_ENTRY_SIZE = 12;
183+
160184
/// Insert an LKMarker for a given code pointer \p PC from a non-code section
161185
/// \p SectionName.
162186
void insertLKMarker(uint64_t PC, uint64_t SectionOffset,
@@ -172,9 +196,6 @@ class LinuxKernelRewriter final : public MetadataRewriter {
172196
/// Process __ksymtab and __ksymtab_gpl.
173197
void processLKKSymtab(bool IsGPL = false);
174198

175-
/// Process special linux kernel section, __bug_table.
176-
void processLKBugTable();
177-
178199
/// Process special linux kernel section, .smp_locks.
179200
void processLKSMPLocks();
180201

@@ -200,6 +221,11 @@ class LinuxKernelRewriter final : public MetadataRewriter {
200221
/// Paravirtual instruction patch sites.
201222
Error readParaInstructions();
202223

224+
Error readBugTable();
225+
226+
/// Read alternative instruction info from .altinstructions.
227+
Error readAltInstructions();
228+
203229
/// Mark instructions referenced by kernel metadata.
204230
Error markInstructions();
205231

@@ -224,6 +250,12 @@ class LinuxKernelRewriter final : public MetadataRewriter {
224250
if (Error E = readParaInstructions())
225251
return E;
226252

253+
if (Error E = readBugTable())
254+
return E;
255+
256+
if (Error E = readAltInstructions())
257+
return E;
258+
227259
return Error::success();
228260
}
229261

@@ -289,7 +321,6 @@ void LinuxKernelRewriter::processLKSections() {
289321
processLKPCIFixup();
290322
processLKKSymtab();
291323
processLKKSymtab(true);
292-
processLKBugTable();
293324
processLKSMPLocks();
294325
}
295326

@@ -356,37 +387,6 @@ void LinuxKernelRewriter::processLKKSymtab(bool IsGPL) {
356387
}
357388
}
358389

359-
/// Process __bug_table section.
360-
/// This section contains information useful for kernel debugging.
361-
/// Each entry in the section is a struct bug_entry that contains a pointer to
362-
/// the ud2 instruction corresponding to the bug, corresponding file name (both
363-
/// pointers use PC relative offset addressing), line number, and flags.
364-
/// The definition of the struct bug_entry can be found in
365-
/// `include/asm-generic/bug.h`
366-
void LinuxKernelRewriter::processLKBugTable() {
367-
ErrorOr<BinarySection &> SectionOrError =
368-
BC.getUniqueSectionByName("__bug_table");
369-
if (!SectionOrError)
370-
return;
371-
372-
const uint64_t SectionSize = SectionOrError->getSize();
373-
const uint64_t SectionAddress = SectionOrError->getAddress();
374-
assert((SectionSize % 12) == 0 &&
375-
"The size of the __bug_table section should be a multiple of 12");
376-
for (uint64_t I = 0; I < SectionSize; I += 12) {
377-
const uint64_t EntryAddress = SectionAddress + I;
378-
ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(EntryAddress, 4);
379-
assert(Offset &&
380-
"Reading valid PC-relative offset for a __bug_table entry");
381-
const int32_t SignedOffset = *Offset;
382-
const uint64_t RefAddress = EntryAddress + SignedOffset;
383-
assert(BC.getBinaryFunctionContainingAddress(RefAddress) &&
384-
"__bug_table entries should point to a function");
385-
386-
insertLKMarker(RefAddress, I, SignedOffset, true, "__bug_table");
387-
}
388-
}
389-
390390
/// .smp_locks section contains PC-relative references to instructions with LOCK
391391
/// prefix. The prefix can be converted to NOP at boot time on non-SMP systems.
392392
void LinuxKernelRewriter::processLKSMPLocks() {
@@ -500,7 +500,8 @@ Error LinuxKernelRewriter::readORCTables() {
500500
// Consume the status of the cursor.
501501
if (!IPCursor)
502502
return createStringError(errc::executable_format_error,
503-
"out of bounds while reading ORC IP table");
503+
"out of bounds while reading ORC IP table: %s",
504+
toString(IPCursor.takeError()).c_str());
504505

505506
if (IP < PrevIP && opts::Verbosity)
506507
BC.errs() << "BOLT-WARNING: out of order IP 0x" << Twine::utohexstr(IP)
@@ -522,7 +523,8 @@ Error LinuxKernelRewriter::readORCTables() {
522523
// Consume the status of the cursor.
523524
if (!ORCCursor)
524525
return createStringError(errc::executable_format_error,
525-
"out of bounds while reading ORC");
526+
"out of bounds while reading ORC: %s",
527+
toString(ORCCursor.takeError()).c_str());
526528

527529
if (Entry.ORC == NullORC)
528530
continue;
@@ -843,7 +845,8 @@ Error LinuxKernelRewriter::readStaticCalls() {
843845
// Consume the status of the cursor.
844846
if (!Cursor)
845847
return createStringError(errc::executable_format_error,
846-
"out of bounds while reading static calls");
848+
"out of bounds while reading static calls: %s",
849+
toString(Cursor.takeError()).c_str());
847850

848851
++EntryID;
849852

@@ -954,8 +957,10 @@ Error LinuxKernelRewriter::readExceptionTable() {
954957

955958
// Consume the status of the cursor.
956959
if (!Cursor)
957-
return createStringError(errc::executable_format_error,
958-
"out of bounds while reading exception table");
960+
return createStringError(
961+
errc::executable_format_error,
962+
"out of bounds while reading exception table: %s",
963+
toString(Cursor.takeError()).c_str());
959964

960965
++EntryID;
961966

@@ -1061,8 +1066,10 @@ Error LinuxKernelRewriter::readParaInstructions() {
10611066
const uint8_t Len = DE.getU8(Cursor);
10621067

10631068
if (!Cursor)
1064-
return createStringError(errc::executable_format_error,
1065-
"out of bounds while reading .parainstructions");
1069+
return createStringError(
1070+
errc::executable_format_error,
1071+
"out of bounds while reading .parainstructions: %s",
1072+
toString(Cursor.takeError()).c_str());
10661073

10671074
++EntryID;
10681075

@@ -1097,6 +1104,185 @@ Error LinuxKernelRewriter::readParaInstructions() {
10971104
return Error::success();
10981105
}
10991106

1107+
/// Process __bug_table section.
1108+
/// This section contains information useful for kernel debugging.
1109+
/// Each entry in the section is a struct bug_entry that contains a pointer to
1110+
/// the ud2 instruction corresponding to the bug, corresponding file name (both
1111+
/// pointers use PC relative offset addressing), line number, and flags.
1112+
/// The definition of the struct bug_entry can be found in
1113+
/// `include/asm-generic/bug.h`
1114+
///
1115+
/// NB: find_bug() uses linear search to match an address to an entry in the bug
1116+
/// table. Hence there is no need to sort entries when rewriting the table.
1117+
Error LinuxKernelRewriter::readBugTable() {
1118+
BugTableSection = BC.getUniqueSectionByName("__bug_table");
1119+
if (!BugTableSection)
1120+
return Error::success();
1121+
1122+
if (BugTableSection->getSize() % BUG_TABLE_ENTRY_SIZE)
1123+
return createStringError(errc::executable_format_error,
1124+
"bug table size error");
1125+
1126+
const uint64_t SectionAddress = BugTableSection->getAddress();
1127+
DataExtractor DE(BugTableSection->getContents(), BC.AsmInfo->isLittleEndian(),
1128+
BC.AsmInfo->getCodePointerSize());
1129+
DataExtractor::Cursor Cursor(0);
1130+
uint32_t EntryID = 0;
1131+
while (Cursor && Cursor.tell() < BugTableSection->getSize()) {
1132+
const uint64_t Pos = Cursor.tell();
1133+
const uint64_t InstAddress =
1134+
SectionAddress + Pos + (int32_t)DE.getU32(Cursor);
1135+
Cursor.seek(Pos + BUG_TABLE_ENTRY_SIZE);
1136+
1137+
if (!Cursor)
1138+
return createStringError(errc::executable_format_error,
1139+
"out of bounds while reading __bug_table: %s",
1140+
toString(Cursor.takeError()).c_str());
1141+
1142+
++EntryID;
1143+
1144+
BinaryFunction *BF = BC.getBinaryFunctionContainingAddress(InstAddress);
1145+
if (!BF && opts::Verbosity) {
1146+
BC.outs() << "BOLT-INFO: no function matches address 0x"
1147+
<< Twine::utohexstr(InstAddress)
1148+
<< " referenced by bug table\n";
1149+
}
1150+
1151+
if (BF && BC.shouldEmit(*BF)) {
1152+
MCInst *Inst = BF->getInstructionAtOffset(InstAddress - BF->getAddress());
1153+
if (!Inst)
1154+
return createStringError(errc::executable_format_error,
1155+
"no instruction at address 0x%" PRIx64
1156+
" referenced by bug table entry %d",
1157+
InstAddress, EntryID);
1158+
BC.MIB->addAnnotation(*Inst, "BugEntry", EntryID);
1159+
}
1160+
}
1161+
1162+
BC.outs() << "BOLT-INFO: parsed " << EntryID << " bug table entries\n";
1163+
1164+
return Error::success();
1165+
}
1166+
1167+
/// The kernel can replace certain instruction sequences depending on hardware
1168+
/// it is running on and features specified during boot time. The information
1169+
/// about alternative instruction sequences is stored in .altinstructions
1170+
/// section. The format of entries in this section is defined in
1171+
/// arch/x86/include/asm/alternative.h:
1172+
///
1173+
/// struct alt_instr {
1174+
/// s32 instr_offset;
1175+
/// s32 repl_offset;
1176+
/// uXX feature;
1177+
/// u8 instrlen;
1178+
/// u8 replacementlen;
1179+
/// u8 padlen; // present in older kernels
1180+
/// } __packed;
1181+
///
1182+
/// Note the structures is packed.
1183+
Error LinuxKernelRewriter::readAltInstructions() {
1184+
AltInstrSection = BC.getUniqueSectionByName(".altinstructions");
1185+
if (!AltInstrSection)
1186+
return Error::success();
1187+
1188+
const uint64_t Address = AltInstrSection->getAddress();
1189+
DataExtractor DE = DataExtractor(AltInstrSection->getContents(),
1190+
BC.AsmInfo->isLittleEndian(),
1191+
BC.AsmInfo->getCodePointerSize());
1192+
uint64_t EntryID = 0;
1193+
DataExtractor::Cursor Cursor(0);
1194+
while (Cursor && !DE.eof(Cursor)) {
1195+
const uint64_t OrgInstAddress =
1196+
Address + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1197+
const uint64_t AltInstAddress =
1198+
Address + Cursor.tell() + (int32_t)DE.getU32(Cursor);
1199+
const uint64_t Feature = DE.getUnsigned(Cursor, opts::AltInstFeatureSize);
1200+
const uint8_t OrgSize = DE.getU8(Cursor);
1201+
const uint8_t AltSize = DE.getU8(Cursor);
1202+
1203+
// Older kernels may have the padlen field.
1204+
const uint8_t PadLen = opts::AltInstHasPadLen ? DE.getU8(Cursor) : 0;
1205+
1206+
if (!Cursor)
1207+
return createStringError(
1208+
errc::executable_format_error,
1209+
"out of bounds while reading .altinstructions: %s",
1210+
toString(Cursor.takeError()).c_str());
1211+
1212+
++EntryID;
1213+
1214+
if (opts::DumpAltInstructions) {
1215+
BC.outs() << "Alternative instruction entry: " << EntryID
1216+
<< "\n\tOrg: 0x" << Twine::utohexstr(OrgInstAddress)
1217+
<< "\n\tAlt: 0x" << Twine::utohexstr(AltInstAddress)
1218+
<< "\n\tFeature: 0x" << Twine::utohexstr(Feature)
1219+
<< "\n\tOrgSize: " << (int)OrgSize
1220+
<< "\n\tAltSize: " << (int)AltSize << '\n';
1221+
if (opts::AltInstHasPadLen)
1222+
BC.outs() << "\tPadLen: " << (int)PadLen << '\n';
1223+
}
1224+
1225+
if (AltSize > OrgSize)
1226+
return createStringError(errc::executable_format_error,
1227+
"error reading .altinstructions");
1228+
1229+
BinaryFunction *BF = BC.getBinaryFunctionContainingAddress(OrgInstAddress);
1230+
if (!BF && opts::Verbosity) {
1231+
BC.outs() << "BOLT-INFO: no function matches address 0x"
1232+
<< Twine::utohexstr(OrgInstAddress)
1233+
<< " of instruction from .altinstructions\n";
1234+
}
1235+
1236+
BinaryFunction *AltBF =
1237+
BC.getBinaryFunctionContainingAddress(AltInstAddress);
1238+
if (AltBF && BC.shouldEmit(*AltBF)) {
1239+
BC.errs()
1240+
<< "BOLT-WARNING: alternative instruction sequence found in function "
1241+
<< *AltBF << '\n';
1242+
AltBF->setIgnored();
1243+
}
1244+
1245+
if (!BF || !BC.shouldEmit(*BF))
1246+
continue;
1247+
1248+
if (OrgInstAddress + OrgSize > BF->getAddress() + BF->getSize())
1249+
return createStringError(errc::executable_format_error,
1250+
"error reading .altinstructions");
1251+
1252+
MCInst *Inst =
1253+
BF->getInstructionAtOffset(OrgInstAddress - BF->getAddress());
1254+
if (!Inst)
1255+
return createStringError(errc::executable_format_error,
1256+
"no instruction at address 0x%" PRIx64
1257+
" referenced by .altinstructions entry %d",
1258+
OrgInstAddress, EntryID);
1259+
1260+
// There could be more than one alternative instruction sequences for the
1261+
// same original instruction. Annotate each alternative separately.
1262+
std::string AnnotationName = "AltInst";
1263+
unsigned N = 2;
1264+
while (BC.MIB->hasAnnotation(*Inst, AnnotationName))
1265+
AnnotationName = "AltInst" + std::to_string(N++);
1266+
1267+
BC.MIB->addAnnotation(*Inst, AnnotationName, EntryID);
1268+
1269+
// Annotate all instructions from the original sequence. Note that it's not
1270+
// the most efficient way to look for instructions in the address range,
1271+
// but since alternative instructions are uncommon, it will do for now.
1272+
for (uint32_t Offset = 1; Offset < OrgSize; ++Offset) {
1273+
Inst = BF->getInstructionAtOffset(OrgInstAddress + Offset -
1274+
BF->getAddress());
1275+
if (Inst)
1276+
BC.MIB->addAnnotation(*Inst, AnnotationName, EntryID);
1277+
}
1278+
}
1279+
1280+
BC.outs() << "BOLT-INFO: parsed " << EntryID
1281+
<< " alternative instruction entries\n";
1282+
1283+
return Error::success();
1284+
}
1285+
11001286
} // namespace
11011287

11021288
std::unique_ptr<MetadataRewriter>

0 commit comments

Comments
 (0)