Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file owee_debug_line.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422openOwee_buftypeheader={is_64bit:bool;total_length:u64;version:u16;address_size:u8option;(* only available in DWARF >= 5 *)prologue_length:u32;minimum_instruction_length:u8;default_is_stmt:u8;line_base:u8;line_range:u8;opcode_base:u8;standard_opcode_lengths:string;filenames:stringarray;}typepointers_to_other_sections={debug_line_str:toption;debug_str:toption;}letread_filename_version_lt_5t=matchRead.zero_stringt()with|None->invalid_format"Unterminated filename"|Somes->matchswith|""->""|fname->let_dir=Read.uleb128tinlet_time=Read.uleb128tinlet_len=Read.uleb128tinfnameletrecskip_directories_version_lt_5t=matchRead.zero_stringt()with|None->invalid_format"Unterminated directory list"|Somes->matchswith|""->()|_dir->(*print_endline _dir;*)skip_directories_version_lt_5tletrecread_filename_version_gte_5t~pointers_to_other_sections~is_64bit~address_size=function|`string->(matchRead.zero_stringt()with|None->invalid_format"Unterminated filename"|Somex->Somex)|`indirect->(* I have no idea if this can actually be hit; the spec doesn't explicitly mention
[indirect] in this context. Let's handle it anyway, just in case. *)letform=Owee_form.readtinread_filename_version_gte_5t~pointers_to_other_sections~is_64bit~address_sizeform|(`line_strp|`strp)asform->letbuf=matchformwith|`line_strp->pointers_to_other_sections.debug_line_str|`strp->pointers_to_other_sections.debug_strin(matchbufwith|None->None|Somebuf->letoffset=ifis_64bitthenInt64.to_int(Read.u64t)elseRead.u32tinletcursor=cursorbuf~at:offsetinRead.zero_stringcursor())|unknown_form->Owee_form.skipunknown_formt~is_64bit~address_size;Noneletunwrap_address_size_v5_only=function|Someaddress_size->address_size|None->failwith"Expected address size in v5"letskip_directories_version_gte_5t~is_64bit~address_size=letformat_count=Read.u8tinletdescriptors=Array.initformat_count(fun_->letcontent_type_code:u128=Read.uleb128tinletform=Owee_form.readtin(content_type_code,form))inletdirectory_entry_count=Read.uleb128tinfor_=1todirectory_entry_countdoArray.iter(fun(_,form)->Owee_form.skipformt~is_64bit~address_size)descriptorsdoneletskip_directoriest~is_64bit~version~address_size=ifversion<5thenskip_directories_version_lt_5telsebeginletaddress_size=unwrap_address_size_v5_onlyaddress_sizeinskip_directories_version_gte_5t~is_64bit~address_sizeendletread_filenames_version_lt_5t=letrecloopacc=matchread_filename_version_lt_5twith|""->acc|fname->(*Printf.eprintf "%S\n%!" fname;*)loop(fname::acc)inloop[]|>List.rev|>Array.of_listletread_filenames_version_gte_5t~pointers_to_other_sections~is_64bit~address_size=letformat_count=Read.u8tinletdescriptors=Array.initformat_count(fun_->letcontent_type_code:u128=Read.uleb128tinletform=Owee_form.readtin(content_type_code,form))inletdirectory_entry_count=Read.uleb128tinletfilenames=ref[]infor_=1todirectory_entry_countdoArray.iter(fun(content_type_code,form)->ifcontent_type_code=0x01(* DW_LNCT_path *)thenbeginmatchread_filename_version_gte_5t~pointers_to_other_sections~is_64bit~address_sizeformwith|None->()|Somefilename->(*Printf.eprintf "%S\n%!" filename;*)filenames:=filename::!filenamesendelseOwee_form.skipformt~is_64bit~address_size)descriptorsdone;!filenames|>List.rev|>Array.of_list(* Returns the list in the other direction. *)letread_filenamest~pointers_to_other_sections~version~is_64bit~address_size=ifversion<5thenread_filenames_version_lt_5telsebeginletaddress_size=unwrap_address_size_v5_onlyaddress_sizeinmatchpointers_to_other_sectionswith|None->invalid_format"Owee needs pointers_to_other_sections for Dwarf5"|Somepointers_to_other_sections->read_filenames_version_gte_5t~pointers_to_other_sections~is_64bit~address_sizeendletread_prologue_lengtht~is_64bit=ifis_64bitthenInt64.to_int(Read.u64t)elseRead.u32tletread_headert~pointers_to_other_sections=ensuret24".debug_line header truncated";lettotal_length=Read.u32tinletis_64bit=total_length=0xFFFF_FFFFinlettotal_length=ifis_64bitthenRead.u64telseInt64.of_inttotal_lengthinletchunk=subt(Int64.to_inttotal_length)inletversion=Read.u16chunkinassert_format(version>=2&&version<=5)"unknown .debug_line version";letaddress_size,segment_selector_size=ifversion>=5thenbeginletaddress_size=Read.u8chunkinletsegment_selector_size=Read.u8chunkin(Someaddress_size,Somesegment_selector_size)endelseNone,Noneinignore(segment_selector_size:u8option);letprologue_length=read_prologue_lengthchunk~is_64bitinensurechunkprologue_length"prologue_length too big";letprologue=subchunkprologue_lengthinletminimum_instruction_length=Read.u8prologueinifversion>=4thenbeginletmax_ops_per_instruction=Read.u8prologueinassert_format(max_ops_per_instruction=1)"VLIW not supported"end;letdefault_is_stmt=Read.u8prologueinletline_base=Read.s8prologueinletline_range=Read.u8prologueinletopcode_base=Read.u8prologueinassert_format(opcode_base>0)"invalid opcode_base";letstandard_opcode_lengths=Read.fixed_stringprologue(opcode_base-1)inskip_directoriesprologue~is_64bit~version~address_size;letfilenames=read_filenamesprologue~pointers_to_other_sections~is_64bit~version~address_sizeinletheader={is_64bit;total_length;version;address_size;prologue_length;minimum_instruction_length;default_is_stmt;line_base;line_range;opcode_base;standard_opcode_lengths;filenames}in(header,chunk)letread_chunk?pointers_to_other_sectionst=ifat_endtthenNoneelseSome(read_headert~pointers_to_other_sections)typestate={mutableaddress:int;mutablefilename:string;mutablefile:int;mutableline:int;mutablecol:int;mutableis_statement:bool;mutablebasic_block:bool;mutableend_sequence:bool;mutableprologue_end:bool;mutableepilogue_begin:bool;mutableisa:int;mutablediscriminator:int;}letinitial_stateheader={address=0;filename="";file=1;line=1;col=0;is_statement=header.default_is_stmt<>0;basic_block=false;end_sequence=false;prologue_end=false;epilogue_begin=false;isa=0;discriminator=0;}letreset_statestateheader=state.address<-0;state.filename<-"";state.file<-1;state.line<-1;state.col<-0;state.is_statement<-header.default_is_stmt<>0;state.basic_block<-false;state.end_sequence<-false;state.prologue_end<-false;state.epilogue_begin<-false;state.isa<-0;state.discriminator<-0letget_filenameheader{file;filename;_}=iffile<=0thenNoneelseiffile<=Array.lengthheader.filenamesthenSomeheader.filenames.(file-1)elseSomefilenameletflush_rowheaderstatefacc=letacc=fheaderstateaccinstate.basic_block<-false;state.prologue_end<-false;state.epilogue_begin<-false;state.discriminator<-0;accletstepheadersectionstatefacc=ifstate.line<0thenprerr_endline"NEGLINE";matchRead.u8sectionwith(*| n when (Printf.eprintf "opcode:%d\n%!" n; false) -> assert false*)|1(*DW_LNS_copy *)->flush_rowheaderstatefacc;|2(*DW_LNS_advance_pc *)->state.address<-state.address+(Read.uleb128section)*header.minimum_instruction_length;acc|3(*DW_LNS_advance_line *)->state.line<-state.line+Read.sleb128section;acc|4(*DW_LNS_set_file *)->state.file<-Read.uleb128section;acc|5(*DW_LNS_set_column *)->state.col<-Read.uleb128section;acc|6(*DW_LNS_negate_stmt *)->state.is_statement<-notstate.is_statement;acc|7(*DW_LNS_set_basic_block *)->state.basic_block<-true;acc|8(*DW_LNS_const_add_pc *)->state.address<-state.address+header.minimum_instruction_length*((255-header.opcode_base)/header.line_range);acc|9(*DW_LNS_fixed_advance_pc*)->state.address<-state.address+Read.u16section;acc|10(*DW_LNS_set_prologue_end*)whenheader.version>2->state.prologue_end<-true;acc|11(*DW_LNS_set_epilogue_begin*)whenheader.version>2->state.epilogue_begin<-true;acc|12(*DW_LNS_set_isa*)whenheader.version>2->state.isa<-Read.uleb128section;acc|0(*DW_LNS_extended_op*)->letinsn_len=Read.uleb128sectioninassert_format(insn_len<>0)"invalid extended opcode length";beginmatchRead.u8sectionwith(*| n when (Printf.eprintf "eopcode:%d\n%!" n; false) -> assert false*)|1(* DW_LNE_end_sequence *)->state.end_sequence<-true;letacc=flush_rowheaderstatefaccinreset_statestateheader;acc|2(* DW_LNE_set_address *)->(* FIXME: target dependent *)state.address<-Int64.to_int(Read.u64section);acc|3(* DW_LNE_define_file *)->(* DW_LNE_define_file was deprecated in DWARF 5. *)assert(header.version<5);state.filename<-read_filename_version_lt_5section;acc|4(* DW_LNE_set_discriminator *)->state.discriminator<-Read.uleb128section;acc|_->(* Unsupported opcode *)advancesection(insn_len-1);accend|opcodewhenopcode>=header.opcode_base(* Special opcode *)->letopcode=opcode-header.opcode_baseinletaddr_adv=opcode/header.line_rangeinletline_adv=opcodemodheader.line_rangeinletstep=addr_adv*header.minimum_instruction_lengthinstate.address<-state.address+step;state.line<-state.line+line_adv+header.line_base;flush_rowheaderstatefacc|opcode->(* Unrecognised opcode *)letcount=Char.codeheader.standard_opcode_lengths.[opcode-1]infor_i=0tocount-1doignore(Read.uleb128section:u128)done;accletrecfold_rowsheadersectionstatefacc=ifat_endsectionthenaccelsefold_rowsheadersectionstatef(stepheadersectionstatefacc)letfold_rows(header,section)facc=fold_rowsheadersection(initial_stateheader)faccletcopystate={address=state.address;filename=state.filename;file=state.file;line=state.line;col=state.col;is_statement=state.is_statement;basic_block=state.basic_block;end_sequence=state.end_sequence;prologue_end=state.prologue_end;epilogue_begin=state.epilogue_begin;isa=state.isa;discriminator=state.discriminator;}