// 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