// This script takes the path to a binary, and the name of a function, and
// prints out a graphviz dot graph of that function in Falcon IL.
// Some standard boilerplate stuff for gluon
let array = import! "std/array.glu"
let function = import! "std/function.glu"
let io = import! "std/io.glu"
let int = import! "std/int.glu"
let option = import! "std/types.glu"
let result = import! "std/result.glu"
let { Option } = option
let { Result } = result
let { (|>) } = function
let string = import! "std/string.glu"
let unwrap option =
match option with
| Some x -> x
| None -> error "unwrapped option with value None"
// Import the falcon library
let falcon = import! "scripts/falcon.glu"
let { analysis, il, loader } = falcon
// Arguments to our script
let filename =
match falcon.env "FILENAME" with
| Some filename -> filename
| None -> error "Could not get filename"
// Load the binary
let binary =
match loader.loader.from_file filename with
| Some x -> x
| None -> error "Could not load binary"
let function =
match falcon.env "FUNCTION_NAME" with
| Some function_name ->
let find functions i name =
if i == (array.len functions) then
None
else
let function_entry = array.index functions i
match loader.function_entry.name function_entry with
| Some entry_name ->
if entry_name == name then
Some function_entry
else
find functions (i + 1) name
| None -> find functions (i + 1) name
let function_entries = loader.loader.function_entries binary
let function_entry = find function_entries 0 function_name
let function_entry =
match function_entry with
| Some function_entry -> function_entry
| None -> error "Failed to find function entry"
let address = loader.function_entry.address function_entry
loader.loader.function binary address
| None ->
match falcon.env "FUNCTION_ADDRESS" with
| Some address ->
let address =
match int.from_str_radix address 16 with
| Ok address -> address
| Err _ -> error "Failed to parse base16 address"
loader.loader.function binary address
| None -> error "Give FUNCTION_NAME or FUNCTION_ADDRESS"
let output =
// let function = analysis.dead_code_elimination function
let cfg = il.function.control_flow_graph function
il.control_flow_graph.dot_graph cfg
falcon.println output