]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support If-Then-Else in Valgrind's gdbserver.
authorIvo Raisr <ivosh@ivosh.net>
Tue, 8 Aug 2017 10:56:35 +0000 (12:56 +0200)
committerIvo Raisr <ivosh@ivosh.net>
Mon, 28 Aug 2017 21:32:17 +0000 (23:32 +0200)
coregrind/m_gdbserver/m_gdbserver.c

index 648d5436094d68d61759ad7efcc32b437787c626..566b449426b4d7237a63a4da26461208efe6d341 100644 (file)
@@ -1148,11 +1148,10 @@ void VG_(helperc_invalidate_if_not_gdbserved) ( Addr addr )
 }
 
 static void VG_(add_stmt_call_invalidate_if_not_gdbserved)
-     ( IRSB* sb_in,
-       const VexGuestLayout* layout, 
-       const VexGuestExtents* vge,
-       IRTemp jmp, 
-       IRSB* irsb)
+     (const VexGuestLayout* layout,
+      const VexGuestExtents* vge,
+      IRTemp jmp,
+      IRSB* irsb)
 {
    
    void*    fn;
@@ -1171,7 +1170,7 @@ static void VG_(add_stmt_call_invalidate_if_not_gdbserved)
 
    di->nFxState = 0;
 
-   addStmtToIRSB(irsb, IRStmt_Dirty(di));
+   addStmtToIRStmtVec(irsb->stmts, IRStmt_Dirty(di));
 }
 
 /* software_breakpoint support --------------------------------------*/
@@ -1186,13 +1185,12 @@ static void VG_(add_stmt_call_invalidate_if_not_gdbserved)
    of other breaks in the same sb_in while the process is stopped), a
    debugger statement will be inserted for all instructions of a block. */
 static void VG_(add_stmt_call_gdbserver) 
-     (IRSB* sb_in,                /* block being translated */
-      const VexGuestLayout* layout, 
+     (const VexGuestLayout* layout,
       const VexGuestExtents* vge,
       IRType gWordTy, IRType hWordTy,
-      Addr  iaddr,                /* Addr of instruction being instrumented */
-      UChar delta,                /* delta to add to iaddr to obtain IP */
-      IRSB* irsb)                 /* irsb block to which call is added */
+      Addr       iaddr,          /* Addr of instruction being instrumented */
+      UChar      delta,          /* delta to add to iaddr to obtain IP */
+      IRStmtVec* stmts)          /* list of statements to which call is added */
 {
    void*    fn;
    const HChar*   nm;
@@ -1217,8 +1215,8 @@ static void VG_(add_stmt_call_gdbserver)
       IP when executing thumb code. gdb uses this thumb bit a.o.
       to properly guess the next IP for the 'step' and 'stepi' commands. */
    vg_assert(delta <= 1);
-   addStmtToIRSB(irsb, IRStmt_Put(layout->offset_IP ,
-                                  mkIRExpr_HWord(iaddr + (Addr)delta)));
+   addStmtToIRStmtVec(stmts, IRStmt_Put(layout->offset_IP ,
+                                        mkIRExpr_HWord(iaddr + (Addr)delta)));
 
    fn    = &VG_(helperc_CallDebugger);
    nm    = "VG_(helperc_CallDebugger)";
@@ -1249,8 +1247,7 @@ static void VG_(add_stmt_call_gdbserver)
    di->fxState[1].nRepeats  = 0;
    di->fxState[1].repeatLen = 0;
 
-   addStmtToIRSB(irsb, IRStmt_Dirty(di));
-
+   addStmtToIRStmtVec(stmts, IRStmt_Dirty(di));
 }
 
 
@@ -1273,31 +1270,27 @@ static void VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved)
                                        : sb_in->next->Iex.Const.con->Ico.U32);
    } else if (sb_in->next->tag == Iex_RdTmp) {
      VG_(add_stmt_call_invalidate_if_not_gdbserved)
-       (sb_in, layout, vge, sb_in->next->Iex.RdTmp.tmp, irsb);
+       (layout, vge, sb_in->next->Iex.RdTmp.tmp, irsb);
    } else {
      vg_assert (0); /* unexpected expression tag in exit. */
    }
 }
 
