[PATCH 14/31] [DbgHelp]: Dwarf compiland
Eric Pouech
eric.pouech at wanadoo.fr
Sun Jun 18 14:31:32 CDT 2006
- rewrote all entities loading to make use of new dwarf2_debug_info_t
scheme
- Note: lots of stuff is still non functional, but parts are now
marked as todo
- commented out the location parsing which is an ugly hack (next
patch will tackle it)
A+
---
dlls/dbghelp/dwarf.c | 1670 ++++++++++++++------------------------------------
1 files changed, 455 insertions(+), 1215 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 5ccc366..6c354b7 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -144,7 +144,7 @@ typedef struct dwarf2_parse_context_s {
} dwarf2_parse_context_t;
/* forward declarations */
-static struct symt_enum* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry);
+static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* entry);
static unsigned char dwarf2_parse_byte(dwarf2_parse_context_t* ctx)
{
@@ -225,28 +225,18 @@ static unsigned long dwarf2_parse_addr(d
return ret;
}
-static const char* dwarf2_debug_ctx(dwarf2_parse_context_t* ctx)
+static const char* dwarf2_debug_ctx(const dwarf2_parse_context_t* ctx)
{
/*return wine_dbg_sprintf("ctx(0x%x,%u)", ctx->data - ctx->start_data, ctx->level); */
return wine_dbg_sprintf("ctx(0x%x)", ctx->data - ctx->data_stream);
}
-static const char* dwarf2_debug_attr(dwarf2_abbrev_entry_attr_t* attr)
-{
- return wine_dbg_sprintf("attr(attr:0x%lx,form:0x%lx)", attr->attribute, attr->form);
-}
-static void dwarf2_check_sibling(dwarf2_parse_context_t* ctx, unsigned long next_sibling)
-{
- if (0 < next_sibling && ctx->data != ctx->data_stream + next_sibling) {
- if ((ctx->data + 1) != ctx->data_stream + next_sibling) {
- /** padding check */
- WARN("cursor error for %s should be sibling<0x%lx>\n", dwarf2_debug_ctx(ctx), next_sibling);
- }
- ctx->data = ctx->data_stream + next_sibling;
- }
+static const char* dwarf2_debug_di(dwarf2_debug_info_t* di)
+{
+ return wine_dbg_sprintf("debug_info(offset:0x%lx,abbrev:%p,symt:%p)",
+ di->offset, di->abbrev, di->symt);
}
-
static dwarf2_abbrev_entry_t*
dwarf2_abbrev_table_find_entry(struct sparse_array* abbrev_table,
unsigned long entry_code)
@@ -316,195 +306,6 @@ static void dwarf2_parse_abbrev_set(dwar
TRACE("found %u entries\n", sparse_array_length(abbrev_table));
}
-static const char* dwarf2_parse_attr_as_string(dwarf2_abbrev_entry_attr_t* attr,
- dwarf2_parse_context_t* ctx)
-{
- const char* ret = NULL;
- switch (attr->form) {
- case DW_FORM_string:
- ret = (const char*) ctx->data;
- ctx->data += strlen(ret) + 1;
- break;
- case DW_FORM_strp:
- {
- unsigned long offset = dwarf2_parse_u4(ctx);
- ret = (const char*) ctx->str_section + offset;
- /*FIXME("Unsupported indirect string format offset 0x%lx (in .debug_str)\n", offset);*/
- }
- break;
- default:
- ERR("Unsupported string format 0x%lx for attr 0x%lx\n", attr->form, attr->attribute);
- }
- return ret;
-}
-
-static unsigned long dwarf2_parse_attr_as_addr(dwarf2_abbrev_entry_attr_t* attr,
- dwarf2_parse_context_t* ctx)
-{
- unsigned long offset = 0;
- switch (ctx->word_size) {
- case 4:
- offset = *(const unsigned int*) ctx->data;
- break;
- case 8:
- default:
- FIXME("Unsupported Word Size %u\n", ctx->word_size);
- }
- ctx->data += ctx->word_size;
- return offset;
-}
-
-static unsigned long dwarf2_parse_attr_as_ref(dwarf2_abbrev_entry_attr_t* attr,
- dwarf2_parse_context_t* ctx)
-{
- unsigned long uvalue = 0;
- switch (attr->form) {
- case DW_FORM_ref1:
- uvalue = ctx->offset + dwarf2_parse_byte(ctx);
- TRACE("ref1<0x%lx>\n", uvalue);
- break;
-
- case DW_FORM_ref2:
- uvalue = ctx->offset + dwarf2_parse_u2(ctx);
- TRACE("ref2<0x%lx>\n", uvalue);
- break;
-
- case DW_FORM_ref4:
- uvalue = ctx->offset + dwarf2_parse_u4(ctx);
- TRACE("ref4<0x%lx>\n", uvalue);
- break;
-
- case DW_FORM_ref8:
- /* FIXME: 64bits support */
- /*
- uvalue = ctx->offset + dwarf2_parse_u8(ctx);
- TRACE("ref8<0x%lx>\n", uvalue);
- */
- ctx->data += 8;
- break;
- }
- return uvalue;
-}
-
-
-static unsigned long dwarf2_parse_attr_as_data(dwarf2_abbrev_entry_attr_t* attr,
- dwarf2_parse_context_t* ctx)
-{
- unsigned long uvalue = 0;
- switch (attr->form) {
- case DW_FORM_data1:
- uvalue = dwarf2_parse_byte(ctx);
- TRACE("data1<%lu>\n", uvalue);
- break;
-
- case DW_FORM_data2:
- uvalue = dwarf2_parse_u2(ctx);
- TRACE("data2<%lu>\n", uvalue);
- break;
-
- case DW_FORM_data4:
- uvalue = dwarf2_parse_u4(ctx);
- TRACE("data4<%lu>\n", uvalue);
- break;
-
- case DW_FORM_data8:
- FIXME("Unsupported 64bits support\n");
- ctx->data += 8;
- break;
- }
- return uvalue;
-}
-
-static void dwarf2_parse_attr(dwarf2_abbrev_entry_attr_t* attr,
- dwarf2_parse_context_t* ctx)
-{
- const unsigned long attribute = attr->attribute;
- const unsigned long form = attr->form;
- unsigned long uvalue = 0;
- long svalue = 0;
- const char* str = NULL;
-
- TRACE("(attr:0x%lx,form:0x%lx)\n", attribute, form);
-
- switch (form) {
- case DW_FORM_ref_addr:
- case DW_FORM_addr:
- uvalue = dwarf2_parse_attr_as_addr(attr, ctx);
- break;
-
- case DW_FORM_flag:
- uvalue = dwarf2_parse_byte(ctx);
- TRACE("flag<0x%lx>\n", uvalue);
- break;
-
- case DW_FORM_data1:
- uvalue = dwarf2_parse_byte(ctx);
- TRACE("data1<%lu>\n", uvalue);
- break;
-
- case DW_FORM_data2:
- uvalue = dwarf2_parse_u2(ctx);
- TRACE("data2<%lu>\n", uvalue);
- break;
-
- case DW_FORM_data4:
- uvalue = dwarf2_parse_u4(ctx);
- TRACE("data4<%lu>\n", uvalue);
- break;
-
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- uvalue = dwarf2_parse_attr_as_ref(attr, ctx);
- /*TRACE("ref<0x%lx>\n", ctx->offset + uvalue);*/
- break;
-
- case DW_FORM_data8:
- FIXME("Unsupported 64bits support\n");
- ctx->data += 8;
- break;
-
- case DW_FORM_sdata:
- svalue = dwarf2_leb128_as_signed(ctx);
- break;
-
- case DW_FORM_ref_udata:
- case DW_FORM_udata:
- uvalue = dwarf2_leb128_as_unsigned(ctx);
- break;
-
- case DW_FORM_string:
- case DW_FORM_strp:
- str = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("string<%s>\n", str);
- break;
-
- case DW_FORM_block:
- uvalue = dwarf2_leb128_as_unsigned(ctx);
- ctx->data += uvalue;
- break;
-
- case DW_FORM_block1:
- uvalue = dwarf2_parse_byte(ctx);
- ctx->data += uvalue;
- break;
-
- case DW_FORM_block2:
- uvalue = dwarf2_parse_u2(ctx);
- ctx->data += uvalue;
- break;
-
- case DW_FORM_block4:
- uvalue = dwarf2_parse_u4(ctx);
- ctx->data += uvalue;
- break;
-
- default:
- break;
- }
-}
-
static void dwarf2_parse_attr_into_di(dwarf2_parse_context_t* ctx,
const dwarf2_abbrev_entry_attr_t* abbrev_attr,
union attribute* attr)
@@ -635,7 +436,6 @@ static BOOL dwarf2_find_attribute(const
static void dwarf2_find_name(dwarf2_parse_context_t* ctx,
const dwarf2_debug_info_t* di,
union attribute* attr, const char* pfx)
-
{
static int index;
@@ -647,10 +447,28 @@ static void dwarf2_find_name(dwarf2_pars
}
}
-static struct symt* dwarf2_find_symt_by_ref(struct module* module, unsigned long ref)
+static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*,
+ struct symt_compiland*);
+
+static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx,
+ const dwarf2_debug_info_t* di)
{
- WARN("want ref<0x%lx>\n", ref);
- return NULL;
+ union attribute attr;
+
+ if (dwarf2_find_attribute(di, DW_AT_type, &attr))
+ {
+ dwarf2_debug_info_t* type;
+
+ type = sparse_array_find(&ctx->debug_info_table, attr.uvalue);
+ if (!type) FIXME("Unable to find back reference to type %lx\n", attr.uvalue);
+ if (!type->symt)
+ {
+ /* load the debug info entity */
+ dwarf2_load_one_entry(ctx, type, NULL);
+ }
+ return type->symt;
+ }
+ return NULL;
}
/******************************************************************
@@ -669,6 +487,7 @@ static BOOL dwarf2_read_one_debug_info(d
dwarf2_debug_info_t** where;
dwarf2_abbrev_entry_attr_t* attr;
unsigned i;
+ union attribute sibling;
offset = ctx->data - ctx->data_stream;
entry_code = dwarf2_leb128_as_unsigned(ctx);
@@ -712,372 +531,188 @@ static BOOL dwarf2_read_one_debug_info(d
*where = child;
}
}
+ if (dwarf2_find_attribute(di, DW_AT_sibling, &sibling) &&
+ ctx->data != ctx->data_stream + sibling.uvalue)
+ {
+ WARN("setting cursor for %s to next sibling <0x%lx>\n",
+ dwarf2_debug_ctx(ctx), sibling.uvalue);
+ ctx->data = ctx->data_stream + sibling.uvalue;
+ }
*pdi = di;
return TRUE;
}
-static struct symt_basic* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
+static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- struct symt_basic* symt = NULL;
- const char* name = NULL;
- unsigned size = 0;
- unsigned encoding = 0;
- enum BasicType bt;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
-
- 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_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_byte_size:
- size = dwarf2_parse_attr_as_data(attr, ctx);
- break;
- case DW_AT_encoding:
- encoding = dwarf2_parse_byte(ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- switch (encoding) {
- case DW_ATE_void: bt = btVoid; break;
- case DW_ATE_address: bt = btULong; break;
- case DW_ATE_boolean: bt = btBool; break;
- case DW_ATE_complex_float: bt = btComplex; break;
- case DW_ATE_float: bt = btFloat; break;
- case DW_ATE_signed: bt = btInt; break;
- case DW_ATE_unsigned: bt = btUInt; break;
- case DW_ATE_signed_char: bt = btChar; break;
- case DW_ATE_unsigned_char: bt = btChar; break;
- default:
- bt = btNoType;
- }
- /*TRACE("symt_new_basic(%p, %u, %s, %u)", module, bt, name, size);*/
- symt = symt_new_basic(ctx->module, bt, name, size);
+ union attribute name;
+ union attribute size;
+ union attribute encoding;
+ enum BasicType bt;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
- return symt;
-}
+ if (di->symt) return di->symt;
-static struct symt_typedef* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
-{
- struct symt_typedef* symt = NULL;
- struct symt* ref_type = NULL;
- const char* name = NULL;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
-
- 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_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- 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(ctx->module, ref);
- }
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- if (NULL != name) {
- symt = symt_new_typedef(ctx->module, ref_type, name);
- }
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
- return symt;
+ dwarf2_find_name(ctx, di, &name, "base_type");
+ if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
+ if (!dwarf2_find_attribute(di, DW_AT_encoding, &encoding)) encoding.uvalue = DW_ATE_void;
+
+ switch (encoding.uvalue)
+ {
+ case DW_ATE_void: bt = btVoid; break;
+ case DW_ATE_address: bt = btULong; break;
+ case DW_ATE_boolean: bt = btBool; break;
+ case DW_ATE_complex_float: bt = btComplex; break;
+ case DW_ATE_float: bt = btFloat; break;
+ case DW_ATE_signed: bt = btInt; break;
+ case DW_ATE_unsigned: bt = btUInt; break;
+ case DW_ATE_signed_char: bt = btChar; break;
+ case DW_ATE_unsigned_char: bt = btChar; break;
+ default: bt = btNoType; break;
+ }
+ di->symt = &symt_new_basic(ctx->module, bt, name.string, size.uvalue)->symt;
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
+ return di->symt;
}
-static struct symt_pointer* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
+static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- struct symt_pointer* symt = NULL;
- struct symt* ref_type = NULL;
- unsigned size = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
-
- 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_byte_size:
- size = dwarf2_parse_attr_as_data(attr, ctx);
- break;
- case DW_AT_type:
- {
- unsigned long ref = dwarf2_parse_attr_as_ref(attr, ctx);
- ref_type = dwarf2_find_symt_by_ref(ctx->module, ref);
- }
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- symt = symt_new_pointer(ctx->module, ref_type);
+ struct symt* ref_type;
+ union attribute name;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
- return symt;
+ if (di->symt) return di->symt;
+
+ TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), di->abbrev->entry_code);
+
+ dwarf2_find_name(ctx, di, &name, "typedef");
+ ref_type = dwarf2_lookup_type(ctx, di);
+
+ if (name.string)
+ {
+ di->symt = &symt_new_typedef(ctx->module, ref_type, name.string)->symt;
+ }
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
+ return di->symt;
}
-static void dwarf2_parse_array_subrange_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_array* parent)
+static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- unsigned min = 0;
- unsigned max = 0;
- struct symt* idx_type = NULL;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
-
- 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(ctx->module, ref);
- /** check if idx_type is a basic_type integer */
- }
- break;
- case DW_AT_lower_bound:
- TRACE("%s %s, lower_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- min = dwarf2_parse_attr_as_data(attr, ctx);
- break;
- case DW_AT_upper_bound:
- TRACE("%s %s, upper_bound\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- max = dwarf2_parse_attr_as_data(attr, ctx);
- break;
- case DW_AT_count:
- TRACE("%s %s, count min:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), min);
- max = min + dwarf2_parse_attr_as_data(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- parent->start = min;
- parent->end = max;
- parent->index_type = idx_type;
+ struct symt* ref_type;
+ union attribute size;
- TRACE("found min:%u max:%u\n", min, max);
+ if (di->symt) return di->symt;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
-}
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+ if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
+ ref_type = dwarf2_lookup_type(ctx, di);
-static struct symt_array* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
+ di->symt = &symt_new_pointer(ctx->module, ref_type)->symt;
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
+ return di->symt;
+}
+
+static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- struct symt_array* symt = NULL;
- struct symt* ref_type = NULL;
- unsigned min = 0;
- unsigned max = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 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_sibling:
- 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(ctx->module, ref);
- }
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
+ struct symt* ref_type;
+ struct symt* idx_type = NULL;
+ union attribute min, max, cnt;
+ dwarf2_debug_info_t** pchild = NULL;
+ dwarf2_debug_info_t* child;
- /* FIXME: ugly as hell */
- symt = symt_new_array(ctx->module, min, max, ref_type, NULL);
-
- if (entry->have_child) { /** any interest to not have child ? */
- while (ctx->data < ctx->end_data) {
- dwarf2_abbrev_entry_t* entry = NULL;
- unsigned long entry_code;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- break ;
- }
-
- entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
- assert( NULL != entry );
-
- switch (entry->tag) {
- case DW_TAG_subrange_type:
- dwarf2_parse_array_subrange_type(ctx, entry, symt);
- break;
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, ctx);
- }
- }
- break;
- }
- }
- }
+ if (di->symt) return di->symt;
+
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ if (!di->abbrev->have_child)
+ {
+ FIXME("array without range information\n");
+ return NULL;
+ }
+ ref_type = dwarf2_lookup_type(ctx, di);
- return symt;
+ while ((pchild = vector_iter_up(&di->children, pchild)))
+ {
+ child = *pchild;
+ switch (child->abbrev->tag)
+ {
+ case DW_TAG_subrange_type:
+ idx_type = dwarf2_lookup_type(ctx, child);
+ if (!dwarf2_find_attribute(child, DW_AT_lower_bound, &min))
+ min.uvalue = 0;
+ if (!dwarf2_find_attribute(child, DW_AT_upper_bound, &max))
+ max.uvalue = 0;
+ if (dwarf2_find_attribute(child, DW_AT_count, &cnt))
+ max.uvalue = min.uvalue + cnt.uvalue;
+ break;
+ default:
+ FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
+ child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+ break;
+ }
+ }
+ di->symt = &symt_new_array(ctx->module, min.uvalue, max.uvalue, ref_type, idx_type)->symt;
+ return di->symt;
}
-static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
+static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- struct symt* ref_type = NULL;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 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(ctx->module, ref);
- }
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
+ struct symt* ref_type;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
+ if (di->symt) return di->symt;
+
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ ref_type = dwarf2_lookup_type(ctx, di);
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
+ di->symt = ref_type;
- return ref_type;
+ return ref_type;
}
-static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
+static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- struct symt* symt = NULL;
- struct symt* ref_type = NULL;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 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_sibling:
- 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(ctx->module, ref);
- }
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- /* FIXME: for now, we hard-wire C++ references to pointers */
- symt = &symt_new_pointer(ctx->module, ref_type)->symt;
+ struct symt* ref_type = NULL;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
+ if (di->symt) return di->symt;
+
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ ref_type = dwarf2_lookup_type(ctx, di);
+ /* FIXME: for now, we hard-wire C++ references to pointers */
+ di->symt = &symt_new_pointer(ctx->module, ref_type)->symt;
- return symt;
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
+
+ return di->symt;
}
-static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_udt* parent)
+static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di,
+ struct symt_udt* parent)
{
- 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;
-
- assert( NULL != parent );
-
- 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_sibling:
- next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- 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(ctx->module, ref);
- }
- break;
- case DW_AT_data_member_location:
- {
- unsigned long uvalue = 0;
+ struct symt* elt_type;
+ union attribute name;
+/* union attribute loc; */
+ unsigned long offset;
+
+ assert(parent);
+
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+
+ dwarf2_find_name(ctx, di, &name, "udt_member");
+ elt_type = dwarf2_lookup_type(ctx, di);
+#if 0
+ if (dwarf2_find_attribute(di, DW_AT_data_member_location, &loc))
+ {
TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- /*offset = dwarf2_parse_attr_as_data(attr, ctx);*/
- switch (attr->form) {
- case DW_FORM_block:
- uvalue = dwarf2_leb128_as_unsigned(ctx);
- break;
- case DW_FORM_block1:
- uvalue = dwarf2_parse_byte(ctx);
- break;
- case DW_FORM_block2:
- uvalue = dwarf2_parse_u2(ctx);
- break;
- case DW_FORM_block4:
- uvalue = dwarf2_parse_u4(ctx);
- break;
- default:
- WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- if (uvalue) {
+ if (loc.uvalue) {
unsigned char op = dwarf2_parse_byte(ctx);
--uvalue;
switch (op) {
@@ -1090,707 +725,328 @@ static void dwarf2_parse_udt_member(dwar
}
TRACE("found offset:%lu\n", offset);
}
- }
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
}
- }
- symt_add_udt_element(ctx->module, parent, name, elt_type, offset, size);
-
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
+#endif
+ FIXME("still to be implemented proper member location\n");
+ offset = 0;
+
+ symt_add_udt_element(ctx->module, parent, name.string, elt_type, offset, 0);
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
}
-static void dwarf2_parse_udt_members(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_udt* symt)
+static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di,
+ enum UdtKind udt)
{
- if (entry->have_child) { /** any interest to not have child ? */
- while (ctx->data < ctx->end_data) {
- dwarf2_abbrev_entry_t* entry = NULL;
- unsigned long entry_code;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- break ;
- }
-
- entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
- assert( NULL != entry );
-
- switch (entry->tag) {
- case DW_TAG_member:
- dwarf2_parse_udt_member(ctx, entry, symt);
- break;
- case DW_TAG_enumeration_type:
- dwarf2_parse_enumeration_type(ctx, entry);
- break;
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, ctx);
- }
- }
- break;
- }
+ union attribute name;
+ union attribute size;
+
+ if (di->symt) return di->symt;
+
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+
+ dwarf2_find_name(ctx, di, &name, "udt");
+ if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
+
+ di->symt = &symt_new_udt(ctx->module, name.string, size.uvalue, udt)->symt;
+
+ if (di->abbrev->have_child) /** any interest to not have child ? */
+ {
+ dwarf2_debug_info_t** pchild = NULL;
+ dwarf2_debug_info_t* child;
+
+ while ((pchild = vector_iter_up(&di->children, pchild)))
+ {
+ child = *pchild;
+
+ switch (child->abbrev->tag)
+ {
+ case DW_TAG_member:
+ /* FIXME: should I follow the sibling stuff ?? */
+ dwarf2_parse_udt_member(ctx, child, (struct symt_udt*)di->symt);
+ break;
+ case DW_TAG_enumeration_type:
+ dwarf2_parse_enumeration_type(ctx, child);
+ break;
+ default:
+ FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
+ child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+ break;
+ }
+ }
}
- }
+
+ return di->symt;
}
-static struct symt_udt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, enum UdtKind udt)
+static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di,
+ struct symt_enum* parent)
{
- struct symt_udt* symt = NULL;
- const char* name = NULL;
- unsigned size = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 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_sibling:
- next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_byte_size:
- size = dwarf2_parse_attr_as_data(attr, ctx);
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- symt = symt_new_udt(ctx->module, name, size, udt);
- dwarf2_parse_udt_members(ctx, entry, symt);
+ union attribute name;
+ union attribute value;
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- return symt;
+ dwarf2_find_name(ctx, di, &name, "enum_value");
+ if (!dwarf2_find_attribute(di, DW_AT_const_value, &value)) value.svalue = 0;
+ symt_add_enum_element(ctx->module, parent, name.string, value.svalue);
+
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
}
-static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_enum* parent)
+static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- const char* name = NULL;
- long value = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
-
- 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_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_const_value:
- switch (attr->form) {
- case DW_FORM_sdata:
- value = dwarf2_leb128_as_signed(ctx);
- TRACE("found value %ld\n", value);
- break;
- case DW_FORM_udata:
- value = dwarf2_leb128_as_unsigned(ctx);
- TRACE("found value %ld\n", value);
- break;
- default:
- WARN("Unhandled attr form at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- symt_add_enum_element(ctx->module, parent, name, value);
+ union attribute name;
+ union attribute size;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
-}
+ if (di->symt) return di->symt;
-static struct symt_enum* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
-{
- struct symt_enum* symt = NULL;
- const char* name = NULL;
- unsigned long size = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 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_sibling:
- next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_byte_size:
- size = dwarf2_parse_attr_as_data(attr, ctx);
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- symt = symt_new_enum(ctx->module, name);
-
- if (entry->have_child) { /** any interest to not have child ? */
- while (ctx->data < ctx->end_data) {
- dwarf2_abbrev_entry_t* entry = NULL;
- unsigned long entry_code;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- break ;
- }
-
- entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
- assert( NULL != entry );
-
- switch (entry->tag) {
- case DW_TAG_enumerator:
- dwarf2_parse_enumerator(ctx, entry, symt);
- break;
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, ctx);
- }
- }
- break;
- }
- }
- }
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ dwarf2_find_name(ctx, di, &name, "enum");
+ if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.uvalue = 0;
+
+ di->symt = &symt_new_enum(ctx->module, name.string)->symt;
+
+ if (di->abbrev->have_child) /* any interest to not have child ? */
+ {
+ dwarf2_debug_info_t** pchild = NULL;
+ dwarf2_debug_info_t* child;
- return symt;
+ /* FIXME: should we use the sibling stuff ?? */
+ while ((pchild = vector_iter_up(&di->children, pchild)))
+ {
+ child = *pchild;
+
+ switch (child->abbrev->tag)
+ {
+ case DW_TAG_enumerator:
+ dwarf2_parse_enumerator(ctx, child, (struct symt_enum*)di->symt);
+ break;
+ default:
+ FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
+ di->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+ }
+ }
+ }
+ return di->symt;
}
static void dwarf2_parse_variable(dwarf2_parse_context_t* ctx,
- dwarf2_abbrev_entry_t* entry)
+ dwarf2_debug_info_t* di)
{
- struct symt* var_type = NULL;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- const char* name = NULL;
- unsigned long next_sibling = 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_sibling:
- 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(ctx->module, ref);
- }
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
+ struct symt* var_type;
+ union attribute name;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+
+ var_type = dwarf2_lookup_type(ctx, di);
+ dwarf2_find_name(ctx, di, &name, "variable");
+ /* FIXME: still lots to do !!! */
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
}
static void dwarf2_parse_subprogram_parameter(dwarf2_parse_context_t* ctx,
- dwarf2_abbrev_entry_t* entry,
- struct symt_function_signature* sig_type,
- struct symt_function* func_type)
+ dwarf2_debug_info_t* di,
+ struct symt_function_signature* sig_type)
{
- struct symt* param_type = NULL;
- const char* name = NULL;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 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_sibling:
- 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(ctx->module, ref);
- }
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- case DW_AT_location:
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
- if (NULL != sig_type) {
- symt_add_function_signature_parameter(ctx->module, sig_type, param_type);
- }
+ struct symt* param_type;
+ union attribute name;
- if (entry->have_child) {
- FIXME("Unsupported children\n");
- }
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
+ param_type = dwarf2_lookup_type(ctx, di);
+ dwarf2_find_name(ctx, di, &name, "parameter");
+ /* DW_AT_location */
+ if (sig_type) symt_add_function_signature_parameter(ctx->module, sig_type, param_type);
+ /* FIXME: add variable to func_type */
+ if (di->abbrev->have_child) FIXME("Unsupported children\n");
}
-static void dwarf2_parse_inlined_subroutine(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry)
+static void dwarf2_parse_inlined_subroutine(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di)
{
- const char* name = NULL;
- unsigned long addr = 0;
- unsigned long low_pc = 0;
- unsigned long high_pc = 0;
- unsigned size = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 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_sibling:
- next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
- break;
- case DW_AT_low_pc:
- low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
- addr = ctx->module->module.BaseOfImage + low_pc;
- break;
- case DW_AT_high_pc:
- high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
- size = high_pc - low_pc;
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (entry->have_child) { /** any interest to not have child ? */
- while (ctx->data < ctx->end_data) {
- dwarf2_abbrev_entry_t* entry = NULL;
- unsigned long entry_code;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- break ;
- }
-
- entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
- assert( NULL != entry );
-
- switch (entry->tag) {
- case DW_TAG_formal_parameter:
- dwarf2_parse_subprogram_parameter(ctx, entry, NULL, NULL);
- break;
- case DW_TAG_variable:
- dwarf2_parse_variable(ctx, entry);
- break;
- case DW_TAG_label:
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, ctx);
- }
- }
- break;
- }
- }
- }
+ /* FIXME: attributes to handle:
+ DW_AT_low_pc:
+ DW_AT_high_pc:
+ DW_AT_name:
+ */
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
-}
+ if (di->abbrev->have_child) /** any interest to not have child ? */
+ {
+ dwarf2_debug_info_t** pchild = NULL;
+ dwarf2_debug_info_t* child;
+ while ((pchild = vector_iter_up(&di->children, pchild)))
+ {
+ child = *pchild;
+
+ switch (child->abbrev->tag)
+ {
+ case DW_TAG_formal_parameter:
+ /* FIXME: this is not properly supported yet
+ * dwarf2_parse_subprogram_parameter(ctx, child, NULL);
+ */
+ break;
+ case DW_TAG_variable:
+ dwarf2_parse_variable(ctx, child);
+ break;
+ default:
+ FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
+ child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+ }
+ }
+ }
+}
static void dwarf2_parse_subprogram_block(dwarf2_parse_context_t* ctx,
- dwarf2_abbrev_entry_t* entry,
+ dwarf2_debug_info_t* di,
struct symt_function_signature* sig_type,
- struct symt_function* func_type)
+ struct symt_function* func)
{
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- const char* name = NULL;
- unsigned long next_sibling = 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_sibling:
- next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
- case DW_AT_decl_file:
- case DW_AT_decl_line:
- dwarf2_parse_attr(attr, ctx);
- break;
- case DW_AT_ranges: /** what to do ? */
- dwarf2_parse_attr(attr, ctx);
- break;
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
- }
- }
-
- if (entry->have_child) { /** any interest to not have child ? */
- while (ctx->data < ctx->end_data) {
- dwarf2_abbrev_entry_t* entry = NULL;
- unsigned long entry_code;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- break ;
- }
-
- entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
- assert( NULL != entry );
-
- switch (entry->tag) {
- case DW_TAG_inlined_subroutine:
- dwarf2_parse_inlined_subroutine(ctx, entry);
- break;
- case DW_TAG_variable:
- dwarf2_parse_variable(ctx, entry);
- break;
- case DW_TAG_label:
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, ctx);
- }
- }
- break;
- }
- }
- }
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
-}
+ /* if (!dwarf2_find_attribute(di, DW_AT_ranges, ??)): what to do ? */
-static void dwarf2_parse_subprogram_content(dwarf2_parse_context_t* ctx,
- dwarf2_abbrev_entry_t* entry,
- struct symt_function_signature* sig_type,
- struct symt_function* func_type)
-{
- if (entry->have_child) { /** any interest to not have child ? */
- while (ctx->data < ctx->end_data) {
- dwarf2_abbrev_entry_t* entry = NULL;
- unsigned long entry_code;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- break ;
- }
-
- entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
- assert( NULL != entry );
-
- switch (entry->tag) {
- case DW_TAG_formal_parameter:
- dwarf2_parse_subprogram_parameter(ctx, entry, sig_type, func_type);
- break;
- case DW_TAG_lexical_block:
- dwarf2_parse_subprogram_block(ctx, entry, sig_type, func_type);
- break;
- case DW_TAG_variable:
- dwarf2_parse_variable(ctx, entry);
- break;
- case DW_TAG_label:
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, ctx);
- }
- }
- break;
- }
- }
- }
-}
+ if (di->abbrev->have_child) /** any interest to not have child ? */
+ {
+ dwarf2_debug_info_t** pchild = NULL;
+ dwarf2_debug_info_t* child;
-static struct symt_function* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, dwarf2_abbrev_entry_t* entry, struct symt_compiland* compiland)
-{
- struct symt_function* func_type = NULL;
- const char* name = NULL;
- struct symt* ret_type = NULL;
- struct symt_function_signature* sig_type = NULL;
- unsigned long addr = 0;
- unsigned long low_pc = 0;
- unsigned long high_pc = 0;
- unsigned size = 0;
- unsigned char is_decl = 0;
- unsigned char inl_flags = 0;
- unsigned char decl_file = 0;
- unsigned char decl_line = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
- unsigned long next_sibling = 0;
- enum CV_call_e call_conv = CV_CALL_FAR_C; /* FIXME: assuming C source code */
- unsigned cc;
-
- 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_sibling:
- next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
- break;
- case DW_AT_low_pc:
- low_pc = dwarf2_parse_attr_as_addr(attr, ctx);
- addr = ctx->module->module.BaseOfImage + low_pc;
- break;
- case DW_AT_high_pc:
- high_pc = dwarf2_parse_attr_as_addr(attr, ctx);
- size = high_pc - low_pc;
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- 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(ctx->module, ref);
- }
- break;
- case DW_AT_declaration:
- is_decl = dwarf2_parse_byte(ctx);
- break;
- case DW_AT_inline:
- inl_flags = dwarf2_parse_byte(ctx);
- break;
- case DW_AT_calling_convention:
- switch (cc = dwarf2_parse_byte(ctx))
+ while ((pchild = vector_iter_up(&di->children, pchild)))
{
- case DW_CC_normal: break;
- case DW_CC_nocall: call_conv = -1;
- default: FIXME("Unsupported calling convention %d\n", cc);
+ child = *pchild;
+
+ switch (child->abbrev->tag)
+ {
+ case DW_TAG_inlined_subroutine:
+ dwarf2_parse_inlined_subroutine(ctx, child);
+ break;
+ case DW_TAG_variable:
+ dwarf2_parse_variable(ctx, child);
+ break;
+ default:
+ FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
+ child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+ }
}
- break;
- /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
- case DW_AT_decl_file:
- decl_file = dwarf2_parse_byte(ctx);
- break;
- case DW_AT_decl_line:
- decl_line = dwarf2_parse_byte(ctx);
- break;
- */
- default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
}
- }
- sig_type = symt_new_function_signature(ctx->module, ret_type, call_conv);
- if (!is_decl) {
- func_type = symt_new_function(ctx->module, compiland, name, addr, size, &sig_type->symt);
- if (low_pc && high_pc) {
- symt_add_function_point(ctx->module, func_type, SymTagFuncDebugStart, low_pc, NULL);
- symt_add_function_point(ctx->module, func_type, SymTagFuncDebugEnd, high_pc, NULL);
- }
- if (decl_file && decl_line) {
- symt_add_func_line(ctx->module, func_type, decl_file, decl_line, low_pc);
- }
- }
- dwarf2_parse_subprogram_content(ctx, entry, sig_type, func_type);
- symt_normalize_function(ctx->module, func_type);
-
- /** set correct data cursor */
- dwarf2_check_sibling(ctx, next_sibling);
-
- return func_type;
}
-static void dwarf2_parse_compiland_content(dwarf2_parse_context_t* ctx, const dwarf2_abbrev_entry_t* entry, struct symt_compiland* compiland)
+static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di,
+ struct symt_compiland* compiland)
{
- if (entry->have_child) { /** any interest to not have child ? */
- while (ctx->data < ctx->end_data) {
- dwarf2_abbrev_entry_t* entry = NULL;
- unsigned long entry_code;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- break ;
- }
-
- entry = dwarf2_abbrev_table_find_entry(&ctx->abbrev_table, entry_code);
- assert( NULL != entry );
-
- switch (entry->tag) {
- case DW_TAG_typedef:
- dwarf2_parse_typedef(ctx, entry);
- break;
- case DW_TAG_base_type:
- dwarf2_parse_base_type(ctx, entry);
- break;
- case DW_TAG_pointer_type:
- dwarf2_parse_pointer_type(ctx, entry);
- break;
- case DW_TAG_class_type:
- dwarf2_parse_udt_type(ctx, entry, UdtClass);
- break;
- case DW_TAG_structure_type:
- dwarf2_parse_udt_type(ctx, entry, UdtStruct);
- break;
- case DW_TAG_union_type:
- dwarf2_parse_udt_type(ctx, entry, UdtUnion);
- break;
- case DW_TAG_array_type:
- dwarf2_parse_array_type(ctx, entry);
- break;
- case DW_TAG_const_type:
- dwarf2_parse_const_type(ctx, entry);
- break;
- case DW_TAG_reference_type:
- dwarf2_parse_reference_type(ctx, entry);
- break;
- case DW_TAG_enumeration_type:
- dwarf2_parse_enumeration_type(ctx, entry);
- break;
- case DW_TAG_subprogram:
- dwarf2_parse_subprogram(ctx, entry, compiland);
- break;
-
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, ctx);
- }
+ union attribute name;
+ union attribute low_pc;
+ union attribute high_pc;
+ union attribute is_decl;
+ union attribute inline_flags;
+ struct symt* ret_type;
+ struct symt_function* func = NULL;
+ struct symt_function_signature* sig_type;
+
+ if (di->symt) return di->symt;
+
+ TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+
+ if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.uvalue = 0;
+ if (!dwarf2_find_attribute(di, DW_AT_high_pc, &high_pc)) high_pc.uvalue = 0;
+ if (!dwarf2_find_attribute(di, DW_AT_declaration, &is_decl)) is_decl.uvalue = 0;
+ if (!dwarf2_find_attribute(di, DW_AT_inline, &inline_flags)) inline_flags.uvalue = 0;
+ dwarf2_find_name(ctx, di, &name, "subprogram");
+ ret_type = dwarf2_lookup_type(ctx, di);
+
+ /* FIXME: assuming C source code */
+ sig_type = symt_new_function_signature(ctx->module, ret_type, CV_CALL_FAR_C);
+ if (!is_decl.uvalue)
+ {
+ func = symt_new_function(ctx->module, compiland, name.string,
+ low_pc.uvalue, high_pc.uvalue - low_pc.uvalue,
+ &sig_type->symt);
+ di->symt = &func->symt;
+ }
+ if (di->abbrev->have_child) /** any interest to not have child ? */
+ {
+ dwarf2_debug_info_t** pchild = NULL;
+ dwarf2_debug_info_t* child;
+
+ while ((pchild = vector_iter_up(&di->children, pchild)))
+ {
+ child = *pchild;
+
+ switch (child->abbrev->tag)
+ {
+ case DW_TAG_formal_parameter:
+ dwarf2_parse_subprogram_parameter(ctx, child, sig_type);
+ break;
+ case DW_TAG_lexical_block:
+ dwarf2_parse_subprogram_block(ctx, child, sig_type, func);
+ break;
+ case DW_TAG_variable:
+ dwarf2_parse_variable(ctx, child);
+ break;
+ default:
+ FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
+ child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
+ }
}
- break;
- }
}
- }
+
+ symt_normalize_function(ctx->module, func);
+
+ return di->symt;
}
-static struct symt_compiland* dwarf2_parse_compiland(dwarf2_parse_context_t* ctx, const dwarf2_abbrev_entry_t* entry)
+static void dwarf2_load_one_entry(dwarf2_parse_context_t* ctx,
+ dwarf2_debug_info_t* di,
+ struct symt_compiland* compiland)
{
- struct symt_compiland* compiland = NULL;
- const char* name = NULL;
- unsigned long next_sibling = 0;
- dwarf2_abbrev_entry_attr_t* attr = NULL;
-
- TRACE("beginning at Ox%x, for %lu\n", ctx->data - ctx->start_data, entry->entry_code);
-
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- switch (attr->attribute) {
- case DW_AT_sibling:
- next_sibling = dwarf2_parse_attr_as_ref(attr, ctx);
- break;
- case DW_AT_name:
- name = dwarf2_parse_attr_as_string(attr, ctx);
- TRACE("found name %s\n", name);
- break;
+ switch (di->abbrev->tag)
+ {
+ case DW_TAG_typedef:
+ dwarf2_parse_typedef(ctx, di);
+ break;
+ case DW_TAG_base_type:
+ dwarf2_parse_base_type(ctx, di);
+ break;
+ case DW_TAG_pointer_type:
+ dwarf2_parse_pointer_type(ctx, di);
+ break;
+ case DW_TAG_class_type:
+ dwarf2_parse_udt_type(ctx, di, UdtClass);
+ break;
+ case DW_TAG_structure_type:
+ dwarf2_parse_udt_type(ctx, di, UdtStruct);
+ break;
+ case DW_TAG_union_type:
+ dwarf2_parse_udt_type(ctx, di, UdtUnion);
+ break;
+ case DW_TAG_array_type:
+ dwarf2_parse_array_type(ctx, di);
+ break;
+ case DW_TAG_const_type:
+ dwarf2_parse_const_type(ctx, di);
+ break;
+ case DW_TAG_reference_type:
+ dwarf2_parse_reference_type(ctx, di);
+ break;
+ case DW_TAG_enumeration_type:
+ dwarf2_parse_enumeration_type(ctx, di);
+ break;
+ case DW_TAG_subprogram:
+ dwarf2_parse_subprogram(ctx, di, compiland);
+ break;
default:
- WARN("Unhandled attr at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr));
- dwarf2_parse_attr(attr, ctx);
+ WARN("Unhandled Tag type 0x%lx at %s, for %lu\n",
+ di->abbrev->tag, dwarf2_debug_ctx(ctx), di->abbrev->entry_code);
}
- }
- compiland = symt_new_compiland(ctx->module, name);
- dwarf2_parse_compiland_content(ctx, entry, compiland);
-
- dwarf2_check_sibling(ctx, next_sibling);
-
- return compiland;
}
BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
@@ -1806,7 +1062,6 @@ BOOL dwarf2_parse(struct module* module,
dwarf2_comp_unit_t comp_unit;
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;
@@ -1849,40 +1104,25 @@ BOOL dwarf2_parse(struct module* module,
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;
- unsigned long entry_ref = 0;
-
- 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);
- if (0 == entry_code) {
- continue ;
- }
- 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);
- pool_destroy(&ctx.pool);
- return FALSE;
- }
-
- switch (entry->tag) {
- case DW_TAG_compile_unit:
- compiland = dwarf2_parse_compiland(&ctx, entry);
- break;
- default:
- {
- dwarf2_abbrev_entry_attr_t* attr;
- WARN("Unhandled Tag type 0x%lx at %s, for %lu\n", entry->tag, dwarf2_debug_ctx(&ctx), entry->entry_code);
- for (attr = entry->attrs; NULL != attr; attr = attr->next) {
- dwarf2_parse_attr(attr, &ctx);
- }
- }
- break;
- }
+ if (di->abbrev->tag == DW_TAG_compile_unit)
+ {
+ union attribute name;
+ dwarf2_debug_info_t** pdi = NULL;
+
+ TRACE("beginning at 0x%lx, for %lu\n", di->offset, di->abbrev->entry_code);
+
+ dwarf2_find_name(&ctx, di, &name, "compiland");
+ di->symt = &symt_new_compiland(module, name.string)->symt;
+
+ if (di->abbrev->have_child)
+ {
+ while ((pdi = vector_iter_up(&di->children, pdi)))
+ {
+ dwarf2_load_one_entry(&ctx, *pdi, (struct symt_compiland*)di->symt);
+ }
+ }
}
+ else FIXME("Should have a compilation unit here\n");
pool_destroy(&ctx.pool);
}
More information about the wine-patches
mailing list