Hi,

On Monday 10 October 2005 09:06, Raphael wrote:
> Changelog:
>   - begin of dwarf debug lines parsing
>   - better robustness
>   - support of unamed syms
>   - better traces
>
> TODO:
>   - find a clean way to handle forward declarations
>   - debug lines parsing
>

as Eric wanted: without type.c modification
I'll try to improve it for next patch

Regards,
Raphael
Index: dbghelp_private.h
===================================================================
RCS file: /home/wine/wine/dlls/dbghelp/dbghelp_private.h,v
retrieving revision 1.16
diff -u -r1.16 dbghelp_private.h
--- dbghelp_private.h	17 May 2005 14:32:55 -0000	1.16
+++ dbghelp_private.h	13 Oct 2005 21:51:16 -0000
@@ -360,7 +360,8 @@
 extern BOOL         dwarf2_parse(struct module* module, unsigned long load_offset,
 				 const unsigned char* debug, unsigned int debug_size, 
 				 const unsigned char* abbrev, unsigned int abbrev_size, 
-				 const unsigned char* str, unsigned int str_sz);
+				 const unsigned char* str, unsigned int str_sz,
+				 const unsigned char* lines, unsigned int lines_sz);
 
 /* symbol.c */
 extern const char*  symt_get_name(const struct symt* sym);
@@ -436,10 +437,10 @@
 extern BOOL         symt_set_udt_size(struct module* module,
                                       struct symt_udt* type, unsigned size);
 extern BOOL         symt_add_udt_element(struct module* module, 
-                                         struct symt_udt* udt_type, 
-                                         const char* name,
-                                         struct symt* elt_type, unsigned offset, 
-                                         unsigned size);
+					 struct symt_udt* udt_type, 
+					 const char* name,
+					 struct symt* elt_type, unsigned offset, 
+					 unsigned size);
 extern struct symt_enum*
                     symt_new_enum(struct module* module, const char* typename);
 extern BOOL         symt_add_enum_element(struct module* module, 
@@ -452,8 +453,8 @@
                     symt_new_function_signature(struct module* module, 
                                                 struct symt* ret_type);
 extern BOOL         symt_add_function_signature_parameter(struct module* module,
-                                                          struct symt_function_signature* sig,
-                                                          struct symt* param);
+							   struct symt_function_signature* sig,
+							   struct symt* param);
 extern struct symt_pointer*
                     symt_new_pointer(struct module* module, 
                                      struct symt* ref_type);
Index: dwarf.c
===================================================================
RCS file: /home/wine/wine/dlls/dbghelp/dwarf.c,v
retrieving revision 1.7
diff -u -r1.7 dwarf.c
--- dwarf.c	27 Jun 2005 09:53:47 -0000	1.7
+++ dwarf.c	13 Oct 2005 21:51:18 -0000
@@ -90,6 +90,10 @@
  * example of projects who do dwarf2 parsing:
  *  http://www.x86-64.org/cgi-bin/cvsweb.cgi/binutils.dead/binutils/readelf.c?rev=1.1.1.2
  *  http://elis.ugent.be/diota/log/ltrace_elf.c
+ *
+ * dwarf3:
+ *  http://cvs.sourceforge.net/viewcvs.py/linux-vax/tools/src/binutils/readelf.c?rev=2.10.0.2&view=markup
+ *  http://cvs.sourceforge.net/viewcvs.py/linux-vax/tools/src/include/elf/dwarf2.h?rev=2.10.0.2&view=auto
  */
 
 typedef struct {
@@ -107,12 +111,23 @@
 } dwarf2_comp_unit_t;
 
 typedef struct {
+  unsigned char length[4];
+  unsigned char version[2];
+  unsigned char prologue_length[4];
+  unsigned char min_insn_length[1];
+  unsigned char default_is_stmt[1];
+  unsigned char line_base[1];
+  unsigned char line_range[1];
+  unsigned char opcode_base[1];
+} dwarf2_line_info_stream_t;
+
+typedef struct {
   unsigned int   length;
   unsigned short version;
   unsigned int   prologue_length;
   unsigned char  min_insn_length;
   unsigned char  default_is_stmt;
-  int            line_base;
+  char           line_base;
   unsigned char  line_range;
   unsigned char  opcode_base;
 } dwarf2_line_info_t;
@@ -166,11 +181,20 @@
   DW_TAG_variant_part           = 0x33,
   DW_TAG_variable               = 0x34,
   DW_TAG_volatile_type          = 0x35,
