|
From: <sv...@va...> - 2010-09-23 22:06:10
|
Author: sewardj
Date: 2010-09-23 23:05:59 +0100 (Thu, 23 Sep 2010)
New Revision: 11377
Log:
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.
Modified:
trunk/coregrind/m_debuginfo/debuginfo.c
trunk/coregrind/m_debuginfo/priv_storage.h
trunk/coregrind/m_debuginfo/readdwarf.c
trunk/coregrind/m_debuginfo/storage.c
trunk/coregrind/m_libcassert.c
trunk/coregrind/m_machine.c
trunk/coregrind/m_signals.c
trunk/coregrind/m_stacktrace.c
trunk/coregrind/pub_core_basics.h
trunk/coregrind/pub_core_debuginfo.h
Modified: trunk/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- trunk/coregrind/m_debuginfo/debuginfo.c 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_debuginfo/debuginfo.c 2010-09-23 22:05:59 UTC (rev 11377)
@@ -1944,10 +1944,10 @@
case Creg_IA_SP: return eec->uregs->xsp;
case Creg_IA_BP: return eec->uregs->xbp;
# elif defined(VGA_arm)
+ 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;
- case Creg_ARM_R15: return eec->uregs->r15;
- case Creg_ARM_R14: return eec->uregs->r14;
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
# else
# error "Unsupported arch"
@@ -2155,6 +2155,9 @@
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 @@
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 @@
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"
Modified: trunk/coregrind/m_debuginfo/priv_storage.h
===================================================================
--- trunk/coregrind/m_debuginfo/priv_storage.h 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_debuginfo/priv_storage.h 2010-09-23 22:05:59 UTC (rev 11377)
@@ -130,15 +130,16 @@
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 @@
#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 @@
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)
Modified: trunk/coregrind/m_debuginfo/readdwarf.c
===================================================================
--- trunk/coregrind/m_debuginfo/readdwarf.c 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_debuginfo/readdwarf.c 2010-09-23 22:05:59 UTC (rev 11377)
@@ -2059,6 +2059,7 @@
/* 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 @@
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 @@
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
Modified: trunk/coregrind/m_debuginfo/storage.c
===================================================================
--- trunk/coregrind/m_debuginfo/storage.c 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_debuginfo/storage.c 2010-09-23 22:05:59 UTC (rev 11377)
@@ -141,6 +141,9 @@
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 @@
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"
Modified: trunk/coregrind/m_libcassert.c
===================================================================
--- trunk/coregrind/m_libcassert.c 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_libcassert.c 2010-09-23 22:05:59 UTC (rev 11377)
@@ -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
Modified: trunk/coregrind/m_machine.c
===================================================================
--- trunk/coregrind/m_machine.c 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_machine.c 2010-09-23 22:05:59 UTC (rev 11377)
@@ -92,6 +92,8 @@
= 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
Modified: trunk/coregrind/m_signals.c
===================================================================
--- trunk/coregrind/m_signals.c 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_signals.c 2010-09-23 22:05:59 UTC (rev 11377)
@@ -378,6 +378,7 @@
(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)
Modified: trunk/coregrind/m_stacktrace.c
===================================================================
--- trunk/coregrind/m_stacktrace.c 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/m_stacktrace.c 2010-09-23 22:05:59 UTC (rev 11377)
@@ -593,11 +593,12 @@
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 @@
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 @@
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. */
Modified: trunk/coregrind/pub_core_basics.h
===================================================================
--- trunk/coregrind/pub_core_basics.h 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/pub_core_basics.h 2010-09-23 22:05:59 UTC (rev 11377)
@@ -103,6 +103,7 @@
UInt r14;
UInt r12;
UInt r11;
+ UInt r7;
} ARM;
} misc;
}
Modified: trunk/coregrind/pub_core_debuginfo.h
===================================================================
--- trunk/coregrind/pub_core_debuginfo.h 2010-09-23 13:24:48 UTC (rev 11376)
+++ trunk/coregrind/pub_core_debuginfo.h 2010-09-23 22:05:59 UTC (rev 11377)
@@ -117,7 +117,7 @@
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
|