Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2021
- 83 participants
- 2620 messages
Re: [PATCH v4 2/4] ntdll: Implement RtlWalkFrameChain() for x86 and x86_64.
by Giovanni Mascellani
Hi,
On 01/11/21 12:13, Paul Gofman wrote:
> + for (requested_count = frame_count - 1; requested_count < frame_count + 1; ++requested_count)
> + {
> + for (i = 0; i < 32; ++i)
> + {
> + winetest_push_context("requested_count %u, i %u", requested_count, i);
> + skip_count = (1 << i) >> 8;
> +
> + if (i < RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT
> + || i >= RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT + 8)
> + expected = 0;
> + else
> + expected = min(frame_count, requested_count);
Notice that requested_count is either frame_count or frame_count - 1, so
that min() always returns requested_count. Not sure if you also meant to
test requested_count == frame_count + 1 and got on off by one.
Giovanni.
Nov. 2, 2021
Re: [PATCH v4 1/4] ntdll: Factor out capture_stack_back_trace() helper.
by Giovanni Mascellani
Hi,
On 01/11/21 12:13, Paul Gofman wrote:
> +USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, ULONG *hash )
> +{
> + ULONG ret;
> +
> + ret = capture_stack_back_trace( skip, count, buffer, hash );
> + return min( ret, ~(USHORT)0 );
I don't think this does what you mean: even if you cast to USHORT, the
operand gets implicitly promoted to int when you pass it to operator ~,
so the result of that expression is 0xffffffff, not 0xffff, which I
guess is what you meant.
See for example https://godbolt.org/z/azzejdWM6.
I would suggest to just write 0xffff, or USHRT_MAX.
Thanks, Giovanni.
Nov. 2, 2021
[PATCH 9/9] include/wine/mscvpdb.h: move parsing definitions to dbghelp (where they belong)
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/dbghelp_private.h | 15 +++++++++++++++
dlls/dbghelp/msc.c | 10 +++++-----
include/wine/mscvpdb.h | 23 -----------------------
3 files changed, 20 insertions(+), 28 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 5682acadf65..61173b34b5a 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -663,6 +663,21 @@ struct cpu
extern struct cpu* dbghelp_current_cpu DECLSPEC_HIDDEN;
+/* PDB and Codeview */
+
+struct msc_debug_info
+{
+ struct module* module;
+ int nsect;
+ const IMAGE_SECTION_HEADER* sectp;
+ int nomap;
+ const OMAP* omapp;
+ const BYTE* root;
+};
+
+/* coff.c */
+extern BOOL coff_process_info(const struct msc_debug_info* msc_dbg) DECLSPEC_HIDDEN;
+
/* dbghelp.c */
extern struct process* process_find_by_handle(HANDLE hProcess) DECLSPEC_HIDDEN;
extern BOOL validate_addr64(DWORD64 addr) DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index b4487d583cb..97991be057f 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1551,15 +1551,15 @@ static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
unsigned int offset)
{
int nomap = msc_dbg->nomap;
- const OMAP_DATA* omapp = msc_dbg->omapp;
+ const OMAP* omapp = msc_dbg->omapp;
int i;
if (!nomap || !omapp) return offset;
/* FIXME: use binary search */
for (i = 0; i < nomap - 1; i++)
- if (omapp[i].from <= offset && omapp[i+1].from > offset)
- return !omapp[i].to ? 0 : omapp[i].to + (offset - omapp[i].from);
+ if (omapp[i].rva <= offset && omapp[i+1].rva > offset)
+ return !omapp[i].rvaTo ? 0 : omapp[i].rvaTo + (offset - omapp[i].rva);
return 0;
}
@@ -3414,8 +3414,8 @@ BOOL pe_load_debug_directory(const struct process* pcs, struct module* module,
{
if (dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC)
{
- msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
- msc_dbg.omapp = (const OMAP_DATA*)(mapping + dbg[i].PointerToRawData);
+ msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP);
+ msc_dbg.omapp = (const OMAP*)(mapping + dbg[i].PointerToRawData);
break;
}
}
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index dcd0e4db303..e199aff785f 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -2520,29 +2520,6 @@ typedef struct _PDB_FPO_DATA
#include "poppack.h"
-/* ----------------------------------------------
- * Information used for parsing
- * ---------------------------------------------- */
-
-typedef struct
-{
- DWORD from;
- DWORD to;
-} OMAP_DATA;
-
-struct msc_debug_info
-{
- struct module* module;
- int nsect;
- const IMAGE_SECTION_HEADER* sectp;
- int nomap;
- const OMAP_DATA* omapp;
- const BYTE* root;
-};
-
-/* coff.c */
-extern BOOL coff_process_info(const struct msc_debug_info* msc_dbg);
-
/* ===================================================
* The old CodeView stuff (for NB09 and NB11)
* =================================================== */
Nov. 2, 2021
[PATCH 8/9] include/dbghelp: added OMAP related definitions
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
include/dbghelp.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/include/dbghelp.h b/include/dbghelp.h
index 4dad9cd45e9..248b3ab418d 100644
--- a/include/dbghelp.h
+++ b/include/dbghelp.h
@@ -1128,6 +1128,14 @@ BOOL WINAPI SymAddSymbolW(HANDLE, ULONG64, PCWSTR, DWORD64, DWORD, DWORD);
BOOL WINAPI SymDeleteSymbol(HANDLE, ULONG64, PCSTR, DWORD64, DWORD);
BOOL WINAPI SymDeleteSymbolW(HANDLE, ULONG64, PCWSTR, DWORD64, DWORD);
+typedef struct _OMAP
+{
+ ULONG rva;
+ ULONG rvaTo;
+} OMAP, *POMAP;
+
+BOOL WINAPI SymGetOmaps(HANDLE, DWORD64, POMAP*, PDWORD64, POMAP*, PDWORD64);
+
/*************************
* Source Files *
*************************/
Nov. 2, 2021
[PATCH 7/9] dbghelp/pdb: convert to new debug subsection definitions (in linetab2)
by Eric Pouech
Removed obsolete linetab2 definitions from include/wine/mscvpdb.h
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
dlls/dbghelp/msc.c | 107 ++++++++++++++++++++++++++----------------------
include/wine/mscvpdb.h | 51 -----------------------
2 files changed, 59 insertions(+), 99 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 4aaee196370..b4487d583cb 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1465,70 +1465,81 @@ static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const
{
unsigned i;
DWORD_PTR addr;
- const struct codeview_linetab2* lt2;
- const struct codeview_linetab2* lt2_files = NULL;
- const struct codeview_lt2blk_lines* lines_blk;
- const struct codeview_linetab2_file*fd;
+ const struct CV_DebugSSubsectionHeader_t* hdr;
+ const struct CV_DebugSSubsectionHeader_t* hdr_next;
+ const struct CV_DebugSSubsectionHeader_t* hdr_files = NULL;
+ const struct CV_DebugSLinesHeader_t* lines_hdr;
+ const struct CV_DebugSLinesFileBlockHeader_t* files_hdr;
+ const struct CV_Line_t* lines;
+ const struct CV_Checksum_t* chksms;
unsigned source;
struct symt_function* func;
- /* locate LT2_FILES_BLOCK (if any) */
- lt2 = (const struct codeview_linetab2*)linetab;
- while ((const BYTE*)(lt2 + 1) < linetab + size)
+ /* locate DEBUG_S_FILECHKSMS (if any) */
+ hdr = (const struct CV_DebugSSubsectionHeader_t*)linetab;
+ while (CV_IS_INSIDE(hdr, linetab + size))
{
- if (lt2->header == LT2_FILES_BLOCK)
+ if (hdr->type == DEBUG_S_FILECHKSMS)
{
- lt2_files = lt2;
+ hdr_files = hdr;
break;
}
- lt2 = codeview_linetab2_next_block(lt2);
+ hdr = CV_RECORD_GAP(hdr, hdr->cbLen);
}
- if (!lt2_files)
+ if (!hdr_files)
{
- TRACE("No LT2_FILES_BLOCK found\n");
+ TRACE("No DEBUG_S_FILECHKSMS found\n");
return;
}
- lt2 = (const struct codeview_linetab2*)linetab;
- while ((const BYTE*)(lt2 + 1) < linetab + size)
- {
- /* FIXME: should also check that whole lines_blk fits in linetab + size */
- switch (lt2->header)
- {
- case LT2_LINES_BLOCK:
- /* Skip blocks that are too small - Intel C Compiler generates these. */
- if (lt2->size_of_block < sizeof (struct codeview_lt2blk_lines)) break;
- lines_blk = (const struct codeview_lt2blk_lines*)lt2;
- /* FIXME: should check that file_offset is within the LT2_FILES_BLOCK we've seen */
- addr = codeview_get_address(msc_dbg, lines_blk->seg, lines_blk->start);
- TRACE("block from %04x:%08x #%x (%x lines)\n",
- lines_blk->seg, lines_blk->start, lines_blk->size, lines_blk->nlines);
- fd = (const struct codeview_linetab2_file*)((const char*)lt2_files + 8 + lines_blk->file_offset);
- /* FIXME: should check that string is within strimage + strsize */
- source = source_new(msc_dbg->module, NULL, strimage + fd->offset);
- func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
- /* FIXME: at least labels support line numbers */
- if (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite))
+ hdr = (const struct CV_DebugSSubsectionHeader_t*)linetab;
+ while (CV_IS_INSIDE(hdr, linetab + size))
+ {
+ hdr_next = CV_RECORD_GAP(hdr, hdr->cbLen);
+ if (!(hdr->type & DEBUG_S_IGNORE))
+ {
+ /* FIXME: should also check that whole lines_blk fits in linetab + size */
+ switch (hdr->type)
{
- WARN("--not a func at %04x:%08x %lx tag=%d\n",
- lines_blk->seg, lines_blk->start, addr, func ? func->symt.tag : -1);
+ case DEBUG_S_LINES:
+ lines_hdr = CV_RECORD_AFTER(hdr);
+ files_hdr = CV_RECORD_AFTER(lines_hdr);
+ /* Skip blocks that are too small - Intel C Compiler generates these. */
+ if (!CV_IS_INSIDE(files_hdr, hdr_next)) break;
+ addr = codeview_get_address(msc_dbg, lines_hdr->segCon, lines_hdr->offCon);
+ TRACE("block from %04x:%08x #%x\n",
+ lines_hdr->segCon, lines_hdr->offCon, lines_hdr->cbCon);
+ chksms = CV_RECORD_GAP(hdr_files, files_hdr->offFile);
+ if (!CV_IS_INSIDE(chksms, CV_RECORD_GAP(hdr_files, hdr_files->cbLen)))
+ {
+ WARN("Corrupt PDB file: offset in CHKSMS subsection is invalid\n");
+ break;
+ }
+ source = source_new(msc_dbg->module, NULL,
+ (chksms->strOffset < strsize) ? strimage + chksms->strOffset : "<<stroutofbounds>>");
+ func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
+ /* FIXME: at least labels support line numbers */
+ if (!symt_check_tag(&func->symt, SymTagFunction) && !symt_check_tag(&func->symt, SymTagInlineSite))
+ {
+ WARN("--not a func at %04x:%08x %Ix tag=%d\n",
+ lines_hdr->segCon, lines_hdr->offCon, addr, func ? func->symt.tag : -1);
+ break;
+ }
+ lines = CV_RECORD_AFTER(files_hdr);
+ for (i = 0; i < files_hdr->nLines; i++)
+ {
+ symt_add_func_line(msc_dbg->module, func, source,
+ lines[i].linenumStart,
+ func->address + lines[i].offset);
+ }
+ break;
+ case DEBUG_S_FILECHKSMS: /* skip */
+ break;
+ default:
break;
}
- for (i = 0; i < lines_blk->nlines; i++)
- {
- symt_add_func_line(msc_dbg->module, func, source,
- lines_blk->l[i].lineno ^ 0x80000000,
- func->address + lines_blk->l[i].offset);
- }
- break;
- case LT2_FILES_BLOCK: /* skip */
- break;
- default:
- TRACE("Block end %x\n", lt2->header);
- lt2 = (const struct codeview_linetab2*)((const char*)linetab + size);
- continue;
}
- lt2 = codeview_linetab2_next_block(lt2);
+ hdr = hdr_next;
}
}
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index 733b4ab5336..dcd0e4db303 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -2279,57 +2279,6 @@ struct startend
unsigned int end;
};
-#define LT2_LINES_BLOCK 0x000000f2
-#define LT2_FILES_BLOCK 0x000000f4
-
-/* there's a new line tab structure from MS Studio 2005 and after
- * it's made of a list of codeview_linetab2 blocks.
- * We've only seen (so far) list with a single LT2_FILES_BLOCK and several
- * LT2_LINES_BLOCK. The LT2_FILES block has been encountered either as first
- * or last block of the list.
- * A LT2_FILES contains one or several codeview_linetab2_file:s
- */
-
-struct codeview_linetab2
-{
- DWORD header;
- DWORD size_of_block;
-};
-
-static inline const struct codeview_linetab2* codeview_linetab2_next_block(const struct codeview_linetab2* lt2)
-{
- return (const struct codeview_linetab2*)((const char*)(lt2 + 1) + lt2->size_of_block);
-}
-
-struct codeview_linetab2_file
-{
- DWORD offset; /* offset in string table for filename */
- WORD unk; /* always 0x0110... type of following information ??? */
- BYTE md5[16]; /* MD5 signature of file (signature on file's content or name ???) */
- WORD pad0; /* always 0 */
-};
-
-struct codeview_lt2blk_files
-{
- struct codeview_linetab2 lt2; /* LT2_FILES */
- struct codeview_linetab2_file file[1];
-};
-
-struct codeview_lt2blk_lines
-{
- struct codeview_linetab2 lt2; /* LT2_LINE_BLOCK */
- DWORD start; /* start address of function with line numbers */
- DWORD seg; /* segment of function with line numbers */
- DWORD size; /* size of function with line numbers */
- DWORD file_offset; /* offset for accessing corresponding codeview_linetab2_file */
- DWORD nlines; /* number of lines in this block */
- DWORD size_lines; /* number of bytes following for line number information */
- struct {
- DWORD offset; /* offset (from <seg>:<start>) for line number */
- DWORD lineno; /* the line number (OR:ed with 0x80000000 why ???) */
- } l[1]; /* actually array of <nlines> */
-};
-
/* ======================================== *
* PDB file information
* ======================================== */
Nov. 2, 2021
[PATCH 6/9] include/wine/mscvpdb.h, tools/winedump: update some line number oriented definitions
by Eric Pouech
Currently, they are described as linetab2 internally. And they miss quite
a number of elements.
>From MS' docs, they are described as debug subsection (inside PDB's SYMBOL
stream)
Update include/wine/mscvpdb.h to describe those.
Update tools/winedump to dump them properly.
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
include/wine/mscvpdb.h | 103 +++++++++++++++++++++++++++++++++
tools/winedump/msc.c | 148 +++++++++++++++++++++++++++++++++---------------
2 files changed, 206 insertions(+), 45 deletions(-)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index ca5422c3a65..733b4ab5336 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -2162,6 +2162,109 @@ enum BinaryAnnotationOpcode
* Line number information
* ======================================== */
+enum DEBUG_S_SUBSECTION_TYPE
+{
+ DEBUG_S_IGNORE = 0x80000000, /* bit flag: when set, ignore whole subsection content */
+
+ DEBUG_S_SYMBOLS = 0xf1,
+ DEBUG_S_LINES,
+ DEBUG_S_STRINGTABLE,
+ DEBUG_S_FILECHKSMS,
+ DEBUG_S_FRAMEDATA,
+ DEBUG_S_INLINEELINES,
+ DEBUG_S_CROSSSCOPEIMPORTS,
+ DEBUG_S_CROSSSCOPEEXPORTS,
+
+ DEBUG_S_IL_LINES,
+ DEBUG_S_FUNC_MDTOKEN_MAP,
+ DEBUG_S_TYPE_MDTOKEN_MAP,
+ DEBUG_S_MERGED_ASSEMBLYINPUT,
+
+ DEBUG_S_COFF_SYMBOL_RVA,
+};
+
+struct CV_DebugSSubsectionHeader_t
+{
+ enum DEBUG_S_SUBSECTION_TYPE type;
+ unsigned cbLen;
+};
+
+struct CV_DebugSLinesHeader_t
+{
+ unsigned offCon;
+ unsigned short segCon;
+ unsigned short flags;
+ unsigned cbCon;
+};
+
+struct CV_DebugSLinesFileBlockHeader_t
+{
+ unsigned offFile;
+ unsigned nLines;
+ unsigned cbBlock;
+ /* followed by two variable length arrays
+ * CV_Line_t lines[nLines];
+ * ^ columns present when CV_DebugSLinesHeader_t.flags has CV_LINES_HAVE_COLUMNS set
+ * CV_Column_t columns[nLines];
+ */
+};
+
+#define CV_LINES_HAVE_COLUMNS 0x0001
+
+struct CV_Line_t
+{
+ unsigned offset;
+ unsigned linenumStart:24;
+ unsigned deltaLineEnd:7;
+ unsigned fStatement:1;
+};
+
+struct CV_Column_t
+{
+ unsigned short offColumnStart;
+ unsigned short offColumnEnd;
+};
+
+struct CV_Checksum_t /* this one is not defined in microsoft pdb information */
+{
+ unsigned strOffset; /* offset in string table for filename */
+ unsigned char size; /* size of checksum */
+ unsigned char method; /* method used to compute check sum */
+ unsigned char checksum[0]; /* (size) bytes */
+ /* result is padded on 4-byte boundary */
+};
+
+#define CV_INLINEE_SOURCE_LINE_SIGNATURE 0x0
+#define CV_INLINEE_SOURCE_LINE_SIGNATURE_EX 0x1
+
+typedef struct CV_InlineeSourceLine_t
+{
+ cv_itemid_t inlinee; /* function id */
+ unsigned fileId; /* offset in DEBUG_S_FILECHKSMS */
+ unsigned sourceLineNum; /* first line number */
+} InlineeSourceLine;
+
+typedef struct CV_InlineeSourceLineEx_t
+{
+ cv_itemid_t inlinee; /* function id */
+ unsigned fileId; /* offset in DEBUG_S_FILECHKSMS */
+ unsigned sourceLineNum; /* first line number */
+ unsigned int countOfExtraFiles;
+ unsigned extraFileId[0];
+} InlineeSourceLineEx;
+
+#ifdef __WINESRC__
+/* those are Wine only helpers */
+/* align ptr on sz boundary; sz must be a power of 2 */
+#define CV_ALIGN(ptr, sz) ((const void*)(((DWORD_PTR)(ptr) + ((sz) - 1)) & ~((sz) - 1)))
+/* move after (ptr) record */
+#define CV_RECORD_AFTER(ptr) ((const void*)((ptr) + 1))
+/* move after (ptr) record and a gap of sz bytes */
+#define CV_RECORD_GAP(ptr, sz) ((const void*)((const char*)((ptr) + 1) + (sz)))
+/* test whether ptr record is within limit boundary */
+#define CV_IS_INSIDE(ptr, limit) (CV_RECORD_AFTER(ptr) <= (const void*)(limit))
+#endif /* __WINESRC__ */
+
struct codeview_linetab_block
{
unsigned short seg;
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index d537764b442..79dd022a088 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -1927,61 +1927,119 @@ void codeview_dump_linetab(const char* linetab, BOOL pascal_str, const char* pfx
void codeview_dump_linetab2(const char* linetab, DWORD size, const char* strimage, DWORD strsize, const char* pfx)
{
unsigned i;
- const struct codeview_linetab2* lt2;
- const struct codeview_linetab2* lt2_files = NULL;
- const struct codeview_lt2blk_lines* lines_blk;
- const struct codeview_linetab2_file*fd;
-
- /* locate LT2_FILES_BLOCK (if any) */
- lt2 = (const struct codeview_linetab2*)linetab;
- while ((const char*)(lt2 + 1) < linetab + size)
+ const struct CV_DebugSSubsectionHeader_t* hdr;
+ const struct CV_DebugSSubsectionHeader_t* next_hdr;
+ const struct CV_DebugSLinesHeader_t* lines_hdr;
+ const struct CV_DebugSLinesFileBlockHeader_t* files_hdr;
+ const struct CV_Column_t* cols;
+ const struct CV_Checksum_t* chksms;
+ const struct CV_InlineeSourceLine_t* inlsrc;
+ const struct CV_InlineeSourceLineEx_t* inlsrcex;
+
+ static const char* subsect_types[] = /* starting at 0xf1 */
{
- if (lt2->header == LT2_FILES_BLOCK)
+ "SYMBOLS", "LINES", "STRINGTABLE", "FILECHKSMS",
+ "FRAMEDATA", "INLINEELINES", "CROSSSCOPEIMPORTS", "CROSSSCOPEEXPORTS",
+ "IL_LINES", "FUNC_MDTOKEN_MAP", "TYPE_MDTOKEN_MAP", "MERGED_ASSEMBLYINPUT",
+ "COFF_SYMBOL_RVA"
+ };
+ hdr = (const struct CV_DebugSSubsectionHeader_t*)linetab;
+ while (CV_IS_INSIDE(hdr, linetab + size))
+ {
+ next_hdr = CV_RECORD_GAP(hdr, hdr->cbLen);
+ if (hdr->type & DEBUG_S_IGNORE)
{
- lt2_files = lt2;
- break;
+ printf("%s------ debug subsection <ignored>\n", pfx);
+ hdr = next_hdr;
+ continue;
}
- lt2 = codeview_linetab2_next_block(lt2);
- }
- if (!lt2_files)
- {
- printf("%sNo LT2_FILES_BLOCK found\n", pfx);
- return;
- }
- lt2 = (const struct codeview_linetab2*)linetab;
- while ((const char*)(lt2 + 1) < linetab + size)
- {
- /* FIXME: should also check that whole lbh fits in linetab + size */
- switch (lt2->header)
+ printf("%s------ debug subsection %s\n", pfx,
+ (hdr->type >= 0xf1 && hdr->type - 0xf1 < ARRAY_SIZE(subsect_types)) ?
+ subsect_types[hdr->type - 0xf1] : "<<unknown>>");
+ switch (hdr->type)
{
- case LT2_LINES_BLOCK:
- lines_blk = (const struct codeview_lt2blk_lines*)lt2;
- printf("%sblock from %04x:%08x #%x (%x lines) fo=%x\n",
- pfx, lines_blk->seg, lines_blk->start, lines_blk->size,
- lines_blk->nlines, lines_blk->file_offset);
- /* FIXME: should check that file_offset is within the LT2_FILES_BLOCK we've seen */
- fd = (const struct codeview_linetab2_file*)((const char*)lt2_files + 8 + lines_blk->file_offset);
- printf("%s md5=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
- pfx, fd->md5[ 0], fd->md5[ 1], fd->md5[ 2], fd->md5[ 3],
- fd->md5[ 4], fd->md5[ 5], fd->md5[ 6], fd->md5[ 7],
- fd->md5[ 8], fd->md5[ 9], fd->md5[10], fd->md5[11],
- fd->md5[12], fd->md5[13], fd->md5[14], fd->md5[15]);
- /* FIXME: should check that string is within strimage + strsize */
- printf("%s file=%s\n", pfx, strimage ? strimage + fd->offset : "--none--");
- for (i = 0; i < lines_blk->nlines; i++)
+ case DEBUG_S_LINES:
+ lines_hdr = CV_RECORD_AFTER(hdr);
+ printf("%s block from %04x:%08x flags:%x size=%u\n",
+ pfx, lines_hdr->segCon, lines_hdr->offCon, lines_hdr->flags, lines_hdr->cbCon);
+ files_hdr = CV_RECORD_AFTER(lines_hdr);
+ /* FIXME: as of today partial coverage:
+ * - only one files_hdr has been seen in PDB files
+ * OTOH, MS github presents two different structures
+ * llvm ? one or two
+ * - next files_hdr (depending on previous question, can be a void question)
+ * is code correct ; what do MS and llvm do?
+ */
+ while (CV_IS_INSIDE(files_hdr, next_hdr))
{
- printf("%s offset=%08x line=%d\n",
- pfx, lines_blk->l[i].offset, lines_blk->l[i].lineno ^ 0x80000000);
+ const struct CV_Line_t* lines;
+ printf("%s file=%u lines=%d size=%x\n", pfx, files_hdr->offFile,
+ files_hdr->nLines, files_hdr->cbBlock);
+ lines = CV_RECORD_AFTER(files_hdr);
+ cols = (const struct CV_Column_t*)&lines[files_hdr->nLines];
+ for (i = 0; i < files_hdr->nLines; i++)
+ {
+ printf("%s offset=%8x line=%d deltaLineEnd=%u %s",
+ pfx, lines[i].offset, lines[i].linenumStart, lines[i].deltaLineEnd,
+ lines[i].fStatement ? "statement" : "expression");
+ if (lines_hdr->flags & CV_LINES_HAVE_COLUMNS)
+ printf(" cols[start=%u end=%u]",
+ cols[i].offColumnStart, cols[i].offColumnEnd);
+ printf("\n");
+ }
+ if (lines_hdr->flags & CV_LINES_HAVE_COLUMNS)
+ files_hdr = (const struct CV_DebugSLinesFileBlockHeader_t*)&cols[files_hdr->nLines];
+ else
+ files_hdr = (const struct CV_DebugSLinesFileBlockHeader_t*)&lines[files_hdr->nLines];
}
break;
- case LT2_FILES_BLOCK: /* skip */
+ case DEBUG_S_FILECHKSMS:
+ chksms = CV_RECORD_AFTER(hdr);
+ while (CV_IS_INSIDE(chksms, next_hdr))
+ {
+ const char* meth[] = {"None", "MD5", "SHA1", "SHA256"};
+ printf("%s %d] name=%s size=%u method=%s checksum=[",
+ pfx, (unsigned)((const char*)chksms - (const char*)(hdr + 1)),
+ strimage ? strimage + chksms->strOffset : "--none--",
+ chksms->size, chksms->method < ARRAY_SIZE(meth) ? meth[chksms->method] : "<<unknown>>");
+ for (i = 0; i < chksms->size; ++i) printf("%02x", chksms->checksum[i]);
+ printf("]\n");
+ chksms = CV_ALIGN(CV_RECORD_GAP(chksms, chksms->size), 4);
+ }
+ break;
+ case DEBUG_S_INLINEELINES:
+ /* 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))
+ {
+ printf("%s inlinee=%x fileref=%d srcstart=%d\n",
+ pfx, inlsrc->inlinee, inlsrc->fileId, inlsrc->sourceLineNum);
+ ++inlsrc;
+ }
+ break;
+ case CV_INLINEE_SOURCE_LINE_SIGNATURE_EX:
+ inlsrcex = CV_RECORD_GAP(hdr, sizeof(DWORD));
+ while (CV_IS_INSIDE(inlsrcex, next_hdr))
+ {
+ printf("%s inlinee=%x fileref=%d srcstart=%d numExtraFiles=%d\n",
+ pfx, inlsrcex->inlinee, inlsrcex->fileId, inlsrcex->sourceLineNum,
+ inlsrcex->countOfExtraFiles);
+ inlsrcex = CV_RECORD_GAP(inlsrcex, inlsrcex->countOfExtraFiles * sizeof(inlsrcex->extraFileId[0]));
+ }
+ break;
+ default:
+ printf("%sUnknown signature %x in INLINEELINES subsection\n", pfx, *(DWORD*)CV_RECORD_AFTER(hdr));
+ break;
+ }
break;
default:
- printf("%sblock end %x\n", pfx, lt2->header);
- lt2 = (const struct codeview_linetab2*)(linetab + size);
- continue;
+ dump_data(CV_RECORD_AFTER(hdr), hdr->cbLen, pfx);
+ break;
}
- lt2 = codeview_linetab2_next_block(lt2);
+ hdr = next_hdr;
}
}
Nov. 2, 2021
[PATCH 5/9] tools/winedump/pdb: dump also library name for a module
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
tools/winedump/pdb.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c
index bbaf1cb94e8..ed4877cd10a 100644
--- a/tools/winedump/pdb.c
+++ b/tools/winedump/pdb.c
@@ -468,18 +468,21 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx
{
int file_nr, symbol_size, lineno_size, lineno2_size;
const char* file_name;
-
+ const char* lib_name;
+
if (symbols->version < 19970000)
{
const PDB_SYMBOL_FILE* sym_file = (const PDB_SYMBOL_FILE*) file;
file_nr = sym_file->file;
file_name = sym_file->filename;
+ lib_name = file_name + strlen(file_name) + 1;
symbol_size = sym_file->symbol_size;
lineno_size = sym_file->lineno_size;
lineno2_size = sym_file->lineno2_size;
- printf("\t--------symbol file----------- %s\n", file_name);
- printf("\tgot symbol_file\n"
- "\t\tunknown1: %08x\n"
+ printf("\t--------symbol file-----------\n");
+ printf("\tName: %s\n", file_name);
+ if (strcmp(file_name, lib_name)) printf("\tLibrary: %s\n", lib_name);
+ printf("\t\tunknown1: %08x\n"
"\t\trange\n"
"\t\t\tsegment: %04x\n"
"\t\t\tpad1: %04x\n"
@@ -514,12 +517,16 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx
else
{
const PDB_SYMBOL_FILE_EX* sym_file = (const PDB_SYMBOL_FILE_EX*) file;
+
file_nr = sym_file->file;
file_name = sym_file->filename;
+ lib_name = file_name + strlen(file_name) + 1;
symbol_size = sym_file->symbol_size;
lineno_size = sym_file->lineno_size;
lineno2_size = sym_file->lineno2_size;
- printf("\t--------symbol file----------- %s\n", file_name);
+ printf("\t--------symbol file-----------\n");
+ printf("\tName: %s\n", file_name);
+ if (strcmp(file_name, lib_name)) printf("\tLibrary: %s\n", lib_name);
printf("\t\tunknown1: %08x\n"
"\t\trange\n"
"\t\t\tsegment: %04x\n"
@@ -581,8 +588,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader, PDB_STREAM_INDEXES* sidx
free(modimage);
}
- file_name += strlen(file_name) + 1;
- file = (char*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3);
+ file = (char*)((DWORD_PTR)(lib_name + strlen(lib_name) + 1 + 3) & ~3);
}
dump_global_symbol(reader, symbols->global_file);
dump_public_symbol(reader, symbols->public_file);
Nov. 2, 2021
[PATCH 4/9] tools/winedump/pdb: dump index leaves (TPI)
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
tools/winedump/msc.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index dca8bcf9560..d537764b442 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -789,6 +789,16 @@ static void do_field(const unsigned char* start, const unsigned char* end)
ptr += 2 + 2 + 4 + 4;
break;
+ case LF_INDEX_V1:
+ printf("\t\tIndex V1: index:%x\n", fieldtype->index_v1.ref);
+ ptr += 2 + 2;
+ break;
+
+ case LF_INDEX_V2:
+ printf("\t\tIndex V2: index:%x\n", fieldtype->index_v2.ref);
+ ptr += 2 + 2 + 4;
+ break;
+
default:
printf(">>> Unsupported field-id %x\n", fieldtype->generic.id);
dump_data((const void*)fieldtype, 0x30, "\t");
Nov. 2, 2021
[PATCH 3/9] include/wine/mscvpdb.h: add definition for friend function V3
by Eric Pouech
Update tools/winedump accordingly
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
include/wine/mscvpdb.h | 9 +++++++++
tools/winedump/msc.c | 3 +--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index 53eeec96916..ca5422c3a65 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -566,6 +566,14 @@ union codeview_fieldtype
struct p_string p_name;
} friendfcn_v2;
+ struct
+ {
+ unsigned short int id;
+ short int _pad0;
+ cv_typ_t type;
+ char name[1];
+ } friendfcn_v3;
+
struct
{
unsigned short int id;
@@ -1266,6 +1274,7 @@ union codeview_fieldtype
#define LF_STRUCTURE_V3 0x1505
#define LF_UNION_V3 0x1506
#define LF_ENUM_V3 0x1507
+#define LF_FRIENDFCN_V3 0x150c
#define LF_MEMBER_V3 0x150d
#define LF_STMEMBER_V3 0x150e
#define LF_METHOD_V3 0x150f
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index 18c591f44ef..dca8bcf9560 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -685,13 +685,12 @@ static void do_field(const unsigned char* start, const unsigned char* end)
ptr += 2 + 2 + 4 + (1 + fieldtype->stmember_v2.p_name.namelen);
break;
-#if 0
case LF_FRIENDFCN_V3:
printf("\t\tFriend function V3: '%s' type:%x\n",
fieldtype->friendfcn_v3.name,
fieldtype->friendfcn_v3.type);
+ ptr += 2 + 2 + 4 + (strlen(fieldtype->stmember_v3.name) + 1);
break;
-#endif
case LF_BCLASS_V1:
leaf_len = numeric_leaf(&value, &fieldtype->bclass_v1.offset);
Nov. 2, 2021
[PATCH 2/9] tools/winedump/pdb: add some missing next record computation for type leaf
by Eric Pouech
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
---
tools/winedump/msc.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index 12d1a9e62ab..18c591f44ef 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -675,12 +675,14 @@ static void do_field(const unsigned char* start, const unsigned char* end)
printf("\t\tFriend function V1: '%s' type:%x\n",
p_string(&fieldtype->friendfcn_v1.p_name),
fieldtype->friendfcn_v1.type);
+ ptr += 2 + 2 + (1 + fieldtype->stmember_v2.p_name.namelen);
break;
case LF_FRIENDFCN_V2:
printf("\t\tFriend function V2: '%s' type:%x\n",
p_string(&fieldtype->friendfcn_v2.p_name),
fieldtype->friendfcn_v2.type);
+ ptr += 2 + 2 + 4 + (1 + fieldtype->stmember_v2.p_name.namelen);
break;
#if 0
@@ -735,10 +737,12 @@ static void do_field(const unsigned char* start, const unsigned char* end)
case LF_FRIENDCLS_V1:
printf("\t\tFriend class V1: type:%x\n", fieldtype->friendcls_v1.type);
+ ptr += 2 + 2;
break;
case LF_FRIENDCLS_V2:
printf("\t\tFriend class V2: type:%x\n", fieldtype->friendcls_v2.type);
+ ptr += 2 + 2 + 4;
break;
case LF_NESTTYPE_V1:
@@ -777,11 +781,13 @@ static void do_field(const unsigned char* start, const unsigned char* end)
case LF_VFUNCOFF_V1:
printf("\t\tVirtual function table offset V1: type:%x offset:%x\n",
fieldtype->vfuncoff_v1.type, fieldtype->vfuncoff_v1.offset);
+ ptr += 2 + 2 + 4;
break;
case LF_VFUNCOFF_V2:
printf("\t\tVirtual function table offset V2: type:%x offset:%x\n",
fieldtype->vfuncoff_v2.type, fieldtype->vfuncoff_v2.offset);
+ ptr += 2 + 2 + 4 + 4;
break;
default:
Nov. 2, 2021