Eric Pouech : dbghelp/pdb: Add line number to inline sites.
Alexandre Julliard
julliard at winehq.org
Mon Nov 8 15:45:08 CST 2021
Module: wine
Branch: master
Commit: d8f26a4233be4afe21dc9a165e920e88823f3c28
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d8f26a4233be4afe21dc9a165e920e88823f3c28
Author: Eric Pouech <eric.pouech at gmail.com>
Date: Mon Nov 8 15:00:01 2021 +0100
dbghelp/pdb: Add line number to inline sites.
Requires to join DEBUG_S_INLINEES subsection with symbol annotations.
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dbghelp/msc.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 84 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 1be73b723f0..c0d09b75c56 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1814,6 +1814,70 @@ static BOOL codeview_advance_binannot(struct cv_binannot* cvba)
return TRUE;
}
+static inline int binannot_getsigned(unsigned i)
+{
+ return (i & 1) ? -(int)(i >> 1) : (int)(i >> 1);
+}
+
+static BOOL cv_dbgsubsect_find_inlinee(const struct msc_debug_info* msc_dbg,
+ unsigned inlineeid,
+ const struct cv_module_snarf* cvmod,
+ const struct CV_DebugSSubsectionHeader_t* hdr_files,
+ unsigned* srcfile, unsigned* srcline)
+{
+ const struct CV_DebugSSubsectionHeader_t* hdr;
+ const struct CV_DebugSSubsectionHeader_t* next_hdr;
+ const struct CV_InlineeSourceLine_t* inlsrc;
+ const struct CV_InlineeSourceLineEx_t* inlsrcex;
+ const struct CV_Checksum_t* chksms;
+
+ for (hdr = cvmod->dbgsubsect; CV_IS_INSIDE(hdr, cvmod->dbgsubsect + cvmod->dbgsubsect_size); hdr = next_hdr)
+ {
+ next_hdr = CV_RECORD_GAP(hdr, hdr->cbLen);
+ if (hdr->type != DEBUG_S_INLINEELINES) continue;
+ /* subsection starts with a DWORD signature */
+ switch (*(DWORD*)CV_RECORD_AFTER(hdr))
+ {
+ case CV_INLINEE_SOURCE_LINE_SIGNATURE:
+ inlsrc = CV_RECORD_GAP(hdr, sizeof(DWORD));
+ while (CV_IS_INSIDE(inlsrc, next_hdr))
+ {
+ if (inlsrc->inlinee == inlineeid)
+ {
+ chksms = CV_RECORD_GAP(hdr_files, inlsrc->fileId);
+ if (!CV_IS_INSIDE(chksms, CV_RECORD_GAP(hdr_files, hdr_files->cbLen))) return FALSE;
+ *srcfile = source_new(msc_dbg->module, NULL,
+ (chksms->strOffset < cvmod->strsize) ? cvmod->strimage + chksms->strOffset : "<<str-out-of-bounds>>");
+ *srcline = inlsrc->sourceLineNum;
+ return TRUE;
+ }
+ ++inlsrc;
+ }
+ break;
+ case CV_INLINEE_SOURCE_LINE_SIGNATURE_EX:
+ inlsrcex = CV_RECORD_GAP(hdr, sizeof(DWORD));
+ while (CV_IS_INSIDE(inlsrcex, next_hdr))
+ {
+ if (inlsrcex->inlinee == inlineeid)
+ {
+ chksms = CV_RECORD_GAP(hdr_files, inlsrcex->fileId);
+ if (!CV_IS_INSIDE(chksms, CV_RECORD_GAP(hdr_files, hdr_files->cbLen))) return FALSE;
+ *srcfile = source_new(msc_dbg->module, NULL,
+ (chksms->strOffset < cvmod->strsize) ? cvmod->strimage + chksms->strOffset : "<<str-out-of-bounds>>");
+ *srcline = inlsrcex->sourceLineNum;
+ return TRUE;
+ }
+ inlsrcex = CV_RECORD_GAP(inlsrcex, inlsrcex->countOfExtraFiles * sizeof(inlsrcex->extraFileId[0]));
+ }
+ break;
+ default:
+ FIXME("Unknown signature %x in INLINEELINES subsection\n", *(DWORD*)CV_RECORD_AFTER(hdr));
+ break;
+ }
+ }
+ return FALSE;
+}
+
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,
@@ -1827,8 +1891,9 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
DWORD64 addr;
struct symt_inlinesite* inlined;
struct cv_binannot cvba;
- BOOL found = FALSE;
- unsigned first, offset, length;
+ BOOL srcok, found = FALSE;
+ unsigned first, offset, length, line, srcfile;
+ const struct CV_Checksum_t* chksms;
if (!cvmod->ipi_ctp || !(cvt = codeview_jump_to_type(cvmod->ipi_ctp, inlinee)))
{
@@ -1891,7 +1956,12 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
break;
}
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
+ srcfile = line = 0;
for (;;)
{
if (!codeview_advance_binannot(&cvba)) break;
@@ -1904,21 +1974,33 @@ static struct symt_inlinesite* codeview_create_inline_site(const struct msc_debu
case BA_OP_ChangeCodeOffset:
offset += cvba.arg1;
length = 1;
+ if (srcok)
+ symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset);
break;
case BA_OP_ChangeCodeLength:
length = cvba.arg1;
break;
case BA_OP_ChangeFile:
+ chksms = CV_RECORD_GAP(hdr_files, cvba.arg1);
+ if (CV_IS_INSIDE(chksms, CV_RECORD_GAP(hdr_files, hdr_files->cbLen)))
+ srcfile = source_new(msc_dbg->module, NULL,
+ (chksms->strOffset < cvmod->strsize) ? cvmod->strimage + chksms->strOffset : "<<str-out-of-bounds>>");
break;
case BA_OP_ChangeLineOffset:
+ 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;
break;
case BA_OP_ChangeCodeLengthAndCodeOffset:
offset += cvba.arg2;
length = cvba.arg1;
+ if (srcok)
+ symt_add_func_line(msc_dbg->module, &inlined->func, srcfile, line, top_func->address + offset);
break;
default:
WARN("Unsupported op %d\n", cvba.opcode);
More information about the wine-cvs
mailing list