[PATCH 3/9] dbghelp/dwarf: Keep open and keep track of parse_context_t inside a module_context_t
Eric Pouech
eric.pouech at gmail.com
Wed Sep 15 03:37:58 CDT 2021
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
dlls/dbghelp/dwarf.c | 97 ++++++++++++++++++++++++++++++--------------------
1 file changed, 58 insertions(+), 39 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 4bb5bb23ac6..e64fcbb822e 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -180,8 +180,16 @@ typedef struct dwarf2_parse_module_context_s
struct module* module;
const struct elf_thunk_area*thunks;
struct symt* symt_cache[sc_num]; /* void, unknown */
+ struct vector unit_contexts;
} dwarf2_parse_module_context_t;
+enum unit_status
+{
+ UNIT_ERROR,
+ UNIT_NOTLOADED,
+ UNIT_LOADED,
+};
+
/* this is the context used for parsing a compilation unit
* inside an ELF/PE section (likely .debug_info)
*/
@@ -196,6 +204,7 @@ typedef struct dwarf2_parse_context_s
ULONG_PTR ref_offset;
char* cpp_name;
dwarf2_cuhead_t head;
+ enum unit_status status;
} dwarf2_parse_context_t;
/* stored in the dbghelp's module internal structure for later reuse */
@@ -2440,10 +2449,9 @@ unsigned dwarf2_cache_cuhead(struct dwarf2_module_info_s* module, struct symt_co
return TRUE;
}
-static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_ctx,
+static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx,
dwarf2_traverse_context_t* mod_ctx)
{
- dwarf2_parse_context_t ctx;
dwarf2_traverse_context_t abbrev_ctx;
dwarf2_debug_info_t* di;
dwarf2_traverse_context_t cu_ctx;
@@ -2454,22 +2462,23 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_
/* FIXME this is a temporary configuration while adding support for dwarf3&4 bits */
static LONG max_supported_dwarf_version = 0;
- cu_length = dwarf2_parse_3264(mod_ctx, &ctx.head.offset_size);
+ cu_length = dwarf2_parse_3264(mod_ctx, &ctx->head.offset_size);
cu_ctx.data = mod_ctx->data;
cu_ctx.end_data = mod_ctx->data + cu_length;
mod_ctx->data += cu_length;
- ctx.head.version = dwarf2_parse_u2(&cu_ctx);
- cu_abbrev_offset = dwarf2_parse_offset(&cu_ctx, ctx.head.offset_size);
- ctx.head.word_size = dwarf2_parse_byte(&cu_ctx);
+ ctx->head.version = dwarf2_parse_u2(&cu_ctx);
+ cu_abbrev_offset = dwarf2_parse_offset(&cu_ctx, ctx->head.offset_size);
+ ctx->head.word_size = dwarf2_parse_byte(&cu_ctx);
+ ctx->status = UNIT_ERROR;
TRACE("Compilation Unit Header found at 0x%x:\n",
- (int)(comp_unit_start - module_ctx->sections[section_debug].address));
+ (int)(comp_unit_start - ctx->module_ctx->sections[section_debug].address));
TRACE("- length: %lu\n", cu_length);
- TRACE("- version: %u\n", ctx.head.version);
+ TRACE("- version: %u\n", ctx->head.version);
TRACE("- abbrev_offset: %lu\n", cu_abbrev_offset);
- TRACE("- word_size: %u\n", ctx.head.word_size);
- TRACE("- offset_size: %u\n", ctx.head.offset_size);
+ TRACE("- word_size: %u\n", ctx->head.word_size);
+ TRACE("- offset_size: %u\n", ctx->head.offset_size);
if (max_supported_dwarf_version == 0)
{
@@ -2478,30 +2487,30 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_
max_supported_dwarf_version = (v >= 2 && v <= 4) ? v : 2;
}
- if (ctx.head.version < 2 || ctx.head.version > max_supported_dwarf_version)
+ if (ctx->head.version < 2 || ctx->head.version > max_supported_dwarf_version)
{
if (max_supported_dwarf_version > 2)
WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2 up to %u.\n",
- ctx.head.version, max_supported_dwarf_version);
+ ctx->head.version, max_supported_dwarf_version);
else
WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n",
- ctx.head.version);
+ ctx->head.version);
return FALSE;
}
- pool_init(&ctx.pool, 65536);
- ctx.section = section_debug;
- ctx.ref_offset = comp_unit_start - module_ctx->sections[section_debug].address;
- ctx.cpp_name = NULL;
- ctx.module_ctx = module_ctx;
+ pool_init(&ctx->pool, 65536);
+ ctx->section = section_debug;
+ ctx->ref_offset = comp_unit_start - ctx->module_ctx->sections[section_debug].address;
+ ctx->cpp_name = NULL;
+ ctx->status = UNIT_NOTLOADED;
- abbrev_ctx.data = module_ctx->sections[section_abbrev].address + cu_abbrev_offset;
- abbrev_ctx.end_data = module_ctx->sections[section_abbrev].address + module_ctx->sections[section_abbrev].size;
- dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
+ abbrev_ctx.data = ctx->module_ctx->sections[section_abbrev].address + cu_abbrev_offset;
+ abbrev_ctx.end_data = ctx->module_ctx->sections[section_abbrev].address + ctx->module_ctx->sections[section_abbrev].size;
+ dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx->abbrev_table, &ctx->pool);
- sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128);
+ sparse_array_init(&ctx->debug_info_table, sizeof(dwarf2_debug_info_t), 128);
- if (dwarf2_read_one_debug_info(&ctx, &cu_ctx, NULL, &di))
+ if (dwarf2_read_one_debug_info(ctx, &cu_ctx, NULL, &di))
{
if (di->abbrev->tag == DW_TAG_compile_unit)
{
@@ -2512,37 +2521,35 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_
struct attribute stmt_list, low_pc;
struct attribute comp_dir;
- if (!dwarf2_find_attribute(&ctx, di, DW_AT_name, &name))
+ if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name))
name.u.string = NULL;
/* get working directory of current compilation unit */
- if (!dwarf2_find_attribute(&ctx, di, DW_AT_comp_dir, &comp_dir))
+ if (!dwarf2_find_attribute(ctx, di, DW_AT_comp_dir, &comp_dir))
comp_dir.u.string = NULL;
- if (!dwarf2_find_attribute(&ctx, di, DW_AT_low_pc, &low_pc))
+ if (!dwarf2_find_attribute(ctx, di, DW_AT_low_pc, &low_pc))
low_pc.u.uvalue = 0;
-
- ctx.compiland = symt_new_compiland(module_ctx->module, module_ctx->load_offset + low_pc.u.uvalue,
- source_new(module_ctx->module, comp_dir.u.string, name.u.string));
- dwarf2_cache_cuhead(module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx.compiland, &ctx.head);
-
- di->symt = &ctx.compiland->symt;
- children = dwarf2_get_di_children(&ctx, di);
+ ctx->compiland = symt_new_compiland(ctx->module_ctx->module, ctx->module_ctx->load_offset + low_pc.u.uvalue,
+ source_new(ctx->module_ctx->module, comp_dir.u.string, name.u.string));
+ dwarf2_cache_cuhead(ctx->module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx->compiland, &ctx->head);
+ di->symt = &ctx->compiland->symt;
+ children = dwarf2_get_di_children(ctx, di);
if (children) for (i = 0; i < vector_length(children); i++)
{
child = *(dwarf2_debug_info_t**)vector_at(children, i);
- dwarf2_load_one_entry(&ctx, child);
+ dwarf2_load_one_entry(ctx, child);
}
- if (dwarf2_find_attribute(&ctx, di, DW_AT_stmt_list, &stmt_list))
+ if (dwarf2_find_attribute(ctx, di, DW_AT_stmt_list, &stmt_list))
{
- if (dwarf2_parse_line_numbers(&ctx, comp_dir.u.string, stmt_list.u.uvalue))
- module_ctx->module->module.LineNumbers = TRUE;
+ if (dwarf2_parse_line_numbers(ctx, comp_dir.u.string, stmt_list.u.uvalue))
+ ctx->module_ctx->module->module.LineNumbers = TRUE;
}
+ ctx->status = UNIT_LOADED;
ret = TRUE;
}
else FIXME("Should have a compilation unit here\n");
}
- pool_destroy(&ctx.pool);
return ret;
}
@@ -3605,6 +3612,7 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset,
BOOL ret = TRUE;
struct module_format* dwarf2_modfmt;
dwarf2_parse_module_context_t module_ctx;
+ unsigned i;
if (!dwarf2_init_section(&eh_frame, fmap, ".eh_frame", NULL, &eh_frame_sect))
/* lld produces .eh_fram to avoid generating a long name */
@@ -3667,10 +3675,14 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset,
memset(module_ctx.symt_cache, 0, sizeof(module_ctx.symt_cache));
module_ctx.symt_cache[sc_void] = &symt_new_basic(module_ctx.module, btVoid, "void", 0)->symt;
module_ctx.symt_cache[sc_unknown] = &symt_new_basic(module_ctx.module, btNoType, "# unknown", 0)->symt;
+ vector_init(&module_ctx.unit_contexts, sizeof(dwarf2_parse_context_t), 16);
while (mod_ctx.data < mod_ctx.end_data)
{
- dwarf2_parse_compilation_unit(&module_ctx, &mod_ctx);
+ dwarf2_parse_context_t* unit_ctx = vector_add(&module_ctx.unit_contexts, &module_ctx.module->pool);
+
+ unit_ctx->module_ctx = &module_ctx;
+ dwarf2_parse_compilation_unit(unit_ctx, &mod_ctx);
}
dwarf2_modfmt->module->module.SymType = SymDia;
dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24);
@@ -3680,6 +3692,13 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset,
dwarf2_modfmt->module->module.SourceIndexed = TRUE;
dwarf2_modfmt->module->module.Publics = TRUE;
+ for (i = 0; i < module_ctx.unit_contexts.num_elts; ++i)
+ {
+ dwarf2_parse_context_t* unit = vector_at(&module_ctx.unit_contexts, i);
+ if (unit->status != UNIT_ERROR)
+ pool_destroy(&unit->pool);
+ }
+
leave:
dwarf2_fini_section(§ion[section_debug]);
dwarf2_fini_section(§ion[section_abbrev]);
More information about the wine-devel
mailing list