2019-09-26 16:35:41 +02:00
|
|
|
(** Entry point file for elf_arrows *)
|
|
|
|
|
|
|
|
exception NotElf;;
|
|
|
|
exception NoDwarf;;
|
|
|
|
exception NoDwarfStatic;;
|
|
|
|
|
|
|
|
let (>>=) = Error.bind
|
|
|
|
|
|
|
|
let make_pp linksem_pp =
|
|
|
|
(fun fmt arg ->
|
|
|
|
linksem_pp arg
|
|
|
|
|> Format.fprintf fmt "%s")
|
|
|
|
|
|
|
|
type elf_path = string
|
2019-11-18 11:35:27 +01:00
|
|
|
type elf_handle =
|
|
|
|
ElfHandle of elf_path * Elf_file.elf_file * Dwarf.dwarf_static
|
|
|
|
* Asm_info.NoAnnot.asm_info_t
|
2019-09-26 16:35:41 +02:00
|
|
|
|
|
|
|
(** Open an ELF file and loads its dwarf_static infos. *)
|
|
|
|
let open_elf elf_path =
|
|
|
|
|
|
|
|
(Byte_sequence.acquire elf_path >>= fun elf_bs -> (
|
|
|
|
match Elf_file.read_elf64_file elf_bs with
|
|
|
|
| Error.Success elf64 -> Error.Success (Elf_file.ELF_File_64 elf64)
|
|
|
|
| Error.Fail _ -> (match Elf_file.read_elf32_file elf_bs with
|
|
|
|
| Error.Success elf32 -> Error.Success (Elf_file.ELF_File_32 elf32)
|
|
|
|
| Error.Fail _ -> raise NotElf)
|
|
|
|
))
|
|
|
|
>>= fun elf_file -> (
|
2019-11-18 11:35:27 +01:00
|
|
|
let asm_info = Asm_acquire.acquire_asm elf_path in
|
2019-09-26 16:35:41 +02:00
|
|
|
let static_info = (match Dwarf.extract_dwarf_static elf_file with
|
|
|
|
| Some static_info -> static_info
|
|
|
|
| None -> raise NoDwarfStatic) in
|
2019-11-18 11:35:27 +01:00
|
|
|
Error.Success (ElfHandle (elf_path, elf_file, static_info, asm_info)))
|
2019-09-26 16:35:41 +02:00
|
|
|
|
|
|
|
|
2019-11-18 13:13:23 +01:00
|
|
|
(** Add boxes according to DWARF info *)
|
2019-11-19 12:52:09 +01:00
|
|
|
let add_line_boxes render_data matcher_data dwarf_lines =
|
2019-11-18 13:13:23 +01:00
|
|
|
(* 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
|
|
|
|
|
2019-11-19 12:52:09 +01:00
|
|
|
List.fold_left (fun (cur_render_data, cur_matcher_data) (_, reg_list) ->
|
|
|
|
fold_ahead (fun (cur_render_data, cur_matcher_data) cur_reg reg_ahead ->
|
2019-11-18 13:13:23 +01:00
|
|
|
let box_start = Z.to_int @@ cur_reg.Dwarf.lnr_address in
|
|
|
|
let box_end = Z.to_int @@ reg_ahead.Dwarf.lnr_address in
|
2019-11-20 15:21:17 +01:00
|
|
|
(match box_start = box_end with
|
|
|
|
| true -> cur_render_data, cur_matcher_data
|
|
|
|
| false ->
|
|
|
|
Format.eprintf "Add box %x -- %x@." box_start box_end ;
|
|
|
|
let n_matcher_data, block_class_id =
|
|
|
|
Asm_matcher.add_block cur_matcher_data cur_reg in
|
|
|
|
let n_render_data, _ = Renderer.add_box_excl
|
|
|
|
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;
|
|
|
|
box_class_id = block_class_id;
|
|
|
|
})
|
|
|
|
in
|
|
|
|
(n_render_data, n_matcher_data))
|
|
|
|
)
|
2019-11-19 12:52:09 +01:00
|
|
|
(cur_render_data, cur_matcher_data) reg_list)
|
|
|
|
(render_data, matcher_data)
|
2019-11-18 13:13:23 +01:00
|
|
|
dwarf_lines
|
|
|
|
|
2019-09-26 16:35:41 +02:00
|
|
|
let elf_files = ref []
|
|
|
|
let speclist = []
|
|
|
|
let parse_anon_arg arg =
|
|
|
|
elf_files := arg :: (!elf_files)
|
|
|
|
|
|
|
|
let _ =
|
|
|
|
Arg.parse speclist parse_anon_arg "./test ELF_FILE" ;
|
|
|
|
let elf_handles = List.rev @@
|
|
|
|
List.map (fun path -> match open_elf path with
|
|
|
|
| Error.Success handle -> handle
|
|
|
|
| Error.Fail msg ->
|
|
|
|
raise (Failure ("Could not open " ^ path ^ ": " ^ msg)))
|
|
|
|
!elf_files
|
|
|
|
in
|
|
|
|
|
2019-11-18 13:13:23 +01:00
|
|
|
List.iter (fun (ElfHandle(path, _, static_info, _)) ->
|
2019-11-18 11:35:27 +01:00
|
|
|
let line_info = static_info.ds_evaluated_line_info in
|
|
|
|
Format.eprintf "Line infos <%s>:@. %a@."
|
|
|
|
path
|
|
|
|
(make_pp Dwarf.pp_evaluated_line_info)
|
|
|
|
line_info ;
|
2019-11-18 13:13:23 +01:00
|
|
|
) elf_handles ;
|
|
|
|
|
2019-11-19 12:52:09 +01:00
|
|
|
let map_with_state mapper initial_state lst =
|
|
|
|
List.fold_right (fun elt (cur_state, accu) ->
|
|
|
|
let n_state, mapped_elt = mapper cur_state elt in
|
|
|
|
n_state, mapped_elt::accu)
|
|
|
|
lst
|
|
|
|
(initial_state, [])
|
|
|
|
in
|
|
|
|
|
|
|
|
let _, multi_render_data = map_with_state
|
|
|
|
(fun matcher_state (ElfHandle(path, _, static_info, asm)) ->
|
|
|
|
let render_data = Renderer.init_render_data asm path in
|
|
|
|
let line_info = static_info.ds_evaluated_line_info in
|
|
|
|
let boxed_render_data, n_matcher_state =
|
|
|
|
add_line_boxes render_data matcher_state line_info in
|
|
|
|
n_matcher_state, boxed_render_data
|
|
|
|
) Asm_matcher.empty_state elf_handles in
|
2019-11-18 13:48:20 +01:00
|
|
|
|
|
|
|
Format.printf "%s@."
|
|
|
|
(Renderer.to_string Html_renderer.render multi_render_data)
|