Simplest: compute first and last address of sub
This commit is contained in:
parent
e021d781f4
commit
5ecd56a134
2 changed files with 94 additions and 34 deletions
|
@ -31,12 +31,16 @@ let pp_cfa_change ppx addr pos = Simplest.(
|
||||||
Format.fprintf ppx "%a u u@." pp_int64_hex addr
|
Format.fprintf ppx "%a u u@." pp_int64_hex addr
|
||||||
)
|
)
|
||||||
|
|
||||||
let pp_pre_dwarf_readelf ppx pre_dwarf =
|
let pp_pre_dwarf_readelf ppx (pre_dwarf: Simplest.subroutine_cfa_map) =
|
||||||
|
Simplest.(
|
||||||
Simplest.StrMap.iter (fun fde_name entry ->
|
Simplest.StrMap.iter (fun fde_name entry ->
|
||||||
Format.fprintf ppx "FDE %s@." fde_name ;
|
Format.fprintf ppx "FDE %s pc=%a..%a@."
|
||||||
if not (Simplest.AddrMap.is_empty entry) then (
|
fde_name pp_int64_hex entry.beg_pos pp_int64_hex entry.end_pos;
|
||||||
|
let cfa_entry = entry.cfa_changes_fde in
|
||||||
|
if not (Simplest.AddrMap.is_empty cfa_entry) then (
|
||||||
Format.fprintf ppx " LOC CFA ra@." ;
|
Format.fprintf ppx " LOC CFA ra@." ;
|
||||||
Simplest.AddrMap.iter (pp_cfa_change ppx) entry ;
|
Simplest.AddrMap.iter (pp_cfa_change ppx) cfa_entry ;
|
||||||
Format.fprintf ppx "@.")
|
Format.fprintf ppx "@.")
|
||||||
)
|
)
|
||||||
pre_dwarf
|
pre_dwarf
|
||||||
|
)
|
||||||
|
|
|
@ -14,8 +14,14 @@ type cfa_pos =
|
||||||
|
|
||||||
type cfa_changes_fde = cfa_pos AddrMap.t
|
type cfa_changes_fde = cfa_pos AddrMap.t
|
||||||
|
|
||||||
|
type subroutine_cfa_data = {
|
||||||
|
cfa_changes_fde: cfa_changes_fde;
|
||||||
|
beg_pos: memory_address;
|
||||||
|
end_pos: memory_address;
|
||||||
|
}
|
||||||
|
|
||||||
module StrMap = Map.Make(String)
|
module StrMap = Map.Make(String)
|
||||||
type cfa_changes = cfa_changes_fde StrMap.t
|
type subroutine_cfa_map = subroutine_cfa_data StrMap.t
|
||||||
|
|
||||||
module TIdMap = Map.Make(BStd.Tid)
|
module TIdMap = Map.Make(BStd.Tid)
|
||||||
|
|
||||||
|
@ -310,7 +316,66 @@ let get_entry_blk graph =
|
||||||
| None -> assert false
|
| None -> assert false
|
||||||
| Some x -> x
|
| Some x -> x
|
||||||
|
|
||||||
let process_sub sub : cfa_changes_fde =
|
let find_last_addr sub =
|
||||||
|
(** Finds the maximal instruction address in a subroutine *)
|
||||||
|
|
||||||
|
let map_opt fl fr merge l r = match l, r with
|
||||||
|
| None, None -> None
|
||||||
|
| Some x, None -> Some (fl x)
|
||||||
|
| None, Some y -> Some (fr y)
|
||||||
|
| Some x, Some y -> Some (merge (fl x) (fr y))
|
||||||
|
in
|
||||||
|
let max_opt_addr_word = map_opt
|
||||||
|
(fun x -> x)
|
||||||
|
(fun y -> to_int64_addr y)
|
||||||
|
max
|
||||||
|
in
|
||||||
|
let max_opt_addr = map_opt
|
||||||
|
(fun x -> x)
|
||||||
|
(fun y -> y)
|
||||||
|
max
|
||||||
|
in
|
||||||
|
let max_def cur_max def =
|
||||||
|
max_opt_addr_word cur_max (opt_addr_of def)
|
||||||
|
in
|
||||||
|
|
||||||
|
let fold_res =
|
||||||
|
BStd.Seq.fold (BStd.Term.enum BStd.blk_t sub)
|
||||||
|
~init:None
|
||||||
|
~f:(fun cur_max blk ->
|
||||||
|
max_opt_addr
|
||||||
|
(BStd.Seq.fold (BStd.Term.enum BStd.def_t blk)
|
||||||
|
~init:cur_max
|
||||||
|
~f:max_def)
|
||||||
|
(BStd.Seq.fold (BStd.Term.enum BStd.jmp_t blk)
|
||||||
|
~init:cur_max
|
||||||
|
~f:max_def)
|
||||||
|
)
|
||||||
|
in
|
||||||
|
match fold_res with
|
||||||
|
| None -> Int64.zero
|
||||||
|
| Some x -> x
|
||||||
|
|
||||||
|
let cleanup_fde (fde_changes: cfa_changes_fde) : cfa_changes_fde =
|
||||||
|
(** Cleanup the result of `of_sub`.
|
||||||
|
|
||||||
|
Merges entries at the same address, propagates track lost *)
|
||||||
|
|
||||||
|
let fold_one addr cfa_change (accu, last_change, lost_track) =
|
||||||
|
match cfa_change, last_change, lost_track with
|
||||||
|
| _, _, true -> (accu, None, lost_track)
|
||||||
|
| CfaLostTrack, _, false ->
|
||||||
|
(AddrMap.add addr cfa_change accu, None, true)
|
||||||
|
| cfa_change, Some prev_change, false when cfa_change = prev_change ->
|
||||||
|
(accu, last_change, false)
|
||||||
|
| cfa_change, _, false ->
|
||||||
|
(AddrMap.add addr cfa_change accu, Some cfa_change, false)
|
||||||
|
in
|
||||||
|
|
||||||
|
match AddrMap.fold fold_one fde_changes (AddrMap.empty, None, false) with
|
||||||
|
| out, _, _ -> out
|
||||||
|
|
||||||
|
let process_sub sub : subroutine_cfa_data =
|
||||||
(** Extracts the `cfa_changes_fde` of a subroutine *)
|
(** Extracts the `cfa_changes_fde` of a subroutine *)
|
||||||
|
|
||||||
Format.eprintf "Sub %s...@." @@ BStd.Sub.name sub ;
|
Format.eprintf "Sub %s...@." @@ BStd.Sub.name sub ;
|
||||||
|
@ -318,6 +383,9 @@ let process_sub sub : cfa_changes_fde =
|
||||||
let cfg = BStd.Sub.to_cfg sub in
|
let cfg = BStd.Sub.to_cfg sub in
|
||||||
let next_instr_graph = build_next_instr cfg in
|
let next_instr_graph = build_next_instr cfg in
|
||||||
|
|
||||||
|
let first_addr = int64_addr_of sub in
|
||||||
|
let last_addr = find_last_addr sub in
|
||||||
|
|
||||||
let initial_cfa_rsp_offset = Int64.of_int 8 in
|
let initial_cfa_rsp_offset = Int64.of_int 8 in
|
||||||
|
|
||||||
let rec dfs_process
|
let rec dfs_process
|
||||||
|
@ -359,34 +427,22 @@ let process_sub sub : cfa_changes_fde =
|
||||||
changes_map
|
changes_map
|
||||||
AddrMap.empty in
|
AddrMap.empty in
|
||||||
|
|
||||||
merged_changes
|
let cfa_changes = cleanup_fde merged_changes in
|
||||||
|
|
||||||
let cleanup_fde (fde_changes: cfa_changes_fde) : cfa_changes_fde =
|
let output = {
|
||||||
(** Cleanup the result of `of_sub`.
|
cfa_changes_fde = cfa_changes ;
|
||||||
|
beg_pos = first_addr ;
|
||||||
|
end_pos = last_addr ;
|
||||||
|
} in
|
||||||
|
|
||||||
Merges entries at the same address, propagates track lost *)
|
output
|
||||||
|
|
||||||
let fold_one addr cfa_change (accu, last_change, lost_track) =
|
let of_prog prog : subroutine_cfa_map =
|
||||||
match cfa_change, last_change, lost_track with
|
|
||||||
| _, _, true -> (accu, None, lost_track)
|
|
||||||
| CfaLostTrack, _, false ->
|
|
||||||
(AddrMap.add addr cfa_change accu, None, true)
|
|
||||||
| cfa_change, Some prev_change, false when cfa_change = prev_change ->
|
|
||||||
(accu, last_change, false)
|
|
||||||
| cfa_change, _, false ->
|
|
||||||
(AddrMap.add addr cfa_change accu, Some cfa_change, false)
|
|
||||||
in
|
|
||||||
|
|
||||||
match AddrMap.fold fold_one fde_changes (AddrMap.empty, None, false) with
|
|
||||||
| out, _, _ -> out
|
|
||||||
|
|
||||||
|
|
||||||
let of_prog prog : cfa_changes =
|
|
||||||
(** Extracts the `cfa_changes` of a program *)
|
(** Extracts the `cfa_changes` of a program *)
|
||||||
let fold_step accu sub =
|
let fold_step accu sub =
|
||||||
(try
|
(try
|
||||||
let res = cleanup_fde @@ process_sub sub in
|
let subroutine_data = process_sub sub in
|
||||||
StrMap.add (BStd.Sub.name sub) res accu
|
StrMap.add (BStd.Sub.name sub) subroutine_data accu
|
||||||
with
|
with
|
||||||
| InvalidSub -> accu
|
| InvalidSub -> accu
|
||||||
| Inconsistent tid ->
|
| Inconsistent tid ->
|
||||||
|
@ -400,7 +456,7 @@ let of_prog prog : cfa_changes =
|
||||||
~init:StrMap.empty
|
~init:StrMap.empty
|
||||||
~f:fold_step
|
~f:fold_step
|
||||||
|
|
||||||
let of_proj proj : cfa_changes =
|
let of_proj proj : subroutine_cfa_map =
|
||||||
(** Extracts the `cfa_changes` of a project *)
|
(** Extracts the `cfa_changes` of a project *)
|
||||||
let prog = BStd.Project.program proj in
|
let prog = BStd.Project.program proj in
|
||||||
of_prog prog
|
of_prog prog
|
||||||
|
|
Loading…
Reference in a new issue