From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- tools/winedump/msc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c index b5708017651..561d3ca98ca 100644 --- a/tools/winedump/msc.c +++ b/tools/winedump/msc.c @@ -1284,7 +1284,7 @@ static void dump_binannot(const unsigned char* ba, const char* last, unsigned in case BA_OP_ChangeCodeOffsetAndLineOffset: { unsigned p1 = binannot_uncompress(&ba); - printf("%*s | ChangeCodeOffsetAndLineOffset %u %u (0x%x)\n", indent, "", p1 & 0xf, binannot_getsigned(p1 >> 4), p1); + printf("%*s | ChangeCodeOffsetAndLineOffset %u %d (0x%x)\n", indent, "", p1 & 0xf, binannot_getsigned(p1 >> 4), p1); } break; case BA_OP_ChangeCodeLengthAndCodeOffset:
From: Eric Pouech eric.pouech@gmail.com
When using an inline context which depth points towards the top level function (so when it's not strictly speaking an inline context), native falls back to picking information in the top level function.
So we do now in SymSetScopeFromInlineContext() and SymFromInlineContext() (instead of returning an error).
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/dbghelp.c | 6 +++--- dlls/dbghelp/symbol.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c index c154d8d9713..df257bb4639 100644 --- a/dlls/dbghelp/dbghelp.c +++ b/dlls/dbghelp/dbghelp.c @@ -712,8 +712,6 @@ BOOL WINAPI SymSetScopeFromInlineContext(HANDLE hProcess, ULONG64 addr, DWORD in
switch (IFC_MODE(inlinectx)) { - case IFC_MODE_IGNORE: - case IFC_MODE_REGULAR: return SymSetScopeFromAddr(hProcess, addr); case IFC_MODE_INLINE: if (!module_init_pair(&pair, hProcess, addr)) return FALSE; inlined = symt_find_inlined_site(pair.effective, addr, inlinectx); @@ -723,7 +721,9 @@ BOOL WINAPI SymSetScopeFromInlineContext(HANDLE hProcess, ULONG64 addr, DWORD in pair.pcs->localscope_symt = &inlined->func.symt; return TRUE; } - return FALSE; + /* fall through */ + case IFC_MODE_IGNORE: + case IFC_MODE_REGULAR: return SymSetScopeFromAddr(hProcess, addr); default: SetLastError(ERROR_INVALID_PARAMETER); return FALSE; diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 8e432e4be08..7b0324f5013 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -2675,9 +2675,6 @@ BOOL WINAPI SymFromInlineContext(HANDLE hProcess, DWORD64 addr, ULONG inline_ctx
switch (IFC_MODE(inline_ctx)) { - case IFC_MODE_IGNORE: - case IFC_MODE_REGULAR: - return SymFromAddr(hProcess, addr, disp, si); case IFC_MODE_INLINE: if (!module_init_pair(&pair, hProcess, addr)) return FALSE; inlined = symt_find_inlined_site(pair.effective, addr, inline_ctx); @@ -2688,6 +2685,9 @@ BOOL WINAPI SymFromInlineContext(HANDLE hProcess, DWORD64 addr, ULONG inline_ctx return TRUE; } /* fall through */ + case IFC_MODE_IGNORE: + case IFC_MODE_REGULAR: + return SymFromAddr(hProcess, addr, disp, si); default: SetLastError(ERROR_INVALID_PARAMETER); return FALSE;
From: Eric Pouech eric.pouech@gmail.com
Store all the internal address ranges for an inline site (as we already do in dwarf debug info).
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/msc.c | 71 ++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 24 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 811c8ffa165..ca2fe1c9302 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2043,6 +2043,18 @@ static BOOL cv_dbgsubsect_find_inlinee(const struct msc_debug_info* msc_dbg, return FALSE; }
+static inline void inline_site_update_last_range(struct symt_inlinesite* inlined, ULONG_PTR hi) +{ + unsigned num = inlined->vranges.num_elts; + if (num) + { + struct addr_range* range = vector_at(&inlined->vranges, num - 1); + /* only change range if it has no span (code start without code end) */ + if (range->low == range->high) + range->high = hi; + } +} + static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debug_info* msc_dbg, const struct cv_module_snarf* cvmod, struct symt_function* top_func, @@ -2053,11 +2065,10 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu { const struct CV_DebugSSubsectionHeader_t* hdr_files = NULL; const union codeview_type* cvt; - DWORD64 addr; struct symt_inlinesite* inlined; struct cv_binannot cvba; BOOL srcok, found = FALSE; - unsigned first, offset, length, line, srcfile; + unsigned offset, line, srcfile; const struct CV_Checksum_t* chksms;
if (!cvmod->ipi_ctp || !(cvt = codeview_jump_to_type(cvmod->ipi_ctp, inlinee))) @@ -2066,7 +2077,6 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu return NULL; }
- addr = top_func->address; /* grasp first code offset in binary annotation to compute inline site start address */ cvba.annot = annot; cvba.last_annot = last_annot; @@ -2075,19 +2085,16 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu cvba.opcode == BA_OP_ChangeCodeOffset || cvba.opcode == BA_OP_ChangeCodeOffsetAndLineOffset) { - addr += first = cvba.arg1; - length = 0; + offset = cvba.arg1; found = TRUE; break; } else if (cvba.opcode == BA_OP_ChangeCodeLengthAndCodeOffset) { - addr += first = cvba.arg2; - length = cvba.arg1; + offset = cvba.arg2; found = TRUE; break; } - offset = first;
if (!found) { @@ -2099,13 +2106,13 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu { case LF_FUNC_ID: inlined = symt_new_inlinesite(msc_dbg->module, top_func, container, - cvt->func_id_v3.name, addr, + cvt->func_id_v3.name, top_func->address + offset, codeview_get_type(cvt->func_id_v3.type, FALSE)); break; case LF_MFUNC_ID: /* FIXME we just declare a function, not a method */ inlined = symt_new_inlinesite(msc_dbg->module, top_func, container, - cvt->mfunc_id_v3.name, addr, + cvt->mfunc_id_v3.name, top_func->address + offset, codeview_get_type(cvt->mfunc_id_v3.type, FALSE)); break; default: @@ -2123,27 +2130,35 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu if (!hdr_files) return FALSE; srcok = cv_dbgsubsect_find_inlinee(msc_dbg, inlinee, cvmod, hdr_files, &srcfile, &line);
- if (srcok) - symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset); - else + if (!srcok) srcfile = line = 0; - for (;;) + + /* rescan all annotations and store ranges & line information */ + offset = 0; + cvba.annot = annot; + cvba.last_annot = last_annot; + + while (codeview_advance_binannot(&cvba)) { - if (!codeview_advance_binannot(&cvba)) break; switch (cvba.opcode) { case BA_OP_CodeOffset: - first = offset = cvba.arg1; - length = 1; + offset = cvba.arg1; break; case BA_OP_ChangeCodeOffset: offset += cvba.arg1; - length = 1; + inline_site_update_last_range(inlined, top_func->address + offset); if (srcok) symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset); + symt_add_inlinesite_range(msc_dbg->module, inlined, top_func->address + offset, top_func->address + offset); break; case BA_OP_ChangeCodeLength: - length = cvba.arg1; + /* this op doesn't seem widely used... */ + if (inlined->vranges.num_elts) + { + struct addr_range* range = vector_at(&inlined->vranges, inlined->vranges.num_elts - 1); + inline_site_update_last_range(inlined, range->low + cvba.arg1); + } break; case BA_OP_ChangeFile: chksms = CV_RECORD_GAP(hdr_files, cvba.arg1); @@ -2154,24 +2169,32 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu line += binannot_getsigned(cvba.arg1); break; case BA_OP_ChangeCodeOffsetAndLineOffset: - if (srcok) - symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset); line += binannot_getsigned(cvba.arg2); offset += cvba.arg1; - length = 1; + inline_site_update_last_range(inlined, top_func->address + offset); + if (srcok) + symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset); + symt_add_inlinesite_range(msc_dbg->module, inlined, top_func->address + offset, top_func->address + offset); break; case BA_OP_ChangeCodeLengthAndCodeOffset: offset += cvba.arg2; - length = cvba.arg1; + inline_site_update_last_range(inlined, top_func->address + offset); if (srcok) symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset); + symt_add_inlinesite_range(msc_dbg->module, inlined, top_func->address + offset, top_func->address + offset + cvba.arg1); break; default: WARN("Unsupported op %d\n", cvba.opcode); break; } } - symt_add_inlinesite_range(msc_dbg->module, inlined, top_func->address + first, top_func->address + offset + length); + if (inlined->vranges.num_elts) + { + struct addr_range* range = vector_at(&inlined->vranges, inlined->vranges.num_elts - 1); + if (range->low == range->high) WARN("pending empty range at end of %s inside %s\n", + inlined->func.hash_elt.name, + top_func->hash_elt.name); + } return inlined; }