+  /* DWARF 3 */
+  DW_TAG_dwarf_procedure        = 0x36,
+  DW_TAG_restrict_type          = 0x37,
+  DW_TAG_interface_type         = 0x38,
+  DW_TAG_namespace              = 0x39,
+  DW_TAG_imported_module        = 0x3a,
+  DW_TAG_unspecified_type       = 0x3b,
+  DW_TAG_partial_unit           = 0x3c,
+  DW_TAG_imported_unit          = 0x3d,
   /** extensions */
   DW_TAG_MIPS_loop              = 0x4081,
   DW_TAG_format_label           = 0x4101,
   DW_TAG_function_template      = 0x4102,
-  DW_TAG_class_template         = 0x4103
+  DW_TAG_class_template         = 0x4103  
 } dwarf_tag_t;
 
 typedef enum dwarf_attribute_e {
@@ -236,8 +260,19 @@
   DW_AT_variable_parameter   = 0x4b,
   DW_AT_virtuality           = 0x4c,
   DW_AT_vtable_elem_location = 0x4d,
-
+  /* DWARF 3 */
+  DW_AT_allocated            = 0x4e,
+  DW_AT_associated           = 0x4f,
+  DW_AT_data_location        = 0x50,
+  DW_AT_stride               = 0x51,
+  DW_AT_entry_pc             = 0x52,
+  DW_AT_use_UTF8             = 0x53,
+  DW_AT_extension            = 0x54,
   DW_AT_ranges               = 0x55,
+  DW_AT_trampoline           = 0x56,
+  DW_AT_call_column          = 0x57,
+  DW_AT_call_file            = 0x58,
+  DW_AT_call_line            = 0x59,
   /* extensions */
   DW_AT_MIPS_fde                     = 0x2001,
   DW_AT_MIPS_loop_begin              = 0x2002,
@@ -255,7 +290,8 @@
   DW_AT_mac_info                     = 0x2103,
   DW_AT_src_coords                   = 0x2104,
   DW_AT_body_begin                   = 0x2105,
-  DW_AT_body_end                     = 0x2106
+  DW_AT_body_end                     = 0x2106,
+  DW_AT_GNU_vector                   = 0x2107
 } dwarf_attribute_t;
 
 typedef enum dwarf_form_e {
@@ -292,7 +328,9 @@
   DW_ATE_signed        = 0x5,
   DW_ATE_signed_char   = 0x6,
   DW_ATE_unsigned      = 0x7,
-  DW_ATE_unsigned_char = 0x8
+  DW_ATE_unsigned_char = 0x8,
+  /* DWARF 3 */
+  DW_ATE_imaginary_float = 0x9
 } dwarf_type_t;
 
 typedef enum dwarf_operation_e {
@@ -447,6 +485,123 @@
  * Parsers
  */
 
+typedef struct ref_hash_table_elt_forwards_s {
+  struct symt** fw;
+  struct ref_hash_table_elt_forwards_s* next;
+} ref_hash_table_elt_forwards_t;
+
+typedef struct ref_hash_table_elt_s {
+  struct symt* sym;
+  unsigned long ref;
+  ref_hash_table_elt_forwards_t* fws;
+  struct ref_hash_table_elt_s* next;
+} ref_hash_table_elt_t;
+
+typedef struct ref_hash_table_s {
+  unsigned               num_buckets;
+  ref_hash_table_elt_t** buckets;
+} ref_hash_table_t;
+
+unsigned ref_hash_table_hash(unsigned long ref, unsigned num_buckets)
+{
+  unsigned  hash = 0;
+  hash = ref % num_buckets;
+  return 0;
+}
+
+int ref_hash_table_cmp(unsigned long ref1, unsigned long ref2)
+{
+  return ref1 != ref2;
+}
+
+void ref_hash_table_init(struct pool* pool, ref_hash_table_t* ht, unsigned num_buckets)
+{
+  ht->buckets = pool_alloc(pool, num_buckets * sizeof(ref_hash_table_elt_t*));
+  assert( NULL != ht->buckets );
+  ht->num_buckets = num_buckets;
+  memset(ht->buckets, 0, num_buckets * sizeof(ref_hash_table_elt_t*));
+}
+
+void ref_hash_table_destroy(struct pool* pool, ref_hash_table_t* ht)
+{
+  ht->num_buckets = 0;
+  ht->buckets = NULL;
+}
+
+void ref_hash_table_insert_fw(struct pool* pool, ref_hash_table_t* ht, unsigned long ref, struct symt** fw)
+{
+  unsigned hash = ref_hash_table_hash(ref, ht->num_buckets);
+  ref_hash_table_elt_t** p = NULL;
+  ref_hash_table_elt_forwards_t* fw_elt = NULL;
+
+  fw_elt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ref_hash_table_elt_forwards_t));
+  fw_elt->fw = fw;
+  fw_elt->next = NULL;
+
+  for (p = &ht->buckets[hash]; NULL != *p; p = &((*p)->next)) {
+    if (!ref_hash_table_cmp((*p)->ref, ref)) {
+      assert( NULL == (*p)->sym );
+      fw_elt->next = (*p)->fws;
+      (*p)->fws = fw_elt->next;
+      return ;
+    }
+  }
+  *p = pool_alloc(pool, sizeof(ref_hash_table_elt_t));
+  assert( NULL != *p );
+  (*p)->ref = ref;
+  (*p)->next = NULL;
+  (*p)->fws = fw_elt;
+  (*p)->sym = NULL;
+}
+
+struct symt* ref_hash_table_insert(struct pool* pool, ref_hash_table_t* ht, unsigned long ref, struct symt* sym)
+{
+  unsigned hash = ref_hash_table_hash(ref, ht->num_buckets);
+  ref_hash_table_elt_t** p = NULL;
+  struct symt* ret = NULL;
+
+  for (p = &ht->buckets[hash]; NULL != *p; p = &((*p)->next)) {
+    if (!ref_hash_table_cmp((*p)->ref, ref)) {
+      ret = (*p)->sym;
+      (*p)->sym = sym;
+      if (NULL != (*p)->fws) {
+	ref_hash_table_elt_forwards_t* it = NULL;
+	ref_hash_table_elt_forwards_t* prev_it = NULL;
+	assert( NULL == ret );
+	assert( NULL != sym );
+	/** resolve forward as we are now adding the long waiting symt ;) */
+	it = (*p)->fws;
+	(*p)->fws = NULL;
+	while (NULL != it) {
+	  *(it->fw) = sym;
+	  prev_it = it;
+	  it = it->next;
+	  HeapFree(GetProcessHeap(), 0, prev_it);
+	}
+      }
+      return ret;
+    }
+  }
+  *p = pool_alloc(pool, sizeof(ref_hash_table_elt_t));
+  assert( NULL != *p );
+  (*p)->ref = ref;
+  (*p)->next = NULL;
+  (*p)->fws = NULL;
+  (*p)->sym = sym;
+  return ret;
+}
+
+struct symt* ref_hash_table_find(ref_hash_table_t* ht, unsigned long ref)
+{
+  unsigned hash = ref_hash_table_hash(ref, ht->num_buckets);
+  ref_hash_table_elt_t* p = NULL;
+
+  for (p = ht->buckets[hash]; NULL != p; p = p->next) {
+    if (!ref_hash_table_cmp(p->ref, ref)) return p->sym;
+  }
+  return NULL;
+}
+
 typedef struct dwarf2_abbrev_entry_attr_s {
   unsigned long attribute;
   unsigned long form;
@@ -473,6 +628,7 @@
   const unsigned char* start_data;
   const unsigned char* end_data;
   const unsigned char* str_section;
+  ref_hash_table_t* ht_ref;
   unsigned long offset;
   unsigned char word_size;
   unsigned char level;
@@ -696,6 +852,7 @@
     break;
   default:
     ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute);
