@@ -476,6 +476,37 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
476476 /* Stop analysis on branch. */
477477 break ;
478478 }
479+ else if (inst .opcode -> iclass == ic_system )
480+ {
481+ struct gdbarch_tdep * tdep = gdbarch_tdep (gdbarch );
482+ int ra_state_val = 0 ;
483+
484+ if (insn == 0xd503233f /* paciasp. */
485+ || insn == 0xd503237f /* pacibsp. */ )
486+ {
487+ /* Return addresses are mangled. */
488+ ra_state_val = 1 ;
489+ }
490+ else if (insn == 0xd50323bf /* autiasp. */
491+ || insn == 0xd50323ff /* autibsp. */ )
492+ {
493+ /* Return addresses are not mangled. */
494+ ra_state_val = 0 ;
495+ }
496+ else
497+ {
498+ if (aarch64_debug )
499+ debug_printf ("aarch64: prologue analysis gave up addr=%s"
500+ " opcode=0x%x (iclass)\n" ,
501+ core_addr_to_string_nz (start ), insn );
502+ break ;
503+ }
504+
505+ if (tdep -> has_pauth () && cache != nullptr )
506+ trad_frame_set_value (cache -> saved_regs ,
507+ tdep -> pauth_ra_state_regnum ,
508+ ra_state_val );
509+ }
479510 else
480511 {
481512 if (aarch64_debug )
@@ -582,11 +613,13 @@ aarch64_analyze_prologue_test (void)
582613 struct gdbarch * gdbarch = gdbarch_find_by_info (info );
583614 SELF_CHECK (gdbarch != NULL );
584615
616+ struct aarch64_prologue_cache cache ;
617+ cache .saved_regs = trad_frame_alloc_saved_regs (gdbarch );
618+
619+ struct gdbarch_tdep * tdep = gdbarch_tdep (gdbarch );
620+
585621 /* Test the simple prologue in which frame pointer is used. */
586622 {
587- struct aarch64_prologue_cache cache ;
588- cache .saved_regs = trad_frame_alloc_saved_regs (gdbarch );
589-
590623 static const uint32_t insns [] = {
591624 0xa9af7bfd , /* stp x29, x30, [sp,#-272]! */
592625 0x910003fd , /* mov x29, sp */
@@ -622,9 +655,6 @@ aarch64_analyze_prologue_test (void)
622655 /* Test a prologue in which STR is used and frame pointer is not
623656 used. */
624657 {
625- struct aarch64_prologue_cache cache ;
626- cache .saved_regs = trad_frame_alloc_saved_regs (gdbarch );
627-
628658 static const uint32_t insns [] = {
629659 0xf81d0ff3 , /* str x19, [sp, #-48]! */
630660 0xb9002fe0 , /* str w0, [sp, #44] */
@@ -664,6 +694,45 @@ aarch64_analyze_prologue_test (void)
664694 == -1 );
665695 }
666696 }
697+
698+ /* Test a prologue in which there is a return address signing instruction. */
699+ if (tdep -> has_pauth ())
700+ {
701+ static const uint32_t insns [] = {
702+ 0xd503233f , /* paciasp */
703+ 0xa9bd7bfd , /* stp x29, x30, [sp, #-48]! */
704+ 0x910003fd , /* mov x29, sp */
705+ 0xf801c3f3 , /* str x19, [sp, #28] */
706+ 0xb9401fa0 , /* ldr x19, [x29, #28] */
707+ };
708+ instruction_reader_test reader (insns );
709+
710+ CORE_ADDR end = aarch64_analyze_prologue (gdbarch , 0 , 128 , & cache ,
711+ reader );
712+
713+ SELF_CHECK (end == 4 * 4 );
714+ SELF_CHECK (cache .framereg == AARCH64_FP_REGNUM );
715+ SELF_CHECK (cache .framesize == 48 );
716+
717+ for (int i = 0 ; i < AARCH64_X_REGISTER_COUNT ; i ++ )
718+ {
719+ if (i == 19 )
720+ SELF_CHECK (cache .saved_regs [i ].addr == -20 );
721+ else if (i == AARCH64_FP_REGNUM )
722+ SELF_CHECK (cache .saved_regs [i ].addr == -48 );
723+ else if (i == AARCH64_LR_REGNUM )
724+ SELF_CHECK (cache .saved_regs [i ].addr == -40 );
725+ else
726+ SELF_CHECK (cache .saved_regs [i ].addr == -1 );
727+ }
728+
729+ if (tdep -> has_pauth ())
730+ {
731+ SELF_CHECK (trad_frame_value_p (cache .saved_regs ,
732+ tdep -> pauth_ra_state_regnum ));
733+ SELF_CHECK (cache .saved_regs [tdep -> pauth_ra_state_regnum ].addr == 1 );
734+ }
735+ }
667736}
668737} // namespace selftests
669738#endif /* GDB_SELF_TEST */
@@ -873,8 +942,16 @@ aarch64_prologue_prev_register (struct frame_info *this_frame,
873942 if (prev_regnum == AARCH64_PC_REGNUM )
874943 {
875944 CORE_ADDR lr ;
945+ struct gdbarch * gdbarch = get_frame_arch (this_frame );
946+ struct gdbarch_tdep * tdep = gdbarch_tdep (gdbarch );
876947
877948 lr = frame_unwind_register_unsigned (this_frame , AARCH64_LR_REGNUM );
949+
950+ if (tdep -> has_pauth ()
951+ && trad_frame_value_p (cache -> saved_regs ,
952+ tdep -> pauth_ra_state_regnum ))
953+ lr = aarch64_frame_unmask_address (tdep , this_frame , lr );
954+
878955 return frame_unwind_got_constant (this_frame , prev_regnum , lr );
879956 }
880957
0 commit comments