[PATCH 09/31] [DbgHelp]: dwarf abbrev table is now a sparse array

Eric Pouech eric.pouech at wanadoo.fr
Sun Jun 18 14:31:13 CDT 2006


- added a pool for memory allocation when parsing a compilation
  unit
- now using the brand new sparse array for the abbrev table

A+
---

 dlls/dbghelp/dwarf.c |  206 +++++++++++++++++++-------------------------------
 1 files changed, 77 insertions(+), 129 deletions(-)

diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index a3e6816..1dd0f6e 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -104,21 +104,18 @@ typedef struct dwarf2_abbrev_entry_attr_
   struct dwarf2_abbrev_entry_attr_s* next;
 } dwarf2_abbrev_entry_attr_t;
 
-typedef struct dwarf2_abbrev_entry_s {
-  unsigned long entry_code;
-  unsigned long tag;
-  unsigned char have_child;
-  dwarf2_abbrev_entry_attr_t* attrs;
-  struct dwarf2_abbrev_entry_s* next;
+typedef struct dwarf2_abbrev_entry_s
+{
+    unsigned long entry_code;
+    unsigned long tag;
+    unsigned char have_child;
+    unsigned num_attr;
+    dwarf2_abbrev_entry_attr_t* attrs;
 } dwarf2_abbrev_entry_t;
 
-typedef struct dwarf2_abbrev_table_s {
-  dwarf2_abbrev_entry_t* first;
-  unsigned n_entries;
-} dwarf2_abbrev_table_t;
-
 typedef struct dwarf2_parse_context_s {
-  dwarf2_abbrev_table_t* abbrev_table;
+  struct pool pool;
+  struct sparse_array abbrev_table;
   const unsigned char* data_stream;
   const unsigned char* data;
   const unsigned char* start_data;
@@ -216,119 +213,73 @@ static void dwarf2_check_sibling(dwarf2_
 }
 
 
-static dwarf2_abbrev_entry_attr_t* dwarf2_abbrev_entry_add_attr(dwarf2_abbrev_entry_t* abbrev_entry, unsigned long attribute, unsigned long form)
-{
-  dwarf2_abbrev_entry_attr_t* ret = NULL;
-  dwarf2_abbrev_entry_attr_t* it = NULL;
-
-  assert( NULL != abbrev_entry );
-  ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_attr_t));
-  assert( NULL != ret );
-
-  ret->attribute = attribute;
-  ret->form      = form;
-
-  ret->next = NULL;
-  if (NULL == abbrev_entry->attrs) {
-    abbrev_entry->attrs = ret;
-  } else {
-    for (it = abbrev_entry->attrs; NULL != it->next; it = it->next) ;
-    it->next = ret;
-  }
-  return ret;
-}
-
-static dwarf2_abbrev_entry_t* dwarf2_abbrev_table_add_entry(dwarf2_abbrev_table_t* abbrev_table, unsigned long entry_code, unsigned long tag, unsigned char have_child)
+static dwarf2_abbrev_entry_t*
+dwarf2_abbrev_table_find_entry(struct sparse_array* abbrev_table,
+                               unsigned long entry_code)
 {
-  dwarf2_abbrev_entry_t* ret = NULL;
-
-  assert( NULL != abbrev_table );
-  ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_entry_t));
-  assert( NULL != ret );
-
-  TRACE("(table:%p,n_entries:%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n", abbrev_table, abbrev_table->n_entries, entry_code, tag, have_child, ret);
-
-  ret->entry_code = entry_code;
-  ret->tag        = tag;
-  ret->have_child = have_child;
-  ret->attrs      = NULL;
-
-  ret->next       = abbrev_table->first;
-  abbrev_table->first = ret;
-  abbrev_table->n_entries++;
-  return ret;
+    assert( NULL != abbrev_table );
+    return sparse_array_find(abbrev_table, entry_code);
 }
 
-static dwarf2_abbrev_entry_t* dwarf2_abbrev_table_find_entry(dwarf2_abbrev_table_t* abbrev_table, unsigned long entry_code)
+static void dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx, 
+                                    struct sparse_array* abbrev_table,
+                                    struct pool* pool)
 {
-  dwarf2_abbrev_entry_t* ret = NULL;
-
-  assert( NULL != abbrev_table );
-  for (ret = abbrev_table->first; ret; ret = ret->next) {
-    if (ret->entry_code == entry_code) { break ; }
-  }
-  return ret;
-}
+    unsigned long entry_code;
+    dwarf2_abbrev_entry_t* abbrev_entry;
+    dwarf2_abbrev_entry_attr_t* new = NULL;
+    dwarf2_abbrev_entry_attr_t* last = NULL;
+    unsigned long attribute;
+    unsigned long form;
 