+    assert( 0 );
   }
   return ret;
 }
@@ -744,6 +901,10 @@
     */
     ctx->data += 8;
     break;
+
+  default:
+    FIXME("Unsupported ref format 0x%lx support\n", attr->form);
+    assert( 0 );
   }
   return uvalue;
 }
@@ -773,6 +934,10 @@
     FIXME("Unsupported 64bits support\n");
     ctx->data += 8;
     break;
+
+  default:
+    FIXME("Unsupported data format 0x%lx support\n", attr->form);
+    assert( 0 );
   }
   return uvalue;
 }
@@ -839,7 +1004,7 @@
   case DW_FORM_string:
   case DW_FORM_strp:
     str = dwarf2_parse_attr_as_string(attr, ctx);
-    TRACE("string<%s>\n", str);
+    TRACE("string<%p>\n", str);
     break;
 
   case DW_FORM_block:
@@ -867,18 +1032,44 @@
   }
 }
 
-static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
+static const char* dwarf2_clean_name(const char* name)
 {
-  TRACE("want ref<0x%lx>\n", ref); 
-  return NULL;
+  static unsigned cnt = 0;
+  static char buffer[255];
+  if (NULL == name) {
+    /*name = "unamed";*/
+    ++cnt;
+    snprintf(buffer, sizeof(buffer), "unamed_%u", cnt);
+    return buffer;
+  }
+  return name;
 }
 
