Compare commits
4 commits
a3a33d4c88
...
4811d68213
Author | SHA1 | Date | |
---|---|---|---|
Théophile Bastian | 4811d68213 | ||
Théophile Bastian | 1aa6caa36c | ||
Théophile Bastian | 1e39d97c88 | ||
Théophile Bastian | a729f654b0 |
|
@ -654,10 +654,15 @@ let process_blk
|
||||||
|
|
||||||
exception Inconsistent of BStd.tid
|
exception Inconsistent of BStd.tid
|
||||||
|
|
||||||
let get_entry_blk graph =
|
let get_entry_blk graph first_addr =
|
||||||
|
let filter_out_of_range = function
|
||||||
|
| None -> None
|
||||||
|
| Some x when x < first_addr -> None
|
||||||
|
| Some x -> Some x
|
||||||
|
in
|
||||||
let entry = BStd.Seq.min_elt (CFG.nodes graph) ~cmp:(fun x y ->
|
let entry = BStd.Seq.min_elt (CFG.nodes graph) ~cmp:(fun x y ->
|
||||||
let ax = opt_addr_of @@ CFG.Node.label x
|
let ax = filter_out_of_range @@ opt_addr_of @@ CFG.Node.label x
|
||||||
and ay = opt_addr_of @@ CFG.Node.label y in
|
and ay = filter_out_of_range @@ opt_addr_of @@ CFG.Node.label y in
|
||||||
match ax, ay with
|
match ax, ay with
|
||||||
| None, None -> compare x y
|
| None, None -> compare x y
|
||||||
| Some _, None -> -1
|
| Some _, None -> -1
|
||||||
|
@ -732,14 +737,27 @@ let process_sub sub next_instr_graph : subroutine_cfa_data =
|
||||||
|
|
||||||
let cfg = BStd.Sub.to_cfg sub in
|
let cfg = BStd.Sub.to_cfg sub in
|
||||||
|
|
||||||
let first_addr = int64_addr_of sub in
|
let first_bap_addr = addr_of sub in
|
||||||
|
let first_addr = to_int64_addr first_bap_addr in
|
||||||
let last_addr = find_last_addr 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 entry_blk = get_entry_blk cfg in
|
let entry_blk = get_entry_blk cfg (first_bap_addr) in
|
||||||
let rbp_pop_set = find_rbp_pop_set cfg entry_blk in
|
let rbp_pop_set = find_rbp_pop_set cfg entry_blk in
|
||||||
|
|
||||||
|
let valid_merge previous_regs cur_regs =
|
||||||
|
let valid_rbp_merge old cur =
|
||||||
|
(old = cur) || (match old, cur with
|
||||||
|
| RbpUndef, RbpCfaOffset _ -> true
|
||||||
|
| _ -> false)
|
||||||
|
in
|
||||||
|
|
||||||
|
let prev_cfa, prev_rbp = previous_regs in
|
||||||
|
let cur_cfa, cur_rbp = cur_regs in
|
||||||
|
(prev_cfa = cur_cfa) && valid_rbp_merge prev_rbp cur_rbp
|
||||||
|
in
|
||||||
|
|
||||||
let rec dfs_process
|
let rec dfs_process
|
||||||
allow_rbp
|
allow_rbp
|
||||||
(sub_changes: (reg_changes_fde * reg_pos) TIdMap.t)
|
(sub_changes: (reg_changes_fde * reg_pos) TIdMap.t)
|
||||||
|
@ -758,12 +776,18 @@ let process_sub sub next_instr_graph : subroutine_cfa_data =
|
||||||
allow_rbp entry_offset cur_blk in
|
allow_rbp entry_offset cur_blk in
|
||||||
let n_sub_changes =
|
let n_sub_changes =
|
||||||
TIdMap.add tid (cur_blk_changes, entry_offset) sub_changes in
|
TIdMap.add tid (cur_blk_changes, entry_offset) sub_changes in
|
||||||
|
|
||||||
BStd.Seq.fold (CFG.Node.succs node cfg)
|
BStd.Seq.fold (CFG.Node.succs node cfg)
|
||||||
~f:(fun accu child -> dfs_process allow_rbp accu child end_reg)
|
~f:(fun accu child ->
|
||||||
|
(match entrypoint_address (CFG.Node.label child) with
|
||||||
|
| Some x when x < first_bap_addr -> accu
|
||||||
|
| _ -> dfs_process allow_rbp accu child end_reg)
|
||||||
|
)
|
||||||
|
|
||||||
~init:n_sub_changes
|
~init:n_sub_changes
|
||||||
| Some (_, former_entry_offset) ->
|
| Some (_, former_entry_offset) ->
|
||||||
(* Already visited: check that entry values are matching *)
|
(* Already visited: check that entry values are matching *)
|
||||||
if entry_offset <> former_entry_offset then (
|
if not @@ valid_merge former_entry_offset entry_offset then (
|
||||||
if allow_rbp then
|
if allow_rbp then
|
||||||
Format.eprintf "Found inconsistency (0x%Lx <%a>): %a -- %a@."
|
Format.eprintf "Found inconsistency (0x%Lx <%a>): %a -- %a@."
|
||||||
(int64_addr_of cur_blk)
|
(int64_addr_of cur_blk)
|
||||||
|
|
|
@ -59,6 +59,24 @@ def detect_clang_flat_to_pyramid(rows):
|
||||||
[k'; k[
|
[k'; k[
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def is_flatness_row(row, prev_cfa, prev_loc, first_row=False):
|
||||||
|
for reg in row:
|
||||||
|
if reg not in ["LOC", "CFA", "ra"] and row[reg] != "u":
|
||||||
|
return prev_cfa, prev_loc, True
|
||||||
|
cfa = row["CFA"]
|
||||||
|
if cfa[:4] != "rsp+":
|
||||||
|
return prev_cfa, prev_loc, True
|
||||||
|
cfa_offset = int(cfa[4:])
|
||||||
|
if cfa_offset != prev_cfa + 8:
|
||||||
|
return prev_cfa, prev_loc, True
|
||||||
|
prev_cfa += 8
|
||||||
|
loc = row["LOC"]
|
||||||
|
if not first_row and loc > prev_loc + 2:
|
||||||
|
return prev_cfa, prev_loc, True
|
||||||
|
prev_loc = loc
|
||||||
|
|
||||||
|
return prev_cfa, prev_loc, False
|
||||||
|
|
||||||
def try_starting_at(start_row):
|
def try_starting_at(start_row):
|
||||||
if len(rows) < start_row + 1: # Ensure we have at least the start row
|
if len(rows) < start_row + 1: # Ensure we have at least the start row
|
||||||
return rows, False
|
return rows, False
|
||||||
|
@ -69,22 +87,17 @@ def detect_clang_flat_to_pyramid(rows):
|
||||||
first_cfa = int(rows[start_row]["CFA"][4:])
|
first_cfa = int(rows[start_row]["CFA"][4:])
|
||||||
prev_cfa = first_cfa
|
prev_cfa = first_cfa
|
||||||
prev_loc = rows[start_row]["LOC"]
|
prev_loc = rows[start_row]["LOC"]
|
||||||
|
first_row = True
|
||||||
|
|
||||||
for row in rows[start_row + 1 :]:
|
for row in rows[start_row + 1 :]:
|
||||||
for reg in row:
|
prev_cfa, prev_loc, flatness = is_flatness_row(
|
||||||
if reg not in ["LOC", "CFA", "ra"] and row[reg] != "u":
|
row, prev_cfa, prev_loc, first_row
|
||||||
break
|
)
|
||||||
cfa = row["CFA"]
|
first_row = False
|
||||||
if cfa[:4] != "rsp+":
|
if flatness:
|
||||||
break
|
break
|
||||||
cfa_offset = int(cfa[4:])
|
|
||||||
if cfa_offset != prev_cfa + 8:
|
|
||||||
break
|
|
||||||
prev_cfa += 8
|
|
||||||
loc = row["LOC"]
|
|
||||||
if loc > prev_loc + 2:
|
|
||||||
break
|
|
||||||
prev_loc = loc
|
|
||||||
flatness_row_id += 1
|
flatness_row_id += 1
|
||||||
|
|
||||||
flatness_row_id += 1
|
flatness_row_id += 1
|
||||||
if flatness_row_id - start_row <= 1 or flatness_row_id >= len(rows):
|
if flatness_row_id - start_row <= 1 or flatness_row_id >= len(rows):
|
||||||
return rows, False # nothing to change
|
return rows, False # nothing to change
|
||||||
|
|
Loading…
Reference in a new issue