Skip to content

Commit 3f4883e

Browse files
openeuler-ci-botgitee-org
authored andcommitted
!173 [BOLT] Add support for kernel instrumentation of aarch64
From: @polaris_jiang Reviewed-by: @chenzheng1030, @liyunfei33 Signed-off-by: @liyunfei33
2 parents 2e6e287 + 526ac9c commit 3f4883e

Some content is hidden

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

57 files changed

+2362
-452
lines changed

bolt/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ if (LLVM_INCLUDE_TESTS)
8989
endif()
9090

9191
if (BOLT_ENABLE_RUNTIME)
92-
message(STATUS "Building BOLT runtime libraries for X86")
92+
message(STATUS "Building BOLT runtime libraries")
9393
set(extra_args "")
9494
if(CMAKE_SYSROOT)
9595
list(APPEND extra_args -DCMAKE_SYSROOT=${CMAKE_SYSROOT})

bolt/docs/CommandLineArgumentReference.md

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,6 @@
5656

5757
Allow processing of stripped binaries
5858

59-
- `--alt-inst-feature-size=<uint>`
60-
61-
Size of feature field in .altinstructions
62-
63-
- `--alt-inst-has-padlen`
64-
65-
Specify that .altinstructions has padlen field
66-
6759
- `--asm-dump[=<dump folder>]`
6860

6961
Dump function into assembly
@@ -250,10 +242,6 @@
250242

251243
Redirect journaling to a file instead of stdout/stderr
252244

253-
- `--long-jump-labels`
254-
255-
Always use long jumps/nops for Linux kernel static keys
256-
257245
- `--match-profile-with-function-hash`
258246

259247
Match profile with function hash

