Skip to content

Commit b327f5f

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:b61e3874fa97 into origin/amd-gfx:01fc438e22db
Local branch origin/amd-gfx 01fc438 Merged main:52f3cad9ffa3 into origin/amd-gfx:31272f8ef7f7 Remote branch main b61e387 Revert "[InstCombine] Match scalable splats in m_ImmConstant (llvm#132522)"
2 parents 01fc438 + b61e387 commit b327f5f

File tree

63 files changed

+2566
-482
lines changed

Some content is hidden

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

63 files changed

+2566
-482
lines changed

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,16 @@ class MCPlusBuilder {
577577
return getNoRegister();
578578
}
579579

580+
/// Returns the register used as call destination, or no-register, if not
581+
/// an indirect call. Sets IsAuthenticatedInternally if the instruction
582+
/// accepts a signed pointer as its operand and authenticates it internally.
583+
virtual MCPhysReg
584+
getRegUsedAsCallDest(const MCInst &Inst,
585+
bool &IsAuthenticatedInternally) const {
586+
llvm_unreachable("not implemented");
587+
return getNoRegister();
588+
}
589+
580590
virtual bool isTerminator(const MCInst &Inst) const;
581591

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

bolt/include/bolt/Passes/PAuthGadgetScanner.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ struct FunctionAnalysisResult {
248248
};
249249

