Skip to content

Commit 4a14784

Browse files
authored
Merge branch 'main' into emualteF8E8M0
2 parents a3dee48 + 94142d9 commit 4a14784

File tree

2,418 files changed

+104218
-39836
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,418 files changed

+104218
-39836
lines changed

.ci/generate_test_report_lib.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ def plural(num_tests):
9292
]
9393
)
9494
elif failures:
95-
report.extend(["", "## Failed Tests", "(click on a test name to see its output)"])
95+
report.extend(
96+
["", "## Failed Tests", "(click on a test name to see its output)"]
97+
)
9698

9799
for testsuite_name, failures in failures.items():
98100
report.extend(["", f"### {testsuite_name}"])

.ci/metrics/metrics.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
# remain small.
6868
BUILDKITE_GRAPHQL_BUILDS_PER_PAGE = 50
6969

70+
7071
@dataclass
7172
class JobMetrics:
7273
job_name: str
@@ -77,6 +78,7 @@ class JobMetrics:
7778
workflow_id: int
7879
workflow_name: str
7980

81+
8082
@dataclass
8183
class GaugeMetric:
8284
name: str
@@ -258,6 +260,7 @@ def buildkite_get_metrics(
258260

259261
return output, incomplete_now
260262

263+
261264
def github_get_metrics(
262265
github_repo: github.Repository, last_workflows_seen_as_completed: set[int]
263266
) -> tuple[list[JobMetrics], int]:

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,19 @@ class BinaryFunction {
804804
return iterator_range<const_cfi_iterator>(cie_begin(), cie_end());
805805
}
806806

807+
/// Iterate over instructions (only if CFG is unavailable or not built yet).
808+
iterator_range<InstrMapType::iterator> instrs() {
809+
assert(!hasCFG() && "Iterate over basic blocks instead");
810+
return make_range(Instructions.begin(), Instructions.end());
811+
}
812+
iterator_range<InstrMapType::const_iterator> instrs() const {
813+
assert(!hasCFG() && "Iterate over basic blocks instead");
814+
return make_range(Instructions.begin(), Instructions.end());
815+
}
816+
817+
/// Returns whether there are any labels at Offset.
818+
bool hasLabelAt(unsigned Offset) const { return Labels.count(Offset) != 0; }
819+
807820
/// Iterate over all jump tables associated with this function.
808821
iterator_range<std::map<uint64_t, JumpTable *>::const_iterator>
809822
jumpTables() const {

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class MCSymbol;
4949
class raw_ostream;
5050

5151
namespace bolt {
52+
class BinaryBasicBlock;
5253
class BinaryFunction;
5354

5455
/// Different types of indirect branches encountered during disassembly.
@@ -572,6 +573,11 @@ class MCPlusBuilder {
572573
return false;
573574
}
574575

576+
virtual MCPhysReg getSignedReg(const MCInst &Inst) const {
577+
llvm_unreachable("not implemented");
578+
return getNoRegister();
579+
}
580+
575581
virtual ErrorOr<MCPhysReg> getRegUsedAsRetDest(const MCInst &Inst) const {
576582
llvm_unreachable("not implemented");
577583
return getNoRegister();
@@ -622,6 +628,54 @@ class MCPlusBuilder {
622628
return std::make_pair(getNoRegister(), getNoRegister());
623629
}
624630

631+
/// Analyzes if a pointer is checked to be authenticated successfully
632+
/// by the end of the basic block.
633+
///
634+
/// It is possible for pointer authentication instructions not to terminate
635+
/// the program abnormally on authentication failure and return some invalid
636+
/// pointer instead (like it is done on AArch64 when FEAT_FPAC is not
637+
/// implemented). This might be enough to crash on invalid memory access when
638+
/// the pointer is later used as the destination of a load, store, or branch
639+
/// instruction. On the other hand, when the pointer is not used right away,
640+
/// it may be important for the compiler to check the address explicitly not
641+
/// to introduce a signing or authentication oracle.
642+
///
643+
/// This function is intended to detect a complex, multi-instruction pointer-
644+
/// checking sequence spanning a contiguous range of instructions at the end
645+
/// of the basic block (as these sequences are expected to end with a
646+
/// conditional branch - this is how they are implemented on AArch64 by LLVM).
647+
/// If a (Reg, FirstInst) pair is returned and before execution of FirstInst
648+
/// Reg was last written to by an authentication instruction, then it is known
649+
/// that in any successor of BB either
650+
/// * the authentication instruction that last wrote to Reg succeeded, or
651+
/// * the program is terminated abnormally without introducing any signing
652+
/// or authentication oracles
653+
///
654+
/// Note that this function is not expected to repeat the results returned
655+
/// by getAuthCheckedReg(Inst, MayOverwrite) function below.
656+
virtual std::optional<std::pair<MCPhysReg, MCInst *>>
657+
getAuthCheckedReg(BinaryBasicBlock &BB) const {
658+
llvm_unreachable("not implemented");
659+
return std::nullopt;
660+
}
661+
662+
/// Returns the register that is checked to be authenticated successfully.
663+
///
664+
/// If the returned register was last written to by an authentication
665+
/// instruction and that authentication failed, then the program is known
666+
/// to be terminated abnormally as a result of execution of Inst.
667+
///
668+
/// Additionally, if MayOverwrite is false, it is known that the authenticated
669+
/// pointer is not clobbered by Inst itself.
670+
///
671+
/// Use this function for simple, single-instruction patterns instead of
672+
/// its getAuthCheckedReg(BB) counterpart.
673+
virtual MCPhysReg getAuthCheckedReg(const MCInst &Inst,
674+
bool MayOverwrite) const {
675+
llvm_unreachable("not implemented");
676+
return getNoRegister();
677+
}
678+
625679
virtual bool isTerminator(const MCInst &Inst) const;
626680

627681
virtual bool isNoop(const MCInst &Inst) const {

bolt/include/bolt/Passes/PAuthGadgetScanner.h

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "bolt/Core/BinaryContext.h"
1313
#include "bolt/Core/BinaryFunction.h"
1414
#include "bolt/Passes/BinaryPasses.h"
15-
#include "llvm/ADT/SmallSet.h"
1615
#include "llvm/Support/raw_ostream.h"
1716
#include <memory>
1817

@@ -65,6 +64,14 @@ struct MCInstInBFReference {
6564
uint64_t Offset;
6665
MCInstInBFReference(BinaryFunction *BF, uint64_t Offset)
6766
: BF(BF), Offset(Offset) {}
67+
68+
static MCInstInBFReference get(const MCInst *Inst, BinaryFunction &BF) {
69+
for (auto &I : BF.instrs())
70+
if (Inst == &I.second)
71+
return MCInstInBFReference(&BF, I.first);
72+
return {};
73+
}
74+
6875
MCInstInBFReference() : BF(nullptr), Offset(0) {}
6976
bool operator==(const MCInstInBFReference &RHS) const {
7077
return BF == RHS.BF && Offset == RHS.Offset;
@@ -104,6 +111,12 @@ struct MCInstReference {
104111
MCInstReference(BinaryFunction *BF, uint32_t Offset)
105112
: MCInstReference(MCInstInBFReference(BF, Offset)) {}
106113

114+
static MCInstReference get(const MCInst *Inst, BinaryFunction &BF) {
115+
if (BF.hasCFG())
116+
return MCInstInBBReference::get(Inst, BF);
117+
return MCInstInBFReference::get(Inst, BF);
118+
}
119+
107120
bool operator<(const MCInstReference &RHS) const {
108121
if (ParentKind != RHS.ParentKind)
109122
return ParentKind < RHS.ParentKind;
@@ -138,6 +151,16 @@ struct MCInstReference {
138151
llvm_unreachable("");
139152
}
140153

154+
operator bool() const {
155+
switch (ParentKind) {
156+
case BasicBlockParent:
157+
return U.BBRef.BB != nullptr;
158+
case FunctionParent:
159+
return U.BFRef.BF != nullptr;
160+
}
161+
llvm_unreachable("");
162+
}
163+
141164
uint64_t getAddress() const {
142165
switch (ParentKind) {
143166
case BasicBlockParent:
@@ -173,9 +196,6 @@ raw_ostream &operator<<(raw_ostream &OS, const MCInstReference &);
173196

174197
namespace PAuthGadgetScanner {
175198

176-
class SrcSafetyAnalysis;
177-
struct SrcState;
178-
179199
/// Description of a gadget kind that can be detected. Intended to be
180200
/// statically allocated to be attached to reports by reference.
181201
class GadgetKind {
@@ -184,7 +204,7 @@ class GadgetKind {
184204
public:
185205
GadgetKind(const char *Description) : Description(Description) {}
186206

187-
const StringRef getDescription() const { return Description; }
207+
StringRef getDescription() const { return Description; }
188208
};
189209

190210
/// Base report located at some instruction, without any additional information.
@@ -199,8 +219,8 @@ struct Report {
199219

200220
// The two methods below are called by Analysis::computeDetailedInfo when
201221
// iterating over the reports.
202-
virtual const ArrayRef<MCPhysReg> getAffectedRegisters() const { return {}; }
203-
virtual void setOverwritingInstrs(const ArrayRef<MCInstReference> Instrs) {}
222+
virtual ArrayRef<MCPhysReg> getAffectedRegisters() const { return {}; }
223+
virtual void setOverwritingInstrs(ArrayRef<MCInstReference> Instrs) {}
204224

205225
void printBasicInfo(raw_ostream &OS, const BinaryContext &BC,
206226
StringRef IssueKind) const;
@@ -223,19 +243,19 @@ struct GadgetReport : public Report {
223243

224244
void generateReport(raw_ostream &OS, const BinaryContext &BC) const override;
225245

226-
const ArrayRef<MCPhysReg> getAffectedRegisters() const override {
246+
ArrayRef<MCPhysReg> getAffectedRegisters() const override {
227247
return AffectedRegisters;
228248
}
229249

230-
void setOverwritingInstrs(const ArrayRef<MCInstReference> Instrs) override {
250+
void setOverwritingInstrs(ArrayRef<MCInstReference> Instrs) override {
231251
OverwritingInstrs.assign(Instrs.begin(), Instrs.end());
232252
}
233253
};
234254

235255
/// Report with a free-form message attached.
236256
struct GenericReport : public Report {
237257
std::string Text;
238-
GenericReport(MCInstReference Location, const std::string &Text)
258+
GenericReport(MCInstReference Location, StringRef Text)
239259
: Report(Location), Text(Text) {}
240260
virtual void generateReport(raw_ostream &OS,
241261
const BinaryContext &BC) const override;

bolt/include/bolt/Profile/DataReader.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,8 @@ struct FuncBranchData {
114114

115115
FuncBranchData() {}
116116

117-
FuncBranchData(StringRef Name, ContainerTy Data)
118-
: Name(Name), Data(std::move(Data)) {}
119-
120-
FuncBranchData(StringRef Name, ContainerTy Data, ContainerTy EntryData)
117+
FuncBranchData(StringRef Name, ContainerTy Data = ContainerTy(),
118+
ContainerTy EntryData = ContainerTy())
121119
: Name(Name), Data(std::move(Data)), EntryData(std::move(EntryData)) {}
122120

123121
ErrorOr<const BranchInfo &> getBranch(uint64_t From, uint64_t To) const;
@@ -205,7 +203,7 @@ struct FuncMemData {
205203

206204
FuncMemData() {}
207205

208-
FuncMemData(StringRef Name, ContainerTy Data)
206+
FuncMemData(StringRef Name, ContainerTy Data = ContainerTy())
209207
: Name(Name), Data(std::move(Data)) {}
210208
};
211209

@@ -241,7 +239,7 @@ struct FuncBasicSampleData {
241239
StringRef Name;
242240
ContainerTy Data;
243241

244-
FuncBasicSampleData(StringRef Name, ContainerTy Data)
242+
FuncBasicSampleData(StringRef Name, ContainerTy Data = ContainerTy())
245243
: Name(Name), Data(std::move(Data)) {}
246244

247245
/// Get the number of samples recorded in [Start, End)

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,10 +1783,22 @@ bool BinaryFunction::scanExternalRefs() {
17831783
// On AArch64, we use instruction patches for fixing references. We make an
17841784
// exception for branch instructions since they require optional
17851785
// relocations.
1786-
if (BC.isAArch64() && !BranchTargetSymbol) {
1787-
LLVM_DEBUG(BC.printInstruction(dbgs(), Instruction, AbsoluteInstrAddr));
1788-
InstructionPatches.push_back({AbsoluteInstrAddr, Instruction});
1789-
continue;
1786+
if (BC.isAArch64()) {
1787+
if (!BranchTargetSymbol) {
1788+
LLVM_DEBUG(BC.printInstruction(dbgs(), Instruction, AbsoluteInstrAddr));
1789+
InstructionPatches.push_back({AbsoluteInstrAddr, Instruction});
1790+
continue;
1791+
}
1792+
1793+
// Conditional tail calls require new relocation types that are currently
1794+
// not supported. https://github.com/llvm/llvm-project/issues/138264
1795+
if (BC.MIB->isConditionalBranch(Instruction)) {
1796+
if (BinaryFunction *TargetBF =
1797+
BC.getFunctionForSymbol(BranchTargetSymbol)) {
1798+
TargetBF->setNeedsPatch(true);
1799+
continue;
1800+
}
1801+
}
17901802
}
17911803

17921804
// Emit the instruction using temp emitter and generate relocations.

bolt/lib/Core/DebugData.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,6 @@ static void writeDWARF5LocList(uint32_t &NumberOfEntries, DIEValue &AttrInfo,
676676
return;
677677
}
678678

679-
std::vector<uint64_t> OffsetsArray;
680679
auto writeExpression = [&](uint32_t Index) -> void {
681680
const DebugLocationEntry &Entry = LocList[Index];
682681
encodeULEB128(Entry.Expr.size(), LocBodyStream);

bolt/lib/Passes/FrameAnalysis.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ bool FrameAnalysis::updateArgsTouchedFor(const BinaryFunction &BF, MCInst &Inst,
320320
if (!BC.MIB->isCall(Inst))
321321
return false;
322322

323-
std::set<int64_t> Res;
324323
const MCSymbol *TargetSymbol = BC.MIB->getTargetSymbol(Inst);
325324
// If indirect call, we conservatively assume it accesses all stack positions
326325
if (TargetSymbol == nullptr) {

bolt/lib/Passes/HFSort.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ std::vector<Cluster> clusterize(const CallGraph &Cg) {
239239
}
240240

241241
std::vector<Cluster> randomClusters(const CallGraph &Cg) {
242-
std::vector<NodeId> FuncIds(Cg.numNodes(), 0);
243242
std::vector<Cluster> Clusters;
244243
Clusters.reserve(Cg.numNodes());
245244

0 commit comments

Comments
 (0)