-static struct symt* dwarf2_add_symt_ref(struct module* module, unsigned long ref, struct symt* symt)
+static struct symt* dwarf2_find_symt_by_ref(struct module* module, dwarf2_parse_context_t* ctx, unsigned long ref)
 {
-  if (NULL != symt) return NULL;
-  return NULL;
+  struct symt* ret = NULL;
+  ret = ref_hash_table_find(ctx->ht_ref, ref);
+  TRACE("want ref<0x%lx> found %p\n", ref, ret);
+  return ret;
+}
+
+static struct symt* dwarf2_add_symt_ref(struct module* module, dwarf2_parse_context_t* ctx, unsigned long ref, struct symt* symt)
+{
+  struct symt* ret = NULL;
+  if (NULL == symt) return NULL;
+  ret = ref_hash_table_insert(&module->pool, ctx->ht_ref, ref, symt);
+  TRACE("(hash:%p) ref<0x%lx> symt(%p) -> %p\n", ctx->ht_ref, ref, symt, ret);
+  return ret;
 }
 
+static void dwarf2_add_symt_ref_fw(struct module* module, dwarf2_parse_context_t* ctx, unsigned long ref, struct symt** fw)
+{
+  if (NULL == fw) return ;
+  ref_hash_table_insert_fw(&module->pool, ctx->ht_ref, ref, fw);
+  TRACE("(hash:%p) ref<0x%lx> fw(%p)\n", ctx->ht_ref, ref, fw);
+}
+
+
 static struct symt_basic* dwarf2_parse_base_type(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx)
 {
   struct symt_basic* symt = NULL;
@@ -935,6 +1126,7 @@
   struct symt* ref_type = NULL;
   const char* name = NULL;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
@@ -945,10 +1137,8 @@
       TRACE("found name %s\n", name);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	ref_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      ref_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     case DW_AT_decl_file:
     case DW_AT_decl_line:
@@ -959,8 +1149,10 @@
       dwarf2_parse_attr(attr, ctx);
     }
   }
-  if (NULL != name) {
-    symt = symt_new_typedef(module, ref_type, name);
+  name = dwarf2_clean_name(name);
+  symt = symt_new_typedef(module, ref_type, name);
+  if (NULL == ref_type) {
+    dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(symt->type));
   }
 
   if (entry->have_child) {
@@ -975,6 +1167,7 @@
   struct symt* ref_type = NULL;
   unsigned size = 0;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
@@ -984,10 +1177,8 @@
       size = dwarf2_parse_byte(ctx);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	ref_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      ref_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     default:
       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
@@ -995,6 +1186,9 @@
     }
   }
   symt = symt_new_pointer(module, ref_type);
+  if (NULL == ref_type) {
+    dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(symt->pointsto));
+  }
 
   if (entry->have_child) {
     FIXME("Unsupported children\n");
@@ -1008,16 +1202,18 @@
   unsigned max = 0;
   struct symt* idx_type = NULL;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
     switch (attr->attribute) {
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	idx_type = dwarf2_find_symt_by_ref(module, ref);
-	/** check if idx_type is a basic_type integer */
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      idx_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
+      /** check if idx_type is a basic_type integer */
+      if (NULL == idx_type) {
+	/*dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(symt->pointsto));*/
       }
       break;
     case DW_AT_lower_bound:
@@ -1056,6 +1252,7 @@
   unsigned max = 0;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
   unsigned long next_sibling = 0;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
@@ -1065,10 +1262,8 @@
       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	ref_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      ref_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     default:
       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
@@ -1077,6 +1272,9 @@
   }
 
   symt = symt_new_array(module, min, max, ref_type);
+  if (NULL == ref_type) {
+    dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(symt->basetype));
+  }
 
   if (entry->have_child) { /** any interest to not have child ? */
     ++ctx->level;
@@ -1088,7 +1286,7 @@
       entry_ref = ctx->data - ctx->data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	break ;
       }
