// 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 { (|>) } = function let int = import! "std/int.glu" let list = import! "std/list.glu" let {List} = list let option = import! "std/option.glu" let {Option} = option let {(++)} = import! "std/string.glu" // Import the falcon library let falcon = import! "scripts/falcon.glu" let {il, loader} = falcon let {Operation} = falcon.types // 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 "Failed to load binary" // Lift the program let program = loader.loader.program_recursive binary let printf = { name="printf", arg="a0" } let sprintf = { name="sprintf", arg="a1" } let snprintf = { name="snprintf", arg="a1" } let prepare_printfs = let f pprintfs = match pprintfs with | Cons p pp -> match il.program.function_by_name program p.name with | Some function -> let address = il.function.address function let p = { address=address, name=p.name, arg=p.arg } Cons p (f pp) | None -> f pp | Nil -> Nil f (Cons printf (Cons sprintf (Cons snprintf Nil))) let printfs = prepare_printfs // Print out the printf types we found let print_printfs printfs = match printfs with | Cons p pp -> falcon.println (p.name ++ " 0x" ++ (falcon.hex p.address)) print_printfs pp | Nil -> () print_printfs printfs let array_to_list a = let ff a i = if (array.len a) == i then Nil else Cons (array.index a i) (ff a (i + 1)) ff a 0 let list_append l r = match l with | Cons x xs -> let f ll = match ll with | Cons x Nil -> Cons x r | Cons x xs -> f xs | Nil -> error "list_append error" f l | Nil -> r let foldl accum l f = match l with | Cons x xs -> foldl (f accum x) xs f | Nil -> accum let map l f = match l with | Cons x xs -> Cons (f x) (map xs f) | Nil -> Nil // given a function, get all branch instructions let branches = let functions = il.program.functions program |> array_to_list foldl Nil functions (\branches function -> Nil) //map branches (\function block instruction target -> // falcon.println (falcon.hex (il.instruction.address instruction))) ()