@@ -172,7 +172,7 @@ class TrackedRegisters {
172
172
// / * RET (which is implicitly RET X30) is a protected return if and only if
173
173
// / X30 is safe-to-dereference - the state computed for sub- and
174
174
// / super-registers is not inspected.
175
- struct State {
175
+ struct SrcState {
176
176
// / A BitVector containing the registers that are either safe at function
177
177
// / entry and were not clobbered yet, or those not clobbered since being
178
178
// / authenticated.
@@ -186,12 +186,12 @@ struct State {
186
186
std::vector<SmallPtrSet<const MCInst *, 4 >> LastInstWritingReg;
187
187
188
188
// / Construct an empty state.
189
- State () {}
189
+ SrcState () {}
190
190
191
- State (unsigned NumRegs, unsigned NumRegsToTrack)
191
+ SrcState (unsigned NumRegs, unsigned NumRegsToTrack)
192
192
: SafeToDerefRegs(NumRegs), LastInstWritingReg(NumRegsToTrack) {}
193
193
194
- State &merge (const State &StateIn) {
194
+ SrcState &merge (const SrcState &StateIn) {
195
195
if (StateIn.empty ())
196
196
return *this ;
197
197
if (empty ())
@@ -208,11 +208,11 @@ struct State {
208
208
// / neither safe, nor unsafe ones.
209
209
bool empty () const { return SafeToDerefRegs.empty (); }
210
210
211
- bool operator ==(const State &RHS) const {
211
+ bool operator ==(const SrcState &RHS) const {
212
212
return SafeToDerefRegs == RHS.SafeToDerefRegs &&
213
213
LastInstWritingReg == RHS.LastInstWritingReg ;
214
214
}
215
- bool operator !=(const State &RHS) const { return !((*this ) == RHS); }
215
+ bool operator !=(const SrcState &RHS) const { return !((*this ) == RHS); }
216
216
};
217
217
218
218
static void printLastInsts (
@@ -228,8 +228,8 @@ static void printLastInsts(
228
228
}
229
229
}
230
230
231
- raw_ostream &operator <<(raw_ostream &OS, const State &S) {
232
- OS << " pacret -state<" ;
231
+ raw_ostream &operator <<(raw_ostream &OS, const SrcState &S) {
232
+ OS << " src -state<" ;
233
233
if (S.empty ()) {
234
234
OS << " empty" ;
235
235
} else {
@@ -240,18 +240,18 @@ raw_ostream &operator<<(raw_ostream &OS, const State &S) {
240
240
return OS;
241
241
}
242
242
243
- class PacStatePrinter {
243
+ class SrcStatePrinter {
244
244
public:
245
- void print (raw_ostream &OS, const State &State) const ;
246
- explicit PacStatePrinter (const BinaryContext &BC) : BC(BC) {}
245
+ void print (raw_ostream &OS, const SrcState &State) const ;
246
+ explicit SrcStatePrinter (const BinaryContext &BC) : BC(BC) {}
247
247
248
248
private:
249
249
const BinaryContext &BC;
250
250
};
251
251
252
- void PacStatePrinter ::print (raw_ostream &OS, const State &S) const {
252
+ void SrcStatePrinter ::print (raw_ostream &OS, const SrcState &S) const {
253
253
RegStatePrinter RegStatePrinter (BC);
254
- OS << " pacret -state<" ;
254
+ OS << " src -state<" ;
255
255
if (S.empty ()) {
256
256
assert (S.SafeToDerefRegs .empty ());
257
257
assert (S.LastInstWritingReg .empty ());
@@ -265,71 +265,71 @@ void PacStatePrinter::print(raw_ostream &OS, const State &S) const {
265
265
OS << " >" ;
266
266
}
267
267
268
- class PacRetAnalysis
269
- : public DataflowAnalysis<PacRetAnalysis, State , /* Backward=*/ false ,
270
- PacStatePrinter > {
268
+ class SrcSafetyAnalysis
269
+ : public DataflowAnalysis<SrcSafetyAnalysis, SrcState , /* Backward=*/ false ,
270
+ SrcStatePrinter > {
271
271
using Parent =
272
- DataflowAnalysis<PacRetAnalysis, State , false , PacStatePrinter >;
272
+ DataflowAnalysis<SrcSafetyAnalysis, SrcState , false , SrcStatePrinter >;
273
273
friend Parent;
274
274
275
275
public:
276
- PacRetAnalysis (BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
277
- const std::vector<MCPhysReg> &RegsToTrackInstsFor)
276
+ SrcSafetyAnalysis (BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId,
277
+ const std::vector<MCPhysReg> &RegsToTrackInstsFor)
278
278
: Parent(BF, AllocId), NumRegs(BF.getBinaryContext().MRI->getNumRegs ()),
279
279
RegsToTrackInstsFor(RegsToTrackInstsFor) {}
280
- virtual ~PacRetAnalysis () {}
280
+ virtual ~SrcSafetyAnalysis () {}
281
281
282
282
protected:
283
283
const unsigned NumRegs;
284
284
// / RegToTrackInstsFor is the set of registers for which the dataflow analysis
285
285
// / must compute which the last set of instructions writing to it are.
286
286
const TrackedRegisters RegsToTrackInstsFor;
287
287
288
- SmallPtrSet<const MCInst *, 4 > &lastWritingInsts (State &S,
288
+ SmallPtrSet<const MCInst *, 4 > &lastWritingInsts (SrcState &S,
289
289
MCPhysReg Reg) const {
290
290
unsigned Index = RegsToTrackInstsFor.getIndex (Reg);
291
291
return S.LastInstWritingReg [Index];
292
292
}
293
- const SmallPtrSet<const MCInst *, 4 > &lastWritingInsts (const State &S,
293
+ const SmallPtrSet<const MCInst *, 4 > &lastWritingInsts (const SrcState &S,
294
294
MCPhysReg Reg) const {
295
295
unsigned Index = RegsToTrackInstsFor.getIndex (Reg);
296
296
return S.LastInstWritingReg [Index];
297
297
}
298
298
299
299
void preflight () {}
300
300
301
- State createEntryState () {
302
- State S (NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters ());
301
+ SrcState createEntryState () {
302
+ SrcState S (NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters ());
303
303
for (MCPhysReg Reg : BC.MIB ->getTrustedLiveInRegs ())
304
304
S.SafeToDerefRegs |= BC.MIB ->getAliases (Reg, /* OnlySmaller=*/ true );
305
305
return S;
306
306
}
307
307
308
- State getStartingStateAtBB (const BinaryBasicBlock &BB) {
308
+ SrcState getStartingStateAtBB (const BinaryBasicBlock &BB) {
309
309
if (BB.isEntryPoint ())
310
310
return createEntryState ();
311
311
312
- return State ();
312
+ return SrcState ();
313
313
}
314
314
315
- State getStartingStateAtPoint (const MCInst &Point ) { return State (); }
315
+ SrcState getStartingStateAtPoint (const MCInst &Point ) { return SrcState (); }
316
316
317
- void doConfluence (State &StateOut, const State &StateIn) {
318
- PacStatePrinter P (BC);
317
+ void doConfluence (SrcState &StateOut, const SrcState &StateIn) {
318
+ SrcStatePrinter P (BC);
319
319
LLVM_DEBUG ({
320
- dbgs () << " PacRetAnalysis ::Confluence(\n " ;
321
- dbgs () << " State 1: " ;
320
+ dbgs () << " SrcSafetyAnalysis ::Confluence(\n " ;
321
+ dbgs () << " State 1: " ;
322
322
P.print (dbgs (), StateOut);
323
323
dbgs () << " \n " ;
324
- dbgs () << " State 2: " ;
324
+ dbgs () << " State 2: " ;
325
325
P.print (dbgs (), StateIn);
326
326
dbgs () << " )\n " ;
327
327
});
328
328
329
329
StateOut.merge (StateIn);
330
330
331
331
LLVM_DEBUG ({
332
- dbgs () << " merged state: " ;
332
+ dbgs () << " merged state: " ;
333
333
P.print (dbgs (), StateOut);
334
334
dbgs () << " \n " ;
335
335
});
@@ -354,7 +354,7 @@ class PacRetAnalysis
354
354
// Returns all registers that can be treated as if they are written by an
355
355
// authentication instruction.
356
356
SmallVector<MCPhysReg> getRegsMadeSafeToDeref (const MCInst &Point ,
357
- const State &Cur) const {
357
+ const SrcState &Cur) const {
358
358
SmallVector<MCPhysReg> Regs;
359
359
const MCPhysReg NoReg = BC.MIB ->getNoRegister ();
360
360
@@ -378,10 +378,10 @@ class PacRetAnalysis
378
378
return Regs;
379
379
}
380
380
381
- State computeNext (const MCInst &Point , const State &Cur) {
382
- PacStatePrinter P (BC);
381
+ SrcState computeNext (const MCInst &Point , const SrcState &Cur) {
382
+ SrcStatePrinter P (BC);
383
383
LLVM_DEBUG ({
384
- dbgs () << " PacRetAnalysis ::ComputeNext(" ;
384
+ dbgs () << " SrcSafetyAnalysis ::ComputeNext(" ;
385
385
BC.InstPrinter ->printInst (&const_cast <MCInst &>(Point ), 0 , " " , *BC.STI ,
386
386
dbgs ());
387
387
dbgs () << " , " ;
@@ -395,7 +395,7 @@ class PacRetAnalysis
395
395
if (Cur.empty ()) {
396
396
LLVM_DEBUG (
397
397
{ dbgs () << " Skipping computeNext(Point, Cur) as Cur is empty.\n " ; });
398
- return State ();
398
+ return SrcState ();
399
399
}
400
400
401
401
// First, compute various properties of the instruction, taking the state
@@ -406,7 +406,7 @@ class PacRetAnalysis
406
406
getRegsMadeSafeToDeref (Point , Cur);
407
407
408
408
// Then, compute the state after this instruction is executed.
409
- State Next = Cur;
409
+ SrcState Next = Cur;
410
410
411
411
Next.SafeToDerefRegs .reset (Clobbered);
412
412
// Keep track of this instruction if it writes to any of the registers we
@@ -430,15 +430,15 @@ class PacRetAnalysis
430
430
}
431
431
432
432
LLVM_DEBUG ({
433
- dbgs () << " .. result: (" ;
433
+ dbgs () << " .. result: (" ;
434
434
P.print (dbgs (), Next);
435
435
dbgs () << " )\n " ;
436
436
});
437
437
438
438
return Next;
439
439
}
440
440
441
- StringRef getAnnotationName () const { return StringRef (" PacRetAnalysis " ); }
441
+ StringRef getAnnotationName () const { return StringRef (" SrcSafetyAnalysis " ); }
442
442
443
443
public:
444
444
std::vector<MCInstReference>
@@ -448,8 +448,8 @@ class PacRetAnalysis
448
448
return {};
449
449
auto MaybeState = getStateBefore (Inst);
450
450
if (!MaybeState)
451
- llvm_unreachable (" Expected State to be present" );
452
- const State &S = *MaybeState;
451
+ llvm_unreachable (" Expected state to be present" );
452
+ const SrcState &S = *MaybeState;
453
453
// Due to aliasing registers, multiple registers may have been tracked.
454
454
std::set<const MCInst *> LastWritingInsts;
455
455
for (MCPhysReg TrackedReg : UsedDirtyRegs) {
@@ -468,7 +468,7 @@ class PacRetAnalysis
468
468
469
469
static std::shared_ptr<Report>
470
470
shouldReportReturnGadget (const BinaryContext &BC, const MCInstReference &Inst,
471
- const State &S) {
471
+ const SrcState &S) {
472
472
static const GadgetKind RetKind (" non-protected ret found" );
473
473
if (!BC.MIB ->isReturn (Inst))
474
474
return nullptr ;
@@ -496,7 +496,7 @@ shouldReportReturnGadget(const BinaryContext &BC, const MCInstReference &Inst,
496
496
497
497
static std::shared_ptr<Report>
498
498
shouldReportCallGadget (const BinaryContext &BC, const MCInstReference &Inst,
499
- const State &S) {
499
+ const SrcState &S) {
500
500
static const GadgetKind CallKind (" non-protected call found" );
501
501
if (!BC.MIB ->isCall (Inst) && !BC.MIB ->isBranch (Inst))
502
502
return nullptr ;
@@ -522,18 +522,19 @@ Analysis::findGadgets(BinaryFunction &BF,
522
522
MCPlusBuilder::AllocatorIdTy AllocatorId) {
523
523
FunctionAnalysisResult Result;
524
524
525
- PacRetAnalysis PRA (BF, AllocatorId, {});
525
+ SrcSafetyAnalysis PRA (BF, AllocatorId, {});
526
+ LLVM_DEBUG ({ dbgs () << " Running src register safety analysis...\n " ; });
526
527
PRA.run ();
527
528
LLVM_DEBUG ({
528
- dbgs () << " After PacRetAnalysis :\n " ;
529
+ dbgs () << " After src register safety analysis :\n " ;
529
530
BF.dump ();
530
531
});
531
532
532
533
BinaryContext &BC = BF.getBinaryContext ();
533
534
for (BinaryBasicBlock &BB : BF) {
534
535
for (int64_t I = 0 , E = BB.size (); I < E; ++I) {
535
536
MCInstReference Inst (&BB, I);
536
- const State &S = *PRA.getStateBefore (Inst);
537
+ const SrcState &S = *PRA.getStateBefore (Inst);
537
538
538
539
// If non-empty state was never propagated from the entry basic block
539
540
// to Inst, assume it to be unreachable and report a warning.
@@ -568,10 +569,12 @@ void Analysis::computeDetailedInfo(BinaryFunction &BF,
568
569
std::vector<MCPhysReg> RegsToTrackVec (RegsToTrack.begin (), RegsToTrack.end ());
569
570
570
571
// Re-compute the analysis with register tracking.
571
- PacRetAnalysis PRWIA (BF, AllocatorId, RegsToTrackVec);
572
+ SrcSafetyAnalysis PRWIA (BF, AllocatorId, RegsToTrackVec);
573
+ LLVM_DEBUG (
574
+ { dbgs () << " \n Running detailed src register safety analysis...\n " ; });
572
575
PRWIA.run ();
573
576
LLVM_DEBUG ({
574
- dbgs () << " After detailed PacRetAnalysis :\n " ;
577
+ dbgs () << " After detailed src register safety analysis :\n " ;
575
578
BF.dump ();
576
579
});
577
580
0 commit comments