mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
On arm-linux, add r7 to the set of registers that the CFI unwinder
knows how to unwind. This is important when unwinding Thumb code the CFA is often stated as being at some offset from r7. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11377
This commit is contained in:
parent
4953c95227
commit
0bb6f49531
@ -1944,10 +1944,10 @@ UWord evalCfiExpr ( XArray* exprs, Int ix,
|
||||
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"
|
||||
@ -2155,6 +2155,9 @@ static Addr compute_cfa ( D3UnwindRegs* uregs,
|
||||
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"
|
||||
@ -2221,7 +2224,7 @@ Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
|
||||
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,
|
||||
@ -2310,6 +2313,7 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
|
||||
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"
|
||||
|
||||
@ -130,15 +130,16 @@ typedef
|
||||
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)
|
||||
@ -147,7 +148,8 @@ typedef
|
||||
#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)
|
||||
@ -181,12 +183,14 @@ typedef
|
||||
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)
|
||||
|
||||
@ -2059,6 +2059,7 @@ static void initUnwindContext ( /*OUT*/UnwindContext* ctx )
|
||||
/* 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
|
||||
}
|
||||
@ -2163,6 +2164,11 @@ static Bool summarise_context( /*OUT*/DiCfSI* si,
|
||||
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;
|
||||
@ -2257,6 +2263,9 @@ static Bool summarise_context( /*OUT*/DiCfSI* si,
|
||||
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
|
||||
|
||||
@ -141,6 +141,9 @@ void ML_(ppDiCfSI) ( XArray* /* of CfiExpr */ exprs, DiCfSI* si )
|
||||
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);
|
||||
@ -166,6 +169,8 @@ void ML_(ppDiCfSI) ( XArray* /* of CfiExpr */ exprs, DiCfSI* si )
|
||||
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"
|
||||
|
||||
@ -116,13 +116,14 @@
|
||||
}
|
||||
#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" \
|
||||
@ -132,6 +133,7 @@
|
||||
(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
|
||||
|
||||
@ -92,6 +92,8 @@ void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs,
|
||||
= 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
|
||||
|
||||
@ -378,6 +378,7 @@ typedef struct SigQueue {
|
||||
(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)
|
||||
|
||||
@ -593,11 +593,12 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
|
||||
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],
|
||||
@ -612,7 +613,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
|
||||
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);
|
||||
@ -652,11 +653,11 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
|
||||
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. */
|
||||
|
||||
@ -103,6 +103,7 @@ typedef
|
||||
UInt r14;
|
||||
UInt r12;
|
||||
UInt r11;
|
||||
UInt r7;
|
||||
} ARM;
|
||||
} misc;
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ typedef
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user