123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2024 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)openCil_typesopenCil_datatypeopenMemory(* -------------------------------------------------------------------------- *)(* --- L-Values & Expressions --- *)(* -------------------------------------------------------------------------- *)typescalar={from:nodeoption;ptr:nodeoption}letintegral={from=None;ptr=None}letpointermv=matchv.ptrwith|Somep->v,p|None->letp=new_chunkm()inOption.iter(funs->Memory.add_points_tomsp)v.from;{vwithptr=Somep},pletrecadd_lval(m:map)(s:stmt)(lv:lval):node=leth=fstlvinadd_loffsetms(add_lhostmsh)(Cil.typeOfLhosth)(sndlv)andadd_lhost(m:map)(s:stmt)=function|Varx->Memory.add_rootmx|Meme->snd@@pointerm@@add_expmseandadd_loffset(m:map)(s:stmt)(r:node)(ty:typ)=function|NoOffset->r|Field(fd,ofs)->add_loffsetms(add_fieldmrfd)fd.ftypeofs|Index(_,ofs)->letelt,size=Cil.typeOf_array_elem_sizetyinletn=Z.to_int@@Option.getsizeinadd_loffsetms(add_indexmreltn)eltofsandadd_valuemse=ignore(add_expmse)andadd_exp(m:map)(s:stmt)(e:exp):scalar=matche.enodewith|AddrOflv|StartOflv->letrv=Some(add_lvalmslv)in{from=rv;ptr=rv}|Lvallv->letrv=add_lvalmslvinMemory.readmrv(Lval(s,lv));letptr=Memory.add_valuemrv@@Cil.typeOfLvallvin{from=Somerv;ptr}|BinOp((PlusPI|MinusPI),p,k,_)->add_valuemsk;letv=add_expmspinOption.iter(funr->Memory.shiftmr(Exp(s,e)))v.from;v|UnOp(_,e,_)->add_valuemse;integral|BinOp(_,a,b,_)->add_valuemsa;add_valuemsb;integral|CastE(ty,p)->letv=add_expmspinifCil.isPointerTypetythenfst@@pointerm@@velseintegral|Const_|SizeOf_|SizeOfE_|SizeOfStr_|AlignOf_|AlignOfE_->integral(* -------------------------------------------------------------------------- *)(* --- Initializers --- *)(* -------------------------------------------------------------------------- *)letrecadd_init(m:map)(s:stmt)(acs:Access.acs)(lv:lval)(iv:init)=matchivwith|SingleInite->letr=add_lvalmslvinMemory.writemracs;Option.iter(Memory.add_points_tomr)(add_expmse).ptr|CompoundInit(_,fvs)->List.iter(fun(ofs,iv)->letlv=Cil.addOffsetLvalofslvinadd_initmsacslviv)fvs(* -------------------------------------------------------------------------- *)(* --- Instructions --- *)(* -------------------------------------------------------------------------- *)letadd_instr(m:map)(s:stmt)(instr:instr)=matchinstrwith|Skip_|Code_annot_->()|Set(lv,{enode=Lvalexp},_)->letl=add_lvalmslvinletr=add_lvalmsexpinMemory.readmr(Lval(s,exp));Memory.writeml(Lval(s,lv));Memory.merge_copym~l~r|Set(lv,e,_)->letr=add_lvalmslvinletv=add_expmseinMemory.writemr(Lval(s,lv));Option.iter(Memory.add_points_tomr)v.ptr|Local_init(x,AssignInitiv,_)->letacs=Access.Init(s,x)inadd_initmsacs(Varx,NoOffset)iv|Call(lr,e,es,_)->add_valuemse;List.iter(add_valuems)es;Option.iter(funlv->letr=add_lvalmslvinMemory.writemr(Lval(s,lv)))lr;Options.warning~source:(fst@@Stmt.locs)"Incomplete call analysis"|Local_init(_,ConsInit_,_)->Options.warning~source:(fst@@Stmt.locs)"Constructor init not yet implemented"|Asm_->Options.warning~source:(fst@@Stmt.locs)"Inline assembly not supported (ignored)"(* -------------------------------------------------------------------------- *)(* --- Statements --- *)(* -------------------------------------------------------------------------- *)typermap=Memory.mapStmt.Map.trefletstorermapms=rmap:=Stmt.Map.adds(Memory.copy~locked:truem)!rmapletrecadd_stmt(r:rmap)(m:map)(s:stmt)=letannots=Annotations.code_annotsinifannots<>[]thenOptions.warning~source:(fst@@Stmt.locs)"Annotations not analyzed";matchs.skindwith|Instrki->add_instrmski;storerms|Return(Somee,_)->add_valuemse;storerms|Goto_|Break_|Continue_|Return(None,_)->storerms|If(e,st,se,_)->add_valuemse;storerms;add_blockrmst;add_blockrmse;|Switch(e,b,_,_)->add_valuemse;storerms;add_blockrmb;|Blockb|Loop(_,b,_,_,_)->add_blockrmb|UnspecifiedSequences->add_blockrm@@Cil.block_from_unspecified_sequences|Throw(exn,_)->Option.iter(fun(e,_)->add_valuemse)exn|TryCatch(b,hs,_)->add_blockrmb;List.iter(fun(c,b)->add_catchrmc;add_blockrmb)hs;|TryExcept(a,(ks,e),b,_)->add_blockrma;List.iter(add_instrms)ks;add_valuemse;add_blockrmb;|TryFinally(a,b,_)->add_blockrma;add_blockrmb;andadd_catch(r:rmap)(m:map)(c:catch_binder)=matchcwith|Catch_all->()|Catch_exn(_,xbs)->List.iter(fun(_,b)->add_blockrmb)xbsandadd_block(r:rmap)(m:map)(b:block)=List.iter(add_stmtrm)b.bstmts(* -------------------------------------------------------------------------- *)(* --- Behavior --- *)(* -------------------------------------------------------------------------- *)typeimap=Memory.mapProperty.Map.trefletistoreimapmip=imap:=Property.Map.addip(Memory.copy~locked:truem)!imapletadd_bhv~kf(s:imap)(m:map)(bhv:behavior)=List.iter(fune->letrs=Annot.of_extensioneinifrs<>[]thenbeginList.iter(Logic.add_regionm)rs;letip=Property.ip_of_extended(ELContractkf)einistoresmip;end)bhv.b_extended(* -------------------------------------------------------------------------- *)(* --- Function --- *)(* -------------------------------------------------------------------------- *)typedomain={map:map;body:mapStmt.Map.t;spec:mapProperty.Map.t;}letdomain?globalkf=letm=matchglobalwithSomeg->g|None->Memory.create()inletr=refStmt.Map.emptyinlets=refProperty.Map.emptyinbegintryletfunspec=Annotations.funspeckfinList.iter(add_bhv~kfsm)funspec.spec_behavior;withAnnotations.No_funspec_->()end;begintryletfundec=Kernel_function.get_definitionkfinadd_blockrmfundec.sbody;withKernel_function.No_Definition->()end;{map=Memory.copy~locked:truem;body=!r;spec=!s;}(* -------------------------------------------------------------------------- *)