-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1340 from SchiJoha/master
master thesis: Taming Recursion with Three Context-Sensitive Analyses (Callstring, LoopfreeCallstring, Context Gas)
- Loading branch information
Showing
65 changed files
with
3,147 additions
and
6 deletions.
There are no files selected for viewing
This file contains 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,94 @@ | ||
(** | ||
Call String analysis [call_string] and/or Call Site analysis [call_site]. | ||
The call string limitation for both approaches can be adjusted with the "callString_length" option. | ||
By adding new implementations of the CallstringType, additional analyses can be added. | ||
*) | ||
|
||
open Analyses | ||
open GoblintCil | ||
open GobConfig | ||
|
||
(* Specifies the type of the call string elements *) | ||
module type CallstringType = | ||
sig | ||
include CilType.S | ||
val ana_name: string | ||
val new_ele: fundec -> ('d,'g,'c,'v) ctx -> t option (* returns an element that should be pushed to the call string *) | ||
end | ||
|
||
(** Analysis with infinite call string or with limited call string (k-CFA, tracks the last k call stack elements). | ||
With the CT argument it is possible to specify the type of the call string elements *) | ||
module Spec (CT:CallstringType) : MCPSpec = | ||
struct | ||
include Analyses.IdentitySpec | ||
|
||
(* simulates a call string (with or without limitation)*) | ||
module CallString = struct | ||
include Printable.PQueue (CT) | ||
|
||
(* pushes "elem" to the call string, guarantees a depth of k if limitation is specified with "ana.context.callString_length" *) | ||
let push callstr elem = | ||
match elem with | ||
| None -> callstr | ||
| Some e -> | ||
let new_callstr = BatDeque.cons e callstr in (* pushes new element to callstr *) | ||
if get_int "ana.context.callString_length" < 0 | ||
then new_callstr (* infinite call string *) | ||
else (* maximum of k elements *) | ||
match BatDeque.size new_callstr - (get_int "ana.context.callString_length") with | ||
| 1 -> fst @@ Option.get (BatDeque.rear new_callstr) | ||
| x when x <= 0 -> new_callstr | ||
| _ -> failwith "CallString Error: It shouldn't happen that more than one element must be deleted to maintain the correct height!" | ||
end | ||
|
||
module D = Lattice.Flat (CallString) (* should be the CallString (C=D). Since a Lattice is required, Lattice.Flat is used to fulfill the type *) | ||
module C = CallString | ||
module V = EmptyV | ||
module G = Lattice.Unit | ||
|
||
let name () = "call_"^ CT.ana_name | ||
let startstate v = `Lifted (BatDeque.empty) | ||
let exitstate v = `Lifted (BatDeque.empty) | ||
|
||
let context fd x = match x with | ||
| `Lifted x -> x | ||
| _ -> failwith "CallString: Context error! The context cannot be derived from Top or Bottom!" | ||
|
||
let callee_state ctx f = | ||
let elem = CT.new_ele f ctx in (* receive element that should be added to call string *) | ||
let new_callstr = CallString.push (context f ctx.local) elem in | ||
`Lifted new_callstr | ||
|
||
let enter ctx r f args = [ctx.local, callee_state ctx f] | ||
|
||
let combine_env ctx lval fexp f args fc au f_ask = ctx.local | ||
|
||
let threadenter ctx ~multiple lval v args = [callee_state ctx (Cilfacade.find_varinfo_fundec v)] | ||
end | ||
|
||
(* implementations of CallstringTypes*) | ||
module Callstring: CallstringType = struct | ||
include CilType.Fundec | ||
let ana_name = "string" | ||
let new_ele f ctx = | ||
let f' = Node.find_fundec ctx.node in | ||
if CilType.Fundec.equal f' dummyFunDec | ||
then None | ||
else Some f' | ||
end | ||
|
||
module Callsite: CallstringType = struct | ||
include CilType.Stmt | ||
let ana_name = "site" | ||
let new_ele f ctx = | ||
match ctx.prev_node with | ||
| Statement stmt -> Some stmt | ||
| _ -> None (* first statement is filtered *) | ||
end | ||
|
||
let _ = | ||
(* call string approach *) | ||
MCP.register_analysis (module Spec (Callstring) : MCPSpec); (* [call_string] *) | ||
|
||
(* call site approach *) | ||
MCP.register_analysis (module Spec (Callsite) : MCPSpec); (* [call_site] *) |
This file contains 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,60 @@ | ||
(** | ||
Loopfree Callstring analysis [loopfree_callstring] that reduces the call string length of the classical Call String approach for recursions | ||
The idea is to improve the Call String analysis by representing all detected call cycle of the call string in a set | ||
In case no call cycles appears, the call string is identical to the call string of the Call String approach | ||
For example: | ||
- call string [main, a, b, c, a] is represented as [main, {a, b, c}] | ||
- call string [main, a, a, b, b, b] is represented as [main, {a}, {b}] | ||
This approach is inspired by | ||
@see <https://arxiv.org/abs/2301.06439> Schwarz, M., Saan, S., Seidl, H., Erhard, J., Vojdani, V. Clustered Relational Thread-Modular Abstract Interpretation with Local Traces. Appendix F. | ||
*) | ||
open Analyses | ||
|
||
module Spec : MCPSpec = | ||
struct | ||
include Analyses.IdentitySpec | ||
|
||
let name () = "loopfree_callstring" | ||
|
||
module FundecSet = SetDomain.Make (CilType.Fundec) | ||
module Either = Printable.Either (CilType.Fundec) (FundecSet) | ||
|
||
module D = Lattice.Flat (Printable.Liszt (Either)) (* A domain element is a list containing fundecs and sets of fundecs.*) | ||
module C = D | ||
module V = EmptyV | ||
module G = Lattice.Unit | ||
let startstate v = `Lifted([]) | ||
let exitstate v = `Lifted([]) | ||
|
||
let get_list list = match list with | ||
| `Lifted e -> e | ||
| _ -> failwith "Error loopfreeCallstring (get_list): The list cannot be derived from Top or Bottom!" | ||
|
||
let loop_detected f = function | ||
(* note: a call string contains each Fundec at most once *) | ||
| `Left ele -> CilType.Fundec.equal f ele | ||
| `Right set -> FundecSet.mem f set | ||
|
||
let add_to_set old = function | ||
| `Left ele -> FundecSet.add ele old | ||
| `Right set -> FundecSet.join old set | ||
|
||
let rec callee_state f prev_set prev_list = function | ||
| [] -> (`Left f)::(List.rev prev_list) (* f is not yet contained in the call string *) | ||
| e::rem_list -> | ||
let new_set = add_to_set prev_set e in | ||
if loop_detected f e (* f is already present in the call string *) | ||
then (`Right new_set)::rem_list (* combine all elements of the call cycle in a set *) | ||
else callee_state f new_set (e::prev_list) rem_list | ||
|
||
let callee_state f ctx = `Lifted(callee_state f (FundecSet.empty ()) [] (get_list ctx.local)) | ||
|
||
let enter ctx r f args = [ctx.local, callee_state f ctx] | ||
|
||
let threadenter ctx ~multiple lval v args = [callee_state (Cilfacade.find_varinfo_fundec v) ctx] | ||
|
||
let combine_env ctx lval fexp f args fc au f_ask = ctx.local | ||
end | ||
|
||
let _ = MCP.register_analysis (module Spec : MCPSpec) |
This file contains 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 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 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 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 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 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.