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
*)
(** 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
module AsmTypes = Asm_info.NoAnnot
(** Pretty printers *)
let pp_hex_bytes ppx bytes_array =
(* 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 ' ')
let pp_asm_instr ppx asm_instr =
Format.fprintf ppx " %04x:\t%a\t%s@."
asm_instr.instr_addr
pp_hex_bytes asm_instr.instr_bytes
asm_instr.instr_asm
AsmTypes.(
Format.fprintf ppx " %04x:\t%a\t%s@."
asm_instr.instr_addr
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_sub ppx asm_sub =
Format.fprintf ppx "%016x <%s> {%s}:@.@[%a@]@."
asm_sub.sub_addr
asm_sub.sub_name
asm_sub.sub_section
pp_asm asm_sub.sub_asm
AsmTypes.(
Format.fprintf ppx "%016x <%s> {%s}:@.@[%a@]@."
asm_sub.sub_addr
asm_sub.sub_name
asm_sub.sub_section
pp_asm asm_sub.sub_asm
)
let pp_asm_info ppx asm_info =
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;
- the current subroutine's asm lines
*)
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
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
object *)
@ -201,11 +191,12 @@ let interpret_objdump objdump_out : asm_info_t =
(Format.sprintf "Invalid subroutine line: \"%s\""
cur_line))
) in
let line = {
let line = AsmTypes.({
instr_addr = addr;
instr_bytes = bytes_repr;
instr_asm = asm_repr
} in
instr_asm = asm_repr;
instr_annot = ();
}) in
(match objdump_accu with
| ObjdumpAccu(cur_info, cur_section, Some in_flight, 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 buffer = Bytes.create 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")
)
else
Bytes.to_string buffer
@ -26,9 +29,8 @@ let _ =
let objdump_out = read_all in_handle in
close_in in_handle ;
let parsed = Asm_acquire.interpret_objdump objdump_out in
Format.eprintf "%a" Asm_acquire.pp_asm_info parsed
(*
List.iter (fun asm_sub ->
Format.eprintf "%a" Asm_acquire.pp_asm_sub asm_sub)
parsed
*)
let render_data = Renderer.init_render_data parsed in
let render_data, box1 = Renderer.add_box render_data (0x1004, 0x100f) in
ignore box1 ;
Format.printf "%s@." (Renderer.to_string Html_renderer.render render_data)