250250
class Analysis : public BinaryFunctionPass {
251+
/// Only search for pac-ret violations.
252+
bool PacRetGadgetsOnly;
253+
251254
void runOnFunction(BinaryFunction &Function,
252255
MCPlusBuilder::AllocatorIdTy AllocatorId);
253256
FunctionAnalysisResult findGadgets(BinaryFunction &BF,
@@ -261,7 +264,8 @@ class Analysis : public BinaryFunctionPass {
261264
std::mutex AnalysisResultsMutex;
262265

263266
public:
264-
explicit Analysis() : BinaryFunctionPass(false) {}
267+
explicit Analysis(bool PacRetGadgetsOnly)
268+
: BinaryFunctionPass(false), PacRetGadgetsOnly(PacRetGadgetsOnly) {}
265269

266270
const char *getName() const override { return "pauth-gadget-scanner"; }
267271

bolt/include/bolt/Utils/CommandLineOpts.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ extern llvm::cl::opt<unsigned> Verbosity;
8181
/// Return true if we should process all functions in the binary.
8282
bool processAllFunctions();
8383

84-
enum GadgetScannerKind { GS_PACRET, GS_ALL };
84+
enum GadgetScannerKind { GS_PACRET, GS_PAUTH, GS_ALL };
8585

86-
extern llvm::cl::list<GadgetScannerKind> GadgetScannersToRun;
86+
extern llvm::cl::bits<GadgetScannerKind> GadgetScannersToRun;
8787

8888
} // namespace opts
8989

bolt/lib/Passes/PAuthGadgetScanner.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,11 @@ class PacRetAnalysis
401401

402402
public:
403403
std::vector<MCInstReference>
404-
getLastClobberingInsts(const MCInst Ret, BinaryFunction &BF,
405-
const ArrayRef<MCPhysReg> UsedDirtyRegs) const {
404+
getLastClobberingInsts(const MCInst &Inst, BinaryFunction &BF,
405+
const ArrayRef<MCPhysReg> UsedDirtyRegs) {
406406
if (RegsToTrackInstsFor.empty())
407407
return {};
408-
auto MaybeState = getStateAt(Ret);
408+
auto MaybeState = getStateBefore(Inst);
409409
if (!MaybeState)
410410
llvm_unreachable("Expected State to be present");
411411
const State &S = *MaybeState;
@@ -453,6 +453,29 @@ shouldReportReturnGadget(const BinaryContext &BC, const MCInstReference &Inst,
453453
return std::make_shared<GadgetReport>(RetKind, Inst, RetReg);
454454
}
455455

456+
static std::shared_ptr<Report>
457+
shouldReportCallGadget(const BinaryContext &BC, const MCInstReference &Inst,
458+
const State &S) {
459+
static const GadgetKind CallKind("non-protected call found");
460+
if (!BC.MIB->isCall(Inst) && !BC.MIB->isBranch(Inst))
461+
return nullptr;
462+
463+
bool IsAuthenticated = false;
464+
MCPhysReg DestReg = BC.MIB->getRegUsedAsCallDest(Inst, IsAuthenticated);
465+
if (IsAuthenticated || DestReg == BC.MIB->getNoRegister())
466+
return nullptr;
467+
468+
LLVM_DEBUG({
469+
traceInst(BC, "Found call inst", Inst);
470+
traceReg(BC, "Call destination reg", DestReg);
471+
traceRegMask(BC, "SafeToDerefRegs", S.SafeToDerefRegs);
472+
});
473+
if (S.SafeToDerefRegs[DestReg])
474+
return nullptr;
475+
476+
return std::make_shared<GadgetReport>(CallKind, Inst, DestReg);
477+
}
478+
456479
FunctionAnalysisResult
457480
Analysis::findGadgets(BinaryFunction &BF,
458481
MCPlusBuilder::AllocatorIdTy AllocatorId) {
@@ -469,7 +492,7 @@ Analysis::findGadgets(BinaryFunction &BF,
469492
for (BinaryBasicBlock &BB : BF) {
470493
for (int64_t I = 0, E = BB.size(); I < E; ++I) {
471494
MCInstReference Inst(&BB, I);
472-
const State &S = *PRA.getStateAt(Inst);
495+
const State &S = *PRA.getStateBefore(Inst);
473496

474497
// If non-empty state was never propagated from the entry basic block
475498
// to Inst, assume it to be unreachable and report a warning.
@@ -481,6 +504,12 @@ Analysis::findGadgets(BinaryFunction &BF,
481504

482505
if (auto Report = shouldReportReturnGadget(BC, Inst, S))
483506
Result.Diagnostics.push_back(Report);
507+
508+
if (PacRetGadgetsOnly)
509+
continue;
510+
511+
if (auto Report = shouldReportCallGadget(BC, Inst, S))
512+
Result.Diagnostics.push_back(Report);
484513
}
485514
}
486515
return Result;

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,14 @@ static cl::opt<bool> WriteBoltInfoSection(
247247
"bolt-info", cl::desc("write bolt info section in the output binary"),
248248
cl::init(true), cl::Hidden, cl::cat(BoltOutputCategory));
249249

250-
cl::list<GadgetScannerKind>
251-
GadgetScannersToRun("scanners", cl::desc("which gadget scanners to run"),
252-
cl::values(clEnumValN(GS_PACRET, "pacret", "pac-ret"),
253-
clEnumValN(GS_ALL, "all", "all")),
254-
cl::ZeroOrMore, cl::CommaSeparated,
255-
cl::cat(BinaryAnalysisCategory));
250+
cl::bits<GadgetScannerKind> GadgetScannersToRun(
251+
"scanners", cl::desc("which gadget scanners to run"),
252+
cl::values(
253+
clEnumValN(GS_PACRET, "pacret",
254+
"pac-ret: return address protection (subset of \"pauth\")"),
255+
clEnumValN(GS_PAUTH, "pauth", "All Pointer Authentication scanners"),
256+
clEnumValN(GS_ALL, "all", "All implemented scanners")),
257+
cl::ZeroOrMore, cl::CommaSeparated, cl::cat(BinaryAnalysisCategory));
256258

257259
} // namespace opts
258260

@@ -3539,12 +3541,18 @@ void RewriteInstance::runBinaryAnalyses() {
35393541
// FIXME: add a pass that warns about which functions do not have CFG,
35403542
// and therefore, analysis is most likely to be less accurate.
35413543
using GSK = opts::GadgetScannerKind;
3542-
// if no command line option was given, act as if "all" was specified.
3543-
if (opts::GadgetScannersToRun.empty())
3544-
opts::GadgetScannersToRun.addValue(GSK::GS_ALL);
3545-
for (GSK ScannerToRun : opts::GadgetScannersToRun) {
3546-
if (ScannerToRun == GSK::GS_PACRET || ScannerToRun == GSK::GS_ALL)
3547-
Manager.registerPass(std::make_unique<PAuthGadgetScanner::Analysis>());
3544+
using PAuthScanner = PAuthGadgetScanner::Analysis;
3545+
3546+
// If no command line option was given, act as if "all" was specified.
3547+
bool RunAll = !opts::GadgetScannersToRun.getBits() ||
3548+
opts::GadgetScannersToRun.isSet(GSK::GS_ALL);
3549+
3550+
if (RunAll || opts::GadgetScannersToRun.isSet(GSK::GS_PAUTH)) {
3551+
Manager.registerPass(
3552+
std::make_unique<PAuthScanner>(/*OnlyPacRetChecks=*/false));
3553+
} else if (RunAll || opts::GadgetScannersToRun.isSet(GSK::GS_PACRET)) {
3554+
Manager.registerPass(
3555+
std::make_unique<PAuthScanner>(/*OnlyPacRetChecks=*/true));
35483556
}
35493557

35503558
BC->logBOLTErrorsAndQuitOnFatal(Manager.runPasses());

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,33 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
277277
}
278278
}
279279

280+
MCPhysReg
281+
getRegUsedAsCallDest(const MCInst &Inst,
282+
bool &IsAuthenticatedInternally) const override {
283+
assert(isCall(Inst) || isBranch(Inst));
284+
IsAuthenticatedInternally = false;
285+
286+
switch (Inst.getOpcode()) {
287+
case AArch64::BR:
288+
case AArch64::BLR:
289+
return Inst.getOperand(0).getReg();
290+
case AArch64::BRAA:
291+
case AArch64::BRAB:
292+
case AArch64::BRAAZ:
293+
case AArch64::BRABZ:
294+
case AArch64::BLRAA:
295+
case AArch64::BLRAB:
296+
case AArch64::BLRAAZ:
297+
case AArch64::BLRABZ:
298+
IsAuthenticatedInternally = true;
299+
return Inst.getOperand(0).getReg();
300+
default:
301+
if (isIndirectCall(Inst) || isIndirectBranch(Inst))
302+
llvm_unreachable("Unhandled indirect branch");
303+
return getNoRegister();
304+
}
305+
}
306+
280307
bool isADRP(const MCInst &Inst) const override {
281308
return Inst.getOpcode() == AArch64::ADRP;
282309
}

bolt/test/binary-analysis/AArch64/cmdline-args.test

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ HELP-EMPTY:
3333
HELP-NEXT: BinaryAnalysis options:
3434
HELP-EMPTY:
3535
HELP-NEXT: --scanners=<value> - which gadget scanners to run
36-
HELP-NEXT: =pacret - pac-ret
37-
HELP-NEXT: =all - all
36+
HELP-NEXT: =pacret - pac-ret: return address protection (subset of "pauth")
37+
HELP-NEXT: =pauth - All Pointer Authentication scanners
38+
HELP-NEXT: =all - All implemented scanners
3839
HELP-EMPTY:
3940
HELP-NEXT: Generic Options:

0 commit comments

Comments
 (0)