1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-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). *)(* *)(**************************************************************************)openLibparsermoduleS=Basic_types.Stringtypeenv={wordsize:int;endianness:Machine.endianness;define:Dba.Var.t->Lexing.position->unit;origin:string->Lexing.positionoption;lookup:string->Dba.LValue.t;lookup_symbol:string->Dba.Var.Tag.attribute->Dba.Expr.t;}type'aloc='aAst.locmoduleSymbol=Ast.SymbolmoduleLoc=Ast.LocmoduleExpr=Ast.ExprmoduleInstr=Ast.InstrexceptionInference_failureofExpr.tlocexceptionInvalid_sizeofExpr.tloc*int*intexceptionInvalid_operationofExpr.tlocexceptionInvalid_annotationof(Loc.tloc*int*Lexing.positionoption)let_=Printexc.register_printer(function|Inference_failure(e,pos)->Some(Format.asprintf"@[<v>Unable to infer the size of %a %a@]"Expr.ppeParse_utils.pp_pospos)|Invalid_size((e,pos),size,expect)->Some(Format.asprintf"@[<v>Invalid size for %a (expected %d, got %d) %a@]"Expr.ppeexpectsizeParse_utils.pp_pospos)|Invalid_operation(e,pos)->Some(Format.asprintf"@[<v>Invalid operation in %a %a@]"Expr.ppeParse_utils.pp_pospos)|Invalid_annotation((var,pos),_,Somepos')->Some(Format.asprintf"@[<v>Conflicting size annotation in %a %a@ Previous definition \
%a@]"Loc.ppvarParse_utils.pp_posposParse_utils.pp_pospos')|Invalid_annotation((var,pos),size,None)->Some(Format.asprintf"@[<v>Invalid size annotation in %a (expected <%d>) %a@]"Loc.ppvarsizeParse_utils.pp_pospos)|_->None)letreceval_expr?size((e,p)ast:Expr.tloc)env=lete=matchewith|Intz->(matchsizewith|None->raise(Inference_failuret)|Somesize->(ifZ.numbitsz>sizethenletline=p.pos_lnumandcolumn=p.pos_cnum-p.pos_bol-1inOptions.Logger.warning"integer %a (line %d, column %d) does not fit in a bitvector \
of %d bit%s"Z.pp_printzlinecolumnsize(ifsize>1then"s"else""));Dba.Expr.constant(Bitvector.createzsize))|Bvbv->Dba.Expr.constantbv|Symbol((name,attr),_)->env.lookup_symbolnameattr|Loc(Sub({hi;lo},loc),_)->Dba.Expr.restrictlohi(Dba.LValue.to_expr(eval_loc?size:Nonelocenv))|Locloc->Dba.LValue.to_expr(eval_loc?sizelocenv)|Unary(op,x)->letsize=matchopwithRestrict_|Uext_|Sext_->None|_->sizeinDba.Expr.unaryop(eval_expr?sizexenv)|Binary(op,x,y)->letx,y=eval_binary?size~opxyenvinDba.Expr.binaryopxy|Ite(q,x,y)->letq=eval_expr~size:1qenvinletx,y=eval_binary?sizexyenvinDba.Expr.iteqxyinOption.iter(funsize->letsize'=Dba.Expr.size_ofeinifsize'<>sizethenraise(Invalid_size(t,size',size)))size;eandeval_binary?(first=true)?size?opxyenv=matcheval_expr?size:(matchopwith|None->size|Some(Plus|Minus|Mult|DivU|DivS|ModU|ModS|Or|And|Xor|LShift|RShiftU|RShiftS|LeftRotate|RightRotate)->size|Some_->None)xenvwith|x->(x,eval_expr?size:(matchopwith|SomeConcat->(matchsizewith|None->None|Somesize->Some(size-Dba.Expr.size_ofx))|None|Some_->Some(Dba.Expr.size_ofx))yenv)|exceptionInference_failure_whenfirst->lety,x=eval_binary~first:false?size?opyxenvin(x,y)andeval_int((e,_)ast:Expr.tloc)env=matchewith|Intz->ifnot(Z.fits_intz)thenraise(Invalid_operationt);Z.to_intz|Bvbv->ifnot(Z.fits_int(Bitvector.signed_ofbv))thenraise(Invalid_operationt);Bitvector.to_intbv|Symbol((name,attr),_)->(matchenv.lookup_symbolnameattrwith|Var{info=Symbol(_,(lazybv));_}->ifnot(Z.fits_int(Bitvector.value_ofbv))thenraise(Invalid_operationt);Bitvector.to_uintbv|_->raise(Invalid_operationt))|Unary(UMinus,x)->-eval_intxenv|Binary(Plus,x,y)->eval_intxenv+eval_intyenv|Binary(Minus,x,y)->eval_intxenv-eval_intyenv|Binary(Mult,x,y)->eval_intxenv*eval_intyenv|Binary(DivS,x,y)->eval_intxenv/eval_intyenv|Loc_|Unary_|Binary_|Ite_->raise(Invalid_operationt)anddeclare_varnamesizeposenv=letvar=Dba.Var.createname~bitsize:(Size.Bit.createsize)~tag:Emptyinenv.definevarpos;Dba.LValue.vvarandeval_var?size((_,p)ast)name(annot:Ast.Size.t)env=letlval=matchenv.lookupnamewith|lval->letsize'=matchannotwith|Explicitsize->size|Sizeoflval->letlval=eval_loclvalenvinDba.LValue.size_oflval|Evalexpr->letsize=eval_intexprenvinifsize<0thenraise(Invalid_operationexpr);size|Implicit->Dba.LValue.size_oflvalandsize=Dba.LValue.size_oflvalinifsize<>size'thenraise(Invalid_annotation(t,size,env.originname));lval|exceptionNot_found->(matchannotwith|Explicitsize->declare_varnamesizepenv|Sizeoflval->letlval=eval_loclvalenvindeclare_varname(Dba.LValue.size_oflval)penv|Evalexpr->letsize=eval_intexprenvinifsize<0thenraise(Invalid_operationexpr);declare_varnamesizepenv|Implicit->(matchsizewith|None->raise(Inference_failure(Expr.loct,p))|Somesize->declare_varnamesizepenv))inOption.iter(funsize->letsize'=Dba.LValue.size_oflvalinifsize'<>sizethenraise(Invalid_size((Expr.loct,p),size',size)))size;lvalandeval_loc?size((l,p)ast:Loc.tloc)env=letlval=matchlwith|Var(name,annot)->eval_var?sizetnameannotenv|Load(len,endianness,addr,array)->letendianness=Option.fold~none:env.endianness~some:Fun.idendiannessinletaddr=eval_expr~size:env.wordsizeaddrenvinDba.LValue.store(Size.Byte.createlen)endiannessaddr?array|Sub({hi;lo},((Var(name,annot),_)ast'))->(matcheval_var?sizet'nameannotenvwith|Varvar->Dba.LValue.restrictvarlohi|Restrict(var,{hi=hi';lo=lo'})->ifhi'>hi+lo'thenraise(Inference_failure(Expr.loct,p));Dba.LValue.restrictvar(lo+lo')(hi+lo')|_->raise(Invalid_operation(Expr.loct,p)))|Sub_->raise(Invalid_operation(Expr.loct,p))inOption.iter(funsize->letsize'=Dba.LValue.size_oflvalinifsize'<>sizethenraise(Invalid_size((Expr.loct,p),size',size)))size;lvalmoduleOutput=structtypeformat=Types.Output.format=Bin|Dec|Hex|Asciitypet=|Model|Formula|Sliceof(Expr.tloc*string)list|Valueofformat*Expr.tloc|Streamofstring|Stringofstringletevalenv(t:t):Types.Output.t=matchtwith|Model->Model|Formula->Formula|Slicevalues->Slice(List.map(fun(e,name)->(eval_expreenv,name))values)|Value(fmt,e)->Value(fmt,eval_expreenv)|Streamname->Streamname|Stringname->Stringnameletformat_str=function|Bin->"bin"|Dec->"dec"|Hex->"hexa"|Ascii->"ascii"letppppf=function|Model->Format.pp_print_stringppf"model"|Formula->Format.pp_print_stringppf"formula"|Slicedefs->Format.fprintfppf"formula for %a"(Format.pp_print_list~pp_sep:(funppf()->Format.pp_print_stringppf", ")(funppf((expr,_),name)->Format.fprintfppf"%a as %s"Expr.ppexprname))defs|Value(fmt,(e,_))->Format.fprintfppf"%s %a"(format_strfmt)Expr.ppe|Streamname->Format.fprintfppf"ascii stream %s"name|Stringname->Format.fprintfppf"c string %s"nameendtypeAst.Obj.t+=|Intofint|Int_listofintlist|FormatofOutput.format|OutputofOutput.t|Output_listofOutput.tlist|String_listofstringlist|Key_valof(string*string)|Key_val_listof(string*string)list|Symbol_listofSymbol.tloclist|Loc_optofLoc.tlocoption|Loc_opt_listofLoc.tlocoptionlist|Expr_optofExpr.tlocoption|Expr_listofExpr.tloclist|Namedof(Expr.tloc*string)|Named_listof(Expr.tloc*string)listtypeAst.Instr.t+=|ArgumentofLoc.tloc*int(** [lval] := arg([i]) *)|ReturnofExpr.tlocoption(** return [rval] *)|CutofExpr.tlocoption|PrintofOutput.t|Reachofint*Expr.tlocoption*Output.tlist|Enumerateofint*Expr.tloctypeAst.t+=|Starting_fromofExpr.tloc*Instr.tlist|Starting_from_coreofInstr.tlist|Load_sectionsofstringlist|Load_dataofLoc.tloc|Concretize_stack_pointer|Import_symbolsofSymbol.tloclist*string|HookofExpr.tloclist*Instr.tlist*bool|DecodeofBinstream.t*Instr.tlist|InitofInstr.tlist|Explore_allletpp_comma_listpp=Format.pp_print_list~pp_sep:(funppf()->Format.pp_print_stringppf", ")ppletpp_exprs=pp_comma_list(funppf(e,_)->Expr.ppppfe)letpp_outputs=Format.pp_print_list~pp_sep:(funppf()->Format.pp_print_stringppf" and ")(funppfoutput->Format.fprintfppf"print %a"Output.ppoutput)let()=Ast.Instr.register_pp(funppfinst->matchinstwith|Argument((lval,_),n)->Format.fprintfppf"%a := arg(%d)"Loc.pplvaln;true|ReturnNone->Format.pp_print_stringppf"return";true|Return(Some(rval,_))->Format.fprintfppf"return %a"Expr.pprval;true|Cutguard->Format.fprintfppf"cut %a"(funppfguard->Option.iter(fun(test,_)->Format.fprintfppf" if %a"Expr.pptest)guard)guard;true|Printoutput->Format.fprintfppf"print %a"Output.ppoutput;true|Enumerate(n,(rval,_))->Format.fprintfppf"enumerate%s %a%a"(ifn=max_intthen"*"else"")Expr.pprval(funppfn->ifn<>1&&n<>max_intthenFormat.fprintfppf" (%d)"n)n;true|Reach(n,guard,outputs)->Format.fprintfppf"reach%s%a%a%a"(ifn<0then"*"else"")(funppfn->if1<nthenFormat.fprintfppf" %d times"n)n(funppfguard->Option.iter(fun(test,_)->Format.fprintfppf" such that %a"Expr.pptest)guard)guard(funppfoutputs->ifoutputs<>[]thenFormat.fprintfppf" then %a"pp_outputsoutputs)outputs;true|_->false)letpp_stmts=Format.pp_print_list~pp_sep:Format.pp_print_spaceInstr.ppletpp_with_stmtsppfstmts=matchstmtswith|[]->Format.pp_close_boxppf()|stmts->Format.fprintfppf" with@ %a@]@ end"pp_stmtsstmtsletdecl_printers=ref[]letregister_pppp=decl_printers:=pp::!decl_printersletrecresolve_ppppfdecl=function|[]->Format.pp_print_stringppf"unknown"|pp::printers->ifnot(ppppfdecl)thenresolve_ppppfdeclprintersletpp_options=Format.pp_print_list~pp_sep:(funppf()->Format.pp_print_charppf',')(funppf(k,v)->Format.fprintfppf"%S"k;ifv<>""thenFormat.fprintfppf"=%S"v)letppppfdecl=matchdeclwith|Starting_from((addr,_),stmts)->Format.fprintfppf"@[<v>@[<v 2>starting from %a%a@]"Expr.ppaddrpp_with_stmtsstmts|Starting_from_corestmts->Format.fprintfppf"@[<v>@[<v 2>starting from core%a@]"pp_with_stmtsstmts|Load_sections[name]->Format.fprintfppf"load section %s from file"name|Load_sectionsnames->Format.fprintfppf"load sections %a from file"(Format.pp_print_list~pp_sep:(funppf()->Format.pp_print_stringppf", ")Format.pp_print_string)names|Load_data(store,_)->Format.fprintfppf"%a from file"Loc.ppstore|Concretize_stack_pointer->Format.pp_print_stringppf"with concrete stack pointer"|Import_symbols(symbols,file)->Format.fprintfppf"import %a from %s"(pp_comma_list(funppf(sym,_)->Symbol.ppppfsym))symbolsfile|Hook(addr,stmts,_)->Format.fprintfppf"@[<v>@[<v 2>hook %a by@ %a@]@ end@]"pp_exprsaddrpp_stmtsstmts|Decode(opcode,stmts)->Format.fprintfppf"@[<v>@[<v 2>hook opcode %a by@ %a@]@ end@]"Binstream.ppopcodepp_stmtsstmts|Initstmts->Format.fprintfppf"@[<v>%a@]"pp_stmtsstmts|Explore_all->Format.pp_print_stringppf"explore all"|_->resolve_ppppfdecl!decl_printerslet_pp_globalppfglobal_data=Format.fprintfppf"@[<v>%a@]"(funppfmap->S.Map.iter(funnamevalues->Format.fprintfppf"@[<h>%s: %a@]@ "name(funppfset->S.Set.iter(funvalue->Format.fprintfppf"%s@ "value)set)values)map)global_dataletgrammar:(unit,Libparser.obj,unit,unit,Libparser.objDyp.dyplexbuf)Dyp.dyp_actionlist=[Dyp.Bind_to_cons[("byte","Obj");("byte_rev_list","Obj");("key_value","Obj");("comma_separated_key_value_rev_list","Obj");("options","Obj");("format","Obj");("named","Obj");("comma_separated_named_rev_list","Obj");("output","Obj");("and_separated_output_rev_list","Obj");("outputs","Obj");("times","Obj");("such_that","Obj");("guard","Obj");("num","Obj");("qident","String");("section","String");("comma_separated_section_rev_list","Obj");("comma_separated_symbol_rev_list","Obj");("arg","Obj");("comma_separated_arg_rev_list","Obj");("arguments","Stmt");("expr_opt","Obj");("comma_separated_expr_rev_list","Obj");("with_stmts_end","Stmt");("directive","Stmt");("decl","Decl");("rev_program","Program");("program","Program");];Dyp.Add_rules[(("byte",[Dyp.Regexp(Dyp.RE_Seq[Dyp.RE_Name"hexdigit";Dyp.RE_Name"hexdigit"]);],"default_priority",[]),fun_->function|[Syntax.Lexeme_matchedbyte]->(Syntax.Obj(Int(Z.to_int(Z.of_string_base16byte))),[])|_->assertfalse);(("byte_rev_list",[],"default_priority",[]),fun__->(Syntax.Obj(Int_list[]),[]));(("byte_rev_list",[Dyp.Non_ter("byte_rev_list",No_priority);Dyp.Non_ter("byte",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(Int_listbytes);Syntax.Obj(Intbyte)]->(Syntax.Obj(Int_list(byte::bytes)),[])|_->assertfalse);(("key_value",[Dyp.Non_ter("qident",No_priority)],"default_priority",[]),fun_->function|[Syntax.Stringkey]->(Syntax.Obj(Key_val(key,"")),[])|_->assertfalse);(("key_value",[Dyp.Non_ter("qident",No_priority);Dyp.Regexp(RE_Char'=');Dyp.Non_ter("qident",No_priority);],"default_priority",[]),fun_->function|[Syntax.Stringkey;_;Syntax.Stringvalue]->(Syntax.Obj(Key_val(key,value)),[])|_->assertfalse);(("comma_separated_key_value_rev_list",[Dyp.Non_ter("key_value",No_priority)],"default_priority",[]),fun_->function|[Syntax.Obj(Key_valpair)]->(Syntax.Obj(Key_val_list[pair]),[])|_->assertfalse);(("comma_separated_key_value_rev_list",[Dyp.Non_ter("comma_separated_key_value_rev_list",No_priority);Dyp.Regexp(RE_Char',');Dyp.Non_ter("key_value",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(Key_val_listl);_;Syntax.Obj(Key_valpair)]->(Syntax.Obj(Key_val_list(pair::l)),[])|_->assertfalse);(("options",[],"default_priority",[]),fun__->(Syntax.Obj(Key_val_list[]),[]));(("options",[Dyp.Regexp(RE_Char'[');Dyp.Non_ter("comma_separated_key_value_rev_list",No_priority);Dyp.Regexp(RE_Char']');],"default_priority",[]),fun_->function|[_;Syntax.Obj(Key_val_listl);_]->(Syntax.Obj(Key_val_list(List.revl)),[])|_->assertfalse);(("num",[],"default_priority",[]),fun__->(Syntax.Obj(Int1),[]));(("num",[Dyp.Regexp(RE_Char'(');Dyp.Ter"INT";Dyp.Regexp(RE_Char')');],"default_priority",[]),fun_->function|[_;Syntax.Obj_INTn;_]->(Syntax.Obj(Int(Z.to_intn)),[])|_->assertfalse);(("times",[],"default_priority",[]),fun__->(Syntax.Obj(Int1),[]));(("times",[Dyp.Ter"INT";Dyp.Regexp(RE_String"times")],"default_priority",[]),fun_->function|[Syntax.Obj_INTn;_]->(Syntax.Obj(Int(Z.to_intn)),[])|_->assertfalse);(("format",[],"default_priority",[]),fun__->(Syntax.Obj(FormatOutput.Hex),[]));(("format",[Dyp.Regexp(RE_String"ascii")],"default_priority",[]),fun_->function_->(Syntax.Obj(FormatOutput.Ascii),[]));(("format",[Dyp.Regexp(RE_String"hexa")],"default_priority",[]),fun_->function_->(Syntax.Obj(FormatOutput.Hex),[]));(("format",[Dyp.Regexp(RE_String"bin")],"default_priority",[]),fun_->function_->(Syntax.Obj(FormatOutput.Bin),[]));(("format",[Dyp.Regexp(RE_String"dec")],"default_priority",[]),fun_->function_->(Syntax.Obj(FormatOutput.Dec),[]));(("named",[Dyp.Non_ter("var",No_priority)],"default_priority",[]),fun_->function|[Syntax.Loc((Loc.Var(name,_),pos)asvar)]->(Syntax.Obj(Named((Expr.locvar,pos),name)),[])|_->assertfalse);(("named",[Dyp.Non_ter("expr",No_priority);Dyp.Regexp(RE_String"as");Dyp.Non_ter("ident",No_priority);],"default_priority",[]),fun_->function|[Syntax.Exprexpr;_;Syntax.Stringalias]->(Syntax.Obj(Named(expr,alias)),[])|_->assertfalse);(("comma_separated_named_rev_list",[Dyp.Non_ter("named",No_priority)],"default_priority",[]),fun_->function|[Syntax.Obj(Namedterm)]->(Syntax.Obj(Named_list[term]),[])|_->assertfalse);(("comma_separated_named_rev_list",[Dyp.Non_ter("comma_separated_named_rev_list",No_priority);Dyp.Regexp(RE_Char',');Dyp.Non_ter("named",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(Named_listl);_;Syntax.Obj(Namedterm)]->(Syntax.Obj(Named_list(term::l)),[])|_->assertfalse);(("output",[Dyp.Regexp(RE_String"print");Dyp.Regexp(RE_String"formula")],"default_priority",[]),fun_->function_->(Syntax.Obj(OutputOutput.Formula),[]));(("output",[Dyp.Regexp(RE_String"print");Dyp.Regexp(RE_String"formula");Dyp.Regexp(RE_String"for");Dyp.Non_ter("comma_separated_named_rev_list",No_priority);],"default_priority",[]),fun_->function|[_;_;_;Syntax.Obj(Named_listterms)]->(Syntax.Obj(Output(Output.Slice(List.revterms))),[])|_->assertfalse);(("output",[Dyp.Regexp(RE_String"print");Dyp.Regexp(RE_String"model")],"default_priority",[]),fun__->(Syntax.Obj(OutputOutput.Model),[]));(("output",[Dyp.Regexp(RE_String"print");Dyp.Non_ter("format",No_priority);Dyp.Non_ter("expr",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Obj(Formatformat);Syntax.Exprterm]->(Syntax.Obj(Output(Output.Value(format,term))),[])|_->assertfalse);(("output",[Dyp.Regexp(RE_String"print");Dyp.Regexp(RE_String"ascii");Dyp.Regexp(RE_String"stream");Dyp.Non_ter("ident",No_priority);],"default_priority",[]),fun_->function|[_;_;_;Syntax.Stringname]->(Syntax.Obj(Output(Output.Streamname)),[])|_->assertfalse);(("output",[Dyp.Regexp(RE_String"print");Dyp.Regexp(RE_String"c");Dyp.Regexp(RE_String"string");Dyp.Non_ter("ident",No_priority);],"default_priority",[]),fun_->function|[_;_;_;Syntax.Stringname]->(Syntax.Obj(Output(Output.Stringname)),[])|_->assertfalse);(("and_separated_output_rev_list",[Dyp.Non_ter("output",No_priority)],"default_priority",[]),fun_->function|[Syntax.Obj(Outputoutput)]->(Syntax.Obj(Output_list[output]),[])|_->assertfalse);(("and_separated_output_rev_list",[Dyp.Non_ter("and_separated_output_rev_list",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Regexp(RE_String"and");Dyp.Non_ter("output",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(Output_listl);_;_;Syntax.Obj(Outputoutput)]->(Syntax.Obj(Output_list(output::l)),[])|_->assertfalse);(("outputs",[],"default_priority",[]),fun_->function_->(Syntax.Obj(Output_list[]),[]));(("outputs",[Dyp.Regexp(RE_String"then");Dyp.Non_ter("and_separated_output_rev_list",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Obj(Output_listl)]->(Syntax.Obj(Output_list(List.revl)),[])|_->assertfalse);(("qident",[Dyp.Non_ter("ident",No_priority)],"default_priority",[]),fun_->function|[Syntax.Stringid]->(Syntax.Stringid,[])|_->assertfalse);(("qident",[Dyp.Ter"CONST"],"default_priority",[]),fun_->function|[Syntax.Obj_CONSTbv]->(Syntax.String(Bitvector.to_asciistringbv),[])|_->assertfalse);(("section",[Dyp.Non_ter("qident",No_priority)],"default_priority",[]),fun_->function|[Syntax.Stringid]->(Syntax.Stringid,[])|_->assertfalse);(("section",[Dyp.Non_ter("label",No_priority)],"default_priority",[]),fun_->function|[Syntax.Stringid]->(Syntax.String("."^id),[])|_->assertfalse);(("comma_separated_section_rev_list",[Dyp.Non_ter("section",No_priority)],"default_priority",[]),fun_->function|[Syntax.Stringsection]->(Syntax.Obj(String_list[section]),[])|_->assertfalse);(("comma_separated_section_rev_list",[Dyp.Non_ter("comma_separated_section_rev_list",No_priority);Dyp.Regexp(RE_Char',');Dyp.Non_ter("section",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(String_listl);_;Syntax.Stringsection]->(Syntax.Obj(String_list(section::l)),[])|_->assertfalse);(("comma_separated_symbol_rev_list",[Dyp.Non_ter("symbol",No_priority)],"default_priority",[]),fun_->function|[Syntax.Symbolsym]->(Syntax.Obj(Symbol_list[sym]),[])|_->assertfalse);(("comma_separated_symbol_rev_list",[Dyp.Non_ter("comma_separated_symbol_rev_list",No_priority);Dyp.Regexp(RE_Char',');Dyp.Non_ter("symbol",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(Symbol_listl);_;Syntax.Symbolsym]->(Syntax.Obj(Symbol_list(sym::l)),[])|_->assertfalse);(("arg",[Dyp.Non_ter("var",No_priority)],"default_priority",[]),fun_->function|[Syntax.Locvar]->(Syntax.Obj(Loc_opt(Somevar)),[])|_->assertfalse);(("arg",[Dyp.Regexp(RE_Char'_')],"default_priority",[]),fun__->(Syntax.Obj(Loc_optNone),[]));(("comma_separated_arg_rev_list",[Dyp.Non_ter("arg",No_priority)],"default_priority",[]),fun_->function|[Syntax.Obj(Loc_optarg)]->(Syntax.Obj(Loc_opt_list[arg]),[])|_->assertfalse);(("comma_separated_arg_rev_list",[Dyp.Non_ter("comma_separated_arg_rev_list",No_priority);Dyp.Regexp(RE_Char',');Dyp.Non_ter("arg",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(Loc_opt_listl);_;Syntax.Obj(Loc_optarg)]->(Syntax.Obj(Loc_opt_list(arg::l)),[])|_->assertfalse);(("arguments",[],"default_priority",[]),fun__->(Syntax.Stmt[],[]));(("arguments",[Dyp.Regexp(RE_Char'(');Dyp.Regexp(RE_Char')')],"default_priority",[]),fun__->(Syntax.Stmt[],[]));(("arguments",[Dyp.Regexp(RE_Char'(');Dyp.Non_ter("comma_separated_arg_rev_list",No_priority);Dyp.Regexp(RE_Char')');],"default_priority",[]),fun_->function|[_;Syntax.Obj(Loc_opt_listargs);_]->(Syntax.Stmt(List.mapi(funiarg->Option.fold~none:Instr.Nop~some:(funname->Argument(name,i))arg)(List.revargs)),[])|_->assertfalse);(("expr_opt",[],"default_priority",[]),fun__->(Syntax.Obj(Expr_optNone),[]));(("expr_opt",[Dyp.Non_ter("expr",No_priority)],"default_priority",[]),fun_->function|[Syntax.Exprexpr]->(Syntax.Obj(Expr_opt(Someexpr)),[])|_->assertfalse);(("control",[Dyp.Regexp(RE_String"return");Dyp.Non_ter("expr_opt",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Obj(Expr_optexpr)]->(Syntax.Stmt[Returnexpr],[])|_->assertfalse);(("comma_separated_expr_rev_list",[Dyp.Non_ter("expr",No_priority)],"default_priority",[]),fun_->function|[Syntax.Exprexpr]->(Syntax.Obj(Expr_list[expr]),[])|_->assertfalse);(("comma_separated_expr_rev_list",[Dyp.Non_ter("comma_separated_expr_rev_list",No_priority);Dyp.Regexp(RE_Char',');Dyp.Non_ter("expr",No_priority);],"default_priority",[]),fun_->function|[Syntax.Obj(Expr_listl);_;Syntax.Exprexpr]->(Syntax.Obj(Expr_list(expr::l)),[])|_->assertfalse);(("with_stmts_end",[],"default_priority",[]),fun__->(Syntax.Stmt[],[]));(("with_stmts_end",[Dyp.Regexp(RE_String"with");Dyp.Non_ter("stmts",No_priority);Dyp.Regexp(RE_String"end");],"default_priority",[]),fun_->function|[_;Syntax.Stmtstmts;_]->(Syntax.Stmtstmts,[])|_->assertfalse);(("such_that",[],"default_priority",[]),fun__->(Syntax.Obj(Expr_optNone),[]));(("such_that",[Dyp.Regexp(RE_String"such");Dyp.Regexp(RE_String"that");Dyp.Non_ter("expr",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Exprguard]->(Syntax.Obj(Expr_opt(Someguard)),[])|_->assertfalse);(("guard",[],"default_priority",[]),fun__->(Syntax.Obj(Expr_optNone),[]));(("guard",[Dyp.Regexp(RE_String"if");Dyp.Non_ter("expr",No_priority)],"default_priority",[]),fun_->function|[_;Syntax.Exprguard]->(Syntax.Obj(Expr_opt(Someguard)),[])|_->assertfalse);(("directive",[Dyp.Regexp(RE_String"enumerate");Dyp.Non_ter("expr",No_priority);Dyp.Non_ter("num",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Exprexpr;Syntax.Obj(Intn)]->(Syntax.Stmt[Enumerate(n,expr)],[])|_->assertfalse);(("directive",[Dyp.Regexp(RE_String"enumerate");Dyp.Regexp(RE_Char'*');Dyp.Non_ter("expr",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Exprexpr]->(Syntax.Stmt[Enumerate(max_int,expr)],[])|_->assertfalse);(("directive",[Dyp.Regexp(RE_String"assume");Dyp.Non_ter("expr",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Exprexpr]->(Syntax.Stmt[Instr.Assumeexpr],[])|_->assertfalse);(("directive",[Dyp.Regexp(RE_String"assert");Dyp.Non_ter("expr",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Exprexpr]->(Syntax.Stmt[Instr.Assertexpr],[])|_->assertfalse);(("fallthrough",[Dyp.Non_ter("output",No_priority)],"default_priority",[]),fun_->function|[Syntax.Obj(Outputoutput)]->(Syntax.Instr(Printoutput),[])|_->assertfalse);(("fallthrough",[Dyp.Regexp(RE_String"enumerate");Dyp.Non_ter("expr",No_priority);Dyp.Non_ter("num",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Exprexpr;Syntax.Obj(Intn)]->(Syntax.Instr(Enumerate(n,expr)),[])|_->assertfalse);(("fallthrough",[Dyp.Regexp(RE_String"reach");Dyp.Non_ter("times",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("such_that",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("outputs",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Obj(Intn);_;Syntax.Obj(Expr_optguard);_;Syntax.Obj(Output_listoutputs);]->(Syntax.Instr(Reach(n,guard,outputs)),[])|_->assertfalse);(("fallthrough",[Dyp.Regexp(RE_String"cut");Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("guard",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Obj(Expr_optguard)]->(Syntax.Instr(Cutguard),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"starting");Dyp.Regexp(RE_String"from");Dyp.Non_ter("expr",No_priority);Dyp.Non_ter("with_stmts_end",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Expraddr;Syntax.Stmtstmts]->(Syntax.Decl(Starting_from(addr,stmts)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"starting");Dyp.Regexp(RE_String"from");Dyp.Regexp(RE_String"core");Dyp.Non_ter("with_stmts_end",No_priority);],"default_priority",[]),fun_->function|[_;_;_;Syntax.Stmtstmts]->(Syntax.Decl(Starting_from_corestmts),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"load");Dyp.Regexp(RE_String"section");Dyp.Non_ter("section",No_priority);Dyp.Regexp(RE_String"from");Dyp.Regexp(RE_String"file");],"default_priority",[]),fun_->function|[_;_;Syntax.Stringsection;_;_]->(Syntax.Decl(Load_sections[section]),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"load");Dyp.Regexp(RE_String"sections");Dyp.Non_ter("comma_separated_section_rev_list",No_priority);Dyp.Regexp(RE_String"from");Dyp.Regexp(RE_String"file");],"default_priority",[]),fun_->function|[_;_;Syntax.Obj(String_listsections);_;_]->(Syntax.Decl(Load_sectionssections),[])|_->assertfalse);(("decl",[Dyp.Non_ter("load",No_priority);Dyp.Regexp(RE_String"from");Dyp.Regexp(RE_String"file");],"default_priority",[]),fun_->function|[Syntax.Locload;_;_]->(Syntax.Decl(Load_dataload),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"import");Dyp.Non_ter("comma_separated_symbol_rev_list",No_priority);Dyp.Regexp(RE_String"from");Dyp.Non_ter("qident",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Obj(Symbol_listsyms);_;Syntax.Stringfile]->(Syntax.Decl(Import_symbols(syms,file)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"concretize");Dyp.Regexp(RE_String"stack");],"default_priority",[]),fun__->Options.Logger.warning"\"concretize stack\" is deprecated, use \"with concrete stack \
pointer\" instead";(Syntax.DeclConcretize_stack_pointer,[]));(("decl",[Dyp.Regexp(RE_String"with");Dyp.Regexp(RE_String"concrete");Dyp.Regexp(RE_String"stack");Dyp.Regexp(RE_String"pointer");],"default_priority",[]),fun__->(Syntax.DeclConcretize_stack_pointer,[]));(("decl",[Dyp.Regexp(RE_String"replace");Dyp.Regexp(RE_String"opcode");Dyp.Non_ter("byte_rev_list",No_priority);Dyp.Regexp(RE_String"by");Dyp.Non_ter("stmts",No_priority);Dyp.Regexp(RE_String"end");],"default_priority",[]),fun_->function|[_;_;Syntax.Obj(Int_listbytes);_;Syntax.Stmtstmts;_]->(Syntax.Decl(Decode(Binstream.of_list(List.revbytes),stmts)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"hook");Dyp.Non_ter("comma_separated_expr_rev_list",No_priority);Dyp.Non_ter("arguments",No_priority);Dyp.Regexp(RE_String"with");Dyp.Non_ter("stmts",No_priority);Dyp.Regexp(RE_String"end");],"default_priority",[]),fun_->function|[_;Syntax.Obj(Expr_listaddr);Syntax.Stmtargs;_;Syntax.Stmtstmts;_;]->(Syntax.Decl(Hook(addr,List.rev_appendargsstmts,true)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"replace");Dyp.Non_ter("comma_separated_expr_rev_list",No_priority);Dyp.Non_ter("arguments",No_priority);Dyp.Regexp(RE_String"by");Dyp.Non_ter("stmts",No_priority);Dyp.Regexp(RE_String"end");],"default_priority",[]),fun_->function|[_;Syntax.Obj(Expr_listaddr);Syntax.Stmtargs;_;Syntax.Stmtstmts;_;]->(Syntax.Decl(Hook(addr,List.rev_appendargsstmts,false)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"abort");Dyp.Regexp(RE_String"at");Dyp.Non_ter("comma_separated_expr_rev_list",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Obj(Expr_listaddr)]->(Syntax.Decl(Hook(addr,[Instr.dynamic_assert(Expr.zero,Lexing.dummy_pos);Instr.halt;],false)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"halt");Dyp.Regexp(RE_String"at");Dyp.Non_ter("comma_separated_expr_rev_list",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Obj(Expr_listaddr)]->(Syntax.Decl(Hook(addr,[Instr.halt],false)),[])|_->assertfalse);(("decl",[Dyp.Non_ter("instr",No_priority)],"default_priority",[]),fun_->function|[Syntax.Stmtinstr]->(Syntax.Decl(Initinstr),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"reach");Dyp.Regexp(RE_String"all")],"default_priority",[]),fun__->Options.Logger.warning"\"reach all\" is deprecated, use \"explore all\" instead";(Syntax.DeclExplore_all,[]));(("decl",[Dyp.Regexp(RE_String"explore");Dyp.Regexp(RE_String"all")],"default_priority",[]),fun__->(Syntax.DeclExplore_all,[]));(("decl",[Dyp.Regexp(RE_String"reach");Dyp.Non_ter("expr",No_priority);Dyp.Non_ter("arguments",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("times",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("such_that",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("outputs",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Expraddr;Syntax.Stmtargs;_;Syntax.Obj(Intn);_;Syntax.Obj(Expr_optguard);_;Syntax.Obj(Output_listoutputs);]->(Syntax.Decl(Hook([addr],List.rev_appendargs[Reach(n,guard,outputs)],true)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"reach");Dyp.Regexp(RE_Char'*');Dyp.Non_ter("expr",No_priority);Dyp.Non_ter("arguments",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("such_that",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("outputs",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Expraddr;Syntax.Stmtargs;_;Syntax.Obj(Expr_optguard);_;Syntax.Obj(Output_listoutputs);]->(Syntax.Decl(Hook([addr],List.rev_appendargs[Reach(-1,guard,outputs)],true)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"cut");Dyp.Regexp(RE_String"at");Dyp.Non_ter("expr",No_priority);Dyp.Non_ter("arguments",No_priority);Dyp.Non_ter("accept_newline",No_priority);Dyp.Non_ter("guard",No_priority);],"default_priority",[]),fun_->function|[_;_;Syntax.Expraddr;Syntax.Stmtargs;_;Syntax.Obj(Expr_optguard);]->(Syntax.Decl(Hook([addr],List.rev_appendargs[Cutguard],true)),[])|_->assertfalse);(("decl",[Dyp.Regexp(RE_String"at");Dyp.Non_ter("expr",No_priority);Dyp.Non_ter("arguments",No_priority);Dyp.Non_ter("directive",No_priority);],"default_priority",[]),fun_->function|[_;Syntax.Expraddr;Syntax.Stmtargs;Syntax.Stmtstmts]->(Syntax.Decl(Hook([addr],List.rev_appendargsstmts,true)),[])|_->assertfalse);(("rev_program",[],"default_priority",[]),fun__->(Syntax.Program[],[]));(("rev_program",[Dyp.Non_ter("rev_program",No_priority);Dyp.Non_ter("decl",No_priority);Dyp.Non_ter("separator",No_priority);],"default_priority",[]),fun_->function|[Syntax.Programrev_program;Syntax.Decldecl;_]->(Syntax.Program(decl::rev_program),[Dyp.Keep_grammar])|_->assertfalse);(("program",[Dyp.Non_ter("rev_program",No_priority);Dyp.RegexpRE_Eof_char],"default_priority",[]),fun_->function|[Syntax.Programrev_program;_]->(Syntax.Program(List.revrev_program),[])|_->assertfalse);];]lettry_and_parsegrammar_extensionslexbuf=letpilot=Dyp.update_pp(Syntax.pp())(List.concat(grammar::grammar_extensions))inmatchDyp.lexparsepilot"program"lexbufwith|[(Syntax.Programast,_)]->ast|exceptionFailure_->lets=Format.asprintf"@[<v>Probable lexing error %a@]"Parse_utils.pp_pos(Dyp.lexeme_end_plexbuf)inraise(Parse_utils.UserFriendlyParseErrors)|_|(exceptionDyp.Syntax_error)->lets=Format.asprintf"@[<v>Parse error at word `%s' %a@]"(Dyp.lexemelexbuf)Parse_utils.pp_pos(Dyp.lexeme_end_plexbuf)inraise(Parse_utils.UserFriendlyParseErrors)typefile_stream=Openedofin_channel*stringlist|Pendingofstringlistletrecrefill_buflexbuffile_streambuflen=match!file_streamwith|Pending[]->0|Pending(filename::files)->(matchopen_infilenamewith|exceptionSys_error_->Options.Logger.fatal"Cannot open file %s"filename|ic->file_stream:=Opened(ic,files);Dyp.set_fname(Option.get!lexbuf)filename;letstd_lexbuf=Dyp.std_lexbuf(Option.get!lexbuf)inLexing.set_positionstd_lexbuf{pos_fname=filename;pos_lnum=0;pos_bol=0;pos_cnum=0};refill_buflexbuffile_streambuflen)|Opened(ic,files)->(matchinputicbuf0lenwith|0->close_inic;file_stream:=Pendingfiles;Bytes.setbuf0'\n';1|n->n)letread_filesgramma_extensionsfiles=letfile_stream=ref(Pendingfiles)andlexbuf=refNoneinlexbuf:=Some(Dyp.from_function(Libparser.Syntax.pp())(refill_buflexbuffile_stream));Fun.protect~finally:(fun()->match!file_streamwithOpened(ic,_)->close_inic|_->())(fun()->try_and_parsegramma_extensions(Option.get!lexbuf))(* include Cli.Make (struct *)(* let shortname = "ast" *)(* let name = "AST" *)(* end) *)(* module Parse = Builder.String_option (struct *)(* let name = "parse" *)(* let doc = "Parse AST node" *)(* end) *)(* let run () = *)(* Option.iter *)(* (fun node -> *)(* let lexbuf = Dyp.from_string (Syntax.pp ()) node in *)(* Logger.result "@[<v>%a@]" *)(* (Format.pp_print_list ~pp_sep:Format.pp_print_space pp) *)(* (try_and_parse lexbuf)) *)(* (Parse.get_opt ()) *)(* let _ = Cli.Boot.enlist ~name:"AST" ~f:run *)