Skip to content

Commit 4d34311

Browse files
authored
adds the specification command (#1197)
The command will print the ogre specification of the file. Also adds the `Image.find_loader` function that enables direct access to the image loaders.
1 parent 856edb2 commit 4d34311

File tree

5 files changed

+78
-2
lines changed

5 files changed

+78
-2
lines changed

lib/bap/bap.mli

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5492,6 +5492,14 @@ module Std : sig
54925492
(** [register_loader ~name backend] registers new loader. *)
54935493
val register_loader : name:string -> (module Loader) -> unit
54945494

5495+
(** [find_loader name] lookups the loader registered under the
5496+
given [name].
5497+
5498+
@since 2.2.0
5499+
*)
5500+
val find_loader : string -> (module Loader) option
5501+
5502+
54955503
(** lists all registered backends *)
54965504
val available_backends : unit -> string list
54975505

lib/bap_image/bap_image.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,9 @@ let map_region data {locn={addr}; info={off; len; endian}} =
182182

183183
let static_view segments = function {addr} as locn ->
184184
match Table.find_addr segments addr with
185-
| None -> Result.failf "region is not mapped to memory" ()
186185
| Some (segmem,_) -> mem_of_locn segmem locn
186+
| None -> Result.failf "region %a is not mapped to memory"
187+
Sexp.pp_hum (sexp_of_location locn) ()
187188

188189
let add_sym segments memory (symtab : symtab)
189190
({name; locn=entry; info={extra_locns=locns}} as sym) =
@@ -327,6 +328,8 @@ let segment_of_symbol {segment_of_symbol = lazy f} = f
327328
let register_loader ~name backend =
328329
Hashtbl.add_exn backends ~key:name ~data:backend
329330

331+
let find_loader = Hashtbl.find backends
332+
330333
module Scheme = struct
331334
open Ogre.Type
332335
type addr = int64

lib/bap_image/bap_image.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ module type Loader = sig
7272
end
7373

7474
val register_loader : name:string -> (module Loader) -> unit
75-
75+
val find_loader : string -> (module Loader) option
7676
val available_backends : unit -> string list
7777

7878

oasis/specification

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Flag specification
2+
Description: Enable the specification command
3+
Default: false
4+
5+
Library specification_plugin
6+
Build$: flag(everything) || flag(specification)
7+
XMETADescription: implements the specification command
8+
Path: plugins/specification
9+
FindlibName: bap-plugin-specification
10+
CompiledObject: best
11+
BuildDepends: bap, core_kernel, bap-main, ogre
12+
InternalModules: Specification_main
13+
XMETAExtraLines: tags="command, specification"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
let doc = "
2+
# DESCRIPTION
3+
4+
Displays information about the binary. The information is printed in
5+
the OGRE format.
6+
"
7+
8+
open Core_kernel
9+
open Bap_main
10+
open Bap.Std
11+
12+
type problem =
13+
| Unknown_loader of string
14+
| Loader_error of Error.t
15+
16+
type Extension.Error.t += Fail of problem
17+
18+
19+
let input = Extension.Command.argument
20+
~doc:"The input file" Extension.Type.("FILE" %: string =? "a.out" )
21+
22+
let loader =
23+
Extension.Command.parameter
24+
~doc:"Use the specified loader.
25+
Use the loader `raw' to load unstructured files"
26+
Extension.Type.(string =? "llvm")
27+
"loader"
28+
29+
let problem is = Error (Fail is)
30+
31+
let () = Extension.Command.(begin
32+
declare "specification" (args $input $loader)
33+
~doc
34+
~requires:["loader"]
35+
end) @@ fun input loader _ctxt ->
36+
match Image.find_loader loader with
37+
| None -> problem (Unknown_loader loader)
38+
| Some (module Load) -> match Load.from_file input with
39+
| Ok (Some spec) -> Format.printf "%a@\n%!" Ogre.Doc.pp spec; Ok ()
40+
| Ok None -> Ok ()
41+
| Error err -> problem (Loader_error err)
42+
43+
let string_of_problem = function
44+
| Unknown_loader name ->
45+
sprintf "The loader `%s' is not registers, known loaders are: %s."
46+
name (Image.available_backends () |> String.concat ~sep:", ")
47+
| Loader_error err ->
48+
sprintf "Failed to load the binary: %s" (Error.to_string_hum err)
49+
50+
let () = Extension.Error.register_printer @@ function
51+
| Fail p -> Some (string_of_problem p)
52+
| _ -> None

0 commit comments

Comments
 (0)