bolt/include/bolt/Core/BinaryBasicBlock.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,17 +689,24 @@ class BinaryBasicBlock {
689689

690690
void setCanOutline(const bool Flag) { CanOutline = Flag; }
691691

692+
void undefineLabels() {
693+
for (const MCInst &Inst : Instructions)
694+
undefineInstLabel(Inst);
695+
}
696+
692697
/// Erase pseudo instruction at a given iterator.
693698
/// Return iterator following the removed instruction.
694699
iterator erasePseudoInstruction(iterator II) {
695700
--NumPseudos;
701+
undefineInstLabel(*II);
696702
return Instructions.erase(II);
697703
}
698704

699705
/// Erase non-pseudo instruction at a given iterator \p II.
700706
/// Return iterator following the removed instruction.
701707
iterator eraseInstruction(iterator II) {
702708
adjustNumPseudos(*II, -1);
709+
undefineInstLabel(*II);
703710
return Instructions.erase(II);
704711
}
705712

@@ -717,6 +724,7 @@ class BinaryBasicBlock {
717724

718725
/// Erase all instructions.
719726
void clear() {
727+
undefineLabels();
720728
Instructions.clear();
721729
NumPseudos = 0;
722730
}
@@ -741,6 +749,7 @@ class BinaryBasicBlock {
741749
adjustNumPseudos(Begin, End, 1);
742750

743751
auto I = II - Instructions.begin();
752+
undefineInstLabel(*II);
744753
Instructions.insert(Instructions.erase(II), Begin, End);
745754
return I + Instructions.begin();
746755
}
@@ -913,6 +922,8 @@ class BinaryBasicBlock {
913922
uint64_t getHash() const { return Hash; }
914923

915924
private:
925+
void undefineInstLabel(const llvm::MCInst &Inst);
926+
916927
void adjustNumPseudos(const MCInst &Inst, int Sign);
917928

918929
template <typename Itr> void adjustNumPseudos(Itr Begin, Itr End, int Sign) {

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,13 @@ class BinaryContext {
426426
Address);
427427
}
428428

429+
bool isInRange(StringRef NameStart, StringRef NameEnd,
430+
uint64_t Address) const {
431+
ErrorOr<uint64_t> Start = getSymbolValue(NameStart);
432+
ErrorOr<uint64_t> End = getSymbolValue(NameEnd);
433+
return Start && End && *Start <= Address && Address < *End;
434+
}
435+
429436
/// Return size of an entry for the given jump table \p Type.
430437
uint64_t getJumpTableEntrySize(JumpTable::JumpTableType Type) const {
431438
return Type == JumpTable::JTT_PIC ? 4 : AsmInfo->getCodePointerSize();
@@ -538,6 +545,11 @@ class BinaryContext {
538545
/// binary and functions created by BOLT.
539546
std::vector<BinaryFunction *> getAllBinaryFunctions();
540547

548+
void undefineInstLabel(const MCInst &Inst) {
549+
if (MCSymbol *const Label = MIB->getInstLabel(Inst))
550+
UndefinedSymbols.insert(Label);
551+
}
552+
541553
/// Construct a jump table for \p Function at \p Address or return an existing
542554
/// one at that location.
543555
///
@@ -606,6 +618,9 @@ class BinaryContext {
606618
/// Addresses reserved for kernel on x86_64 start at this location.
607619
static constexpr uint64_t KernelStartX86_64 = 0xFFFF'FFFF'8000'0000;
608620

621+
/// Addresses reserved for kernel on aarch64 start at this location.
622+
static constexpr uint64_t KernelStartAArch64 = 0xFFFF'0000'0000'0000;
623+
609624
/// Map address to a constant island owner (constant data in code section)
610625
std::map<uint64_t, BinaryFunction *> AddressToConstantIslandMap;
611626

@@ -749,6 +764,8 @@ class BinaryContext {
749764
/// Area in the input binary reserved for BOLT.
750765
AddressRange BOLTReserved;
751766

767+
AddressRange BOLTReservedRW;
768+
752769
/// Address of the code/function that is executed before any other code in
753770
/// the binary.
754771
std::optional<uint64_t> StartFunctionAddress;
@@ -884,7 +901,11 @@ class BinaryContext {
884901
/// Return a value of the global \p Symbol or an error if the value
885902
/// was not set.
886903
ErrorOr<uint64_t> getSymbolValue(const MCSymbol &Symbol) const {
887-
const BinaryData *BD = getBinaryDataByName(Symbol.getName());
904+
return getSymbolValue(Symbol.getName());
905+
}
906+
907+
ErrorOr<uint64_t> getSymbolValue(StringRef Name) const {
908+
const BinaryData *BD = getBinaryDataByName(Name);
888909
if (!BD)
889910
return std::make_error_code(std::errc::bad_address);
890911
return BD->getAddress();
@@ -1202,6 +1223,13 @@ class BinaryContext {
12021223
return const_cast<BinaryContext *>(this)->getSectionForAddress(Address);
12031224
}
12041225

1226+
ErrorOr<BinarySection &> getSectionForOutputAddress(uint64_t Address);
1227+
ErrorOr<const BinarySection &>
1228+
getSectionForOutputAddress(uint64_t Address) const {
1229+
return const_cast<BinaryContext *>(this)->getSectionForOutputAddress(
1230+
Address);
1231+
}
1232+
12051233
/// Return internal section representation for a section in a file.
12061234
BinarySection *getSectionForSectionRef(SectionRef Section) const {
12071235
return SectionRefToBinarySection.lookup(Section);

bolt/include/bolt/Core/BinaryData.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ class BinaryData {
169169
return Parent && (Parent == BD || Parent->isAncestorOf(BD));
170170
}
171171

172+
void updateSize(uint64_t N) {
173+
if (N > Size)
174+
Size = N;
175+
}
176+
172177
void setIsMoveable(bool Flag) { IsMoveable = Flag; }
173178
void setSection(BinarySection &NewSection);
174179
void setOutputSection(BinarySection &NewSection) {

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ class BinaryFunction {
295295
/// Pseudo functions should not be disassembled or emitted.
296296
bool IsPseudo{false};
297297

298+
// True if address of this function can not be changed
299+
bool KeepAddress{false};
300+
301+
// True if code of this function might be changed at run time
302+
bool MayChange{false};
303+
298304
/// True if the original function code has all necessary relocations to track
299305
/// addresses of functions emitted to new locations. Typically set for
300306
/// functions that we are not going to emit.
@@ -1176,6 +1182,21 @@ class BinaryFunction {
11761182
/// Return true if all callbacks returned true, false otherwise.
11771183
bool forEachEntryPoint(EntryPointCallbackTy Callback) const;
11781184

1185+
void undefineLabels() {
1186+
for (std::pair<const uint32_t, MCSymbol *> &LI : Labels)
1187+
BC.UndefinedSymbols.insert(LI.second);
1188+
1189+
for (MCSymbol *const EndLabel : FunctionEndLabels)
1190+
if (EndLabel)
1191+
BC.UndefinedSymbols.insert(EndLabel);
1192+
1193+
for (const std::pair<const uint32_t, MCInst> &II : Instructions)
1194+
BC.undefineInstLabel(II.second);
1195+
1196+
for (BinaryBasicBlock *BB : BasicBlocks)
1197+
BB->undefineLabels();
1198+
}
1199+
11791200
/// Return MC symbol associated with the end of the function.
11801201
MCSymbol *
11811202
getFunctionEndLabel(const FragmentNum Fragment = FragmentNum::main()) const {
@@ -1221,6 +1242,17 @@ class BinaryFunction {
12211242
return Islands->FunctionColdConstantIslandLabel;
12221243
}
12231244

1245+
const FunctionFragment *
1246+
getFunctionFragmentForOutputAddress(uint64_t OutputAddress) const {
1247+
for (const FunctionFragment &FF : Layout.fragments()) {
1248+
uint64_t Address = FF.getAddress();
1249+
uint64_t Size = FF.getImageSize();
1250+
if (Address <= OutputAddress && OutputAddress < Address + Size)
1251+
return &FF;
1252+
}
1253+
return nullptr;
1254+
}
1255+
12241256
/// Return true if this is a function representing a PLT entry.
12251257
bool isPLTFunction() const { return PLTSymbol != nullptr; }
12261258

@@ -1296,6 +1328,12 @@ class BinaryFunction {
12961328
/// otherwise processed.
12971329
bool isPseudo() const { return IsPseudo; }
12981330

1331+
/// Return true if address of this function can not be changed
1332+
bool mustKeepAddress() const { return KeepAddress; }
1333+
1334+
/// Return true if code of this function might be changed at run time
1335+
bool mayChange() const { return MayChange; }
1336+
12991337
/// Return true if the function contains explicit or implicit indirect branch
13001338
/// to its split fragments, e.g., split jump table, landing pad in split
13011339
/// fragment.
@@ -1723,6 +1761,8 @@ class BinaryFunction {
17231761
/// Mark the function as using ORC format for stack unwinding.
17241762
void setHasORC(bool V) { HasORC = V; }
17251763

1764+
void setMayChange() { MayChange = true; }
1765+
17261766
BinaryFunction &setPersonalityFunction(uint64_t Addr) {
17271767
assert(!PersonalityFunction && "can't set personality function twice");
17281768
PersonalityFunction = BC.getOrCreateGlobalSymbol(Addr, "FUNCat");

bolt/include/bolt/Core/BinarySection.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,10 @@ class BinarySection {
390390
Patches.emplace_back(BinaryPatch(Offset, Bytes));
391391
}
392392

393+
void addPatch(uint64_t Offset, StringRef Bytes) {
394+
addPatch(Offset, SmallVector<char>(Bytes.begin(), Bytes.end()));
395+
}
396+
393397
/// Register patcher for this section.
394398
void registerPatcher(std::unique_ptr<BinaryPatcher> BPatcher) {
395399
Patcher = std::move(BPatcher);

bolt/include/bolt/Core/FunctionLayout.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ class FunctionFragment {
117117
uint64_t getFileOffset() const { return FileOffset; }
118118
void setFileOffset(uint64_t Offset) { FileOffset = Offset; }
119119

120+
uint8_t *getOutputData() const {
121+
return reinterpret_cast<uint8_t *>(getImageAddress());
122+
}
123+
120124
unsigned size() const { return Size; };
121125
bool empty() const { return size() == 0; };
122126
iterator begin();

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,12 @@ class MCPlusBuilder {
672672
return StringRef();
673673
}
674674

675+
/// Used to fill the executable space with undefined instructions.
676+
virtual StringRef getUndefFillValue() const {
677+
llvm_unreachable("not implemented");
678+
return StringRef();
679+
}
680+
675681
/// Interface and basic functionality of a MCInstMatcher. The idea is to make
676682
/// it easy to match one or more MCInsts against a tree-like pattern and
677683
/// extract the fragment operands. Example:

bolt/include/bolt/Core/Relocation.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ struct Relocation {
9292
/// Return true if relocation type is RELATIVE
9393
static bool isRelative(uint64_t Type);
9494

95+
/// Return true if relocation type is GLOB_DAT
96+
static bool isGlobDat(uint64_t Type);
97+
9598
/// Return true if relocation type is IRELATIVE
9699
static bool isIRelative(uint64_t Type);
97100

@@ -124,6 +127,10 @@ struct Relocation {
124127
/// otherwise.
125128
bool isRelative() const { return isRelative(Type); }
126129

130+
/// Return true if this relocation is R_*_GLOB_DAT type. Return false
131+
/// otherwise.
132+
bool isGlobDat() const { return isGlobDat(Type); }
133+
127134
/// Return true if this relocation is R_*_IRELATIVE type. Return false
128135
/// otherwise.
129136
bool isIRelative() const { return isIRelative(Type); }

0 commit comments

Comments
 (0)