Changeset 13013


Ignore:
Timestamp:
Oct 14, 2009, 3:56:56 AM (10 years ago)
Author:
rme
Message:

New functions x86-memory-operand-ea, x86-emulate-instruction, and
x86-can-emulate-instruction.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lib/misc.lisp

    r13011 r13013  
    10851085                area-watched area-watched)))
    10861086     
     1087;;; Return the effective address of a memory operand by using the
     1088;;; register state in xp, or NIL if we can't figure it out.
     1089;;; Needs to run inside a without-gcing form.
     1090(defun x86-memory-operand-ea (xp op)
     1091  (let* ((seg (x86::x86-memory-operand-seg op))
     1092         (disp (x86::x86-memory-operand-disp op))
     1093         (base (x86::x86-memory-operand-base op))
     1094         (index (x86::x86-memory-operand-index op))
     1095         (scale (x86::x86-memory-operand-scale op)))
     1096    (cond
     1097      ((and base index (not seg))
     1098       (let* ((base-re (x86::x86-register-operand-entry base))
     1099              (index-re (x86::x86-register-operand-entry index))
     1100              (base-num (x86::reg-entry-reg-num base-re))
     1101              (index-num (x86::reg-entry-reg-num index-re))
     1102              (base-val nil)
     1103              (index-val nil))
     1104         (when (logtest (x86::reg-entry-reg-flags base-re) x86::+regrex+)
     1105           (incf base-num 8))
     1106         (setq base-val (encoded-gpr-integer xp base-num))
     1107         (when (logtest (x86::reg-entry-reg-flags index-re) x86::+regrex+)
     1108           (incf index-num 8))
     1109         (setq index-val (encoded-gpr-integer xp index-num))
     1110         (when scale
     1111           (setq index-val (ash index-val scale)))
     1112         (+ (or disp 0) base-val index-val))))))
     1113
     1114;;; Try to emulate the disassembled instruction using the
     1115;;; register state in xp.  Return NIL if we couldn't do it.
     1116;;; This will run with other threads suspended.
     1117(defun x86-emulate-instruction (xp instruction)
     1118  (let* ((mnemonic (x86-di-mnemonic instruction))
     1119         (op0 (x86-di-op0 instruction))
     1120         (op1 (x86-di-op1 instruction))
     1121         (op2 (x86-di-op2 instruction)))
     1122    (when (and op0 op1 (not op2)
     1123               (typep op0 'x86::x86-register-operand)
     1124               (typep op1 'x86::x86-memory-operand))
     1125      (without-gcing
     1126        (let* ((src-re (x86::x86-register-operand-entry op0))
     1127               (src-num (x86::reg-entry-reg-num src-re))
     1128               (src-val nil)
     1129               (ea (x86-memory-operand-ea xp op1)))
     1130          (when (logtest (x86::reg-entry-reg-flags src-re) x86::+regrex+)
     1131            (incf src-num 8))
     1132          (setq src-val (encoded-gpr-integer xp src-num))
     1133          (when ea
     1134            (with-macptrs ((p (%int-to-ptr ea)))
     1135              (cond
     1136                ((string= mnemonic "movb")
     1137                 (setf (%get-signed-byte p) (ldb (byte 8 0) src-val)))
     1138                ((string= mnemonic "movw")
     1139                 (setf (%get-signed-word p) (ldb (byte 16 0) src-val)))
     1140                ((string= mnemonic "movl")
     1141                 (setf (%get-signed-long p) (ldb (byte 32 0) src-val)))
     1142                ((string= mnemonic "movq")
     1143                 (setf (%%get-signed-longlong p 0) (ldb (byte 64 0) src-val)))))))))))
     1144
     1145(defun x86-can-emulate-instruction (instruction)
     1146  (let* ((mnemonic (x86-di-mnemonic instruction))
     1147         (op0 (x86-di-op0 instruction))
     1148         (op1 (x86-di-op1 instruction))
     1149         (op2 (x86-di-op2 instruction)))
     1150    (when (and op0 op1 (not op2)
     1151               (typep op0 'x86::x86-register-operand)
     1152               (typep op1 'x86::x86-memory-operand)
     1153               (member mnemonic '("movb" "movw" "movl" "movq") :test 'string=))
     1154      (let* ((seg (x86::x86-memory-operand-seg op1))
     1155             (base (x86::x86-memory-operand-base op1))
     1156             (index (x86::x86-memory-operand-index op1)))
     1157        (and base index (not seg))))))
Note: See TracChangeset for help on using the changeset viewer.