Add asm annotated type

This commit is contained in:
Théophile Bastian 2019-11-18 11:34:14 +01:00
parent 99adfcaa39
commit 5548c7d1c6
3 changed files with 58 additions and 39 deletions

View file

@ -3,26 +3,10 @@
Uses `objdump -d` internally, and parses the output Uses `objdump -d` internally, and parses the output
*) *)
(** A memory address *)
type addr_t = int
(** A single asm instruction *)
type asm_instr_t = {
instr_addr: addr_t; (** Memory location of this instruction *)
instr_bytes: Bytes.t; (** Binary representation of the instruction *)
instr_asm: string; (** Asm for the instruction (eg `movq …`) *)
}
type asm_t = asm_instr_t list
type asm_sub_t = {
sub_section: string;
sub_name: string;
sub_addr: addr_t;
sub_asm: asm_t;
}
type asm_info_t = asm_sub_t list
exception ParseError of string exception ParseError of string
module AsmTypes = Asm_info.NoAnnot
(** Pretty printers *) (** Pretty printers *)
let pp_hex_bytes ppx bytes_array = let pp_hex_bytes ppx bytes_array =
(* Number of lone spaces to be printed after the bytes. Objdump prints 21. *) (* Number of lone spaces to be printed after the bytes. Objdump prints 21. *)
@ -32,19 +16,23 @@ let pp_hex_bytes ppx bytes_array =
Format.fprintf ppx "%s" (String.make remaining_spaces ' ') Format.fprintf ppx "%s" (String.make remaining_spaces ' ')
let pp_asm_instr ppx asm_instr = let pp_asm_instr ppx asm_instr =
Format.fprintf ppx " %04x:\t%a\t%s@." AsmTypes.(
asm_instr.instr_addr Format.fprintf ppx " %04x:\t%a\t%s@."
pp_hex_bytes asm_instr.instr_bytes asm_instr.instr_addr
asm_instr.instr_asm pp_hex_bytes asm_instr.instr_bytes
asm_instr.instr_asm
)
let pp_asm ppx asm_instrs = List.iter (pp_asm_instr ppx) asm_instrs let pp_asm ppx asm_instrs = List.iter (pp_asm_instr ppx) asm_instrs
let pp_asm_sub ppx asm_sub = let pp_asm_sub ppx asm_sub =
Format.fprintf ppx "%016x <%s> {%s}:@.@[%a@]@." AsmTypes.(
asm_sub.sub_addr Format.fprintf ppx "%016x <%s> {%s}:@.@[%a@]@."
asm_sub.sub_name asm_sub.sub_addr
asm_sub.sub_section asm_sub.sub_name
pp_asm asm_sub.sub_asm asm_sub.sub_section
pp_asm asm_sub.sub_asm
)
let pp_asm_info ppx asm_info = let pp_asm_info ppx asm_info =
List.iter (fun asm_sub -> Format.fprintf ppx "%a" pp_asm_sub asm_sub) List.iter (fun asm_sub -> Format.fprintf ppx "%a" pp_asm_sub asm_sub)
@ -131,12 +119,14 @@ let get_objdump prog_path =
None if the previous subroutine was committed; None if the previous subroutine was committed;
- the current subroutine's asm lines - the current subroutine's asm lines
*) *)
type interpret_objdump_accu = type interpret_objdump_accu =
ObjdumpAccu of asm_info_t * string * asm_sub_t option * asm_t ObjdumpAccu of AsmTypes.asm_info_t * string * AsmTypes.asm_sub_t option *
AsmTypes.asm_t
(** Interprets `objdump -d` output and yield a list of functions, alongside (** Interprets `objdump -d` output and yield a list of functions, alongside
with their addresses, symbol names, asm, *) with their addresses, symbol names, asm, *)
let interpret_objdump objdump_out : asm_info_t = let interpret_objdump objdump_out : AsmTypes.asm_info_t =
(* Reads a string of bytes formatted like "01 23 ae 3f" and output a Bytes.t (* Reads a string of bytes formatted like "01 23 ae 3f" and output a Bytes.t
object *) object *)
@ -201,11 +191,12 @@ let interpret_objdump objdump_out : asm_info_t =
(Format.sprintf "Invalid subroutine line: \"%s\"" (Format.sprintf "Invalid subroutine line: \"%s\""
cur_line)) cur_line))
) in ) in
let line = { let line = AsmTypes.({
instr_addr = addr; instr_addr = addr;
instr_bytes = bytes_repr; instr_bytes = bytes_repr;
instr_asm = asm_repr instr_asm = asm_repr;
} in instr_annot = ();
}) in
(match objdump_accu with (match objdump_accu with
| ObjdumpAccu(cur_info, cur_section, Some in_flight, asm) -> | ObjdumpAccu(cur_info, cur_section, Some in_flight, asm) ->
ObjdumpAccu(cur_info, cur_section, Some in_flight, line::asm) ObjdumpAccu(cur_info, cur_section, Some in_flight, line::asm)

26
src/asm_info.ml Normal file
View file

@ -0,0 +1,26 @@
module type Annot_type = sig
type instr_annot_t
end
module S (Annot: Annot_type) = struct
(** A memory address *)
type addr_t = int
(** A single asm instruction *)
type asm_instr_t = {
instr_addr: addr_t; (** Memory location of this instruction *)
instr_bytes: Bytes.t; (** Binary representation of the instruction *)
instr_asm: string; (** Asm for the instruction (eg `movq …`) *)
instr_annot: Annot.instr_annot_t; (** User-defined annotation *)
}
type asm_t = asm_instr_t list
type asm_sub_t = {
sub_section: string;
sub_name: string;
sub_addr: addr_t;
sub_asm: asm_t;
}
type asm_info_t = asm_sub_t list
end
module NoAnnot = S(struct type instr_annot_t = unit end)

View file

@ -13,8 +13,11 @@ let read_all handle =
let len = in_channel_length handle in let len = in_channel_length handle in
let buffer = Bytes.create len in let buffer = Bytes.create len in
let bytes_read = input handle buffer 0 len in let bytes_read = input handle buffer 0 len in
if bytes_read <> len then if bytes_read <> len then (
Format.eprintf "Could not read whole file. Read %d, expected %d.@."
bytes_read len ;
raise (Failure "Could not read whole file") raise (Failure "Could not read whole file")
)
else else
Bytes.to_string buffer Bytes.to_string buffer
@ -26,9 +29,8 @@ let _ =
let objdump_out = read_all in_handle in let objdump_out = read_all in_handle in
close_in in_handle ; close_in in_handle ;
let parsed = Asm_acquire.interpret_objdump objdump_out in let parsed = Asm_acquire.interpret_objdump objdump_out in
Format.eprintf "%a" Asm_acquire.pp_asm_info parsed
(* let render_data = Renderer.init_render_data parsed in
List.iter (fun asm_sub -> let render_data, box1 = Renderer.add_box render_data (0x1004, 0x100f) in
Format.eprintf "%a" Asm_acquire.pp_asm_sub asm_sub) ignore box1 ;
parsed Format.printf "%s@." (Renderer.to_string Html_renderer.render render_data)
*)