@@ -1126,24 +1324,26 @@
   struct symt* ref_type = NULL;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
   unsigned long next_sibling = 0;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
   for (attr = entry->attrs; NULL != attr; attr = attr->next) {
     switch (attr->attribute) {
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	ref_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      ref_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     default:
       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
       dwarf2_parse_attr(attr, ctx);
     }
   }
-  FIXME("need to generate a name\n");
-  symt = symt_new_typedef(module, ref_type, "");
+  TRACE("need to generate a better name\n");
+  symt = symt_new_typedef(module, ref_type, dwarf2_clean_name(NULL));
+  if (NULL == ref_type) {
+    dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(symt->type));
+  }
 
   if (entry->have_child) {
     FIXME("Unsupported children\n");
@@ -1161,6 +1361,7 @@
   struct symt* ref_type = NULL;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
   unsigned long next_sibling = 0;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
@@ -1170,18 +1371,19 @@
       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	ref_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      ref_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     default:
       TRACE("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); 
       dwarf2_parse_attr(attr, ctx);
     }
   }
-  FIXME("need to generate a name\n");
-  symt = symt_new_typedef(module, ref_type, "");
+  FIXME("need to generate a better name\n");
+  symt = symt_new_typedef(module, ref_type, dwarf2_clean_name(NULL));
+  if (NULL == ref_type) {
+    dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(symt->type));
+  }
 
   if (entry->have_child) {
     FIXME("Unsupported children\n");
@@ -1195,12 +1397,14 @@
 
 static void dwarf2_parse_udt_member(struct module* module, dwarf2_abbrev_entry_t* entry, dwarf2_parse_context_t* ctx, struct symt_udt* parent)
 {
+  /*struct symt_data* symt = NULL;*/
   struct symt* elt_type = NULL;
   const char* name = NULL; 
   unsigned long offset = 0;
   unsigned size = 0;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
   unsigned long next_sibling = 0;
+  unsigned long ref_ref_type = 0;
 
   assert( NULL != parent );
 
@@ -1216,10 +1420,8 @@
       TRACE("found name %s\n", name);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	elt_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      elt_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     case DW_AT_data_member_location:
       {
@@ -1267,7 +1469,14 @@
       dwarf2_parse_attr(attr, ctx);
     }
   }
+  name = dwarf2_clean_name(name);
   symt_add_udt_element(module, parent, name, elt_type, offset, size);
+  /*
+  assert( NULL != symt );
+  if (NULL == elt_type) {
+    dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(symt->type));
+  }
+  */
 
   if (entry->have_child) {
     FIXME("Unsupported children\n");
@@ -1289,7 +1498,7 @@
       entry_ref = ctx->data - ctx->data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	break ;
       }
@@ -1376,7 +1585,7 @@
       TRACE("found name %s\n", name);
       break;
     case DW_AT_byte_size:
-      size = dwarf2_parse_byte(ctx);
+      size = dwarf2_parse_attr_as_data(attr, ctx);
       break;
     case DW_AT_decl_file:
     case DW_AT_decl_line:
@@ -1387,6 +1596,7 @@
       dwarf2_parse_attr(attr, ctx);
     }
   }
+  name = dwarf2_clean_name(name);
   symt = symt_new_udt(module, name, size, UdtStruct);
   dwarf2_parse_udt_members(module, entry, ctx, symt);
 
@@ -1427,6 +1637,7 @@
       dwarf2_parse_attr(attr, ctx);
     }
   }
+  name = dwarf2_clean_name(name);
   symt = symt_new_udt(module, name, size, UdtUnion);
   dwarf2_parse_udt_members(module, entry, ctx, symt);
 
@@ -1508,6 +1719,7 @@
       dwarf2_parse_attr(attr, ctx);
     }
   }
+  name = dwarf2_clean_name(name);
   symt = symt_new_enum(module, name);
 
   if (entry->have_child) { /** any interest to not have child ? */
@@ -1520,7 +1732,7 @@
       entry_ref = ctx->data - ctx->data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	break ;
       }
@@ -1560,6 +1772,7 @@
   dwarf2_abbrev_entry_attr_t* attr = NULL;
   const char* name = NULL;
   unsigned long next_sibling = 0;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
