You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
6.8 KiB
204 lines
6.8 KiB
7 years ago
|
(*
|
||
6 years ago
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||
7 years ago
|
*
|
||
|
* This source code is licensed under the MIT license found in the
|
||
|
* LICENSE file in the root directory of this source tree.
|
||
|
*)
|
||
7 years ago
|
|
||
5 years ago
|
(** LLAIR (Low-Level Analysis Internal Representation) is an IR tailored for
|
||
|
static analysis using a low-level model of memory. *)
|
||
7 years ago
|
|
||
|
(** Instructions for memory manipulation or other non-control effects. *)
|
||
|
type inst = private
|
||
5 years ago
|
| Move of {reg_exps: (Reg.t * Exp.t) vector; loc: Loc.t}
|
||
5 years ago
|
(** Move each value [exp] into corresponding register [reg]. All of
|
||
|
the moves take effect simultaneously. *)
|
||
5 years ago
|
| Load of {reg: Reg.t; ptr: Exp.t; len: Exp.t; loc: Loc.t}
|
||
6 years ago
|
(** Read a [len]-byte value from the contents of memory at address
|
||
|
[ptr] into [reg]. *)
|
||
|
| Store of {ptr: Exp.t; exp: Exp.t; len: Exp.t; loc: Loc.t}
|
||
|
(** Write [len]-byte value [exp] into memory at address [ptr]. *)
|
||
6 years ago
|
| Memset of {dst: Exp.t; byt: Exp.t; len: Exp.t; loc: Loc.t}
|
||
|
(** Store byte [byt] into [len] memory addresses starting from [dst]. *)
|
||
7 years ago
|
| Memcpy of {dst: Exp.t; src: Exp.t; len: Exp.t; loc: Loc.t}
|
||
|
(** Copy [len] bytes starting from address [src] to [dst], undefined
|
||
|
if ranges overlap. *)
|
||
|
| Memmov of {dst: Exp.t; src: Exp.t; len: Exp.t; loc: Loc.t}
|
||
|
(** Copy [len] bytes starting from address [src] to [dst]. *)
|
||
5 years ago
|
| Alloc of {reg: Reg.t; num: Exp.t; len: Exp.t; loc: Loc.t}
|
||
7 years ago
|
(** Allocate a block of memory large enough to store [num] elements of
|
||
6 years ago
|
[len] bytes each and bind [reg] to the first address. *)
|
||
6 years ago
|
| Free of {ptr: Exp.t; loc: Loc.t}
|
||
|
(** Deallocate the previously allocated block at address [ptr]. *)
|
||
5 years ago
|
| Nondet of {reg: Reg.t option; msg: string; loc: Loc.t}
|
||
6 years ago
|
(** Bind [reg] to an arbitrary value, representing non-deterministic
|
||
|
approximation of behavior described by [msg]. *)
|
||
6 years ago
|
| Abort of {loc: Loc.t} (** Trigger abnormal program termination *)
|
||
7 years ago
|
|
||
|
(** A (straight-line) command is a sequence of instructions. *)
|
||
|
type cmnd = inst vector
|
||
|
|
||
|
(** A label is a name of a block. *)
|
||
|
type label = string
|
||
|
|
||
5 years ago
|
(** A jump to a block. *)
|
||
|
type jump = {mutable dst: block; mutable retreating: bool}
|
||
|
|
||
|
(** A call to a function. *)
|
||
|
and 'a call =
|
||
|
{ callee: 'a
|
||
|
; typ: Typ.t (** Type of the callee. *)
|
||
5 years ago
|
; actuals: Exp.t list (** Stack of arguments, first-arg-last. *)
|
||
5 years ago
|
; areturn: Reg.t option (** Register to receive return value. *)
|
||
5 years ago
|
; return: jump (** Return destination. *)
|
||
|
; throw: jump option (** Handler destination. *)
|
||
|
; mutable recursive: bool
|
||
|
(** Holds unless [callee] is definitely not recursive. *)
|
||
|
; loc: Loc.t }
|
||
7 years ago
|
|
||
|
(** Block terminators for function call/return or other control transfers. *)
|
||
|
and term = private
|
||
6 years ago
|
| Switch of {key: Exp.t; tbl: (Exp.t * jump) vector; els: jump; loc: Loc.t}
|
||
|
(** Invoke the [jump] in [tbl] associated with the integer expression
|
||
|
[case] which is equal to [key], if any, otherwise invoke [els]. *)
|
||
6 years ago
|
| Iswitch of {ptr: Exp.t; tbl: jump vector; loc: Loc.t}
|
||
7 years ago
|
(** Invoke the [jump] in [tbl] whose [dst] is equal to [ptr]. *)
|
||
5 years ago
|
| Call of Exp.t call
|
||
|
(** Call function with arguments. A [global] for non-virtual call. *)
|
||
7 years ago
|
| Return of {exp: Exp.t option; loc: Loc.t}
|
||
|
(** Invoke [return] of the dynamically most recent [Call]. *)
|
||
|
| Throw of {exc: Exp.t; loc: Loc.t}
|
||
|
(** Invoke [throw] of the dynamically most recent [Call] with [throw]
|
||
|
not [None]. *)
|
||
|
| Unreachable
|
||
|
(** Halt as control is assumed to never reach [Unreachable]. *)
|
||
|
|
||
|
(** A block is a destination of a jump with arguments, contains code. *)
|
||
|
and block = private
|
||
|
{ lbl: label
|
||
|
; cmnd: cmnd
|
||
|
; term: term
|
||
|
; mutable parent: func
|
||
|
; mutable sort_index: int
|
||
|
(** Position in a topological order, ignoring [retreating] edges. *)
|
||
|
}
|
||
|
|
||
|
(** A function is a control-flow graph with distinguished entry block, whose
|
||
6 years ago
|
parameters are the function parameters. *)
|
||
6 years ago
|
and func = private
|
||
|
{ name: Global.t
|
||
5 years ago
|
; formals: Reg.t list (** Formal parameters, first-param-last stack *)
|
||
5 years ago
|
; freturn: Reg.t option
|
||
|
; fthrow: Reg.t
|
||
|
; locals: Reg.Set.t (** Local registers *)
|
||
5 years ago
|
; entry: block }
|
||
7 years ago
|
|
||
6 years ago
|
type functions
|
||
|
|
||
7 years ago
|
type t = private
|
||
6 years ago
|
{ globals: Global.t vector (** Global variable definitions. *)
|
||
6 years ago
|
; functions: functions (** (Global) function definitions. *) }
|
||
7 years ago
|
|
||
6 years ago
|
val pp : t pp
|
||
7 years ago
|
|
||
6 years ago
|
include Invariant.S with type t := t
|
||
|
|
||
|
val mk : globals:Global.t list -> functions:func list -> t
|
||
7 years ago
|
|
||
|
module Inst : sig
|
||
|
type t = inst
|
||
|
|
||
6 years ago
|
val pp : t pp
|
||
5 years ago
|
val move : reg_exps:(Reg.t * Exp.t) vector -> loc:Loc.t -> inst
|
||
|
val load : reg:Reg.t -> ptr:Exp.t -> len:Exp.t -> loc:Loc.t -> inst
|
||
6 years ago
|
val store : ptr:Exp.t -> exp:Exp.t -> len:Exp.t -> loc:Loc.t -> inst
|
||
6 years ago
|
val memset : dst:Exp.t -> byt:Exp.t -> len:Exp.t -> loc:Loc.t -> inst
|
||
6 years ago
|
val memcpy : dst:Exp.t -> src:Exp.t -> len:Exp.t -> loc:Loc.t -> inst
|
||
|
val memmov : dst:Exp.t -> src:Exp.t -> len:Exp.t -> loc:Loc.t -> inst
|
||
5 years ago
|
val alloc : reg:Reg.t -> num:Exp.t -> len:Exp.t -> loc:Loc.t -> inst
|
||
6 years ago
|
val free : ptr:Exp.t -> loc:Loc.t -> inst
|
||
5 years ago
|
val nondet : reg:Reg.t option -> msg:string -> loc:Loc.t -> inst
|
||
6 years ago
|
val abort : loc:Loc.t -> inst
|
||
6 years ago
|
val loc : inst -> Loc.t
|
||
5 years ago
|
val locals : inst -> Reg.Set.t
|
||
5 years ago
|
val fold_exps : inst -> init:'a -> f:('a -> Exp.t -> 'a) -> 'a
|
||
7 years ago
|
end
|
||
|
|
||
|
module Jump : sig
|
||
6 years ago
|
type t = jump [@@deriving compare, equal, sexp_of]
|
||
7 years ago
|
|
||
6 years ago
|
val pp : jump pp
|
||
5 years ago
|
val mk : string -> jump
|
||
7 years ago
|
end
|
||
|
|
||
|
module Term : sig
|
||
|
type t = term
|
||
|
|
||
6 years ago
|
val pp : t pp
|
||
|
|
||
6 years ago
|
val goto : dst:jump -> loc:Loc.t -> term
|
||
|
(** Construct a [Switch] representing an unconditional branch. *)
|
||
|
|
||
6 years ago
|
val branch : key:Exp.t -> nzero:jump -> zero:jump -> loc:Loc.t -> term
|
||
|
(** Construct a [Switch] representing a conditional branch. *)
|
||
|
|
||
6 years ago
|
val switch :
|
||
6 years ago
|
key:Exp.t -> tbl:(Exp.t * jump) vector -> els:jump -> loc:Loc.t -> term
|
||
7 years ago
|
|
||
6 years ago
|
val iswitch : ptr:Exp.t -> tbl:jump vector -> loc:Loc.t -> term
|
||
7 years ago
|
|
||
6 years ago
|
val call :
|
||
5 years ago
|
callee:Exp.t
|
||
6 years ago
|
-> typ:Typ.t
|
||
5 years ago
|
-> actuals:Exp.t list
|
||
5 years ago
|
-> areturn:Reg.t option
|
||
6 years ago
|
-> return:jump
|
||
|
-> throw:jump option
|
||
|
-> loc:Loc.t
|
||
|
-> term
|
||
7 years ago
|
|
||
6 years ago
|
val return : exp:Exp.t option -> loc:Loc.t -> term
|
||
|
val throw : exc:Exp.t -> loc:Loc.t -> term
|
||
|
val unreachable : term
|
||
6 years ago
|
val loc : term -> Loc.t
|
||
7 years ago
|
end
|
||
|
|
||
|
module Block : sig
|
||
6 years ago
|
type t = block [@@deriving compare, equal, sexp_of]
|
||
7 years ago
|
|
||
6 years ago
|
include Comparator.S with type t := t
|
||
7 years ago
|
|
||
6 years ago
|
val pp : t pp
|
||
5 years ago
|
val mk : lbl:label -> cmnd:cmnd -> term:term -> block
|
||
7 years ago
|
end
|
||
|
|
||
|
module Func : sig
|
||
|
type t = func
|
||
|
|
||
6 years ago
|
val pp : t pp
|
||
7 years ago
|
|
||
6 years ago
|
include Invariant.S with type t := t
|
||
7 years ago
|
|
||
5 years ago
|
val mk :
|
||
|
name:Global.t
|
||
5 years ago
|
-> formals:Reg.t list
|
||
5 years ago
|
-> freturn:Reg.t option
|
||
|
-> fthrow:Reg.t
|
||
5 years ago
|
-> entry:block
|
||
|
-> cfg:block vector
|
||
|
-> func
|
||
|
|
||
5 years ago
|
val mk_undefined :
|
||
|
name:Global.t
|
||
5 years ago
|
-> formals:Reg.t list
|
||
5 years ago
|
-> freturn:Reg.t option
|
||
|
-> fthrow:Reg.t
|
||
5 years ago
|
-> t
|
||
6 years ago
|
|
||
5 years ago
|
val find : functions -> string -> func option
|
||
7 years ago
|
(** Look up a function of the given name in the given functions. *)
|
||
|
|
||
|
val is_undefined : func -> bool
|
||
|
(** Holds of functions that are declared but not defined. *)
|
||
|
end
|