From caac87e70a9ae39b61fdfa628cf30f084ad1a51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Mon, 18 Nov 2019 13:48:20 +0100 Subject: [PATCH] Allow rendering of multiple files side by side --- src/elf_arrows.ml | 18 ++++++++--- src/html_renderer.ml | 22 ++++++++----- src/render_html.jingoo | 70 +++++++++++++++++++++++++++--------------- src/renderer.ml | 59 ++++++++++++++++++++++------------- 4 files changed, 111 insertions(+), 58 deletions(-) diff --git a/src/elf_arrows.ml b/src/elf_arrows.ml index 6b552cd..d592314 100644 --- a/src/elf_arrows.ml +++ b/src/elf_arrows.ml @@ -51,7 +51,13 @@ let add_line_boxes render_data dwarf_lines = 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 + cur_render_data (box_start, box_end) + Renderer.(Some { + box_file = Z.to_int cur_reg.lnr_file; + box_line = Z.to_int cur_reg.lnr_line; + box_col = Z.to_int cur_reg.lnr_column; + }) + in n_render_data) cur_render_data reg_list) render_data @@ -80,10 +86,12 @@ let _ = line_info ; ) elf_handles ; - List.iter (fun (ElfHandle(_, _, static_info, asm)) -> + let multi_render_data = List.map (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; + boxed_render_data + ) elf_handles in + + Format.printf "%s@." + (Renderer.to_string Html_renderer.render multi_render_data) diff --git a/src/html_renderer.ml b/src/html_renderer.ml index f8b38cb..bd19334 100644 --- a/src/html_renderer.ml +++ b/src/html_renderer.ml @@ -18,14 +18,17 @@ let render_prog_box annotated_prog = Jingoo.Jg_types.(Renderer.AnnotAsm.( )); ("instr_asm", box_string row.instr_asm); ("instr_events", (List.map (fun event -> - let typ, id, bound = Renderer.(match event with - | BoxStart(id, bound) -> "start", id, bound - | BoxEnd(id, bound) -> "end", id, bound + let typ, id, bound, data = Renderer.(match event with + | BoxStart(id, bound, data) -> "start", id, bound, data + | BoxEnd(id, bound, data) -> "end", id, bound, data ) in [ ("typ", box_string typ); ("id", box_int id); ("bound", box_string @@ render_addr bound); + ("data", box_string @@ Format.sprintf "File %d, %d:%d" + data.box_file data.box_line data.box_col); + ] |> box_obj) row.instr_annot.Renderer.events) |> box_list); @@ -36,11 +39,16 @@ let render_prog_box annotated_prog = Jingoo.Jg_types.(Renderer.AnnotAsm.( |> box_list )) -(** [render render_data] renders the given [render_data] to a string. *) -let render render_data = Jingoo.( - let annotated_prog = Renderer.render_data_to_annotated_asm render_data in +let render_progs_box annotated_progs = + List.map render_prog_box annotated_progs + |> Jingoo.Jg_types.box_list + +(** [render multi_render_data] renders the given [render_data] to a string. *) +let render multi_render_data = Jingoo.( + let annotated_progs = List.map (fun render_data -> + Renderer.render_data_to_annotated_asm render_data) multi_render_data in let models = [ - ("subroutines", render_prog_box annotated_prog); + ("progs", render_progs_box annotated_progs); ] in Jg_template.from_file "src/render_html.jingoo" ~models:models ) diff --git a/src/render_html.jingoo b/src/render_html.jingoo index d7db314..2f4c17b 100644 --- a/src/render_html.jingoo +++ b/src/render_html.jingoo @@ -6,6 +6,18 @@ body { font-family: "mono"; font-size: 12px; + background-color: #f7f6fd; + } + + .prog_container { + display: flex; + justify-content: space-around; + } + + .prog { + background-color: white; + padding: 15px; + border: 1px solid #9584ff; } .subroutine { @@ -28,40 +40,48 @@ .instr_bytes { color: grey; } - + .instr_box { background-color: #ffffb4; } - {% for subroutine in subroutines %} -
-
- {{ subroutine.sub_addr }} - [{{ subroutine.sub_section }}] - <{{ subroutine.sub_name }}>: -
-
- {% for row in subroutine.sub_asm %} - {% for event in row.instr_events %} - {% if event.typ == "start" %} -
- {% endif %} - {% endfor %} -
- {{ row.instr_addr }} -
{{ row.instr_bytes }}
- {{ row.instr_asm }} +
+ {% for subroutines in progs %} +
+ {% for subroutine in subroutines %} +
+
+ {{ subroutine.sub_addr }} + [{{ subroutine.sub_section }}] + <{{ subroutine.sub_name }}>: +
+
+ {% for row in subroutine.sub_asm %} + {% for event in row.instr_events %} + {% if event.typ == "start" %} +
+ {% endif %} + {% endfor %} +
+ {{ row.instr_addr }} +
{{ row.instr_bytes }}
+ {{ row.instr_asm }} +
+ {% for event in row.instr_events %} + {% if event.typ == "end" %} +
+ {% endif %} + {% endfor %} + {% endfor %}
- {% for event in row.instr_events %} - {% if event.typ == "end" %} -
- {% endif %} - {% endfor %} - {% endfor %}
+ {% endfor %}
{% endfor %} +
diff --git a/src/renderer.ml b/src/renderer.ml index 6717be5..4cfb055 100644 --- a/src/renderer.ml +++ b/src/renderer.ml @@ -7,8 +7,14 @@ module RawAsm = Asm_info.NoAnnot type addr_range_t = RawAsm.addr_t * RawAsm.addr_t +type box_data_t = { + box_file : int; + box_line : int; + box_col : int; +} type addr_range_tag_t = int -type tag_addr_range_t = TaggedRange of addr_range_tag_t * addr_range_t +type tag_addr_range_t = TaggedRange of addr_range_tag_t * addr_range_t * + box_data_t type render_data_t = { render_prog : RawAsm.asm_info_t ; @@ -16,9 +22,11 @@ type render_data_t = { render_prev_address : RawAsm.addr_t RawAsm.AddrMap.t } +type multi_render_data_t = render_data_t list + type render_box_event_t = - BoxStart of addr_range_tag_t * RawAsm.addr_t - | BoxEnd of addr_range_tag_t * RawAsm.addr_t + BoxStart of addr_range_tag_t * RawAsm.addr_t * box_data_t + | BoxEnd of addr_range_tag_t * RawAsm.addr_t * box_data_t type asm_annot_type = { events : render_box_event_t list @@ -52,24 +60,33 @@ let init_render_data prog = (** [add_box render_data range] adds a box around an address range, inclusive of both bounds, in [render_data] and returns the new render data and the newly inserted element's id *) -let add_box render_data range : render_data_t * int = +let add_box render_data range opt_data : render_data_t * int = let elt_id = (match render_data.render_boxes with | [] -> 0 - | TaggedRange(prev_id, _)::_ -> prev_id + 1) in + | TaggedRange(prev_id, _, _)::_ -> prev_id + 1) in + let data = (match opt_data with + | Some data -> data + | None -> { + box_file = 0; + box_line = 0; + box_col = 0 + }) + in { render_data with - render_boxes = (TaggedRange(elt_id, range)) :: render_data.render_boxes + render_boxes = + (TaggedRange(elt_id, range, data)) :: render_data.render_boxes }, elt_id (** Same as [add_box], with an included start, excluded end for range. *) -let add_box_excl render_data (addr_beg, addr_end) = +let add_box_excl render_data (addr_beg, addr_end) opt_data = (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) + | Some end_bound -> add_box render_data (addr_beg, end_bound) opt_data ) (** [to_file renderer render_data path] renders the given [render_data] to a @@ -81,17 +98,17 @@ let to_file renderer render_data path = |> output_string handle ; close_out handle -(** [to_string renderer render_data] renders the given [render_data] to a - returned string using the provided specific renderer. - This function is provided for unification and clarity, but is an alias for - [renderer]. +(** [to_string renderer multi_render_data] renders the given + [multi_render_data] to a returned string using the provided specific + renderer. This function is provided for unification and clarity, but is an + alias for [renderer]. *) -let to_string renderer render_data = - renderer render_data +let to_string renderer multi_render_data = + renderer multi_render_data let extract_event_addr box_event = match box_event with - | BoxStart(_, addr) -> addr - | BoxEnd(_, addr) -> addr + | BoxStart(_, addr, _) -> addr + | BoxEnd(_, addr, _) -> addr (** [boxes_to_events render_data] converts the list of boxes of `render_data` to a list of events, that is, an address-ordered list of @@ -103,16 +120,16 @@ let boxes_to_events render_data = | 0 -> (match e1, e2 with | BoxEnd(_), BoxStart(_) -> -1 | BoxStart(_), BoxEnd(_) -> 1 - | BoxStart(id1, _), BoxStart(id2, _) -> compare id1 id2 - | BoxEnd(id1, _), BoxEnd(id2, _) -> compare id1 id2 + | BoxStart(id1, _, _), BoxStart(id2, _, _) -> compare id1 id2 + | BoxEnd(id1, _, _), BoxEnd(id2, _, _) -> compare id1 id2 ) | n -> n in let unordered_events = List.fold_left - (fun accu (TaggedRange(elt_id, (range_beg, range_end))) -> - (BoxStart(elt_id, range_beg)) - :: (BoxEnd(elt_id, range_end)) + (fun accu (TaggedRange(elt_id, (range_beg, range_end), data)) -> + (BoxStart(elt_id, range_beg, data)) + :: (BoxEnd(elt_id, range_end, data)) :: accu ) []