Skip to content

Commit f6768f9

Browse files
committed
Merge branch 'main' into attributor-light-denormal-fp-math
2 parents c93a9cb + 083d8aa commit f6768f9

File tree

2,079 files changed

+98332
-29004
lines changed

Some content is hidden

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

2,079 files changed

+98332
-29004
lines changed

.arcconfig

Lines changed: 0 additions & 8 deletions
This file was deleted.

.arclint

Lines changed: 0 additions & 15 deletions
This file was deleted.

.github/new-prs-labeler.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,9 @@ backend:SystemZ:
869869
third-party:unittests:
870870
- third-party/unittests/**
871871

872+
third-party:benchmark:
873+
- third-party/benchmark/**
874+
872875
llvm:binary-utilities:
873876
- llvm/docs/CommandGuide/llvm-*
874877
- llvm/include/llvm/BinaryFormat/**

.github/workflows/build-ci-container.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,18 @@ jobs:
7777
cp ./.github/workflows/containers/github-action-ci/storage.conf ~/.config/containers/storage.conf
7878
podman info
7979
80+
# Download the container image into /mnt/podman rather than
81+
# $GITHUB_WORKSPACE to avoid space limitations on the default drive
82+
# and use the permissions setup for /mnt/podman.
8083
- name: Download stage1-toolchain
8184
uses: actions/download-artifact@v4
8285
with:
8386
name: stage1-toolchain
87+
path: /mnt/podman
8488

8589
- name: Load stage1-toolchain
8690
run: |
87-
podman load -i stage1-toolchain.tar
91+
podman load -i /mnt/podman/stage1-toolchain.tar
8892
8993
- name: Build Container
9094
working-directory: ./.github/workflows/containers/github-action-ci/

.github/workflows/containers/github-action-ci/stage2.Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ COPY --from=stage2-toolchain $LLVM_SYSROOT $LLVM_SYSROOT
1212
# Need to install curl for hendrikmuhs/ccache-action
1313
# Need nodejs for some of the GitHub actions.
1414
# Need perl-modules for clang analyzer tests.
15+
# Need git for SPIRV-Tools tests.
1516
RUN apt-get update && \
1617
apt-get install -y \
1718
binutils \
1819
cmake \
1920
curl \
21+
git \
2022
libstdc++-11-dev \
2123
ninja-build \
2224
nodejs \

bolt/include/bolt/Core/ParallelUtilities.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "bolt/Core/MCPlusBuilder.h"
2020
#include "llvm/Support/CommandLine.h"
21+
#include "llvm/Support/ThreadPool.h"
2122

2223
using namespace llvm;
2324

@@ -28,8 +29,6 @@ extern cl::opt<unsigned> TaskCount;
2829
} // namespace opts
2930

3031
namespace llvm {
31-
class ThreadPool;
32-
3332
namespace bolt {
3433
class BinaryContext;
3534
class BinaryFunction;

bolt/lib/Core/Relocation.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,14 @@ static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
381381
// OP 1001_01 goes in bits 31:26 of BL.
382382
Value = ((Value >> 2) & 0x3ffffff) | 0x94000000ULL;
383383
break;
384+
case ELF::R_AARCH64_JUMP26:
385+
Value -= PC;
386+
assert(isInt<28>(Value) &&
387+
"only PC +/- 128MB is allowed for direct branch");
388+
// Immediate goes in bits 25:0 of B.
389+
// OP 0001_01 goes in bits 31:26 of B.
390+
Value = ((Value >> 2) & 0x3ffffff) | 0x14000000ULL;
391+
break;
384392
}
385393
return Value;
386394
}

bolt/lib/Rewrite/LinuxKernelRewriter.cpp

Lines changed: 140 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "bolt/Rewrite/MetadataRewriter.h"
1515
#include "bolt/Rewrite/MetadataRewriters.h"
1616
#include "bolt/Utils/CommandLineOpts.h"
17+
#include "llvm/ADT/DenseSet.h"
1718
#include "llvm/Support/BinaryStreamWriter.h"
1819
#include "llvm/Support/CommandLine.h"
1920
#include "llvm/Support/Debug.h"
@@ -27,9 +28,9 @@ using namespace bolt;
2728
namespace opts {
2829

2930
static cl::opt<bool>
30-
PrintORC("print-orc",
31-
cl::desc("print ORC unwind information for instructions"),
32-
cl::init(true), cl::Hidden, cl::cat(BoltCategory));
31+
DumpExceptions("dump-linux-exceptions",
32+
cl::desc("dump Linux kernel exception table"),
33+
cl::init(false), cl::Hidden, cl::cat(BoltCategory));
3334

3435
static cl::opt<bool>
3536
DumpORC("dump-orc", cl::desc("dump raw ORC unwind information (sorted)"),
@@ -40,6 +41,11 @@ static cl::opt<bool> DumpStaticCalls("dump-static-calls",
4041
cl::init(false), cl::Hidden,
4142
cl::cat(BoltCategory));
4243

44+
static cl::opt<bool>
45+
PrintORC("print-orc",
46+
cl::desc("print ORC unwind information for instructions"),
47+
cl::init(true), cl::Hidden, cl::cat(BoltCategory));
48+
4349
} // namespace opts
4450

4551
/// Linux Kernel supports stack unwinding using ORC (oops rewind capability).
@@ -134,6 +140,13 @@ class LinuxKernelRewriter final : public MetadataRewriter {
134140
using StaticCallListType = std::vector<StaticCallInfo>;
135141
StaticCallListType StaticCallEntries;
136142

143+
/// Section containing the Linux exception table.
144+
ErrorOr<BinarySection &> ExceptionsSection = std::errc::bad_address;
145+
static constexpr size_t EXCEPTION_TABLE_ENTRY_SIZE = 12;
146+
147+
/// Functions with exception handling code.
148+
DenseSet<BinaryFunction *> FunctionsWithExceptions;
149+
137150
/// Insert an LKMarker for a given code pointer \p PC from a non-code section
138151
/// \p SectionName.
139152
void insertLKMarker(uint64_t PC, uint64_t SectionOffset,
@@ -143,9 +156,6 @@ class LinuxKernelRewriter final : public MetadataRewriter {
143156
/// Process linux kernel special sections and their relocations.
144157
void processLKSections();
145158

146-
/// Process special linux kernel section, __ex_table.
147-
void processLKExTable();
148-
149159
/// Process special linux kernel section, .pci_fixup.
150160
void processLKPCIFixup();
151161

@@ -174,6 +184,9 @@ class LinuxKernelRewriter final : public MetadataRewriter {
174184
Error readStaticCalls();
175185
Error rewriteStaticCalls();
176186

187+
Error readExceptionTable();
188+
Error rewriteExceptionTable();
189+
177190
/// Mark instructions referenced by kernel metadata.
178191
Error markInstructions();
179192

@@ -192,6 +205,9 @@ class LinuxKernelRewriter final : public MetadataRewriter {
192205
if (Error E = readStaticCalls())
193206
return E;
194207

208+
if (Error E = readExceptionTable())
209+
return E;
210+
195211
return Error::success();
196212
}
197213

@@ -203,6 +219,11 @@ class LinuxKernelRewriter final : public MetadataRewriter {
203219
}
204220

205221
Error preEmitFinalizer() override {
222+
// Since rewriteExceptionTable() can mark functions as non-simple, run it
223+
// before other rewriters that depend on simple/emit status.
224+
if (Error E = rewriteExceptionTable())
225+
return E;
226+
206227
if (Error E = rewriteORCTables())
207228
return E;
208229

@@ -249,77 +270,13 @@ void LinuxKernelRewriter::insertLKMarker(uint64_t PC, uint64_t SectionOffset,
249270
}
250271

251272
void LinuxKernelRewriter::processLKSections() {
252-
processLKExTable();
253273
processLKPCIFixup();
254274
processLKKSymtab();
255275
processLKKSymtab(true);
256276
processLKBugTable();
257277
processLKSMPLocks();
258278
}
259279

260-
/// Process __ex_table section of Linux Kernel.
261-
/// This section contains information regarding kernel level exception
262-
/// handling (https://www.kernel.org/doc/html/latest/x86/exception-tables.html).
263-
/// More documentation is in arch/x86/include/asm/extable.h.
264-
///
265-
/// The section is the list of the following structures:
266-
///
267-
/// struct exception_table_entry {
268-
/// int insn;
269-
/// int fixup;
270-
/// int handler;
271-
/// };
272-
///
273-
void LinuxKernelRewriter::processLKExTable() {
274-
ErrorOr<BinarySection &> SectionOrError =
275-
BC.getUniqueSectionByName("__ex_table");
276-
if (!SectionOrError)
277-
return;
278-
279-
const uint64_t SectionSize = SectionOrError->getSize();
280-
const uint64_t SectionAddress = SectionOrError->getAddress();
281-
assert((SectionSize % 12) == 0 &&
282-
"The size of the __ex_table section should be a multiple of 12");
283-
for (uint64_t I = 0; I < SectionSize; I += 4) {
284-
const uint64_t EntryAddress = SectionAddress + I;
285-
ErrorOr<uint64_t> Offset = BC.getSignedValueAtAddress(EntryAddress, 4);
286-
assert(Offset && "failed reading PC-relative offset for __ex_table");
287-
int32_t SignedOffset = *Offset;
288-
const uint64_t RefAddress = EntryAddress + SignedOffset;
289-
290-
BinaryFunction *ContainingBF =
291-
BC.getBinaryFunctionContainingAddress(RefAddress);
292-
if (!ContainingBF)
293-
continue;
294-
295-
MCSymbol *ReferencedSymbol = ContainingBF->getSymbol();
296-
const uint64_t FunctionOffset = RefAddress - ContainingBF->getAddress();
297-
switch (I % 12) {
298-
default:
299-
llvm_unreachable("bad alignment of __ex_table");
300-
break;
301-
case 0:
302-
// insn
303-
insertLKMarker(RefAddress, I, SignedOffset, true, "__ex_table");
304-
break;
305-
case 4:
306-
// fixup
307-
if (FunctionOffset)
308-
ReferencedSymbol = ContainingBF->addEntryPointAtOffset(FunctionOffset);
309-
BC.addRelocation(EntryAddress, ReferencedSymbol, Relocation::getPC32(), 0,
310-
*Offset);
311-
break;
312-
case 8:
313-
// handler
314-
assert(!FunctionOffset &&
315-
"__ex_table handler entry should point to function start");
316-
BC.addRelocation(EntryAddress, ReferencedSymbol, Relocation::getPC32(), 0,
317-
*Offset);
318-
break;
319-
}
320-
}
321-
}
322-
323280
/// Process .pci_fixup section of Linux Kernel.
324281
/// This section contains a list of entries for different PCI devices and their
325282
/// corresponding hook handler (code pointer where the fixup
@@ -943,6 +900,119 @@ Error LinuxKernelRewriter::rewriteStaticCalls() {
943900
return Error::success();
944901
}
945902

903+
/// Instructions that access user-space memory can cause page faults. These
904+
/// faults will be handled by the kernel and execution will resume at the fixup
905+
/// code location if the address was invalid. The kernel uses the exception
906+
/// table to match the faulting instruction to its fixup. The table consists of
907+
/// the following entries:
908+
///
909+
/// struct exception_table_entry {
910+
/// int insn;
911+
/// int fixup;
912+
/// int data;
913+
/// };
914+
///
915+
/// More info at:
916+
/// https://www.kernel.org/doc/Documentation/x86/exception-tables.txt
917+
Error LinuxKernelRewriter::readExceptionTable() {
918+
ExceptionsSection = BC.getUniqueSectionByName("__ex_table");
919+
if (!ExceptionsSection)
920+
return Error::success();
921+
922+
if (ExceptionsSection->getSize() % EXCEPTION_TABLE_ENTRY_SIZE)
923+
return createStringError(errc::executable_format_error,
924+
"exception table size error");
925+
926+
const uint64_t SectionAddress = ExceptionsSection->getAddress();
927+
DataExtractor DE(ExceptionsSection->getContents(),
928+
BC.AsmInfo->isLittleEndian(),
929+
BC.AsmInfo->getCodePointerSize());
930+
DataExtractor::Cursor Cursor(0);
931+
uint32_t EntryID = 0;
932+
while (Cursor && Cursor.tell() < ExceptionsSection->getSize()) {
933+
const uint64_t InstAddress =
934+
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
935+
const uint64_t FixupAddress =
936+
SectionAddress + Cursor.tell() + (int32_t)DE.getU32(Cursor);
937+
const uint64_t Data = DE.getU32(Cursor);
938+
939+
// Consume the status of the cursor.
940+
if (!Cursor)
941+
return createStringError(errc::executable_format_error,
942+
"out of bounds while reading exception table");
943+
944+
++EntryID;
945+
946+
if (opts::DumpExceptions) {
947+
BC.outs() << "Exception Entry: " << EntryID << '\n';
948+
BC.outs() << "\tInsn: 0x" << Twine::utohexstr(InstAddress) << '\n'
949+
<< "\tFixup: 0x" << Twine::utohexstr(FixupAddress) << '\n'
950+
<< "\tData: 0x" << Twine::utohexstr(Data) << '\n';
951+
}
952+
953+
MCInst *Inst = nullptr;
954+
MCSymbol *FixupLabel = nullptr;
955+
956+
BinaryFunction *InstBF = BC.getBinaryFunctionContainingAddress(InstAddress);
957+
if (InstBF && BC.shouldEmit(*InstBF)) {
958+
Inst = InstBF->getInstructionAtOffset(InstAddress - InstBF->getAddress());
959+
if (!Inst)
960+
return createStringError(errc::executable_format_error,
961+
"no instruction at address 0x%" PRIx64
962+
" in exception table",
963+
InstAddress);
964+
BC.MIB->addAnnotation(*Inst, "ExceptionEntry", EntryID);
965+
FunctionsWithExceptions.insert(InstBF);
966+
}
967+
968+
if (!InstBF && opts::Verbosity) {
969+
BC.outs() << "BOLT-INFO: no function matches instruction at 0x"
970+
<< Twine::utohexstr(InstAddress)
971+
<< " referenced by Linux exception table\n";
972+
}
973+
974+
BinaryFunction *FixupBF =
975+
BC.getBinaryFunctionContainingAddress(FixupAddress);
976+
if (FixupBF && BC.shouldEmit(*FixupBF)) {
977+
const uint64_t Offset = FixupAddress - FixupBF->getAddress();
978+
if (!FixupBF->getInstructionAtOffset(Offset))
979+
return createStringError(errc::executable_format_error,
980+
"no instruction at fixup address 0x%" PRIx64
981+
" in exception table",
982+
FixupAddress);
983+
FixupLabel = Offset ? FixupBF->addEntryPointAtOffset(Offset)
984+
: FixupBF->getSymbol();
985+
if (Inst)
986+
BC.MIB->addAnnotation(*Inst, "Fixup", FixupLabel->getName());
987+
FunctionsWithExceptions.insert(FixupBF);
988+
}
989+
990+
if (!FixupBF && opts::Verbosity) {
991+
BC.outs() << "BOLT-INFO: no function matches fixup code at 0x"
992+
<< Twine::utohexstr(FixupAddress)
993+
<< " referenced by Linux exception table\n";
994+
}
995+
}
996+
997+
BC.outs() << "BOLT-INFO: parsed "
998+
<< ExceptionsSection->getSize() / EXCEPTION_TABLE_ENTRY_SIZE
999+
<< " exception table entries\n";
1000+
1001+
return Error::success();
1002+
}
1003+
1004+
/// Depending on the value of CONFIG_BUILDTIME_TABLE_SORT, the kernel expects
1005+
/// the exception table to be sorted. Hence we have to sort it after code
1006+
/// reordering.
1007+
Error LinuxKernelRewriter::rewriteExceptionTable() {
1008+
// Disable output of functions with exceptions before rewrite support is
1009+
// added.
1010+
for (BinaryFunction *BF : FunctionsWithExceptions)
1011+
BF->setSimple(false);
1012+
1013+
return Error::success();
1014+
}
1015+
9461016
} // namespace
9471017

9481018
std::unique_ptr<MetadataRewriter>

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
16291629
uint64_t RelType;
16301630
if (Fixup.getKind() == MCFixupKind(AArch64::fixup_aarch64_pcrel_call26))
16311631
RelType = ELF::R_AARCH64_CALL26;
1632+
else if (Fixup.getKind() ==
1633+
MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26))
1634+
RelType = ELF::R_AARCH64_JUMP26;
16321635
else if (FKI.Flags & MCFixupKindInfo::FKF_IsPCRel) {
16331636
switch (FKI.TargetSize) {
16341637
default:

0 commit comments

Comments
 (0)