Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file codex_logger.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218(**************************************************************************)(* This file is part of the Codex semantics library. *)(* *)(* Copyright (C) 2013-2025 *)(* 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 LICENSE). *)(* *)(**************************************************************************)letcurrent_instr_addr:Virtual_address.tref=ref(Virtual_address.create0)moduleAlarm_record:sigtypetvalempty:tvalcheck:string->t->tvalalarm:string->t->tvalpretty:unique:bool->Format.formatter->t->unitvalpretty_html:unique:bool->Format.formatter->t->unitvalnew_phase:string->t->tvaltotal_alarms:ignore:(stringlist)->?ignore_phase:(stringlist)->unique:bool->t->intend=structmoduleAddrSet=Virtual_address.SetmoduleSMap=Basic_types.String.MapmoduleSTbl=Basic_types.String.Htbl(* Per-alarm address set *)typecounter=(AddrSet.t*AddrSet.t)SMap.t(* Per-phase counter. *)typet={counts:counterSMap.t;cur_phase:string}letempty={counts=SMap.empty;cur_phase="_none_"}letcheckalarm_namex=letcounts=x.counts|>SMap.updatex.cur_phase(function|Somec->Some(c|>SMap.updatealarm_name(function|None->SomeAddrSet.(singleton!current_instr_addr,empty)|Some(checks,alarms)->SomeVirtual_address.Set.(add!current_instr_addrchecks,alarms)))|None->Some(SMap.singletonalarm_nameAddrSet.(singleton!current_instr_addr,empty)))in{xwithcounts}letalarmalarm_namex=letcounts=x.counts|>SMap.updatex.cur_phase(function|Somec->Some(c|>SMap.updatealarm_name(function|None->SomeAddrSet.(empty,singleton!current_instr_addr)|Some(checks,alarms)->SomeVirtual_address.Set.(checks,add!current_instr_addralarms)))|None->Some(SMap.singletonalarm_nameAddrSet.(singleton!current_instr_addr,empty)))in{xwithcounts}letnew_phasepx={xwithcur_phase=p}letmerge_countersc1c2=SMap.merge(funalarm_namev1v2->matchv1,v2with|None,None->assertfalse|Some(c,a),None|None,Some(c,a)->Some(c,a)|Some(c1,a1),Some(c2,a2)->SomeAddrSet.(unionc1c2,uniona1a2))c1c2lettotal_alarms~ignore?(ignore_phase=[])~uniquex=ifuniquethenletmerged=SMap.fold(funphasecounteracc->ifList.memphaseignore_phasethenaccelsemerge_countersacccounter)x.countsSMap.emptyinSMap.fold(funalarm_name(_checks,alarms)acc->ifList.memalarm_nameignorethenaccelseacc+AddrSet.cardinalalarms)merged0elseSMap.fold(funphasecounteracc->ifList.memphaseignore_phasethenaccelseSMap.fold(funalarm_name(_checks,alarms)acc->ifList.memalarm_nameignorethenaccelseacc+AddrSet.cardinalalarms)counteracc)x.counts0letpretty~uniquefmtx=letopenFormatinx.counts|>SMap.iter(funphasecounter->fprintffmt"@[<v>@.== %s ==@.@]"phase;counter|>SMap.iter(funalarm_name(checks,alarms)->ifVirtual_address.Set.cardinalalarms>0thenfprintffmt"@[<v>-alarm count-,%s,%d,%d,[@[<hov 2>%a@]]@.@]"alarm_name(AddrSet.cardinalchecks)(AddrSet.cardinalalarms)Format.(pp_print_listVirtual_address.pp~pp_sep:pp_print_space)(AddrSet.elementsalarms);));fprintffmt"\n\n-total alarm count-,%d\n"@@total_alarms~ignore:[]~uniquexletpretty_html~uniquefmtx=letopenFormatinx.counts|>SMap.iter(funphasecounter->fprintffmt"Phase: %s"phase;counter|>SMap.iter(funalarm_name(checks,alarms)->ifVirtual_address.Set.cardinalalarms>0thenfprintffmt"<div style=\"padding: 3px; padding-left: 10px\">%s, %d, %d, %a</div>\n"alarm_name(AddrSet.cardinalchecks)(AddrSet.cardinalalarms)Format.(pp_print_listVirtual_address.pp~pp_sep:pp_print_space)(AddrSet.elementsalarms);));fprintffmt"</br>-total alarm count-,%d"@@total_alarms~ignore:[]~uniquexendmoduletypeBINSEC_LOGGER_S=sigincludeLogger.Svalcheck:string->unit(** Emit a check notification, i.e. inform the log reader that an alarm may
follow. *)valalarm:_Operator.Alarm.t->unit(** Emit an alarm, i.e. a notification that the code could not be proved
conform to the specification. *)valalarm_record:unit->Alarm_record.tvalswitch_to_phase:string->unitendmoduleBinsec_logger:BINSEC_LOGGER_S=structincludeCodex_options.Loggerletrecord=refAlarm_record.emptyletwarning?levelfmt=warning?level("[%a]@ "^^fmt)Virtual_address.pp!current_instr_addrleterrorfmt=error("[%a]@ "^^fmt)Virtual_address.pp!current_instr_addrletfatal?efmt=fatal?e("[%a]@ "^^fmt)Virtual_address.pp!current_instr_addrletresultfmt=result("[%a]@ "^^fmt)Virtual_address.pp!current_instr_addrletcheckalarm_name=result"@[<hov 2>-check- %s@]"alarm_name;record:=Alarm_record.checkalarm_name!recordletalarmalarm_name=letalarm_name=Operator.Alarm.showalarm_nameinerror"@[<hov 2>-alarm- %s@]"alarm_name;record:=Alarm_record.alarmalarm_name!recordlet()=Emit_alarm.register_alarm_hook{hook=(funalarm_name_stack_loc->alarmalarm_name)}letalarm_record()=!recordletswitch_to_phasephase=record:=Alarm_record.new_phasephase!recordendmoduleQuiet:BINSEC_LOGGER_S=structletrecord=refAlarm_record.emptyincludeCodex_options.Loggerletlogwithx=Format.ikfprintf(fun_fmt->())Format.err_formatterxletwarning?level:_=logwithleterror=Binsec_logger.errorletresult=logwithletcheckalarm_name=result"@[<hov 2>-check- %s@]"alarm_name;record:=Alarm_record.checkalarm_name!recordletalarmalarm_name=letalarm_name=Operator.Alarm.showalarm_nameinerror"@[<hov 2>-alarm- %s@]"alarm_name;record:=Alarm_record.alarmalarm_name!recordletalarm_record()=!recordletswitch_to_phasephase=record:=Alarm_record.new_phasephase!recordendmoduleCodex_logger:Codex.Codex_log.S=structincludeBinsec_logger(* include Quiet *)letwarningfmt=warningfmtletperformance_warningfmt=resultfmtletimprecision_warningfmt=resultfmtletdebug?level?category:_fmt=debugfmtletfatalfmt=Format.kasprintf(funx->failwithx)fmtletfeedbackfmt=resultfmtend(* include Quiet *)includeBinsec_logger