Blame SOURCES/dyninst-9.2.0-modify-data-64.patch

43d1af
commit c3db2bda113dff501862928bcf4f2efbc531f520 (from 9d5a42622dfd95dcefccc1de756f42ac3a7ee352)
43d1af
Merge: 9d5a42622dfd 2ef16d809162
43d1af
Author: Josh Stone <cuviper@gmail.com>
43d1af
Date:   Tue Aug 30 12:08:52 2016 -0700
43d1af
43d1af
    Merge pull request #163 from cuviper/modify-data-64
43d1af
    
43d1af
    fix insnCodeGen::modifyData's 64-bit conversion
43d1af
43d1af
diff --git a/dyninstAPI/src/codegen-x86.C b/dyninstAPI/src/codegen-x86.C
43d1af
index ef8a6b0b4731..ad9ac8ec90ba 100644
43d1af
--- a/dyninstAPI/src/codegen-x86.C
43d1af
+++ b/dyninstAPI/src/codegen-x86.C
43d1af
@@ -1196,10 +1196,6 @@ bool insnCodeGen::modifyData(Address targetAddr, instruction &insn, codeGen &gen
43d1af
 
43d1af
     /* get the prefix count */
43d1af
     size_t pref_count = instruct.getSize();
43d1af
-
43d1af
-    /* copy the prefix */
43d1af
-    memcpy(newInsn, origInsn, pref_count);
43d1af
-    newInsn += pref_count;
43d1af
     origInsn += pref_count;
43d1af
 
43d1af
     /* Decode the opcode */
43d1af
@@ -1208,27 +1204,31 @@ bool insnCodeGen::modifyData(Address targetAddr, instruction &insn, codeGen &gen
43d1af
 
43d1af
     /* Calculate the amount of opcode bytes */
43d1af
     size_t opcode_len = instruct.getSize() - pref_count;
43d1af
-
43d1af
-    /* Copy the opcode bytes */
43d1af
-    memcpy(newInsn, origInsn, opcode_len);
43d1af
-    newInsn += opcode_len;
43d1af
     origInsn += opcode_len;
43d1af
 
43d1af
     /* Get the value of the Mod/RM byte */
43d1af
-    unsigned char mod_rm = *origInsn;
43d1af
-    origInsn++;
43d1af
+    unsigned char mod_rm = *origInsn++;
43d1af
 
43d1af
+#if defined(arch_x86_64)
43d1af
     if (!is_disp32(newDisp+insnSz) && !is_addr32(targetAddr)) 
43d1af
     {
43d1af
         // Case C: replace with 64-bit.
43d1af
+        // This preamble must come before any writes to newInsn!
43d1af
         is_data_abs64 = true;
43d1af
-#if defined(arch_x86_64)
43d1af
         pointer_reg = (mod_rm & 0x38) != 0 ? 0 : 3;
43d1af
         SET_PTR(newInsn, gen);
43d1af
         emitPushReg64(pointer_reg, gen);
43d1af
         emitMovImmToReg64(pointer_reg, targetAddr, true, gen);
43d1af
         REGET_PTR(newInsn, gen);
43d1af
+    }
43d1af
+#endif
43d1af
+
43d1af
+    /* copy the prefix and opcode bytes */
43d1af
+    memcpy(newInsn, origInsnStart, pref_count + opcode_len);
43d1af
+    newInsn += pref_count + opcode_len;
43d1af
 
43d1af
+    if (is_data_abs64)
43d1af
+    {
43d1af
         // change ModRM byte to use [pointer_reg]: requires
43d1af
         // us to change last three bits (the r/m field)
43d1af
         // to the value of pointer_reg
43d1af
@@ -1236,7 +1236,6 @@ bool insnCodeGen::modifyData(Address targetAddr, instruction &insn, codeGen &gen
43d1af
         mod_rm = (mod_rm & 0xf8) | pointer_reg;
43d1af
         /* Set the new ModR/M byte of the new instruction */
43d1af
         *newInsn++ = mod_rm;
43d1af
-#endif
43d1af
     } else if (is_disp32(newDisp + insnSz)) 
43d1af
     {
43d1af
         /* Instruction can remain a 32 bit instruction */