case Creg_IA_SP: return eec->uregs->xsp;
case Creg_IA_BP: return eec->uregs->xbp;
# elif defined(VGA_arm)
- case Creg_ARM_R13: return eec->uregs->r13;
- case Creg_ARM_R12: return eec->uregs->r12;
case Creg_ARM_R15: return eec->uregs->r15;
case Creg_ARM_R14: return eec->uregs->r14;
+ case Creg_ARM_R13: return eec->uregs->r13;
+ case Creg_ARM_R12: return eec->uregs->r12;
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
# else
# error "Unsupported arch"
case CFIC_ARM_R11REL:
cfa = cfsi->cfa_off + uregs->r11;
break;
+ case CFIC_ARM_R7REL:
+ cfa = cfsi->cfa_off + uregs->r7;
+ break;
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
# else
# error "Unsupported arch"
For x86 and amd64, the unwound registers are: {E,R}IP,
{E,R}SP, {E,R}BP.
- For arm, the unwound registers are: R11 R12 R13 R14 R15.
+ For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
*/
Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
Addr min_accessible,
COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi->r13_how, cfsi->r13_off);
COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi->r12_how, cfsi->r12_off);
COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi->r11_how, cfsi->r11_off);
+ COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi->r7_how, cfsi->r7_off);
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
# else
# error "Unknown arch"
CFIC_R13REL -> r13 + cfa_off
CFIC_R12REL -> r12 + cfa_off
CFIC_R11REL -> r11 + cfa_off
+ CFIC_R7REL -> r7 + cfa_off
CFIR_EXPR -> expr whose index is in cfa_off
- old_r14/r13/r12/r11/ra
- = case r14/r13/r12/r11/ra_how of
+ old_r14/r13/r12/r11/r7/ra
+ = case r14/r13/r12/r11/r7/ra_how of
CFIR_UNKNOWN -> we don't know, sorry
- CFIR_SAME -> same as it was before (r14/r13/r12/r11 only)
- CFIR_CFAREL -> cfa + r14/r13/r12/r11/ra_off
- CFIR_MEMCFAREL -> *( cfa + r14/r13/r12/r11/ra_off )
- CFIR_EXPR -> expr whose index is in r14/r13/r12/r11/ra_off
+ CFIR_SAME -> same as it was before (r14/r13/r12/r11/r7 only)
+ CFIR_CFAREL -> cfa + r14/r13/r12/r11/r7/ra_off
+ CFIR_MEMCFAREL -> *( cfa + r14/r13/r12/r11/r7/ra_off )
+ CFIR_EXPR -> expr whose index is in r14/r13/r12/r11/r7/ra_off
*/
#define CFIC_IA_SPREL ((UChar)1)
#define CFIC_ARM_R13REL ((UChar)4)
#define CFIC_ARM_R12REL ((UChar)5)
#define CFIC_ARM_R11REL ((UChar)6)
-#define CFIC_EXPR ((UChar)7) /* all targets */
+#define CFIC_ARM_R7REL ((UChar)7)
+#define CFIC_EXPR ((UChar)8) /* all targets */
#define CFIR_UNKNOWN ((UChar)64)
#define CFIR_SAME ((UChar)65)
UChar r13_how; /* a CFIR_ value */
UChar r12_how; /* a CFIR_ value */
UChar r11_how; /* a CFIR_ value */
+ UChar r7_how; /* a CFIR_ value */
Int cfa_off;
Int ra_off;
Int r14_off;
Int r13_off;
Int r12_off;
Int r11_off;
+ Int r7_off;
}
DiCfSI;
#elif defined(VGA_ppc32) || defined(VGA_ppc64)
/* ctx->state[j].reg[13].tag = RR_Same; */
ctx->state[j].reg[14].tag = RR_Same;
ctx->state[j].reg[12].tag = RR_Same;
+ ctx->state[j].reg[7].tag = RR_Same;
/* this can't be right though: R12 (IP) isn't callee saved. */
# endif
}
si->cfa_how = CFIC_ARM_R11REL;
si->cfa_off = ctxs->cfa_off;
}
+ else
+ if (ctxs->cfa_is_regoff && ctxs->cfa_reg == 7/*??_REG*/) {
+ si->cfa_how = CFIC_ARM_R7REL;
+ si->cfa_off = ctxs->cfa_off;
+ }
# endif
else {
why = 1;
SUMMARISE_HOW(si->r11_how, si->r11_off,
ctxs->reg[11/*FP_REG*/] );
+ SUMMARISE_HOW(si->r7_how, si->r7_off,
+ ctxs->reg[7] );
+
if (ctxs->reg[14/*LR*/].tag == RR_Same
&& ctx->ra_reg == 14/*as we expect it always to be*/) {
/* Generate a trivial CfiExpr, which merely says "r14". First
case CFIC_ARM_R11REL:
VG_(printf)("let cfa=oldR11+%d", si->cfa_off);
break;
+ case CFIC_ARM_R7REL:
+ VG_(printf)("let cfa=oldR7+%d", si->cfa_off);
+ break;
case CFIC_EXPR:
VG_(printf)("let cfa={");
ML_(ppCfiExpr)(exprs, si->cfa_off);
SHOW_HOW(si->r12_how, si->r12_off);
VG_(printf)(" R11=");
SHOW_HOW(si->r11_how, si->r11_off);
+ VG_(printf)(" R7=");
+ SHOW_HOW(si->r7_how, si->r7_off);
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
# else
# error "Unknown arch"
}
#elif defined(VGP_arm_linux)
# define GET_STARTREGS(srP) \
- { UInt block[5]; \
+ { UInt block[6]; \
__asm__ __volatile__( \
"str r15, [%0, #+0];" \
"str r14, [%0, #+4];" \
"str r13, [%0, #+8];" \
"str r12, [%0, #+12];" \
"str r11, [%0, #+16];" \
+ "str r7, [%0, #+20];" \
: /* out */ \
: /* in */ "r"(&block[0]) \
: /* trash */ "memory" \
(srP)->misc.ARM.r14 = block[2]; \
(srP)->misc.ARM.r12 = block[3]; \
(srP)->misc.ARM.r11 = block[4]; \
+ (srP)->misc.ARM.r7 = block[5]; \
}
#else
# error Unknown platform
= VG_(threads)[tid].arch.vex.guest_R12;
regs->misc.ARM.r11
= VG_(threads)[tid].arch.vex.guest_R11;
+ regs->misc.ARM.r7
+ = VG_(threads)[tid].arch.vex.guest_R7;
# else
# error "Unknown arch"
# endif
(srP)->misc.ARM.r14 = (uc)->uc_mcontext.arm_lr; \
(srP)->misc.ARM.r12 = (uc)->uc_mcontext.arm_ip; \
(srP)->misc.ARM.r11 = (uc)->uc_mcontext.arm_fp; \
+ (srP)->misc.ARM.r7 = (uc)->uc_mcontext.arm_r7; \
}
#elif defined(VGP_ppc32_aix5)
vg_assert(sizeof(Addr) == sizeof(void*));
D3UnwindRegs uregs;
- uregs.r15 = startRegs->r_pc;
+ uregs.r15 = startRegs->r_pc & 0xFFFFFFFE;
uregs.r14 = startRegs->misc.ARM.r14;
uregs.r13 = startRegs->r_sp;
uregs.r12 = startRegs->misc.ARM.r12;
uregs.r11 = startRegs->misc.ARM.r11;
+ uregs.r7 = startRegs->misc.ARM.r7;
Addr fp_min = uregs.r13;
/* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
fp_max -= sizeof(Addr);
if (debug)
- VG_(printf)("max_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
+ VG_(printf)("\nmax_n_ips=%d fp_min=0x%lx fp_max_orig=0x%lx, "
"fp_max=0x%lx r15=0x%lx r13=0x%lx\n",
max_n_ips, fp_min, fp_max_orig, fp_max,
uregs.r15, uregs.r13);
if (VG_(use_CF_info)( &uregs, fp_min, fp_max )) {
if (sps) sps[i] = uregs.r13;
if (fps) fps[i] = 0;
- ips[i++] = uregs.r15 -1;
+ ips[i++] = (uregs.r15 & 0xFFFFFFFE) - 1;
if (debug)
VG_(printf)("USING CFI: r15: 0x%lx, r13: 0x%lx\n",
uregs.r15, uregs.r13);
- uregs.r15 = uregs.r15 - 1;
+ uregs.r15 = (uregs.r15 & 0xFFFFFFFE) - 1;
continue;
}
/* No luck. We have to give up. */
UInt r14;
UInt r12;
UInt r11;
+ UInt r7;
} ARM;
} misc;
}
D3UnwindRegs;
#elif defined(VGA_arm)
typedef
- struct { Addr r15; Addr r14; Addr r13; Addr r12; Addr r11; }
+ struct { Addr r15; Addr r14; Addr r13; Addr r12; Addr r11; Addr r7; }
D3UnwindRegs;
#elif defined(VGA_ppc32) || defined(VGA_ppc64)
typedef