package bap-callsites
Inject data definition terms at callsites
Install
Dune Dependency
Authors
Maintainers
Sources
v2.5.0.tar.gz
sha256=9c126781385d2fa9b8edab22e62b25c70bf2f99f6ec78abb7e5e36d63cfa4174
md5=5abd9b3628b43f797326034f31ca574f
doc/src/bap-plugin-callsites/callsites_main.ml.html
Source file callsites_main.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
open Core_kernel[@@warning "-D"] open Bap.Std include Self() open Option.Monad_infix let call_of_jmp jmp = match Jmp.kind jmp with | Ret _ | Int _ | Goto _ -> None | Call call -> Some call let callee call prog = match Call.target call with | Indirect _ -> None | Direct tid -> Term.find sub_t prog tid let require x = Option.some_if x () let def_of_arg arg = let d = Def.create (Arg.lhs arg) (Arg.rhs arg) in Some (Term.with_attrs d (Term.attrs arg)) let intent_matches x y = match Arg.intent x with | None -> true | Some x -> match x,y with | In,In | Out,Out -> true | Both,_| _,Both -> true | _ -> false let transfer_attr attr t1 t2 = match Term.get_attr t1 attr with | None -> t2 | Some v -> Term.set_attr t2 attr v let transfer_attrs t1 t2 = let t2 = Term.set_attr t2 Term.synthetic () in Term.set_attr t2 Term.origin (Term.tid t1) |> transfer_attr Disasm.insn t1 |> transfer_attr address t1 let is_out = function | Out -> true | _ -> false let add_def intent blk def = if is_out intent then Term.prepend def_t blk def else Term.append def_t blk def let defs_of_args call intent args = List.filter_map args ~f:(fun arg -> require (intent_matches arg intent) >>= fun () -> def_of_arg arg >>| transfer_attrs call) let target intent sub blk call = if is_out intent then Call.return call >>= function | Direct tid -> Term.find blk_t sub tid | _ -> None else Some blk (* Note, that output arguments will be inserted in the reverse order, so we sort all of them in a natural way to get the following order: In Both Out *) let enum_args t = let compare x y = Option.compare compare_intent (Arg.intent x) (Arg.intent y) in Term.enum arg_t t |> Seq.to_list |> List.stable_sort ~compare let insert_defs prog sub = let blk_with_def intent blk jmp sub : blk term option = call_of_jmp jmp >>= fun caller -> callee caller prog >>= fun callee -> target intent sub blk caller >>| fun blk -> enum_args callee |> defs_of_args jmp intent |> List.fold ~init:blk ~f:(add_def intent) in let insert intent blk jmp sub = Option.value_map (blk_with_def intent blk jmp sub) ~default:sub ~f:(Term.update blk_t sub) in List.fold [In;Out] ~init:sub ~f:(fun sub intent -> Term.enum blk_t sub |> Seq.fold ~init:sub ~f:(fun sub blk -> Term.enum jmp_t blk |> Seq.fold ~init:sub ~f:(fun sub jmp -> insert intent blk jmp sub))) let fill_calls program = Term.map sub_t program ~f:(insert_defs program) let main = Project.map_program ~f:fill_calls let () = Config.manpage [ `S "DESCRIPTION"; `P "This pass will inject artificial definitions of a subroutine arguments at call sites. Consider function $(b,malloc) that has the following declaration in BIR:"; `Pre " sub malloc(malloc_size, malloc_result) malloc_size :: in u32 = R0 malloc_result :: out u32 = R0"; `P "This plugin will add two definitions, one just before the call to the malloc:"; `Pre " ... 000001c3: malloc_size := R0 0000015b: call @malloc with return %0000015c"; `P "And prepend another to the block to which malloc will return:"; `Pre " 0000015c: 000001c4: R0 := malloc_result ..."; `S "SEE ALSO"; `P "$(b,bap-plugin-api)(1)" ]; Config.when_ready (fun _ -> Project.register_pass ~deps:["abi"] main)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>