Skip to content

Commit 3fe9155

Browse files
committed
rewrites x86 abi using the new infrastructure
Rewrites all x86 and x86_64 ABI using the new infrastructure. The ABI comprise calling conventions and name demangling schemes. We now support (at various levels of detail) 12 ABI. The most popular ABI, such as cdecl, stdcall, ms, and sysv are quite complete, with sysv lacking only the ability to pass extra wide vectors (a feature that is rarely used in libraries). The improved name demangling scheme now handles x86 and darwin files, so now we have a much better chance to be able to execute them. This commit also includes slight extensions to the bap-c library, such as a new `rebase` operator in the calling convention DSL, an ability to reverse registers when a value is passed via several registers (x86 passes values in the reversed order) and the `is_void` predicate in the `C.Type` module.
1 parent 7c548e0 commit 3fe9155

File tree

17 files changed

+526
-346
lines changed

17 files changed

+526
-346
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ testsuite:
5555
git clone https://github.com/BinaryAnalysisPlatform/bap-testsuite.git testsuite
5656

5757
check: testsuite
58-
make REVISION=c40b332290bab -C testsuite
58+
make REVISION=f0043aaa2cc -C testsuite
5959

6060
.PHONY: indent check-style status-clean
6161

lib/bap_c/bap_c_abi.ml

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -527,14 +527,14 @@ module Arg = struct
527527

528528
let concat = List.reduce_exn ~f:Bil.concat
529529

530-
let registers ?limit file t =
530+
let registers ?(rev=false) ?limit file t =
531531
let* s = Arg.get () in
532532
let* bits = size t in
533533
let* regs_needed = registers_needed file bits in
534534
let limit = Option.value limit ~default:regs_needed in
535535
require (regs_needed <= limit) >>= fun () ->
536536
let* args = Arena.popn ~n:regs_needed s file in
537-
push_arg t @@ concat args
537+
push_arg t @@ concat (if rev then List.rev args else args)
538538

539539
let align_even file =
540540
let* s = Arg.get () in
@@ -556,15 +556,7 @@ module Arg = struct
556556

557557
let reference file t =
558558
with_hidden @@ fun () ->
559-
register file (`Pointer C.Type.Spec.{
560-
t;
561-
attrs = [];
562-
qualifier = C.Type.Qualifier.{
563-
const = false;
564-
volatile = false;
565-
restrict = false;
566-
}
567-
})
559+
register file (C.Type.pointer t)
568560

569561
let update_stack f =
570562
let* s = Arg.get () in
@@ -583,8 +575,16 @@ module Arg = struct
583575
let* bits = size t in
584576
update_stack @@ Stack.add t (data s.ruler t) bits
585577

578+
let hidden t =
579+
with_hidden @@ fun () ->
580+
memory (C.Type.pointer t)
581+
586582
let skip_memory bits = update_stack @@ Stack.skip bits
587583

584+
let rebase slots =
585+
let* {target} = Arg.get () in
586+
skip_memory (slots * Theory.Target.data_addr_size target)
587+
588588
let load t bits sp base =
589589
let mem = Var.reify (Theory.Target.data t) in
590590
let width = Theory.Target.data_addr_size t in
@@ -698,12 +698,9 @@ end
698698

699699
let define target ruler pass =
700700
let open Bap_core_theory in
701-
let target_name = Theory.Target.name target in
702-
let abi_name =
703-
let abi = Theory.Target.abi target in
704-
if Theory.Abi.(abi = unknown)
705-
then Format.asprintf "%a-unknown" KB.Name.pp target_name
706-
else Format.asprintf "%a" KB.Name.pp target_name in
701+
let abi = Theory.Target.abi target in
702+
let abi_name = Format.asprintf "%s"
703+
(KB.Name.unqualified (Theory.Abi.name abi)) in
707704
let abi_processor = {
708705
apply_attrs = (fun _ x -> x);
709706
insert_args = fun _ attrs proto ->

lib/bap_c/bap_c_abi.mli

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,13 @@ module Arg : sig
270270
Rejects the computation if [arena] doesn't have the necessary
271271
number of registers; the number of required registers is greater
272272
than [limit]; or if the size of [t] is unknown.
273+
274+
If [rev] is true, then the allocated registers will be used in
275+
the reversed order.
276+
277+
@since 2.5.0 accepts the optional [rev] parameter.
273278
*)
274-
val registers : ?limit:int -> arena -> ctype -> unit t
279+
val registers : ?rev:bool -> ?limit:int -> arena -> ctype -> unit t
275280

276281

277282
(** [align_even arena] ensures that the first available register in
@@ -312,6 +317,15 @@ module Arg : sig
312317
pointer role. The size of [t] is not required. *)
313318
val reference : arena -> ctype -> unit t
314319

320+
321+
(** [hidden t] passes the argument of type [t] as a pointer
322+
to [t] via the first available stack slot.
323+
324+
The computation is rejected if the target doesn't have a stack.
325+
326+
@since 2.5.0 *)
327+
val hidden : ctype -> unit t
328+
315329
(** [memory t] passes the argument of type [t] in the next
316330
available stack slot.
317331
@@ -333,6 +347,11 @@ module Arg : sig
333347
*)
334348
val memory : ctype -> unit t
335349

350+
(** [rebase off] rebases the stack position by [n] words.
351+
352+
@since 2.5.0
353+
*)
354+
val rebase : int -> unit t
336355

337356
(** [split a1 a2 t] passes the lower half of the value
338357
via registers in the arena [a1] and the higher via the registers
@@ -387,12 +406,12 @@ module Arg : sig
387406

388407
(** [size t] is the size in bits of an object of type [t].
389408
390-
The computation is rejected if the size is unknown.
409+
The computation is rejected if the size is unknown, i.e., the
410+
type is incomplete.
391411
392412
@since 2.5.0 *)
393413
val size : ctype -> int t
394414

395-
396415
(** [require cnd] rejects the computation if [cnd] doesn't hold.
397416
398417
@since 2.5.0 *)

lib/bap_c/bap_c_type.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ let is_restrict : t -> Bool.t = function
174174
| `Pointer {qualifier={restrict}} -> restrict
175175

176176

177+
let is_void = function `Void -> true | _ -> false
178+
177179
let qualifier ?(const=false) ?(volatile=false) restrict =
178180
Qualifier.{const; volatile; restrict}
179181

lib/bap_c/bap_c_type.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ val is_volatile : t -> Bool.t
161161
val is_restrict : t -> Bool.t
162162

163163

164+
(** [is_void t] true iff [t] is [`Void] *)
165+
val is_void : t -> Bool.t
166+
167+
164168
(** {2 Basic Types} *)
165169

166170
(** [basic x] constructs a basic type.

lib/x86_cpu/.merlin

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
REC
2+
B ../bap_demangle

0 commit comments

Comments
 (0)