-static void dwarf2_abbrev_table_free(dwarf2_abbrev_table_t* abbrev_table)
-{
-  dwarf2_abbrev_entry_t* entry = NULL;
-  dwarf2_abbrev_entry_t* next_entry = NULL;
-  assert( NULL != abbrev_table );
-  for (entry = abbrev_table->first; NULL != entry; entry = next_entry) {
-    dwarf2_abbrev_entry_attr_t* attr = NULL;
-    dwarf2_abbrev_entry_attr_t* next_attr = NULL;
-    for (attr = entry->attrs; NULL != attr; attr = next_attr) {
-      next_attr = attr->next;
-      HeapFree(GetProcessHeap(), 0, attr);
-    }
-    next_entry = entry->next;
-    HeapFree(GetProcessHeap(), 0, entry);
-  }
-  abbrev_table->first = NULL;
-  abbrev_table->n_entries = 0;
-}
+    TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data); 
 
-static dwarf2_abbrev_table_t* dwarf2_parse_abbrev_set(dwarf2_parse_context_t* abbrev_ctx)
-{
-  dwarf2_abbrev_table_t* abbrev_table = NULL;
+    assert( NULL != abbrev_ctx );
 
-  TRACE("%s, end at %p\n", dwarf2_debug_ctx(abbrev_ctx), abbrev_ctx->end_data); 
+    sparse_array_init(abbrev_table, sizeof(dwarf2_abbrev_entry_t), 32);
+    while (abbrev_ctx->data < abbrev_ctx->end_data)
+    {
+        TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
+        entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
+        TRACE("found entry_code %lu\n", entry_code);
+        if (!entry_code)
+        {
+            TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
+            break;
+        }
+        abbrev_entry = sparse_array_add(abbrev_table, entry_code, pool);
+        assert( NULL != abbrev_entry );
 
-  assert( NULL != abbrev_ctx );
-  abbrev_table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dwarf2_abbrev_table_t));
-  assert( NULL != abbrev_table );
+        abbrev_entry->entry_code = entry_code;
+        abbrev_entry->tag        = dwarf2_leb128_as_unsigned(abbrev_ctx);
+        abbrev_entry->have_child = dwarf2_parse_byte(abbrev_ctx);
+        abbrev_entry->attrs      = NULL;
+        abbrev_entry->num_attr   = 0;
 
-  while (abbrev_ctx->data < abbrev_ctx->end_data) {
-    unsigned long entry_code;
-    unsigned long tag;
-    unsigned char have_child;
-    dwarf2_abbrev_entry_t* abbrev_entry;
+        TRACE("table:(%p,#%u) entry_code(%lu) tag(0x%lx) have_child(%u) -> %p\n",
+              abbrev_table, sparse_array_length(abbrev_table),
+              entry_code, abbrev_entry->tag, abbrev_entry->have_child, abbrev_entry);
 
-    TRACE("now at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
-    entry_code = dwarf2_leb128_as_unsigned(abbrev_ctx);
-    TRACE("found entry_code %lu\n", entry_code);
-    if (0 == entry_code) {
-      TRACE("NULL entry code at %s\n", dwarf2_debug_ctx(abbrev_ctx)); 
-      break ;
-    }
-    tag = dwarf2_leb128_as_unsigned(abbrev_ctx);
-    have_child = dwarf2_parse_byte(abbrev_ctx);
-
-    abbrev_entry = dwarf2_abbrev_table_add_entry(abbrev_table, entry_code, tag, have_child);
-    assert( NULL != abbrev_entry );
-    while (1) {
-      unsigned long attribute;
-      unsigned long form;
-      attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
-      form = dwarf2_leb128_as_unsigned(abbrev_ctx);
-      if (0 == attribute) break;
-      dwarf2_abbrev_entry_add_attr(abbrev_entry, attribute, form);
+        last = NULL;
+        while (1)
+        {
+            attribute = dwarf2_leb128_as_unsigned(abbrev_ctx);
+            form = dwarf2_leb128_as_unsigned(abbrev_ctx);
+            if (!attribute) break;
+
+            new = pool_alloc(pool, sizeof(dwarf2_abbrev_entry_attr_t));
+            assert(new);
+
+            new->attribute = attribute;
+            new->form      = form;
+            new->next      = NULL;
+            if (abbrev_entry->attrs)    last->next = new;
+            else                        abbrev_entry->attrs = new;
+            last = new;
+            abbrev_entry->num_attr++;
+        }
     }
-  }
-
-  TRACE("found %u entries\n", abbrev_table->n_entries);
-  return abbrev_table;
+    TRACE("found %u entries\n", sparse_array_length(abbrev_table));
 }
 
 static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr,
