[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