Skip to content

Commit 60a5121

Browse files
committed
LLVM and SPIRV-LLVM-Translator pulldown (WW46)
LLVM: llvm/llvm-project@9aae3dd SPIRV-LLVM-Translator: [KhronosGroup/SPIRV-LLVM-Translator@bdc5988](KhronosGroup/SPIRV-LLVM-Translator@5ce6a99)
2 parents e39e8eb + 6aeabf8 commit 60a5121

File tree

2,007 files changed

+73524
-44527
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,007 files changed

+73524
-44527
lines changed

bolt/include/bolt/Passes/Hugify.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===- bolt/Passes/Hugify.h -------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef BOLT_PASSES_HUGIFY_H
10+
#define BOLT_PASSES_HUGIFY_H
11+
12+
#include "bolt/Passes/BinaryPasses.h"
13+
14+
namespace llvm {
15+
namespace bolt {
16+
17+
class HugePage : public BinaryFunctionPass {
18+
public:
19+
HugePage(const cl::opt<bool> &PrintPass) : BinaryFunctionPass(PrintPass) {}
20+
21+
void runOnFunctions(BinaryContext &BC) override;
22+
23+
const char *getName() const override { return "HugePage"; }
24+
};
25+
26+
} // namespace bolt
27+
} // namespace llvm
28+
29+
#endif

