Eric Pouech : dbghelp: dwarf: Started parsing the attributes for
lines ( in compilation unit).
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jun 20 05:23:43 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 52db5c094e6c9c7a883c71d996d3aaafa325f0a4
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=52db5c094e6c9c7a883c71d996d3aaafa325f0a4
Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date: Sun Jun 18 21:32:17 2006 +0200
dbghelp: dwarf: Started parsing the attributes for lines (in compilation unit).
Walking the whole lot, not doing anything interesting apart from
traversing the data.
---
dlls/dbghelp/dwarf.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++
dlls/dbghelp/dwarf.h | 15 +++++
2 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 12d0226..c7eabdd 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -1380,6 +1380,147 @@ static void dwarf2_load_one_entry(dwarf2
}
}
+static void dwarf2_parse_line_numbers(const dwarf2_section_t* sections,
+ dwarf2_parse_context_t* ctx,
+ unsigned long offset)
+{
+ dwarf2_traverse_context_t traverse;
+ unsigned long length;
+ unsigned version, header_len, insn_size, default_stmt;
+ unsigned line_range, opcode_base;
+ int line_base;
+ const unsigned char* opcode_len;
+
+ traverse.sections = sections;
+ traverse.section = section_line;
+ traverse.data = sections[section_line].address + offset;
+ traverse.start_data = traverse.data;
+ traverse.end_data = traverse.data + 4;
+ traverse.offset = offset;
+ traverse.word_size = ctx->word_size;
+
+ length = dwarf2_parse_u4(&traverse);
+ traverse.end_data = traverse.start_data + length;
+
+ version = dwarf2_parse_u2(&traverse);
+ header_len = dwarf2_parse_u4(&traverse);
+ insn_size = dwarf2_parse_byte(&traverse);
+ default_stmt = dwarf2_parse_byte(&traverse);
+ line_base = (char)dwarf2_parse_byte(&traverse);
+ line_range = dwarf2_parse_byte(&traverse);
+ opcode_base = dwarf2_parse_byte(&traverse);
+
+ opcode_len = traverse.data;
+ traverse.data += opcode_base;
+
+ while (*traverse.data)
+ {
+ TRACE("Got include %s\n", (const char*)traverse.data);
+ traverse.data += strlen((const char *)traverse.data) + 1;
+ }
+ traverse.data++;
+ while (*traverse.data)
+ {
+ unsigned int dir_index, mod_time, length;
+ const char* name;
+
+ name = (const char*)traverse.data;
+ traverse.data += strlen(name) + 1;
+ dir_index = dwarf2_leb128_as_unsigned(&traverse);
+ mod_time = dwarf2_leb128_as_unsigned(&traverse);
+ length = dwarf2_leb128_as_unsigned(&traverse);
+ TRACE("Got file %s (%u,%u,%u)\n",
+ name, dir_index, mod_time, length);
+ }
+ traverse.data++;
+
+ while (traverse.data < traverse.end_data)
+ {
+ unsigned long address;
+ unsigned file = 1;
+ unsigned line = 1;
+ unsigned is_stmt = default_stmt;
+ BOOL basic_block = FALSE, end_sequence = FALSE;
+ unsigned opcode, extopcode, i;
+
+ while (!end_sequence)
+ {
+ opcode = dwarf2_parse_byte(&traverse);
+ TRACE("Got opcode %x\n", opcode);
+
+ if (opcode >= opcode_base)
+ {
+ unsigned delta = opcode - opcode_base;
+
+ address += (delta / line_range) * insn_size;
+ line += line_base + (delta % line_range);
+ basic_block = TRUE;
+ }
+ else
+ {
+ switch (opcode)
+ {
+ case DW_LNS_copy:
+ basic_block = FALSE;
+ break;
+ case DW_LNS_advance_pc:
+ address += insn_size * dwarf2_leb128_as_unsigned(&traverse);
+ break;
+ case DW_LNS_advance_line:
+ line += dwarf2_leb128_as_unsigned(&traverse);
+ break;
+ case DW_LNS_set_file:
+ file = dwarf2_leb128_as_signed(&traverse);
+ break;
+ case DW_LNS_set_column:
+ dwarf2_leb128_as_unsigned(&traverse);
+ break;
+ case DW_LNS_negate_stmt:
+ is_stmt = !is_stmt;
+ break;
+ case DW_LNS_set_basic_block:
+ basic_block = 1;
+ break;
+ case DW_LNS_const_add_pc:
+ address += ((255 - opcode_base) / line_range) * insn_size;
+ break;
+ case DW_LNS_fixed_advance_pc:
+ address += dwarf2_parse_u2(&traverse);
+ break;
+ case DW_LNS_extended_op:
+ dwarf2_leb128_as_unsigned(&traverse);
+ extopcode = dwarf2_parse_byte(&traverse);
+ switch (extopcode)
+ {
+ case DW_LNE_end_sequence:
+ end_sequence = TRUE;
+ break;
+ case DW_LNE_set_address:
+ address = dwarf2_parse_addr(&traverse);
+ address += ctx->module->module.BaseOfImage;
+ break;
+ case DW_LNE_define_file:
+ traverse.data += strlen((const char *)traverse.data) + 1;
+ dwarf2_leb128_as_unsigned(&traverse);
+ dwarf2_leb128_as_unsigned(&traverse);
+ dwarf2_leb128_as_unsigned(&traverse);
+ break;
+ default:
+ FIXME("Unsupported extended opcode %x\n", extopcode);
+ break;
+ }
+ break;
+ default:
+ WARN("Unsupported opcode %x\n", opcode);
+ for (i = 0; i < opcode_len[opcode]; i++)
+ dwarf2_leb128_as_unsigned(&traverse);
+ break;
+ }
+ }
+ }
+ }
+}
+
static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections,
const dwarf2_comp_unit_t* comp_unit,
struct module* module,
@@ -1433,6 +1574,7 @@ static BOOL dwarf2_parse_compilation_uni
{
union attribute name;
dwarf2_debug_info_t** pdi = NULL;
+ union attribute stmt_list;
TRACE("beginning at 0x%lx, for %lu\n", di->offset, di->abbrev->entry_code);
@@ -1446,6 +1588,10 @@ static BOOL dwarf2_parse_compilation_uni
dwarf2_load_one_entry(&ctx, *pdi, (struct symt_compiland*)di->symt);
}
}
+ if (dwarf2_find_attribute(di, DW_AT_stmt_list, &stmt_list))
+ {
+ dwarf2_parse_line_numbers(sections, &ctx, stmt_list.uvalue);
+ }
ret = TRUE;
}
else FIXME("Should have a compilation unit here\n");
diff --git a/dlls/dbghelp/dwarf.h b/dlls/dbghelp/dwarf.h
index 4307720..c03799e 100644
--- a/dlls/dbghelp/dwarf.h
+++ b/dlls/dbghelp/dwarf.h
@@ -386,3 +386,18 @@ enum dwarf_calling_convention
#define DW_CC_lo_user 0x40
#define DW_CC_hi_user 0xff
+
+#define DW_LNS_extended_op 0x00
+#define DW_LNS_copy 0x01
+#define DW_LNS_advance_pc 0x02
+#define DW_LNS_advance_line 0x03
+#define DW_LNS_set_file 0x04
+#define DW_LNS_set_column 0x05
+#define DW_LNS_negate_stmt 0x06
+#define DW_LNS_set_basic_block 0x07
+#define DW_LNS_const_add_pc 0x08
+#define DW_LNS_fixed_advance_pc 0x09
+
+#define DW_LNE_end_sequence 0x01
+#define DW_LNE_set_address 0x02
+#define DW_LNE_define_file 0x03
More information about the wine-cvs
mailing list