123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265(**************************************************************************)(* *)(* 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_datatypeopenServermoduleMd=Markdownletpackage=Package.package~plugin:"region"~title:"Region Analysis"()(* -------------------------------------------------------------------------- *)(* --- Server Data --- *)(* -------------------------------------------------------------------------- *)moduleNode:Data.Swithtypet=Memory.node=structtypet=Memory.nodeletjtype=Data.declare~package~name:"node"(Jindex"node")letto_jsonn=Json.of_int@@Memory.idnletof_jsonjs=Memory.forge@@Json.intjsendmoduleNodeOpt=Data.Joption(Node)moduleNodeList=Data.Jlist(Node)moduleRange:Data.Swithtypet=Memory.range=structtypet=Memory.rangeletjtype=Data.declare~package~name:"range"@@Jrecord["label",Jstring;"offset",Jnumber;"length",Jnumber;"cells",Jnumber;"data",Node.jtype;]letto_json(rg:Memory.range)=Json.of_fields["label",Json.of_stringrg.label;"offset",Json.of_intrg.offset;"length",Json.of_intrg.length;"cells",Json.of_intrg.cells;"data",Node.to_jsonrg.data;]letof_json_=failwith"Region.Range.of_json"endmoduleRanges=Data.Jlist(Range)moduleRegion:Data.Swithtypet=Memory.region=structtypet=Memory.regionletroots_to_jsonvs=letopenCil_typesinJson.of_list@@List.map(funv->Json.of_stringv.vname)vsletlabels_to_jsonls=Json.of_list@@List.mapJson.of_stringlsletikind_to_char(ikind:Cil_types.ikind)=matchikindwith|IBool|IUChar->'b'|IChar|ISChar->'c'|IInt->'i'|IUInt->'u'|IShort->'s'|IUShort->'r'|ILong|ILongLong->'l'|IULong|IULongLong->'w'letfkind_to_char(fkind:Cil_types.fkind)=matchfkindwith|FFloat->'f'|FDouble|FLongDouble->'d'lettyp_to_char(ty:Cil_types.typ)=matchtywith|TVoid_->'b'|TPtr_->'p'|TInt(ik,_)->ikind_to_charik|TFloat(fk,_)->fkind_to_charfk|TComp({cstruct},_)->ifcstructthen'S'else'U'|TArray_->'A'|TNamed_->'T'|TEnum_->'E'|TFun_->'F'|TBuiltin_va_list_->'x'lettyps_to_char(typs:Cil_types.typlist)=matchtypswith|[]->'-'|[ty]->typ_to_charty|_->'x'letlabel(m:Memory.region)=letbuffer=Buffer.create4inifm.reads<>[]thenBuffer.add_charbuffer'R';ifm.writes<>[]thenBuffer.add_charbuffer'W';ifm.pointed<>NonethenBuffer.add_charbuffer'*'elseifm.reads<>[]||m.writes<>[]thenbeginBuffer.add_charbuffer'(';Buffer.add_charbuffer@@typs_to_charm.types;Buffer.add_charbuffer')';end;Buffer.contentsbufferletpp_typ_layouts0fmtty=lets=Cil.bitsSizeOftyinifs<>s0thenFormat.fprintffmt"(%a)%%%db"Typ.prettytyselseTyp.prettyfmttylettitle(m:Memory.region)=Format.asprintf"%t (%db)"beginfunfmt->matchm.typeswith|[]->Format.pp_print_stringfmt"Compound"|[ty]->pp_typ_layoutm.sizeoffmtty;|ty::ts->pp_typ_layout0fmtty;List.iter(Format.fprintffmt", %a"(pp_typ_layout0))ts;endm.sizeofletjtype=Data.declare~package~name:"region"@@Jrecord["node",Node.jtype;"roots",JarrayJalpha;"labels",JarrayJalpha;"parents",NodeList.jtype;"sizeof",Jnumber;"ranges",Ranges.jtype;"pointed",NodeOpt.jtype;"reads",Jboolean;"writes",Jboolean;"bytes",Jboolean;"label",Jstring;"title",Jstring;]letto_json(m:Memory.region)=Json.of_fields["node",Node.to_jsonm.node;"roots",roots_to_jsonm.roots;"labels",labels_to_jsonm.labels;"parents",NodeList.to_jsonm.parents;"sizeof",Json.of_int@@m.sizeof;"ranges",Ranges.to_json@@m.ranges;"pointed",NodeOpt.to_json@@m.pointed;"reads",Json.of_bool(m.reads<>[]);"writes",Json.of_bool(m.writes<>[]);"bytes",Json.of_bool(List.lengthm.types>1);"label",Json.of_string@@labelm;"title",Json.of_string@@titlem;]letof_json_=failwith"Region.Layout.of_json"endmoduleRegions=Data.Jlist(Region)(* -------------------------------------------------------------------------- *)(* --- Server API --- *)(* -------------------------------------------------------------------------- *)letmap_of_localizable?(atStmt=false)(loc:Printer_tag.localizable)=letopenPrinter_taginmatchkf_of_localizablelocwith|None->raiseNot_found|Somekf->letdomain=Analysis.findkfinifatStmtthenmatchki_of_localizablelocwith|Kglobal->domain.map|Kstmts->Stmt.Map.findsdomain.bodyelsedomain.mapletregion_of_localizable(m:Memory.map)(loc:Printer_tag.localizable)=trymatchlocwith|PExp(_,_,e)->Memory.expme|PLval(_,_,lv)->Some(Memory.lvalmlv)|PVDecl(_,_,x)->Some(Memory.lvalm(Varx,NoOffset))|PStmt_|PStmtStart_|PTermLval_|PGlobal_|PIP_|PType_->NonewithNot_found->Noneletmap_of_declaration(decl:Printer_tag.declaration)=matchdeclwith|SFunctionkf->(Analysis.findkf).map|_->raiseNot_foundletsignal=Request.signal~package~name:"updated"~descr:(Md.plain"Region Analysis Updated")let()=Analysis.add_hook(fun()->Request.emitsignal)let()=Request.register~package~kind:`EXEC~name:"compute"~descr:(Md.plain"Compute regions for the given declaration")~input:(moduleKernel_ast.Decl)~output:(moduleData.Junit)(functionSFunctionkf->Analysis.computekf|_->())let()=Request.register~package~kind:`GET~name:"regions"~descr:(Md.plain"Returns computed regions for the given declaration")~input:(moduleKernel_ast.Decl)~output:(moduleRegions)~signals:[signal]beginfundecl->tryMemory.regions@@map_of_declarationdeclwithNot_found->[]endlet()=Request.register~package~kind:`GET~name:"regionsAt"~descr:(Md.plain"Compute regions at the given marker program point")~input:(moduleKernel_ast.Marker)~output:(moduleRegions)~signals:[signal]beginfunloc->tryMemory.regions@@map_of_localizable~atStmt:truelocwithNot_found->[]endlet()=Request.register~package~kind:`GET~name:"localize"~descr:(Md.plain"Localize the marker in its map")~input:(moduleKernel_ast.Marker)~output:(moduleNodeOpt)~signals:[signal]beginfunloc->tryletmap=map_of_localizablelocinregion_of_localizablemaplocwithNot_found->Noneend(* -------------------------------------------------------------------------- *)