bolt/include/bolt/RuntimeLibs/HugifyRuntimeLibrary.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ class HugifyRuntimeLibrary : public RuntimeLibrary {
2222
public:
2323
/// Add custom section names generated by the runtime libraries to \p
2424
/// SecNames.
25-
void addRuntimeLibSections(std::vector<std::string> &SecNames) const final {
26-
SecNames.push_back(".bolt.hugify.entries");
27-
}
25+
void addRuntimeLibSections(std::vector<std::string> &SecNames) const final {}
2826

2927
void adjustCommandLineOptions(const BinaryContext &BC) const final;
3028

31-
void emitBinary(BinaryContext &BC, MCStreamer &Streamer) final;
29+
void emitBinary(BinaryContext &BC, MCStreamer &Streamer) final {}
3230

3331
void link(BinaryContext &BC, StringRef ToolPath, RuntimeDyld &RTDyld,
3432
std::function<void(RuntimeDyld &)> OnLoad) final;

bolt/include/bolt/Utils/CommandLineOpts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern llvm::cl::opt<unsigned long long> HeatmapMinAddress;
4444
extern llvm::cl::opt<bool> HotData;
4545
extern llvm::cl::opt<bool> HotFunctionsAtEnd;
4646
extern llvm::cl::opt<bool> HotText;
47+
extern llvm::cl::opt<bool> Hugify;
4748
extern llvm::cl::opt<bool> Instrument;
4849
extern llvm::cl::opt<std::string> OutputFilename;
4950
extern llvm::cl::opt<std::string> PerfData;

bolt/lib/Core/BinaryEmitter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -740,10 +740,12 @@ void BinaryEmitter::emitJumpTables(const BinaryFunction &BF) {
740740

741741
for (auto &JTI : BF.jumpTables()) {
742742
JumpTable &JT = *JTI.second;
743+
// Only emit shared jump tables once, when processing the first parent
744+
if (JT.Parents.size() > 1 && JT.Parents[0] != &BF)
745+
continue;
743746
if (opts::PrintJumpTables)
744747
JT.print(outs());
745-
if ((opts::JumpTables == JTS_BASIC || !BF.isSimple()) &&
746-
BC.HasRelocations) {
748+
if (opts::JumpTables == JTS_BASIC && BC.HasRelocations) {
747749
JT.updateOriginal();
748750
} else {
749751
MCSection *HotSection, *ColdSection;

bolt/lib/Passes/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_llvm_library(LLVMBOLTPasses
1515
FrameOptimizer.cpp
1616
HFSort.cpp
1717
HFSortPlus.cpp
18+
Hugify.cpp
1819
IdenticalCodeFolding.cpp
1920
IndirectCallPromotion.cpp
2021
Inliner.cpp

bolt/lib/Passes/Hugify.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===--- bolt/Passes/Hugify.cpp -------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "bolt/Passes/Hugify.h"
10+
#include "llvm/Support/CommandLine.h"
11+
12+
#define DEBUG_TYPE "bolt-hugify"
13+
14+
using namespace llvm;
15+
16+
namespace llvm {
17+
namespace bolt {
18+
19+
void HugePage::runOnFunctions(BinaryContext &BC) {
20+
auto *RtLibrary = BC.getRuntimeLibrary();
21+
if (!RtLibrary || !BC.isELF() || !BC.StartFunctionAddress) {
22+
return;
23+
}
24+
25+
auto createSimpleFunction =
26+
[&](std::string Title, std::vector<MCInst> Instrs) -> BinaryFunction * {
27+
BinaryFunction *Func = BC.createInjectedBinaryFunction(Title);
28+
29+
std::vector<std::unique_ptr<BinaryBasicBlock>> BBs;
30+
BBs.emplace_back(Func->createBasicBlock(nullptr));
31+
BBs.back()->addInstructions(Instrs.begin(), Instrs.end());
32+
BBs.back()->setCFIState(0);
33+
BBs.back()->setOffset(BinaryBasicBlock::INVALID_OFFSET);
34+
35+
Func->insertBasicBlocks(nullptr, std::move(BBs),
36+
/*UpdateLayout=*/true,
37+
/*UpdateCFIState=*/false);
38+
Func->updateState(BinaryFunction::State::CFG_Finalized);
39+
return Func;
40+
};
41+
42+
const BinaryFunction *const Start =
43+
BC.getBinaryFunctionAtAddress(*BC.StartFunctionAddress);
44+
assert(Start && "Entry point function not found");
45+
const MCSymbol *StartSym = Start->getSymbol();
46+
createSimpleFunction("__bolt_hugify_start_program",
47+
BC.MIB->createSymbolTrampoline(StartSym, BC.Ctx.get()));
48+
}
49+
} // namespace bolt
50+
} // namespace llvm

bolt/lib/Rewrite/BinaryPassManager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "bolt/Passes/AsmDump.h"
1414
#include "bolt/Passes/CMOVConversion.h"
1515
#include "bolt/Passes/FrameOptimizer.h"
16+
#include "bolt/Passes/Hugify.h"
1617
#include "bolt/Passes/IdenticalCodeFolding.h"
1718
#include "bolt/Passes/IndirectCallPromotion.h"
1819
#include "bolt/Passes/Inliner.h"
@@ -333,6 +334,8 @@ void BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
333334

334335
if (opts::Instrument)
335336
Manager.registerPass(std::make_unique<Instrumentation>(NeverPrint));
337+
else if (opts::Hugify)
338+
Manager.registerPass(std::make_unique<HugePage>(NeverPrint));
336339

337340
Manager.registerPass(std::make_unique<ShortenInstructions>(NeverPrint));
338341

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,11 @@ Error RewriteInstance::discoverStorage() {
479479
NextAvailableAddress = alignTo(NextAvailableAddress, BC->PageAlign);
480480
NextAvailableOffset = alignTo(NextAvailableOffset, BC->PageAlign);
481481

482+
// Hugify: Additional huge page from left side due to
483+
// weird ASLR mapping addresses (4KB aligned)
484+
if (opts::Hugify && !BC->HasFixedLoadAddress)
485+
NextAvailableAddress += BC->PageAlign;
486+
482487
if (!opts::UseGnuStack) {
483488
// This is where the black magic happens. Creating PHDR table in a segment
484489
// other than that containing ELF header is tricky. Some loaders and/or
@@ -3719,6 +3724,12 @@ void RewriteInstance::mapCodeSections(RuntimeDyld &RTDyld) {
37193724
Address = alignTo(Address, Section->getAlignment());
37203725
Section->setOutputAddress(Address);
37213726
Address += Section->getOutputSize();
3727+
3728+
// Hugify: Additional huge page from right side due to
3729+
// weird ASLR mapping addresses (4KB aligned)
3730+
if (opts::Hugify && !BC->HasFixedLoadAddress &&
3731+
Section->getName() == BC->getMainCodeSectionName())
3732+
Address = alignTo(Address, Section->getAlignment());
37223733
}
37233734

37243735
// Make sure we allocate enough space for huge pages.

bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -60,35 +60,6 @@ void HugifyRuntimeLibrary::adjustCommandLineOptions(
6060
}
6161
}
6262

63-
void HugifyRuntimeLibrary::emitBinary(BinaryContext &BC, MCStreamer &Streamer) {
64-
const BinaryFunction *StartFunction =
65-
BC.getBinaryFunctionAtAddress(*(BC.StartFunctionAddress));
66-
assert(!StartFunction->isFragment() && "expected main function fragment");
67-
if (!StartFunction) {
68-
errs() << "BOLT-ERROR: failed to locate function at binary start address\n";
69-
exit(1);
70-
}
71-
72-
const auto Flags = BinarySection::getFlags(/*IsReadOnly=*/false,
73-
/*IsText=*/false,
74-
/*IsAllocatable=*/true);
75-
MCSectionELF *Section =
76-
BC.Ctx->getELFSection(".bolt.hugify.entries", ELF::SHT_PROGBITS, Flags);
77-
78-
// __bolt_hugify_init_ptr stores the poiter the hugify library needs to
79-
// jump to after finishing the init code.
80-
MCSymbol *InitPtr = BC.Ctx->getOrCreateSymbol("__bolt_hugify_init_ptr");
81-
82-
Section->setAlignment(llvm::Align(BC.RegularPageSize));
83-
Streamer.switchSection(Section);
84-
85-
Streamer.emitLabel(InitPtr);
86-
Streamer.emitSymbolAttribute(InitPtr, MCSymbolAttr::MCSA_Global);
87-
Streamer.emitValue(
88-
MCSymbolRefExpr::create(StartFunction->getSymbol(), *(BC.Ctx)),
89-
/*Size=*/8);
90-
}
91-
9263
void HugifyRuntimeLibrary::link(BinaryContext &BC, StringRef ToolPath,
9364
RuntimeDyld &RTDyld,
9465
std::function<void(RuntimeDyld &)> OnLoad) {

bolt/runtime/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ set(BOLT_RT_FLAGS
2727
-fno-exceptions
2828
-fno-rtti
2929
-fno-stack-protector
30-
-mno-sse)
30+
-mno-sse
31+
-fPIE)
3132

3233
# Don't let the compiler think it can create calls to standard libs
33-
target_compile_options(bolt_rt_instr PRIVATE ${BOLT_RT_FLAGS} -fPIE)
34+
target_compile_options(bolt_rt_instr PRIVATE ${BOLT_RT_FLAGS})
3435
target_include_directories(bolt_rt_instr PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
3536
target_compile_options(bolt_rt_hugify PRIVATE ${BOLT_RT_FLAGS})
3637
target_include_directories(bolt_rt_hugify PRIVATE ${CMAKE_CURRENT_BINARY_DIR})

bolt/runtime/common.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,22 @@ uint32_t strLen(const char *Str) {
283283
return Size;
284284
}
285285

286+
void *strStr(const char *const Haystack, const char *const Needle) {
287+
int j = 0;
288+
289+
for (int i = 0; i < strLen(Haystack); i++) {
290+
if (Haystack[i] == Needle[0]) {
291+
for (j = 1; j < strLen(Needle); j++) {
292+
if (Haystack[i + j] != Needle[j])
293+
break;
294+
}
295+
if (j == strLen(Needle))
296+
return (void *)&Haystack[i];
297+
}
298+
}
299+
return nullptr;
300+
}
301+
286302
void reportNumber(const char *Msg, uint64_t Num, uint32_t Base) {
287303
char Buf[BufSize];
288304
char *Ptr = Buf;
@@ -310,6 +326,25 @@ unsigned long hexToLong(const char *Str, char Terminator = '\0') {
310326
return Res;
311327
}
312328

329+
/// Starting from character at \p buf, find the longest consecutive sequence
330+
/// of digits (0-9) and convert it to uint32_t. The converted value
331+
/// is put into \p ret. \p end marks the end of the buffer to avoid buffer
332+
/// overflow. The function \returns whether a valid uint32_t value is found.
333+
/// \p buf will be updated to the next character right after the digits.
334+
static bool scanUInt32(const char *&Buf, const char *End, uint32_t &Ret) {
335+
uint64_t Result = 0;
336+
const char *OldBuf = Buf;
337+
while (Buf < End && ((*Buf) >= '0' && (*Buf) <= '9')) {
338+
Result = Result * 10 + (*Buf) - '0';
339+
++Buf;
340+
}
341+
if (OldBuf != Buf && Result <= 0xFFFFFFFFu) {
342+
Ret = static_cast<uint32_t>(Result);
343+
return true;
344+
}
345+
return false;
346+
}
347+
313348
#if !defined(__APPLE__)
314349
// We use a stack-allocated buffer for string manipulation in many pieces of
315350
// this code, including the code that prints each line of the fdata file. This
@@ -387,6 +422,28 @@ int __madvise(void *addr, size_t length, int advice) {
387422
return ret;
388423
}
389424

425+
#define _UTSNAME_LENGTH 65
426+
427+
struct UtsNameTy {
428+
char sysname[_UTSNAME_LENGTH]; /* Operating system name (e.g., "Linux") */
429+
char nodename[_UTSNAME_LENGTH]; /* Name within "some implementation-defined
430+
network" */
431+
char release[_UTSNAME_LENGTH]; /* Operating system release (e.g., "2.6.28") */
432+
char version[_UTSNAME_LENGTH]; /* Operating system version */
433+
char machine[_UTSNAME_LENGTH]; /* Hardware identifier */
434+
char domainname[_UTSNAME_LENGTH]; /* NIS or YP domain name */
435+
};
436+
437+
int __uname(struct UtsNameTy *Buf) {
438+
int Ret;
439+
__asm__ __volatile__("movq $63, %%rax\n"
440+
"syscall\n"
441+
: "=a"(Ret)
442+
: "D"(Buf)
443+
: "cc", "rcx", "r11", "memory");
444+
return Ret;
445+
}
446+
390447
struct timespec {
391448
uint64_t tv_sec; /* seconds */
392449
uint64_t tv_nsec; /* nanoseconds */
@@ -482,6 +539,23 @@ int __fsync(int fd) {
482539
return ret;
483540
}
484541

542+
// %rdi %rsi %rdx %r10 %r8
543+
// sys_prctl int option unsigned unsigned unsigned unsigned
544+
// long arg2 long arg3 long arg4 long arg5
545+
int __prctl(int Option, unsigned long Arg2, unsigned long Arg3,
546+
unsigned long Arg4, unsigned long Arg5) {
547+
int Ret;
548+
register long rdx asm("rdx") = Arg3;
549+
register long r8 asm("r8") = Arg5;
550+
register long r10 asm("r10") = Arg4;
551+
__asm__ __volatile__("movq $157, %%rax\n"
552+
"syscall\n"
553+
: "=a"(Ret)
554+
: "D"(Option), "S"(Arg2), "d"(rdx), "r"(r10), "r"(r8)
555+
:);
556+
return Ret;
557+
}
558+
485559
#endif
486560

487561
void reportError(const char *Msg, uint64_t Size) {

0 commit comments

Comments
 (0)