Skip to content

Commit dbf22ef

Browse files
authored
fixes the bitvector order function (#1502)
After #1405 the bitvector order function started to take into account, in some cases, the length of the vector so that 0:8 < 0:32, which is not what we want or ever had. This commit fixes this as well as provides two submodules to the bitvector module, `Unsigned` and `Literal` that provides alternative ordering. The former compares bitvectors unsigned and the latter treat them literally, i.e., compares them including their sizes, signedness, and values.
1 parent fa01322 commit dbf22ef

File tree

3 files changed

+66
-8
lines changed

3 files changed

+66
-8
lines changed

lib/bap/bap.mli

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,9 +1235,33 @@ module Std : sig
12351235
expected from integral values. *)
12361236
include Integer.S with type t := t
12371237

1238-
(** A comparable interface with size-monomorphic comparison. *)
1238+
(** The comparable interface with size-monomorphic comparison. *)
12391239
module Mono : Comparable with type t := t
12401240

1241+
1242+
(** The comparable interface using the unsigned order.
1243+
1244+
@since 2.5.0 *)
1245+
module Unsigned : sig
1246+
include Binable.S with type t = t
1247+
include Comparable.S_binable with type t := t
1248+
include Hashable.S_binable with type t := t
1249+
end
1250+
1251+
(** The comparable interface using the literal order.
1252+
1253+
In this order the bitvectors are compared literally, so that
1254+
bitvectors of different sizes but with equal values will be
1255+
different. This is the fastest order.
1256+
1257+
@since 2.5.0 *)
1258+
module Literal : sig
1259+
include Binable.S with type t = t
1260+
include Comparable.S_binable with type t := t
1261+
include Hashable.S_binable with type t := t
1262+
end
1263+
1264+
12411265
(** Specifies the order of bytes in a word. *)
12421266
type endian =
12431267
| LittleEndian (** least significant byte comes first *)

lib/bap_types/bap_bitvector.ml

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ let data_word t x = create x (Theory.Target.bits t) [@@inline]
157157
let to_bitvec x = Packed.payload x [@@inline]
158158
let unsigned x = x [@@inline]
159159
let signed x = Packed.signed x [@@inline]
160-
let hash x = Packed.hash x [@@inline]
160+
let hash x = Bitvec.hash (Packed.payload x) [@@inline]
161161
let bits_of_z x = Bitvec.to_binary (Packed.payload x)
162162
let unop op t = Packed.lift1 t op [@@inline]
163163
let binop op t1 t2 = Packed.lift2 t1 t2 op [@@inline]
@@ -271,20 +271,26 @@ type packed = Packed.t [@@deriving bin_io]
271271
let sexp_of_packed = Sexp_hum.sexp_of_t
272272
let packed_of_sexp = Sexp_hum.t_of_sexp
273273

274+
275+
let compare_literal = Packed.compare
276+
277+
let compare_unsigned x y =
278+
Bitvec.compare (payload x) (payload y)
279+
[@@inline]
280+
274281
let compare_signed x y =
275282
if phys_equal x y then 0
276-
else match Packed.compare x y with
283+
else
284+
match compare_literal x y with
277285
| 0 -> 0
278-
| r ->
286+
| _ ->
279287
if is_signed x || is_signed y then
280288
let x_is_neg = msb x and y_is_neg = msb y in
281289
match x_is_neg, y_is_neg with
282290
| true,false -> -1
283291
| false,true -> 1
284-
| _ -> Bitvec.compare (payload x) (payload y)
285-
else r
286-
287-
292+
| _ -> compare_unsigned x y
293+
else compare_unsigned x y
288294

289295
let with_validation t ~f = Or_error.map ~f (Validate.result t)
290296

@@ -628,6 +634,23 @@ module Trie = struct
628634
end
629635
end
630636

637+
module Literal = struct
638+
type t = packed [@@deriving bin_io, sexp]
639+
include Comparable.Make_binable(Packed)
640+
include Hashable.Make_binable_and_derive_hash_fold_t(Packed)
641+
end
642+
643+
module Unsigned = struct
644+
module Order = struct
645+
type t = packed [@@deriving bin_io,sexp]
646+
let compare = compare_unsigned
647+
let hash = hash
648+
end
649+
include Comparable.Make_binable(Order)
650+
include Hashable.Make_binable_and_derive_hash_fold_t(Order)
651+
include Order
652+
end
653+
631654
include Or_error.Monad_infix
632655
include Regular.Make(struct
633656
type t = packed [@@deriving bin_io, sexp]
@@ -698,6 +721,7 @@ module Stable = struct
698721
end
699722

700723

724+
701725
let to_string = string_of_word
702726
let of_string = word_of_string
703727

lib/bap_types/bap_bitvector.mli

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ type endian =
1313
include Regular.S with type t := t
1414
include Bap_integer.S with type t := t
1515
module Mono : Comparable.S with type t := t
16+
module Unsigned : sig
17+
include Binable.S with type t = t
18+
include Comparable.S_binable with type t := t
19+
include Hashable.S_binable with type t := t
20+
end
21+
module Literal : sig
22+
include Binable.S with type t = t
23+
include Comparable.S_binable with type t := t
24+
include Hashable.S_binable with type t := t
25+
end
1626

1727
val create : Bitvec.t -> int -> t
1828

0 commit comments

Comments
 (0)