@@ -747,7 +698,7 @@ static struct symt_array* dwarf2_parse_a
 	break ;
       }
 
-      entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
       assert( NULL != entry );
 
       switch (entry->tag) {
@@ -943,7 +894,7 @@ static void dwarf2_parse_udt_members(str
 	break ;
       }
 
-      entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
       assert( NULL != entry );
 
       switch (entry->tag) {
@@ -1178,7 +1129,7 @@ static struct symt_enum* dwarf2_parse_en
 	break ;
       }
 
-      entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
       assert( NULL != entry );
 
       switch (entry->tag) {
@@ -1353,7 +1304,7 @@ static void dwarf2_parse_inlined_subrout
 	break ;
       }
 
-      entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
       assert( NULL != entry );
 
       switch (entry->tag) {
@@ -1430,7 +1381,7 @@ static void dwarf2_parse_subprogram_bloc
 	break ;
       }
 
-      entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
       assert( NULL != entry );
 
       switch (entry->tag) {
@@ -1478,7 +1429,7 @@ static void dwarf2_parse_subprogram_cont
 	break ;
       }
 
-      entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
       assert( NULL != entry );
 
       switch (entry->tag) {
@@ -1613,7 +1564,7 @@ static void dwarf2_parse_compiland_conte
 	break ;
       }
 
-      entry = dwarf2_abbrev_table_find_entry(ctx->abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
       assert( NULL != entry );
 
       switch (entry->tag) {
@@ -1738,7 +1689,6 @@ BOOL dwarf2_parse(struct module* module,
   const unsigned char* end_debug = debug + debug_size;
 
   while (comp_unit_cursor < end_debug) {
-    dwarf2_abbrev_table_t* abbrev_table;
     const dwarf2_comp_unit_stream_t* comp_unit_stream;
     dwarf2_comp_unit_t comp_unit;
     dwarf2_parse_context_t ctx;
@@ -1758,6 +1708,7 @@ BOOL dwarf2_parse(struct module* module,
     TRACE("- abbrev_offset: %lu\n", comp_unit.abbrev_offset);
     TRACE("- word_size:     %u\n",  comp_unit.word_size);
 
+    pool_init(&ctx.pool, 65536);
     ctx.data_stream = debug;
     ctx.data = ctx.start_data = comp_unit_cursor + sizeof(dwarf2_comp_unit_stream_t);
     ctx.offset = comp_unit_cursor - debug;
@@ -1772,15 +1723,12 @@ BOOL dwarf2_parse(struct module* module,
       continue ;
     }
 
-    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);    
-
-    ctx.abbrev_table = abbrev_table;
+    dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
 
     while (ctx.data < ctx.end_data) {
       const dwarf2_abbrev_entry_t* entry = NULL;
@@ -1794,10 +1742,10 @@ BOOL dwarf2_parse(struct module* module,
       if (0 == entry_code) {
 	continue ;
       }
-      entry = dwarf2_abbrev_table_find_entry(abbrev_table, entry_code);
+      entry = dwarf2_abbrev_table_find_entry(&ctx.abbrev_table, entry_code);
       if (NULL == entry) {
 	WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, entry_ref);
-	dwarf2_abbrev_table_free(abbrev_table);
+	pool_destroy(&ctx.pool);
 	return FALSE;
       }
 
@@ -1820,7 +1768,7 @@ BOOL dwarf2_parse(struct module* module,
 	break;
       }
     }
-    dwarf2_abbrev_table_free(abbrev_table);
+    pool_destroy(&ctx.pool);
   }
   
   module->module.SymType = SymDia;



More information about the wine-patches mailing list