@@ -325,18 +325,7 @@ class PacRetAnalysis
325325 });
326326 }
327327
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 {
340329 BitVector Clobbered (NumRegs, false );
341330 // Assume a call can clobber all registers, including callee-saved
342331 // registers. There's a good chance that callee-saved registers will be
@@ -349,24 +338,81 @@ class PacRetAnalysis
349338 Clobbered.set ();
350339 else
351340 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+
352397 Next.SafeToDerefRegs .reset (Clobbered);
353398 // Keep track of this instruction if it writes to any of the registers we
354399 // need to track that for:
355400 for (MCPhysReg Reg : RegsToTrackInstsFor.getRegisters ())
356401 if (Clobbered[Reg])
357402 lastWritingInsts (Next, Reg) = {&Point};
358403
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 ();
370416 }
371417
372418 LLVM_DEBUG ({
0 commit comments