|
 |
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 */
|