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