Skip to content

Commit 2ba28e8

Browse files
committed
LLVM and SPIRV-LLVM-Translator pulldown (WW44)
LLVM: llvm/llvm-project@cb088e8 SPIRV-LLVM-Translator: KhronosGroup/SPIRV-LLVM-Translator@7a559fa
2 parents 9811ef2 + 79509df commit 2ba28e8

File tree

10,401 files changed

+904805
-761493
lines changed

Some content is hidden

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

10,401 files changed

+904805
-761493
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ class BinaryContext {
179179
using NameToSectionMapType = std::multimap<std::string, BinarySection *>;
180180
NameToSectionMapType NameToSection;
181181

182+
/// Map section references to BinarySection for matching sections in the
183+
/// input file to internal section representation.
184+
DenseMap<SectionRef, BinarySection *> SectionRefToBinarySection;
185+
182186
/// Low level section registration.
183187
BinarySection &registerSection(BinarySection *Section);
184188

@@ -224,6 +228,9 @@ class BinaryContext {
224228
/// DWARF line info for CUs.
225229
std::map<unsigned, DwarfLineTable> DwarfLineTablesCUMap;
226230

231+
/// Internal helper for removing section name from a lookup table.
232+
void deregisterSectionName(const BinarySection &Section);
233+
227234
public:
228235
static Expected<std::unique_ptr<BinaryContext>>
229236
createBinaryContext(const ObjectFile *File, bool IsPIC,
@@ -951,13 +958,13 @@ class BinaryContext {
951958
BinarySection &registerSection(SectionRef Section);
952959

953960
/// Register a copy of /p OriginalSection under a different name.
954-
BinarySection &registerSection(StringRef SectionName,
961+
BinarySection &registerSection(const Twine &SectionName,
955962
const BinarySection &OriginalSection);
956963

957964
/// Register or update the information for the section with the given
958965
/// /p Name. If the section already exists, the information in the
959966
/// section will be updated with the new data.
960-
BinarySection &registerOrUpdateSection(StringRef Name, unsigned ELFType,
967+
BinarySection &registerOrUpdateSection(const Twine &Name, unsigned ELFType,
961968
unsigned ELFFlags,
962969
uint8_t *Data = nullptr,
963970
uint64_t Size = 0,
@@ -967,7 +974,7 @@ class BinaryContext {
967974
/// with the given /p Name. If the section already exists, the
968975
/// information in the section will be updated with the new data.
969976
BinarySection &
970-
registerOrUpdateNoteSection(StringRef Name, uint8_t *Data = nullptr,
977+
registerOrUpdateNoteSection(const Twine &Name, uint8_t *Data = nullptr,
971978
uint64_t Size = 0, unsigned Alignment = 1,
972979
bool IsReadOnly = true,
973980
unsigned ELFType = ELF::SHT_PROGBITS) {
@@ -976,10 +983,16 @@ class BinaryContext {
976983
Size, Alignment);
977984
}
978985

986+
/// Remove sections that were preregistered but never used.
987+
void deregisterUnusedSections();
988+
979989
/// Remove the given /p Section from the set of all sections. Return
980990
/// true if the section was removed (and deleted), otherwise false.
981991
bool deregisterSection(BinarySection &Section);
982992

993+
/// Re-register \p Section under the \p NewName.
994+
void renameSection(BinarySection &Section, const Twine &NewName);
995+
983996
/// Iterate over all registered sections.
984997
iterator_range<FilteredSectionIterator> sections() {
985998
auto notNull = [](const SectionIterator &Itr) { return (bool)*Itr; };
@@ -1073,20 +1086,26 @@ class BinaryContext {
10731086
return const_cast<BinaryContext *>(this)->getSectionForAddress(Address);
10741087
}
10751088

1089+
/// Return internal section representation for a section in a file.
1090+
BinarySection *getSectionForSectionRef(SectionRef Section) const {
1091+
return SectionRefToBinarySection.lookup(Section);
1092+
}
1093+
10761094
/// Return section(s) associated with given \p Name.
10771095
iterator_range<NameToSectionMapType::iterator>
1078-
getSectionByName(StringRef Name) {
1079-
return make_range(NameToSection.equal_range(std::string(Name)));
1096+
getSectionByName(const Twine &Name) {
1097+
return make_range(NameToSection.equal_range(Name.str()));
10801098
}
10811099
iterator_range<NameToSectionMapType::const_iterator>
1082-
getSectionByName(StringRef Name) const {
1083-
return make_range(NameToSection.equal_range(std::string(Name)));
1100+
getSectionByName(const Twine &Name) const {
1101+
return make_range(NameToSection.equal_range(Name.str()));
10841102
}
10851103

10861104
/// Return the unique section associated with given \p Name.
10871105
/// If there is more than one section with the same name, return an error
10881106
/// object.
1089-
ErrorOr<BinarySection &> getUniqueSectionByName(StringRef SectionName) const {
1107+
ErrorOr<BinarySection &>
1108+
getUniqueSectionByName(const Twine &SectionName) const {
10901109
auto Sections = getSectionByName(SectionName);
10911110
if (Sections.begin() != Sections.end() &&
10921111
std::next(Sections.begin()) == Sections.end())
@@ -1217,10 +1236,10 @@ class BinaryContext {
12171236
return Size;
12181237
}
12191238

1220-
/// Verify that assembling instruction \p Inst results in the same sequence of
1221-
/// bytes as \p Encoding.
1222-
bool validateEncoding(const MCInst &Instruction,
1223-
ArrayRef<uint8_t> Encoding) const;
1239+
/// Validate that disassembling the \p Sequence of bytes into an instruction
1240+
/// and assembling the instruction again, results in a byte sequence identical
1241+
/// to the original one.
1242+
bool validateInstructionEncoding(ArrayRef<uint8_t> Sequence) const;
12241243

12251244
/// Return a function execution count threshold for determining whether
12261245
/// the function is 'hot'. Consider it hot if count is above the average exec

bolt/include/bolt/Core/BinarySection.h

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ class BinaryData;
4343
class BinarySection {
4444
friend class BinaryContext;
4545

46+
/// Count the number of sections created.
47+
static uint64_t Count;
48+
4649
BinaryContext &BC; // Owning BinaryContext
4750
std::string Name; // Section name
48-
const SectionRef Section; // SectionRef (may be null)
51+
const SectionRef Section; // SectionRef for input binary sections.
4952
StringRef Contents; // Input section contents
5053
const uint64_t Address; // Address of section in input binary (may be 0)
5154
const uint64_t Size; // Input section size
@@ -86,6 +89,7 @@ class BinarySection {
8689
uint64_t OutputSize{0}; // Section size in the rewritten binary.
8790
uint64_t OutputFileOffset{0}; // File offset in the rewritten binary file.
8891
StringRef OutputContents; // Rewritten section contents.
92+
const uint64_t SectionNumber; // Order in which the section was created.
8993
unsigned SectionID{-1u}; // Unique ID used for address mapping.
9094
// Set by ExecutableFileMemoryManager.
9195
uint32_t Index{0}; // Section index in the output file.
@@ -140,20 +144,21 @@ class BinarySection {
140144

141145
public:
142146
/// Copy a section.
143-
explicit BinarySection(BinaryContext &BC, StringRef Name,
147+
explicit BinarySection(BinaryContext &BC, const Twine &Name,
144148
const BinarySection &Section)
145-
: BC(BC), Name(Name), Section(Section.getSectionRef()),
149+
: BC(BC), Name(Name.str()), Section(SectionRef()),
146150
Contents(Section.getContents()), Address(Section.getAddress()),
147151
Size(Section.getSize()), Alignment(Section.getAlignment()),
148152
ELFType(Section.getELFType()), ELFFlags(Section.getELFFlags()),
149153
Relocations(Section.Relocations),
150-
PendingRelocations(Section.PendingRelocations), OutputName(Name) {}
154+
PendingRelocations(Section.PendingRelocations), OutputName(Name.str()),
155+
SectionNumber(++Count) {}
151156

152157
BinarySection(BinaryContext &BC, SectionRef Section)
153158
: BC(BC), Name(getName(Section)), Section(Section),
154159
Contents(getContents(Section)), Address(Section.getAddress()),
155160
Size(Section.getSize()), Alignment(Section.getAlignment()),
156-
OutputName(Name) {
161+
OutputName(Name), SectionNumber(++Count) {
157162
if (isELF()) {
158163
ELFType = ELFSectionRef(Section).getType();
159164
ELFFlags = ELFSectionRef(Section).getFlags();
@@ -167,13 +172,14 @@ class BinarySection {
167172
}
168173

169174
// TODO: pass Data as StringRef/ArrayRef? use StringRef::copy method.
170-
BinarySection(BinaryContext &BC, StringRef Name, uint8_t *Data, uint64_t Size,
171-
unsigned Alignment, unsigned ELFType, unsigned ELFFlags)
172-
: BC(BC), Name(Name),
175+
BinarySection(BinaryContext &BC, const Twine &Name, uint8_t *Data,
176+
uint64_t Size, unsigned Alignment, unsigned ELFType,
177+
unsigned ELFFlags)
178+
: BC(BC), Name(Name.str()),
173179
Contents(reinterpret_cast<const char *>(Data), Data ? Size : 0),
174180
Address(0), Size(Size), Alignment(Alignment), ELFType(ELFType),
175-
ELFFlags(ELFFlags), IsFinalized(true), OutputName(Name),
176-
OutputSize(Size), OutputContents(Contents) {
181+
ELFFlags(ELFFlags), IsFinalized(true), OutputName(Name.str()),
182+
OutputSize(Size), OutputContents(Contents), SectionNumber(++Count) {
177183
assert(Alignment > 0 && "section alignment must be > 0");
178184
}
179185

@@ -207,10 +213,34 @@ class BinarySection {
207213

208214
// Order sections by their immutable properties.
209215
bool operator<(const BinarySection &Other) const {
210-
return (getAddress() < Other.getAddress() ||
211-
(getAddress() == Other.getAddress() &&
212-
(getSize() < Other.getSize() ||
213-
(getSize() == Other.getSize() && getName() < Other.getName()))));
216+
// Allocatable before non-allocatable.
217+
if (isAllocatable() != Other.isAllocatable())
218+
return isAllocatable() > Other.isAllocatable();
219+
220+
// Input sections take precedence.
221+
if (hasSectionRef() != Other.hasSectionRef())
222+
return hasSectionRef() > Other.hasSectionRef();
223+
224+
// Compare allocatable input sections by their address.
225+
if (hasSectionRef() && getAddress() != Other.getAddress())
226+
return getAddress() < Other.getAddress();
227+
if (hasSectionRef() && getAddress() && getSize() != Other.getSize())
228+
return getSize() < Other.getSize();
229+
230+
// Code before data.
231+
if (isText() != Other.isText())
232+
return isText() > Other.isText();
233+
234+
// Read-only before writable.
235+
if (isReadOnly() != Other.isReadOnly())
236+
return isReadOnly() > Other.isReadOnly();
237+
238+
// BSS at the end.
239+
if (isBSS() != Other.isBSS())
240+
return isBSS() < Other.isBSS();
241+
242+
// Otherwise, preserve the order of creation.
243+
return SectionNumber < Other.SectionNumber;
214244
}
215245

216246
///
@@ -228,13 +258,13 @@ class BinarySection {
228258
bool isText() const {
229259
if (isELF())
230260
return (ELFFlags & ELF::SHF_EXECINSTR);
231-
return getSectionRef().isText();
261+
return hasSectionRef() && getSectionRef().isText();
232262
}
233263
bool isData() const {
234264
if (isELF())
235265
return (ELFType == ELF::SHT_PROGBITS &&
236266
(ELFFlags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)));
237-
return getSectionRef().isData();
267+
return hasSectionRef() && getSectionRef().isData();
238268
}
239269
bool isBSS() const {
240270
return (ELFType == ELF::SHT_NOBITS &&
@@ -406,6 +436,7 @@ class BinarySection {
406436
return SectionID;
407437
}
408438
bool hasValidSectionID() const { return SectionID != -1u; }
439+
bool hasValidIndex() { return Index != 0; }
409440
uint32_t getIndex() const { return Index; }
410441

411442
// mutation
@@ -416,12 +447,12 @@ class BinarySection {
416447
SectionID = ID;
417448
}
418449
void setIndex(uint32_t I) { Index = I; }
419-
void setOutputName(StringRef Name) { OutputName = std::string(Name); }
450+
void setOutputName(const Twine &Name) { OutputName = Name.str(); }
420451
void setAnonymous(bool Flag) { IsAnonymous = Flag; }
421452

422-
/// Emit the section as data, possibly with relocations. Use name \p NewName
423-
// for the section during emission if non-empty.
424-
void emitAsData(MCStreamer &Streamer, StringRef NewName = StringRef()) const;
453+
/// Emit the section as data, possibly with relocations.
454+
/// Use name \p SectionName for the section during the emission.
455+
void emitAsData(MCStreamer &Streamer, const Twine &SectionName) const;
425456

426457
using SymbolResolverFuncTy = llvm::function_ref<uint64_t(const MCSymbol *)>;
427458

@@ -430,6 +461,13 @@ class BinarySection {
430461
void flushPendingRelocations(raw_pwrite_stream &OS,
431462
SymbolResolverFuncTy Resolver);
432463

464+
/// Change contents of the section.
465+
void updateContents(const uint8_t *Data, size_t NewSize) {
466+
OutputContents = StringRef(reinterpret_cast<const char *>(Data), NewSize);
467+
OutputSize = NewSize;
468+
IsFinalized = true;
469+
}
470+
433471
/// Reorder the contents of this section according to /p Order. If
434472
/// /p Inplace is true, the entire contents of the section is reordered,
435473
/// otherwise the new contents contain only the reordered data.

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,8 +1266,18 @@ class MCPlusBuilder {
12661266
/// Replace displacement in compound memory operand with given \p Label.
12671267
bool replaceMemOperandDisp(MCInst &Inst, const MCSymbol *Label,
12681268
MCContext *Ctx) const {
1269-
return replaceMemOperandDisp(
1270-
Inst, MCOperand::createExpr(MCSymbolRefExpr::create(Label, *Ctx)));
1269+
return replaceMemOperandDisp(Inst, Label, 0, Ctx);
1270+
}
1271+
1272+
/// Replace displacement in compound memory operand with given \p Label
1273+
/// plus addend.
1274+
bool replaceMemOperandDisp(MCInst &Inst, const MCSymbol *Label,
1275+
int64_t Addend, MCContext *Ctx) const {
1276+
MCInst::iterator MemOpI = getMemOperandDisp(Inst);
1277+
if (MemOpI == Inst.end())
1278+
return false;
1279+
return setOperandToSymbolRef(Inst, MemOpI - Inst.begin(), Label, Addend,
1280+
Ctx, 0);
12711281
}
12721282

12731283
/// Returns how many bits we have in this instruction to encode a PC-rel
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===- bolt/Passes/ValidateMemRefs.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_VALIDATEMEMREFS_H
10+
#define BOLT_PASSES_VALIDATEMEMREFS_H
11+
12+
#include "bolt/Passes/BinaryPasses.h"
13+
14+
namespace llvm::bolt {
15+
16+
/// Post processing to check for memory references that cause a symbol
17+
/// in data section to be ambiguous, requiring us to avoid moving that
18+
/// object or disambiguating such references. This is currently
19+
/// limited to fixing false references to the location of jump tables.
20+
///
21+
class ValidateMemRefs : public BinaryFunctionPass {
22+
public:
23+
explicit ValidateMemRefs(const cl::opt<bool> &PrintPass)
24+
: BinaryFunctionPass(PrintPass) {}
25+
26+
const char *getName() const override { return "validate-mem-refs"; }
27+
28+
void runOnFunctions(BinaryContext &BC) override;
29+
30+
private:
31+
bool checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
32+
uint32_t OperandNum, const MCSymbol *Sym,
33+
uint64_t Offset);
34+
void runOnFunction(BinaryFunction &BF);
35+
36+
static std::atomic<std::uint64_t> ReplacedReferences;
37+
};
38+
39+
} // namespace llvm::bolt
40+
41+
#endif

bolt/include/bolt/Rewrite/ExecutableFileMemoryManager.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ class ExecutableFileMemoryManager : public RuntimeDyld::MemoryManager {
3535
};
3636
SmallVector<AllocInfo, 8> AllocatedSections;
3737

38+
// All new sections will be identified by the following prefix.
39+
std::string NewSecPrefix;
40+
41+
// Name prefix used for sections from the input.
42+
std::string OrgSecPrefix;
43+
3844
public:
3945
// Our linker's main purpose is to handle a single object file, created
4046
// by RewriteInstance after reading the input binary and reordering it.
@@ -86,6 +92,10 @@ class ExecutableFileMemoryManager : public RuntimeDyld::MemoryManager {
8692
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
8793
size_t Size) override {}
8894
void deregisterEHFrames() override {}
95+
96+
/// Section name management.
97+
void setNewSecPrefix(StringRef Prefix) { NewSecPrefix = Prefix; }
98+
void setOrgSecPrefix(StringRef Prefix) { OrgSecPrefix = Prefix; }
8999
};
90100

91101
} // namespace bolt

bolt/include/bolt/Rewrite/MachORewriteInstance.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class MachORewriteInstance {
4646
void processProfileDataPreCFG();
4747
void processProfileData();
4848

49+
static StringRef getNewSecPrefix() { return ".bolt.new"; }
4950
static StringRef getOrgSecPrefix() { return ".bolt.org"; }
5051

5152
void mapInstrumentationSection(StringRef SectionName);

0 commit comments

Comments
 (0)