]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
On arm-linux, add r7 to the set of registers that the CFI unwinder
authorJulian Seward <jseward@acm.org>
Thu, 23 Sep 2010 22:05:59 +0000 (22:05 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 23 Sep 2010 22:05:59 +0000 (22:05 +0000)
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

coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/priv_storage.h
coregrind/m_debuginfo/readdwarf.c
coregrind/m_debuginfo/storage.c
coregrind/m_libcassert.c
coregrind/m_machine.c
coregrind/m_signals.c
coregrind/m_stacktrace.c
coregrind/pub_core_basics.h
coregrind/pub_core_debuginfo.h

index 25f5615e7f56b68704f07d970c465d49d0122561..6133fea1fd00de39ffa3a29a003b6edc3c154e2b 100644 (file)
@@ -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"
index b26982516636d9235b986825b214f48ace6676a5..e2725296090106fcd28cd5625f747331a8214bdf 100644 (file)
@@ -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)
index 3d16d5e37a65aaac994777b87adf4334047a0262..d637a759fc20a854c8543fefd23d98cf0aac1563 100644 (file)
@@ -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
index 8046f1eacc212572dedeca593a58e9ead6453640..52aec793760d4e106ad5b203f71eefec7a26a6a2 100644 (file)
@@ -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"
index 4a1b7658422234903e197c45b9a82851dc1ce6ea..731864ff26000838b39aac322131b6d65dda7e79 100644 (file)
       }
 #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
index 5f3bc927b9438050221e66ad1ee8b9772e78b1b9..8dc3e17dbef4894574641f8578c48829930d1700 100644 (file)
@@ -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
index 76c05df2c60a9999ff805946ccaf034ee8fb801b..a3b7690a58d7e57df3f3e5cf9638e766930e9cb0 100644 (file)
@@ -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)
index ad86b79d94be53553b80d18899e25631fd5122c0..4896a9a1e1a959e39630079f54f6a1f33aaef4c3 100644 (file)
@@ -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. */
index fdfd733f6fb3bfa5e5c3f95a2945662032a0189f..35aba2f2ba69fdfbebc5957539235595102215a6 100644 (file)
@@ -103,6 +103,7 @@ typedef
             UInt r14;
             UInt r12;
             UInt r11;
+            UInt r7;
          } ARM;
       } misc;
    }
index 48ac9aa9c31ecde631fd7ea5c46aa786d5810f92..facca244d3976cdbf7537cacfeff0ac453e2b00c 100644 (file)
@@ -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