12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2023 *)(* 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->unit;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.tlocletpp_posppf(pos:Lexing.position)=tryletic=open_inpos.pos_fnameinletrecscaniclnumr=letline=input_lineicinletlen=String.lengthlineiniflen<rthenscanic(lnum+1)(r-len-1)elseFormat.fprintfppf"(line %d, column %d in %s)@ %S@ %s^"lnumrpos.pos_fnameline(String.make(r+1)' ')inscanic1pos.pos_cnumwithSys_error_|End_of_file->()let_=Printexc.register_printer(function|Inference_failure(e,pos)->Some(Format.asprintf"@[<v>Unable to infer the size of %a %a@]"Expr.ppepp_pospos)|Invalid_size((e,pos),size,expect)->Some(Format.asprintf"@[<v>Invalid size for %a (expected %d, got %d) %a@]"Expr.ppeexpectsizepp_pospos)|Invalid_operation(e,pos)->Some(Format.asprintf"@[<v>Invalid operation in %a %a@]"Expr.ppepp_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_varnamesizeenv=letvar=Dba.Var.createname~bitsize:(Size.Bit.createsize)~tag:Emptyinenv.definevar;Dba.LValue.vvarandeval_var?size((_,p)ast)name(annot:Ast.Size.t)env=letlval=tryenv.lookupnamewithNot_found->(matchannotwith|Explicitsize->declare_varnamesizeenv|Sizeoflval->letlval=eval_loclvalenvindeclare_varname(Dba.LValue.size_oflval)env|Evalexpr->letsize=eval_intexprenvinifsize<0thenraise(Invalid_operationexpr);declare_varnamesizeenv|Implicit->(matchsizewith|None->raise(Inference_failure(Expr.loct,p))|Somesize->declare_varnamesizeenv))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@]"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)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 *)