elf_arrows: add boxes according to debug_lines
This commit is contained in:
parent
520d9527ab
commit
4583ad6a92
3 changed files with 68 additions and 7 deletions
|
@ -6,6 +6,8 @@ module S (Annot: Annot_type) = struct
|
||||||
(** A memory address *)
|
(** A memory address *)
|
||||||
type addr_t = int
|
type addr_t = int
|
||||||
|
|
||||||
|
module AddrMap = Map.Make(struct type t = addr_t let compare = compare end)
|
||||||
|
|
||||||
(** A single asm instruction *)
|
(** A single asm instruction *)
|
||||||
type asm_instr_t = {
|
type asm_instr_t = {
|
||||||
instr_addr: addr_t; (** Memory location of this instruction *)
|
instr_addr: addr_t; (** Memory location of this instruction *)
|
||||||
|
|
|
@ -34,6 +34,29 @@ let open_elf elf_path =
|
||||||
Error.Success (ElfHandle (elf_path, elf_file, static_info, asm_info)))
|
Error.Success (ElfHandle (elf_path, elf_file, static_info, asm_info)))
|
||||||
|
|
||||||
|
|
||||||
|
(** Add boxes according to DWARF info *)
|
||||||
|
let add_line_boxes render_data dwarf_lines =
|
||||||
|
(* List.fold_left with two elements in scope at once. *)
|
||||||
|
let fold_ahead folder base lst =
|
||||||
|
let rec do_fold accu = function
|
||||||
|
| [] | _::[] -> accu
|
||||||
|
| hd1::hd2::tl -> do_fold (folder accu hd1 hd2) (hd2::tl)
|
||||||
|
in
|
||||||
|
do_fold base lst
|
||||||
|
in
|
||||||
|
|
||||||
|
List.fold_left (fun cur_render_data (_, reg_list) ->
|
||||||
|
fold_ahead (fun cur_render_data cur_reg reg_ahead ->
|
||||||
|
let box_start = Z.to_int @@ cur_reg.Dwarf.lnr_address in
|
||||||
|
let box_end = Z.to_int @@ reg_ahead.Dwarf.lnr_address in
|
||||||
|
Format.eprintf "Add box %x -- %x@." box_start box_end ;
|
||||||
|
let n_render_data, _ = Renderer.add_box_excl
|
||||||
|
cur_render_data (box_start, box_end) in
|
||||||
|
n_render_data)
|
||||||
|
cur_render_data reg_list)
|
||||||
|
render_data
|
||||||
|
dwarf_lines
|
||||||
|
|
||||||
let elf_files = ref []
|
let elf_files = ref []
|
||||||
let speclist = []
|
let speclist = []
|
||||||
let parse_anon_arg arg =
|
let parse_anon_arg arg =
|
||||||
|
@ -49,11 +72,18 @@ let _ =
|
||||||
!elf_files
|
!elf_files
|
||||||
in
|
in
|
||||||
|
|
||||||
List.iter (fun (ElfHandle(path, _, static_info, asm)) ->
|
List.iter (fun (ElfHandle(path, _, static_info, _)) ->
|
||||||
ignore asm ;
|
|
||||||
let line_info = static_info.ds_evaluated_line_info in
|
let line_info = static_info.ds_evaluated_line_info in
|
||||||
Format.eprintf "Line infos <%s>:@. %a@."
|
Format.eprintf "Line infos <%s>:@. %a@."
|
||||||
path
|
path
|
||||||
(make_pp Dwarf.pp_evaluated_line_info)
|
(make_pp Dwarf.pp_evaluated_line_info)
|
||||||
line_info ;
|
line_info ;
|
||||||
) elf_handles
|
) elf_handles ;
|
||||||
|
|
||||||
|
List.iter (fun (ElfHandle(_, _, static_info, asm)) ->
|
||||||
|
let render_data = Renderer.init_render_data asm in
|
||||||
|
let line_info = static_info.ds_evaluated_line_info in
|
||||||
|
let boxed_render_data = add_line_boxes render_data line_info in
|
||||||
|
Format.printf "%s@."
|
||||||
|
(Renderer.to_string Html_renderer.render boxed_render_data)
|
||||||
|
) elf_handles;
|
||||||
|
|
|
@ -13,6 +13,7 @@ type tag_addr_range_t = TaggedRange of addr_range_tag_t * addr_range_t
|
||||||
type render_data_t = {
|
type render_data_t = {
|
||||||
render_prog : RawAsm.asm_info_t ;
|
render_prog : RawAsm.asm_info_t ;
|
||||||
render_boxes : tag_addr_range_t list ;
|
render_boxes : tag_addr_range_t list ;
|
||||||
|
render_prev_address : RawAsm.addr_t RawAsm.AddrMap.t
|
||||||
}
|
}
|
||||||
|
|
||||||
type render_box_event_t =
|
type render_box_event_t =
|
||||||
|
@ -24,15 +25,33 @@ type asm_annot_type = {
|
||||||
}
|
}
|
||||||
module AnnotAsm = Asm_info.S(struct type instr_annot_t = asm_annot_type end)
|
module AnnotAsm = Asm_info.S(struct type instr_annot_t = asm_annot_type end)
|
||||||
|
|
||||||
|
(** Make a map mapping addresses to the preceding instruction address appearing
|
||||||
|
in `prog` *)
|
||||||
|
let make_prev_address prog =
|
||||||
|
let _, addr_map =
|
||||||
|
List.fold_left (fun (prev_addr, cmap) sub ->
|
||||||
|
List.fold_left (fun (prev_addr, cmap) instr ->
|
||||||
|
(instr.RawAsm.instr_addr,
|
||||||
|
RawAsm.AddrMap.add instr.RawAsm.instr_addr prev_addr cmap)
|
||||||
|
)
|
||||||
|
(prev_addr, cmap)
|
||||||
|
sub.RawAsm.sub_asm
|
||||||
|
)
|
||||||
|
(0, RawAsm.AddrMap.empty)
|
||||||
|
prog
|
||||||
|
in
|
||||||
|
addr_map
|
||||||
|
|
||||||
(** Initializes a rendering data structure on the given program *)
|
(** Initializes a rendering data structure on the given program *)
|
||||||
let init_render_data prog =
|
let init_render_data prog =
|
||||||
{ render_prog = prog ;
|
{ render_prog = prog ;
|
||||||
render_boxes = []
|
render_boxes = [] ;
|
||||||
|
render_prev_address = make_prev_address prog ;
|
||||||
}
|
}
|
||||||
|
|
||||||
(** [add_box render_data range] adds a box around an address range in
|
(** [add_box render_data range] adds a box around an address range, inclusive
|
||||||
[render_data] and returns the new render data and the newly inserted
|
of both bounds, in [render_data] and returns the new render data and the
|
||||||
element's id *)
|
newly inserted element's id *)
|
||||||
let add_box render_data range : render_data_t * int =
|
let add_box render_data range : render_data_t * int =
|
||||||
let elt_id = (match render_data.render_boxes with
|
let elt_id = (match render_data.render_boxes with
|
||||||
| [] -> 0
|
| [] -> 0
|
||||||
|
@ -43,6 +62,16 @@ let add_box render_data range : render_data_t * int =
|
||||||
render_boxes = (TaggedRange(elt_id, range)) :: render_data.render_boxes
|
render_boxes = (TaggedRange(elt_id, range)) :: render_data.render_boxes
|
||||||
}, elt_id
|
}, elt_id
|
||||||
|
|
||||||
|
|
||||||
|
(** Same as [add_box], with an included start, excluded end for range. *)
|
||||||
|
let add_box_excl render_data (addr_beg, addr_end) =
|
||||||
|
(match RawAsm.AddrMap.find_opt addr_end render_data.render_prev_address with
|
||||||
|
| None -> Format.eprintf "Box end address %x not found, ignoring box."
|
||||||
|
addr_end ;
|
||||||
|
raise Not_found
|
||||||
|
| Some end_bound -> add_box render_data (addr_beg, end_bound)
|
||||||
|
)
|
||||||
|
|
||||||
(** [to_file renderer render_data path] renders the given [render_data] to a
|
(** [to_file renderer render_data path] renders the given [render_data] to a
|
||||||
file at [path] using the provided specific renderer *)
|
file at [path] using the provided specific renderer *)
|
||||||
let to_file renderer render_data path =
|
let to_file renderer render_data path =
|
||||||
|
|
Loading…
Reference in a new issue