Skip to content

Commit 4c7bdcb

Browse files
committed
Merge branch 'main' into dwarf-pauth-llvm-dinodes
2 parents f765247 + a11ab13 commit 4c7bdcb

File tree

1,163 files changed

+40182
-20492
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,163 files changed

+40182
-20492
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

bolt/lib/Core/ParallelUtilities.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ namespace ParallelUtilities {
4949

5050
namespace {
5151
/// A single thread pool that is used to run parallel tasks
52-
std::unique_ptr<ThreadPool> ThreadPoolPtr;
52+
std::unique_ptr<DefaultThreadPool> ThreadPoolPtr;
5353

5454
unsigned computeCostFor(const BinaryFunction &BF,
5555
const PredicateTy &SkipPredicate,
@@ -106,7 +106,7 @@ ThreadPoolInterface &getThreadPool() {
106106
if (ThreadPoolPtr.get())
107107
return *ThreadPoolPtr;
108108

109-
ThreadPoolPtr = std::make_unique<ThreadPool>(
109+
ThreadPoolPtr = std::make_unique<DefaultThreadPool>(
110110
llvm::hardware_concurrency(opts::ThreadCount));
111111
return *ThreadPoolPtr;
112112
}

bolt/lib/Rewrite/LinuxKernelRewriter.cpp

Lines changed: 154 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ static cl::opt<bool>
3636
DumpORC("dump-orc", cl::desc("dump raw ORC unwind information (sorted)"),
3737
cl::init(false), cl::Hidden, cl::cat(BoltCategory));
3838

39+
static cl::opt<bool> DumpParavirtualPatchSites(
40+
"dump-para-sites", cl::desc("dump Linux kernel paravitual patch sites"),
41+
cl::init(false), cl::Hidden, cl::cat(BoltCategory));
42+
3943
static cl::opt<bool> DumpStaticCalls("dump-static-calls",
4044
cl::desc("dump Linux kernel static calls"),
4145
cl::init(false), cl::Hidden,
@@ -147,6 +151,18 @@ class LinuxKernelRewriter final : public MetadataRewriter {
147151
/// Functions with exception handling code.
148152
DenseSet<BinaryFunction *> FunctionsWithExceptions;
149153

154+
/// Section with paravirtual patch sites.
155+
ErrorOr<BinarySection &> ParavirtualPatchSection = std::errc::bad_address;
156+
157+
/// Alignment of paravirtual patch structures.
158+
static constexpr size_t PARA_PATCH_ALIGN = 8;
159+
160+
/// Section containing Linux bug table.
161+
ErrorOr<BinarySection &> BugTableSection = std::errc::bad_address;
162+
163+
/// Size of bug_entry struct.
164+
static constexpr size_t BUG_TABLE_ENTRY_SIZE = 12;
165+
150166
/// Insert an LKMarker for a given code pointer \p PC from a non-code section
151167
/// \p SectionName.
152168
void insertLKMarker(uint64_t PC, uint64_t SectionOffset,
@@ -162,9 +178,6 @@ class LinuxKernelRewriter final : public MetadataRewriter {
162178
/// Process __ksymtab and __ksymtab_gpl.
163179
void processLKKSymtab(bool IsGPL = false);
164180

165-
/// Process special linux kernel section, __bug_table.
166-
void processLKBugTable();
167-
168181
/// Process special linux kernel section, .smp_locks.
169182
void processLKSMPLocks();
170183

@@ -187,6 +200,11 @@ class LinuxKernelRewriter final : public MetadataRewriter {
187200
Error readExceptionTable();
188201
Error rewriteExceptionTable();
189202

203+
/// Paravirtual instruction patch sites.
204+
Error readParaInstructions();
205+
206+
Error readBugTable();
207+
190208
/// Mark instructions referenced by kernel metadata.
191209
Error markInstructions();
192210

@@ -208,6 +226,12 @@ class LinuxKernelRewriter final : public MetadataRewriter {
208226
if (Error E = readExceptionTable())
209227
return E;
210228

229+
if (Error E = readParaInstructions())
230+
return E;
231+
232+
if (Error E = readBugTable())
233+
return E;
234+
211235
return Error::success();
212236
}
213237

@@ -273,7 +297,6 @@ void LinuxKernelRewriter::processLKSections() {
273297
processLKPCIFixup();
274298
processLKKSymtab();
275299
processLKKSymtab(true);
276-
processLKBugTable();
277300
processLKSMPLocks();
278301
}
279302

@@ -340,37 +363,6 @@ void LinuxKernelRewriter::processLKKSymtab(bool IsGPL) {
340363
}
341364
}
342365

343-
/// Process __bug_table section.
344-
/// This section contains information useful for kernel debugging.
345-
/// Each entry in the section is a struct bug_entry that contains a pointer to
346-
/// the ud2 instruction corresponding to the bug, corresponding file name (both
347-
/// pointers use PC relative offset addressing), line number, and flags.
348-
/// The definition of the struct bug_entry can be found in
349-
/// `include/asm-generic/bug.h`
350-
void LinuxKernelRewriter::processLKBugTable() {
351-
ErrorOr<BinarySection &> SectionOrError =
352-
BC.getUniqueSectionByName("__bug_table");
353-
if (!SectionOrError)
354-
return;
355-
356-
const uint64_t SectionSize = SectionOrError->getSize();
357-
const uint64_t SectionAddress = SectionOrError->getAddress();
358-
assert((SectionSize % 12) == 0 &&
359-
"The size of the __bug_table section should be a multiple of 12");
360-
for (uint64_t I = 0; I < SectionSize; I += 12) {
361-
const uint64_t EntryAddress = SectionAddress + I;
362-
ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(EntryAddress, 4);
363-
assert(Offset &&
364-
"Reading valid PC-relative offset for a __bug_table entry");
365-
const int32_t SignedOffset = *Offset;
366-
const uint64_t RefAddress = EntryAddress + SignedOffset;
367-
assert(BC.getBinaryFunctionContainingAddress(RefAddress) &&
368-
"__bug_table entries should point to a function");
369-
370-
insertLKMarker(RefAddress, I, SignedOffset, true, "__bug_table");
371-
}
372-
}
373-
374366
/// .smp_locks section contains PC-relative references to instructions with LOCK
375367
/// prefix. The prefix can be converted to NOP at boot time on non-SMP systems.
376368
void LinuxKernelRewriter::processLKSMPLocks() {
@@ -1013,6 +1005,133 @@ Error LinuxKernelRewriter::rewriteExceptionTable() {
10131005
return Error::success();
10141006
}
10151007

1008+
/// .parainsrtuctions section contains information for patching parvirtual call
1009+
/// instructions during runtime. The entries in the section are in the form:
1010+
///
1011+
/// struct paravirt_patch_site {
1012+
/// u8 *instr; /* original instructions */
1013+
/// u8 type; /* type of this instruction */
1014+
/// u8 len; /* length of original instruction */
1015+
/// };
1016+
///
1017+
/// Note that the structures are aligned at 8-byte boundary.
1018+
Error LinuxKernelRewriter::readParaInstructions() {
1019+
ParavirtualPatchSection = BC.getUniqueSectionByName(".parainstructions");
1020+
if (!ParavirtualPatchSection)
1021+
return Error::success();
1022+
1023+
DataExtractor DE = DataExtractor(ParavirtualPatchSection->getContents(),
1024+
BC.AsmInfo->isLittleEndian(),
1025+
BC.AsmInfo->getCodePointerSize());
1026+
uint32_t EntryID = 0;
1027+
DataExtractor::Cursor Cursor(0);
1028+
while (Cursor && !DE.eof(Cursor)) {
1029+
const uint64_t NextOffset = alignTo(Cursor.tell(), Align(PARA_PATCH_ALIGN));
1030+
if (!DE.isValidOffset(NextOffset))
1031+
break;
1032+
1033+
Cursor.seek(NextOffset);
1034+
1035+
const uint64_t InstrLocation = DE.getU64(Cursor);
1036+
const uint8_t Type = DE.getU8(Cursor);
1037+
const uint8_t Len = DE.getU8(Cursor);
1038+
1039+
if (!Cursor)
1040+
return createStringError(errc::executable_format_error,
1041+
"out of bounds while reading .parainstructions");
1042+
1043+
++EntryID;
1044+
1045+
if (opts::DumpParavirtualPatchSites) {
1046+
BC.outs() << "Paravirtual patch site: " << EntryID << '\n';
1047+
BC.outs() << "\tInstr: 0x" << Twine::utohexstr(InstrLocation)
1048+
<< "\n\tType: 0x" << Twine::utohexstr(Type) << "\n\tLen: 0x"
1049+
<< Twine::utohexstr(Len) << '\n';
1050+
}
1051+
1052+
BinaryFunction *BF = BC.getBinaryFunctionContainingAddress(InstrLocation);
1053+
if (!BF && opts::Verbosity) {
1054+
BC.outs() << "BOLT-INFO: no function matches address 0x"
1055+
<< Twine::utohexstr(InstrLocation)
1056+
<< " referenced by paravirutal patch site\n";
1057+
}
1058+
1059+
if (BF && BC.shouldEmit(*BF)) {
1060+
MCInst *Inst =
1061+
BF->getInstructionAtOffset(InstrLocation - BF->getAddress());
1062+
if (!Inst)
1063+
return createStringError(errc::executable_format_error,
1064+
"no instruction at address 0x%" PRIx64
1065+
" in paravirtual call site %d",
1066+
InstrLocation, EntryID);
1067+
BC.MIB->addAnnotation(*Inst, "ParaSite", EntryID);
1068+
}
1069+
}
1070+
1071+
BC.outs() << "BOLT-INFO: parsed " << EntryID << " paravirtual patch sites\n";
1072+
1073+
return Error::success();
1074+
}
1075+
1076+
/// Process __bug_table section.
1077+
/// This section contains information useful for kernel debugging.
1078+
/// Each entry in the section is a struct bug_entry that contains a pointer to
1079+
/// the ud2 instruction corresponding to the bug, corresponding file name (both
1080+
/// pointers use PC relative offset addressing), line number, and flags.
1081+
/// The definition of the struct bug_entry can be found in
1082+
/// `include/asm-generic/bug.h`
1083+
///
1084+
/// NB: find_bug() uses linear search to match an address to an entry in the bug
1085+
/// table. Hence there is no need to sort entries when rewriting the table.
1086+
Error LinuxKernelRewriter::readBugTable() {
1087+
BugTableSection = BC.getUniqueSectionByName("__bug_table");
1088+
if (!BugTableSection)
1089+
return Error::success();
1090+
1091+
if (BugTableSection->getSize() % BUG_TABLE_ENTRY_SIZE)
1092+
return createStringError(errc::executable_format_error,
1093+
"bug table size error");
1094+
1095+
const uint64_t SectionAddress = BugTableSection->getAddress();
1096+
DataExtractor DE(BugTableSection->getContents(), BC.AsmInfo->isLittleEndian(),
1097+
BC.AsmInfo->getCodePointerSize());
1098+
DataExtractor::Cursor Cursor(0);
1099+
uint32_t EntryID = 0;
1100+
while (Cursor && Cursor.tell() < BugTableSection->getSize()) {
1101+
const uint64_t Pos = Cursor.tell();
1102+
const uint64_t InstAddress =
1103+
SectionAddress + Pos + (int32_t)DE.getU32(Cursor);
1104+
Cursor.seek(Pos + BUG_TABLE_ENTRY_SIZE);
1105+
1106+
if (!Cursor)
1107+
return createStringError(errc::executable_format_error,
1108+
"out of bounds while reading __bug_table");
1109+
1110+
++EntryID;
1111+
1112+
BinaryFunction *BF = BC.getBinaryFunctionContainingAddress(InstAddress);
1113+
if (!BF && opts::Verbosity) {
1114+
BC.outs() << "BOLT-INFO: no function matches address 0x"
1115+
<< Twine::utohexstr(InstAddress)
1116+
<< " referenced by bug table\n";
1117+
}
1118+
1119+
if (BF && BC.shouldEmit(*BF)) {
1120+
MCInst *Inst = BF->getInstructionAtOffset(InstAddress - BF->getAddress());
1121+
if (!Inst)
1122+
return createStringError(errc::executable_format_error,
1123+
"no instruction at address 0x%" PRIx64
1124+
" referenced by bug table entry %d",
1125+
InstAddress, EntryID);
1126+
BC.MIB->addAnnotation(*Inst, "BugEntry", EntryID);
1127+
}
1128+
}
1129+
1130+
BC.outs() << "BOLT-INFO: parsed " << EntryID << " bug table entries\n";
1131+
1132+
return Error::success();
1133+
}
1134+
10161135
} // namespace
10171136

10181137
std::unique_ptr<MetadataRewriter>

bolt/test/X86/gotpcrelx.s

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
## kinds of handling of the relocation by the linker (no relaxation, pic, and
66
## non-pic).
77

8-
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux \
9-
# RUN: -relax-relocations %s -o %t.o
8+
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o
109
# RUN: ld.lld %t.o -o %t.exe -q
1110
# RUN: ld.lld %t.o -o %t.pie.exe -q -pie
1211
# RUN: ld.lld %t.o -o %t.no-relax.exe -q --no-relax

bolt/test/X86/linux-bug-table.s

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# REQUIRES: system-linux
2+
3+
## Check that BOLT correctly parses the Linux kernel __bug_table section.
4+
5+
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
6+
# RUN: %clang %cflags -nostdlib %t.o -o %t.exe \
7+
# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
8+
9+
## Verify bug entry bindings to instructions.
10+
11+
# RUN: llvm-bolt %t.exe --print-normalized -o %t.out | FileCheck %s
12+
13+
# CHECK: BOLT-INFO: Linux kernel binary detected
14+
# CHECK: BOLT-INFO: parsed 2 bug table entries
15+
16+
.text
17+
.globl _start
18+
.type _start, %function
19+
_start:
20+
# CHECK: Binary Function "_start"
21+
nop
22+
.L0:
23+
ud2
24+
# CHECK: ud2
25+
# CHECK-SAME: BugEntry: 1
26+
nop
27+
.L1:
28+
ud2
29+
# CHECK: ud2
30+
# CHECK-SAME: BugEntry: 2
31+
ret
32+
.size _start, .-_start
33+
34+
35+
## Bug table.
36+
.section __bug_table,"a",@progbits
37+
1:
38+
.long .L0 - . # instruction
39+
.org 1b + 12
40+
2:
41+
.long .L1 - . # instruction
42+
.org 2b + 12
43+
44+
## Fake Linux Kernel sections.
45+
.section __ksymtab,"a",@progbits
46+
.section __ksymtab_gpl,"a",@progbits
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# REQUIRES: system-linux
2+
3+
## Check that BOLT correctly parses the Linux kernel .parainstructions section.
4+
5+
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
6+
# RUN: %clang %cflags -nostdlib %t.o -o %t.exe \
7+
# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
8+
9+
## Verify paravirtual bindings to instructions.
10+
11+
# RUN: llvm-bolt %t.exe --print-normalized -o %t.out | FileCheck %s
12+
13+
# CHECK: BOLT-INFO: Linux kernel binary detected
14+
# CHECK: BOLT-INFO: parsed 2 paravirtual patch sites
15+
16+
.rodata
17+
fptr:
18+
.quad 0
19+
20+
.text
21+
.globl _start
22+
.type _start, %function
23+
_start:
24+
# CHECK: Binary Function "_start"
25+
nop
26+
.L1:
27+
call *fptr(%rip)
28+
# CHECK: call
29+
# CHECK-SAME: ParaSite: 1
30+
nop
31+
.L2:
32+
call *fptr(%rip)
33+
# CHECK: call
34+
# CHECK-SAME: ParaSite: 2
35+
ret
36+
.size _start, .-_start
37+
38+
39+
## Paravirtual patch sites.
40+
.section .parainstructions,"a",@progbits
41+
42+
.balign 8
43+
.quad .L1 # instruction
44+
.byte 1 # type
45+
.byte 7 # length
46+
47+
.balign 8
48+
.quad .L2 # instruction
49+
.byte 1 # type
50+
.byte 7 # length
51+
52+
## Fake Linux Kernel sections.
53+
.section __ksymtab,"a",@progbits
54+
.section __ksymtab_gpl,"a",@progbits

bolt/test/X86/pt_gnu_relro.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Check that BOLT recognizes PT_GNU_RELRO segment and marks respective sections
44
# accordingly.
55

6-
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o -relax-relocations
6+
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o
77
# RUN: ld.lld %t.o -o %t.exe -q --no-relax
88
# RUN: llvm-readelf -We %t.exe | FileCheck --check-prefix=READELF %s
99
# Unfortunately there's no direct way to extract a segment to section mapping

0 commit comments

Comments
 (0)