Skip to content

Commit aa81f60

Browse files
committed
implements AVR ABI and refines AVR targets
1 parent cc50b0c commit aa81f60

File tree

4 files changed

+111
-15
lines changed

4 files changed

+111
-15
lines changed

Diff for: lib/bap_avr/bap_avr_target.ml

+52-7
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,87 @@ let package = "bap"
88
type r16 and r8
99

1010
type 'a bitv = 'a Theory.Bitv.t Theory.Value.sort
11+
type reg = r8 Theory.Bitv.t Theory.var
12+
1113

1214
let r16 : r16 bitv = Theory.Bitv.define 16
1315
let r8 : r8 bitv = Theory.Bitv.define 8
1416
let bool = Theory.Bool.t
1517

1618
let reg t n = Theory.Var.define t n
1719

18-
let array ?(index=string_of_int) t pref size =
19-
List.init size ~f:(fun i -> reg t (pref ^ index i))
20+
let array ?(rev=false) ?(start=0) ?(index=string_of_int) t pref size =
21+
let stop = if rev then start-size else start+size in
22+
let stride = if rev then -1 else 1 in
23+
List.range ~stride start stop |>
24+
List.map ~f:(fun i -> reg t (pref ^ index i))
2025

2126
let untyped = List.map ~f:Theory.Var.forget
2227
let (@<) xs ys = untyped xs @ untyped ys
2328

24-
let gpr = array r8 "R" 32
29+
let regs t = List.map ~f:(reg t)
30+
let nums = array r8 "R" 24
31+
let wxyz = regs r8 [
32+
"Wlo"; "Whi";
33+
"Xlo"; "Xhi";
34+
"Ylo"; "Yhi";
35+
"Zlo"; "Zhi";
36+
]
37+
let gpr = nums @< wxyz
2538
let sp = reg r16 "SP"
26-
let flags = List.map ~f:(reg bool) [
39+
let flags = regs bool [
2740
"CF"; "ZF"; "NF"; "VF"; "SF"; "HF"; "TF"; "IF"
2841
]
2942

43+
3044
let datas = Theory.Mem.define r16 r8
3145
let codes = Theory.Mem.define r16 r16
3246

3347
let data = reg datas "data"
3448
let code = reg codes "code"
3549

36-
let parent = Theory.Target.declare ~package "avr"
50+
let parent = Theory.Target.declare ~package "avr8"
3751
~bits:8
3852
~byte:8
3953
~endianness:Theory.Endianness.le
4054

41-
let atmega328 = Theory.Target.declare ~package "ATmega328"
55+
56+
let tiny = Theory.Target.declare ~package "avr8-tiny"
4257
~parent
4358
~data
4459
~code
4560
~vars:(gpr @< [sp] @< flags @< [data] @< [code])
4661

62+
let mega = Theory.Target.declare ~package "avr8-mega"
63+
~parent:tiny
64+
65+
let xmega = Theory.Target.declare ~package "avr8-xmega"
66+
~parent:mega
67+
68+
module Gcc = struct
69+
let abi = Theory.Abi.declare ~package "avr-gcc"
70+
let wreg = regs r8 ["Whi"; "Wlo"]
71+
let args = wreg @ array ~rev:true ~start:23 r8 "R" 16
72+
let rets = wreg @ array ~rev:true ~start:23 r8 "R" 6
73+
let regs = Theory.Role.Register.[
74+
[general; integer], gpr;
75+
[function_argument], untyped args;
76+
[function_return], untyped rets;
77+
[stack_pointer], untyped [sp];
78+
[caller_saved], rets @< regs r8 ["R0"; "Xlo"; "Xhi"; "Zlo"; "Zhi"];
79+
[callee_saved], array ~start:1 r8 "R" 17 @< regs r8 ["Ylo"; "Yhi"];
80+
]
81+
82+
let target parent name =
83+
Theory.Target.declare ~package name ~regs ~parent ~abi
84+
85+
let tiny = target tiny "avr8-tiny-gcc"
86+
let mega = target mega "avr8-mega-gcc"
87+
let xmega = target xmega "avr8-xmega-gcc"
88+
end
89+
90+
91+
4792
let pcode =
4893
Theory.Language.declare ~package:"bap" "pcode-avr"
4994

@@ -69,7 +114,7 @@ let enable_loader () =
69114
| Ok arch -> arch in
70115
KB.promise Theory.Unit.target @@ fun unit ->
71116
KB.collect Image.Spec.slot unit >>| request_arch >>| function
72-
| Some "avr" -> atmega328
117+
| Some "avr" -> Gcc.mega
73118
| _ -> Theory.Target.unknown
74119

75120

Diff for: lib/bap_avr/bap_avr_target.mli

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
open Bap_core_theory
22

3-
val parent : Theory.target
43

54
val load : unit -> unit
5+
6+
type r8
7+
type reg = r8 Theory.Bitv.t Theory.var
8+
9+
val parent : Theory.target
10+
11+
val tiny : Theory.target
12+
val mega : Theory.target
13+
val xmega : Theory.target
14+
15+
module Gcc : sig
16+
val args : reg list
17+
val rets : reg list
18+
val tiny : Theory.target
19+
val mega : Theory.target
20+
val xmega : Theory.target
21+
end

Diff for: oasis/avr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Library avr_plugin
1414
XMETADescription: provide Avr lifter
1515
Path: plugins/avr
1616
Build$: flag(everything) || flag(avr)
17-
BuildDepends: bap-main, bap-avr
17+
BuildDepends: bap-main, bap-avr, bap, bap-core-theory
1818
FindlibName: bap-plugin-avr
1919
InternalModules: Avr_main
2020
XMETAExtraLines: tags="avr, lifter, atmega"

Diff for: plugins/avr/avr_main.ml

+41-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,47 @@
11
open Bap_main
2+
open Bap_core_theory
3+
4+
module AT = Bap_avr_target
5+
6+
module Abi = struct
7+
open Bap_c.Std
8+
9+
module Arg = C.Abi.Arg
10+
open Arg.Let
11+
open Arg.Syntax
12+
13+
let model = new C.Size.base `LP32
14+
15+
let define t =
16+
C.Abi.define t model @@ fun _ {C.Type.Proto.return=r; args} ->
17+
let* iregs = Arg.Arena.create AT.Gcc.args in
18+
let* irets = Arg.Arena.create AT.Gcc.rets in
19+
let pass_via regs (_,t) =
20+
let open Arg in
21+
choice [
22+
sequence [
23+
align_even regs;
24+
registers regs t;
25+
];
26+
sequence [
27+
deplet regs;
28+
memory t;
29+
]
30+
] in
31+
let args = Arg.List.iter args ~f:(pass_via iregs) in
32+
let return = match r with
33+
| `Void -> None
34+
| r -> Some (pass_via irets ("",r)) in
35+
Arg.define ?return args
36+
37+
let setup () =
38+
List.iter define AT.Gcc.[tiny; mega; xmega]
39+
end
240

341
let main _ctxt =
4-
Bap_avr_target.load ();
42+
AT.load ();
43+
Abi.setup ();
544
Ok ()
645

7-
846
let () = Bap_main.Extension.declare main
9-
~provides:[
10-
"avr";
11-
"lifter";
12-
]
47+
~provides:["avr"; "lifter"; "disassembler"]

0 commit comments

Comments
 (0)