aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--debug/DwarfTypes.ml277
-rw-r--r--debug/DwarfUtil.ml71
3 files changed, 349 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 2b668724..a0744c0d 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@
include Makefile.config
-DIRS=lib common $(ARCH) backend cfrontend driver \
+DIRS=lib common $(ARCH) backend cfrontend driver debug\
flocq/Core flocq/Prop flocq/Calc flocq/Appli exportclight \
cparser cparser/validator
diff --git a/debug/DwarfTypes.ml b/debug/DwarfTypes.ml
new file mode 100644
index 00000000..70d31ef8
--- /dev/null
+++ b/debug/DwarfTypes.ml
@@ -0,0 +1,277 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Bernhard Schommer, AbsInt Angewandte Informatik GmbH *)
+(* *)
+(* AbsInt Angewandte Informatik GmbH. All rights reserved. This file *)
+(* is distributed under the terms of the INRIA Non-Commercial *)
+(* License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(* Types used for writing dwarf debug information *)
+
+(* Basic types for the value of attributes *)
+
+type constant = int
+
+type flag = bool
+
+type reference = int
+
+type encoding =
+ | DW_ATE_address
+ | DW_ATE_boolean
+ | DW_ATE_complex_float
+ | DW_ATE_float
+ | DW_ATE_signed
+ | DW_ATE_signed_char
+ | DW_ATE_unsigned
+ | DW_ATE_unsigned_char
+
+type identifier_case =
+ | DW_ID_case_sensitive
+ | DW_ID_up_case
+ | DW_ID_down_case
+ | DW_ID_case_insensitive
+
+type address = int
+
+type language =
+ | DW_LANG_C
+ | DW_LANG_C89
+
+type block = string (* Used as bitvector *)
+
+type calling_convention =
+ | DW_CC_normal
+ | DW_CC_program
+ | DW_CC_nocall
+ | DW_CC_lo_user
+ | DW_CC_hi_user
+
+type inline =
+ | DW_INL_not_inlined
+ | DW_INL_inlined
+ | DW_INL_declared_not_inlined
+ | DW_INL_declared_inlined
+
+type const_value =
+ | String of string
+ | Const of constant
+ | Block of block
+
+type location_value =
+ | Const of constant
+ | Block of block
+
+type data_location_value =
+ | Block of block
+ | Ref of reference
+
+type bound_value =
+ | Const of constant
+ | Ref of reference
+
+(* Types representing the attribute information per tag value *)
+
+type dw_tag_array_type =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_type: reference;
+ }
+
+type dw_tag_base_type =
+ {
+ dw_at_byte_size: constant;
+ dw_at_encoding: encoding;
+ dw_at_name: string;
+ }
+
+type dw_tag_compile_unit =
+ {
+ dw_at_base_types: reference option;
+ dw_at_comp_dir: string;
+ dw_at_identifier_case: identifier_case option;
+ dw_at_high_pc: address;
+ dw_at_language: language;
+ dw_at_low_pc: address;
+ dw_at_macro_info: constant option;
+ dw_at_name: string;
+ dw_at_producer: string;
+ dw_at_stmt_list: constant option;
+ }
+
+type dw_tag_const_type =
+ {
+ dw_at_type: reference;
+ }
+
+type dw_tag_enumeration_type =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_byte_size: constant;
+ dw_at_declaration: flag option;
+ dw_at_name: string;
+ dw_at_start_scope: constant option;
+ }
+
+type dw_tag_enumerator =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_const_value: constant;
+ dw_at_name: string;
+ }
+
+type dw_tag_formal_parameter =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_artificial: flag option;
+ dw_at_location: location_value option;
+ dw_at_name: string;
+ dw_at_segment: location_value option;
+ dw_at_type: reference;
+ dw_at_variable_parameter: flag option;
+ }
+
+type dw_tag_label =
+ {
+ dw_at_low_pc: address;
+ dw_at_name: string;
+ }
+
+type dw_tag_lexical_block =
+ {
+ dw_at_high_pc: address;
+ dw_at_low_pc: address;
+ }
+
+type dw_tag_member =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_byte_size: constant option;
+ dw_at_bit_offset: constant option;
+ dw_at_bit_size: constant option;
+ dw_at_data_member_location: data_location_value option;
+ dw_at_declaration: flag option;
+ dw_at_name: string;
+ dw_at_type: reference;
+ }
+
+type dw_tag_pointer_type =
+ {
+ dw_at_type: reference;
+ }
+
+type dw_tag_structure_type =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_byte_size: constant;
+ dw_at_declaration: flag option;
+ dw_at_name: string;
+ }
+
+type dw_tag_subprogram =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_external: flag option;
+ dw_at_frame_base: location_value option;
+ dw_at_high_pc: address;
+ dw_at_inline: inline option;
+ dw_at_low_pc: address;
+ dw_at_name: string;
+ dw_at_prototyped: flag;
+ dw_at_type: reference;
+ }
+
+type dw_tag_subrange_type =
+ {
+ dw_at_type: reference option;
+ dw_at_upper_bound: bound_value;
+ }
+
+type dw_tag_subroutine_type =
+ {
+ dw_at_prototyped: flag;
+ }
+
+type dw_tag_typedef =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_name: string;
+ dw_at_type: reference;
+ }
+
+type dw_tag_union_type =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_byte_size: constant;
+ dw_at_name: string;
+ }
+
+type dw_tag_unspecified_parameter =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_artificial: flag option;
+ }
+
+type dw_tag_variable =
+ {
+ dw_at_decl_file: constant option;
+ dw_at_decl_line: constant option;
+ dw_at_declaration: flag option;
+ dw_at_external: flag option;
+ dw_at_location: location_value option;
+ dw_at_name: string;
+ dw_at_segment: location_value option;
+ dw_at_type: reference;
+ }
+
+type dw_tag_volatile_type =
+ {
+ dw_at_type: reference;
+ }
+
+type dw_tag =
+ | DW_TAG_array_type of dw_tag_array_type
+ | DW_TAG_base_type of dw_tag_base_type
+ | DW_TAG_compile_unit of dw_tag_compile_unit
+ | DW_TAG_const_type of dw_tag_const_type
+ | DW_TAG_enumeration_type of dw_tag_enumeration_type
+ | DW_TAG_enumerator of dw_tag_enumerator
+ | DW_TAG_formal_parameter of dw_tag_formal_parameter
+ | DW_TAG_label of dw_tag_label
+ | DW_TAG_lexical_block of dw_tag_lexical_block
+ | DW_TAG_member of dw_tag_member
+ | DW_TAG_pointer_type of dw_tag_pointer_type
+ | DW_TAG_structure_type of dw_tag_structure_type
+ | DW_TAG_tag_subprogram of dw_tag_subprogram
+ | DW_TAG_subrange_type of dw_tag_subrange_type
+ | DW_TAG_subroutine_type of dw_tag_subroutine_type
+ | DW_TAG_typedef of dw_tag_typedef
+ | DW_TAG_union_type of dw_tag_union_type
+ | DW_TAG_unspecified_parameter of dw_tag_unspecified_parameter
+ | DW_TAG_variable of dw_tag_variable
+ | DW_TAG_volatile_type of dw_tag_volatile_type
+
+(* The type of the entries. *)
+
+type dw_entry =
+ {
+ tag: dw_tag;
+ children: dw_entry list;
+ id: reference;
+ }
+
+
diff --git a/debug/DwarfUtil.ml b/debug/DwarfUtil.ml
new file mode 100644
index 00000000..ec5495c1
--- /dev/null
+++ b/debug/DwarfUtil.ml
@@ -0,0 +1,71 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Bernhard Schommer, AbsInt Angewandte Informatik GmbH *)
+(* *)
+(* AbsInt Angewandte Informatik GmbH. All rights reserved. This file *)
+(* is distributed under the terms of the INRIA Non-Commercial *)
+(* License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(* Utility functions for the dwarf debuging type *)
+
+open DwarfTypes
+
+let id = ref 0
+
+let next_id () =
+ let nid = !id in
+ incr id; nid
+
+let reset_id () =
+ id := 0
+
+(* Hashtable to from type name to entry id *)
+let type_table: (string, int) Hashtbl.t = Hashtbl.create 7
+
+(* Generate a new entry from a given tag *)
+let new_entry tag =
+ let id = next_id () in
+ {
+ tag = tag;
+ children = [];
+ id = id;
+ }
+
+
+(* Add an entry as child to another entry *)
+let add_children entry child =
+ {entry with children = child::entry.children;}
+
+
+(* Iter over the tree in prefix order *)
+let rec entry_iter f entry =
+ f entry.tag;
+ List.iter (entry_iter f) entry.children
+
+(* Iter over the tree in prefix order with passing additional reference to next sibling *)
+let entry_iter_sibling f acc entry =
+ f None entry.tag;
+ let rec aux = (function
+ | [] -> ()
+ | [last] -> f None last.tag
+ | a::b::rest -> f (Some b.id) a.tag; aux (b::rest)) in
+ aux entry.children
+
+
+(* Fold over the tree in prefix order *)
+let rec entry_fold f acc entry =
+ let acc = f acc entry.tag in
+ List.fold_left (entry_fold f) acc entry.children
+
+(* Fold over the tree in prefix order with passing additional reference to next sibling *)
+let entry_fold_sibling f acc entry =
+ let acc = f acc None entry.tag in
+ let rec aux acc = (function
+ | [] -> acc
+ | [last] -> f acc None last.tag
+ | a::b::rest -> aux (f acc (Some b.id) a.tag) (b::rest)) in
+ aux acc entry.children