]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
insn_has_no_other_exits_or_PUTs_to_PC: also check Ist_PutI and Ist_Dirty for writes...
authorJulian Seward <jseward@acm.org>
Wed, 13 Nov 2019 14:45:11 +0000 (15:45 +0100)
committerJulian Seward <jseward@acm.org>
Wed, 13 Nov 2019 14:45:11 +0000 (15:45 +0100)
VEX/priv/guest_generic_bb_to_IR.c

index 67e506fcd2ac12a5af0ec4ac55a138bd4541ecc9..3da99bc25b48dd6cdfe9c3940ca440cb09ad8c34 100644 (file)
@@ -622,9 +622,8 @@ static Bool any_overlap ( Int start1, Int len1, Int start2, Int len2 )
    words, it scans backwards through some prefix of an instruction's IR to see
    if there is an exit there.
 
-   It also checks for explicit PUTs to the PC.
-
-   FIXME: also check PutI and dirty helper calls for such PUTs. */
+   It also checks for explicit PUTs to the PC, via Ist_Put, Ist_PutI or
+   Ist_Dirty.  I suspect this is ridiculous overkill, but is here for safety. */
 static Bool insn_has_no_other_exits_or_PUTs_to_PC (
                IRStmt** const stmts, Int scan_start,
                Int offB_GUEST_IP, Int szB_GUEST_IP,
@@ -654,6 +653,39 @@ static Bool insn_has_no_other_exits_or_PUTs_to_PC (
             break;
          }
       }
+      if (st->tag == Ist_PutI) {
+         const IRPutI* details = st->Ist.PutI.details;
+         const IRRegArray* descr = details->descr;
+         Int offB = descr->base;
+         Int szB  = descr->nElems * sizeofIRType(descr->elemTy);
+         if (any_overlap(offB, szB, offB_GUEST_IP, szB_GUEST_IP)) {
+            found_PUT_to_PC = True;
+            break;
+         }
+      }
+      if (st->tag == Ist_Dirty) {
+         vassert(!found_PUT_to_PC);
+         const IRDirty* details = st->Ist.Dirty.details;
+         for (Int j = 0; j < details->nFxState; j++) {
+            const IREffect fx   = details->fxState[j].fx;
+            const Int offset    = details->fxState[j].offset;
+            const Int size      = details->fxState[j].size;
+            const Int nRepeats  = details->fxState[j].nRepeats;
+            const Int repeatLen = details->fxState[j].repeatLen;
+            if (fx == Ifx_Write || fx == Ifx_Modify) {
+               for (Int k = 0; k < nRepeats; k++) {
+                  Int offB = offset + k * repeatLen;
+                  Int szB  = size;
+                  if (any_overlap(offB, szB, offB_GUEST_IP, szB_GUEST_IP)) {
+                     found_PUT_to_PC = True;
+                  }
+               }
+            }
+         }
+         if (found_PUT_to_PC) {
+            break;
+         }
+      }
       i--;
    }
    // We expect IR for all instructions to start with an IMark.