Skip to content

Commit 9f7d1ba

Browse files
authored
fixes some T32 instructions that are accessing to PC (#1357)
The PC register wasn't handled correctly and slipped into the IR. Some of the affected instructions were lifted in the OCaml-written part of lifter and are now rewritten in Primus Lisp (with corrected and extended semantics). There are also a few instruction in the ARM lifter (i.e., A32 encoding) that although treat PC correctly but do not initiate the interworking branch. It might be that handling them correctly might let us to discover more code in the interworked binaries, see E1-4253 in ARMv8 Architecture reference manual, ``` In A32 state only, ADC, ADD, ADR, AND, ASR (immediate), BIC, EOR, LSL (immediate), LSR (immediate), MOV, MVN, ORR, ROR (immediate), RRX, RSB, RSC, SBC, and SUB instructions with <Rd> equal to the PC and without flag-setting specified ```
1 parent dfb4f23 commit 9f7d1ba

File tree

6 files changed

+29
-16
lines changed

6 files changed

+29
-16
lines changed

lib/arm/arm_lifter.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1092,14 +1092,18 @@ module CPU = struct
10921092
let is_mem = is mem
10931093
end
10941094

1095-
10961095
(** Substitute PC with its value *)
10971096
let resolve_pc mem = Stmt.map (object
10981097
inherit Stmt.mapper as super
10991098
method! map_var var =
11001099
if Var.(equal var CPU.pc) then
11011100
Bil.int (CPU.addr_of_pc mem)
11021101
else super#map_var var
1102+
1103+
method! map_move v x =
1104+
if Var.(equal v CPU.pc)
1105+
then super#map_jmp x
1106+
else super#map_move v x
11031107
end)
11041108

11051109
let insn_exn mem insn : bil Or_error.t =

plugins/arm/semantics/thumb.lisp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
(set NF (msb rd))))
5454

5555
(defun tADDhirr (rd rn rm _ _)
56-
(set$ rd (+ rn rm)))
56+
(set$ rd (+ rn (t2reg rm))))
5757

5858
(defun tSBC (rd _ rn rm _ _)
5959
(add-with-carry rd rn (lnot rm) CF))
@@ -87,4 +87,24 @@
8787
(defun t2B (off pre _)
8888
"b.w imm; A7-207, T3"
8989
(when (condition-holds pre)
90-
(exec-addr (+ (get-program-counter) off 4))))
90+
(exec-addr (+ (t2pc) off))))
91+
92+
(defun t2LDRs (rt rn rm imm pre _)
93+
(when (condition-holds pre)
94+
(t2set rt (load-word (+ rn (lshift rm imm))))))
95+
96+
(defun tMOVr (rt rn pre _)
97+
(when (condition-holds pre)
98+
(t2set rt rn)))
99+
100+
(defun t2pc () (+ (get-program-counter) 4))
101+
102+
(defun is-pc (r) (= (symbol r) 'PC))
103+
104+
(defun t2reg (r)
105+
(if (is-pc r) (t2pc) r))
106+
107+
(defun t2set (reg val)
108+
(if (is-pc reg)
109+
(exec-addr val)
110+
(set$ reg val)))

plugins/thumb/thumb_main.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ module Thumb(CT : Theory.Core) = struct
9494
movi8 (reg rd) (imm x)
9595
| `tMOVSr, [|Reg rd; Reg rn|] ->
9696
movsr (reg rd) (reg rn)
97-
| `tMOVr, [|Reg rd; Reg rn; _; _|] ->
98-
movr (reg rd) (reg rn)
9997
| `tASRri, [|Reg rd; _; Reg rm; Imm x; _; _|] ->
10098
asri (reg rd) (reg rm) (imm x)
10199
| `tLSRri, [|Reg rd; _; Reg rm; Imm x; _; _|] ->
@@ -120,8 +118,7 @@ module Thumb(CT : Theory.Core) = struct
120118
| `tLDRi, [|Reg rd; Reg rm; Imm i; _; _|]
121119
| `tLDRspi, [|Reg rd; Reg rm; Imm i; _; _|] ->
122120
ldri (reg rd) (reg rm) (imm i * 4)
123-
| `tLDRr, [|Reg rd; Reg rm; Reg rn; _; _|]
124-
| `t2LDRs, [|Reg rd; Reg rm; Reg rn; _; _; _|] ->
121+
| `tLDRr, [|Reg rd; Reg rm; Reg rn; _; _|] ->
125122
ldrr (reg rd) (reg rm) (reg rn)
126123
| `tLDRpci, [|Reg rd; Imm i; _; _|] ->
127124
ldrpci (reg rd) W32.(pc + int 2) (imm i)

plugins/thumb/thumb_mov.ml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ module Make(CT : Theory.Core) = struct
2929
zf := is_zero (var rd);
3030
]
3131

32-
let movr rd rn = data [
33-
rd := var rn
34-
]
35-
3632
let addi3 rd rn x = with_result rd @@ fun r -> [
3733
r := var rn + const x;
3834
nf := msb (var r);

plugins/thumb/thumb_mov.mli

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ module Make(CT : Theory.Core) : sig
4040
(** [movs rd, rn] *)
4141
val movsr : r32 reg -> r32 reg -> unit eff
4242

43-
(** [mov rd, rn] with [d] or [n] greater than 7. *)
44-
val movr : r32 reg -> r32 reg -> unit eff
45-
4643
(** [asrs rd, rn, #i] *)
4744
val asri : r32 reg -> r32 reg -> int -> unit eff
4845

plugins/thumb/thumb_opcodes.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ open Bap.Std
44
(* all the `mov` series, registers marked with `e` means extended *)
55
type opmov = [
66
| `tMOVi8 (* Rd imm8 *)
7-
| `tMOVr (* Rde Rse *)
87
| `tMOVSr (* Rd Rm affect CSPR *)
98
| `tMVN (* Rd Rm *)
109
| `tADC (* Rd Rn Rm *)
@@ -63,7 +62,7 @@ type opmem_multi = [
6362

6463
type opmem = [
6564
| `tLDRi
66-
| `tLDRr | `t2LDRs
65+
| `tLDRr
6766
| `tLDRpci | `t2LDRpci
6867
| `tLDRspi
6968
| `tLDRBi

0 commit comments

Comments
 (0)