-IRSB* VG_(instrument_for_gdbserver_if_needed)
-     (IRSB* sb_in,
-      const VexGuestLayout* layout,
-      const VexGuestExtents* vge,
-      IRType gWordTy, IRType hWordTy)
+static IRStmtVec* instrument_for_gdbserver_IRStmtVec
+                    (IRStmtVec*             stmts_in,
+                     IRStmtVec*             parent,
+                     const VgVgdb           instr_needed,
+                     const VexGuestLayout*  layout,
+                     const VexGuestExtents* vge,
+                     IRType gWordTy, IRType hWordTy)
 {
-   IRSB* sb_out;
-   Int i;
-   const VgVgdb instr_needed = VG_(gdbserver_instrumentation_needed) (vge);
-
-   if (instr_needed == Vg_VgdbNo)
-     return sb_in;
+   IRStmtVec* stmts_out = emptyIRStmtVec();
+   stmts_out->parent    = parent;
+   stmts_out->id        = stmts_in->id;
+   stmts_out->defset    = deepCopyIRTempDefSet(stmts_in->defset);
 
-
-   /* here, we need to instrument for gdbserver */
-   sb_out = deepCopyIRSBExceptStmts(sb_in);
-
-   for (i = 0; i < sb_in->stmts_used; i++) {
-      IRStmt* st = sb_in->stmts[i];
+   for (UInt i = 0; i < stmts_in->stmts_used; i++) {
+      IRStmt* st = stmts_in->stmts[i];
       
       if (!st || st->tag == Ist_NoOp) continue;
       
@@ -1307,18 +1300,30 @@ IRSB* VG_(instrument_for_gdbserver_if_needed)
            st->Ist.Exit.dst->Ico.U64 : 
            st->Ist.Exit.dst->Ico.U32);
       }
-      addStmtToIRSB( sb_out, st );
+
+      if (st->tag == Ist_IfThenElse) {
+         st = IRStmt_IfThenElse(
+                st->Ist.IfThenElse.details->cond,
+                st->Ist.IfThenElse.details->hint,
+                instrument_for_gdbserver_IRStmtVec(
+                                st->Ist.IfThenElse.details->then_leg, stmts_out,
+                                instr_needed, layout, vge, gWordTy, hWordTy),
+                instrument_for_gdbserver_IRStmtVec(
+                                st->Ist.IfThenElse.details->else_leg, stmts_out,
+                                instr_needed, layout, vge, gWordTy, hWordTy),
+                st->Ist.IfThenElse.details->phi_nodes);
+      }
+      addStmtToIRStmtVec(stmts_out, st);
+
       if (st->tag == Ist_IMark) {
          /* For an Ist_Mark, add a call to debugger. */
          switch (instr_needed) {
          case Vg_VgdbNo: vg_assert (0);
          case Vg_VgdbYes:
          case Vg_VgdbFull:
-            VG_(add_stmt_call_gdbserver) ( sb_in, layout, vge,
-                                           gWordTy, hWordTy,
-                                           st->Ist.IMark.addr,
-                                           st->Ist.IMark.delta,
-                                           sb_out);
+            VG_(add_stmt_call_gdbserver)(layout, vge, gWordTy, hWordTy,
+                                         st->Ist.IMark.addr, st->Ist.IMark.delta,
+                                         stmts_out);
             /* There is an optimisation possible here for Vg_VgdbFull:
                Put a guard ensuring we only call gdbserver if 'FullCallNeeded'.
                FullCallNeeded would be set to 1 we have just switched on
@@ -1333,11 +1338,28 @@ IRSB* VG_(instrument_for_gdbserver_if_needed)
       }
    }
 
+   return stmts_out;
+}
+
+IRSB* VG_(instrument_for_gdbserver_if_needed)
+     (IRSB* sb_in,
+      const VexGuestLayout* layout,
+      const VexGuestExtents* vge,
+      IRType gWordTy, IRType hWordTy)
+{
+   const VgVgdb instr_needed = VG_(gdbserver_instrumentation_needed) (vge);
+
+   if (instr_needed == Vg_VgdbNo)
+     return sb_in;
+
+   /* Here, we need to instrument for gdbserver. */
+   IRSB* sb_out = deepCopyIRSBExceptStmts(sb_in);
+   sb_out->stmts = instrument_for_gdbserver_IRStmtVec(sb_in->stmts, NULL,
+                                   instr_needed, layout, vge, gWordTy, hWordTy);
+
    if (instr_needed == Vg_VgdbYes) {
-      VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved) (sb_in,
-                                                                  layout, vge,
-                                                                  gWordTy,
-                                                                  sb_out);
+      VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved)(sb_in, layout,
+                                                          vge, gWordTy, sb_out);
    }
 
    return sb_out;