Skip to content

Commit

Permalink
fixes register assignments in p-code semantics
Browse files Browse the repository at this point in the history
In p-code the lower parts of registers are referenced as variables
with the same name as the base register but with the size equal to
the size of the referenced part, e.g., YMM0:64 refers to the lower
64 bits of the YMM0 register. The semantics of assignemnt assumes
that the upper parts are preserved.

This commit implements the proper semantics of the `set#`
operator, i.e., it extends the right-hand side to the size of the
base register, and properly ORs it with the left-hand side.

Note, the fix also touches the `setw` macro from BinaryAnalysisPlatform#1454. It was still
correct, since all uses of setw was properly typed (unlike p-code),
but the new version is more consistent and more general as it now
allows the right-hand side to have a different type.
  • Loading branch information
ivg committed Mar 29, 2022
1 parent 1415134 commit 9485fd0
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 5 deletions.
6 changes: 2 additions & 4 deletions plugins/arm/semantics/arm-bits.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
(set-flags r x y))
(set$ rd r))))

(defun logandnot (rd rn)
(logand rd (lnot rn)))

(defmacro shift-with-carry (shift rd rn rm cnd)
(when (condition-holds cnd)
(let ((r (cast-signed (word-width) rn)))
Expand Down Expand Up @@ -61,4 +58,5 @@

(defmacro setw (reg val)
"(set Wx V) sets a Wx register clearing the upper 32 bits."
(set$ (alias-base-register reg) val))
(set$ (alias-base-register reg)
(cast-unsigned (word-width) val)))
5 changes: 4 additions & 1 deletion plugins/ghidra/semantics/pcode.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
(defmacro set# (typ dst src)
(if (is-symbol typ)
(store-word (cast-word dst) src)
(set$ dst src)))
(let ((typ (coerce (word-width dst) typ)))
(set$ dst (logor
(logandnot dst (- (lshift 1 typ) 1))
(cast-unsigned (word-width dst) src))))))

(defmacro get# (typ src)
(if (is-symbol typ) (load-word (cast-word src))
Expand Down
4 changes: 4 additions & 0 deletions plugins/primus_lisp/semantics/bits.lisp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
(in-package core)

(defun logandnot (rd rn)
"(logandnot X Y) is X & ~Y, i.e., X and complement of Y"
(logand rd (lnot rn)))

(defun msb (x)
"(msb X) is the most significant bit of X."
(select (- (word-width x) 1) x))
Expand Down

0 comments on commit 9485fd0

Please sign in to comment.