-
Notifications
You must be signed in to change notification settings - Fork 5
Memory allocation intrinsics #163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
b1bf43f
Setup grammar
JTrenerry c4ee88d
changes grammar to include call and type check
JTrenerry 27df95d
parse test
JTrenerry 3632bb4
does the transform
JTrenerry 6954856
minimal test
JTrenerry 161ed12
promo
JTrenerry 5d8e204
remove output of free
JTrenerry 2ded50c
remove unused func
JTrenerry 13020d9
was hidden by gitignore :(
JTrenerry 7e6da37
fmt
JTrenerry File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,4 +7,5 @@ trace.json | |
| *.dot | ||
| **/*.dot | ||
|
|
||
| .vscode/ | ||
| .vscode/ | ||
| .helix/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| open Bincaml_util.Common | ||
| open Lang | ||
| open Expr | ||
|
|
||
| let string_to_intrin = | ||
| Stmt.Intrinsic.( | ||
| function | ||
| | "@malloc" | "@#malloc" | "@_malloc" -> Malloc | ||
| | "@calloc" | "@_calloc" | "@zmalloc" -> Calloc | ||
| | "@alloca" | "@_alloca" -> AllocStack | ||
| | "@free" | "@#free" | "@_free" -> Free | ||
| | _ -> failwith "Unreachable") | ||
|
|
||
| let transform_proc proc prog = | ||
| let replace_call (stmt : Program.stmt) : Program.stmt Iter.t = | ||
| match stmt with | ||
| | Stmt.Instr_Call { procid; lhs; args; attrib } -> ( | ||
| match ID.name procid with | ||
| | ( "@malloc" | "@#malloc" | "@calloc" | "@alloca" | "@_malloc" | ||
| | "@_calloc" | "@_alloca" ) as name -> | ||
| let modifies = | ||
| List.filter | ||
| (fun var -> | ||
| not @@ String.starts_with (Var.name var) ~prefix:"R0") | ||
| (Procedure.specification (Program.proc prog procid)) | ||
| .modifies_globs | ||
| in | ||
| let lhs = | ||
| StringMap.filter | ||
| (fun name _ -> String.starts_with name ~prefix:"R0") | ||
| lhs | ||
| |> StringMap.values |> List.of_iter | ||
| in | ||
| let args = | ||
| StringMap.filter | ||
| (fun name _ -> String.starts_with name ~prefix:"R0") | ||
| args | ||
| |> StringMap.values |> List.of_iter | ||
| in | ||
| Iter.doubleton | ||
| (Stmt.Instr_IntrinCall | ||
| { name = string_to_intrin name; lhs; args; attrib }) | ||
| (Stmt.Instr_IntrinCall | ||
| { | ||
| name = Stmt.Intrinsic.Havoc; | ||
| lhs = modifies; | ||
| args = []; | ||
| attrib = Attrib.empty; | ||
| }) | ||
| | ("@#free" | "@free" | "@_free") as name -> | ||
| let modifies = | ||
| (Procedure.specification (Program.proc prog procid)) | ||
| .modifies_globs | ||
| in | ||
| let lhs = StringMap.values lhs |> List.of_iter in | ||
| let args = | ||
| StringMap.filter | ||
| (fun name _ -> String.starts_with name ~prefix:"R0") | ||
| args | ||
| |> StringMap.values |> List.of_iter | ||
| in | ||
| Iter.doubleton | ||
| (Stmt.Instr_IntrinCall | ||
| { name = string_to_intrin name; lhs; args; attrib }) | ||
| (Stmt.Instr_IntrinCall | ||
| { | ||
| name = Stmt.Intrinsic.Havoc; | ||
| lhs = modifies; | ||
| args = []; | ||
| attrib = Attrib.empty; | ||
| }) | ||
| | ("@#havoc" | "@havoc" | "@_havoc") as name -> | ||
| let modifies = | ||
| (Procedure.specification (Program.proc prog procid)) | ||
| .modifies_globs | ||
| in | ||
| let lhs = StringMap.values lhs |> List.of_iter in | ||
| Iter.doubleton | ||
| (Stmt.Instr_IntrinCall | ||
| { name = string_to_intrin name; lhs; args = []; attrib }) | ||
| (Stmt.Instr_IntrinCall | ||
| { | ||
| name = Stmt.Intrinsic.Havoc; | ||
| lhs = modifies; | ||
| args = []; | ||
| attrib = Attrib.empty; | ||
| }) | ||
| | _ -> Iter.singleton stmt) | ||
| | _ -> Iter.singleton stmt | ||
| in | ||
| let open BasilExpr in | ||
| Procedure.map_blocks_topo_fwd | ||
| (fun _ b -> Block.flat_map ~phi:id replace_call b) | ||
| proc | ||
|
|
||
| let transform (prog : Program.t) = | ||
| Program.map_procedures (fun pid proc -> transform_proc proc prog) prog | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -263,6 +263,49 @@ let type_check stmt_id block_id expr = | |
| in | ||
| BasilExpr.cata type_error_alg expr | ||
|
|
||
| let check_intrin_call (intrin_call : Stmt.Intrinsic.t) args params = | ||
| Stmt.Intrinsic.( | ||
| match intrin_call with | ||
| | Havoc -> ( | ||
| match params with | ||
| | [] -> [] | ||
| | _ -> [ TypeError { text = "Havoc should not have args" } ]) | ||
| | Malloc | AllocStack | Calloc -> ( | ||
| match (args, params) with | ||
| | [ size ], [ ptr ] -> | ||
| let err = | ||
| if Types.leq (Bitvector 64) (BasilExpr.type_of ptr) then [] | ||
| else | ||
| [ | ||
| TypeError | ||
| { text = "Wrong type of arg in " ^ to_string intrin_call }; | ||
| ] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you put this if-then-else into a function, since it's quite big and repeated |
||
| in | ||
| if Types.equal (Bitvector 64) (Var.typ size) then err | ||
| else | ||
| TypeError | ||
| { text = "Wrong type of arg in " ^ to_string intrin_call } | ||
| :: err | ||
| | _ -> | ||
| [ | ||
| TypeError | ||
| { text = "Wrong amount of args in " ^ to_string intrin_call }; | ||
| ]) | ||
| | Free | FreeStack -> ( | ||
| match (args, params) with | ||
| | [ ptr ], [] -> | ||
| if Types.leq (Bitvector 64) (Var.typ ptr) then [] | ||
| else | ||
| [ | ||
| TypeError | ||
| { text = "Wrong type of arg in " ^ to_string intrin_call }; | ||
| ] | ||
| | _ -> | ||
| [ | ||
| TypeError | ||
| { text = "Wrong amount of args in " ^ to_string intrin_call }; | ||
| ])) | ||
|
|
||
| let check_stmt_types (stmt : Program.stmt) (pt : Program.t) stmt_id block_id = | ||
| let type_err fmt = type_err fmt stmt_id block_id in | ||
| let expect_equal msg a b (s : type_error list) = | ||
|
|
@@ -273,7 +316,6 @@ let check_stmt_types (stmt : Program.stmt) (pt : Program.t) stmt_id block_id = | |
| in | ||
| let type_check = type_check stmt_id block_id in | ||
| match stmt with | ||
| | Stmt.Instr_IntrinCall _ -> [] | ||
| | Stmt.Instr_Assign { al } -> | ||
| al | ||
| |> List.fold_left | ||
|
|
@@ -386,6 +428,7 @@ let check_stmt_types (stmt : Program.stmt) (pt : Program.t) stmt_id block_id = | |
| output) | ||
| in | ||
| params_check | ||
| | Stmt.Instr_IntrinCall { name; lhs; args } -> check_intrin_call name lhs args | ||
|
|
||
| let check_block prog (id, b) = | ||
| Block.stmts_iter b | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| proc @main_4196164(R0_in:bv64, R10_in:bv64, R11_in:bv64, R12_in:bv64, R13_in:bv64, | ||
| R14_in:bv64, R15_in:bv64, R16_in:bv64, R17_in:bv64, R18_in:bv64, R1_in:bv64, | ||
| R29_in:bv64, R2_in:bv64, R30_in:bv64, R31_in:bv64, R3_in:bv64, R4_in:bv64, | ||
| R5_in:bv64, R6_in:bv64, R7_in:bv64, R8_in:bv64, R9_in:bv64, _PC_in:bv64) | ||
| -> (R0_out:bv64, R1_out:bv64) { .address = 4196164; .name = "main"; | ||
| .returnBlock = "main_return" } | ||
|
|
||
| [ | ||
| block %main_entry [ | ||
| var as:bv64 := 0x32:bv64; | ||
| (var x_2:bv64, var x_3:bv64, var addr:bv64):= call @_havoc(); | ||
| (var ptr0:bv64):= call @_malloc(as:bv64); | ||
| (var ptr1:bv64):= call @_calloc(as:bv64); | ||
| call @_free(ptr0:bv64); | ||
| call @_free(ptr1:bv64); | ||
| (var stack_ptr:bv64):= call @_alloca(as:bv64); | ||
| call @_free_alloca(stack_ptr:bv64); | ||
| goto (%main_return); | ||
| ]; | ||
| block %main_return [ | ||
| (var R0_out:bv64 := 0x0:bv64, var R1_out:bv64 := 0x2a:bv64); | ||
| return; | ||
| ] | ||
| ]; | ||
| prog entry @main_4196164; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| (load-il "../../examples/memory/malloc_free.il") | ||
| (run-transforms "intrin-call") | ||
| (dump-il "after.il") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| $ bincaml script intrin_call.sexp | ||
| (load-il ../../examples/memory/malloc_free.il) | ||
| (run-transforms intrin-call) | ||
| (dump-il after.il) | ||
| $ cat after.il | ||
| var observable $mem:(bv64->bv8); | ||
| var $stack:(bv64->bv8); | ||
| proc @main_2276(R0_in:bv64, R16_in:bv64, R17_in:bv64, R1_in:bv64, R29_in:bv64, | ||
| R30_in:bv64, R31_in:bv64, _PC_in:bv64) | ||
| -> (R0_out:bv64, R17_out:bv64, R1_out:bv64, R29_out:bv64, R30_out:bv64) { .address = 2276; | ||
| .name = "main"; .returnBlock = "main_return" } | ||
| modifies $mem:(bv64->bv8), $stack:(bv64->bv8) | ||
| captures $mem:(bv64->bv8), $stack:(bv64->bv8) | ||
|
|
||
| [ | ||
| block %main_entry [ | ||
| $stack:(bv64->bv8) := store le $stack:(bv64->bv8) bvadd(R31_in:bv64, | ||
| 0xffffffffffffffe0:bv64) R29_in:bv64 64; | ||
| $stack:(bv64->bv8) := store le $stack:(bv64->bv8) bvadd(R31_in:bv64, | ||
| 0xffffffffffffffe8:bv64) R30_in:bv64 64; | ||
| var Exp14__5_2_1:bv64 := load le $mem:(bv64->bv8) 0x20010:bv64 64; | ||
| assert true; | ||
| (var R0_3:bv64):= call @_malloc(0x1:bv64); | ||
| ($mem:(bv64->bv8), $stack:(bv64->bv8)):= call @_havoc(); | ||
| goto (%phi_5); | ||
| ]; | ||
| block %phi_5 [ | ||
| $stack:(bv64->bv8) := store le $stack:(bv64->bv8) bvadd(R31_in:bv64, | ||
| 0xfffffffffffffff8:bv64) R0_3:bv64 64; | ||
| var Exp14__5_21_1:bv64 := load le $stack:(bv64->bv8) bvadd(R31_in:bv64, | ||
| 0xfffffffffffffff8:bv64) 64; | ||
| $mem:(bv64->bv8) := store le $mem:(bv64->bv8) Exp14__5_21_1:bv64 0x79:bv8 8; | ||
| var Exp14__5_22_1:bv64 := load le $stack:(bv64->bv8) bvadd(R31_in:bv64, | ||
| 0xfffffffffffffff8:bv64) 64; | ||
| var Exp14__5_1_1:bv64 := load le $mem:(bv64->bv8) 0x20028:bv64 64; | ||
| assert true; | ||
| call @_free(Exp14__5_22_1:bv64); | ||
| ($mem:(bv64->bv8), $stack:(bv64->bv8)):= call @_havoc(); | ||
| goto (%phi_6); | ||
| ]; | ||
| block %phi_6 [ | ||
| var Exp16__5_24_1:bv64 := load le $stack:(bv64->bv8) bvadd(R31_in:bv64, | ||
| 0xffffffffffffffe0:bv64) 64; | ||
| var Exp18__5_25_1:bv64 := load le $stack:(bv64->bv8) bvadd(R31_in:bv64, | ||
| 0xffffffffffffffe8:bv64) 64; | ||
| goto (%main_return); | ||
| ]; | ||
| block %main_return [ | ||
| (var R0_out:bv64 := 0x0:bv64, var R17_out:bv64 := Exp14__5_1_1:bv64, | ||
| var R1_out:bv64 := 0x79:bv64, var R29_out:bv64 := Exp16__5_24_1:bv64, | ||
| var R30_out:bv64 := Exp18__5_25_1:bv64); | ||
| return; | ||
| ] | ||
| ]; | ||
| proc @malloc(R0_in:bv64) -> (R0_out:bv64) { .name = "malloc" } | ||
| modifies $mem:(bv64->bv8), $stack:(bv64->bv8) | ||
| captures $mem:(bv64->bv8), $stack:(bv64->bv8) | ||
| ; | ||
| proc @#free(R0_in:bv64) -> () { .name = "#free" } | ||
| modifies $mem:(bv64->bv8), $stack:(bv64->bv8) | ||
| captures $mem:(bv64->bv8), $stack:(bv64->bv8) | ||
| ; | ||
| prog entry @main_2276; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this return an option and have
replace_callmatch on the result of this function? that way there isn't duplication of function name strings (though they are also duplicated in lang/stmt.ml so perhaps a better solution exists).