Skip to content

Commit e2a189b

Browse files
authored
Merge branch 'main' into bolt-ppc-port
2 parents 7b292ac + 0fa3ba7 commit e2a189b

File tree

2,241 files changed

+82134
-66632
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,241 files changed

+82134
-66632
lines changed

.ci/generate_test_report_lib.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ def plural(num_tests):
122122
]
123123
)
124124

125+
if failures or return_code != 0:
126+
report.extend(
127+
[
128+
"",
129+
"If these failures are unrelated to your changes (for example "
130+
"tests are broken or flaky at HEAD), please open an issue at "
131+
"https://github.com/llvm/llvm-project/issues and add the "
132+
"`infrastructure` label.",
133+
]
134+
)
135+
125136
report = "\n".join(report)
126137
if len(report.encode("utf-8")) > size_limit:
127138
return generate_report(

.ci/generate_test_report_lib_test.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ def test_no_failures_build_failed(self):
109109
110110
All tests passed but another part of the build **failed**.
111111
112-
[Download](https://buildkite.com/organizations/organization_slug/pipelines/pipeline_slug/builds/build_number/jobs/job_id/download.txt) the build's log file to see the details."""
112+
[Download](https://buildkite.com/organizations/organization_slug/pipelines/pipeline_slug/builds/build_number/jobs/job_id/download.txt) the build's log file to see the details.
113+
114+
If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label."""
113115
),
114116
"error",
115117
),
@@ -169,7 +171,9 @@ def test_report_single_file_single_testsuite(self):
169171
```
170172
Other output goes here
171173
```
172-
</details>"""
174+
</details>
175+
176+
If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label."""
173177
),
174178
"error",
175179
),
@@ -203,7 +207,9 @@ def test_report_single_file_single_testsuite(self):
203207
```
204208
DEF/test_2 output goes here
205209
```
206-
</details>"""
210+
</details>
211+
212+
If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label."""
207213
),
208214
"error",
209215
)
@@ -311,7 +317,9 @@ def test_report_dont_list_failures(self):
311317
312318
* 1 test failed
313319
314-
Failed tests and their output was too large to report. Download the build's log file to see the details."""
320+
Failed tests and their output was too large to report. Download the build's log file to see the details.
321+
322+
If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label."""
315323
),
316324
"error",
317325
),
@@ -352,13 +360,16 @@ def test_report_dont_list_failures_link_to_log(self):
352360
353361
* 1 test failed
354362
355-
Failed tests and their output was too large to report. [Download](https://buildkite.com/organizations/organization_slug/pipelines/pipeline_slug/builds/build_number/jobs/job_id/download.txt) the build's log file to see the details."""
363+
Failed tests and their output was too large to report. [Download](https://buildkite.com/organizations/organization_slug/pipelines/pipeline_slug/builds/build_number/jobs/job_id/download.txt) the build's log file to see the details.
364+
365+
If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label."""
356366
),
357367
"error",
358368
),
359369
)
360370

361371
def test_report_size_limit(self):
372+
test_output = "f" * 1000
362373
self.assertEqual(
363374
generate_test_report_lib.generate_report(
364375
"Foo",
@@ -371,14 +382,16 @@ def test_report_size_limit(self):
371382
<testsuites time="0.02">
372383
<testsuite name="Bar" tests="1" failures="1" skipped="0" time="0.02">
373384
<testcase classname="Bar/test_1" name="test_1" time="0.02">
374-
<failure><![CDATA[Some long output goes here...]]></failure>
385+
<failure><![CDATA[{output}]]></failure>
375386
</testcase>
376387
</testsuite>
377-
</testsuites>"""
388+
</testsuites>""".format(
389+
output=test_output
390+
)
378391
)
379392
)
380393
],
381-
size_limit=128,
394+
size_limit=512,
382395
),
383396
(
384397
dedent(
@@ -387,7 +400,9 @@ def test_report_size_limit(self):
387400
388401
* 1 test failed
389402
390-
Failed tests and their output was too large to report. Download the build's log file to see the details."""
403+
Failed tests and their output was too large to report. Download the build's log file to see the details.
404+
405+
If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label."""
391406
),
392407
"error",
393408
),

bolt/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ if(BOLT_BUILT_STANDALONE)
4646
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
4747
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
4848

49+
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
50+
add_definitions(${LLVM_DEFINITIONS_LIST})
51+
list(APPEND CMAKE_REQUIRED_DEFINITIONS ${LLVM_DEFINITIONS_LIST})
52+
4953
include(AddLLVM)
5054
include(TableGen)
5155
include_directories(${LLVM_INCLUDE_DIRS})

bolt/include/bolt/Passes/PAuthGadgetScanner.h

Lines changed: 109 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -196,73 +196,148 @@ raw_ostream &operator<<(raw_ostream &OS, const MCInstReference &);
196196

197197
namespace PAuthGadgetScanner {
198198

199+
// The report classes are designed to be used in an immutable manner.
200+
// When an issue report is constructed in multiple steps, an attempt is made
201+
// to distinguish intermediate and final results at the type level.
202+
//
203+
// Here is an overview of issue life-cycle:
204+
// * an analysis (SrcSafetyAnalysis at now, DstSafetyAnalysis will be added
205+
// later to support the detection of authentication oracles) computes register
206+
// state for each instruction in the function.
207+
// * for each instruction, it is checked whether it is a gadget of some kind,
208+
// taking the computed state into account. If a gadget is found, its kind
209+
// and location are stored into a subclass of Diagnostic wrapped into
210+
// PartialReport<ReqT>.
211+
// * if any issue is to be reported for the function, the same analysis is
212+
// re-run to collect extra information to provide to the user. Which extra
213+
// information can be requested depends on the particular analysis (for
214+
// example, SrcSafetyAnalysis is able to compute the set of instructions
215+
// clobbering the particular register, thus ReqT is MCPhysReg). At this stage,
216+
// `FinalReport`s are created.
217+
//
218+
// Here, the subclasses of Diagnostic store the pieces of information which
219+
// are kept unchanged since they are collected on the first run of the analysis.
220+
// PartialReport<T>::RequestedDetails, on the other hand, is replaced with
221+
// FinalReport::Details computed by the second run of the analysis.
222+
199223
/// Description of a gadget kind that can be detected. Intended to be
200-
/// statically allocated to be attached to reports by reference.
224+
/// statically allocated and attached to reports by reference.
201225
class GadgetKind {
202226
const char *Description;
203227

204228
public:
229+
/// Wraps a description string which must be a string literal.
205230
GadgetKind(const char *Description) : Description(Description) {}
206231

207232
StringRef getDescription() const { return Description; }
208233
};
209234

210-
/// Base report located at some instruction, without any additional information.
211-
struct Report {
235+
/// Basic diagnostic information, which is kept unchanged since it is collected
236+
/// on the first run of the analysis.
237+
struct Diagnostic {
212238
MCInstReference Location;
213239

214-
Report(MCInstReference Location) : Location(Location) {}
215-
virtual ~Report() {}
240+
Diagnostic(MCInstReference Location) : Location(Location) {}
241+
virtual ~Diagnostic() {}
216242

217243
virtual void generateReport(raw_ostream &OS,
218244
const BinaryContext &BC) const = 0;
219245

220-
// The two methods below are called by Analysis::computeDetailedInfo when
221-
// iterating over the reports.
222-
virtual ArrayRef<MCPhysReg> getAffectedRegisters() const { return {}; }
223-
virtual void setOverwritingInstrs(ArrayRef<MCInstReference> Instrs) {}
224-
225246
void printBasicInfo(raw_ostream &OS, const BinaryContext &BC,
226247
StringRef IssueKind) const;
227248
};
228249

229-
struct GadgetReport : public Report {
250+
struct GadgetDiagnostic : public Diagnostic {
230251
// The particular kind of gadget that is detected.
231252
const GadgetKind &Kind;
232-
// The set of registers related to this gadget report (possibly empty).
233-
SmallVector<MCPhysReg, 1> AffectedRegisters;
234-
// The instructions that clobber the affected registers.
235-
// There is no one-to-one correspondence with AffectedRegisters: for example,
236-
// the same register can be overwritten by different instructions in different
237-
// preceding basic blocks.
238-
SmallVector<MCInstReference> OverwritingInstrs;
239-
240-
GadgetReport(const GadgetKind &Kind, MCInstReference Location,
241-
MCPhysReg AffectedRegister)
242-
: Report(Location), Kind(Kind), AffectedRegisters({AffectedRegister}) {}
243253

244-
void generateReport(raw_ostream &OS, const BinaryContext &BC) const override;
254+
GadgetDiagnostic(const GadgetKind &Kind, MCInstReference Location)
255+
: Diagnostic(Location), Kind(Kind) {}
245256

246-
ArrayRef<MCPhysReg> getAffectedRegisters() const override {
247-
return AffectedRegisters;
248-
}
249-
250-
void setOverwritingInstrs(ArrayRef<MCInstReference> Instrs) override {
251-
OverwritingInstrs.assign(Instrs.begin(), Instrs.end());
252-
}
257+
void generateReport(raw_ostream &OS, const BinaryContext &BC) const override;
253258
};
254259

255260
/// Report with a free-form message attached.
256-
struct GenericReport : public Report {
261+
struct GenericDiagnostic : public Diagnostic {
257262
std::string Text;
258-
GenericReport(MCInstReference Location, StringRef Text)
259-
: Report(Location), Text(Text) {}
263+
GenericDiagnostic(MCInstReference Location, StringRef Text)
264+
: Diagnostic(Location), Text(Text) {}
260265
virtual void generateReport(raw_ostream &OS,
261266
const BinaryContext &BC) const override;
262267
};
263268

269+
/// Extra information about an issue collected on the slower, detailed,
270+
/// run of the analysis.
271+
class ExtraInfo {
272+
public:
273+
virtual void print(raw_ostream &OS, const MCInstReference Location) const = 0;
274+
275+
virtual ~ExtraInfo() {}
276+
};
277+
278+
class ClobberingInfo : public ExtraInfo {
279+
SmallVector<MCInstReference> ClobberingInstrs;
280+
281+
public:
282+
ClobberingInfo(ArrayRef<MCInstReference> Instrs) : ClobberingInstrs(Instrs) {}
283+
284+
void print(raw_ostream &OS, const MCInstReference Location) const override;
285+
};
286+
287+
/// A brief version of a report that can be further augmented with the details.
288+
///
289+
/// A half-baked report produced on the first run of the analysis. An extra,
290+
/// analysis-specific information may be requested to be collected on the
291+
/// second run.
292+
template <typename T> struct PartialReport {
293+
PartialReport(std::shared_ptr<Diagnostic> Issue,
294+
const std::optional<T> RequestedDetails)
295+
: Issue(Issue), RequestedDetails(RequestedDetails) {}
296+
297+
std::shared_ptr<Diagnostic> Issue;
298+
std::optional<T> RequestedDetails;
299+
};
300+
301+
/// A final version of the report.
302+
struct FinalReport {
303+
FinalReport(std::shared_ptr<Diagnostic> Issue,
304+
std::shared_ptr<ExtraInfo> Details)
305+
: Issue(Issue), Details(Details) {}
306+
307+
std::shared_ptr<Diagnostic> Issue;
308+
std::shared_ptr<ExtraInfo> Details;
309+
};
310+
264311
struct FunctionAnalysisResult {
265-
std::vector<std::shared_ptr<Report>> Diagnostics;
312+
std::vector<FinalReport> Diagnostics;
313+
};
314+
315+
/// A helper class storing per-function context to be instantiated by Analysis.
316+
class FunctionAnalysisContext {
317+
BinaryContext &BC;
318+
BinaryFunction &BF;
319+
MCPlusBuilder::AllocatorIdTy AllocatorId;
320+
FunctionAnalysisResult Result;
321+
322+
bool PacRetGadgetsOnly;
323+
324+
void findUnsafeUses(SmallVector<PartialReport<MCPhysReg>> &Reports);
325+
void augmentUnsafeUseReports(ArrayRef<PartialReport<MCPhysReg>> Reports);
326+
327+
/// Process the reports which do not have to be augmented, and remove them
328+
/// from Reports.
329+
void handleSimpleReports(SmallVector<PartialReport<MCPhysReg>> &Reports);
330+
331+
public:
332+
FunctionAnalysisContext(BinaryFunction &BF,
333+
MCPlusBuilder::AllocatorIdTy AllocatorId,
334+
bool PacRetGadgetsOnly)
335+
: BC(BF.getBinaryContext()), BF(BF), AllocatorId(AllocatorId),
336+
PacRetGadgetsOnly(PacRetGadgetsOnly) {}
337+
338+
void run();
339+
340+
const FunctionAnalysisResult &getResult() const { return Result; }
266341
};
267342

268343
class Analysis : public BinaryFunctionPass {
@@ -271,12 +346,6 @@ class Analysis : public BinaryFunctionPass {
271346

272347
void runOnFunction(BinaryFunction &Function,
273348
MCPlusBuilder::AllocatorIdTy AllocatorId);
274-
FunctionAnalysisResult findGadgets(BinaryFunction &BF,
275-
MCPlusBuilder::AllocatorIdTy AllocatorId);
276-
277-
void computeDetailedInfo(BinaryFunction &BF,
278-
MCPlusBuilder::AllocatorIdTy AllocatorId,
279-
FunctionAnalysisResult &Result);
280349

281350
std::map<const BinaryFunction *, FunctionAnalysisResult> AnalysisResults;
282351
std::mutex AnalysisResultsMutex;

bolt/lib/Core/BinaryContext.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
201201

202202
std::string Error;
203203
const Target *TheTarget =
204-
TargetRegistry::lookupTarget(std::string(ArchName), TheTriple, Error);
204+
TargetRegistry::lookupTarget(ArchName, TheTriple, Error);
205205
if (!TheTarget)
206206
return createStringError(make_error_code(std::errc::not_supported),
207207
Twine("BOLT-ERROR: ", Error));
@@ -2425,6 +2425,10 @@ BinaryContext::createInstructionPatch(uint64_t Address,
24252425

24262426
std::pair<size_t, size_t>
24272427
BinaryContext::calculateEmittedSize(BinaryFunction &BF, bool FixBranches) {
2428+
// Use the original size for non-simple functions.
2429+
if (!BF.isSimple() || BF.isIgnored())
2430+
return std::make_pair(BF.getSize(), 0);
2431+
24282432
// Adjust branch instruction to match the current layout.
24292433
if (FixBranches)
24302434
BF.fixBranches();

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,7 @@ bool shouldPrint(const BinaryFunction &Function) {
166166
}
167167

168168
std::optional<StringRef> Origin = Function.getOriginSectionName();
169-
if (Origin && llvm::any_of(opts::PrintOnly, [&](const std::string &Name) {
170-
return Name == *Origin;
171-
}))
172-
return true;
173-
174-
return false;
169+
return Origin && llvm::is_contained(opts::PrintOnly, *Origin);
175170
}
176171

177172
} // namespace opts
@@ -3584,6 +3579,8 @@ bool BinaryFunction::validateCFG() const {
35843579
}
35853580

35863581
void BinaryFunction::fixBranches() {
3582+
assert(isSimple() && "Expected function with valid CFG.");
3583+
35873584
auto &MIB = BC.MIB;
35883585
MCContext *Ctx = BC.Ctx.get();
35893586

bolt/lib/Core/DIEBuilder.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,6 @@ void DIEBuilder::updateReferences() {
175175
LocExpr.Die.replaceValue(getState().DIEAlloc, LocExpr.Attr, LocExpr.Form,
176176
Value);
177177
}
178-
179-
return;
180178
}
181179

182180
uint32_t DIEBuilder::allocDIE(const DWARFUnit &DU, const DWARFDie &DDie,

0 commit comments

Comments
 (0)