@@ -325,18 +325,7 @@ class PacRetAnalysis
325
325
});
326
326
}
327
327
328
- State computeNext (const MCInst &Point , const State &Cur) {
329
- PacStatePrinter P (BC);
330
- LLVM_DEBUG ({
331
- dbgs () << " PacRetAnalysis::ComputeNext(" ;
332
- BC.InstPrinter ->printInst (&const_cast <MCInst &>(Point ), 0 , " " , *BC.STI ,
333
- dbgs ());
334
- dbgs () << " , " ;
335
- P.print (dbgs (), Cur);
336
- dbgs () << " )\n " ;
337
- });
338
-
339
- State Next = Cur;
328
+ BitVector getClobberedRegs (const MCInst &Point ) const {
340
329
BitVector Clobbered (NumRegs, false );
341
330
// Assume a call can clobber all registers, including callee-saved
342
331
// registers. There's a good chance that callee-saved registers will be
@@ -349,24 +338,81 @@ class PacRetAnalysis
349
338
Clobbered.set ();
350
339
else
351
340
BC.MIB ->getClobberedRegs (Point , Clobbered);
341
+ return Clobbered;
342
+ }
343
+
344
+ // Returns all registers that can be treated as if they are written by an
345
+ // authentication instruction.
346
+ SmallVector<MCPhysReg> getAuthenticatedRegs (const MCInst &Point ,
347
+ const State &Cur) const {
348
+ SmallVector<MCPhysReg> Regs;
349
+ const MCPhysReg NoReg = BC.MIB ->getNoRegister ();
350
+
351
+ // A signed pointer can be authenticated, or
352
+ ErrorOr<MCPhysReg> AutReg = BC.MIB ->getAuthenticatedReg (Point );
353
+ if (AutReg && *AutReg != NoReg)
354
+ Regs.push_back (*AutReg);
355
+
356
+ // ... a safe address can be materialized, or
357
+ MCPhysReg NewAddrReg = BC.MIB ->getSafelyMaterializedAddressReg (Point );
358
+ if (NewAddrReg != NoReg)
359
+ Regs.push_back (NewAddrReg);
360
+
361
+ // ... address can be updated in a safe manner, producing the result
362
+ // which is as trusted as the input address.
363
+ MCPhysReg ArithResult, ArithSrc;
364
+ std::tie (ArithResult, ArithSrc) =
365
+ BC.MIB ->analyzeSafeAddressArithmetics (Point );
366
+ if (ArithResult != NoReg && Cur.SafeToDerefRegs [ArithSrc])
367
+ Regs.push_back (ArithResult);
368
+
369
+ return Regs;
370
+ }
371
+
372
+ State computeNext (const MCInst &Point , const State &Cur) {
373
+ PacStatePrinter P (BC);
374
+ LLVM_DEBUG ({
375
+ dbgs () << " PacRetAnalysis::ComputeNext(" ;
376
+ BC.InstPrinter ->printInst (&const_cast <MCInst &>(Point ), 0 , " " , *BC.STI ,
377
+ dbgs ());
378
+ dbgs () << " , " ;
379
+ P.print (dbgs (), Cur);
380
+ dbgs () << " )\n " ;
381
+ });
382
+
383
+ // First, compute various properties of the instruction, taking the state
384
+ // before its execution into account, if necessary.
385
+
386
+ BitVector Clobbered = getClobberedRegs (Point );
387
+ // Compute the set of registers that can be considered as written by
388
+ // an authentication instruction. This includes operations that are
389
+ // *strictly better* than authentication, such as materializing a
390
+ // PC-relative constant.
391
+ SmallVector<MCPhysReg> AuthenticatedOrBetter =
392
+ getAuthenticatedRegs (Point , Cur);
393
+
394
+ // Then, compute the state after this instruction is executed.
395
+ State Next = Cur;
396
+
352
397
Next.SafeToDerefRegs .reset (Clobbered);
353
398
// Keep track of this instruction if it writes to any of the registers we
354
399
// need to track that for:
355
400
for (MCPhysReg Reg : RegsToTrackInstsFor.getRegisters ())
356
401
if (Clobbered[Reg])
357
402
lastWritingInsts (Next, Reg) = {&Point };
358
403
359
- ErrorOr<MCPhysReg> AutReg = BC.MIB ->getAuthenticatedReg (Point );
360
- if (AutReg && *AutReg != BC.MIB ->getNoRegister ()) {
361
- // The sub-registers of *AutReg are also trusted now, but not its
362
- // super-registers (as they retain untrusted register units).
363
- BitVector AuthenticatedSubregs =
364
- BC.MIB ->getAliases (*AutReg, /* OnlySmaller=*/ true );
365
- for (MCPhysReg Reg : AuthenticatedSubregs.set_bits ()) {
366
- Next.SafeToDerefRegs .set (Reg);
367
- if (RegsToTrackInstsFor.isTracked (Reg))
368
- lastWritingInsts (Next, Reg).clear ();
369
- }
404
+ // After accounting for clobbered registers in general, override the state
405
+ // according to authentication and other *special cases* of clobbering.
406
+
407
+ // The sub-registers of each authenticated register are also trusted now,
408
+ // but not their super-registers (as they retain untrusted register units).
409
+ BitVector AuthenticatedSubregs (NumRegs);
410
+ for (MCPhysReg AutReg : AuthenticatedOrBetter)
411
+ AuthenticatedSubregs |= BC.MIB ->getAliases (AutReg, /* OnlySmaller=*/ true );
412
+ for (MCPhysReg Reg : AuthenticatedSubregs.set_bits ()) {
413
+ Next.SafeToDerefRegs .set (Reg);
414
+ if (RegsToTrackInstsFor.isTracked (Reg))
415
+ lastWritingInsts (Next, Reg).clear ();
370
416
}
371
417
372
418
LLVM_DEBUG ({
0 commit comments