@@ -1569,10 +1782,8 @@
       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	var_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      var_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     case DW_AT_name:
       name = dwarf2_parse_attr_as_string(attr, ctx);
@@ -1602,10 +1813,12 @@
 					      struct symt_function_signature* sig_type,
 					      struct symt_function* func_type)
 {
+  /*struct symt** psymt = NULL;*/
   struct symt* param_type = NULL;
   const char* name = NULL;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
   unsigned long next_sibling = 0;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
@@ -1615,10 +1828,8 @@
       next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	param_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      param_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     case DW_AT_name:
       name = dwarf2_parse_attr_as_string(attr, ctx);
@@ -1638,6 +1849,11 @@
   }
   if (NULL != sig_type) {
     symt_add_function_signature_parameter(module, sig_type, param_type);
+    /*
+    if (NULL == param_type) {
+      dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, psymt);
+    }
+    */
   }
 
   if (entry->have_child) {
@@ -1697,7 +1913,7 @@
       entry_ref = ctx->data - ctx->data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	break ;
       }
@@ -1776,7 +1992,7 @@
       entry_ref = ctx->data - ctx->data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	break ;
       }
@@ -1826,7 +2042,7 @@
       entry_ref = ctx->data - ctx->data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	break ;
       }
@@ -1876,6 +2092,7 @@
   unsigned char decl_line = 0;
   dwarf2_abbrev_entry_attr_t* attr = NULL;
   unsigned long next_sibling = 0;
+  unsigned long ref_ref_type = 0;
 
   TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); 
 
@@ -1897,10 +2114,8 @@
       TRACE("found name %s\n", name);
       break;
     case DW_AT_type:
-      {
-	unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
-	ret_type = dwarf2_find_symt_by_ref(module, ref);
-      }
+      ref_ref_type = dwarf2_parse_attr_as_ref(attr, ctx);
+      ret_type = dwarf2_find_symt_by_ref(module, ctx, ref_ref_type);
       break;
     case DW_AT_declaration:
       is_decl = dwarf2_parse_byte(ctx);
@@ -1922,8 +2137,13 @@
     }
   }
   sig_type = symt_new_function_signature(module, ret_type);
+  assert( NULL != sig_type );
+  if (NULL == ret_type) {
+    dwarf2_add_symt_ref_fw(module, ctx, ref_ref_type, &(sig_type->rettype));
+  }
   if (!is_decl) {
     func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt);
