Add asm annotated type
This commit is contained in:
parent
99adfcaa39
commit
5548c7d1c6
3 changed files with 58 additions and 39 deletions
|
@ -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
26
src/asm_info.ml
Normal 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)
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue