From f6f295cc5353c8cc2f6523bcc62474ee24a3f385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Tue, 28 May 2024 20:16:49 +0200 Subject: [PATCH] [region] expr, term, init, instr --- src/plugins/region/access.ml | 32 ++++++++- src/plugins/region/access.mli | 10 ++- src/plugins/region/insert.ml | 122 ++++++++++++++++++++++++++++++++-- src/plugins/region/insert.mli | 8 +++ src/plugins/region/memory.ml | 12 +++- 5 files changed, 171 insertions(+), 13 deletions(-) diff --git a/src/plugins/region/access.ml b/src/plugins/region/access.ml index 10768c98f64..5baa3096b5d 100644 --- a/src/plugins/region/access.ml +++ b/src/plugins/region/access.ml @@ -24,19 +24,34 @@ open Cil_types open Cil_datatype type acs = + | Exp of Stmt.t * exp | Lval of Stmt.t * lval + | Init of Stmt.t * varinfo | Term of Property.t * term_lval let compare (a : acs) (b : acs) : int = match a, b with + | Init(sa,xa), Init(sb,xb) -> + let cmp = Stmt.compare sa sb in + if cmp <> 0 then cmp else Varinfo.compare xa xb + | Init _ , _ -> (-1) + | _ , Init _ -> (+1) + | Lval(sa,la), Lval(sb,lb) -> let cmp = Stmt.compare sa sb in if cmp <> 0 then cmp else Lval.compare la lb + | Lval _ , _ -> (-1) + | _ , Lval _ -> (+1) + + | Exp(sa,ea), Exp(sb,eb) -> + let cmp = Stmt.compare sa sb in + if cmp <> 0 then cmp else Exp.compare ea eb + | Exp _ , _ -> (-1) + | _ , Exp _ -> (+1) + | Term(sa,ta), Term(sb,tb) -> let cmp = Property.compare sa sb in if cmp <> 0 then cmp else Term_lval.compare ta tb - | Lval _ , Term _ -> (-1) - | Term _ , Lval _ -> (+1) let pstmt fmt (s : stmt) = match s.labels with @@ -46,10 +61,23 @@ let pstmt fmt (s : stmt) = Format.fprintf fmt "L%d" loc.pos_lnum let pretty fmt = function + | Init(s,x) -> + Format.fprintf fmt "%a@%a" Varinfo.pretty x pstmt s + | Exp(s,e) -> + Format.fprintf fmt "%a@%a" Exp.pretty e pstmt s | Lval(s,l) -> Format.fprintf fmt "%a@%a" Lval.pretty l pstmt s | Term(s,l) -> Format.fprintf fmt "%a@%s" Term_lval.pretty l (Property.Names.get_prop_name_id s) +let typeof = function + | Init(_,x) -> x.vtype + | Lval(_,lv) -> Cil.typeOfLval lv + | Exp(_,e) -> Cil.typeOf e + | Term(_,lt) -> + match Cil.typeOfTermLval lt with + | Ctype ty -> ty + | _ -> Cil.voidType + module Set = Set.Make(struct type t = acs let compare = compare end) diff --git a/src/plugins/region/access.mli b/src/plugins/region/access.mli index b36604e1bdf..cadb24bc098 100644 --- a/src/plugins/region/access.mli +++ b/src/plugins/region/access.mli @@ -20,11 +20,17 @@ (* *) (**************************************************************************) +open Cil_types + type acs = - | Lval of Cil_types.stmt * Cil_types.lval - | Term of Property.t * Cil_types.term_lval + | Exp of stmt * exp + | Lval of stmt * lval + | Init of stmt * varinfo + | Term of Property.t * term_lval val compare : acs -> acs -> int val pretty : Format.formatter -> acs -> unit +val typeof : acs -> typ + module Set : Set.S with type elt = acs diff --git a/src/plugins/region/insert.ml b/src/plugins/region/insert.ml index 0da88f88ec9..721feee97b2 100644 --- a/src/plugins/region/insert.ml +++ b/src/plugins/region/insert.ml @@ -23,20 +23,128 @@ open Cil_types open Memory -[@@@ warning "-a"] +let typeof_array_elt ty = + match Cil.unrollType ty with + | TArray(te,_,_) -> te + | _ -> Cil.voidType -let rec lval (m: map) (lv : lval) : node = +(* -------------------------------------------------------------------------- *) +(* --- L-Values & Expressions --- *) +(* -------------------------------------------------------------------------- *) + +let rec lval (m:map) (s:stmt) (lv:lval) : node = let h = fst lv in - offset m (host m h) (Cil.typeOfLhost h) (snd lv) + loffset m s (lhost m s h) (Cil.typeOfLhost h) (snd lv) -and host (m: map) = function +and lhost (m:map) (s:stmt) = function | Var x -> Memory.root m x - | Mem e -> assert false + | Mem e -> ptr m s e -and offset (m: map) (r: node) (ty: typ)= function +and loffset (m:map) (s:stmt) (r:node) (ty:typ)= function | NoOffset -> r | Field(fd,ofs) -> let size = Cil.bitsSizeOf ty in let offset, length = Cil.fieldBitsOffset fd in + let data = Memory.cell m () in + let rc = Memory.range m ~size ~offset ~length ~data in + ignore @@ Memory.merge m r rc ; loffset m s data fd.ftype ofs + | Index(_,ofs) -> + let size = Cil.bitsSizeOf ty in + let te = typeof_array_elt ty in + let data = Memory.cell m () in + let rc = Memory.range m ~size ~offset:0 ~length:size ~data in + ignore @@ Memory.merge m r rc ; loffset m s data te ofs + +and ptr m s e = + match exp m s e with None -> cell m () | Some r -> r + +and exp (m: map) (s:stmt) (e:exp) : node option = + match e.enode with + + | AddrOf lv | StartOf lv -> + let rv = lval m s lv in + Some rv + + | Lval lv -> + let rv = lval m s lv in + Memory.read m rv (Lval(s,lv)) ; + if Cil.isPointerType @@ Cil.typeOfLval lv then + let rp = cell m () in + Memory.points_to m rv rp ; + Some rp + else + None + + | UnOp(_,e,_) -> + ignore (exp m s e) ; None + + | BinOp((PlusPI|MinusPI),p,k,_) -> + ignore (exp m s k) ; + let r = ptr m s p in + Memory.shift m r (Exp(s,e)) ; + Some r + + | BinOp(_,a,b,_) -> + ignore (exp m s a) ; + ignore (exp m s b) ; + None + + | CastE(ty,p) -> + if Cil.isPointerType ty then + Some (ptr m s p) + else + (ignore (exp m s e) ; None) + + | Const _ + | SizeOf _ | SizeOfE _ | SizeOfStr _ + | AlignOf _ | AlignOfE _ + -> None + +(* -------------------------------------------------------------------------- *) +(* --- Initializers --- *) +(* -------------------------------------------------------------------------- *) + +let rec init (m:map) (s:stmt) (acs:Access.acs) (lv:lval) (iv:init) = + match iv with + + | SingleInit e -> + let r = lval m s lv in + Memory.write m r acs ; + Option.iter (Memory.points_to m r) (exp m s e) + + | CompoundInit(_,fvs) -> + List.iter + (fun (ofs,iv) -> + let lv = Cil.addOffsetLval ofs lv in + init m s acs lv iv + ) fvs + +(* -------------------------------------------------------------------------- *) +(* --- Instructions --- *) +(* -------------------------------------------------------------------------- *) + +let instr (m:map) (s:stmt) (instr:instr) = + match instr with + | Skip _ | Code_annot _ -> () + + | Set(lv,e,_) -> + let r = lval m s lv in + let v = exp m s e in + Memory.write m r (Lval(s,lv)) ; + Option.iter (Memory.points_to m r) v + + | Local_init(x,AssignInit iv,_) -> + let acs = Access.Init(s,x) in + init m s acs (Var x,NoOffset) iv + + | Call _ -> assert false - | Index(exp,ofs) -> assert false + + | Local_init(_,ConsInit _,_) -> + Options.warning ~source:(fst @@ Cil_datatype.Stmt.loc s) + "Constructor init not yet implemented" + | Asm _ -> + Options.warning ~source:(fst @@ Cil_datatype.Stmt.loc s) + "Inline assembly not supported (ignored)" + +(* -------------------------------------------------------------------------- *) diff --git a/src/plugins/region/insert.mli b/src/plugins/region/insert.mli index 664d5d2b3c7..9016f2094c9 100644 --- a/src/plugins/region/insert.mli +++ b/src/plugins/region/insert.mli @@ -19,3 +19,11 @@ (* for more details (enclosed in the file licenses/LGPLv2.1). *) (* *) (**************************************************************************) + +open Cil_types +open Memory + +val lval : map -> stmt -> lval -> node +val ptr : map -> stmt -> exp -> node +val exp : map -> stmt -> exp -> node option +val instr : map -> stmt -> instr -> unit diff --git a/src/plugins/region/memory.ml b/src/plugins/region/memory.ml index 5287fb031c7..98b06b38d6a 100644 --- a/src/plugins/region/memory.ml +++ b/src/plugins/region/memory.ml @@ -220,19 +220,27 @@ let merge (m: map) (a: node) (b: node) : node = (* --- Access --- *) (* -------------------------------------------------------------------------- *) +let access (m:map) (a:node) (ty: typ) = + let sr = sizeof (region m a).layout in + let size = Ranges.gcd sr (Cil.bitsSizeOf ty) in + if sr <> size then ignore (merge m a (cell m ~size ())) + let points_to (m: map) (a: node) (b: node) = ignore @@ merge m a @@ cell m ~ptr:b () let read (m: map) (a: node) from = let r = region m a in - Ufind.set m.store a { r with reads = Access.Set.add from r.reads } + Ufind.set m.store a { r with reads = Access.Set.add from r.reads } ; + access m a (Access.typeof from) let write (m: map) (a: node) from = let r = region m a in - Ufind.set m.store a { r with writes = Access.Set.add from r.writes } + Ufind.set m.store a { r with writes = Access.Set.add from r.writes } ; + access m a (Access.typeof from) let shift (m: map) (a: node) from = let r = region m a in Ufind.set m.store a { r with shifts = Access.Set.add from r.shifts } +(* no access *) (* -------------------------------------------------------------------------- *) -- GitLab