summaryrefslogtreecommitdiff
path: root/lib/ocaml_rts/linksem/dwarf.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ocaml_rts/linksem/dwarf.ml')
-rw-r--r--lib/ocaml_rts/linksem/dwarf.ml4619
1 files changed, 0 insertions, 4619 deletions
diff --git a/lib/ocaml_rts/linksem/dwarf.ml b/lib/ocaml_rts/linksem/dwarf.ml
deleted file mode 100644
index 9e5a31aa..00000000
--- a/lib/ocaml_rts/linksem/dwarf.ml
+++ /dev/null
@@ -1,4619 +0,0 @@
-(*Generated by Lem from dwarf.lem.*)
-open Lem_basic_classes
-open Lem_bool
-open Lem_function
-open Lem_maybe
-open Lem_num
-open Lem_string
-
-open Lem_list (* TODO: check why this is not imported in ELF *)
-
-open Byte_sequence
-open Error
-open Hex_printing
-open Missing_pervasives
-open Show
-
-open Default_printing
-
-open Endianness
-open String_table
-
-open Elf_dynamic
-open Elf_file
-open Elf_header
-open Elf_program_header_table
-open Elf_relocation
-open Elf_section_header_table
-open Elf_symbol_table
-open Elf_types_native_uint
-
-
-(** ***************** experimental DWARF reading *********** *)
-
-(*
-
-This defines a representation of some of the DWARF debug information,
-with parsing functions to extract it from the byte sequences of the
-relevant ELF sections, and pretty-printing function to dump it in a
-human-readable form, similar to that of readelf. The main functions
-for this are:
-
- val extract_dwarf : elf64_file -> maybe dwarf
- val pp_dwarf : dwarf -> string
-
-It also defines evaluation of DWARF expressions and analysis functions
-to convert the variable location information to a form suitable for
-looking up variable names from machine addresses that arise during
-execution, including the call frame address calculation. The main
-types and functions for this are:
-
- type analysed_location_data
- val analyse_locations : dwarf -> analysed_location_data
-
- type evaluated_frame_info
- val evaluate_frame_info : dwarf -> evaluated_frame_info
-
- type dwarf_static
- val extract_dwarf_static : elf64_file -> maybe dwarf_static
-
-The last collects all the above - information that can be computed statically.
-
-Then to do lookup from addresses to source-code names, we have:
-
- type analysed_location_data_at_pc
- val analysed_locations_at_pc : evaluation_context -> dwarf_static -> natural -> analysed_location_data_at_pc
- val names_of_address : dwarf -> analysed_location_data_at_pc -> natural -> list string
-
-The definitions are deliberately simple-minded, to be quick to write,
-easy to see the correspondence to the DWARF text specification, and
-potentially support generation of theorem-prover definitions in
-future. They are in a pure functional style, making the information
-dependencies explicit. They are not written for performance, though
-they may be efficient enough for small examples as-is. They are
-written in Lem, and compiled from that to executable OCaml.
-
-The development follows the DWARF 4 pdf specification at http://www.dwarfstd.org/
-though tweaked in places where our examples use earlier versions. It doesn't
-systematically cover all the DWARF versions.
-It doesn't cover the GNU extensions
-(at https://fedorahosted.org/elfutils/wiki/DwarfExtensions).
-The representation, parsing, and pretty printing are mostly complete for the
-data in these DWARF ELF sections:
-
-.debug_abbrev
-.debug_info
-.debug_types
-.debug_loc
-.debug_str
-.debug_ranges
-.debug_frame (without augmentations)
-.debug_line
-
-The following DWARF ELF sections are not covered:
-
-.debug_aranges
-.debug_macinfo
-.debug_pubnames
-.debug_pubtypes
-
-The evaluation of DWARF expressions covers only some of the operations
-- probably enough for common cases.
-
-The analysis of DWARF location data should be enough to look up names
-from the addresses of variables and formal parameters. It does not
-currently handle the DWARF type data, so will not be useful for accesses
-strictly within the extent of a variable or parameter.
-
-The 'dwarf' type gives a lightly parsed representation of some of the
-dwarf information, with the byte sequences of the above .debug_*
-sections parsed into a structured representation. That makes the list
-and tree structures explicit, and converts the various numeric types
-into just natural, integer, and byte sequences. The lem natural and
-integer could be replaced by unsigned and signed 64-bit types; that'd
-probably be better for execution but not for theorem-prover use.
-
-*)
-
-(* some spec ambiguities (more in comments in-line below): *)
-(* can a location list be referenced from multiple compilation units, with different base addresses? *)
-
-
-(** debug *)
-
-(* workaround debug.lem linking *)
-(*val print_endline : string -> unit*)
-
-let my_debug s:unit= () (*print_endline s*)
-let my_debug2 s:unit= () (*print_endline s*)
-let my_debug3 s:unit= () (*print_endline s*)
-let my_debug4 s:unit= () (*print_endline s*)
-let my_debug5 s:unit= (print_endline s)
-
-
-(** ************************************************************ *)
-(** ** dwarf representation types **************************** *)
-(** ************************************************************ *)
-
-
-type dwarf_attribute_classes =
- | DWA_7_5_3
- | DWA_address
- | DWA_block
- | DWA_constant
- | DWA_dash
- | DWA_exprloc
- | DWA_flag
- | DWA_lineptr
- | DWA_loclistptr
- | DWA_macptr
- | DWA_rangelistptr
- | DWA_reference
- | DWA_string
-
-(* operations and expression evalution *)
-
-type operation_argument_type =
- | OAT_addr
- | OAT_dwarf_format_t
- | OAT_uint8
- | OAT_uint16
- | OAT_uint32
- | OAT_uint64
- | OAT_sint8
- | OAT_sint16
- | OAT_sint32
- | OAT_sint64
- | OAT_ULEB128
- | OAT_SLEB128
- | OAT_block
-
-type operation_argument_value =
- | OAV_natural of Nat_big_num.num
- | OAV_integer of Nat_big_num.num
- | OAV_block of Nat_big_num.num * char list
-
-type operation_stack = Nat_big_num.num list
-
-type arithmetic_context =
- {
- ac_bitwidth: Nat_big_num.num;
- ac_half: Nat_big_num.num; (* 2 ^ (ac_bitwidth -1) *)
- ac_all: Nat_big_num.num; (* 2 ^ ac_bitwidth *)
- ac_max: Nat_big_num.num; (* (2 ^ ac_bitwidth) -1 *) (* also the representation of -1 *)
-}
-
-type operation_semantics =
- | OpSem_lit
- | OpSem_deref
- | OpSem_stack of (arithmetic_context -> operation_stack -> operation_argument_value list -> operation_stack option)
- | OpSem_not_supported
- | OpSem_binary of (arithmetic_context -> Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num option)
- | OpSem_unary of (arithmetic_context -> Nat_big_num.num -> Nat_big_num.num option)
- | OpSem_opcode_lit of Nat_big_num.num
- | OpSem_reg
- | OpSem_breg
- | OpSem_bregx
- | OpSem_fbreg
- | OpSem_deref_size
- | OpSem_nop
- | OpSem_piece
- | OpSem_bit_piece
- | OpSem_implicit_value
- | OpSem_stack_value
- | OpSem_call_frame_cfa
-
-type operation =
- {
- op_code: Nat_big_num.num;
- op_string: string;
- op_argument_values: operation_argument_value list;
- op_semantics: operation_semantics;
- }
-
-
-(* the result of a location expression evaluation is a single_location (or failure) *)
-
-type simple_location =
- | SL_memory_address of Nat_big_num.num
- | SL_register of Nat_big_num.num
- | SL_implicit of char list (* used for implicit and stack values *)
- | SL_empty
-
-type composite_location_piece =
- | CLP_piece of Nat_big_num.num * simple_location
- | CLP_bit_piece of Nat_big_num.num * Nat_big_num.num * simple_location
-
-type single_location =
- | SL_simple of simple_location
- | SL_composite of composite_location_piece list
-
-(* location expression evaluation is a stack machine operating over the following state *)
-
-type state =
- {
- s_stack: operation_stack;
- s_value: simple_location;
- s_location_pieces: composite_location_piece list;
- }
-
-(* location expression evaluation can involve register and memory reads, via the following interface *)
-
-type 'a register_read_result =
- | RRR_result of Nat_big_num.num
- | RRR_not_currently_available
- | RRR_bad_register_number
-
-type 'a memory_read_result =
- | MRR_result of Nat_big_num.num
- | MRR_not_currently_available
- | MRR_bad_address
-
-type evaluation_context =
- {
- read_register: Nat_big_num.num -> Nat_big_num.num register_read_result;
- read_memory: Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num memory_read_result;
- }
-
-
-(* dwarf sections *)
-
-type dwarf_format =
- | Dwarf32
- | Dwarf64
-
-(* .debug_abbrev section *)
-
-type abbreviation_declaration =
- {
- ad_abbreviation_code: Nat_big_num.num;
- ad_tag: Nat_big_num.num;
- ad_has_children: bool;
- ad_attribute_specifications: (Nat_big_num.num * Nat_big_num.num) list;
- }
-
-type abbreviations_table = abbreviation_declaration list
-
-(* .debug_info section *)
-
-type attribute_value =
- | AV_addr of Nat_big_num.num
- | AV_block of Nat_big_num.num * char list
- | AV_constantN of Nat_big_num.num * char list
- | AV_constant_SLEB128 of Nat_big_num.num
- | AV_constant_ULEB128 of Nat_big_num.num
- | AV_exprloc of Nat_big_num.num * char list
- | AV_flag of bool
- | AV_ref of Nat_big_num.num
- | AV_ref_addr of Nat_big_num.num (* dwarf_format dependent *)
- | AV_ref_sig8 of Nat_big_num.num
- | AV_sec_offset of Nat_big_num.num
- | AV_string of char list (* not including terminating null *)
- | AV_strp of Nat_big_num.num (* dwarf_format dependent *)
-
-type die =
- {
- die_offset: Nat_big_num.num;
- die_abbreviation_code: Nat_big_num.num;
- die_abbreviation_declaration: abbreviation_declaration;
- die_attribute_values: (Nat_big_num.num (*pos*) * attribute_value) list;
- die_children: die list;
- }
-
-type compilation_unit_header =
- {
- cuh_offset: Nat_big_num.num;
- cuh_dwarf_format: dwarf_format;
- cuh_unit_length: Nat_big_num.num;
- cuh_version: Nat_big_num.num;
- cuh_debug_abbrev_offset: Nat_big_num.num;
- cuh_address_size: Nat_big_num.num;
- }
-
-type compilation_unit =
- {
- cu_header: compilation_unit_header;
- cu_abbreviations_table: abbreviations_table;
- cu_die: die;
- }
-
-type compilation_units = compilation_unit list
-
-(* .debug_type section *)
-
-type type_unit_header =
- {
- tuh_cuh: compilation_unit_header;
- tuh_type_signature: Nat_big_num.num;
- tuh_type_offset: Nat_big_num.num;
- }
-
-type type_unit =
- {
- tu_header: type_unit_header;
- tu_abbreviations_table: abbreviations_table;
- tu_die: die;
- }
-
-type type_units = type_unit list
-
-(* .debug_loc section *)
-
-type single_location_description = char list
-
-type location_list_entry =
- {
- lle_beginning_address_offset: Nat_big_num.num;
- lle_ending_address_offset: Nat_big_num.num;
- lle_single_location_description: single_location_description;
- }
-
-type base_address_selection_entry =
- {
- base_address: Nat_big_num.num;
- }
-
-type location_list_item =
- | LLI_lle of location_list_entry
- | LLI_base of base_address_selection_entry
-
-type location_list = Nat_big_num.num (*offset*) * location_list_item list
-
-type location_list_list = location_list list
-
-(* .debug_ranges section *)
-
-type range_list_entry =
- {
- rle_beginning_address_offset: Nat_big_num.num;
- rle_ending_address_offset: Nat_big_num.num;
- }
-
-type range_list_item =
- | RLI_rle of range_list_entry
- | RLI_base of base_address_selection_entry
-
-type range_list = Nat_big_num.num (*offset*) * range_list_item list
-
-type range_list_list = range_list list
-
-(* .debug_frame section: call frame instructions *)
-
-type cfa_address = Nat_big_num.num
-type cfa_block = char list
-type cfa_delta = Nat_big_num.num
-type cfa_offset = Nat_big_num.num
-type cfa_register = Nat_big_num.num
-type cfa_sfoffset = Nat_big_num.num
-
-type call_frame_argument_type =
- | CFAT_address
- | CFAT_delta1
- | CFAT_delta2
- | CFAT_delta4
- | CFAT_delta_ULEB128
- | CFAT_offset (*ULEB128*)
- | CFAT_sfoffset (*SLEB128*)
- | CFAT_register (*ULEB128*)
- | CFAT_block
-
-type call_frame_argument_value =
- | CFAV_address of cfa_address
- | CFAV_block of cfa_block
- | CFAV_delta of cfa_delta
- | CFAV_offset of cfa_offset
- | CFAV_register of cfa_register
- | CFAV_sfoffset of cfa_sfoffset
-
-type call_frame_instruction =
- | DW_CFA_advance_loc of cfa_delta
- | DW_CFA_offset of cfa_register * cfa_offset
- | DW_CFA_restore of cfa_register
- | DW_CFA_nop
- | DW_CFA_set_loc of cfa_address
- | DW_CFA_advance_loc1 of cfa_delta
- | DW_CFA_advance_loc2 of cfa_delta
- | DW_CFA_advance_loc4 of cfa_delta
- | DW_CFA_offset_extended of cfa_register * cfa_offset
- | DW_CFA_restore_extended of cfa_register
- | DW_CFA_undefined of cfa_register
- | DW_CFA_same_value of cfa_register
- | DW_CFA_register of cfa_register * cfa_register
- | DW_CFA_remember_state
- | DW_CFA_restore_state
- | DW_CFA_def_cfa of cfa_register * cfa_offset
- | DW_CFA_def_cfa_register of cfa_register
- | DW_CFA_def_cfa_offset of cfa_offset
- | DW_CFA_def_cfa_expression of cfa_block
- | DW_CFA_expression of cfa_register * cfa_block
- | DW_CFA_offset_extended_sf of cfa_register * cfa_sfoffset
- | DW_CFA_def_cfa_sf of cfa_register * cfa_sfoffset
- | DW_CFA_def_cfa_offset_sf of cfa_sfoffset
- | DW_CFA_val_offset of cfa_register * cfa_offset
- | DW_CFA_val_offset_sf of cfa_register * cfa_sfoffset
- | DW_CFA_val_expression of cfa_register * cfa_block
- | DW_CFA_unknown of char
-
-(* .debug_frame section: top-level *)
-
-type cie =
- {
- cie_offset: Nat_big_num.num;
- cie_length: Nat_big_num.num;
- cie_id: Nat_big_num.num;
- cie_version: Nat_big_num.num;
- cie_augmentation: char list; (* not including terminating null *)
- cie_address_size: Nat_big_num.num option;
- cie_segment_size: Nat_big_num.num option;
- cie_code_alignment_factor: Nat_big_num.num;
- cie_data_alignment_factor: Nat_big_num.num;
- cie_return_address_register: cfa_register;
- cie_initial_instructions_bytes: char list;
- cie_initial_instructions: call_frame_instruction list;
- }
-
-type fde =
- {
- fde_offset: Nat_big_num.num;
- fde_length: Nat_big_num.num;
- fde_cie_pointer: Nat_big_num.num;
- fde_initial_location_segment_selector: Nat_big_num.num option;
- fde_initial_location_address: Nat_big_num.num;
- fde_address_range: Nat_big_num.num;
- fde_instructions_bytes: char list;
- fde_instructions: call_frame_instruction list;
- }
-
-type frame_info_element =
- | FIE_cie of cie
- | FIE_fde of fde
-
-type frame_info = frame_info_element list
-
-
-(* evaluated cfa data *)
-
-type cfa_rule =
- | CR_undefined
- | CR_register of cfa_register * Nat_big_num.num
- | CR_expression of single_location_description
-
-type register_rule =
- | RR_undefined (*A register that has this rule has no recoverable value in the previous frame.
- (By convention, it is not preserved by a callee.)*)
- | RR_same_value (*This register has not been modified from the previous frame. (By convention,
- it is preserved by the callee, but the callee has not modified it.)*)
- | RR_offset of Nat_big_num.num (* The previous value of this register is saved at the address CFA+N where CFA
- is the current CFA value and N is a signed offset.*)
- | RR_val_offset of Nat_big_num.num (* The previous value of this register is the value CFA+N where CFA is the
- current CFA value and N is a signed offset.*)
- | RR_register of Nat_big_num.num (* The previous value of this register is stored in another register numbered R.*)
- | RR_expression of single_location_description (* The previous value of this register is located at the address produced by
- executing the DWARF expression E.*)
- | RR_val_expression of single_location_description (* The previous value of this register is the value produced by executing the
-DWARF expression E.*)
- | RR_architectural (*The rule is defined externally to this specification by the augmenter*)
-
-type register_rule_map = (cfa_register * register_rule) list
-
-type cfa_table_row =
- {
- ctr_loc: Nat_big_num.num;
- ctr_cfa: cfa_rule;
- ctr_regs: register_rule_map;
- }
-
-type cfa_state =
- {
- cs_current_row: cfa_table_row;
- cs_previous_rows: cfa_table_row list;
- cs_initial_instructions_row: cfa_table_row;
- cs_row_stack: cfa_table_row list;
- }
-
-
-type evaluated_frame_info = (fde * cfa_table_row list)
- list
-
-
-(* line number *)
-
-type line_number_argument_type =
- | LNAT_address
- | LNAT_ULEB128
- | LNAT_SLEB128
- | LNAT_uint16
- | LNAT_string
-
-type line_number_argument_value =
- | LNAV_address of Nat_big_num.num
- | LNAV_ULEB128 of Nat_big_num.num
- | LNAV_SLEB128 of Nat_big_num.num
- | LNAV_uint16 of Nat_big_num.num
- | LNAV_string of char list (* not including terminating null *)
-
-type line_number_operation =
- (* standard *)
- | DW_LNS_copy
- | DW_LNS_advance_pc of Nat_big_num.num
- | DW_LNS_advance_line of Nat_big_num.num
- | DW_LNS_set_file of Nat_big_num.num
- | DW_LNS_set_column of Nat_big_num.num
- | DW_LNS_negate_stmt
- | DW_LNS_set_basic_block
- | DW_LNS_const_add_pc
- | DW_LNS_fixed_advance_pc of Nat_big_num.num
- | DW_LNS_set_prologue_end
- | DW_LNS_set_epilogue_begin
- | DW_LNS_set_isa of Nat_big_num.num
- (* extended *)
- | DW_LNE_end_sequence
- | DW_LNE_set_address of Nat_big_num.num
- | DW_LNE_define_file of ( char list) * Nat_big_num.num * Nat_big_num.num * Nat_big_num.num
- | DW_LNE_set_discriminator of Nat_big_num.num
- (* special *)
- | DW_LN_special of Nat_big_num.num (* the adjusted opcode *)
-
-type line_number_file_entry =
- {
- lnfe_path: char list;
- lnfe_directory_index: Nat_big_num.num;
- lnfe_last_modification: Nat_big_num.num;
- lnfe_length: Nat_big_num.num;
- }
-
-type line_number_header =
- {
- lnh_offset: Nat_big_num.num;
- lnh_dwarf_format: dwarf_format;
- lnh_unit_length: Nat_big_num.num;
- lnh_version: Nat_big_num.num;
- lnh_header_length: Nat_big_num.num;
- lnh_minimum_instruction_length: Nat_big_num.num;
- lnh_maximum_operations_per_instruction: Nat_big_num.num;
- lnh_default_is_stmt: bool;
- lnh_line_base: Nat_big_num.num;
- lnh_line_range: Nat_big_num.num;
- lnh_opcode_base: Nat_big_num.num;
- lnh_standard_opcode_lengths: Nat_big_num.num list;
- lnh_include_directories: ( char list) list;
- lnh_file_names: line_number_file_entry list;
- }
-
-type line_number_program =
- {
- lnp_header: line_number_header;
- lnp_operations: line_number_operation list;
- }
-
-(* line number evaluation *)
-
-type line_number_registers =
- {
- lnr_address: Nat_big_num.num;
- lnr_op_index: Nat_big_num.num;
- lnr_file: Nat_big_num.num;
- lnr_line: Nat_big_num.num;
- lnr_column: Nat_big_num.num;
- lnr_is_stmt: bool;
- lnr_basic_block: bool;
- lnr_end_sequence: bool;
- lnr_prologue_end: bool;
- lnr_epilogue_begin: bool;
- lnr_isa: Nat_big_num.num;
- lnr_discriminator: Nat_big_num.num;
- }
-
-
-
-
-(* top-level collection of dwarf data *)
-
-type dwarf =
- {
- d_endianness: Endianness.endianness; (* from the ELF *)
- d_str: char list;
- d_compilation_units: compilation_units;
- d_type_units: type_units;
- d_loc: location_list_list;
- d_ranges: range_list_list;
- d_frame_info: frame_info;
- d_line_info: line_number_program list;
- }
-
-(* analysed location data *)
-
-type analysed_location_data = ((compilation_unit * ( die list) * die) * ( (Nat_big_num.num * Nat_big_num.num * single_location_description)list)option) list
-
-type analysed_location_data_at_pc = ((compilation_unit * ( die list) * die) * (Nat_big_num.num * Nat_big_num.num * single_location_description * single_location error)) list
-
-(* evaluated line data *)
-
-type evaluated_line_info = (line_number_header * line_number_registers list) list
-
-type dwarf_static =
- {
- ds_dwarf: dwarf;
- ds_analysed_location_data: analysed_location_data;
- ds_evaluated_frame_info: evaluated_frame_info;
- ds_evaluated_line_info: evaluated_line_info;
- }
-
-type dwarf_dynamic_at_pc = analysed_location_data_at_pc
-
-(** context for parsing and pp functions *)
-
-type p_context =
- {
- endianness: Endianness.endianness;
- }
-
-
-
-(** ************************************************************ *)
-(** ** missing pervasives ************************************ *)
-(** ************************************************************ *)
-
-(** hex parsing *)
-
-(* this should be in lem, either built-in or in pervasives *)
-
-(*val natural_of_char : char -> natural*)
-let natural_of_char c:Nat_big_num.num=
- (let naturalOrd c'= (Nat_big_num.of_int (Char.code c')) in
- let n = (naturalOrd c) in
- if Nat_big_num.greater_equal n (naturalOrd '0') && Nat_big_num.less_equal n (naturalOrd '9') then Nat_big_num.sub_nat n (naturalOrd '0')
- else if Nat_big_num.greater_equal n (naturalOrd 'A') && Nat_big_num.less_equal n (naturalOrd 'F') then Nat_big_num.add (Nat_big_num.sub_nat n (naturalOrd 'A'))(Nat_big_num.of_int 10)
- else if Nat_big_num.greater_equal n (naturalOrd 'a') && Nat_big_num.less_equal n (naturalOrd 'f') then Nat_big_num.add (Nat_big_num.sub_nat n (naturalOrd 'a'))(Nat_big_num.of_int 10)
- else failwith ("natural_of_char argument #'" ^ (Xstring.implode [c] ^ "' not in 0-9,A-F,a-f")))
-
-(*val natural_of_hex' : list char -> natural*)
-let rec natural_of_hex' cs:Nat_big_num.num=
- ((match cs with
- | c :: cs' -> Nat_big_num.add (natural_of_char c) (Nat_big_num.mul(Nat_big_num.of_int 16) (natural_of_hex' cs'))
- | [] ->Nat_big_num.of_int 0
- ))
-
-(*val natural_of_hex : string -> natural*)
-let natural_of_hex s:Nat_big_num.num=
- (let cs = (Xstring.explode s) in
- (match cs with
- | '0'::'x'::cs' ->
- (match cs' with
- | c :: _ -> natural_of_hex' (List.rev cs')
- | [] -> failwith ("natural_of_hex argument \"" ^ (s ^ "\" has no digits"))
- )
- | _ -> failwith ("natural_of_hex argument \"" ^ (s ^ "\" does not begin 0x"))
- ))
-
-
-(* natural version of List.index *)
-(*val index_natural : forall 'a. list 'a -> natural -> maybe 'a*)
-let rec index_natural l n:'a option= ((match l with
- | [] -> None
- | x :: xs -> if Nat_big_num.equal n(Nat_big_num.of_int 0) then Some x else index_natural xs (Nat_big_num.sub_nat n(Nat_big_num.of_int 1))
-))
-
-let partialNaturalFromInteger (i:Nat_big_num.num) : Nat_big_num.num=
- (if Nat_big_num.less i(Nat_big_num.of_int 0) then failwith "partialNaturalFromInteger" else Nat_big_num.abs i)
-
-(*val natural_nat_shift_left : natural -> nat -> natural*)
-
-(*val natural_nat_shift_right : natural -> nat -> natural*)
-
-
-
-(** ************************************************************ *)
-(** ** dwarf encodings *************************************** *)
-(** ************************************************************ *)
-
-(* these encoding tables are pasted from the DWARF 4 specification *)
-
-(* tag encoding *)
-let tag_encodings:(string*Nat_big_num.num)list= ([
- ("DW_TAG_array_type" , natural_of_hex "0x01" );
- ("DW_TAG_class_type" , natural_of_hex "0x02" );
- ("DW_TAG_entry_point" , natural_of_hex "0x03" );
- ("DW_TAG_enumeration_type" , natural_of_hex "0x04" );
- ("DW_TAG_formal_parameter" , natural_of_hex "0x05" );
- ("DW_TAG_imported_declaration" , natural_of_hex "0x08" );
- ("DW_TAG_label" , natural_of_hex "0x0a" );
- ("DW_TAG_lexical_block" , natural_of_hex "0x0b" );
- ("DW_TAG_member" , natural_of_hex "0x0d" );
- ("DW_TAG_pointer_type" , natural_of_hex "0x0f" );
- ("DW_TAG_reference_type" , natural_of_hex "0x10" );
- ("DW_TAG_compile_unit" , natural_of_hex "0x11" );
- ("DW_TAG_string_type" , natural_of_hex "0x12" );
- ("DW_TAG_structure_type" , natural_of_hex "0x13" );
- ("DW_TAG_subroutine_type" , natural_of_hex "0x15" );
- ("DW_TAG_typedef" , natural_of_hex "0x16" );
- ("DW_TAG_union_type" , natural_of_hex "0x17" );
- ("DW_TAG_unspecified_parameters" , natural_of_hex "0x18" );
- ("DW_TAG_variant" , natural_of_hex "0x19" );
- ("DW_TAG_common_block" , natural_of_hex "0x1a" );
- ("DW_TAG_common_inclusion" , natural_of_hex "0x1b" );
- ("DW_TAG_inheritance" , natural_of_hex "0x1c" );
- ("DW_TAG_inlined_subroutine" , natural_of_hex "0x1d" );
- ("DW_TAG_module" , natural_of_hex "0x1e" );
- ("DW_TAG_ptr_to_member_type" , natural_of_hex "0x1f" );
- ("DW_TAG_set_type" , natural_of_hex "0x20" );
- ("DW_TAG_subrange_type" , natural_of_hex "0x21" );
- ("DW_TAG_with_stmt" , natural_of_hex "0x22" );
- ("DW_TAG_access_declaration" , natural_of_hex "0x23" );
- ("DW_TAG_base_type" , natural_of_hex "0x24" );
- ("DW_TAG_catch_block" , natural_of_hex "0x25" );
- ("DW_TAG_const_type" , natural_of_hex "0x26" );
- ("DW_TAG_constant" , natural_of_hex "0x27" );
- ("DW_TAG_enumerator" , natural_of_hex "0x28" );
- ("DW_TAG_file_type" , natural_of_hex "0x29" );
- ("DW_TAG_friend" , natural_of_hex "0x2a" );
- ("DW_TAG_namelist" , natural_of_hex "0x2b" );
- ("DW_TAG_namelist_item" , natural_of_hex "0x2c" );
- ("DW_TAG_packed_type" , natural_of_hex "0x2d" );
- ("DW_TAG_subprogram" , natural_of_hex "0x2e" );
- ("DW_TAG_template_type_parameter" , natural_of_hex "0x2f" );
- ("DW_TAG_template_value_parameter" , natural_of_hex "0x30" );
- ("DW_TAG_thrown_type" , natural_of_hex "0x31" );
- ("DW_TAG_try_block" , natural_of_hex "0x32" );
- ("DW_TAG_variant_part" , natural_of_hex "0x33" );
- ("DW_TAG_variable" , natural_of_hex "0x34" );
- ("DW_TAG_volatile_type" , natural_of_hex "0x35" );
- ("DW_TAG_dwarf_procedure" , natural_of_hex "0x36" );
- ("DW_TAG_restrict_type" , natural_of_hex "0x37" );
- ("DW_TAG_interface_type" , natural_of_hex "0x38" );
- ("DW_TAG_namespace" , natural_of_hex "0x39" );
- ("DW_TAG_imported_module" , natural_of_hex "0x3a" );
- ("DW_TAG_unspecified_type" , natural_of_hex "0x3b" );
- ("DW_TAG_partial_unit" , natural_of_hex "0x3c" );
- ("DW_TAG_imported_unit" , natural_of_hex "0x3d" );
- ("DW_TAG_condition" , natural_of_hex "0x3f" );
- ("DW_TAG_shared_type" , natural_of_hex "0x40" );
- ("DW_TAG_type_unit" , natural_of_hex "0x41" );
- ("DW_TAG_rvalue_reference_type" , natural_of_hex "0x42" );
- ("DW_TAG_template_alias" , natural_of_hex "0x43" );
- ("DW_TAG_lo_user" , natural_of_hex "0x4080");
- ("DW_TAG_hi_user" , natural_of_hex "0xffff")
-])
-
-
-(* child determination encoding *)
-
-let vDW_CHILDREN_no:Nat_big_num.num= (natural_of_hex "0x00")
-let vDW_CHILDREN_yes:Nat_big_num.num= (natural_of_hex "0x01")
-
-
-(* attribute encoding *)
-
-let attribute_encodings:(string*Nat_big_num.num*(dwarf_attribute_classes)list)list= ([
- ("DW_AT_sibling" , natural_of_hex "0x01", [DWA_reference]) ;
- ("DW_AT_location" , natural_of_hex "0x02", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_name" , natural_of_hex "0x03", [DWA_string]) ;
- ("DW_AT_ordering" , natural_of_hex "0x09", [DWA_constant]) ;
- ("DW_AT_byte_size" , natural_of_hex "0x0b", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_bit_offset" , natural_of_hex "0x0c", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_bit_size" , natural_of_hex "0x0d", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_stmt_list" , natural_of_hex "0x10", [DWA_lineptr]) ;
- ("DW_AT_low_pc" , natural_of_hex "0x11", [DWA_address]) ;
- ("DW_AT_high_pc" , natural_of_hex "0x12", [DWA_address; DWA_constant]) ;
- ("DW_AT_language" , natural_of_hex "0x13", [DWA_constant]) ;
- ("DW_AT_discr" , natural_of_hex "0x15", [DWA_reference]) ;
- ("DW_AT_discr_value" , natural_of_hex "0x16", [DWA_constant]) ;
- ("DW_AT_visibility" , natural_of_hex "0x17", [DWA_constant]) ;
- ("DW_AT_import" , natural_of_hex "0x18", [DWA_reference]) ;
- ("DW_AT_string_length" , natural_of_hex "0x19", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_common_reference" , natural_of_hex "0x1a", [DWA_reference]) ;
- ("DW_AT_comp_dir" , natural_of_hex "0x1b", [DWA_string]) ;
- ("DW_AT_const_value" , natural_of_hex "0x1c", [DWA_block; DWA_constant; DWA_string]) ;
- ("DW_AT_containing_type" , natural_of_hex "0x1d", [DWA_reference]) ;
- ("DW_AT_default_value" , natural_of_hex "0x1e", [DWA_reference]) ;
- ("DW_AT_inline" , natural_of_hex "0x20", [DWA_constant]) ;
- ("DW_AT_is_optional" , natural_of_hex "0x21", [DWA_flag]) ;
- ("DW_AT_lower_bound" , natural_of_hex "0x22", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_producer" , natural_of_hex "0x25", [DWA_string]) ;
- ("DW_AT_prototyped" , natural_of_hex "0x27", [DWA_flag]) ;
- ("DW_AT_return_addr" , natural_of_hex "0x2a", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_start_scope" , natural_of_hex "0x2c", [DWA_constant; DWA_rangelistptr]) ;
- ("DW_AT_bit_stride" , natural_of_hex "0x2e", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_upper_bound" , natural_of_hex "0x2f", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_abstract_origin" , natural_of_hex "0x31", [DWA_reference]) ;
- ("DW_AT_accessibility" , natural_of_hex "0x32", [DWA_constant]) ;
- ("DW_AT_address_class" , natural_of_hex "0x33", [DWA_constant]) ;
- ("DW_AT_artificial" , natural_of_hex "0x34", [DWA_flag]) ;
- ("DW_AT_base_types" , natural_of_hex "0x35", [DWA_reference]) ;
- ("DW_AT_calling_convention" , natural_of_hex "0x36", [DWA_constant]) ;
- ("DW_AT_count" , natural_of_hex "0x37", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_data_member_location" , natural_of_hex "0x38", [DWA_constant; DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_decl_column" , natural_of_hex "0x39", [DWA_constant]) ;
- ("DW_AT_decl_file" , natural_of_hex "0x3a", [DWA_constant]) ;
- ("DW_AT_decl_line" , natural_of_hex "0x3b", [DWA_constant]) ;
- ("DW_AT_declaration" , natural_of_hex "0x3c", [DWA_flag]) ;
- ("DW_AT_discr_list" , natural_of_hex "0x3d", [DWA_block]) ;
- ("DW_AT_encoding" , natural_of_hex "0x3e", [DWA_constant]) ;
- ("DW_AT_external" , natural_of_hex "0x3f", [DWA_flag]) ;
- ("DW_AT_frame_base" , natural_of_hex "0x40", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_friend" , natural_of_hex "0x41", [DWA_reference]) ;
- ("DW_AT_identifier_case" , natural_of_hex "0x42", [DWA_constant]) ;
- ("DW_AT_macro_info" , natural_of_hex "0x43", [DWA_macptr]) ;
- ("DW_AT_namelist_item" , natural_of_hex "0x44", [DWA_reference]) ;
- ("DW_AT_priority" , natural_of_hex "0x45", [DWA_reference]) ;
- ("DW_AT_segment" , natural_of_hex "0x46", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_specification" , natural_of_hex "0x47", [DWA_reference]) ;
- ("DW_AT_static_link" , natural_of_hex "0x48", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_type" , natural_of_hex "0x49", [DWA_reference]) ;
- ("DW_AT_use_location" , natural_of_hex "0x4a", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_variable_parameter" , natural_of_hex "0x4b", [DWA_flag]) ;
- ("DW_AT_virtuality" , natural_of_hex "0x4c", [DWA_constant]) ;
- ("DW_AT_vtable_elem_location" , natural_of_hex "0x4d", [DWA_exprloc; DWA_loclistptr]) ;
- ("DW_AT_allocated" , natural_of_hex "0x4e", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_associated" , natural_of_hex "0x4f", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_data_location" , natural_of_hex "0x50", [DWA_exprloc]) ;
- ("DW_AT_byte_stride" , natural_of_hex "0x51", [DWA_constant; DWA_exprloc; DWA_reference]) ;
- ("DW_AT_entry_pc" , natural_of_hex "0x52", [DWA_address]) ;
- ("DW_AT_use_UTF8" , natural_of_hex "0x53", [DWA_flag]) ;
- ("DW_AT_extension" , natural_of_hex "0x54", [DWA_reference]) ;
- ("DW_AT_ranges" , natural_of_hex "0x55", [DWA_rangelistptr]) ;
- ("DW_AT_trampoline" , natural_of_hex "0x56", [DWA_address; DWA_flag; DWA_reference; DWA_string]);
- ("DW_AT_call_column" , natural_of_hex "0x57", [DWA_constant]) ;
- ("DW_AT_call_file" , natural_of_hex "0x58", [DWA_constant]) ;
- ("DW_AT_call_line" , natural_of_hex "0x59", [DWA_constant]) ;
- ("DW_AT_description" , natural_of_hex "0x5a", [DWA_string]) ;
- ("DW_AT_binary_scale" , natural_of_hex "0x5b", [DWA_constant]) ;
- ("DW_AT_decimal_scale" , natural_of_hex "0x5c", [DWA_constant]) ;
- ("DW_AT_small" , natural_of_hex "0x5d", [DWA_reference]) ;
- ("DW_AT_decimal_sign" , natural_of_hex "0x5e", [DWA_constant]) ;
- ("DW_AT_digit_count" , natural_of_hex "0x5f", [DWA_constant]) ;
- ("DW_AT_picture_string" , natural_of_hex "0x60", [DWA_string]) ;
- ("DW_AT_mutable" , natural_of_hex "0x61", [DWA_flag]) ;
- ("DW_AT_threads_scaled" , natural_of_hex "0x62", [DWA_flag]) ;
- ("DW_AT_explicit" , natural_of_hex "0x63", [DWA_flag]) ;
- ("DW_AT_object_pointer" , natural_of_hex "0x64", [DWA_reference]) ;
- ("DW_AT_endianity" , natural_of_hex "0x65", [DWA_constant]) ;
- ("DW_AT_elemental" , natural_of_hex "0x66", [DWA_flag]) ;
- ("DW_AT_pure" , natural_of_hex "0x67", [DWA_flag]) ;
- ("DW_AT_recursive" , natural_of_hex "0x68", [DWA_flag]) ;
- ("DW_AT_signature" , natural_of_hex "0x69", [DWA_reference]) ;
- ("DW_AT_main_subprogram" , natural_of_hex "0x6a", [DWA_flag]) ;
- ("DW_AT_data_bit_offset" , natural_of_hex "0x6b", [DWA_constant]) ;
- ("DW_AT_const_expr" , natural_of_hex "0x6c", [DWA_flag]) ;
- ("DW_AT_enum_class" , natural_of_hex "0x6d", [DWA_flag]) ;
- ("DW_AT_linkage_name" , natural_of_hex "0x6e", [DWA_string]) ;
- ("DW_AT_lo_user" , natural_of_hex "0x2000", [DWA_dash]) ;
- ("DW_AT_hi_user" , natural_of_hex "0x3fff", [DWA_dash])
-])
-
-
-(* attribute form encoding *)
-
-let attribute_form_encodings:(string*Nat_big_num.num*(dwarf_attribute_classes)list)list= ([
- ("DW_FORM_addr" , natural_of_hex "0x01", [DWA_address]) ;
- ("DW_FORM_block2" , natural_of_hex "0x03", [DWA_block]) ;
- ("DW_FORM_block4" , natural_of_hex "0x04", [DWA_block]) ;
- ("DW_FORM_data2" , natural_of_hex "0x05", [DWA_constant]) ;
- ("DW_FORM_data4" , natural_of_hex "0x06", [DWA_constant]) ;
- ("DW_FORM_data8" , natural_of_hex "0x07", [DWA_constant]) ;
- ("DW_FORM_string" , natural_of_hex "0x08", [DWA_string]) ;
- ("DW_FORM_block" , natural_of_hex "0x09", [DWA_block]) ;
- ("DW_FORM_block1" , natural_of_hex "0x0a", [DWA_block]) ;
- ("DW_FORM_data1" , natural_of_hex "0x0b", [DWA_constant]) ;
- ("DW_FORM_flag" , natural_of_hex "0x0c", [DWA_flag]) ;
- ("DW_FORM_sdata" , natural_of_hex "0x0d", [DWA_constant]) ;
- ("DW_FORM_strp" , natural_of_hex "0x0e", [DWA_string]) ;
- ("DW_FORM_udata" , natural_of_hex "0x0f", [DWA_constant]) ;
- ("DW_FORM_ref_addr" , natural_of_hex "0x10", [DWA_reference]);
- ("DW_FORM_ref1" , natural_of_hex "0x11", [DWA_reference]);
- ("DW_FORM_ref2" , natural_of_hex "0x12", [DWA_reference]);
- ("DW_FORM_ref4" , natural_of_hex "0x13", [DWA_reference]);
- ("DW_FORM_ref8" , natural_of_hex "0x14", [DWA_reference]);
- ("DW_FORM_ref_udata" , natural_of_hex "0x15", [DWA_reference]);
- ("DW_FORM_indirect" , natural_of_hex "0x16", [DWA_7_5_3]) ;
- ("DW_FORM_sec_offset" , natural_of_hex "0x17", [DWA_lineptr; DWA_loclistptr; DWA_macptr; DWA_rangelistptr]) ;
- ("DW_FORM_exprloc" , natural_of_hex "0x18", [DWA_exprloc]) ;
- ("DW_FORM_flag_present", natural_of_hex "0x19", [DWA_flag]) ;
- ("DW_FORM_ref_sig8" , natural_of_hex "0x20", [DWA_reference])
-])
-
-
-(* operation encoding *)
-
-let operation_encodings:(string*Nat_big_num.num*(operation_argument_type)list*operation_semantics)list= ([
-("DW_OP_addr", natural_of_hex "0x03", [OAT_addr] , OpSem_lit); (*1*) (*constant address (size target specific)*)
-("DW_OP_deref", natural_of_hex "0x06", [] , OpSem_deref); (*0*)
-("DW_OP_const1u", natural_of_hex "0x08", [OAT_uint8] , OpSem_lit); (*1*) (* 1-byte constant *)
-("DW_OP_const1s", natural_of_hex "0x09", [OAT_sint8] , OpSem_lit); (*1*) (* 1-byte constant *)
-("DW_OP_const2u", natural_of_hex "0x0a", [OAT_uint16] , OpSem_lit); (*1*) (* 2-byte constant *)
-("DW_OP_const2s", natural_of_hex "0x0b", [OAT_sint16] , OpSem_lit); (*1*) (* 2-byte constant *)
-("DW_OP_const4u", natural_of_hex "0x0c", [OAT_uint32] , OpSem_lit); (*1*) (* 4-byte constant *)
-("DW_OP_const4s", natural_of_hex "0x0d", [OAT_sint32] , OpSem_lit); (*1*) (* 4-byte constant *)
-("DW_OP_const8u", natural_of_hex "0x0e", [OAT_uint64] , OpSem_lit); (*1*) (* 8-byte constant *)
-("DW_OP_const8s", natural_of_hex "0x0f", [OAT_sint64] , OpSem_lit); (*1*) (* 8-byte constant *)
-("DW_OP_constu", natural_of_hex "0x10", [OAT_ULEB128] , OpSem_lit); (*1*) (* ULEB128 constant *)
-("DW_OP_consts", natural_of_hex "0x11", [OAT_SLEB128] , OpSem_lit); (*1*) (* SLEB128 constant *)
-("DW_OP_dup", natural_of_hex "0x12", [] , OpSem_stack (fun ac vs args -> (match vs with v::vs -> Some (v::(v::vs)) | _ -> None ))); (*0*)
-("DW_OP_drop", natural_of_hex "0x13", [] , OpSem_stack (fun ac vs args -> (match vs with v::vs -> Some vs | _ -> None ))); (*0*)
-("DW_OP_over", natural_of_hex "0x14", [] , OpSem_stack (fun ac vs args -> (match vs with v::v'::vs -> Some (v'::(v::(v'::vs))) | _ -> None ))); (*0*)
-("DW_OP_pick", natural_of_hex "0x15", [OAT_uint8] , OpSem_stack (fun ac vs args -> (match args with [OAV_natural n] -> (match index_natural vs n with Some v -> Some (v::vs) | None -> None ) | _ -> None ))); (*1*) (* 1-byte stack index *)
-("DW_OP_swap", natural_of_hex "0x16", [] , OpSem_stack (fun ac vs args -> (match vs with v::v'::vs -> Some (v'::(v::vs)) | _ -> None ))); (*0*)
-("DW_OP_rot", natural_of_hex "0x17", [] , OpSem_stack (fun ac vs args -> (match vs with v::v'::v''::vs -> Some (v'::(v''::(v::vs))) | _ -> None ))); (*0*)
-("DW_OP_xderef", natural_of_hex "0x18", [] , OpSem_not_supported); (*0*)
-("DW_OP_abs", natural_of_hex "0x19", [] , OpSem_unary (fun ac v -> if Nat_big_num.less v ac.ac_half then Some v else if Nat_big_num.equal v ac.ac_max then None else Some (Nat_big_num.sub_nat ac.ac_all v))); (*0*)
-("DW_OP_and", natural_of_hex "0x1a", [] , OpSem_binary (fun ac v1 v2 -> Some (Nat_big_num.bitwise_and v1 v2))); (*0*)
-("DW_OP_div", natural_of_hex "0x1b", [] , OpSem_not_supported) (*TODO*); (*0*)
-("DW_OP_minus", natural_of_hex "0x1c", [] , OpSem_binary (fun ac v1 v2 -> Some (partialNaturalFromInteger ( Nat_big_num.modulus( Nat_big_num.sub( v1) ( v2)) ( ac.ac_all))))); (*0*)
-("DW_OP_mod", natural_of_hex "0x1d", [] , OpSem_binary (fun ac v1 v2 -> Some ( Nat_big_num.modulus v1 v2))); (*0*)
-("DW_OP_mul", natural_of_hex "0x1e", [] , OpSem_binary (fun ac v1 v2 -> Some (partialNaturalFromInteger ( Nat_big_num.modulus( Nat_big_num.mul( v1) ( v2)) ( ac.ac_all))))); (*0*)
-("DW_OP_neg", natural_of_hex "0x1f", [] , OpSem_unary (fun ac v -> if Nat_big_num.less v ac.ac_half then Some ( Nat_big_num.sub_nat ac.ac_max v) else if Nat_big_num.equal v ac.ac_half then None else Some ( Nat_big_num.sub_nat ac.ac_all v))); (*0*)
-("DW_OP_not", natural_of_hex "0x20", [] , OpSem_unary (fun ac v -> Some (Nat_big_num.bitwise_xor v ac.ac_max))); (*0*)
-("DW_OP_or", natural_of_hex "0x21", [] , OpSem_binary (fun ac v1 v2 -> Some (Nat_big_num.bitwise_or v1 v2))); (*0*)
-("DW_OP_plus", natural_of_hex "0x22", [] , OpSem_binary (fun ac v1 v2 -> Some ( Nat_big_num.modulus( Nat_big_num.add v1 v2) ac.ac_all))); (*0*)
-("DW_OP_plus_uconst", natural_of_hex "0x23", [OAT_ULEB128] , OpSem_stack (fun ac vs args -> (match args with [OAV_natural n] -> (match vs with v::vs' -> let v' = (Nat_big_num.modulus (Nat_big_num.add v n) ac.ac_all) in Some (v'::vs) | [] -> None ) | _ -> None ))); (*1*) (* ULEB128 addend *)
-("DW_OP_shl", natural_of_hex "0x24", [] , OpSem_binary (fun ac v1 v2 -> if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some(Nat_big_num.of_int 0) else Some (Nat_big_num.shift_left v1 (Nat_big_num.to_int v2)))); (*0*)
-("DW_OP_shr", natural_of_hex "0x25", [] , OpSem_binary (fun ac v1 v2 -> if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some(Nat_big_num.of_int 0) else Some (Nat_big_num.shift_right v1 (Nat_big_num.to_int v2)))); (*0*)
-("DW_OP_shra", natural_of_hex "0x26", [] , OpSem_binary (fun ac v1 v2 -> if Nat_big_num.less v1 ac.ac_half then (if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some(Nat_big_num.of_int 0) else Some (Nat_big_num.shift_right v1 (Nat_big_num.to_int v2))) else (if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some ac.ac_max else Some ( Nat_big_num.sub_nat ac.ac_max (Nat_big_num.shift_right ( Nat_big_num.sub_nat ac.ac_max v1) (Nat_big_num.to_int v2)))))); (*0*)
-("DW_OP_xor", natural_of_hex "0x27", [] , OpSem_binary (fun ac v1 v2 -> Some (Nat_big_num.bitwise_xor v1 v2))); (*0*)
-("DW_OP_skip", natural_of_hex "0x2f", [OAT_sint16] , OpSem_not_supported); (*1*) (* signed 2-byte constant *)
-("DW_OP_bra", natural_of_hex "0x28", [OAT_sint16] , OpSem_not_supported); (*1*) (* signed 2-byte constant *)
-("DW_OP_eq", natural_of_hex "0x29", [] , OpSem_not_supported); (*0*)
-("DW_OP_ge", natural_of_hex "0x2a", [] , OpSem_not_supported); (*0*)
-("DW_OP_gt", natural_of_hex "0x2b", [] , OpSem_not_supported); (*0*)
-("DW_OP_le", natural_of_hex "0x2c", [] , OpSem_not_supported); (*0*)
-("DW_OP_lt", natural_of_hex "0x2d", [] , OpSem_not_supported); (*0*)
-("DW_OP_ne", natural_of_hex "0x2e", [] , OpSem_not_supported); (*0*)
-("DW_OP_lit0", natural_of_hex "0x30", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) (* literals 0..31 =(DW_OP_lit0 + literal) *)
-("DW_OP_lit1", natural_of_hex "0x31", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit2", natural_of_hex "0x32", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit3", natural_of_hex "0x33", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit4", natural_of_hex "0x34", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit5", natural_of_hex "0x35", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit6", natural_of_hex "0x36", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit7", natural_of_hex "0x37", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit8", natural_of_hex "0x38", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit9", natural_of_hex "0x39", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit10", natural_of_hex "0x3a", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit11", natural_of_hex "0x3b", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit12", natural_of_hex "0x3c", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit13", natural_of_hex "0x3d", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit14", natural_of_hex "0x3e", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit15", natural_of_hex "0x3f", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit16", natural_of_hex "0x40", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit17", natural_of_hex "0x41", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit18", natural_of_hex "0x42", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit19", natural_of_hex "0x43", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit20", natural_of_hex "0x44", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit21", natural_of_hex "0x45", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit22", natural_of_hex "0x46", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit23", natural_of_hex "0x47", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit24", natural_of_hex "0x48", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit25", natural_of_hex "0x49", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit26", natural_of_hex "0x4a", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit27", natural_of_hex "0x4b", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit28", natural_of_hex "0x4c", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit29", natural_of_hex "0x4d", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit30", natural_of_hex "0x4e", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_lit31", natural_of_hex "0x4f", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*)
-("DW_OP_reg0", natural_of_hex "0x50", [] , OpSem_reg); (*1*) (* reg 0..31 = (DW_OP_reg0 + regnum) *)
-("DW_OP_reg1", natural_of_hex "0x51", [] , OpSem_reg); (*1*)
-("DW_OP_reg2", natural_of_hex "0x52", [] , OpSem_reg); (*1*)
-("DW_OP_reg3", natural_of_hex "0x53", [] , OpSem_reg); (*1*)
-("DW_OP_reg4", natural_of_hex "0x54", [] , OpSem_reg); (*1*)
-("DW_OP_reg5", natural_of_hex "0x55", [] , OpSem_reg); (*1*)
-("DW_OP_reg6", natural_of_hex "0x56", [] , OpSem_reg); (*1*)
-("DW_OP_reg7", natural_of_hex "0x57", [] , OpSem_reg); (*1*)
-("DW_OP_reg8", natural_of_hex "0x58", [] , OpSem_reg); (*1*)
-("DW_OP_reg9", natural_of_hex "0x59", [] , OpSem_reg); (*1*)
-("DW_OP_reg10", natural_of_hex "0x5a", [] , OpSem_reg); (*1*)
-("DW_OP_reg11", natural_of_hex "0x5b", [] , OpSem_reg); (*1*)
-("DW_OP_reg12", natural_of_hex "0x5c", [] , OpSem_reg); (*1*)
-("DW_OP_reg13", natural_of_hex "0x5d", [] , OpSem_reg); (*1*)
-("DW_OP_reg14", natural_of_hex "0x5e", [] , OpSem_reg); (*1*)
-("DW_OP_reg15", natural_of_hex "0x5f", [] , OpSem_reg); (*1*)
-("DW_OP_reg16", natural_of_hex "0x60", [] , OpSem_reg); (*1*)
-("DW_OP_reg17", natural_of_hex "0x61", [] , OpSem_reg); (*1*)
-("DW_OP_reg18", natural_of_hex "0x62", [] , OpSem_reg); (*1*)
-("DW_OP_reg19", natural_of_hex "0x63", [] , OpSem_reg); (*1*)
-("DW_OP_reg20", natural_of_hex "0x64", [] , OpSem_reg); (*1*)
-("DW_OP_reg21", natural_of_hex "0x65", [] , OpSem_reg); (*1*)
-("DW_OP_reg22", natural_of_hex "0x66", [] , OpSem_reg); (*1*)
-("DW_OP_reg23", natural_of_hex "0x67", [] , OpSem_reg); (*1*)
-("DW_OP_reg24", natural_of_hex "0x68", [] , OpSem_reg); (*1*)
-("DW_OP_reg25", natural_of_hex "0x69", [] , OpSem_reg); (*1*)
-("DW_OP_reg26", natural_of_hex "0x6a", [] , OpSem_reg); (*1*)
-("DW_OP_reg27", natural_of_hex "0x6b", [] , OpSem_reg); (*1*)
-("DW_OP_reg28", natural_of_hex "0x6c", [] , OpSem_reg); (*1*)
-("DW_OP_reg29", natural_of_hex "0x6d", [] , OpSem_reg); (*1*)
-("DW_OP_reg30", natural_of_hex "0x6e", [] , OpSem_reg); (*1*)
-("DW_OP_reg31", natural_of_hex "0x6f", [] , OpSem_reg); (*1*)
-("DW_OP_breg0", natural_of_hex "0x70", [OAT_SLEB128] , OpSem_breg); (*1*) (* base register 0..31 = (DW_OP_breg0 + regnum) *)
-("DW_OP_breg1", natural_of_hex "0x71", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg2", natural_of_hex "0x72", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg3", natural_of_hex "0x73", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg4", natural_of_hex "0x74", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg5", natural_of_hex "0x75", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg6", natural_of_hex "0x76", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg7", natural_of_hex "0x77", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg8", natural_of_hex "0x78", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg9", natural_of_hex "0x79", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg10", natural_of_hex "0x7a", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg11", natural_of_hex "0x7b", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg12", natural_of_hex "0x7c", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg13", natural_of_hex "0x7d", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg14", natural_of_hex "0x7e", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg15", natural_of_hex "0x7f", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg16", natural_of_hex "0x80", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg17", natural_of_hex "0x81", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg18", natural_of_hex "0x82", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg19", natural_of_hex "0x83", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg20", natural_of_hex "0x84", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg21", natural_of_hex "0x85", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg22", natural_of_hex "0x86", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg23", natural_of_hex "0x87", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg24", natural_of_hex "0x88", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg25", natural_of_hex "0x89", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg26", natural_of_hex "0x8a", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg27", natural_of_hex "0x8b", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg28", natural_of_hex "0x8c", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg29", natural_of_hex "0x8d", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg30", natural_of_hex "0x8e", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_breg31", natural_of_hex "0x8f", [OAT_SLEB128] , OpSem_breg); (*1*)
-("DW_OP_regx", natural_of_hex "0x90", [OAT_ULEB128] , OpSem_lit); (*1*) (* ULEB128 register *)
-("DW_OP_fbreg", natural_of_hex "0x91", [OAT_SLEB128] , OpSem_fbreg); (*1*) (* SLEB128 offset *)
-("DW_OP_bregx", natural_of_hex "0x92", [OAT_ULEB128; OAT_SLEB128] , OpSem_bregx); (*2*) (* ULEB128 register followed by SLEB128 offset *)
-("DW_OP_piece", natural_of_hex "0x93", [OAT_ULEB128] , OpSem_piece); (*1*) (* ULEB128 size of piece addressed *)
-("DW_OP_deref_size", natural_of_hex "0x94", [OAT_uint8] , OpSem_deref_size); (*1*) (* 1-byte size of data retrieved *)
-("DW_OP_xderef_size", natural_of_hex "0x95", [OAT_uint8] , OpSem_not_supported); (*1*) (* 1-byte size of data retrieved *)
-("DW_OP_nop", natural_of_hex "0x96", [] , OpSem_nop); (*0*)
-("DW_OP_push_object_address", natural_of_hex "0x97", [] , OpSem_not_supported); (*0*)
-("DW_OP_call2", natural_of_hex "0x98", [OAT_uint16] , OpSem_not_supported); (*1*) (* 2-byte offset of DIE *)
-("DW_OP_call4", natural_of_hex "0x99", [OAT_uint32] , OpSem_not_supported); (*1*) (* 4-byte offset of DIE *)
-("DW_OP_call_ref", natural_of_hex "0x9a", [OAT_dwarf_format_t] , OpSem_not_supported); (*1*) (* 4- or 8-byte offset of DIE *)
-("DW_OP_form_tls_address", natural_of_hex "0x9b", [] , OpSem_not_supported); (*0*)
-("DW_OP_call_frame_cfa", natural_of_hex "0x9c", [] , OpSem_call_frame_cfa); (*0*)
-("DW_OP_bit_piece", natural_of_hex "0x9d", [OAT_ULEB128; OAT_ULEB128] , OpSem_bit_piece); (*2*) (* ULEB128 size followed by ULEB128 offset *)
-("DW_OP_implicit_value", natural_of_hex "0x9e", [OAT_block] , OpSem_implicit_value); (*2*) (* ULEB128 size followed by block of that size *)
-("DW_OP_stack_value", natural_of_hex "0x9f", [] , OpSem_stack_value); (*0*)
-(* these aren't real operations
-("DW_OP_lo_user", natural_of_hex "0xe0", [] , );
-("DW_OP_hi_user", natural_of_hex "0xff", [] , );
-*)
-
-(* GCC also produces these for our example:
-https://fedorahosted.org/elfutils/wiki/DwarfExtensions
-http://dwarfstd.org/ShowIssue.php?issue=100909.1 *)
-("DW_GNU_OP_entry_value", natural_of_hex "0xf3", [OAT_block], OpSem_not_supported); (*2*) (* ULEB128 size followed by DWARF expression block of that size*)
-("DW_OP_GNU_implicit_pointer", natural_of_hex "0xf2", [OAT_dwarf_format_t;OAT_SLEB128], OpSem_not_supported)
-
-])
-
-
-let vDW_OP_reg0:Nat_big_num.num= (natural_of_hex "0x50")
-let vDW_OP_breg0:Nat_big_num.num= (natural_of_hex "0x70")
-
-
-(* call frame instruction encoding *)
-
-let call_frame_instruction_encoding : (string * Nat_big_num.num * Nat_big_num.num * call_frame_argument_type list * (( call_frame_argument_value list) -> call_frame_instruction option)) list= ([
-(* high-order 2 bits low-order 6 bits uniformly parsed arguments *)
-
-(* instructions using low-order 6 bits for first argument *)
-(*
-("DW_CFA_advance_loc", 1, 0,(*delta *) []);
-("DW_CFA_offset", 2, 0,(*register*) [CFAT_offset]);
-("DW_CFA_restore", 3, 0,(*register*) []);
-*)
-(* instructions using low-order 6 bits as part of opcode *)
-("DW_CFA_nop",Nat_big_num.of_int 0, natural_of_hex "0x00", [],
-( (* *)fun avs -> (match avs with [] -> Some (DW_CFA_nop) | _ -> None )));
-("DW_CFA_set_loc",Nat_big_num.of_int 0, natural_of_hex "0x01", [CFAT_address],
-( (* address *)fun avs -> (match avs with [CFAV_address a] -> Some (DW_CFA_set_loc a) | _ -> None )));
-("DW_CFA_advance_loc1",Nat_big_num.of_int 0, natural_of_hex "0x02", [CFAT_delta1],
-( (* 1-byte delta *)fun avs -> (match avs with [CFAV_delta d] -> Some (DW_CFA_advance_loc1 d) | _ -> None )));
-("DW_CFA_advance_loc2",Nat_big_num.of_int 0, natural_of_hex "0x03", [CFAT_delta2],
-( (* 2-byte delta *)fun avs -> (match avs with [CFAV_delta d] -> Some (DW_CFA_advance_loc2 d) | _ -> None )));
-("DW_CFA_advance_loc4",Nat_big_num.of_int 0, natural_of_hex "0x04", [CFAT_delta4],
-( (* 4-byte delta *)fun avs -> (match avs with [CFAV_delta d] -> Some (DW_CFA_advance_loc4 d) | _ -> None )));
-("DW_CFA_offset_extended",Nat_big_num.of_int 0, natural_of_hex "0x05", [CFAT_register; CFAT_offset],
-( (* ULEB128 register ULEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_offset n] -> Some (DW_CFA_offset_extended( r, n)) | _ -> None )));
-("DW_CFA_restore_extended",Nat_big_num.of_int 0, natural_of_hex "0x06", [CFAT_register],
-( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_restore_extended r) | _ -> None )));
-("DW_CFA_undefined",Nat_big_num.of_int 0, natural_of_hex "0x07", [CFAT_register],
-( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_undefined r) | _ -> None )));
-("DW_CFA_same_value",Nat_big_num.of_int 0, natural_of_hex "0x08", [CFAT_register],
-( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_same_value r) | _ -> None )));
-("DW_CFA_register",Nat_big_num.of_int 0, natural_of_hex "0x09", [CFAT_register; CFAT_register],
-( (* ULEB128 register ULEB128 register *)fun avs -> (match avs with [CFAV_register r1; CFAV_register r2] -> Some (DW_CFA_register( r1, r2)) | _ -> None )));
-("DW_CFA_remember_state",Nat_big_num.of_int 0, natural_of_hex "0x0a", [],
-( (* *)fun avs -> (match avs with [] -> Some (DW_CFA_remember_state) | _ -> None )));
-("DW_CFA_restore_state",Nat_big_num.of_int 0, natural_of_hex "0x0b", [],
-( (* *)fun avs -> (match avs with [] -> Some (DW_CFA_restore_state) | _ -> None )));
-("DW_CFA_def_cfa",Nat_big_num.of_int 0, natural_of_hex "0x0c", [CFAT_register; CFAT_offset],
-( (* ULEB128 register ULEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_offset n] -> Some (DW_CFA_def_cfa( r, n)) | _ -> None )));
-("DW_CFA_def_cfa_register",Nat_big_num.of_int 0, natural_of_hex "0x0d", [CFAT_register],
-( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_def_cfa_register r) | _ -> None )));
-("DW_CFA_def_cfa_offset",Nat_big_num.of_int 0, natural_of_hex "0x0e", [CFAT_offset],
-( (* ULEB128 offset *)fun avs -> (match avs with [CFAV_offset n] -> Some (DW_CFA_def_cfa_offset n) | _ -> None )));
-("DW_CFA_def_cfa_expression",Nat_big_num.of_int 0, natural_of_hex "0x0f", [CFAT_block],
-( (* BLOCK *)fun avs -> (match avs with [CFAV_block b] -> Some (DW_CFA_def_cfa_expression b) | _ -> None )));
-("DW_CFA_expression",Nat_big_num.of_int 0, natural_of_hex "0x10", [CFAT_register; CFAT_block],
-( (* ULEB128 register BLOCK *)fun avs -> (match avs with [CFAV_register r; CFAV_block b] -> Some (DW_CFA_expression( r, b)) | _ -> None )));
-("DW_CFA_offset_extended_sf",Nat_big_num.of_int 0, natural_of_hex "0x11", [CFAT_register; CFAT_sfoffset],
-( (* ULEB128 register SLEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_sfoffset i] -> Some (DW_CFA_offset_extended_sf( r, i)) | _ -> None )));
-("DW_CFA_def_cfa_sf",Nat_big_num.of_int 0, natural_of_hex "0x12", [CFAT_register; CFAT_sfoffset],
-( (* ULEB128 register SLEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_sfoffset i] -> Some (DW_CFA_def_cfa_sf( r, i)) | _ -> None )));
-("DW_CFA_def_cfa_offset_sf",Nat_big_num.of_int 0, natural_of_hex "0x13", [CFAT_sfoffset],
-( (* SLEB128 offset *)fun avs -> (match avs with [CFAV_sfoffset i] -> Some (DW_CFA_def_cfa_offset_sf i) | _ -> None )));
-("DW_CFA_val_offset",Nat_big_num.of_int 0, natural_of_hex "0x14", [CFAT_register; CFAT_offset],
-( (* ULEB128 ULEB128 *)fun avs -> (match avs with [CFAV_register r; CFAV_offset n] -> Some (DW_CFA_val_offset( r, n)) | _ -> None )));
-("DW_CFA_val_offset_sf",Nat_big_num.of_int 0, natural_of_hex "0x15", [CFAT_register; CFAT_sfoffset],
-( (* ULEB128 SLEB128 *)fun avs -> (match avs with [CFAV_register r; CFAV_sfoffset i] -> Some (DW_CFA_val_offset_sf( r, i)) | _ -> None )));
-("DW_CFA_val_expression",Nat_big_num.of_int 0, natural_of_hex "0x16", [CFAT_register; CFAT_block],
-( (* ULEB128 BLOCK *)fun avs -> (match avs with [CFAV_register r; CFAV_block b] -> Some (DW_CFA_val_expression( r, b)) | _ -> None )))
-])
-
-(*
-("DW_CFA_lo_user", 0, natural_of_hex "0x1c", []); (* *)
-("DW_CFA_hi_user", 0, natural_of_hex "0x3f", []); (* *)
-*)
-
-
-(* line number encodings *)
-
-let line_number_standard_encodings:(string*Nat_big_num.num*(line_number_argument_type)list*((line_number_argument_value)list ->(line_number_operation)option))list= ([
- ("DW_LNS_copy" , natural_of_hex "0x01", [ ],
- (fun lnvs -> (match lnvs with [] -> Some DW_LNS_copy | _ -> None )));
- ("DW_LNS_advance_pc" , natural_of_hex "0x02", [LNAT_ULEB128 ],
- (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_advance_pc n) | _ -> None )));
- ("DW_LNS_advance_line" , natural_of_hex "0x03", [LNAT_SLEB128 ],
- (fun lnvs -> (match lnvs with [LNAV_SLEB128 i] -> Some (DW_LNS_advance_line i) | _ -> None )));
- ("DW_LNS_set_file" , natural_of_hex "0x04", [LNAT_ULEB128 ],
- (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_set_file n) | _ -> None )));
- ("DW_LNS_set_column" , natural_of_hex "0x05", [LNAT_ULEB128 ],
- (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_set_column n) | _ -> None )));
- ("DW_LNS_negate_stmt" , natural_of_hex "0x06", [ ],
- (fun lnvs -> (match lnvs with [] -> Some (DW_LNS_negate_stmt) | _ -> None )));
- ("DW_LNS_set_basic_block" , natural_of_hex "0x07", [ ],
- (fun lnvs -> (match lnvs with [] -> Some (DW_LNS_set_basic_block) | _ -> None )));
- ("DW_LNS_const_add_pc" , natural_of_hex "0x08", [ ],
- (fun lnvs -> (match lnvs with [] -> Some (DW_LNS_const_add_pc) | _ -> None )));
- ("DW_LNS_fixed_advance_pc" , natural_of_hex "0x09", [LNAT_uint16 ],
- (fun lnvs -> (match lnvs with [LNAV_uint16 n] -> Some (DW_LNS_fixed_advance_pc n) | _ -> None )));
- ("DW_LNS_set_prologue_end" , natural_of_hex "0x0a", [ ],
-(fun lnvs -> (match lnvs with [] -> Some (DW_LNS_set_prologue_end) | _ -> None )));
- ("DW_LNS_set_epilogue_begin" , natural_of_hex "0x0b", [ ],
-(fun lnvs -> (match lnvs with [] -> Some (DW_LNS_set_epilogue_begin) | _ -> None )));
- ("DW_LNS_set_isa" , natural_of_hex "0x0c", [LNAT_ULEB128 ],
- (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_set_isa n) | _ -> None )))
-])
-
-let line_number_extended_encodings:(string*Nat_big_num.num*(line_number_argument_type)list*((line_number_argument_value)list ->(line_number_operation)option))list= ([
- ("DW_LNE_end_sequence" , natural_of_hex "0x01", [],
- (fun lnvs -> (match lnvs with [] -> Some (DW_LNE_end_sequence) | _ -> None )));
- ("DW_LNE_set_address" , natural_of_hex "0x02", [LNAT_address],
- (fun lnvs -> (match lnvs with [LNAV_address n] -> Some (DW_LNE_set_address n) | _ -> None )));
- ("DW_LNE_define_file" , natural_of_hex "0x03", [LNAT_string; LNAT_ULEB128; LNAT_ULEB128; LNAT_ULEB128],
- (fun lnvs -> (match lnvs with [LNAV_string s; LNAV_ULEB128 n1; LNAV_ULEB128 n2; LNAV_ULEB128 n3] -> Some (DW_LNE_define_file( s, n1, n2, n3)) | _ -> None )));
- ("DW_LNE_set_discriminator" , natural_of_hex "0x04", [LNAT_ULEB128],
- (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNE_set_discriminator n) | _ -> None ))) (* new in Dwarf 4*)
-])
-
-
-(*
-(DW_LNE_lo_user , natural_of_hex "0x80", "DW_LNE_lo_user");
-(DW_LNE_hi_user , natural_of_hex "0xff", "DW_LNE_hi_user");
-*)
-
-
-
-(* booleans encoded as a single byte containing the value 0 for “false,” and a non-zero value for “true.” *)
-
-
-(** ************************************************************ *)
-(** ** more missing pervasives and bits *********************** *)
-(** ************************************************************ *)
-
-
-(* quick hacky workaround: this is in String.lem, in src_lem_library, but the linker doesn't find it *)
-(*val myconcat : string -> list string -> string*)
-let rec myconcat sep ss:string=
- ((match ss with
- | [] -> ""
- | s :: ss' ->
- (match ss' with
- | [] -> s
- | _ -> s ^ (sep ^ myconcat sep ss')
- )
- ))
-
-(*val myhead : forall 'a. list 'a -> 'a*)
-let myhead l:'a= ((match l with | x::xs -> x | [] -> failwith "myhead of empty list" ))
-
-
-(*val myfindNonPure : forall 'a. ('a -> bool) -> list 'a -> 'a*)
-let myfindNonPure p0 l:'a= ((match (Lem_list.list_find_opt p0 l) with
- | Some e -> e
- | None -> failwith "myfindNonPure"
-))
-
-(*val myfindmaybe : forall 'a 'b. ('a -> maybe 'b) -> list 'a -> maybe 'b*)
-let rec myfindmaybe f xs:'b option=
- ((match xs with
- | [] -> None
- | x::xs' -> (match f x with Some y -> Some y | None -> myfindmaybe f xs' )
- ))
-
-(*val myfind : forall 'a. ('a -> bool) -> list 'a -> maybe 'a*)
-let rec myfind f xs:'a option=
- ((match xs with
- | [] -> None
- | x::xs' -> (match f x with true -> Some x | false -> myfind f xs' )
- ))
-
-(*val myfiltermaybe : forall 'a 'b. ('a -> maybe 'b) -> list 'a -> list 'b*)
-let rec myfiltermaybe f xs:'b list=
- ((match xs with
- | [] -> []
- | x::xs' -> (match f x with Some y -> y::myfiltermaybe f xs'| None -> myfiltermaybe f xs' )
- ))
-
-
-
-(*val bytes_of_natural: endianness -> natural (*size*) -> natural (*value*) -> list byte*)
-let bytes_of_natural en size2 n:(char)list=
- (if Nat_big_num.equal size2(Nat_big_num.of_int 8) then
- bytes_of_elf64_xword en (Uint64.of_string (Nat_big_num.to_string n))
- else if Nat_big_num.equal size2(Nat_big_num.of_int 4) then
- bytes_of_elf32_word en (Uint32.of_string (Nat_big_num.to_string n))
- else
- failwith "bytes_of_natural given size that is not 4 or 8")
-
-(* TODO: generalise *)
-(*val natural_of_bytes: endianness -> list byte -> natural*)
-let natural_of_bytes en bs:Nat_big_num.num=
- ((match bs with
- | b0::b1::b2::b3::b4::b5::b6::b7::[] ->
- let v = (if en=Little then
- Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
- (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b4)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b7))))
- else
- Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
-(natural_of_byte b7)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b4))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0)))))
- in
- v
- | b0::b1::b2::b3::[] ->
- let v = (if en=Little then Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
- (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3))
- else Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
-(natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0)))
-
- in
- v
- | b0::b1::[] ->
- let v = (if en=Little then Nat_big_num.add
- (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1))
- else Nat_big_num.add
-(natural_of_byte b1)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b0)))
-
- in
- v
- | b0::[] ->
- natural_of_byte b0
- | _ -> failwith "natural_of_bytes given not-8/4/2/1 bytes"
- ))
-
-
-(*val bigunionListMap : forall 'a 'b. SetType 'b => ('a -> set 'b) -> list 'a -> set 'b*)
-let rec bigunionListMap dict_Basic_classes_SetType_b f xs:'b Pset.set=
- ((match xs with
- | [] ->(Pset.from_list
- dict_Basic_classes_SetType_b.setElemCompare_method [])
- | x::xs' -> Pset.(union) (f x) (bigunionListMap
- dict_Basic_classes_SetType_b f xs')
- ))
-
-let rec mytake' (n:Nat_big_num.num) acc xs:('a list*'a list)option=
- (
- if(Nat_big_num.equal n (Nat_big_num.of_int 0)) then
- (Some (List.rev acc, xs)) else
- ((match xs with
- [] -> None
- | x::xs' -> mytake' (Nat_big_num.sub_nat n (Nat_big_num.of_int 1))
- (x :: acc) xs'
- )))
-
-(*val mytake : forall 'a. natural -> (list 'a) -> maybe (list 'a * list 'a)*)
-let mytake n xs:('a list*'a list)option= (mytake' n [] xs)
-
-(*val mynth : forall 'a. natural -> (list 'a) -> maybe 'a*)
-let rec mynth (n:Nat_big_num.num) xs:'a option=
- ( (*Assert_extra.failwith "mynth"*)
- if(Nat_big_num.equal n (Nat_big_num.of_int 0)) then
- ((match xs with x::xs' -> Some x | [] -> None )) else
- ((match xs with
- x::xs' -> mynth (Nat_big_num.sub_nat n (Nat_big_num.of_int 1)) xs'
- )))
-
-
-(** basic pretty printing *)
-
-let pphex n:string= ("0x" ^ unsafe_hex_string_of_natural( 0) n)
-
-let ppbytes dict_Show_Show_a xs:string= (string_of_list
- instance_Show_Show_string_dict (Lem_list.map (fun x ->
- dict_Show_Show_a.show_method x) xs))
-
-let rec ppbytes2 dict_Show_Show_a n xs:string= ((match xs with | [] -> "" | x::xs' -> "<"^(pphex n^("> "^(
- dict_Show_Show_a.show_method x^("\n"^ppbytes2 dict_Show_Show_a (Nat_big_num.add n(Nat_big_num.of_int 1)) xs')))) ))
-
-(* workaround: from String *)
-(*val mytoString : list char -> string*)
-
-let string_of_bytes bs:string= (Xstring.implode (Lem_list.map (fun x-> x) bs))
-
-
-let just_one s xs:'a=
- ((match xs with
- | [] -> failwith ("no " ^ s)
- | x1::x2::_ -> failwith ("more than one " ^ s)
- | [x] -> x
- ))
-
-
-
-
-let max_address (as': Nat_big_num.num) : Nat_big_num.num=
- (
- if(Nat_big_num.equal as' (Nat_big_num.of_int 4)) then
- (natural_of_hex "0xffffffff") else
- (
- if(Nat_big_num.equal as' (Nat_big_num.of_int 8)) then
- (natural_of_hex "0xffffffffffffffff") else
- (failwith "max_address size not 4 or 8")))
-
-
-(** lookup of encodings *)
-
-(*val lookup_Ab_b : forall 'a 'b. Eq 'a => 'a -> list ('a * 'b) -> maybe 'b*)
-let rec lookup_Ab_b dict_Basic_classes_Eq_a x0 xys:'b option=
- ((match xys with
- | [] -> None
- | (x,y)::xys' -> if
- dict_Basic_classes_Eq_a.isEqual_method x x0 then Some y else lookup_Ab_b
- dict_Basic_classes_Eq_a x0 xys'
- ))
-
-(*val lookup_aB_a : forall 'a 'b. Eq 'b => 'b -> list ('a * 'b) -> maybe 'a*)
-let rec lookup_aB_a dict_Basic_classes_Eq_b y0 xys:'a option=
- ((match xys with
- | [] -> None
- | (x,y)::xys' -> if
- dict_Basic_classes_Eq_b.isEqual_method y y0 then Some x else lookup_aB_a
- dict_Basic_classes_Eq_b y0 xys'
- ))
-
-
-(*val lookup_aBc_a : forall 'a 'b 'c. Eq 'b => 'b -> list ('a * 'b * 'c) -> maybe 'a*)
-let rec lookup_aBc_a dict_Basic_classes_Eq_b y0 xyzs:'a option=
- ((match xyzs with
- | [] -> None
- | (x,y,_)::xyzs' -> if
- dict_Basic_classes_Eq_b.isEqual_method y y0 then Some x else lookup_aBc_a
- dict_Basic_classes_Eq_b y0 xyzs'
- ))
-
-(*val lookup_aBc_ac : forall 'a 'b 'c. Eq 'b => 'b -> list ('a * 'b * 'c) -> maybe ('a*'c)*)
-let rec lookup_aBc_ac dict_Basic_classes_Eq_b y0 xyzs:('a*'c)option=
- ((match xyzs with
- | [] -> None
- | (x,y,z)::xyzs' -> if
- dict_Basic_classes_Eq_b.isEqual_method y y0 then Some (x,z) else lookup_aBc_ac
- dict_Basic_classes_Eq_b y0 xyzs'
- ))
-
-(*val lookup_Abc_b : forall 'a 'b 'c. Eq 'a => 'a -> list ('a * 'b * 'c) -> maybe 'b*)
-let rec lookup_Abc_b dict_Basic_classes_Eq_a x0 xyzs:'b option=
- ((match xyzs with
- | [] -> None
- | (x,y,_)::xyzs' -> if
- dict_Basic_classes_Eq_a.isEqual_method x x0 then Some y else lookup_Abc_b
- dict_Basic_classes_Eq_a x0 xyzs'
- ))
-
-
-
-(*val lookup_aBcd_a : forall 'a 'b 'c 'd. Eq 'b => 'b -> list ('a * 'b * 'c * 'd) -> maybe 'a*)
-let rec lookup_aBcd_a dict_Basic_classes_Eq_b y0 xyzws:'a option=
- ((match xyzws with
- | [] -> None
- | (x,y,_,_)::xyzws' -> if
- dict_Basic_classes_Eq_b.isEqual_method y y0 then Some x else lookup_aBcd_a
- dict_Basic_classes_Eq_b y0 xyzws'
- ))
-
-(*val lookup_aBcd_acd : forall 'a 'b 'c 'd. Eq 'b => 'b -> list ('a * 'b * 'c * 'd) -> maybe ('a * 'c * 'd)*)
-let rec lookup_aBcd_acd dict_Basic_classes_Eq_b y0 xyzws:('a*'c*'d)option=
- ((match xyzws with
- | [] -> None
- | (x,y,z,w)::xyzws' -> if
- dict_Basic_classes_Eq_b.isEqual_method y y0 then Some (x,z,w) else lookup_aBcd_acd
- dict_Basic_classes_Eq_b y0 xyzws'
- ))
-
-(*val lookup_abCde_de : forall 'a 'b 'c 'd 'e. Eq 'c => 'c -> list ('a * 'b * 'c * 'd * 'e) -> maybe ('d * 'e)*)
-let rec lookup_abCde_de dict_Basic_classes_Eq_c z0 xyzwus:('d*'e)option=
- ((match xyzwus with
- | [] -> None
- | (x,y,z,w,u)::xyzwus' -> if
- dict_Basic_classes_Eq_c.isEqual_method z z0 then Some (w,u) else lookup_abCde_de
- dict_Basic_classes_Eq_c z0 xyzwus'
- ))
-
-
-let pp_maybe ppf n:string= ((match ppf n with Some s -> s | None -> "encoding not found: " ^ pphex n ))
-
-let pp_tag_encoding n:string= (pp_maybe (fun n -> lookup_aB_a
- instance_Basic_classes_Eq_Num_natural_dict n tag_encodings) n)
-let pp_attribute_encoding n:string= (pp_maybe (fun n -> lookup_aBc_a
- instance_Basic_classes_Eq_Num_natural_dict n attribute_encodings) n)
-let pp_attribute_form_encoding n:string= (pp_maybe (fun n -> lookup_aBc_a
- instance_Basic_classes_Eq_Num_natural_dict n attribute_form_encodings) n)
-let pp_operation_encoding n:string= (pp_maybe (fun n -> lookup_aBcd_a
- instance_Basic_classes_Eq_Num_natural_dict n operation_encodings) n)
-
-let tag_encode (s: string) : Nat_big_num.num=
- ((match lookup_Ab_b
- instance_Basic_classes_Eq_string_dict s tag_encodings with
- | Some n -> n
- | None -> failwith "attribute_encode"
- ))
-
-
-let attribute_encode (s: string) : Nat_big_num.num=
- ((match lookup_Abc_b
- instance_Basic_classes_Eq_string_dict s attribute_encodings with
- | Some n -> n
- | None -> failwith "attribute_encode"
- ))
-
-let attribute_form_encode (s: string) : Nat_big_num.num=
- ((match lookup_Abc_b
- instance_Basic_classes_Eq_string_dict s attribute_form_encodings with
- | Some n -> n
- | None -> failwith "attribute_form_encode"
- ))
-
-
-
-(** ************************************************************ *)
-(** ** parser combinators and primitives ********************* *)
-(** ************************************************************ *)
-
-(* parsing combinators *)
-
-type parse_context = { pc_bytes: char list; pc_offset: Nat_big_num.num }
-
-type 'a parse_result =
- | PR_success of 'a * parse_context
- | PR_fail of string * parse_context
-
-type 'a parser = parse_context -> 'a parse_result
-
-let pp_parse_context pc:string= ("pc_offset = " ^ pphex pc.pc_offset)
-
-let pp_parse_fail s pc:string=
- ("Parse fail\n" ^ (s ^ (" at " ^ (pp_parse_context pc ^ "\n"))))
-
-let pp_parse_result ppa pr:string=
- ((match pr with
- | PR_success( x, pc) -> "Parse success\n" ^ (ppa x ^ ("\n" ^ (pp_parse_context pc ^ "\n")))
- | PR_fail( s, pc) -> pp_parse_fail s pc
- ))
-
-(* [(>>=)] should be the monadic binding function for [parse_result]. *)
-(* but there's a type clash if we use >>=, and lem seems to output bad ocaml for >>>=. So we just use a non-infix version for now *)
-
-(*val pr_bind : forall 'a 'b. parse_result 'a -> ('a -> parser 'b) -> parse_result 'b*)
-let pr_bind x f:'b parse_result=
- ((match x with
- | PR_success( v, pc) -> f v pc
- | PR_fail( err, pc) -> PR_fail( err, pc)
- ))
-
-(*val pr_return : forall 'a. 'a -> (parser 'a)*)
-let pr_return x pc:'a parse_result= (PR_success( x, pc))
-
-(*val pr_map : forall 'a 'b. ('a -> 'b) -> parse_result 'a -> parse_result 'b*)
-let pr_map f x:'b parse_result=
- ((match x with
- | PR_success( v, pc) -> PR_success( (f v), pc)
- | PR_fail( err, pc) -> PR_fail( err, pc)
- ))
-
-(*val pr_map2 : forall 'a 'b. ('a -> 'b) -> (parser 'a) -> (parser 'b)*)
-let pr_map2 f p:parse_context ->'b parse_result= (fun pc -> pr_map f (p pc))
-
-(*val pr_post_map1 : forall 'a 'b. (parse_result 'a) -> ('a -> 'b) -> (parse_result 'b)*)
-let pr_post_map1 x f:'b parse_result= (pr_map f x)
-
-(*
-val pr_post_map : forall 'a 'b 'c. ('c -> parse_result 'a) -> ('a -> 'b) -> ('c -> parse_result 'b)
-let pr_post_map g f = fun x -> pr_map f (g x)
-*)
-(*val pr_post_map : forall 'a 'b. (parser 'a) -> ('a -> 'b) -> (parser 'b)*)
-let pr_post_map p f:parse_context ->'b parse_result= (fun (pc: parse_context) -> pr_map f (p pc))
-
-
-(*val pr_with_pos : forall 'a. (parser 'a) -> (parser (natural * 'a))*)
-let pr_with_pos p:parse_context ->(Nat_big_num.num*'a)parse_result= (fun pc -> pr_map (fun x -> (pc.pc_offset,x)) (p pc))
-
-
-(*val parse_pair : forall 'a 'b. (parser 'a) -> (parser 'b) -> (parser ('a * 'b))*)
-let parse_pair p1 p2:parse_context ->('a*'b)parse_result=
- (fun pc ->
- let _ = (my_debug "pair ") in
- pr_bind (p1 pc) (fun x pc' -> (match p2 pc' with
- | PR_success( y, pc'') -> PR_success( (x,y), pc'')
- | PR_fail( s, pc'') -> PR_fail( s, pc'')
- )))
-
-(*val parse_triple : forall 'a 'b 'c. (parser 'a) -> (parser 'b) -> (parser 'c) -> parser ('a * ('b * 'c))*)
-let parse_triple p1 p2 p3:parse_context ->('a*('b*'c))parse_result=
- (parse_pair p1 (parse_pair p2 p3))
-
-(*val parse_quadruple : forall 'a 'b 'c 'd. (parser 'a) -> (parser 'b) -> (parser 'c) -> (parser 'd) -> parser ('a * ('b * ('c * 'd)))*)
-let parse_quadruple p1 p2 p3 p4:parse_context ->('a*('b*('c*'d)))parse_result=
- (parse_pair p1 (parse_pair p2 (parse_pair p3 p4)))
-
-(*val parse_pentuple : forall 'a 'b 'c 'd 'e. (parser 'a) -> (parser 'b) -> (parser 'c) -> (parser 'd) -> (parser 'e) -> parser ('a * ('b * ('c * ('d * 'e))))*)
-let parse_pentuple p1 p2 p3 p4 p5:parse_context ->('a*('b*('c*('d*'e))))parse_result=
- (parse_pair p1 (parse_pair p2 (parse_pair p3 (parse_pair p4 p5))))
-
-(*val parse_sextuple : forall 'a 'b 'c 'd 'e 'f. (parser 'a) -> (parser 'b) -> (parser 'c) -> (parser 'd) -> (parser 'e) -> (parser 'f) -> parser ('a * ('b * ('c * ('d * ('e * 'f)))))*)
-let parse_sextuple p1 p2 p3 p4 p5 p6:parse_context ->('a*('b*('c*('d*('e*'f)))))parse_result=
- (parse_pair p1 (parse_pair p2 (parse_pair p3 (parse_pair p4 (parse_pair p5 p6)))))
-
-(*val parse_dependent_pair : forall 'a 'b. (parser 'a) -> ('a -> parser 'b) -> (parser ('a * 'b))*)
-let parse_dependent_pair p1 p2:parse_context ->('a*'b)parse_result=
- (fun pc ->
- pr_bind (p1 pc) (fun x pc' -> (match p2 x pc' with
- | PR_success( y, pc'') -> PR_success( (x,y), pc'')
- | PR_fail( s, pc'') -> PR_fail( s, pc'')
- )))
-
-(*val parse_dependent : forall 'a 'b. (parser 'a) -> ('a -> parser 'b) -> (parser 'b)*)
-let parse_dependent p1 p2:parse_context ->'b parse_result=
- (fun pc ->
- pr_bind (p1 pc) (fun x pc' -> p2 x pc'))
-
-
-
-(*val parse_list' : forall 'a. (parser (maybe 'a)) -> (list 'a -> parser (list 'a))*)
-let rec parse_list' p1:'a list ->parse_context ->('a list)parse_result=
- (fun acc pc -> let _ = (my_debug "list' ") in pr_bind (p1 pc) (fun mx pc' ->
- (match mx with
- | None -> PR_success( acc, pc')
- | Some x -> parse_list' p1 (x :: acc) pc'
- )))
-
-(*val parse_list : forall 'a. (parser (maybe 'a)) -> (parser (list 'a))*)
-let parse_list p1:parse_context ->('a list)parse_result=
- (pr_post_map
- (parse_list' p1 [])
- (List.rev))
-
-(*val parse_parser_list : forall 'a. (list (parser 'a)) -> (parser (list 'a))*)
-let rec parse_parser_list ps:parse_context ->('a list)parse_result=
- ((match ps with
- | [] -> pr_return []
- | p::ps' ->
- (fun pc -> pr_bind (p pc) (fun x pc' ->
- (match parse_parser_list ps' pc' with
- | PR_success( xs, pc'') -> PR_success( (x::xs), pc'')
- | PR_fail( s, pc'') -> PR_fail( s, pc'')
- )))
- ))
-
-(*val parse_maybe : forall 'a. parser 'a -> parser (maybe 'a)*)
-let parse_maybe p:parse_context ->('a option)parse_result=
- (fun pc ->
- (match pc.pc_bytes with
- | [] -> pr_return None pc
- | _ ->
- (match p pc with
- | PR_success( v, pc'') -> PR_success( (Some v), pc'')
- | PR_fail( s, pc'') -> PR_fail( s, pc'')
- )
- ))
-
-(*val parse_demaybe : forall 'a. string ->parser (maybe 'a) -> parser 'a*)
-let parse_demaybe s p:parse_context ->'a parse_result=
- (fun pc ->
- (match p pc with
- | PR_success( (Some v), pc'') -> PR_success( v, pc'')
- | PR_success( (None), pc'') -> PR_fail( s, pc'')
- | PR_fail( s, pc'') -> PR_fail( s, pc'')
-
- ))
-
-
-(*val parse_restrict_length : forall 'a. natural -> parser 'a -> parser 'a*)
-let parse_restrict_length n p:parse_context ->'a parse_result=
- (fun pc ->
- (match mytake n pc.pc_bytes with
- | None -> failwith "parse_restrict_length not given enough bytes"
- | Some (xs,ys) ->
- let pc' = ({ pc_bytes = xs; pc_offset = (pc.pc_offset) }) in
- p pc'
- ))
-
-
-(* parsing of basic types *)
-
-
-let parse_n_bytes (n:Nat_big_num.num) : ( char list) parser=
- (fun (pc:parse_context) ->
- (match mytake n pc.pc_bytes with
- | None -> PR_fail( ("parse_n_bytes n=" ^ pphex n), pc)
- | Some (xs,bs) -> PR_success( xs, ({pc_bytes=bs; pc_offset= (Nat_big_num.add pc.pc_offset (Nat_big_num.of_int (List.length xs))) } ))
- ))
-
-let rec mytakestring' acc xs:((char)list*(char)list)option=
- ((match xs with
- | [] -> None
- | x::xs' -> if Nat_big_num.equal (natural_of_byte x)(Nat_big_num.of_int 0) then Some (List.rev acc, xs') else mytakestring' (x::acc) xs'
- ))
-
-let parse_string : ( char list) parser=
- (fun (pc:parse_context) ->
- (match mytakestring' [] pc.pc_bytes with
- | None -> PR_fail( "parse_string", pc)
- | Some (xs,bs) -> PR_success( xs, ({pc_bytes=bs; pc_offset = (Nat_big_num.add (Nat_big_num.add pc.pc_offset (Nat_big_num.of_int (List.length xs))) (Nat_big_num.of_int( 1))) } ))
- ))
-
-(* parse a null-terminated string; return Nothing if it is empty, Just s otherwise *)
-let parse_non_empty_string : ( ( char list)option) parser=
- (fun (pc:parse_context) ->
- (match mytakestring' [] pc.pc_bytes with
- | None -> PR_fail( "parse_string", pc)
- | Some (xs,bs) ->
- (*let _ = my_debug5 ("**" ^string_of_bytes xs ^ "**\n") in *)
- let pc' = ({pc_bytes=bs; pc_offset = (Nat_big_num.add (Nat_big_num.add pc.pc_offset (Nat_big_num.of_int (List.length xs))) (Nat_big_num.of_int( 1))) } ) in
- if (listEqualBy (=) xs []) then PR_success( (None), pc')
- else PR_success( (Some xs), pc')
- ))
-
-
-let parse_uint8 : Nat_big_num.num parser=
- (fun (pc:parse_context) ->
- let _ = (my_debug "uint8 ") in
- (match pc.pc_bytes with
- | b0::bytes' ->
- let v = (natural_of_byte b0) in
- PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) }))
- | _ -> PR_fail( "parse_uint32 not given enough bytes", pc)
- ))
-
-let parse_uint16 c : Nat_big_num.num parser=
- (fun (pc:parse_context) ->
- let _ = (my_debug "uint16 ") in
- (match pc.pc_bytes with
- | b0::b1::bytes' ->
- let v = (if c.endianness=Little then Nat_big_num.add
- (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1))
- else Nat_big_num.add
- (natural_of_byte b1)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b0))) in
- PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 2)) }))
- | _ -> PR_fail( "parse_uint32 not given enough bytes", pc)
- ))
-
-let parse_uint32 c : Nat_big_num.num parser=
- (fun (pc:parse_context) ->
- let _ = (my_debug "uint32 ") in
- (match pc.pc_bytes with
- | b0::b1::b2::b3::bytes' ->
- let v = (if c.endianness=Little then Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
- (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3))
- else Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
- (natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0))) in
- PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 4)) }))
- | _ -> PR_fail( "parse_uint32 not given enough bytes", pc)
- ))
-
-let parse_uint64 c : Nat_big_num.num parser=
- (fun (pc:parse_context) ->
- let _ = (my_debug "uint64 ") in
- (match pc.pc_bytes with
- | b0::b1::b2::b3::b4::b5::b6::b7::bytes' ->
- let v = (if c.endianness=Little then
- Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
- (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b4)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b7))))
- else
- Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add
-(natural_of_byte b7)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b4))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0)))))
- in
- PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 8)) }))
- | _ -> PR_fail( "parse_uint64 not given enough bytes", pc)
- ))
-
-let integerFromTwosComplementNatural (n:Nat_big_num.num) (half: Nat_big_num.num) (all:Nat_big_num.num) : Nat_big_num.num=
- (if Nat_big_num.less n half then n else Nat_big_num.sub ( n) all)
-
-let partialTwosComplementNaturalFromInteger (i:Nat_big_num.num) (half: Nat_big_num.num) (all:Nat_big_num.num) : Nat_big_num.num=
- (if Nat_big_num.greater_equal i(Nat_big_num.of_int 0) && Nat_big_num.less i ( half) then partialNaturalFromInteger i
- else if Nat_big_num.greater_equal i (Nat_big_num.sub(Nat_big_num.of_int 0)( half)) && Nat_big_num.less i(Nat_big_num.of_int 0) then partialNaturalFromInteger ( Nat_big_num.add all i)
- else failwith "partialTwosComplementNaturalFromInteger")
-
-
-let parse_sint8 : Nat_big_num.num parser=
- (pr_post_map (parse_uint8) (fun n -> integerFromTwosComplementNatural n(Nat_big_num.of_int 128)(Nat_big_num.of_int 256)))
-
-let parse_sint16 c : Nat_big_num.num parser=
- (pr_post_map (parse_uint16 c) (fun n -> integerFromTwosComplementNatural n (Nat_big_num.mul(Nat_big_num.of_int 128)(Nat_big_num.of_int 256)) (Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))))
-
-let parse_sint32 c : Nat_big_num.num parser=
- (pr_post_map (parse_uint32 c) (fun n -> integerFromTwosComplementNatural n (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 128)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256)) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))))
-
-let parse_sint64 c : Nat_big_num.num parser=
- (pr_post_map (parse_uint64 c) (fun n -> integerFromTwosComplementNatural n (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 128)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256)) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))))
-
-let rec parse_ULEB128' (acc: Nat_big_num.num) (shift_factor: Nat_big_num.num) : Nat_big_num.num parser=
- (fun (pc:parse_context) ->
- let _ = (my_debug "ULEB128' ") in
- (match pc.pc_bytes with
- | b::bytes' ->
- let n = (natural_of_byte b) in
- let acc' = (Nat_big_num.add (Nat_big_num.mul (Nat_big_num.bitwise_and n(Nat_big_num.of_int 127)) shift_factor) acc) in
- let finished = ( Nat_big_num.equal(Nat_big_num.bitwise_and n(Nat_big_num.of_int 128))(Nat_big_num.of_int 0)) in
- let pc' = ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) }) in
- if finished then
- PR_success( acc', pc')
- else
- parse_ULEB128' acc' ( Nat_big_num.mul shift_factor(Nat_big_num.of_int 128)) pc'
- | _ ->
- PR_fail( "parse_ULEB128' not given enough bytes", pc)
- ))
-
-let parse_ULEB128 : Nat_big_num.num parser=
- (fun (pc:parse_context) ->
- parse_ULEB128'(Nat_big_num.of_int 0)(Nat_big_num.of_int 1) pc)
-
-let rec parse_SLEB128' (acc: Nat_big_num.num) (shift_factor: Nat_big_num.num) : (bool * Nat_big_num.num * Nat_big_num.num) parser=
- (fun (pc:parse_context) ->
- let _ = (my_debug "SLEB128' ") in
- (match pc.pc_bytes with
- | b::bytes' ->
- let n = (natural_of_byte b) in
- let acc' = (Nat_big_num.add acc (Nat_big_num.mul (Nat_big_num.bitwise_and n(Nat_big_num.of_int 127)) shift_factor)) in
- let shift_factor' = (Nat_big_num.mul shift_factor(Nat_big_num.of_int 128)) in
- let finished = ( Nat_big_num.equal(Nat_big_num.bitwise_and n(Nat_big_num.of_int 128))(Nat_big_num.of_int 0)) in
- let positive = ( Nat_big_num.equal(Nat_big_num.bitwise_and n(Nat_big_num.of_int 64))(Nat_big_num.of_int 0)) in
- let pc' = ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) }) in
- if finished then
- PR_success( (positive, shift_factor', acc'), pc')
- else
- parse_SLEB128' acc' shift_factor' pc'
- | _ ->
- PR_fail( "parse_SLEB128' not given enough bytes", pc)
- ))
-
-let parse_SLEB128 : Nat_big_num.num parser=
- (pr_post_map (parse_SLEB128'(Nat_big_num.of_int 0)(Nat_big_num.of_int 1)) (fun (positive, shift_factor, acc) ->
- if positive then acc else Nat_big_num.sub ( acc) ( shift_factor)))
-
-let parse_nonzero_ULEB128_pair : ( (Nat_big_num.num*Nat_big_num.num)option) parser=
- (let _ = (my_debug "nonzero_ULEB128_pair ") in
- pr_post_map
- (parse_pair parse_ULEB128 parse_ULEB128)
- (fun (n1,n2) -> if Nat_big_num.equal n1(Nat_big_num.of_int 0) &&Nat_big_num.equal n2(Nat_big_num.of_int 0) then None else Some (n1,n2)))
-
-let parse_zero_terminated_ULEB128_pair_list : ( (Nat_big_num.num*Nat_big_num.num)list) parser=
- (let _ = (my_debug "zero_terminated_ULEB128_pair_list ") in
- parse_list parse_nonzero_ULEB128_pair)
-
-let parse_uintDwarfN c (df: dwarf_format) : Nat_big_num.num parser=
- ((match df with
- | Dwarf32 -> (parse_uint32 c)
- | Dwarf64 -> (parse_uint64 c)
- ))
-
-let parse_uint_address_size c (as': Nat_big_num.num) : Nat_big_num.num parser=
- (
- if(Nat_big_num.equal as' (Nat_big_num.of_int 4)) then (parse_uint32 c) else
- (
- if(Nat_big_num.equal as' (Nat_big_num.of_int 8)) then (parse_uint64 c)
- else
- (failwith ("cuh_address_size not 4 or 8: " ^ Nat_big_num.to_string as'))))
-
-let parse_uint_segment_selector_size c (ss: Nat_big_num.num) : ( Nat_big_num.num option) parser=
- (
- if(Nat_big_num.equal ss (Nat_big_num.of_int 0)) then (pr_return None) else
- (
- if(Nat_big_num.equal ss (Nat_big_num.of_int 1)) then
- (pr_post_map (parse_uint8) (fun n -> Some n)) else
- (
- if(Nat_big_num.equal ss (Nat_big_num.of_int 2)) then
- (pr_post_map (parse_uint16 c) (fun n -> Some n)) else
- (
- if(Nat_big_num.equal ss (Nat_big_num.of_int 4)) then
- (pr_post_map (parse_uint32 c) (fun n -> Some n)) else
- (
- if(Nat_big_num.equal ss (Nat_big_num.of_int 8)) then
- (pr_post_map (parse_uint64 c) (fun n -> Some n)) else
- (failwith "cuh_address_size not 4 or 8"))))))
-
-
-
-(** ************************************************************ *)
-(** ** parsing and pretty printing of .debug_* sections ****** *)
-(** ************************************************************ *)
-
-
-(** abbreviations table: pp and parsing *)
-
-let pp_abbreviation_declaration (x:abbreviation_declaration):string=
- (" "
- ^ (Nat_big_num.to_string x.ad_abbreviation_code ^ (" "
- ^ (pp_tag_encoding x.ad_tag ^ (" "
- ^ ((if x.ad_has_children then "[has children]" else "[no children]")
- ^ ("\n"
-(* ^ " "^show (List.length x.ad_attribute_specifications) ^ " attributes\n"*)
- ^ myconcat ""
- (Lem_list.map
- (fun (n1,n2) ->
- " " ^ (pp_attribute_encoding n1 ^ (" " ^ (pp_attribute_form_encoding n2 ^ "\n"))))
- x.ad_attribute_specifications))))))))
-
-let pp_abbreviations_table (x:abbreviations_table):string=
- (myconcat "" (Lem_list.map (pp_abbreviation_declaration) x))
-
-let parse_abbreviation_declaration c : ( abbreviation_declaration option) parser=
- (fun (pc: parse_context) ->
- pr_bind (parse_ULEB128 pc) (fun n1 pc' ->
- if Nat_big_num.equal n1(Nat_big_num.of_int 0) then
- PR_success( None, pc')
- else
- pr_bind (parse_ULEB128 pc') (fun n2 pc'' ->
- pr_bind (parse_uint8 pc'') (fun c pc''' ->
- pr_post_map1
- (parse_zero_terminated_ULEB128_pair_list pc''')
- (fun l ->
- Some ( let ad =
- ({
- ad_abbreviation_code = n1;
- ad_tag = n2;
- ad_has_children = (not (Nat_big_num.equal c(Nat_big_num.of_int 0)));
- ad_attribute_specifications = l;
- }) in let _ = (my_debug2 (pp_abbreviation_declaration ad)) in ad)
- )))))
-
-let parse_abbreviations_table c:parse_context ->((abbreviation_declaration)list)parse_result=
- (parse_list (parse_abbreviation_declaration c))
-
-
-(** debug_str entry *)
-
-(*val mydrop : forall 'a. natural -> list 'a -> maybe (list 'a)*)
-let rec mydrop n xs:('a list)option=
- (if Nat_big_num.equal n(Nat_big_num.of_int 0) then Some xs
- else
- (match xs with
- | x::xs' -> mydrop (Nat_big_num.sub_nat n(Nat_big_num.of_int 1)) xs'
- | [] -> None
- ))
-
-let rec null_terminated_list (acc: char list) (xs: char list) : char list=
- ((match xs with
- | [] -> List.rev acc (* TODO: flag failure? *)
- | x::xs' -> if Nat_big_num.equal (natural_of_byte x)(Nat_big_num.of_int 0) then List.rev acc else null_terminated_list (x::acc) xs'
- ))
-
-let pp_debug_str_entry (str: char list) (n: Nat_big_num.num):string=
- ((match mydrop n str with
- | None -> "strp beyond .debug_str extent"
- | Some xs -> string_of_bytes (null_terminated_list [] xs)
- ))
-
-(** operations: pp and parsing *)
-
-let pp_operation_argument_value (oav:operation_argument_value) : string=
- ((match oav with
- | OAV_natural n -> pphex n
- | OAV_integer n -> Nat_big_num.to_string n
- | OAV_block( n, bs) -> pphex n ^ (" " ^ ppbytes
- instance_Show_Show_Missing_pervasives_byte_dict bs)
- ))
-
-let pp_operation_semantics (os: operation_semantics) : string=
- ((match os with
- | OpSem_lit -> "OpSem_lit"
- | OpSem_deref -> "OpSem_deref"
- | OpSem_stack _ -> "OpSem_stack ..."
- | OpSem_not_supported -> "OpSem_not_supported"
- | OpSem_binary _ -> "OpSem_binary ..."
- | OpSem_unary _ -> "OpSem_unary ..."
- | OpSem_opcode_lit _ -> "OpSem_opcode_lit ..."
- | OpSem_reg -> "OpSem_reg"
- | OpSem_breg -> "OpSem_breg"
- | OpSem_bregx -> "OpSem_bregx"
- | OpSem_fbreg -> "OpSem_fbreg"
- | OpSem_deref_size -> "OpSem_deref_size"
- | OpSem_nop -> "OpSem_nop"
- | OpSem_piece -> "OpSem_piece"
- | OpSem_bit_piece -> "OpSem_bitpiece"
- | OpSem_implicit_value -> "OpSem_implicit_value"
- | OpSem_stack_value -> "OpSem_stack_value"
- | OpSem_call_frame_cfa -> "OpSem_call_frame_cfa"
- ))
-
-let pp_operation (op: operation) : string=
- (op.op_string ^ (" " ^ (myconcat " " (Lem_list.map pp_operation_argument_value op.op_argument_values) ^ (" (" ^ (pp_operation_semantics op.op_semantics ^ ")")))))
-
-let pp_operations (ops: operation list) : string=
- (myconcat "; " (Lem_list.map pp_operation ops))
-
-(*val parser_of_operation_argument_type : p_context -> compilation_unit_header -> operation_argument_type -> (parser operation_argument_value)*)
-let parser_of_operation_argument_type c cuh oat:parse_context ->(operation_argument_value)parse_result=
- ((match oat with
- | OAT_addr ->
- pr_map2 (fun n -> OAV_natural n) (parse_uint_address_size c cuh.cuh_address_size)
- | OAT_dwarf_format_t ->
- pr_map2 (fun n -> OAV_natural n) (parse_uintDwarfN c cuh.cuh_dwarf_format)
- | OAT_uint8 -> pr_map2 (fun n -> OAV_natural n) (parse_uint8)
- | OAT_uint16 -> pr_map2 (fun n -> OAV_natural n) (parse_uint16 c)
- | OAT_uint32 -> pr_map2 (fun n -> OAV_natural n) (parse_uint32 c)
- | OAT_uint64 -> pr_map2 (fun n -> OAV_natural n) (parse_uint64 c)
- | OAT_sint8 -> pr_map2 (fun n -> OAV_integer n) (parse_sint8)
- | OAT_sint16 -> pr_map2 (fun n -> OAV_integer n) (parse_sint16 c)
- | OAT_sint32 -> pr_map2 (fun n -> OAV_integer n) (parse_sint32 c)
- | OAT_sint64 -> pr_map2 (fun n -> OAV_integer n) (parse_sint64 c)
- | OAT_ULEB128 -> pr_map2 (fun n -> OAV_natural n) parse_ULEB128
- | OAT_SLEB128 -> pr_map2 (fun n -> OAV_integer n) parse_SLEB128
- | OAT_block ->
- (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' ->
- pr_map (fun bs -> OAV_block( n, bs)) (parse_n_bytes n pc')))
- ))
-
-(*val parse_operation : p_context -> compilation_unit_header -> parser (maybe operation)*)
-let parse_operation c cuh pc:((operation)option)parse_result=
- ((match parse_uint8 pc with
- | PR_fail( s, pc') -> PR_success( None, pc)
- | PR_success( code, pc') ->
- (match lookup_aBcd_acd
- instance_Basic_classes_Eq_Num_natural_dict code operation_encodings with
- | None -> PR_fail( ("encoding not found: " ^ pphex code), pc)
- | Some (s,oats,opsem) ->
- let ps = (Lem_list.map (parser_of_operation_argument_type c cuh) oats) in
- (pr_post_map
- (parse_parser_list ps)
- (fun oavs -> Some { op_code = code; op_string = s; op_argument_values = oavs; op_semantics = opsem })
- )
- pc'
- )
- ))
-
-(*val parse_operations : p_context -> compilation_unit_header -> parser (list operation)*)
-let parse_operations c cuh:parse_context ->((operation)list)parse_result=
- (parse_list (parse_operation c cuh))
-
-(*val parse_and_pp_operations : p_context -> compilation_unit_header -> list byte -> string*)
-let parse_and_pp_operations c cuh bs:string=
- (let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in
- (match parse_operations c cuh pc with
- | PR_fail( s, pc') -> "parse_operations fail: " ^ pp_parse_fail s pc'
- | PR_success( ops, pc') ->
- pp_operations ops
- ^ (if not ((listEqualBy (=) pc'.pc_bytes [])) then " Warning: extra non-parsed bytes" else "")
- ))
-
-
-(** attribute values: pp and parsing *)
-
-(*val pp_attribute_value : p_context -> compilation_unit_header -> list byte -> natural (*attribute tag*) -> attribute_value -> string*)
-let pp_attribute_value c cuh str at av:string=
- ((match av with
- | AV_addr x -> "AV_addr " ^ pphex x
- | AV_block( n, bs) -> "AV_block " ^ (Nat_big_num.to_string n ^ (" " ^ (ppbytes
- instance_Show_Show_Missing_pervasives_byte_dict bs
- ^ (if Nat_big_num.equal at (attribute_encode "DW_AT_location") then " " ^ parse_and_pp_operations c cuh bs else ""))))
- | AV_constantN( n, bs) -> "AV_constantN " ^ (Nat_big_num.to_string n ^ (" " ^ ppbytes
- instance_Show_Show_Missing_pervasives_byte_dict bs))
- | AV_constant_SLEB128 i -> "AV_constant_SLEB128 " ^ Nat_big_num.to_string i
- | AV_constant_ULEB128 n -> "AV_constant_ULEB128 " ^ Nat_big_num.to_string n
- | AV_exprloc( n, bs) -> "AV_exprloc " ^ (Nat_big_num.to_string n ^ (" " ^ (ppbytes
- instance_Show_Show_Missing_pervasives_byte_dict bs
- ^ (" " ^ parse_and_pp_operations c cuh bs))))
- | AV_flag b -> "AV_flag " ^ string_of_bool b
- | AV_ref n -> "AV_ref " ^ pphex n
- | AV_ref_addr n -> "AV_ref_addr " ^ pphex n
- | AV_ref_sig8 n -> "AV_ref_sig8 " ^ pphex n
- | AV_sec_offset n -> "AV_sec_offset " ^ pphex n
- | AV_string bs -> string_of_bytes bs
- | AV_strp n -> "AV_sec_offset " ^ (pphex n ^ (" "
- ^ pp_debug_str_entry str n))
- ))
-
-
-(*val parser_of_attribute_form_non_indirect : p_context -> compilation_unit_header -> natural -> parser attribute_value*)
-let parser_of_attribute_form_non_indirect c cuh n:parse_context ->(attribute_value)parse_result=
-(
-(* address*)if Nat_big_num.equal n (attribute_form_encode "DW_FORM_addr") then
- pr_map2 (fun n -> AV_addr n) (parse_uint_address_size c cuh.cuh_address_size)
-(* block *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block1") then
- (fun pc -> pr_bind (parse_uint8 pc) (fun n pc' ->
- pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc')))
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block2") then
- (fun pc -> pr_bind (parse_uint16 c pc) (fun n pc' ->
- pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc')))
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block4") then
- (fun pc -> pr_bind (parse_uint32 c pc) (fun n pc' ->
- pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc')))
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block") then
- (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' ->
- pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc')))
-(* constant *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data1") then
- pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 1), bs)) (parse_n_bytes(Nat_big_num.of_int 1))
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data2") then
- pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 2), bs)) (parse_n_bytes(Nat_big_num.of_int 2))
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data4") then
- pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 4), bs)) (parse_n_bytes(Nat_big_num.of_int 4))
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data8") then
- pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 8), bs)) (parse_n_bytes(Nat_big_num.of_int 8))
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_sdata") then
- pr_map2 (fun i -> AV_constant_SLEB128 i) parse_SLEB128
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_udata") then
- pr_map2 (fun n -> AV_constant_ULEB128 n) parse_ULEB128
-(* exprloc *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_exprloc") then
- (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' ->
- pr_map (fun bs -> AV_exprloc( n, bs)) (parse_n_bytes n pc')))
-(* flag *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_flag") then
- pr_map2 (fun n -> AV_flag (not (Nat_big_num.equal n(Nat_big_num.of_int 0)))) (parse_uint8)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_flag_present") then
- pr_map2 (fun () -> AV_flag true) (pr_return ())
-(* lineptr, loclistptr, macptr, rangelistptr *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_sec_offset") then
- pr_map2 (fun n -> AV_sec_offset n) (parse_uintDwarfN c cuh.cuh_dwarf_format)
-(* reference - first type *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref1") then
- pr_map2 (fun n -> AV_ref n) (parse_uint8)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref2") then
- pr_map2 (fun n -> AV_ref n) (parse_uint16 c)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref4") then
- pr_map2 (fun n -> AV_ref n) (parse_uint32 c)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref8") then
- pr_map2 (fun n -> AV_ref n) (parse_uint64 c)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref_udata") then
- pr_map2 (fun n -> AV_ref n) parse_ULEB128
-(* reference - second type *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref_addr") then
- pr_map2 (fun n -> AV_ref_addr n) (parse_uintDwarfN c cuh.cuh_dwarf_format)
-(* reference - third type *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref_sig8") then
- pr_map2 (fun n -> AV_ref_sig8 n) (parse_uint64 c)
-(* string *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_string") then
- pr_map2 (fun bs -> AV_string bs) parse_string
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_strp") then
- pr_map2 (fun n -> AV_strp n) (parse_uintDwarfN c cuh.cuh_dwarf_format)
-(* indirect (cycle detection) *)
- else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_indirect") then
- failwith "DW_FORM_INDIRECT cycle"
-(* unknown *)
- else
- failwith "parser_of_attribute_form_non_indirect: unknown attribute form")
-
-
-let parser_of_attribute_form c cuh n:parse_context ->(attribute_value)parse_result=
- (if Nat_big_num.equal n (attribute_form_encode "DW_FORM_indirect") then
- (fun pc -> pr_bind (parse_ULEB128 pc) (fun n ->
- parser_of_attribute_form_non_indirect c cuh n) )
- else
- parser_of_attribute_form_non_indirect c cuh n)
-
-(** attribute find *)
-
-let find_name str ats : string option=
- (myfindmaybe
- (fun (((at: Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) ->
- if Nat_big_num.equal (attribute_encode "DW_AT_name") at then
- let name1 =
- ((match av with
- | AV_string bs -> string_of_bytes bs
- | AV_strp n -> pp_debug_str_entry str n
- | _ -> "av_name AV not understood"
- )) in
- Some name1
- else
- None)
- ats)
-
-let find_name_of_die str die1 : string option=
- (let ats = (Lem_list.list_combine
- die1.die_abbreviation_declaration.ad_attribute_specifications
- die1.die_attribute_values) in
- find_name str ats)
-
-let find_attribute_value (an: string) (die1:die) : attribute_value option=
- (let at = (attribute_encode an) in
- let ats = (Lem_list.list_combine
- die1.die_abbreviation_declaration.ad_attribute_specifications
- die1.die_attribute_values) in
- myfindmaybe
- (fun (((at': Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) ->
- if Nat_big_num.equal at' at then Some av else None)
- ats)
-
-(** compilation unit header: pp and parsing *)
-
-let pp_dwarf_format df:string= ((match df with Dwarf32 -> "(32-bit)" | Dwarf64 -> "(64-bit)" ))
-
-let pp_unit_header (s:string) (x:compilation_unit_header) : string=
- (" " ^ (s ^ (" Unit @ offset " ^ (pphex x.cuh_offset ^ (":\n"
- ^ (" Length: " ^ (pphex x.cuh_unit_length ^ (" " ^ (pp_dwarf_format x.cuh_dwarf_format ^ ("\n"
- ^ (" Version: " ^ (Nat_big_num.to_string x.cuh_version ^ ("\n"
- ^ (" Abbrev Offset: " ^ (pphex x.cuh_debug_abbrev_offset ^ ("\n"
- ^ (" Pointer Size: " ^ (Nat_big_num.to_string x.cuh_address_size ^ "\n"))))))))))))))))))
-
-let pp_compilation_unit_header (x:compilation_unit_header) : string=
- (pp_unit_header "Compilation" x)
-
-let parse_unit_length c : (dwarf_format * Nat_big_num.num) parser=
- (fun (pc: parse_context) ->
- pr_bind (parse_uint32 c pc) (fun x pc' ->
- if Nat_big_num.less x (natural_of_hex "0xfffffff0") then PR_success( (Dwarf32,x), pc')
- else if not (Nat_big_num.equal x (natural_of_hex "0xffffffff")) then PR_fail( "bad unit_length", pc)
- else
- pr_bind (parse_uint64 c pc') (fun x' pc'' ->
- PR_success( (Dwarf64, x'), pc'))))
-
-
-let parse_compilation_unit_header c : compilation_unit_header parser=
- (pr_post_map
- (pr_with_pos
- (parse_dependent_pair
- (parse_unit_length c)
- (fun (df,ul) ->
- parse_triple
- (parse_uint16 c) (* version *)
- (parse_uintDwarfN c df) (* debug abbrev offset *)
- (parse_uint8) (* address_size *))))
- (fun (offset,((df,ul), (v, (dao, as')))) ->
- {
- cuh_offset = offset;
- cuh_dwarf_format = df;
- cuh_unit_length = ul;
- cuh_version = v;
- cuh_debug_abbrev_offset = dao;
- cuh_address_size = as';
- }))
-
-
-(** type unit header: pp and parsing *)
-
-(* the test binaries don't have a .debug_types section, so this isn't tested *)
-
-let pp_type_unit_header (x:type_unit_header) : string=
- (pp_unit_header "Type" x.tuh_cuh
- ^ (" Type Signature: " ^ (pphex x.tuh_type_signature ^ ("\n"
- ^ (" Type Offset: " ^ (pphex x.tuh_type_offset ^ "\n"))))))
-
-
-let parse_type_unit_header c : type_unit_header parser=
- (pr_post_map
- (parse_dependent_pair
- (parse_compilation_unit_header c)
- (fun cuh ->
- parse_pair
- (parse_uint64 c) (* type signature *)
- (parse_uintDwarfN c cuh.cuh_dwarf_format) (* type offset *) ))
- (fun (cuh, (ts, to')) ->
- {
- tuh_cuh = cuh;
- tuh_type_signature = ts;
- tuh_type_offset = to';
- }))
-
-
-(** debugging information entries: pp and parsing *)
-
-(* example pp from readelf
- <2><51>: Abbrev Number: 3 (DW_TAG_variable)
- <52> DW_AT_name : x
- <54> DW_AT_decl_file : 1
- <55> DW_AT_decl_line : 2
- <56> DW_AT_type : <0x6a>
- <5a> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)
-*)
-
-let pp_pos pos:string= ("<" ^ (pphex pos ^">"))
-
-let indent_level (level: Nat_big_num.num):string= (Xstring.implode (replicate0 ( Nat_big_num.mul(Nat_big_num.of_int 3) level) ' '))
-
-let pp_die_attribute c (cuh:compilation_unit_header) (str : char list) (level: Nat_big_num.num) (((at: Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) : string=
- (indent_level ( Nat_big_num.add level(Nat_big_num.of_int 1)) ^ (pp_pos pos ^ (" "
- ^ (pp_attribute_encoding at ^ (" : "
- ^ ("(" ^ (pp_attribute_form_encoding af ^ (") "
- ^ (pp_attribute_value c cuh str at av
- ^ "\n")))))))))
-
-(*val pp_die : p_context -> compilation_unit_header -> list byte -> natural -> bool -> die -> string*)
-let rec pp_die c cuh str level (pp_children:bool) die1:string=
- (indent_level level ^ ("<" ^ (Nat_big_num.to_string level ^ (">"
- ^ (pp_pos die1.die_offset
- ^ (": Abbrev Number: " ^ (Nat_big_num.to_string die1.die_abbreviation_code
- ^ (" (" ^ (pp_tag_encoding die1.die_abbreviation_declaration.ad_tag ^(")\n"
- ^
-(let ats = (Lem_list.list_combine
- die1.die_abbreviation_declaration.ad_attribute_specifications
- die1.die_attribute_values) in
- (myconcat "" (Lem_list.map (pp_die_attribute c cuh str level) ats))
- ^
-(if pp_children then myconcat "" (Lem_list.map (pp_die c cuh str ( Nat_big_num.add level(Nat_big_num.of_int 1)) pp_children) die1.die_children) else ""))))))))))))
-
-(*val pp_die_abbrev : p_context -> compilation_unit_header -> list byte -> natural -> bool -> (list die) -> die -> string*)
-let rec pp_die_abbrev c cuh str level (pp_children:bool) parents die1:string=
- (indent_level level
- ^ (pp_tag_encoding die1.die_abbreviation_declaration.ad_tag
- ^ (" (" ^ (pp_pos die1.die_offset ^ (") "
-(* ^ ": Abbrev Number: " ^ show die.die_abbreviation_code *)
- ^
-(let ats = (Lem_list.list_combine
- die1.die_abbreviation_declaration.ad_attribute_specifications
- die1.die_attribute_values) in
- ((match find_name str ats with Some s -> s | None -> "-" ))
- ^ (" : " ^ (myconcat " : " (Lem_list.map (fun die' -> pp_tag_encoding die'.die_abbreviation_declaration.ad_tag) parents)
- ^ ("\n"
- ^
-
-( (*(myconcat "" (List.map (pp_die_abbrev_attribute c cuh str) ats))*)if pp_children then myconcat "" (Lem_list.map (pp_die_abbrev c cuh str ( Nat_big_num.add level(Nat_big_num.of_int 1)) pp_children (die1::parents)) die1.die_children) else ""))))))))))
-
-
-
-(*val parse_die : p_context -> list byte -> compilation_unit_header -> (natural->abbreviation_declaration) -> parser (maybe die)*)
-let rec parse_die c str cuh find_abbreviation_declaration:parse_context ->((die)option)parse_result=
- (fun (pc: parse_context) ->
- let _ = (my_debug3 ("parse_die called at " ^ (pp_parse_context pc ^ "\n"))) in
- pr_bind (parse_ULEB128 pc) (fun abbreviation_code pc' ->
- if Nat_big_num.equal abbreviation_code(Nat_big_num.of_int 0) then PR_success( None, pc')
- else
- let _ = (my_debug3 ("parse_die abbreviation code "^(pphex abbreviation_code ^"\n"))) in
- let ad = (find_abbreviation_declaration abbreviation_code) in
- let attribute_value_parsers = (Lem_list.map (fun (at,af) -> pr_with_pos (parser_of_attribute_form c cuh af)) ad.ad_attribute_specifications) in
- pr_bind (parse_parser_list attribute_value_parsers pc') (fun avs pc'' ->
-
-(*
- let die_header =
- <|
- die_offset = pc.pc_offset;
- die_abbreviation_code = abbreviation_code;
- die_abbreviation_declaration = ad;
- die_attribute_values = avs;
- die_children = [];
- |> in let _ = my_debug3 ("die_header " ^ pp_die cuh str 999 die_header) in
- *)
- pr_bind
- (if ad.ad_has_children then parse_list (parse_die c str cuh find_abbreviation_declaration) pc'' else pr_return [] pc'')
- (fun dies pc''' ->
- PR_success( (Some ( let die1 =
- ({
- die_offset = (pc.pc_offset);
- die_abbreviation_code = abbreviation_code;
- die_abbreviation_declaration = ad;
- die_attribute_values = avs;
- die_children = dies;
- }) in (* let _ = my_debug3 ("die entire " ^ pp_die cuh str 999 die) in *)die1)), pc''')))))
-
-let has_attribute (an: string) (die1: die) : bool=
- (Lem_list.elem instance_Basic_classes_Eq_Num_natural_dict
- (attribute_encode an)
- (Lem_list.map fst die1.die_abbreviation_declaration.ad_attribute_specifications))
-
-
-(** compilation units: pp and parsing *)
-
-let pp_compilation_unit c (debug_str_section_body: char list) cu:string=
-
- ("*** compilation unit header ***\n"
- ^ (pp_compilation_unit_header cu.cu_header
- ^ ("\n*** compilation unit abbreviation table ***\n"
- ^ (pp_abbreviations_table cu.cu_abbreviations_table
- ^ ("\n*** compilation unit die tree ***\n"
- ^ (pp_die c cu.cu_header debug_str_section_body(Nat_big_num.of_int 0) true cu.cu_die
- ^ "\n"))))))
-
-let pp_compilation_units c debug_string_section_body (compilation_units1: compilation_unit list) : string=
- (myconcat "" (Lem_list.map (pp_compilation_unit c debug_string_section_body) compilation_units1))
-
-
-let pp_compilation_unit_abbrev c (debug_str_section_body: char list) cu:string=
- (pp_compilation_unit_header cu.cu_header
-(* ^ pp_abbreviations_table cu.cu_abbreviations_table*)
- ^ pp_die_abbrev c cu.cu_header debug_str_section_body(Nat_big_num.of_int 0) true [] cu.cu_die)
-
-let pp_compilation_units_abbrev c debug_string_section_body (compilation_units1: compilation_unit list) : string=
- (myconcat "" (Lem_list.map (pp_compilation_unit_abbrev c debug_string_section_body) compilation_units1))
-
-
-let parse_compilation_unit c (debug_str_section_body: char list) (debug_abbrev_section_body: char list) : ( compilation_unit option) parser=
- (fun (pc:parse_context) ->
-
- if (listEqualBy (=) pc.pc_bytes []) then PR_success( None, pc) else
-
- let (cuh, pc') =
-
- ((match parse_compilation_unit_header c pc with
- | PR_fail( s, pc') -> failwith ("parse_cuh_header fail: " ^ pp_parse_fail s pc')
- | PR_success( cuh, pc') -> (cuh,pc')
- )) in
-
- let _ = (my_debug4 (pp_compilation_unit_header cuh)) in
-
- let pc_abbrev = ({pc_bytes = ((match mydrop cuh.cuh_debug_abbrev_offset debug_abbrev_section_body with Some bs -> bs | None -> failwith "mydrop of debug_abbrev" )); pc_offset = (cuh.cuh_debug_abbrev_offset) }) in
-
- let abbreviations_table1 =
- ((match parse_abbreviations_table c pc_abbrev with
- | PR_fail( s, pc_abbrev') -> failwith ("parse_abbrevations_table fail: " ^ pp_parse_fail s pc_abbrev')
- | PR_success( at, pc_abbrev') -> at
- )) in
-
- let _ = (my_debug4 (pp_abbreviations_table abbreviations_table1)) in
-
- let find_abbreviation_declaration (ac:Nat_big_num.num) : abbreviation_declaration=
- (let _ = (my_debug4 ("find_abbreviation_declaration "^pphex ac)) in
- myfindNonPure (fun ad -> Nat_big_num.equal ad.ad_abbreviation_code ac) abbreviations_table1) in
-
- let _ = (my_debug3 (pp_abbreviations_table abbreviations_table1)) in
-
- (match parse_die c debug_str_section_body cuh find_abbreviation_declaration pc' with
- | PR_fail( s, pc'') -> failwith ("parse_die fail: " ^ pp_parse_fail s pc'')
- | PR_success( (None), pc'') -> failwith ("parse_die returned Nothing: " ^ pp_parse_context pc'')
- | PR_success( (Some die1), pc'') ->
- let cu =
- ({
- cu_header = cuh;
- cu_abbreviations_table = abbreviations_table1;
- cu_die = die1;
- }) in
- PR_success( (Some cu), pc'')
- ))
-
-let parse_compilation_units c (debug_str_section_body: char list) (debug_abbrev_section_body: char list): ( compilation_unit list) parser=
-
- (parse_list (parse_compilation_unit c debug_str_section_body debug_abbrev_section_body))
-
-
-(** type units: pp and parsing *)
-
-let pp_type_unit c (debug_str_section_body: char list) tu:string=
- (pp_type_unit_header tu.tu_header
- ^ (pp_abbreviations_table tu.tu_abbreviations_table
- ^ pp_die c tu.tu_header.tuh_cuh debug_str_section_body(Nat_big_num.of_int 0) true tu.tu_die))
-
-let pp_type_units c debug_string_section_body (type_units1: type_unit list) : string=
- (myconcat "" (Lem_list.map (pp_type_unit c debug_string_section_body) type_units1))
-
-
-let parse_type_unit c (debug_str_section_body: char list) (debug_abbrev_section_body: char list) : ( type_unit option) parser=
- (fun (pc:parse_context) ->
-
- if (listEqualBy (=) pc.pc_bytes []) then PR_success( None, pc) else
-
- let (tuh, pc') =
- ((match parse_type_unit_header c pc with
- | PR_fail( s, pc') -> failwith ("parse_tuh_header fail: " ^ pp_parse_fail s pc')
- | PR_success( tuh, pc') -> (tuh,pc')
- )) in
-
- let _ = (my_debug4 (pp_type_unit_header tuh)) in
-
- let pc_abbrev = (let n = (tuh.tuh_cuh.cuh_debug_abbrev_offset) in {pc_bytes = ((match mydrop n debug_abbrev_section_body with Some bs -> bs | None -> failwith "mydrop of debug_abbrev" )); pc_offset = n }) in
-
- let abbreviations_table1 =
- ((match parse_abbreviations_table c pc_abbrev with
- | PR_fail( s, pc_abbrev') -> failwith ("parse_abbrevations_table fail: " ^ pp_parse_fail s pc_abbrev')
- | PR_success( at, pc_abbrev') -> at
- )) in
-
- let _ = (my_debug4 (pp_abbreviations_table abbreviations_table1)) in
-
- let find_abbreviation_declaration (ac:Nat_big_num.num) : abbreviation_declaration=
- (let _ = (my_debug4 ("find_abbreviation_declaration "^pphex ac)) in
- myfindNonPure (fun ad -> Nat_big_num.equal ad.ad_abbreviation_code ac) abbreviations_table1) in
-
- let _ = (my_debug3 (pp_abbreviations_table abbreviations_table1)) in
-
- (match parse_die c debug_str_section_body tuh.tuh_cuh find_abbreviation_declaration pc' with
- | PR_fail( s, pc'') -> failwith ("parse_die fail: " ^ pp_parse_fail s pc'')
- | PR_success( (None), pc'') -> failwith ("parse_die returned Nothing: " ^ pp_parse_context pc'')
- | PR_success( (Some die1), pc'') ->
- let tu =
- ({
- tu_header = tuh;
- tu_abbreviations_table = abbreviations_table1;
- tu_die = die1;
- }) in
- PR_success( (Some tu), pc'')
- ))
-
-let parse_type_units c (debug_str_section_body: char list) (debug_abbrev_section_body: char list): ( type_unit list) parser=
-
- (parse_list (parse_type_unit c debug_str_section_body debug_abbrev_section_body))
-
-(** location lists, pp and parsing *)
-
-(* readelf example
-Contents of the .debug_loc section:
-
- Offset Begin End Expression
- 00000000 0000000000400168 0000000000400174 (DW_OP_reg0 (r0))
- 00000000 0000000000400174 0000000000400184 (DW_OP_GNU_entry_value: (DW_OP_reg0 (r0)); DW_OP_stack_value)
- 00000000 <End of list>
- 00000039 000000000040017c 0000000000400180 (DW_OP_lit1; DW_OP_stack_value)
-*)
-
-let pp_location_list_entry c (cuh:compilation_unit_header) (offset:Nat_big_num.num) (x:location_list_entry) : string=
- (" " ^ (pphex offset
- ^ (" " ^ (pphex x.lle_beginning_address_offset
- ^ (" " ^ (pphex x.lle_ending_address_offset
- ^ (" (" ^ (parse_and_pp_operations c cuh x.lle_single_location_description ^(")"
- ^ "\n")))))))))
-
-let pp_base_address_selection_entry c (cuh:compilation_unit_header) (offset:Nat_big_num.num) (x:base_address_selection_entry) : string=
- (" " ^ (pphex offset
- ^ (" " ^ (pphex x.base_address
- ^ "\n"))))
-
-let pp_location_list_item c (cuh: compilation_unit_header) (offset: Nat_big_num.num) (x:location_list_item):string=
- ((match x with
- | LLI_lle lle -> pp_location_list_entry c cuh offset lle
- | LLI_base base -> pp_base_address_selection_entry c cuh offset base
- ))
-
-let pp_location_list c (cuh: compilation_unit_header) ((offset:Nat_big_num.num), (llis: location_list_item list)):string=
- (myconcat "" (Lem_list.map (pp_location_list_item c cuh offset) llis))
-(* ^ " " ^ pphex offset ^ " <End of list>\n"*)
-
-let pp_loc c (cuh: compilation_unit_header) (lls: location_list list):string=
- (" Offset Begin End Expression\n"
- ^ myconcat "" (Lem_list.map (pp_location_list c cuh) lls))
-
-(* Note that this is just pp'ing the raw location list data - Sectoin
-3.1.1 says: The applicable base address of a location list entry is
-determined by the closest preceding base address selection entry in
-the same location list. If there is no such selection entry, then the
-applicable base address defaults to the base address of the
-compilation unit. That is handled by the interpret_location_list below *)
-
-
-
-let parse_location_list_item c (cuh: compilation_unit_header) : ( location_list_item option) parser=
- (fun (pc:parse_context) ->
- pr_bind
- (parse_pair
- (parse_uint_address_size c cuh.cuh_address_size)
- (parse_uint_address_size c cuh.cuh_address_size)
- pc)
- (fun ((a1: Nat_big_num.num),(a2:Nat_big_num.num)) pc' ->
- let _ = (my_debug4 ("offset="^(pphex pc.pc_offset ^ (" begin=" ^ (pphex a1 ^ (" end=" ^ pphex a2)))))) in
- if Nat_big_num.equal a1(Nat_big_num.of_int 0) &&Nat_big_num.equal a2(Nat_big_num.of_int 0) then
- PR_success( None, pc')
- else if Nat_big_num.equal a1 (max_address cuh.cuh_address_size) then
- let x = (LLI_base { (*base_offset=pc.pc_offset;*) base_address=a1 }) in
- PR_success( (Some x (*(pc.pc_offset, x)*)), pc')
- else
- pr_bind (parse_uint16 c pc') (fun n pc'' ->
- pr_post_map1
- (parse_n_bytes n pc'')
- (fun bs ->
- let x =
- (LLI_lle {
- (*lle_offset = pc.pc_offset;*)
- lle_beginning_address_offset = a1;
- lle_ending_address_offset = a2;
- lle_single_location_description = bs;
- }) in
- Some x (*(pc.pc_offset, x)*))
- )
- ))
-
-let parse_location_list c cuh : ( location_list option) parser=
- (fun (pc: parse_context) ->
- if (listEqualBy (=) pc.pc_bytes []) then
- PR_success( None, pc)
- else
- pr_post_map1
- (parse_list (parse_location_list_item c cuh) pc)
- (fun llis -> (Some (pc.pc_offset, llis))))
-
-let parse_location_list_list c cuh : location_list_list parser=
- (parse_list (parse_location_list c cuh))
-
-let find_location_list dloc n : location_list=
- (myfindNonPure (fun (n',_)->Nat_big_num.equal n' n) dloc)
- (* fails if location list not found *)
-
-(* interpretation of a location list applies the base_address and LLI_base offsets to give a list indexed by concrete address ranges *)
-
-let rec interpret_location_list (base_address1: Nat_big_num.num) (llis: location_list_item list) : (Nat_big_num.num * Nat_big_num.num * single_location_description) list=
- ((match llis with
- | [] -> []
- | LLI_base base::llis' -> interpret_location_list base.base_address llis'
- | LLI_lle lle :: llis' -> (Nat_big_num.add base_address1 lle.lle_beginning_address_offset,Nat_big_num.add base_address1 lle.lle_ending_address_offset, lle.lle_single_location_description) :: interpret_location_list base_address1 llis'
- ))
-
-
-(** range lists, pp and parsing *)
-
-(* readelf example
-Contents of the .debug_aranges section:
-
- Length: 44
- Version: 2
- Offset into .debug_info: 0x0
- Pointer Size: 8
- Segment Size: 0
-
- Address Length
- 00000000100000e8 0000000000000090
- 0000000000000000 0000000000000000
- Length: 44
- Version: 2
- Offset into .debug_info: 0x1de
- Pointer Size: 8
- Segment Size: 0
-*)
-
-let pp_range_list_entry c (cuh:compilation_unit_header) (offset:Nat_big_num.num) (x:range_list_entry) : string=
- (" " ^ (pphex offset
- ^ (" " ^ (pphex x.rle_beginning_address_offset
- ^ (" " ^ (pphex x.rle_ending_address_offset
- ^ "\n"))))))
-
-let pp_range_list_item c (cuh: compilation_unit_header) (offset: Nat_big_num.num) (x:range_list_item):string=
- ((match x with
- | RLI_rle rle -> pp_range_list_entry c cuh offset rle
- | RLI_base base -> pp_base_address_selection_entry c cuh offset base
- ))
-
-let pp_range_list c (cuh: compilation_unit_header) ((offset:Nat_big_num.num), (rlis: range_list_item list)):string=
- (myconcat "" (Lem_list.map (pp_range_list_item c cuh offset) rlis))
-(* ^ " " ^ pphex offset ^ " <End of list>\n"*)
-
-let pp_ranges c (cuh: compilation_unit_header) (rls: range_list list):string=
- (" Offset Begin End Expression\n"
- ^ myconcat "" (Lem_list.map (pp_range_list c cuh) rls))
-
-(* Note that this is just pp'ing the raw range list data - see also
-the interpret_range_list below *)
-
-
-let parse_range_list_item c (cuh: compilation_unit_header) : ( range_list_item option) parser=
- (fun (pc:parse_context) ->
- pr_bind
- (parse_pair
- (parse_uint_address_size c cuh.cuh_address_size)
- (parse_uint_address_size c cuh.cuh_address_size)
- pc)
- (fun ((a1: Nat_big_num.num),(a2:Nat_big_num.num)) pc' ->
- let _ = (my_debug4 ("offset="^(pphex pc.pc_offset ^ (" begin=" ^ (pphex a1 ^ (" end=" ^ pphex a2)))))) in
- if Nat_big_num.equal a1(Nat_big_num.of_int 0) &&Nat_big_num.equal a2(Nat_big_num.of_int 0) then
- PR_success( None, pc')
- else if Nat_big_num.equal a1 (max_address cuh.cuh_address_size) then
- let x = (RLI_base { base_address=a1 }) in
- PR_success( (Some x), pc')
- else
- let x =
- (RLI_rle {
- rle_beginning_address_offset = a1;
- rle_ending_address_offset = a2;
- }) in
- PR_success( (Some x (*(pc.pc_offset, x)*)), pc')
- ))
-
-let parse_range_list c cuh : ( range_list option) parser=
- (fun (pc: parse_context) ->
- if (listEqualBy (=) pc.pc_bytes []) then
- PR_success( None, pc)
- else
- pr_post_map1
- (parse_list (parse_range_list_item c cuh) pc)
- (fun rlis -> (Some (pc.pc_offset, rlis))))
-
-let parse_range_list_list c cuh : range_list_list parser=
- (parse_list (parse_range_list c cuh))
-
-let find_range_list dranges n : range_list=
- (myfindNonPure (fun (n',_)->Nat_big_num.equal n' n) dranges)
- (* fails if range list not found *)
-
-(* interpretation of a range list applies the base_address and RLI_base offsets to give a list of concrete address ranges *)
-
-let rec interpret_range_list (base_address1: Nat_big_num.num) (rlis: range_list_item list) : (Nat_big_num.num * Nat_big_num.num) list=
- ((match rlis with
- | [] -> []
- | RLI_base base::rlis' -> interpret_range_list base.base_address rlis'
- | RLI_rle rle :: rlis' -> (Nat_big_num.add base_address1 rle.rle_beginning_address_offset,Nat_big_num.add base_address1 rle.rle_ending_address_offset) :: interpret_range_list base_address1 rlis'
- ))
-
-(** frame information, pp and parsing *)
-
-(* readelf example
-
-Contents of the .debug_frame section:
-
-00000000 0000000c ffffffff CIE
- Version: 1
- Augmentation: ""
- Code alignment factor: 4
- Data alignment factor: -8
- Return address column: 65
-
- DW_CFA_def_cfa: r1 ofs 0
-
-00000010 00000024 00000000 FDE cie=00000000 pc=100000b0..10000120
- DW_CFA_advance_loc: 8 to 100000b8
- DW_CFA_def_cfa_offset: 80
- DW_CFA_offset: r31 at cfa-8
- DW_CFA_advance_loc: 4 to 100000bc
- DW_CFA_def_cfa_register: r31
- DW_CFA_advance_loc: 80 to 1000010c
- DW_CFA_def_cfa: r1 ofs 0
- DW_CFA_nop
- DW_CFA_nop
- DW_CFA_nop
- DW_CFA_nop
-
-00000038 00000024 00000000 FDE cie=00000000 pc=10000120..100001a4
- DW_CFA_advance_loc: 16 to 10000130
- DW_CFA_def_cfa_offset: 144
- DW_CFA_offset_extended_sf: r65 at cfa+16
- DW_CFA_offset: r31 at cfa-8
- DW_CFA_advance_loc: 4 to 10000134
- DW_CFA_def_cfa_register: r31
- DW_CFA_advance_loc: 84 to 10000188
- DW_CFA_def_cfa: r1 ofs 0
-*)
-
-
-
-let pp_cfa_address a:string= (pphex a)
-let pp_cfa_block dict_Show_Show_a b:string= (ppbytes
- dict_Show_Show_a b)
-let pp_cfa_delta d:string= (pphex d)
-(*let pp_cfa_offset n = pphex n
-let pp_cfa_register r = show r*)
-let pp_cfa_sfoffset dict_Show_Show_a i:string= (
- dict_Show_Show_a.show_method i)
-
-let pp_cfa_register dict_Show_Show_a r:string= ("r"^
- dict_Show_Show_a.show_method r) (*TODO: arch-specific register names *)
-
-let pp_cfa_offset (i:Nat_big_num.num):string= (if Nat_big_num.equal i(Nat_big_num.of_int 0) then "" else if Nat_big_num.less i(Nat_big_num.of_int 0) then Nat_big_num.to_string i else "+" ^ Nat_big_num.to_string i)
-
-let pp_cfa_rule (cr:cfa_rule) : string=
- ((match cr with
- | CR_undefined -> "u"
- | CR_register( r, i) -> pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ pp_cfa_offset i
- | CR_expression bs -> "exp"
- ))
-
-let pp_register_rule (rr:register_rule) : string=
-( (*TODO make this more readelf-like *)(match rr with
- | RR_undefined -> "u"
- | RR_same_value -> "s"
- | RR_offset i -> "c" ^ pp_cfa_offset i
- | RR_val_offset i -> "val(c" ^ (pp_cfa_offset i ^ ")")
- | RR_register r -> pp_cfa_register
- instance_Show_Show_Num_natural_dict r
- | RR_expression bs -> "exp"
- | RR_val_expression bs -> "val(exp)"
- | RR_architectural -> ""
- ))
-
-
-
-let pp_call_frame_instruction i:string=
- ((match i with
- | DW_CFA_advance_loc d -> "DW_CFA_advance_loc" ^ (" " ^ pp_cfa_delta d)
- | DW_CFA_offset( r, n) -> "DW_CFA_offset" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n))))
- | DW_CFA_restore r -> "DW_CFA_restore" ^ (" " ^ pp_cfa_register
- instance_Show_Show_Num_natural_dict r)
- | DW_CFA_nop -> "DW_CFA_nop"
- | DW_CFA_set_loc a -> "DW_CFA_set_loc" ^ (" " ^ pp_cfa_address a)
- | DW_CFA_advance_loc1 d -> "DW_CFA_advance_loc1" ^ (" " ^ pp_cfa_delta d)
- | DW_CFA_advance_loc2 d -> "DW_CFA_advance_loc2" ^ (" " ^ pp_cfa_delta d)
- | DW_CFA_advance_loc4 d -> "DW_CFA_advance_loc4" ^ (" " ^ pp_cfa_delta d)
- | DW_CFA_offset_extended( r, n) -> "DW_CFA_offset_extended" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n))))
- | DW_CFA_restore_extended r -> "DW_CFA_restore_extended" ^ (" " ^ pp_cfa_register
- instance_Show_Show_Num_natural_dict r)
- | DW_CFA_undefined r -> "DW_CFA_undefined" ^ (" " ^ pp_cfa_register
- instance_Show_Show_Num_natural_dict r)
- | DW_CFA_same_value r -> "DW_CFA_same_value" ^ (" " ^ pp_cfa_register
- instance_Show_Show_Num_natural_dict r)
- | DW_CFA_register( r1, r2) -> "DW_CFA_register" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r1 ^ (" " ^ pp_cfa_register
- instance_Show_Show_Num_natural_dict r2)))
- | DW_CFA_remember_state -> "DW_CFA_remember_state"
- | DW_CFA_restore_state -> "DW_CFA_restore_state"
- | DW_CFA_def_cfa( r, n) -> "DW_CFA_def_cfa" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n))))
- | DW_CFA_def_cfa_register r -> "DW_CFA_def_cfa_register" ^ (" " ^ pp_cfa_register
- instance_Show_Show_Num_natural_dict r)
- | DW_CFA_def_cfa_offset n -> "DW_CFA_def_cfa_offset" ^ (" " ^ pp_cfa_offset ( n))
- | DW_CFA_def_cfa_expression b -> "DW_CFA_def_cfa_expression" ^ (" " ^ pp_cfa_block
- instance_Show_Show_Missing_pervasives_byte_dict b)
- | DW_CFA_expression( r, b) -> "DW_CFA_expression" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_block
- instance_Show_Show_Missing_pervasives_byte_dict b)))
- | DW_CFA_offset_extended_sf( r, i) -> "DW_CFA_offset_extended_sf" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_sfoffset
- instance_Show_Show_Num_integer_dict i)))
- | DW_CFA_def_cfa_sf( r, i) -> "DW_CFA_def_cfa_sf" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_sfoffset
- instance_Show_Show_Num_integer_dict i)))
- | DW_CFA_def_cfa_offset_sf i -> "DW_CFA_def_cfa_offset_sf" ^ (" " ^ pp_cfa_sfoffset
- instance_Show_Show_Num_integer_dict i)
- | DW_CFA_val_offset( r, n) -> "DW_CFA_val_offset" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n))))
- | DW_CFA_val_offset_sf( r, i) -> "DW_CFA_val_offset_sf" ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_sfoffset
- instance_Show_Show_Num_integer_dict i))
- | DW_CFA_val_expression( r, b) -> "DW_CFA_val_expression" ^ (" " ^ (pp_cfa_register
- instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_block
- instance_Show_Show_Missing_pervasives_byte_dict b)))
- | DW_CFA_unknown bt -> "DW_CFA_unknown" ^ (" " ^ hex_string_of_byte bt)
- ))
-
-let pp_call_frame_instructions is:string= (myconcat "" (Lem_list.map (fun i -> " " ^ (pp_call_frame_instruction i ^ "\n")) is))
-
-
-let parser_of_call_frame_argument_type c cuh (cfat: call_frame_argument_type) : call_frame_argument_value parser=
- ((match cfat with
- | CFAT_address -> pr_map2 (fun n -> CFAV_address n) (parse_uint_address_size c cuh.cuh_address_size)
- | CFAT_delta1 -> pr_map2 (fun n -> CFAV_delta n) (parse_uint8)
- | CFAT_delta2 -> pr_map2 (fun n -> CFAV_delta n) (parse_uint16 c)
- | CFAT_delta4 -> pr_map2 (fun n -> CFAV_delta n) (parse_uint32 c)
- | CFAT_delta_ULEB128 -> pr_map2 (fun n -> CFAV_delta n) (parse_ULEB128)
- | CFAT_offset -> pr_map2 (fun n -> CFAV_offset n) (parse_ULEB128)
- | CFAT_sfoffset -> pr_map2 (fun n -> CFAV_sfoffset n) (parse_SLEB128)
- | CFAT_register -> pr_map2 (fun n -> CFAV_register n) (parse_ULEB128)
- | CFAT_block ->
- (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' ->
- pr_map (fun bs -> CFAV_block bs) (parse_n_bytes n pc')))
- ))
-
-let parse_call_frame_instruction c cuh : ( call_frame_instruction option) parser=
- (fun pc ->
- (match pc.pc_bytes with
- | [] -> PR_success( None, pc)
- | b::bs' ->
- let pc' = ({ pc_bytes = bs'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) }) in
- let ch = (Uint32.of_int (Char.code b)) in
- let high_bits = (Uint32.logand ch (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 192)))) in
- let low_bits = (Nat_big_num.of_string (Uint32.to_string (Uint32.logand ch (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 63)))))) in
- if high_bits = Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)) then
- (match lookup_abCde_de
- instance_Basic_classes_Eq_Num_natural_dict low_bits call_frame_instruction_encoding with
- | Some ((args: call_frame_argument_type list), result) ->
- let ps = (Lem_list.map (parser_of_call_frame_argument_type c cuh) args) in
- let p =
- (pr_post_map
- (parse_parser_list ps)
- result) in
- (match p pc' with
- | PR_success( (Some cfi), pc'') -> PR_success( (Some cfi), pc'')
- | PR_success( (None), pc'') -> failwith "bad call frame instruction argument 1"
- | PR_fail( s, pc'') -> failwith "bad call frame instruction argument 2"
- )
- | None ->
- (*Assert_extra.failwith ("can't parse " ^ show b ^ " as call frame instruction")*)
- PR_success( (Some (DW_CFA_unknown b)), pc')
- )
- else
- if high_bits = Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 64)) then
- PR_success( (Some (DW_CFA_advance_loc low_bits)), pc')
- else if high_bits = Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 192)) then
- PR_success( (Some (DW_CFA_restore low_bits)), pc')
- else
- let p = (parser_of_call_frame_argument_type c cuh CFAT_offset) in
- (match p pc' with
- | PR_success( (CFAV_offset n), pc'') -> PR_success( (Some (DW_CFA_offset( low_bits, n))), pc'')
- | PR_success( _, pc'') -> failwith "bad call frame instruction argument 3"
- | PR_fail( s, pc'') -> failwith "bad call frame instruction argument 4"
- )
- ))
-
-let parse_call_frame_instructions c cuh : ( call_frame_instruction list) parser=
- (parse_list (parse_call_frame_instruction c cuh))
-
-(*val parse_and_pp_call_frame_instructions : p_context -> compilation_unit_header -> list byte -> string*)
-let parse_and_pp_call_frame_instructions c cuh bs:string=
- (let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in
- (match parse_call_frame_instructions c cuh pc with
- | PR_fail( s, pc') -> "parse_call_frame_instructions fail: " ^ pp_parse_fail s pc'
- | PR_success( is, pc') ->
- pp_call_frame_instructions is
- ^ (if not ((listEqualBy (=) pc'.pc_bytes [])) then " Warning: extra non-parsed bytes" else "")
- ))
-
-
-
-let pp_call_frame_instructions' c cuh bs:string=
-(
- (* ppbytes bs ^ "\n" *)parse_and_pp_call_frame_instructions c cuh bs)
-
-
-
-let pp_cie c cuh cie1:string=
- (pphex cie1.cie_offset
- ^ (" " ^ (pphex cie1.cie_length
- ^ (" " ^ (pphex cie1.cie_id
- ^ (" CIE\n"
- ^ (" Version: " ^ (Nat_big_num.to_string cie1.cie_version ^ ("\n"
- ^ (" Augmentation: \""^ (string_of_string (Xstring.implode (Lem_list.map (fun x-> x) cie1.cie_augmentation)) ^ ("\"\n"
- ^ (" Code alignment factor: " ^ (Nat_big_num.to_string cie1.cie_code_alignment_factor ^ ("\n"
- ^ (" Data alignment factor: " ^ (Nat_big_num.to_string cie1.cie_data_alignment_factor ^ ("\n"
- ^ (" Return address column: " ^ (Nat_big_num.to_string cie1.cie_return_address_register ^ ("\n"
- ^ ("\n"
- ^ (ppbytes instance_Show_Show_Missing_pervasives_byte_dict cie1.cie_initial_instructions_bytes ^ ("\n"
- ^ pp_call_frame_instructions cie1.cie_initial_instructions))))))))))))))))))))))))
-
-(* cie_address_size: natural; (* not shown by readelf - must match compilation unit *)*)
-(* cie_segment_size: natural; (* not shown by readelf *)*)
-(* readelf says "Return address column", but the DWARF spec says "Return address register" *)
-
-
-let pp_fde c cuh fde1:string=
- (pphex fde1.fde_offset
- ^ (" " ^ (pphex fde1.fde_length
- ^ (" " ^ (pphex fde1.fde_cie_pointer (* not what this field of readelf output is *)
- ^ (" FDE"
- ^ (" cie=" ^ (pphex fde1.fde_cie_pointer (* duplicated?? *)
- ^ (" pc=" ^ ((match fde1.fde_initial_location_segment_selector with None -> "" | Some segment_selector -> "("^(pphex segment_selector^")") ) ^ (pphex fde1.fde_initial_location_address ^ (".." ^ (pphex ( Nat_big_num.add fde1.fde_initial_location_address fde1.fde_address_range) ^ ("\n"
- ^ (ppbytes instance_Show_Show_Missing_pervasives_byte_dict fde1.fde_instructions_bytes ^ ("\n"
- ^ pp_call_frame_instructions fde1.fde_instructions))))))))))))))))
-
-let pp_frame_info_element c cuh fie:string=
- ((match fie with
- | FIE_cie cie1 -> pp_cie c cuh cie1
- | FIE_fde fde1 -> pp_fde c cuh fde1
- ))
-
-let pp_frame_info c cuh fi:string=
- ("Contents of the .debug_frame section:\n\n"
- ^ (myconcat "\n" (Lem_list.map (pp_frame_info_element c cuh) fi)
- ^ "\n"))
-
-
-
-let rec find_cie fi cie_id1:cie=
- ((match fi with
- | [] -> failwith "find_cie: cie_id not found"
- | FIE_fde _ :: fi' -> find_cie fi' cie_id1
- | FIE_cie cie1 :: fi' -> if Nat_big_num.equal cie_id1 cie1.cie_offset then cie1 else find_cie fi' cie_id1
- ))
-
-let parse_initial_location c cuh mss mas' : (( Nat_big_num.num option) * Nat_big_num.num) parser=
-( (*(segment selector and target address)*)
- (* assume segment selector size is zero unless given explicitly. Probably we need to do something architecture-specific for earlier dwarf versions?*)parse_pair
- (parse_uint_segment_selector_size c ((match mss with Some n -> n | None ->Nat_big_num.of_int 0 )))
- (parse_uint_address_size c ((match mas' with Some n -> n | None -> cuh.cuh_address_size ))))
-
-
-let parse_call_frame_instruction_bytes offset' ul:parse_context ->((char)list)parse_result=
- (fun (pc: parse_context) ->
- parse_n_bytes ( Nat_big_num.sub_nat ul ( Nat_big_num.sub_nat pc.pc_offset offset')) pc)
-
-let parse_frame_info_element c cuh (fi: frame_info_element list) : frame_info_element parser=
- (parse_dependent
- (pr_with_pos
- (parse_dependent_pair
- (parse_unit_length c)
- (fun (df,ul) ->
- pr_with_pos
- (parse_uintDwarfN c df) (* CIE_id (cie) or CIE_pointer (fde) *)
- )))
- (fun (offset,((df,ul),(offset',cie_id1))) ->
- if ( Nat_big_num.equal cie_id1
- (match df with
- | Dwarf32 -> natural_of_hex "0xffffffff"
- | Dwarf64 -> natural_of_hex "0xffffffffffffffff"
- ))
- then
- (* parse cie *)
- pr_post_map
- (parse_pair
- (parse_dependent_pair
- parse_uint8 (* version *)
- (fun v ->
- parse_triple
- parse_string (* augmentation *)
- (if Nat_big_num.equal v(Nat_big_num.of_int 4) ||Nat_big_num.equal v(Nat_big_num.of_int 46) then pr_post_map parse_uint8 (fun i->Some i) else pr_return None) (* address_size *)
- (if Nat_big_num.equal v(Nat_big_num.of_int 4) ||Nat_big_num.equal v(Nat_big_num.of_int 46) then pr_post_map parse_uint8 (fun i->Some i) else pr_return None))) (* segment_size *)
- (parse_quadruple
- parse_ULEB128 (* code_alignment_factor *)
- parse_SLEB128 (* data_alignment_factor *)
- parse_ULEB128 (* return address register *)
- (parse_call_frame_instruction_bytes offset' ul)))
- (fun ( (v,(aug,(mas',mss))), (caf,(daf,(rar,bs))) ) ->
- let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in
- (match parse_call_frame_instructions c cuh pc with
- | PR_success( is, _) ->
- FIE_cie
- (
- {
- cie_offset = offset;
- cie_length = ul;
- cie_id = cie_id1;
- cie_version = v;
- cie_augmentation = aug;
- cie_address_size = mas';
- cie_segment_size = mss;
- cie_code_alignment_factor = caf;
- cie_data_alignment_factor = daf;
- cie_return_address_register = rar;
- cie_initial_instructions_bytes = bs;
- cie_initial_instructions = is;
- })
- | PR_fail( s, _) -> failwith s
- )
- )
-
- else
- (* parse fde *)
- let cie1 = (find_cie fi cie_id1) in
- let _ = (my_debug4 (pp_cie c cuh cie1)) in
- pr_post_map
- (parse_triple
- (parse_initial_location c cuh cie1.cie_segment_size cie1.cie_address_size) (*(segment selector and target address)*)
- (parse_uint_address_size c ((match cie1.cie_address_size with Some n -> n | None -> cuh.cuh_address_size ))) (* address_range (target address) *)
- (parse_call_frame_instruction_bytes offset' ul)
- )
- (fun ( (ss,adr), (ar, bs)) ->
- let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in
- (match parse_call_frame_instructions c cuh pc with
- | PR_success( is, _) ->
- FIE_fde
- (
- {
- fde_offset = offset;
- fde_length = ul;
- fde_cie_pointer = cie_id1;
- fde_initial_location_segment_selector = ss;
- fde_initial_location_address = adr;
- fde_address_range = ar;
- fde_instructions_bytes = bs;
- fde_instructions = is;
- } )
- | PR_fail( s, _) -> failwith s
- )
- )
- ))
-
-(* you can't even parse an fde without accessing the cie it refers to
-(to determine the segment selector size). Gratuitous complexity or what?
-Hence the following, which should be made more tail-recursive. *)
-
-(*val parse_dependent_list' : forall 'a. (list 'a -> parser 'a) -> list 'a -> parser (list 'a)*)
-let rec parse_dependent_list' p1 acc:parse_context ->('a list)parse_result=
- (fun pc ->
- if (listEqualBy (=) pc.pc_bytes []) then
- PR_success( (List.rev acc), pc)
- else
- pr_bind
- (p1 acc pc)
- (fun x pc' ->
- parse_dependent_list' p1 (x::acc) pc'))
-
-(*val parse_dependent_list : forall 'a. (list 'a -> parser 'a) -> parser (list 'a)*)
-let parse_dependent_list p1:parse_context ->('a list)parse_result= (parse_dependent_list' p1 [])
-
-
-let parse_frame_info c cuh : frame_info parser=
-
-(parse_dependent_list (parse_frame_info_element c cuh))
-
-
-(** line numbers .debug_line, pp and parsing *)
-
-let pp_line_number_file_entry lnfe:string=
- ("lnfe_path = " ^ (string_of_bytes lnfe.lnfe_path ^ ("\n"
-^ ("lnfe_directory_index " ^ (Nat_big_num.to_string lnfe.lnfe_directory_index ^ ("\n"
-^ ("lnfe_last_modification = " ^ (Nat_big_num.to_string lnfe.lnfe_last_modification ^ ("\n"
-^ ("lnfe_length = " ^ (Nat_big_num.to_string lnfe.lnfe_length ^ "\n")))))))))))
-
-
-let pp_line_number_header lnh:string=
- ("offset = " ^ (pphex lnh.lnh_offset ^ ("\n"
-^ ("dwarf_format = " ^ (pp_dwarf_format lnh.lnh_dwarf_format ^ ("\n"
-^ ("unit_length = " ^ (Nat_big_num.to_string lnh.lnh_unit_length ^ ("\n"
-^ ("version = " ^ (Nat_big_num.to_string lnh.lnh_version ^ ("\n"
-^ ("header_length = " ^ (Nat_big_num.to_string lnh.lnh_header_length ^ ("\n"
-^ ("minimum_instruction_length = " ^ (Nat_big_num.to_string lnh.lnh_minimum_instruction_length ^ ("\n"
-^ ("maximum_operations_per_instruction = " ^ (Nat_big_num.to_string lnh.lnh_maximum_operations_per_instruction ^ ("\n"
-^ ("default_is_stmt = " ^ (string_of_bool lnh.lnh_default_is_stmt ^ ("\n"
-^ ("line_base = " ^ (Nat_big_num.to_string lnh.lnh_line_base ^ ("\n"
-^ ("line_range = " ^ (Nat_big_num.to_string lnh.lnh_line_range ^ ("\n"
-^ ("opcode_base = " ^ (Nat_big_num.to_string lnh.lnh_opcode_base ^ ("\n"
-^ ("standard_opcode_lengths = " ^ (string_of_list
- instance_Show_Show_Num_natural_dict lnh.lnh_standard_opcode_lengths ^ ("\n"
-^ ("include_directories = " ^ (myconcat ", " (Lem_list.map string_of_bytes lnh.lnh_include_directories) ^ ("\n"
-^ ("file_names = \n\n" ^ (myconcat "\n" (Lem_list.map pp_line_number_file_entry lnh.lnh_file_names) ^ "\n")))))))))))))))))))))))))))))))))))))))))
-
-let pp_line_number_operation lno:string=
- ((match lno with
- | DW_LNS_copy -> "DW_LNS_copy"
- | DW_LNS_advance_pc n -> "DW_LNS_advance_pc" ^ (" " ^ Nat_big_num.to_string n)
- | DW_LNS_advance_line i -> "DW_LNS_advance_line" ^ (" " ^ Nat_big_num.to_string i)
- | DW_LNS_set_file n -> "DW_LNS_set_file" ^ (" " ^ Nat_big_num.to_string n)
- | DW_LNS_set_column n -> "DW_LNS_set_column" ^ (" " ^ Nat_big_num.to_string n)
- | DW_LNS_negate_stmt -> "DW_LNS_negate_stmt"
- | DW_LNS_set_basic_block -> "DW_LNS_set_basic_block"
- | DW_LNS_const_add_pc -> "DW_LNS_const_add_pc"
- | DW_LNS_fixed_advance_pc n -> "DW_LNS_fixed_advance_pc" ^ (" " ^ Nat_big_num.to_string n)
- | DW_LNS_set_prologue_end -> "DW_LNS_set_prologue_end"
- | DW_LNS_set_epilogue_begin -> "DW_LNS_set_epilogue_begin"
- | DW_LNS_set_isa n -> "DW_LNS_set_isa" ^ (" " ^ Nat_big_num.to_string n)
- | DW_LNE_end_sequence -> "DW_LNE_end_sequence"
- | DW_LNE_set_address n -> "DW_LNE_set_address" ^ (" " ^ pphex n)
- | DW_LNE_define_file( s, n1, n2, n3) -> "DW_LNE_define_file" ^ (" " ^ (string_of_list
- instance_Show_Show_Missing_pervasives_byte_dict s ^ (" " ^ (Nat_big_num.to_string n1 ^ (" " ^ (Nat_big_num.to_string n2 ^ (" " ^ Nat_big_num.to_string n3)))))))
- | DW_LNE_set_discriminator n -> "DW_LNE_set_discriminator" ^ (" " ^ Nat_big_num.to_string n)
- | DW_LN_special n -> "DW_LN_special" ^ (" " ^ Nat_big_num.to_string n)
- ))
-
-let pp_line_number_program lnp:string=
- (pp_line_number_header lnp.lnp_header
- ^ ("[" ^ (myconcat ", " (Lem_list.map pp_line_number_operation lnp.lnp_operations) ^ "]\n")))
-
-
-
-let parse_line_number_file_entry : ( line_number_file_entry option) parser=
-
-(parse_dependent
- (parse_non_empty_string)
- (fun ms ->
- (match ms with
- | None ->
- pr_return None
- | Some s ->
- pr_post_map
- (parse_triple
- parse_ULEB128
- parse_ULEB128
- parse_ULEB128
- )
- (fun (n1,(n2,n3)) ->
- (Some
- {
- lnfe_path = s;
- lnfe_directory_index = n1;
- lnfe_last_modification = n2;
- lnfe_length = n3;
- } )
- )
- )
- ))
-
-let parse_line_number_header c : line_number_header parser=
- (parse_dependent
- ((pr_with_pos
- (parse_unit_length c) ))
- (fun (pos,(df,ul)) ->
- parse_dependent
- (parse_pair
- (parse_triple
- (parse_uint16 c) (* version *)
- (parse_uintDwarfN c df) (* header_length *)
- (parse_uint8) (* minimum_instruction_length *)
- (* (parse_uint8) (* maximum_operations_per_instruction *) NOT IN DWARF 2*)
- )
- (parse_quadruple
- (parse_uint8) (* default_is_stmt *)
- (parse_sint8) (* line_base *)
- (parse_uint8) (* line_range *)
- (parse_uint8) (* opcode_base *)
- ))
- (fun ((v,(hl,(minil(*,maxopi*)))),(dis,(lb,(lr,ob)))) ->
- pr_post_map
- (parse_triple
- (pr_post_map (parse_n_bytes (Nat_big_num.sub_nat ob(Nat_big_num.of_int 1))) (Lem_list.map natural_of_byte)) (* standard_opcode_lengths *)
- ((*pr_return [[]]*) parse_list parse_non_empty_string) (* include_directories *)
- (parse_list parse_line_number_file_entry) (* file names *)
- )
- (fun (sols, (ids, fns)) ->
- {
- lnh_offset = pos;
- lnh_dwarf_format = df;
- lnh_unit_length = ul;
- lnh_version = v;
- lnh_header_length = hl;
- lnh_minimum_instruction_length = minil;
- lnh_maximum_operations_per_instruction =(Nat_big_num.of_int 1) (*maxopi*);
- lnh_default_is_stmt = (not (Nat_big_num.equal dis(Nat_big_num.of_int 0)));
- lnh_line_base = lb;
- lnh_line_range = lr;
- lnh_opcode_base = ob;
- lnh_standard_opcode_lengths = sols;
- lnh_include_directories = ids;
- lnh_file_names = fns;
- }
- )
- )
- )
- )
-
-let parser_of_line_number_argument_type c (cuh: compilation_unit_header) (lnat: line_number_argument_type) : line_number_argument_value parser=
- ((match lnat with
- | LNAT_address -> pr_map2 (fun n -> LNAV_address n) (parse_uint_address_size c cuh.cuh_address_size)
- | LNAT_ULEB128 -> pr_map2 (fun n -> LNAV_ULEB128 n) (parse_ULEB128)
- | LNAT_SLEB128 -> pr_map2 (fun i -> LNAV_SLEB128 i) (parse_SLEB128)
- | LNAT_uint16 -> pr_map2 (fun n -> LNAV_uint16 n) (parse_uint16 c)
- | LNAT_string -> pr_map2 (fun s -> LNAV_string s) (parse_string)
- ))
-
-let parse_line_number_operation c (cuh: compilation_unit_header) (lnh: line_number_header) : line_number_operation parser=
- (parse_dependent
- parse_uint8
- (fun opcode ->
- if Nat_big_num.equal opcode(Nat_big_num.of_int 0) then
- (* parse extended opcode *)
- parse_dependent
- (parse_pair
- parse_ULEB128
- parse_uint8)
- (fun (size2,opcode') ->
- (match lookup_aBcd_acd
- instance_Basic_classes_Eq_Num_natural_dict opcode' line_number_extended_encodings with
- | Some (_, arg_types, result) ->
- let ps = (Lem_list.map (parser_of_line_number_argument_type c cuh) arg_types) in
- parse_demaybe ("parse_line_number_operation fail")
- (pr_post_map
- (parse_parser_list ps)
- result )
- | None ->
- failwith ("parse_line_number_operation extended opcode not found: " ^ Nat_big_num.to_string opcode')
- ))
- (* it's not clear what the ULEB128 size field is for, as the extended opcides all seem to have well-defined sizes. perhaps there can be extra padding that needs to be absorbed? *)
- else if Nat_big_num.greater_equal opcode lnh.lnh_opcode_base then
- (* parse special opcode *)
- let adjusted_opcode = (Nat_big_num.sub_nat opcode lnh.lnh_opcode_base) in
- pr_return (DW_LN_special adjusted_opcode)
- else
- (* parse standard opcode *)
- (match lookup_aBcd_acd
- instance_Basic_classes_Eq_Num_natural_dict opcode line_number_standard_encodings with
- | Some (_, arg_types, result) ->
- let ps = (Lem_list.map (parser_of_line_number_argument_type c cuh) arg_types) in
- parse_demaybe ("parse_line_number_operation fail")
- (pr_post_map
- (parse_parser_list ps)
- result)
- | None ->
- failwith ("parse_line_number_operation standard opcode not found: " ^ Nat_big_num.to_string opcode)
- (* the standard_opcode_lengths machinery is intended to allow vendor specific extension instructions to be parsed and ignored, but here we couldn't usefully process such instructions in any case, so we just fail *)
- )))
-
-
-let parse_line_number_operations c (cuh:compilation_unit_header) (lnh:line_number_header) : ( line_number_operation list) parser=
- (parse_list (parse_maybe (parse_line_number_operation c cuh lnh)))
-
-
- (* assume operations start immediately after the header - not completely clear in DWARF whether the header_length is just an optimisation or whether it's intended to allow the operations to start later *)
- (* line number operations have no no-op and no termination operation, so we have to cut down the available bytes to the right length *)
-
-let parse_line_number_program c (cuh:compilation_unit_header) : line_number_program parser=
- (parse_dependent
- (parse_line_number_header c)
- (fun lnh ->
- let byte_count_of_operations = (Nat_big_num.sub_nat
- lnh.lnh_unit_length ( Nat_big_num.add (Nat_big_num.add lnh.lnh_header_length(Nat_big_num.of_int 2)) ((match lnh.lnh_dwarf_format with Dwarf32 ->Nat_big_num.of_int 4 | Dwarf64 ->Nat_big_num.of_int 8 )))) in
- pr_post_map
- (parse_restrict_length
- byte_count_of_operations
- (parse_line_number_operations c cuh lnh)
- )
- (fun ops ->
- {
- lnp_header = lnh;
- lnp_operations = ops;
- })
- ))
-
-let parse_line_number_info c (d_line: char list) (cu: compilation_unit) : line_number_program=
- (let f n=
- (let d_line' = ((match mydrop n d_line with Some xs -> xs | None -> failwith "parse_line_number_info drop" )) in
- let pc = ({ pc_bytes = d_line'; pc_offset = n}) in
- (match parse_line_number_program c cu.cu_header pc with
- | PR_success( lnp, pc') ->
- (*let _ = print_endline (pp_line_number_program lnp) in*)
- lnp
- | PR_fail( s, pc') -> failwith ("parse_line_number_header failed: " ^ s)
- )) in
- (match find_attribute_value "DW_AT_stmt_list" cu.cu_die with
- | Some (AV_sec_offset n) -> f n
- | Some (AV_block( n, bs)) -> f (natural_of_bytes c.endianness bs)
- (* a 32-bit MIPS example used a 4-byte AV_block not AV_sec_offset *)
- | Some _ -> failwith "compilation unit DW_AT_stmt_list attribute was not an AV_sec_offset"
- | _ -> failwith "compilation unit did not have a DW_AT_stmt_list attribute"
- ))
-
-
-let parse_line_number_infos c debug_line_section_body compilation_units1:(line_number_program)list=
-
- (Lem_list.map (parse_line_number_info c debug_line_section_body) compilation_units1)
-
-let pp_line_info li:string=
-
-(myconcat "\n" (Lem_list.map (pp_line_number_program) li))
-
-
-(** all dwarf info: pp and parsing *)
-
-let pp_dwarf d:string=
- (let c : p_context = ({ endianness = (d.d_endianness) }) in
-
- "\n************** .debug_info section - abbreviated *****************\n"
- ^ (pp_compilation_units_abbrev c d.d_str d.d_compilation_units
- ^ ("\n************** .debug_info section - full ************************\n"
- ^ (pp_compilation_units c d.d_str d.d_compilation_units
- ^ ("\n************** .debug_loc section: location lists ****************\n"
- ^ (let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in
- pp_loc c cuh_default d.d_loc
- ^ ("\n************** .debug_ranges section: range lists ****************\n"
- ^ (pp_ranges c cuh_default d.d_ranges
- ^ ("\n************** .debug_frame section: frame info ****************\n"
- ^ (pp_frame_info c cuh_default d.d_frame_info
- ^ ("\n************** .debug_line section: line number info ****************\n"
- ^ pp_line_info d.d_line_info)))))))))))
-
-
-let parse_dwarf c
- (debug_info_section_body: char list)
- (debug_abbrev_section_body: char list)
- (debug_str_section_body: char list)
- (debug_loc_section_body: char list)
- (debug_ranges_section_body: char list)
- (debug_frame_section_body: char list)
- (debug_line_section_body: char list)
- : dwarf=
-
- (let pc_info = ({pc_bytes = debug_info_section_body; pc_offset =(Nat_big_num.of_int 0) }) in
-
- let compilation_units1 =
- ((match parse_compilation_units c debug_str_section_body debug_abbrev_section_body pc_info with
- | PR_fail( s, pc_info') -> failwith ("parse_compilation_units: " ^ pp_parse_fail s pc_info')
- | PR_success( cus, pc_info') -> cus
- )) in
-
- (*let _ = my_debug5 (pp_compilation_units c debug_str_section_body compilation_units) in*)
-
-
-(* the DWARF4 spec doesn't seem to specify the address size used in the .debug_loc section, so we (hackishly) take it from the first compilation unit *)
- let (cuh_default : compilation_unit_header) = (let cu = (myhead compilation_units1) in cu.cu_header) in
-
- let pc_loc = ({pc_bytes = debug_loc_section_body; pc_offset =(Nat_big_num.of_int 0) }) in
-
- let loc =
- ((match parse_location_list_list c cuh_default pc_loc with
- | PR_fail( s, pc_info') -> failwith ("parse_location_list: " ^ pp_parse_fail s pc_info')
- | PR_success( loc, pc_loc') -> loc
- )) in
-
- let pc_ranges = ({pc_bytes = debug_ranges_section_body; pc_offset =(Nat_big_num.of_int 0) }) in
-
- let ranges =
- ((match parse_range_list_list c cuh_default pc_ranges with
- | PR_fail( s, pc_info') -> failwith ("parse_range_list: " ^ pp_parse_fail s pc_info')
- | PR_success( r, pc_loc') -> r
- )) in
-
- let pc_frame = ({pc_bytes = debug_frame_section_body; pc_offset =(Nat_big_num.of_int 0) }) in
-
- let fi =
- (let _ = (my_debug5 ("debug_frame_section_body:\n" ^ ppbytes2
- instance_Show_Show_Missing_pervasives_byte_dict(Nat_big_num.of_int 0) debug_frame_section_body)) in
-
- (match parse_frame_info c cuh_default pc_frame with
- | PR_fail( s, pc_info') -> failwith ("parse_frame_info: " ^ pp_parse_fail s pc_info')
- | PR_success( fi, pc_loc') -> fi
- )) in
-
- let li = (parse_line_number_infos c debug_line_section_body compilation_units1) in
-
- {
- d_endianness = (c.endianness);
- d_str = debug_str_section_body;
- d_compilation_units = compilation_units1;
- d_type_units = ([]);
- d_loc = loc;
- d_ranges = ranges;
- d_frame_info = fi;
- d_line_info = li;
- })
-
-(*val extract_dwarf : elf_file -> maybe dwarf*)
-let extract_dwarf f:(dwarf)option=
-
- (let (en: Endianness.endianness) =
- ((match f with
- | ELF_File_32 f32 -> Elf_header.get_elf32_header_endianness f32.Elf_file.elf32_file_header
- | ELF_File_64 f64 -> Elf_header.get_elf64_header_endianness f64.Elf_file.elf64_file_header
- )) in
- let (c: p_context) = ({ endianness = en }) in
- let extract_section_body section_name (strict: bool)=
- ((match f with
- | ELF_File_32 f32 ->
- let sections =
- (List.filter
- (fun x ->
- x.Elf_interpreted_section.elf32_section_name_as_string = section_name
- ) f32.elf32_file_interpreted_sections) in
- (match sections with
- | [section] ->
- let section_body = ((match section.Elf_interpreted_section.elf32_section_body with Sequence bs -> bs )) in
- let _ = (my_debug4 (section_name ^ (": \n" ^ (Elf_interpreted_section.string_of_elf32_interpreted_section section ^ ("\n"
- ^ (" body = " ^ (ppbytes2
- instance_Show_Show_Missing_pervasives_byte_dict(Nat_big_num.of_int 0) section_body ^ "\n"))))))) in
- section_body
- | [] ->
- if strict then
- failwith ("" ^ (section_name ^ " section not present"))
- else
- []
- | _ -> failwith ("multiple " ^ (section_name ^ " sections present"))
- )
-
-
- | ELF_File_64 f64 ->
- let sections =
- (List.filter
- (fun x ->
- x.Elf_interpreted_section.elf64_section_name_as_string = section_name
- ) f64.elf64_file_interpreted_sections) in
- (match sections with
- | [section] ->
- let section_body = ((match section.Elf_interpreted_section.elf64_section_body with Sequence bs -> bs )) in
- section_body
- | [] ->
- if strict then
- failwith ("" ^ (section_name ^ " section not present"))
- else
- []
- | _ -> failwith ("multiple " ^ (section_name ^ " sections present"))
- )
- )) in
-
- let debug_info_section_body = (extract_section_body ".debug_info" true) in
- let debug_abbrev_section_body = (extract_section_body ".debug_abbrev" false) in
- let debug_str_section_body = (extract_section_body ".debug_str" false) in
- let debug_loc_section_body = (extract_section_body ".debug_loc" false) in
- let debug_ranges_section_body = (extract_section_body ".debug_ranges" false) in
- let debug_frame_section_body = (extract_section_body ".debug_frame" false) in
- let debug_line_section_body = (extract_section_body ".debug_line" false) in
-
- let d = (parse_dwarf c debug_info_section_body debug_abbrev_section_body debug_str_section_body debug_loc_section_body debug_ranges_section_body debug_frame_section_body debug_line_section_body) in
-
- Some d)
-
-
-(** ************************************************************ *)
-(** ****** location evaluation ******************************** *)
-(** ************************************************************ *)
-
-
-(** pp of locations *)
-
-(*val pp_simple_location : simple_location -> string*)
-let pp_simple_location sl:string=
- ((match sl with
- | SL_memory_address n -> pphex n
- | SL_register n -> "reg" ^ Nat_big_num.to_string n
- | SL_implicit bs -> "value: " ^ ppbytes
- instance_Show_Show_Missing_pervasives_byte_dict bs
- | SL_empty -> "<empty>"
- ))
-
-(*val pp_composite_location_piece : composite_location_piece -> string*)
-let pp_composite_location_piece clp:string=
- ((match clp with
- | CLP_piece( n, sl) -> "piece (" ^ (Nat_big_num.to_string n ^ (") " ^ pp_simple_location sl))
- | CLP_bit_piece( n1, n2, sl) -> "bit_piece (" ^ (Nat_big_num.to_string n1 ^ ("," ^ (Nat_big_num.to_string n2 ^ (") " ^ pp_simple_location sl))))
- ))
-
-(*val pp_single_location: single_location -> string*)
-let pp_single_location sl:string=
- ((match sl with
- | SL_simple sl -> pp_simple_location sl
- | SL_composite clps -> "composite: " ^ myconcat ", " (Lem_list.map pp_composite_location_piece clps)
- ))
-
-
-(** evaluation of location expressions *)
-
-(* cf dwarflist, btw: https://fedorahosted.org/elfutils/wiki/DwarfLint?format=txt *)
-
-(*
-
-location description ::=
-| single location description
-| location list
-
-single location description ::=
-| simple location description
-| composite location description
-
-simple location description ::=
-| memory location description : non-empty dwarf expr, value is address of all or part of object in memory
-| register location description : single DW_OP_regN or DW_OP_regx, naming a register in which all the object is
-| implicit location description : single DW_OP_implicit_value or a non-empty dwarf expr ending in DW_OP_stack_value, giving the value of all/part of object
-| empty location description : an empty dwarf expr, indicating a part or all of an object that is not represented
-
-composite location description : a list of simple location descriptions, each followed by a DW_OP_piece or DW_OP_bitpiece
-
-(the simple location description can be a register location description: https://www.mail-archive.com/dwarf-discuss@lists.dwarfstd.org/msg00271.html)
-(contradicting "A register location description must stand alone as the entire description of an object or a piece of an object.")
-
-location list entry : a list of address ranges (possibly overlapping), each with a single location description
-
-Dwarf expressions can include data-dependent control flow choices
-(though we don't see that in the examples?), so we can't statically
-determine which kind of single location description or simple location
-description we have. We can distinguish:
-
-- empty -> simple.empty
-- DW_OP_regN/DW_OP_regx -> simple.register
-- DW_OP_implicit_value -> simple.implicit
-- any of those followed by DW_OP_piece or DW_OP_bitpiece, perhaps followed by more composite parts -> composite part :: composite
-
-otherwise run to the end, or a DW_OP_stack_value at the end, or to
-anything (except a DO_OP_regN/DW_OP_regx) followed by a
-DW_OP_piece/DW_OP_bitpiece. Pfeh.
-
-
-actually used in our examples (ignoring GNU extentions):
-
-DW_OP_addr literal
-DW_OP_lit1 literal
-DW_OP_const4u literal
-
-DW_OP_breg3 (r3) read register value and add offset
-
-DW_OP_and bitwise and
-DW_OP_plus addition (mod whatever)
-
-DW_OP_deref_size
-DW_OP_fbreg evaluate location description from DW_AT_frame_base attribute of the current function (which is DW_OP_call_frame_cfa in our examples) and add offset
-
-DW_OP_implicit_value the argument block is the actual value (not location) of the entity in question
-DW_OP_stack_value use the value at top of stack as the actual value (not location) of the entity in question
-
-DW_OP_reg0 (r0)) read register value
-
-DW_OP_call_frame_cfa go off to 6.4 and pull info out of .debug_frame (possibly involving other location expressions)
-
-*)
-
-
-
-let initial_state:state=
- ({
- s_stack = ([]);
- s_value = SL_empty;
- s_location_pieces = ([]);
-})
-
-(* the main location expression evaluation function *)
-
-(* location expression evaluation is basically a recursive function
-down a list of operations, maintaining an operation_stack (a list of
-naturals representing machine-address-size words), the current
-simple_location, and a list of any composite_location_piece's
-accumulated so far *)
-
-
-
-let arithmetic_context_of_cuh cuh:arithmetic_context=
- (
- if(Nat_big_num.equal cuh.cuh_address_size (Nat_big_num.of_int 8)) then
- ({ ac_bitwidth =(Nat_big_num.of_int 64);
- ac_half = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 32));
- ac_all = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 64));
- ac_max = (Nat_big_num.sub_nat
- (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 64))
- (Nat_big_num.of_int 1)); }) else
- (
- if(Nat_big_num.equal cuh.cuh_address_size (Nat_big_num.of_int 4)) then
- ({ ac_bitwidth =(Nat_big_num.of_int 32);
- ac_half = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 16));
- ac_all = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 32));
- ac_max = (Nat_big_num.sub_nat
- (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 32))
- (Nat_big_num.of_int 1)); }) else
- (failwith "arithmetic_context_of_cuh given non-4/8 size")))
-
-let find_cfa_table_row_for_pc (evaluated_frame_info1: evaluated_frame_info) (pc: Nat_big_num.num) : cfa_table_row=
- ((match
- myfind
- (fun (fde1,rows) -> Nat_big_num.greater_equal pc fde1.fde_initial_location_address && Nat_big_num.less pc (Nat_big_num.add fde1.fde_initial_location_address fde1.fde_address_range))
- evaluated_frame_info1
- with
- | Some (fde1,rows) ->
- (match myfind (fun row -> Nat_big_num.greater_equal pc row.ctr_loc) rows with
- | Some row -> row
- | None -> failwith "evaluate_cfa: no matchine row"
- )
- | None -> failwith "evaluate_cfa: no fde encloding pc"
- ))
-
-
-let rec evaluate_operation_list (c:p_context) (dloc: location_list_list) (evaluated_frame_info1: evaluated_frame_info) (cuh: compilation_unit_header) (ac: arithmetic_context) (ev: evaluation_context) (mfbloc: attribute_value option) (pc: Nat_big_num.num) (s: state) (ops: operation list) : single_location error=
-
- (let push_memory_address v vs'= (Success { s with s_stack = (v :: vs'); s_value = (SL_memory_address v) }) in
-
- let push_memory_address_maybe (mv: Nat_big_num.num option) vs' (err:string) op=
- ((match mv with
- | Some v -> push_memory_address v vs'
- | None -> Fail (err ^ pp_operation op)
- )) in
-
- let bregxi r i=
- ((match ev.read_register r with
- | RRR_result v -> push_memory_address (partialNaturalFromInteger ( Nat_big_num.modulus(Nat_big_num.add( v)i) ( ac.ac_all))) s.s_stack
- | RRR_not_currently_available -> Fail "RRR_not_currently_available"
- | RRR_bad_register_number -> Fail ("RRR_bad_register_number " ^ Nat_big_num.to_string r)
- )) in
-
- let deref_size n=
- ((match s.s_stack with
- | v::vs' ->
- (match ev.read_memory v n with
- | MRR_result v' -> push_memory_address v' vs'
- | MRR_not_currently_available -> Fail "MRR_not_currently_available"
- | MRR_bad_address -> Fail "MRR_bad_address"
- )
- | _ -> Fail "OpSem unary not given an element on stack"
- )) in
-
- (match ops with
- | [] ->
- if (listEqualBy (=) s.s_location_pieces []) then
- Success (SL_simple s.s_value)
- else if s.s_value = SL_empty then
- Success (SL_composite s.s_location_pieces)
- else
- (* unclear what's supposed to happen in this case *)
- Fail "unfinished part of composite expression"
-
- | op::ops' ->
- let es' =
- ((match (op.op_semantics, op.op_argument_values) with
- | (OpSem_nop, []) ->
- Success s
- | (OpSem_lit, [OAV_natural n]) ->
- push_memory_address n s.s_stack
- | (OpSem_lit, [OAV_integer i]) ->
- push_memory_address (partialTwosComplementNaturalFromInteger i ac.ac_half ( ac.ac_all)) s.s_stack
- | (OpSem_stack f, []) ->
- (match f ac s.s_stack op.op_argument_values with
- | Some stack' ->
- let value' : simple_location = ((match stack' with [] -> SL_empty | v'::_ -> SL_memory_address v' )) in
- Success { s with s_stack = stack'; s_value = value' }
- | None -> Fail "OpSem_stack failed"
- )
- | (OpSem_not_supported, []) ->
- Fail ("OpSem_not_supported: " ^ pp_operation op)
- | (OpSem_binary f, []) ->
- (match s.s_stack with
- | v1::v2::vs' -> push_memory_address_maybe (f ac v1 v2) vs' "OpSem_binary error: " op
- | _ -> Fail "OpSem binary not given two elements on stack"
- )
- | (OpSem_unary f, []) ->
- (match s.s_stack with
- | v1::vs' -> push_memory_address_maybe (f ac v1) vs' "OpSem_unary error: " op
- | _ -> Fail "OpSem unary not given an element on stack"
- )
- | (OpSem_opcode_lit base, []) ->
- if Nat_big_num.greater_equal op.op_code base && Nat_big_num.less op.op_code (Nat_big_num.add base(Nat_big_num.of_int 32)) then
- push_memory_address ( Nat_big_num.sub_nat op.op_code base) s.s_stack
- else
- Fail "OpSem_opcode_lit opcode not within [base,base+32)"
- | (OpSem_reg, []) ->
- (* TODO: unclear whether this should push the register id or not *)
- let r = (Nat_big_num.sub_nat op.op_code vDW_OP_reg0) in
- Success { s with s_stack = (r :: s.s_stack); s_value = (SL_register r) }
- | (OpSem_breg, [OAV_integer i]) ->
- let r = (Nat_big_num.sub_nat op.op_code vDW_OP_breg0) in
- bregxi r i
- | (OpSem_bregx, [OAV_natural r; OAV_integer i]) ->
- bregxi r i
- | (OpSem_deref, []) ->
- deref_size cuh.cuh_address_size
- | (OpSem_deref_size, [OAV_natural n]) ->
- deref_size n
- | (OpSem_fbreg, [OAV_integer i]) ->
- (match mfbloc with
- | Some fbloc ->
- (*let _ = my_debug5 ("OpSem_fbreg (" ^ show i ^ ")\n") in*)
- (match evaluate_location_description c dloc evaluated_frame_info1 cuh ac ev (*mfbloc*)None pc fbloc with
- (* what to do if the recursive call also uses fbreg? for now assume that's not allowed *)
- | Success l ->
- (match l with
- | SL_simple (SL_memory_address a) ->
- (*let _ = my_debug5 ("OpSem_fbreg: a = "^ pphex a ^ "\n") in*)
- let vi = (Nat_big_num.modulus ( Nat_big_num.add( a) i) ( ac.ac_all)) in
- (*let _ = my_debug5 ("OpSem_fbreg: v = "^ show vi ^ "\n") in*)
- let v = (partialNaturalFromInteger vi) (*ac.ac_half (integerFromNatural ac.ac_all)*) in
- push_memory_address v s.s_stack
- | _ ->
- Fail "OpSem_fbreg got a non-SL_simple (SL_memory_address _) result"
- (* "The DW_OP_fbreg operation provides a signed LEB128
- offset from the address specified by the location
- description in the DW_AT_frame_base attribute of the
- current function. "
- - so what to do if the location description returns a non-memory-address location? *)
- )
- | Fail e ->
- Fail ("OpSem_fbreg failure: " ^ e)
- )
- | None ->
- Fail "OpSem_fbreg: no frame base location description given"
- )
-
- | (OpSem_piece, [OAV_natural size_bytes]) ->
- let piece = (CLP_piece( size_bytes, s.s_value)) in
- (* we allow a piece (or bit_piece) to be any simple_location, including implicit and stack values. Unclear if this is intended, esp. the latter *)
- let stack' = ([]) in
- let value' = SL_empty in
- Success { s_stack = stack'; s_value = value'; s_location_pieces = (List.rev_append (List.rev s.s_location_pieces) [piece]) }
- | (OpSem_bit_piece, [OAV_natural size_bits; OAV_natural offset_bits]) ->
- let piece = (CLP_bit_piece( size_bits, offset_bits, s.s_value)) in
- let stack' = ([]) in
- let value' = SL_empty in
- Success { s_stack = stack'; s_value = value'; s_location_pieces = (List.rev_append (List.rev s.s_location_pieces) [piece]) }
- | (OpSem_implicit_value, [OAV_block( size2, bs)]) ->
- let stack' = ([]) in
- let value' = (SL_implicit bs) in
- Success { s with s_stack = stack'; s_value = value' }
- | (OpSem_stack_value, []) ->
- (* "The DW_OP_stack_value operation terminates the expression." - does
- this refer to just the subexpression, ie allowing a stack value to be
- a piece of a composite location, or necessarily the whole expression?
- Why does DW_OP_stack_value have this clause while DW_OP_implicit_value
- does not? *)
- (* why doesn't DW_OP_stack_value have a size argument? *)
- (match s.s_stack with
- | v::vs' ->
- let stack' = ([]) in
- let value' = (SL_implicit (bytes_of_natural c.endianness cuh.cuh_address_size v)) in
- Success { s with s_stack = stack'; s_value = value' }
-
- | _ -> Fail "OpSem_stack_value not given an element on stack"
- )
- | (OpSem_call_frame_cfa, []) ->
- let row = (find_cfa_table_row_for_pc evaluated_frame_info1 pc) in
- (match row.ctr_cfa with
- | CR_undefined ->
- failwith "evaluate_cfa of CR_undefined"
- | CR_register( r, i) ->
- bregxi r i (* same behaviour as an OpSem_bregx *)
- | CR_expression bs ->
- failwith "CR_expression"
- (*TODO: fix result type - not this evaluate_location_description_bytes c dloc evaluated_frame_info cuh ac ev mfbloc pc bs*)
- (* TODO: restrict allowed OpSem_* in that recursive call *)
- )
- | (_, _) ->
- Fail ("bad OpSem invocation: op=" ^ (pp_operation op ^ (" arguments=" ^ myconcat "" (Lem_list.map pp_operation_argument_value op.op_argument_values))))
- ))
- in
- (match es' with
- | Success s' ->
- evaluate_operation_list c dloc evaluated_frame_info1 cuh ac ev mfbloc pc s' ops'
- | Fail e ->
- Fail e
- )
- ))
-
-and evaluate_location_description_bytes (c:p_context) (dloc: location_list_list) (evaluated_frame_info1: evaluated_frame_info) (cuh: compilation_unit_header) (ac: arithmetic_context) (ev: evaluation_context) (mfbloc: attribute_value option) (pc: Nat_big_num.num) (bs: char list) : single_location error=
- (let parse_context1 = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in
- (match parse_operations c cuh parse_context1 with
- | PR_fail( s, pc') -> Fail ("evaluate_location_description_bytes: parse_operations fail: " ^ pp_parse_fail s pc')
- | PR_success( ops, pc') ->
- if not ((listEqualBy (=) pc'.pc_bytes [])) then
- Fail "evaluate_location_description_bytes: extra non-parsed bytes"
- else
- evaluate_operation_list c dloc evaluated_frame_info1 cuh ac ev mfbloc pc initial_state ops
- ))
-
-and evaluate_location_description (c:p_context) (dloc: location_list_list) (evaluated_frame_info1: evaluated_frame_info) (cuh: compilation_unit_header) (ac: arithmetic_context) (ev: evaluation_context) (mfbloc: attribute_value option) (pc: Nat_big_num.num) (loc:attribute_value) : single_location error=
- ((match loc with
- | AV_exprloc( n, bs) ->
- evaluate_location_description_bytes c dloc evaluated_frame_info1 cuh ac ev mfbloc pc bs
- | AV_block( n, bs) ->
- evaluate_location_description_bytes c dloc evaluated_frame_info1 cuh ac ev mfbloc pc bs
- | AV_sec_offset n ->
- let location_list1 = (find_location_list dloc n) in
- let (offset,(llis: location_list_item list)) = location_list1 in
- let f (lli:location_list_item) : single_location_description option=
- ((match lli with
- | LLI_lle lle ->
- if Nat_big_num.greater_equal pc lle.lle_beginning_address_offset && Nat_big_num.less pc lle.lle_ending_address_offset then Some lle.lle_single_location_description else None
- | LLI_base _ ->
- None (* TODO: either refactor to do offset during parsing or update base offsets here. Should refactor to use "interpreted". *)
- )) in
- (match myfindmaybe f llis with
- | Some bs ->
- evaluate_location_description_bytes c dloc evaluated_frame_info1 cuh ac ev mfbloc pc bs
- | None ->
- Fail "evaluate_location_description didn't find pc in location list ranges"
- )
- | _ -> Fail "evaluate_location_description av_location not understood"
- ))
-
-
-
-
-
-(** ************************************************************ *)
-(** **** evaluation of frame information ********************** *)
-(** ************************************************************ *)
-
-(** register maps *)
-
-(*val rrp_update : register_rule_map -> cfa_register -> register_rule -> register_rule_map*)
-let rrp_update rrp r rr:(Nat_big_num.num*register_rule)list= ((r,rr)::rrp)
-
-(*val rrp_lookup : cfa_register -> register_rule_map -> register_rule*)
-let rrp_lookup r rrp:register_rule=
- ((match (lookupBy Nat_big_num.equal r rrp) with
- | Some rr -> rr
- | None -> RR_undefined
- ))
-
-(*val rrp_empty : register_rule_map*)
-let rrp_empty:(cfa_register*register_rule)list= ([])
-
-
-
-(** pp of evaluated cfa information from .debug_frame *)
-(* readelf --debug-dump=frames-interp test/a.out
-
-Contents of the .eh_frame section:
-
-00000000 00000014 00000000 CIE "zR" cf=1 df=-8 ra=16
- LOC CFA ra
-0000000000000000 rsp+8 c-8
-
-00000018 00000024 0000001c FDE cie=00000000 pc=004003b0..004003d0
- LOC CFA ra
-00000000004003b0 rsp+16 c-8
-00000000004003b6 rsp+24 c-8
-00000000004003c0 exp c-8
-
-00000040 0000001c 00000044 FDE cie=00000000 pc=004004b4..004004ba
- LOC CFA rbp ra
-00000000004004b4 rsp+8 u c-8
-00000000004004b5 rsp+16 c-16 c-8
-00000000004004b8 rbp+16 c-16 c-8
-00000000004004b9 rsp+8 c-16 c-8
-
-00000060 00000024 00000064 FDE cie=00000000 pc=004004c0..00400549
- LOC CFA rbx rbp r12 r13 r14 r15 ra
-00000000004004c0 rsp+8 u u u u u u c-8
-00000000004004d1 rsp+8 u c-48 c-40 u u u c-8
-00000000004004f0 rsp+64 c-56 c-48 c-40 c-32 c-24 c-16 c-8
-0000000000400548 rsp+8 c-56 c-48 c-40 c-32 c-24 c-16 c-8
-
-00000088 00000014 0000008c FDE cie=00000000 pc=00400550..00400552
- LOC CFA ra
-0000000000400550 rsp+8 c-8
-
-000000a0 ZERO terminator
-*)
-
-
-
-(*val mytoList : forall 'a. SetType 'a => set 'a -> list 'a*)
-
-let register_footprint_rrp (rrp: register_rule_map) : cfa_register Pset.set=
- (Pset.from_list Nat_big_num.compare (Lem_list.map fst rrp))
-
-let register_footprint (rows: cfa_table_row list) : cfa_register list=
- (Pset.elements (bigunionListMap
- instance_Basic_classes_SetType_Num_natural_dict (fun row -> register_footprint_rrp row.ctr_regs) rows))
-
-
-(*val max_lengths : list (list string) -> list natural*)
-let rec max_lengths xss:(Nat_big_num.num)list=
- ((match xss with
- | [] -> failwith "max_lengths"
- | xs::xss' ->
- let lens = (Lem_list.map (fun x -> Nat_big_num.of_int (String.length x)) xs) in
- if (listEqualBy (listEqualBy (=)) xss' []) then lens
- else
- let lens' = (max_lengths xss') in
- let z = (Lem_list.list_combine lens lens') in
- let lens'' = (Lem_list.map (fun (l1,l2)-> Nat_big_num.max l1 l2) z) in
- lens''
- ))
-
-let rec pad_row xs lens:(string)list=
- ((match (xs,lens) with
- | ([],[]) -> []
- | (x::xs', len::lens') -> right_space_padded_to len x :: pad_row xs' lens'
- ))
-
-let pad_rows (xss : ( string list) list) : string=
- (let lens = (max_lengths xss) in
- myconcat "" (Lem_list.map (fun xs -> myconcat " " (pad_row xs lens) ^ "\n") xss))
-
-let pp_evaluated_fde (fde1, (rows: cfa_table_row list)) : string=
- (let regs = (register_footprint rows) in
- let header : string list = ("LOC" :: ("CFA" :: Lem_list.map
- (pp_cfa_register instance_Show_Show_Num_natural_dict) regs)) in
- let ppd_rows : ( string list) list =
- (Lem_list.map (fun row -> pphex row.ctr_loc :: (pp_cfa_rule row.ctr_cfa :: Lem_list.map (fun r -> pp_register_rule (rrp_lookup r row.ctr_regs)) regs)) rows) in
- pad_rows (header :: ppd_rows))
-
-
-
-(** evaluation of cfa information from .debug_frame *)
-
-let evaluate_call_frame_instruction (fi: frame_info) (cie1: cie) (state1: cfa_state) (cfi: call_frame_instruction) : cfa_state=
-
- (let create_row (loc: Nat_big_num.num)=
- (let row = ({ state1.cs_current_row with ctr_loc = loc }) in
- { state1 with cs_current_row = row; cs_previous_rows = (state1.cs_current_row::state1.cs_previous_rows) }) in
-
- let update_cfa (cr:cfa_rule)=
- (let row = ({ state1.cs_current_row with ctr_cfa = cr }) in
- { state1 with cs_current_row = row }) in
-
- let update_reg r rr=
- (let row = ({ state1.cs_current_row with ctr_regs = (rrp_update state1.cs_current_row.ctr_regs r rr) }) in
- { state1 with cs_current_row = row }) in
-
- (match cfi with
- (* Row Creation Instructions *)
- | DW_CFA_set_loc a ->
- create_row a
- | DW_CFA_advance_loc d ->
- create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor))
- | DW_CFA_advance_loc1 d ->
- create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor))
- | DW_CFA_advance_loc2 d ->
- create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor))
- | DW_CFA_advance_loc4 d ->
- create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor))
-
- (* CFA Definition Instructions *)
- | DW_CFA_def_cfa( r, n) ->
- update_cfa (CR_register( r, ( n)))
- | DW_CFA_def_cfa_sf( r, i) ->
- update_cfa (CR_register( r, ( Nat_big_num.mul i cie1.cie_data_alignment_factor)))
- | DW_CFA_def_cfa_register r ->
- (match state1.cs_current_row.ctr_cfa with
- | CR_register( r', i) ->
- update_cfa (CR_register( r, i))
- | _ -> failwith "DW_CFA_def_cfa_register: current rule is not CR_register"
- )
- | DW_CFA_def_cfa_offset n ->
- (match state1.cs_current_row.ctr_cfa with
- | CR_register( r, i) ->
- update_cfa (CR_register( r, ( n)))
- | _ -> failwith "DW_CFA_def_cfa_offset: current rule is not CR_register"
- )
- | DW_CFA_def_cfa_offset_sf i ->
- (match state1.cs_current_row.ctr_cfa with
- | CR_register( r, i') ->
- update_cfa (CR_register( r, ( Nat_big_num.mul i' cie1.cie_data_alignment_factor)))
- | _ -> failwith "DW_CFA_def_cfa_offset_sf: current rule is not CR_register"
- )
- | DW_CFA_def_cfa_expression b ->
- update_cfa (CR_expression b)
-
- (* Register Rule Instrutions *)
- | DW_CFA_undefined r ->
- update_reg r (RR_undefined)
- | DW_CFA_same_value r ->
- update_reg r (RR_same_value)
- | DW_CFA_offset( r, n) ->
- update_reg r (RR_offset ( Nat_big_num.mul( n) cie1.cie_data_alignment_factor))
- | DW_CFA_offset_extended( r, n) ->
- update_reg r (RR_offset ( Nat_big_num.mul( n) cie1.cie_data_alignment_factor))
- | DW_CFA_offset_extended_sf( r, i) ->
- update_reg r (RR_offset ( Nat_big_num.mul i cie1.cie_data_alignment_factor))
- | DW_CFA_val_offset( r, n) ->
- update_reg r (RR_val_offset ( Nat_big_num.mul( n) cie1.cie_data_alignment_factor))
- | DW_CFA_val_offset_sf( r, i) ->
- update_reg r (RR_val_offset ( Nat_big_num.mul i cie1.cie_data_alignment_factor))
- | DW_CFA_register( r1, r2) ->
- update_reg r1 (RR_register r2)
- | DW_CFA_expression( r, b) ->
- update_reg r (RR_expression b)
- | DW_CFA_val_expression( r, b) ->
- update_reg r (RR_val_expression b)
- | DW_CFA_restore r ->
- update_reg r (rrp_lookup r state1.cs_initial_instructions_row.ctr_regs)
-(* RR_undefined if the lookup fails? *)
- | DW_CFA_restore_extended r ->
- update_reg r (rrp_lookup r state1.cs_initial_instructions_row.ctr_regs)
-
-(* Row State Instructions *)
-(* do these also push and restore the CFA rule? *)
- | DW_CFA_remember_state ->
- { state1 with cs_row_stack = (state1.cs_current_row :: state1.cs_row_stack) }
- | DW_CFA_restore_state ->
- (match state1.cs_row_stack with
- | r::rs -> { state1 with cs_current_row = r; cs_row_stack = rs }
- | [] -> failwith "DW_CFA_restore_state: empty row stack"
- )
-(* Padding Instruction *)
- | DW_CFA_nop ->
- state1
-
-(* Unknown *)
- | DW_CFA_unknown b ->
- failwith ("evaluate_call_frame_instruction: DW_CFA_unknown " ^ hex_string_of_byte b)
-
- ))
-
-
-
-let rec evaluate_call_frame_instructions (fi: frame_info) (cie1: cie) (state1: cfa_state) (cfis: call_frame_instruction list) : cfa_state=
- ((match cfis with
- | [] -> state1
- | cfi::cfis' ->
- let state' = (evaluate_call_frame_instruction fi cie1 state1 cfi) in
- evaluate_call_frame_instructions fi cie1 state' cfis'
- ))
-
-
-let evaluate_fde (fi: frame_info) (fde1:fde) : cfa_table_row list=
- (let cie1 = (find_cie fi fde1.fde_cie_pointer) in
- let final_location = (Nat_big_num.add fde1.fde_initial_location_address fde1.fde_address_range) in
- let initial_cfa_state =
- (let initial_row =
- ({
- ctr_loc = (fde1.fde_initial_location_address);
- ctr_cfa = CR_undefined;
- ctr_regs = rrp_empty;
- }) in
- {
- cs_current_row = initial_row;
- cs_previous_rows = ([]);
- cs_initial_instructions_row = initial_row;
- cs_row_stack = ([]);
- })
- in
- let state' =
- (evaluate_call_frame_instructions fi cie1 initial_cfa_state cie1.cie_initial_instructions) in
- let initial_row' = (state'.cs_current_row) in
- let state'' = ({ initial_cfa_state with cs_current_row = initial_row'; cs_initial_instructions_row = initial_row' }) in
- let state''' =
- (evaluate_call_frame_instructions fi cie1 (*final_location*) state'' fde1.fde_instructions) in
- List.rev (state'''.cs_current_row:: state'''.cs_previous_rows))
-
-
-
-(*val evaluate_frame_info : dwarf -> evaluated_frame_info*)
-let evaluate_frame_info (d: dwarf) : evaluated_frame_info=
- (Lem_list.mapMaybe (fun fie -> (match fie with FIE_fde fde1 -> Some (fde1, (evaluate_fde d.d_frame_info fde1)) | FIE_cie _ -> None )) d.d_frame_info)
-
-let pp_evaluated_frame_info (efi: evaluated_frame_info):string=
- (myconcat "\n" (Lem_list.map pp_evaluated_fde efi))
-
-
-
-(** ************************************************************ *)
-(** ** analysis of location and frame data for reverse mapping *)
-(** ************************************************************ *)
-
-(** analysis *)
-
-(*val find_dies_in_die : (die->bool) -> compilation_unit -> list die -> die -> list (compilation_unit * (list die) * die)*)
-let rec find_dies_in_die (p:die->bool) (cu:compilation_unit) (parents: die list) (d: die):(compilation_unit*(die)list*die)list=
- (let ds = (List.concat (map (find_dies_in_die p cu (d::parents)) d.die_children)) in
- if p d then (cu,parents,d)::ds else ds)
-
-let find_dies (p:die->bool) (d: dwarf) : (compilation_unit * ( die list) * die) list=
- (List.concat (map (fun cu -> find_dies_in_die p cu [] cu.cu_die) d.d_compilation_units))
-
-
-(** simple-minded analysis of location *)
-
-let analyse_locations_raw c (d: dwarf):string=
-
- (let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in
-
- (* find all DW_TAG_variable and DW_TAG_formal_parameter dies with a DW_AT_name attribute *)
- let tags = (Lem_list.map tag_encode ["DW_TAG_variable"; "DW_TAG_formal_parameter"]) in
- let dies : (compilation_unit * ( die list) * die) list =
- (find_dies
- (fun die1 ->
- Lem_list.elem
- instance_Basic_classes_Eq_Num_natural_dict die1.die_abbreviation_declaration.ad_tag tags
- && has_attribute "DW_AT_name" die1)
- d) in
-
- myconcat ""
- (Lem_list.map
- (fun (cu,parents,die1) ->
-
- let ats = (Lem_list.list_combine
- die1.die_abbreviation_declaration.ad_attribute_specifications
- die1.die_attribute_values) in
-
- let find_ats (s:string)= (myfindNonPure (fun (((at: Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) -> Nat_big_num.equal (attribute_encode s) at) ats) in
-
- let ((_,_),(_,av_name)) = (find_ats "DW_AT_name") in
-
- let name1 =
- ((match av_name with
- | AV_string bs -> string_of_bytes bs
- | AV_strp n -> pp_debug_str_entry d.d_str n
- | _ -> "av_name AV not understood"
- )) in
-
-
- let ((_,_),(_,av_location)) = (find_ats "DW_AT_location") in
-
- let ppd_location =
- ((match av_location with
- | AV_exprloc( n, bs) -> " "^(parse_and_pp_operations c cuh_default bs^"\n")
- | AV_block( n, bs) -> " "^(parse_and_pp_operations c cuh_default bs^"\n")
- | AV_sec_offset n ->
- let location_list1 = (myfindNonPure (fun (n',_)->Nat_big_num.equal n' n) d.d_loc) in
- pp_location_list c cuh_default location_list1
- | _ -> "av_location AV not understood"
- )) in
-
- pp_tag_encoding die1.die_abbreviation_declaration.ad_tag ^ (" " ^ (name1 ^ (":\n" ^ (ppd_location ^ "\n")))) )
-
- dies))
-
-
-(** more proper analysis of locations *)
-
-(* TODO: handle this:
-In a variable entry representing the definition of a variable (that is, with no
-DW_AT_declaration attribute) if no location attribute is present, or if the location attribute is
-present but has an empty location description (as described in Section 2.6), the variable is
-assumed to exist in the source code but not in the executable program (but see number 10,
-below).
-In a variable entry representing a non-defining declaration of a variable, the location
-specified modifies the location specified by the defining declaration and only applies for the
-scope of the variable entry; if no location is specified, then the location specified in the
-defining declaration applies.
-The location of a variable may be further specified with a DW_AT_segment attribute, if
-appropriate.
-*)
-
-
-(*
-if there's a DW_AT_location that's a location list (DW_FORM_sec_offset/AV_sec_offset) : use that for both the range(s) and location; interpret the range(s) wrt the applicable base address of the compilation unit
-
-if there's a DW_AT_location that's a location expression (DW_FORM_exprloc/AV_exprloc or DW_block/AV_block), look for the closest enclosing range:
- - DW_AT_low_pc (AV_addr) and no DW_AT_high_pc or DW_AT_ranges: just the singleton address
- - DW_AT_low_pc (AV_addr) and DW_AT_high_pc (either an absolute AV_addr or an offset AV_constantN/AV_constant_SLEB128/AV_constantULEB128) : that range
- - DW_AT_ranges (DW_FORM_sec_offset/AV_sec_offset) : get a range list from .debug_ranges; interpret wrt the applicable base address of the compilation unit
- - for compilation units: a DW_AT_ranges together with a DW_AT_low_pc to specify the default base address to use in interpeting location and range lists
-
-DW_OP_fbreg in location expressions evaluate the DW_AT_frame_base of
-the closest enclosing function - which is either a location expression
-or a location list (what happens if the ranges of that location list
-don't cover where we are?)
-
-For each variable and formal parameter that has a DW_AT_name, we'll calculate a list of pairs of a concrete (low,high) range and a location expression.
-*)
-
-let rec closest_enclosing_range c (dranges: range_list_list) (cu_base_address1: Nat_big_num.num) (parents: die list) : ( (Nat_big_num.num * Nat_big_num.num)list)option=
- ((match parents with
- | [] -> None
- | die1::parents' ->
- (match (find_attribute_value "DW_AT_low_pc" die1, find_attribute_value "DW_AT_high_pc" die1, find_attribute_value "DW_AT_ranges" die1) with
- | (Some (AV_addr n), None, None ) -> Some [(n,Nat_big_num.add n(Nat_big_num.of_int 1))] (* unclear if this case is used? *)
- | (Some (AV_addr n1), Some (AV_addr n2), None ) -> Some [(n1,n2)]
- | (Some (AV_addr n1), Some (AV_constant_ULEB128 n2), None ) -> Some [(n1,Nat_big_num.add n1 n2)] (* should be mod all? *)
- | (Some (AV_addr n1), Some (AV_constant_SLEB128 i2), None ) -> Some [(n1, Nat_big_num.abs ( Nat_big_num.add( n1) i2))] (* should
- be mod all? *)
- | (Some (AV_addr n1), Some (AV_constantN( _, _)), None ) -> failwith "AV_constantN in closest_enclosing_range"
-
- | (Some (AV_addr n1), Some (AV_block( n, bs)), None ) -> let n2 = (natural_of_bytes c.endianness bs) in Some [(n1,Nat_big_num.add n1 n2)] (* should be mod all? *) (* signed or unsigned interp? *)
-
- | (_, None, Some (AV_sec_offset n)) ->
- let rlis = (snd (find_range_list dranges n)) in
- let nns = (interpret_range_list cu_base_address1 rlis) in
- Some nns
- | (None, None, None ) -> closest_enclosing_range c dranges cu_base_address1 parents'
- | (_, _, _ ) -> Some [] (*Assert_extra.failwith "unexpected attribute values in closest_enclosing_range"*)
- )
- ))
-
-(*
-If one of the DW_FORM_data<n> forms is used to represent a signed or unsigned integer, it
-can be hard for a consumer to discover the context necessary to determine which
-interpretation is intended. Producers are therefore strongly encouraged to use
-DW_FORM_sdata or DW_FORM_udata for signed and unsigned integers respectively,
-rather than DW_FORM_data<n>.
-no kidding - if we get an AV_constantN for DW_AT_high_pc, should it be interpreted as signed or unsigned? *)
-
-
-let rec closest_enclosing_frame_base dloc (base_address1: Nat_big_num.num) (parents: die list) : attribute_value option=
- ((match parents with
- | [] -> None
- | die1::parents' ->
- (match find_attribute_value "DW_AT_frame_base" die1 with
- | Some av -> Some av
- | None -> closest_enclosing_frame_base dloc base_address1 parents'
- )
- ))
-
-
-
-
-let interpreted_location_of_die c cuh (dloc: location_list_list) (dranges: range_list_list) (base_address1: Nat_big_num.num) (parents: die list) (die1: die) : ( (Nat_big_num.num * Nat_big_num.num * single_location_description)list)option=
-(
-
- (* for a simple location expression bs, we look in the enclosing die
- tree to find the associated pc range *)let location bs=
- ((match closest_enclosing_range c dranges base_address1 (die1::parents) with
- | Some nns ->
- Some (Lem_list.map (fun (n1,n2) -> (n1,n2,bs)) nns)
- | None ->
- (* if there is no such range, we take the full 0 - 0xfff.fff range*)
- Some [(Nat_big_num.of_int 0,(arithmetic_context_of_cuh cuh).ac_max,bs)]
- )) in
-
- (match find_attribute_value "DW_AT_location" die1 with
- | Some (AV_exprloc( n, bs)) -> location bs
- | Some (AV_block( n, bs)) -> location bs
- (* while for a location list, we take the associated pc range from
- each element of the list *)
- | Some (AV_sec_offset n) ->
- let (_,llis) = (find_location_list dloc n) in
- Some (interpret_location_list base_address1 llis)
- | None -> None
- ))
-
-
-let cu_base_address cu:Nat_big_num.num=
- ((match find_attribute_value "DW_AT_low_pc" cu.cu_die with
- | Some (AV_addr n) -> n
- | _ ->Nat_big_num.of_int 0 (*Nothing*) (*Assert_extra.failwith "no cu DW_AT_low_pc"*)
- ))
-
-
-(*val analyse_locations : dwarf -> analysed_location_data*)
-let analyse_locations (d: dwarf) : analysed_location_data=
-
- (let c : p_context = ({ endianness = (d.d_endianness) }) in
-
- let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in
-
- (* find all DW_TAG_variable and DW_TAG_formal_parameter dies with a DW_AT_name and DW_AT_location attribute *)
- let tags = (Lem_list.map tag_encode ["DW_TAG_variable"; "DW_TAG_formal_parameter"]) in
- let dies : (compilation_unit * ( die list) * die) list =
- (find_dies
- (fun die1 ->
- Lem_list.elem
- instance_Basic_classes_Eq_Num_natural_dict die1.die_abbreviation_declaration.ad_tag tags
- && (has_attribute "DW_AT_name" die1
- && has_attribute "DW_AT_location" die1))
- d) in
-
- Lem_list.map
- (fun ((((cu:compilation_unit), (parents: die list), (die1: die)) as x)) ->
- let base_address1 = (cu_base_address cu) in
- let interpreted_locations : ( (Nat_big_num.num * Nat_big_num.num * single_location_description)list)option =
- (interpreted_location_of_die c cuh_default d.d_loc d.d_ranges base_address1 parents die1) in
- (x,interpreted_locations)
- )
- dies)
-
-
-
-let pp_analysed_locations1 c cuh (nnls: (Nat_big_num.num * Nat_big_num.num * single_location_description) list) : string=
- (myconcat ""
- (Lem_list.map
- (fun (n1,n2,bs) -> " " ^ (pphex n1 ^ (" " ^ (pphex n2 ^ (" " ^ (parse_and_pp_operations c cuh bs ^ "\n"))))))
- nnls))
-
-let pp_analysed_locations2 c cuh mnnls:string=
- ((match mnnls with
- | Some nnls -> pp_analysed_locations1 c cuh nnls
- | None -> " <no locations>\n"
- ))
-
-let pp_analysed_locations3 c cuh str (als: analysed_location_data) : string=
- (myconcat "\n"
- (Lem_list.map
- (fun ((cu,parents,die1),mnnls) ->
- pp_die_abbrev c cuh str(Nat_big_num.of_int 0) false parents die1
- ^ pp_analysed_locations2 c cuh mnnls
- )
- als
- ))
-
-let pp_analysed_location_data (d: dwarf) (als: analysed_location_data) : string=
- (let c : p_context = ({ endianness = (d.d_endianness) }) in
- let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in
- pp_analysed_locations3 c (*HACK*) cuh_default d.d_str als)
-
-
-
-let pp_analysed_location_data_at_pc (d: dwarf) (alspc: analysed_location_data_at_pc) : string=
- (myconcat "" (Lem_list.map
- (fun ((cu,parents,die1),(n1,n2,sld,esl)) ->
- " " ^
- (let name1 =
- ((match find_name_of_die d.d_str die1 with
- | Some s -> s
- | None -> "<no name>\n"
- )) in
- (match esl with
- | Success sl ->
- name1 ^ (" @ " ^ (pp_single_location sl ^"\n"))
-
- | Fail e -> name1 ^ (" @ " ^ ("<fail: " ^ (e ^ ">\n")))
- ))
- )
- alspc))
-
-
-(*val analysed_locations_at_pc : evaluation_context -> dwarf_static -> natural -> analysed_location_data_at_pc*)
-let analysed_locations_at_pc
- (ev)
- (ds: dwarf_static)
- (pc: Nat_big_num.num)
- : analysed_location_data_at_pc=
-
-(let c : p_context = ({ endianness = (ds.ds_dwarf.d_endianness) }) in
-
- let xs =
- (Lem_list.mapMaybe
- (fun (cupd,mnns) ->
- (match mnns with
- | None -> None
- | Some nns ->
- let nns' = (List.filter (fun (n1,n2,sld) -> Nat_big_num.greater_equal pc n1 && Nat_big_num.less pc n2) nns) in
- (match nns' with
- | [] -> None
- | _ -> Some (cupd,nns')
- )
- ))
- ds.ds_analysed_location_data)
-in
-
-List.concat
- (Lem_list.map
- (fun ((cu,parents,die1),nns) ->
- let ac = (arithmetic_context_of_cuh cu.cu_header) in
- let base_address1 = (cu_base_address cu) in
- let mfbloc : attribute_value option =
- (closest_enclosing_frame_base ds.ds_dwarf.d_loc base_address1 parents) in
- Lem_list.map
- (fun (n1,n2,sld) ->
- let el : single_location error =
- (evaluate_location_description_bytes c ds.ds_dwarf.d_loc ds.ds_evaluated_frame_info cu.cu_header ac ev mfbloc pc sld) in
- ((cu,parents,die1),(n1,n2,sld,el))
- )
- nns
- )
- xs))
-
-(*val names_of_address : dwarf -> analysed_location_data_at_pc -> natural -> list string*)
-let names_of_address
- (d: dwarf)
- (alspc: analysed_location_data_at_pc)
- (address: Nat_big_num.num)
- : string list=
-
-(Lem_list.mapMaybe
- (fun ((cu,parents,die1),(n1,n2,sld,esl)) ->
- (match esl with
- | Success (SL_simple (SL_memory_address a)) ->
- if Nat_big_num.equal a address then
- (match find_name_of_die d.d_str die1 with
- | Some s -> Some s
- | None -> None
- )
- else
- None
- | Success _ -> None (* just suppress? *)
- | Fail e -> None (* just suppress? *)
- )
- )
- alspc)
-
-
-(** ************************************************************ *)
-(** ** evaluation of line-number info *)
-(** ************************************************************ *)
-
-let initial_line_number_registers (lnh: line_number_header) : line_number_registers=
- ({
- lnr_address =(Nat_big_num.of_int 0);
- lnr_op_index =(Nat_big_num.of_int 0);
- lnr_file =(Nat_big_num.of_int 1);
- lnr_line =(Nat_big_num.of_int 1);
- lnr_column =(Nat_big_num.of_int 0);
- lnr_is_stmt = (lnh.lnh_default_is_stmt);
- lnr_basic_block = false;
- lnr_end_sequence = false;
- lnr_prologue_end = false;
- lnr_epilogue_begin = false;
- lnr_isa =(Nat_big_num.of_int 0);
- lnr_discriminator =(Nat_big_num.of_int 0);
- })
-
-let evaluate_line_number_operation
- (lnh: line_number_header)
- ((s: line_number_registers), (lnrs: line_number_registers list))
- (lno: line_number_operation)
- : line_number_registers * line_number_registers list=
-
- (let new_address s operation_advance= (Nat_big_num.add s.lnr_address (Nat_big_num.mul
- lnh.lnh_minimum_instruction_length
- (Nat_big_num.div( Nat_big_num.add s.lnr_op_index operation_advance)lnh.lnh_maximum_operations_per_instruction))) in
- let new_op_index s operation_advance= (Nat_big_num.modulus
- ( Nat_big_num.add s.lnr_op_index operation_advance) lnh.lnh_maximum_operations_per_instruction) in
-
- (match lno with
- | DW_LN_special adjusted_opcode ->
- let operation_advance = (Nat_big_num.div adjusted_opcode lnh.lnh_line_range) in
- let line_increment = (Nat_big_num.add lnh.lnh_line_base (( Nat_big_num.modulus adjusted_opcode lnh.lnh_line_range))) in
- let s' =
- ({ s with
- lnr_line = (partialNaturalFromInteger ( Nat_big_num.add( s.lnr_line) line_increment));
- lnr_address = (new_address s operation_advance);
- lnr_op_index = (new_op_index s operation_advance);
- }) in
- let lnrs' = (s'::lnrs) in
- let s'' =
-({ s' with
- lnr_basic_block = false;
- lnr_prologue_end = false;
- lnr_epilogue_begin = false;
- lnr_discriminator =(Nat_big_num.of_int 0);
- }) in
- (s'', lnrs')
- | DW_LNS_copy ->
- let lnrs' = (s::lnrs) in
- let s' =
-({ s with
- lnr_basic_block = false;
- lnr_prologue_end = false;
- lnr_epilogue_begin = false;
- lnr_discriminator =(Nat_big_num.of_int 0);
- }) in
- (s', lnrs')
- | DW_LNS_advance_pc operation_advance ->
- let s' =
- ({ s with
- lnr_address = (new_address s operation_advance);
- lnr_op_index = (new_op_index s operation_advance);
- }) in
- (s', lnrs)
- | DW_LNS_advance_line line_increment ->
- let s' = ({ s with lnr_line = (partialNaturalFromInteger ( Nat_big_num.add( s.lnr_line) line_increment)) }) in (s', lnrs)
- | DW_LNS_set_file n ->
- let s' = ({ s with lnr_file = n }) in (s', lnrs)
- | DW_LNS_set_column n ->
- let s' = ({ s with lnr_column = n }) in (s', lnrs)
- | DW_LNS_negate_stmt ->
- let s' = ({ s with lnr_is_stmt = (not s.lnr_is_stmt) }) in (s', lnrs)
- | DW_LNS_set_basic_block ->
- let s' = ({ s with lnr_basic_block = true }) in (s', lnrs)
- | DW_LNS_const_add_pc ->
- let opcode =(Nat_big_num.of_int 255) in
- let adjusted_opcode = (Nat_big_num.sub_nat opcode lnh.lnh_opcode_base) in
- let operation_advance = (Nat_big_num.div adjusted_opcode lnh.lnh_line_range) in
- let s' =
- ({ s with
- lnr_address = (new_address s operation_advance);
- lnr_op_index = (new_op_index s operation_advance);
- }) in
- (s', lnrs)
- | DW_LNS_fixed_advance_pc n ->
- let s' =
- ({ s with
- lnr_address = (Nat_big_num.add s.lnr_address n);
- lnr_op_index =(Nat_big_num.of_int 0);
- }) in
- (s', lnrs)
- | DW_LNS_set_prologue_end ->
- let s' = ({ s with lnr_prologue_end = true }) in (s', lnrs)
- | DW_LNS_set_epilogue_begin ->
- let s' = ({ s with lnr_epilogue_begin = true }) in (s', lnrs)
- | DW_LNS_set_isa n ->
- let s' = ({ s with lnr_isa = n }) in (s', lnrs)
- | DW_LNE_end_sequence ->
- let s' = ({ s with lnr_end_sequence = true }) in
- let lnrs' = (s' :: lnrs) in
- let s'' = (initial_line_number_registers lnh) in
- (s'', lnrs')
- | DW_LNE_set_address n ->
- let s' =
- ({ s with
- lnr_address = n;
- lnr_op_index =(Nat_big_num.of_int 0);
- }) in
- (s', lnrs)
- | DW_LNE_define_file( s, n1, n2, n3) ->
- failwith "DW_LNE_define_file not implemented" (*TODO: add to file list in header - but why is this in the spec? *)
- | DW_LNE_set_discriminator n ->
- let s' = ({ s with lnr_discriminator = n }) in (s', lnrs)
- ))
-
-let rec evaluate_line_number_operations
- (lnh: line_number_header)
- ((s: line_number_registers), (lnrs: line_number_registers list))
- (lnos: line_number_operation list)
- : line_number_registers * line_number_registers list=
- ((match lnos with
- | [] -> (s,lnrs)
- | lno :: lnos' ->
- let (s',lnrs') =
- (evaluate_line_number_operation lnh (s,lnrs) lno) in
- evaluate_line_number_operations lnh (s',lnrs') lnos'
- ))
-
-let evaluate_line_number_program
- (lnp:line_number_program)
- : line_number_registers list=
- (List.rev (snd (evaluate_line_number_operations lnp.lnp_header ((initial_line_number_registers lnp.lnp_header),[]) lnp.lnp_operations)))
-
-
-let pp_line_number_registers lnr:string=
- (""
- ^ ("address = " ^ (pphex lnr.lnr_address ^ ("\n"
- ^ ("op_index = " ^ (Nat_big_num.to_string lnr.lnr_op_index ^ ("\n"
- ^ ("file = " ^ (Nat_big_num.to_string lnr.lnr_file ^ ("\n"
- ^ ("line = " ^ (Nat_big_num.to_string lnr.lnr_line ^ ("\n"
- ^ ("column = " ^ (Nat_big_num.to_string lnr.lnr_column ^ ("\n"
- ^ ("is_stmt = " ^ (string_of_bool lnr.lnr_is_stmt ^ ("\n"
- ^ ("basic_block = " ^ (string_of_bool lnr.lnr_basic_block ^ ("\n"
- ^ ("end_sequence = " ^ (string_of_bool lnr.lnr_end_sequence ^ ("\n"
- ^ ("prologue_end = " ^ (string_of_bool lnr.lnr_prologue_end ^ ("\n"
- ^ ("epilogue_begin = " ^ (string_of_bool lnr.lnr_epilogue_begin ^ ("\n"
- ^ ("isa = " ^ (Nat_big_num.to_string lnr.lnr_isa ^ ("\n"
- ^ ("discriminator = " ^ (pphex lnr.lnr_discriminator ^ "\n"))))))))))))))))))))))))))))))))))))
-
-let pp_line_number_registers_tight lnr : string list=
- ([
- pphex lnr.lnr_address ;
- Nat_big_num.to_string lnr.lnr_op_index ;
- Nat_big_num.to_string lnr.lnr_file ;
- Nat_big_num.to_string lnr.lnr_line ;
- Nat_big_num.to_string lnr.lnr_column ;
- string_of_bool lnr.lnr_is_stmt ;
- string_of_bool lnr.lnr_basic_block ;
- string_of_bool lnr.lnr_end_sequence ;
- string_of_bool lnr.lnr_prologue_end ;
- string_of_bool lnr.lnr_epilogue_begin ;
- Nat_big_num.to_string lnr.lnr_isa ;
- pphex lnr.lnr_discriminator
- ])
-
-let pp_line_number_registerss lnrs:string=
- (pad_rows
- (
- ["address"; "op_index"; "file"; "line"; "column"; "is_stmt"; "basic_block"; "end_sequence"; "prologue_end"; "epilogue_begin"; "isa"; "discriminator"]
- ::
- (Lem_list.map pp_line_number_registers_tight lnrs)
- ))
-
-let pp_evaluated_line_info (eli: evaluated_line_info) : string=
- (myconcat "\n" (Lem_list.map (fun (lnh,lnrs) -> pp_line_number_header lnh ^ ("\n" ^ pp_line_number_registerss lnrs)) eli))
-
-(* readef example:
-Decoded dump of debug contents of section .debug_line:
-
-CU: /var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/test-concurrent.c:
-File name Line number Starting address
-test-concurrent.c 11 0x400144
-
-test-concurrent.c 12 0x40014c
-test-concurrent.c 13 0x400154
-test-concurrent.c 14 0x400158
-test-concurrent.c 17 0x400160
-
-/var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/../thread_start_aarch64.h:
-thread_start_aarch64.h 34 0x400168
-thread_start_aarch64.h 36 0x400174
-
-/var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/test-concurrent.c:
-test-concurrent.c 19 0x400174
-
-test-concurrent.c 20 0x40017c
-test-concurrent.c 22 0x400180
-
-CU: /var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/malloc.c:
-...
-*)
-
-
-let source_lines_of_address (ds:dwarf_static) (a: Nat_big_num.num) : (string * Nat_big_num.num * line_number_registers) list=
- (List.concat
- (Lem_list.map
- (fun (lnh, lnrs) ->
- myfiltermaybe
- (fun lnr ->
- if Nat_big_num.equal a lnr.lnr_address && not lnr.lnr_end_sequence then
- (match mynth ( Nat_big_num.sub_nat lnr.lnr_file(Nat_big_num.of_int 1)) lnh.lnh_file_names with
- | Some lnfe ->
- Some (string_of_bytes lnfe.lnfe_path, lnr.lnr_line, lnr)
- | None ->
- Some ("<source_lines_of_address: file entry not found>",Nat_big_num.of_int 0, lnr)
- )
- else
- None)
- lnrs
- )
- ds.ds_evaluated_line_info
- ))
-
-
-(** ************************************************************ *)
-(** ** collecting all the statically calculated analysis info *)
-(** ************************************************************ *)
-
-(*val extract_dwarf_static : elf_file -> maybe dwarf_static*)
-let extract_dwarf_static f1:(dwarf_static)option=
- ((match extract_dwarf f1 with
- | None -> None
- | Some dwarf1 ->
- let _ = (my_debug5 (pp_dwarf dwarf1)) in
-
- let ald : analysed_location_data =
- (analyse_locations dwarf1) in
- let efi : evaluated_frame_info =
- (evaluate_frame_info dwarf1) in
- let eli : evaluated_line_info =
- (Lem_list.map (fun lnp -> (lnp.lnp_header, evaluate_line_number_program lnp)) dwarf1.d_line_info) in
- let ds =
- ({
- ds_dwarf = dwarf1;
- ds_analysed_location_data = ald;
- ds_evaluated_frame_info = efi;
- ds_evaluated_line_info = eli;
- }) in
- Some ds
- ))
-
-
-
-
-(** ************************************************************ *)
-(** ** top level for main_elf ******************************** *)
-(** ************************************************************ *)
-
-(*val harness_string_of_elf : elf_file -> byte_sequence -> string*)
-let harness_string_of_elf f1 bs:string=
- (let mds = (extract_dwarf_static f1) in
- (match mds with
- | None -> "<no dwarf information extracted>"
- | Some ds ->
- pp_dwarf ds.ds_dwarf
- (* ^ analyse_locations_raw c d *)
- ^ ("************** evaluation of frame data *************************\n"
- ^ (pp_evaluated_frame_info ds.ds_evaluated_frame_info
- ^ ("************** analysis of location data *************************\n"
- ^ (pp_analysed_location_data ds.ds_dwarf ds.ds_analysed_location_data
- ^ ("************** line info *************************\n"
- ^ pp_evaluated_line_info ds.ds_evaluated_line_info)))))
- ))
-
-
-(*val harness_string_of_elf64_debug_info_section : elf64_file -> byte_sequence -> (*(natural -> string) -> (natural -> string) -> (natural -> string) -> elf64_header -> elf64_section_header_table -> string_table -> *) string*)
-let harness_string_of_elf64_debug_info_section f1 bs0:string=
- ( (*os proc usr hdr sht stbl*)harness_string_of_elf (ELF_File_64 f1) bs0)
-
-(*val harness_string_of_elf32_debug_info_section : elf32_file -> byte_sequence -> (* (natural -> string) -> (natural -> string) -> (natural -> string) -> elf32_header -> elf32_section_header_table -> string_table ->*) string*)
-let harness_string_of_elf32_debug_info_section f1 bs0:string=
- ( (*os proc usr hdr sht stbl*)harness_string_of_elf (ELF_File_32 f1) bs0)
-