Eric Pouech : dbghelp: Dwarf & debug info entries.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jun 20 05:23:32 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: c571b8506e94fd0b590f702a4ce09a4449a8a229
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c571b8506e94fd0b590f702a4ce09a4449a8a229
Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date: Sun Jun 18 21:31:17 2006 +0200
dbghelp: Dwarf & debug info entries.
- now loading the debug info entries into specific structures
- this will help writing new functions
- this will allow handling of forward references
---
dlls/dbghelp/dwarf.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 211 insertions(+), 0 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 1dd0f6e..6630fb3 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -113,9 +113,26 @@ typedef struct dwarf2_abbrev_entry_s
dwarf2_abbrev_entry_attr_t* attrs;
} dwarf2_abbrev_entry_t;
+union attribute
+{
+ unsigned long uvalue;
+ long svalue;
+ const char* string;
+};
+
+typedef struct dwarf2_debug_info_s
+{
+ unsigned long offset;
+ const dwarf2_abbrev_entry_t*abbrev;
+ struct symt* symt;
+ union attribute* attributes;
+ struct vector children;
+} dwarf2_debug_info_t;
+
typedef struct dwarf2_parse_context_s {
struct pool pool;
struct sparse_array abbrev_table;
+ struct sparse_array debug_info_table;
const unsigned char* data_stream;
const unsigned char* data;
const unsigned char* start_data;
@@ -191,6 +208,22 @@ static long dwarf2_leb128_as_signed(dwar
return ret;
}
+static unsigned long dwarf2_parse_addr(dwarf2_parse_context_t* ctx)
+{
+ unsigned long ret;
+
+ switch (ctx->word_size)
+ {
+ case 4:
+ ret = dwarf2_parse_u4(ctx);
+ break;
+ default:
+ FIXME("Unsupported Word Size %u\n", ctx->word_size);
+ ret = 0;
+ }
+ return ret;
+}
+
static const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx)
{
/*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
@@ -471,6 +504,116 @@ static void dwarf2_parse_attr(dwarf2_abb
}
}
+static void dwarf2_parse_attr_into_di(dwarf2_parse_context_t* ctx,
+ const dwarf2_abbrev_entry_attr_t* abbrev_attr,
+ union attribute* attr)
+
+{
+ TRACE("(attr:0x%lx,form:0x%lx)\n", abbrev_attr->attribute, abbrev_attr->form);
+
+ switch (abbrev_attr->form) {
+ case DW_FORM_ref_addr:
+ case DW_FORM_addr:
+ attr->uvalue = dwarf2_parse_addr(ctx);
+ TRACE("addr<0x%lx>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_flag:
+ attr->uvalue = dwarf2_parse_byte(ctx);
+ TRACE("flag<0x%lx>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_data1:
+ attr->uvalue = dwarf2_parse_byte(ctx);
+ TRACE("data1<%lu>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_data2:
+ attr->uvalue = dwarf2_parse_u2(ctx);
+ TRACE("data2<%lu>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_data4:
+ attr->uvalue = dwarf2_parse_u4(ctx);
+ TRACE("data4<%lu>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_data8:
+ FIXME("Unhandled 64bits support\n");
+ ctx->data += 8;
+ break;
+
+ case DW_FORM_ref1:
+ attr->uvalue = ctx->offset + dwarf2_parse_byte(ctx);
+ TRACE("ref1<0x%lx>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_ref2:
+ attr->uvalue = ctx->offset + dwarf2_parse_u2(ctx);
+ TRACE("ref2<0x%lx>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_ref4:
+ attr->uvalue = ctx->offset + dwarf2_parse_u4(ctx);
+ TRACE("ref4<0x%lx>\n", attr->uvalue);
+ break;
+
+ case DW_FORM_ref8:
+ FIXME("Unhandled 64 bit support\n");
+ ctx->data += 8;
+ break;
+
+ case DW_FORM_sdata:
+ attr->svalue = dwarf2_leb128_as_signed(ctx);
+ break;
+
+ case DW_FORM_ref_udata:
+ attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
+ break;
+
+ case DW_FORM_udata:
+ attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
+ break;
+
+ case DW_FORM_string:
+ attr->string = (const char*)ctx->data;
+ ctx->data += strlen(attr->string) + 1;
+ TRACE("string<%s>\n", attr->string);
+ break;
+
+ case DW_FORM_strp:
+ {
+ unsigned long offset = dwarf2_parse_u4(ctx);
+ attr->string = (const char*)ctx->str_section + offset;
+ }
+ TRACE("strp<%s>\n", attr->string);
+ break;
+ case DW_FORM_block:
+ attr->uvalue = dwarf2_leb128_as_unsigned(ctx);
+ ctx->data += attr->uvalue;
+ break;
+
+ case DW_FORM_block1:
+ attr->uvalue = dwarf2_parse_byte(ctx);
+ ctx->data += attr->uvalue;
+ break;
+
+ case DW_FORM_block2:
+ attr->uvalue = dwarf2_parse_u2(ctx);
+ ctx->data += attr->uvalue;
+ break;
+
+ case DW_FORM_block4:
+ attr->uvalue = dwarf2_parse_u4(ctx);
+ ctx->data += attr->uvalue;
+ break;
+
+ default:
+ FIXME("Unhandled attribute form %lx\n", abbrev_attr->form);
+ break;
+ }
+}
+
static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
{
WARN("want ref<0x%lx>\n", ref);
@@ -483,6 +626,69 @@ static struct symt* dwarf2_add_symt_ref(
return NULL;
}
+/******************************************************************
+ * dwarf2_read_one_debug_info
+ *
+ * Loads into memory one debug info entry, and recursively its children (if any)
+ */
+static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t** pdi)
+{
+ const dwarf2_abbrev_entry_t*abbrev;
+ unsigned long entry_code;
+ unsigned long offset;
+ dwarf2_debug_info_t* di;
+ dwarf2_debug_info_t* child;
+ dwarf2_debug_info_t** where;
+ dwarf2_abbrev_entry_attr_t* attr;
+ unsigned i;
+
+ offset = ctx->data - ctx->data_stream;
+ entry_code = dwarf2_leb128_as_unsigned(ctx);
+ TRACE("found entry_code %lu at 0x%lx\n", entry_code, offset);
+ if (!entry_code)
+ {
+ *pdi = NULL;
+ return TRUE;
+ }
+ abbrev = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
+ if (!abbrev)
+ {
+ WARN("Cannot find abbrev entry for %lu at 0x%lx\n", entry_code, offset);
+ return FALSE;
+ }
+ di = sparse_array_add(&ctx->debug_info_table, offset, &ctx->pool);
+ if (!di) return FALSE;
+ di->offset = offset;
+ di->abbrev = abbrev;
+ di->symt = NULL;
+
+ if (abbrev->num_attr)
+ {
+ di->attributes = pool_alloc(&ctx->pool,
+ abbrev->num_attr * sizeof(union attribute));
+ for (i = 0, attr = abbrev->attrs; attr; i++, attr = attr->next)
+ {
+ dwarf2_parse_attr_into_di(ctx, attr, &di->attributes[i]);
+ }
+ }
+ else di->attributes = NULL;
+ if (abbrev->have_child)
+ {
+ vector_init(&di->children, sizeof(dwarf2_debug_info_t*), 16);
+ while (ctx->data < ctx->end_data)
+ {
+ if (!dwarf2_read_one_debug_info(ctx, &child)) return FALSE;
+ if (!child) break;
+ where = vector_add(&di->children, &ctx->pool);
+ if (!where) return FALSE;
+ *where = child;
+ }
+ }
+ *pdi = di;
+ return TRUE;
+}
+
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;
@@ -1694,6 +1900,7 @@ BOOL dwarf2_parse(struct module* module,
dwarf2_parse_context_t ctx;
dwarf2_parse_context_t abbrev_ctx;
struct symt_compiland* compiland = NULL;
+ dwarf2_debug_info_t* di;
comp_unit_stream = (const dwarf2_comp_unit_stream_t*) comp_unit_cursor;
@@ -1730,6 +1937,10 @@ BOOL dwarf2_parse(struct module* module,
abbrev_ctx.str_section = str;
dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
+ sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128);
+ dwarf2_read_one_debug_info(&ctx, &di);
+ ctx.data = ctx.start_data; /* FIXME */
+
while (ctx.data < ctx.end_data) {
const dwarf2_abbrev_entry_t* entry = NULL;
unsigned long entry_code;
More information about the wine-cvs
mailing list