+    assert( NULL != func_type );
     if (low_pc && high_pc) {
       symt_add_function_point(module, func_type, SymTagFuncDebugStart, low_pc, NULL);
       symt_add_function_point(module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
@@ -1953,7 +2173,7 @@
       entry_ref = ctx->data - ctx->data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	break ;
       }
@@ -1965,67 +2185,67 @@
       case DW_TAG_typedef:
 	{
 	  struct symt_typedef* symt = dwarf2_parse_typedef(module, entry, ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_base_type:
 	{
 	  struct symt_basic* symt = dwarf2_parse_base_type(module, entry, ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_pointer_type:
 	{
 	  struct symt_pointer* symt = dwarf2_parse_pointer_type(module, entry, ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_class_type:
 	{
 	  struct symt_udt* symt = dwarf2_parse_class_type(module, entry, ctx);
-	  if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  if (NULL != symt) dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_structure_type:
 	{
 	  struct symt_udt* symt = dwarf2_parse_struct_type(module, entry, ctx);
-	  if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  if (NULL != symt) dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_union_type:
 	{
 	  struct symt_udt* symt = dwarf2_parse_union_type(module, entry, ctx);
-	  if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  if (NULL != symt) dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_array_type:
 	{
 	  struct symt_array* symt = dwarf2_parse_array_type(module, entry, ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_const_type:
 	{
 	  struct symt_typedef* symt = dwarf2_parse_const_type(module, entry, ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_reference_type:
 	{
 	  struct symt_typedef* symt = dwarf2_parse_reference_type(module, entry, ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_enumeration_type:
 	{
 	  struct symt_enum* symt = dwarf2_parse_enumeration_type(module, entry, ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
       case DW_TAG_subprogram:
 	{
 	  struct symt_function* symt = dwarf2_parse_subprogram(module, entry, ctx, compiland);
-	  if (NULL != symt) dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  if (NULL != symt) dwarf2_add_symt_ref(module, ctx, entry_ref, &symt->symt);
 	}
 	break;
 
@@ -2075,14 +2295,81 @@
   return compiland;
 }
 
+/**
+ * Machine State Registers for DW line parsing
+ */
+typedef struct dwarf2_state_machine_regs_s {
+  unsigned long  address;
+  unsigned int   file;
+  unsigned int   line;
+  unsigned int   column;
+  unsigned char  is_stmt; /** BOOL */
+  unsigned char  basic_block; /** BOOL */
+  unsigned char  end_sequence; /** BOOL */
+} dwarf2_state_machine_regs_t;
+
+static void dwarf2_reset_sm_regs(dwarf2_state_machine_regs_t* regs, int is_stmt) 
+{
+  regs->address = 0;
+  regs->file = 1;
+  regs->line = 1;
+  regs->column = 0;
+  regs->is_stmt = is_stmt;
+  regs->basic_block = 0;
+  regs->end_sequence = 0;
+}
+
+BOOL dwarf2_parse_lines(struct module* module, dwarf2_parse_context_t* ctx)
+{
+  dwarf2_state_machine_regs_t sm_regs;
+  const unsigned char* end_seq = NULL;
+  const unsigned char* std_opcodes = NULL;
+
+  /** TO BE DONE */
+  return FALSE;
+
+  while (ctx->data < ctx->end_data) {
+    dwarf2_line_info_stream_t* line_info_stream;
+    dwarf2_line_info_t line_info;
+
+    line_info_stream = (dwarf2_line_info_stream_t*) ctx->data; 
+
+    line_info.length = *(unsigned long*)  line_info_stream->length;
+    line_info.version = *(unsigned short*) line_info_stream->version;
+    line_info.prologue_length = *(unsigned long*) line_info_stream->prologue_length;
+    line_info.min_insn_length = *(unsigned char*) line_info_stream->min_insn_length;
+    line_info.default_is_stmt = *(unsigned char*) line_info_stream->default_is_stmt;
+    line_info.line_base = *(unsigned char*) line_info_stream->line_base;
+    line_info.line_range = *(unsigned char*) line_info_stream->line_range;
+    line_info.opcode_base = *(unsigned char*) line_info_stream->opcode_base;
+
+    if (2 != line_info.version) {
+      WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", line_info.version);
+      break ;
+    }
+
+
+    dwarf2_reset_sm_regs(&sm_regs, line_info.default_is_stmt);
+
+    end_seq = ctx->data + line_info.length + sizeof(line_info_stream->length);
+    std_opcodes = ctx->data + sizeof(dwarf2_line_info_stream_t);
+
+  }  
+  return FALSE;
+}
+
 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
 		  const unsigned char* debug, unsigned int debug_size,
 		  const unsigned char* abbrev, unsigned int abbrev_size,
-		  const unsigned char* str, unsigned int str_sz)
+		  const unsigned char* str, unsigned int str_sz,
+		  const unsigned char* lines, unsigned int lines_size)
 {
   const unsigned char* comp_unit_cursor = debug;
   const unsigned char* end_debug = debug + debug_size;
   BOOL bRet = TRUE;
+  ref_hash_table_t ht_ref;
+
+  ref_hash_table_init(&module->pool, &ht_ref, 4097);
 
   while (comp_unit_cursor < end_debug) {
     dwarf2_abbrev_table_t* abbrev_table;
@@ -2090,6 +2377,7 @@
     dwarf2_comp_unit_t comp_unit;
     dwarf2_parse_context_t ctx;
     dwarf2_parse_context_t abbrev_ctx;
+    dwarf2_parse_context_t lines_ctx;
     struct symt_compiland* compiland = NULL;
     
     comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
@@ -2111,6 +2399,7 @@
     ctx.word_size = comp_unit.word_size;
     ctx.str_section = str;
     ctx.level = 0;
+    ctx.ht_ref = &ht_ref;
 
     comp_unit_cursor += comp_unit.length + sizeof(unsigned);
     ctx.end_data = comp_unit_cursor;
@@ -2120,13 +2409,22 @@
       continue ;
     }
 
+    lines_ctx.abbrev_table = NULL;
+    lines_ctx.data_stream = lines;
+    lines_ctx.data = lines_ctx.start_data = lines;
+    lines_ctx.end_data = lines + lines_size;
+    lines_ctx.offset = 0;
+    lines_ctx.word_size = comp_unit.word_size;
+    lines_ctx.str_section = str;
+    dwarf2_parse_lines(module, &lines_ctx);    
+
     abbrev_ctx.abbrev_table = NULL;
     abbrev_ctx.data_stream = abbrev;
     abbrev_ctx.data = abbrev_ctx.start_data = abbrev + comp_unit.abbrev_offset;
     abbrev_ctx.end_data = abbrev + abbrev_size;
     abbrev_ctx.offset = comp_unit.abbrev_offset;
     abbrev_ctx.str_section = str;
-    abbrev_table = dwarf2_parse_abbrev_set(&abbrev_ctx);    
+    abbrev_table = dwarf2_parse_abbrev_set(&abbrev_ctx);
 
     ctx.abbrev_table = abbrev_table;
 
@@ -2138,7 +2436,7 @@
       entry_ref = ctx.data - ctx.data_stream;
       
       entry_code = dwarf2_leb128_as_unsigned(&ctx);
-      TRACE("found entry_code %lu at 0x%lx\n", entry_code, entry_ref);
+      TRACE("found entry_code %lu at ref<0x%lx>\n", entry_code, entry_ref);
       if (0 == entry_code) {
 	continue ;
       }
@@ -2153,7 +2451,7 @@
       case DW_TAG_compile_unit:
 	{
 	  struct symt_compiland* symt = dwarf2_parse_compiland(module, entry, &ctx);
-	  dwarf2_add_symt_ref(module, entry_ref, &symt->symt);
+	  dwarf2_add_symt_ref(module, &ctx, entry_ref, &symt->symt);
 	  compiland = symt;
 	}
 	break;
@@ -2170,5 +2468,7 @@
     }
     dwarf2_abbrev_table_free(abbrev_table);
   }
+  ref_hash_table_destroy(&module->pool, &ht_ref);
   return bRet;
 }
+
Index: elf_module.c
===================================================================
RCS file: /home/wine/wine/dlls/dbghelp/elf_module.c,v
retrieving revision 1.25
diff -u -r1.25 elf_module.c
--- elf_module.c	2 Sep 2005 14:47:36 -0000	1.25
+++ elf_module.c	13 Oct 2005 21:51:19 -0000
@@ -854,8 +854,8 @@
 
     if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
     {
-        if (stab_sect != -1 && stabstr_sect != -1)
-        {
+      if (stab_sect != -1 && stabstr_sect != -1)
+      {
             const char* stab;
             const char* stabstr;
 
@@ -885,23 +885,28 @@
             const BYTE* dw2_debug;
             const BYTE* dw2_debug_abbrev;
             const BYTE* dw2_debug_str;
+            const BYTE* dw2_debug_line;
 
             FIXME("Alpha-support for Dwarf2 information for %s\n", module->module.ModuleName);
 
+            if (dw2_debug != NO_MAP && NO_MAP != dw2_debug_abbrev && dw2_debug_str != NO_MAP && dw2_debug_line != NO_MAP)
             dw2_debug = (const BYTE*) elf_map_section(fmap, debug_sect);
             dw2_debug_abbrev = (const BYTE*) elf_map_section(fmap, debug_abbrev_sect);
             dw2_debug_str = (const BYTE*) elf_map_section(fmap, debug_str_sect);
+            dw2_debug_line = (const BYTE*) elf_map_section(fmap, debug_line_sect);
             if (dw2_debug != NO_MAP && NO_MAP != dw2_debug_abbrev && dw2_debug_str != NO_MAP)
             {
                 /* OK, now just parse dwarf2 debug infos. */
                 ret = dwarf2_parse(module, module->elf_info->elf_addr,
 				   dw2_debug, fmap->sect[debug_sect].shdr.sh_size,
 				   dw2_debug_abbrev, fmap->sect[debug_abbrev_sect].shdr.sh_size,
-				   dw2_debug_str, fmap->sect[debug_str_sect].shdr.sh_size);
+				   dw2_debug_str, fmap->sect[debug_str_sect].shdr.sh_size,
+				   dw2_debug_line,fmap->sect[debug_line_sect].shdr.sh_size);
             }
             elf_unmap_section(fmap, debug_sect);
             elf_unmap_section(fmap, debug_abbrev_sect);
             elf_unmap_section(fmap, debug_str_sect);
+            elf_unmap_section(fmap, debug_line_sect);
             if (!ret)
             {
                 WARN("Couldn't correctly read stabs\n");

Attachment: pgpOvbQCGB2EG.pgp
Description: PGP signature



Reply via email to