The following series implements file and file number information for inline sitesi (and cleans up and fixes a couple of issue wrt source information).
A+
---
Eric Pouech (7): dbghelp: rename line_info's pc_offset field into address dbghelp: let symt_add_func_line() last parameter be an absolute address dbghelp: in SymGetLine* family, compute displacement relative to line_info's address dbghelp: implement SymGetLineFromInlineContext(W) for inlined frame dbghelp/dwarf: store line numbers and file info for inlined functions dbghelp: silence a couple of C++ oriented requests in SymGetTypeInfo() dbghelp: silence a couple more CV entries
dlls/dbghelp/coff.c | 7 +-- dlls/dbghelp/dbghelp_private.h | 2 +- dlls/dbghelp/dwarf.c | 16 ++++++- dlls/dbghelp/msc.c | 7 +-- dlls/dbghelp/stabs.c | 4 +- dlls/dbghelp/symbol.c | 78 ++++++++++++++++++++-------------- dlls/dbghelp/type.c | 22 ++++++++-- 7 files changed, 87 insertions(+), 49 deletions(-)
as it's actually an absolute address
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dbghelp_private.h | 2 +- dlls/dbghelp/symbol.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 7a0f089877e..5682acadf65 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -519,7 +519,7 @@ struct line_info line_number; union { - ULONG_PTR pc_offset; /* if is_source_file isn't set */ + ULONG_PTR address; /* absolute, if is_source_file isn't set */ unsigned source_file; /* if is_source_file is set */ } u; }; diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 503432e461f..e4208bc2418 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -435,7 +435,7 @@ void symt_add_func_line(struct module* module, struct symt_function* func, dli->is_first = 0; /* only a source file can be first */ dli->is_last = 1; dli->line_number = line_num; - dli->u.pc_offset = func->address + offset; + dli->u.address = func->address + offset; }
/****************************************************************** @@ -1870,9 +1870,9 @@ static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, dli = vector_at(&func->vlines, i); if (!dli->is_source_file) { - if (found || dli->u.pc_offset > addr) continue; + if (found || dli->u.address > addr) continue; intl->line_number = dli->line_number; - intl->address = dli->u.pc_offset; + intl->address = dli->u.address; intl->key = dli; found = TRUE; continue; @@ -2013,7 +2013,7 @@ static BOOL symt_get_func_line_prev(HANDLE hProcess, struct internal_line_t* int if (!li->is_source_file) { intl->line_number = li->line_number; - intl->address = li->u.pc_offset; + intl->address = li->u.address; intl->key = li; /* search source file */ for (srcli = li; !srcli->is_source_file; srcli--); @@ -2092,7 +2092,7 @@ static BOOL symt_get_func_line_next(HANDLE hProcess, struct internal_line_t* int if (!li->is_source_file) { intl->line_number = li->line_number; - intl->address = li->u.pc_offset; + intl->address = li->u.address; intl->key = li; return internal_line_set_nameA(pair.pcs, intl, (char*)source_get(pair.effective, srcli->u.source_file), FALSE); } @@ -2559,7 +2559,7 @@ BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, sci.Key = dli; sci.Obj[0] = '\0'; /* FIXME */ sci.LineNumber = dli->line_number; - sci.Address = dli->u.pc_offset; + sci.Address = dli->u.address; if (!cb(&sci, user)) break; } }
used to be an offset to the start of function, but it's actually stored as an absolute address afterwards
this avoids unnecessary computations
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/coff.c | 7 +------ dlls/dbghelp/dwarf.c | 2 +- dlls/dbghelp/msc.c | 5 ++--- dlls/dbghelp/stabs.c | 4 ++-- dlls/dbghelp/symbol.c | 8 ++++---- 5 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/dlls/dbghelp/coff.c b/dlls/dbghelp/coff.c index 8684a493310..cc005a3bbc5 100644 --- a/dlls/dbghelp/coff.c +++ b/dlls/dbghelp/coff.c @@ -421,16 +421,11 @@ DECLSPEC_HIDDEN BOOL coff_process_info(const struct msc_debug_info* msc_dbg) { if (coff_files.files[j].entries[l+1]->tag == SymTagFunction) { - /* - * Add the line number. This is always relative to the - * start of the function, so we need to subtract that offset - * first. - */ symt_add_func_line(msc_dbg->module, (struct symt_function*)coff_files.files[j].entries[l+1], coff_files.files[j].compiland->source, linepnt->Linenumber, - msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress - addr); + msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress); } break; } diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 1ea8d2df773..eab6609cdf4 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2526,7 +2526,7 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address, if (symt_check_tag(&symt->symt, SymTagFunction)) { func = (struct symt_function*)symt; - symt_add_func_line(module, func, *psrc, line, address - func->address); + symt_add_func_line(module, func, *psrc, line, address); } }
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index c557cb24636..191e33e781f 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -1454,8 +1454,7 @@ static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const B break; } } - symt_add_func_line(msc_dbg->module, func, source, - linenos[k], addr - func->address); + symt_add_func_line(msc_dbg->module, func, source, linenos[k], addr); } } } @@ -1519,7 +1518,7 @@ static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const { symt_add_func_line(msc_dbg->module, func, source, lines_blk->l[i].lineno ^ 0x80000000, - lines_blk->l[i].offset); + func->address + lines_blk->l[i].offset); } break; case LT2_FILES_BLOCK: /* skip */ diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c index 9d7d5131fc4..647a71ec258 100644 --- a/dlls/dbghelp/stabs.c +++ b/dlls/dbghelp/stabs.c @@ -1168,7 +1168,7 @@ static void pending_flush(struct pending_list* pending, struct module* module, if (module->type == DMT_MACHO) pending->objs[i].u.line.offset -= func->address - pending->objs[i].u.line.load_offset; symt_add_func_line(module, func, pending->objs[i].u.line.source_idx, - pending->objs[i].u.line.line_num, pending->objs[i].u.line.offset); + pending->objs[i].u.line.line_num, func->address + pending->objs[i].u.line.offset); break; default: ERR("Unknown pending object tag %u\n", (unsigned)pending->objs[i].tag); @@ -1492,7 +1492,7 @@ BOOL stabs_parse(struct module* module, ULONG_PTR load_offset, if (module->type == DMT_MACHO) offset -= curr_func->address - load_offset; symt_add_func_line(module, curr_func, source_idx, - stab_ptr->n_desc, offset); + stab_ptr->n_desc, curr_func->address + offset); } else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc, n_value, load_offset); diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index e4208bc2418..43f7b3fdec2 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -391,7 +391,7 @@ struct symt_inlinesite* symt_new_inlinesite(struct module* module, }
void symt_add_func_line(struct module* module, struct symt_function* func, - unsigned source_idx, int line_num, ULONG_PTR offset) + unsigned source_idx, int line_num, ULONG_PTR addr) { struct line_info* dli; unsigned vlen; @@ -401,8 +401,8 @@ void symt_add_func_line(struct module* module, struct symt_function* func,
if (func == NULL || !(dbghelp_options & SYMOPT_LOAD_LINES)) return;
- TRACE_(dbghelp_symt)("(%p)%s:%lx %s:%u\n", - func, func->hash_elt.name, offset, + TRACE_(dbghelp_symt)("(%p)%s:%Ix %s:%u\n", + func, func->hash_elt.name, addr, source_get(module, source_idx), line_num);
assert(func->symt.tag == SymTagFunction || func->symt.tag == SymTagInlineSite); @@ -435,7 +435,7 @@ void symt_add_func_line(struct module* module, struct symt_function* func, dli->is_first = 0; /* only a source file can be first */ dli->is_last = 1; dli->line_number = line_num; - dli->u.address = func->address + offset; + dli->u.address = addr; }
/******************************************************************
(was incorrectly computed relatively to the start of function)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/symbol.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 43f7b3fdec2..30e1c0d2bf7 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -1853,7 +1853,7 @@ static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, PDWORD pdwDisplacement, struct internal_line_t* intl) { struct line_info* dli = NULL; - BOOL found = FALSE; + struct line_info* found_dli = NULL; int i; struct module_pair pair; struct symt_ht* symt; @@ -1870,14 +1870,14 @@ static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, dli = vector_at(&func->vlines, i); if (!dli->is_source_file) { - if (found || dli->u.address > addr) continue; + if (found_dli || dli->u.address > addr) continue; intl->line_number = dli->line_number; intl->address = dli->u.address; intl->key = dli; - found = TRUE; + found_dli = dli; continue; } - if (found) + if (found_dli) { BOOL ret; if (dbghelp_opt_native) @@ -1891,7 +1891,7 @@ static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, ret = internal_line_set_nameW(pair.pcs, intl, dospath, TRUE); HeapFree( GetProcessHeap(), 0, dospath ); } - if (ret) *pdwDisplacement = intl->address - func->address; + if (ret) *pdwDisplacement = addr - found_dli->u.address; return ret; } }
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/symbol.c | 52 ++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 30e1c0d2bf7..7747aaae2ae 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -1844,28 +1844,14 @@ static BOOL internal_line_set_nameW(struct process* pcs, struct internal_line_t* return TRUE; }
-/****************************************************************** - * get_line_from_addr - * - * fills source file information from an address - */ -static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, - PDWORD pdwDisplacement, struct internal_line_t* intl) +static BOOL get_line_from_function(struct module_pair* pair, struct symt_function* func, DWORD64 addr, + PDWORD pdwDisplacement, struct internal_line_t* intl) { struct line_info* dli = NULL; struct line_info* found_dli = NULL; int i; - struct module_pair pair; - struct symt_ht* symt; - struct symt_function* func;
- if (!module_init_pair(&pair, hProcess, addr)) return FALSE; - if ((symt = symt_find_nearest(pair.effective, addr)) == NULL) return FALSE; - - if (symt->symt.tag != SymTagFunction) return FALSE; - func = (struct symt_function*)symt; - - for (i=vector_length(&func->vlines)-1; i>=0; i--) + for (i = vector_length(&func->vlines) - 1; i >= 0; i--) { dli = vector_at(&func->vlines, i); if (!dli->is_source_file) @@ -1883,12 +1869,12 @@ static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, if (dbghelp_opt_native) { /* Return native file paths when using winedbg */ - ret = internal_line_set_nameA(pair.pcs, intl, (char*)source_get(pair.effective, dli->u.source_file), FALSE); + ret = internal_line_set_nameA(pair->pcs, intl, (char*)source_get(pair->effective, dli->u.source_file), FALSE); } else { - WCHAR *dospath = wine_get_dos_file_name(source_get(pair.effective, dli->u.source_file)); - ret = internal_line_set_nameW(pair.pcs, intl, dospath, TRUE); + WCHAR *dospath = wine_get_dos_file_name(source_get(pair->effective, dli->u.source_file)); + ret = internal_line_set_nameW(pair->pcs, intl, dospath, TRUE); HeapFree( GetProcessHeap(), 0, dospath ); } if (ret) *pdwDisplacement = addr - found_dli->u.address; @@ -1898,6 +1884,24 @@ static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, return FALSE; }
+/****************************************************************** + * get_line_from_addr + * + * fills source file information from an address + */ +static BOOL get_line_from_addr(HANDLE hProcess, DWORD64 addr, + PDWORD pdwDisplacement, struct internal_line_t* intl) +{ + struct module_pair pair; + struct symt_ht* symt; + + if (!module_init_pair(&pair, hProcess, addr)) return FALSE; + if ((symt = symt_find_nearest(pair.effective, addr)) == NULL) return FALSE; + + if (symt->symt.tag != SymTagFunction && symt->symt.tag != SymTagInlineSite) return FALSE; + return get_line_from_function(&pair, (struct symt_function*)symt, addr, pdwDisplacement, intl); +} + /*********************************************************************** * SymGetSymNext64 (DBGHELP.@) */ @@ -2699,9 +2703,17 @@ BOOL WINAPI SymFromInlineContextW(HANDLE hProcess, DWORD64 addr, ULONG inline_ct static BOOL get_line_from_inline_context(HANDLE hProcess, DWORD64 addr, ULONG inline_ctx, DWORD64 mod_addr, PDWORD disp, struct internal_line_t* intl) { + struct module_pair pair; + struct symt_inlinesite* inlined; + + if (!module_init_pair(&pair, hProcess, mod_addr ? mod_addr : addr)) return FALSE; switch (IFC_MODE(inline_ctx)) { case IFC_MODE_INLINE: + inlined = symt_find_inlined_site(pair.effective, addr, inline_ctx); + if (inlined && get_line_from_function(&pair, &inlined->func, addr, disp, intl)) + return TRUE; + /* fall through: check if we can find line info at top function level */ case IFC_MODE_IGNORE: case IFC_MODE_REGULAR: return get_line_from_addr(hProcess, addr, disp, intl);
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index eab6609cdf4..269cfadd56c 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2515,6 +2515,7 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address, const struct vector* v, unsigned file, unsigned line) { struct symt_function* func; + struct symt_inlinesite* inlined; struct symt_ht* symt; unsigned* psrc;
@@ -2526,6 +2527,19 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address, if (symt_check_tag(&symt->symt, SymTagFunction)) { func = (struct symt_function*)symt; + for (inlined = func->next_inlinesite; inlined; inlined = inlined->func.next_inlinesite) + { + int i; + for (i = 0; i < inlined->vranges.num_elts; ++i) + { + struct addr_range* ar = (struct addr_range*)vector_at(&inlined->vranges, i); + if (ar->low <= address && address < ar->high) + { + symt_add_func_line(module, &inlined->func, *psrc, line, address); + return; /* only add to lowest matching inline site */ + } + } + } symt_add_func_line(module, func, *psrc, line, address); } }
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/type.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index 3a7ebfb6a0a..b7eb49116e2 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -991,10 +991,26 @@ BOOL symt_get_info(struct module* module, const struct symt* type, X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->index_type); break;
- case TI_GET_CLASSPARENTID: - /* FIXME: we don't support properly C++ for now, pretend this symbol doesn't - * belong to a parent class + case TI_GET_SYMINDEX: + /* not very useful as it is... + * native sometimes (eg for UDT) return id of another instance + * of the same UDT definition... maybe forward declaration? */ + X(DWORD) = symt_ptr2index(module, type); + break; + + /* FIXME: we don't support properly C++ for now */ + case TI_GET_VIRTUALBASECLASS: + case TI_GET_VIRTUALTABLESHAPEID: + case TI_GET_VIRTUALBASEPOINTEROFFSET: + case TI_GET_CLASSPARENTID: + case TI_GET_THISADJUST: + case TI_GET_VIRTUALBASEOFFSET: + case TI_GET_VIRTUALBASEDISPINDEX: + case TI_GET_IS_REFERENCE: + case TI_GET_INDIRECTVIRTUALBASECLASS: + case TI_GET_VIRTUALBASETABLETYPE: + case TI_GET_OBJECTPOINTERTYPE: return FALSE;
#undef X
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/msc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 191e33e781f..a1f009cf678 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2022,6 +2022,8 @@ static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* roo case S_INLINESITE_END: case S_FILESTATIC: case S_CALLEES: + case S_UNAMESPACE: + case S_INLINEES: TRACE("Unsupported symbol id %x\n", sym->generic.id); break;