[PATCH] - added -G option to winedump's dump mode (same option as
Eric Pouech
eric.pouech at wanadoo.fr
Sun Aug 27 01:50:46 CDT 2006
objdump) in order to dump raw stabs information from PE files
- removed stabs' dump facility from dbghelp/stabs.c now
that we have it (for PE files) in winedump. Note that
objdump would do the job for ELF files.
A+
---
dlls/dbghelp/stabs.c | 36 -------------
tools/winedump/debug.c | 113 ++++++++++++++++++++++++++++++++++++++++
tools/winedump/main.c | 6 ++
tools/winedump/pe.c | 32 +++++++++++
tools/winedump/winedump.h | 1
tools/winedump/winedump.man.in | 3 +
6 files changed, 155 insertions(+), 36 deletions(-)
diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c
index e94bd71..534e1b0 100644
--- a/dlls/dbghelp/stabs.c
+++ b/dlls/dbghelp/stabs.c
@@ -1266,42 +1266,6 @@ BOOL stabs_parse(struct module* module,
}
}
-#if 0
- const char* defs[] = {"","","","", /* 00 */
- "","","","", /* 08 */
- "","","","", /* 10 */
- "","","","", /* 18 */
- "gsym","","fun","stsym", /* 20 */
- "lcsym","main","rosym","", /* 28 */
- "","","","", /* 30 */
- "","","opt","", /* 38 */
- "rsym","","sline","", /* 40 */
- "","","","", /* 48 */
- "","","","", /* 50 */
- "","","","", /* 58 */
- "","","so","", /* 60 */
- "","","","", /* 68 */
- "","","","", /* 70 */
- "","","","", /* 78 */
- "lsym","bincl","sol","", /* 80 */
- "","","","", /* 88 */
- "","","","", /* 90 */
- "","","","", /* 98 */
- "psym","eincl","","", /* a0 */
- "","","","", /* a8 */
- "","","","", /* b0 */
- "","","","", /* b8 */
- "lbrac","excl","","", /* c0 */
- "","","","", /* c8 */
- "","","","", /* d0 */
- "","","","", /* d8 */
- "rbrac","","","", /* e0 */
- };
-
- FIXME("Got %s<%u> %u/%ld (%s)\n",
- defs[stab_ptr->n_type / 2], stab_ptr->n_type, stab_ptr->n_desc, stab_ptr->n_value, debugstr_a(ptr));
-#endif
-
switch (stab_ptr->n_type)
{
case N_GSYM:
diff --git a/tools/winedump/debug.c b/tools/winedump/debug.c
index 07ae75c..8d24a17 100644
--- a/tools/winedump/debug.c
+++ b/tools/winedump/debug.c
@@ -582,3 +582,116 @@ void dump_frame_pointer_omission(unsigne
/* FPO is used to describe nonstandard stack frames */
printf("FIXME: FPO (frame pointer omission) debug symbol dumping not implemented yet.\n");
}
+
+struct stab_nlist
+{
+ union
+ {
+ char* n_name;
+ struct stab_nlist* n_next;
+ long n_strx;
+ } n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+};
+
+static const char* stabs_defs[] = {
+ NULL,NULL,NULL,NULL, /* 00 */
+ NULL,NULL,NULL,NULL, /* 08 */
+ NULL,NULL,NULL,NULL, /* 10 */
+ NULL,NULL,NULL,NULL, /* 18 */
+ "GSYM","FNAME","FUN","STSYM", /* 20 */
+ "LCSYM","MAIN","ROSYM","PC", /* 28 */
+ NULL,"NSYMS","NOMAP",NULL, /* 30 */
+ "OBJ",NULL,"OPT",NULL, /* 38 */
+ "RSYM","M2C","SLINE","DSLINE", /* 40 */
+ "BSLINE","DEFD","FLINE",NULL, /* 48 */
+ "EHDECL",NULL,"CATCH",NULL, /* 50 */
+ NULL,NULL,NULL,NULL, /* 58 */
+ "SSYM","ENDM","SO",NULL, /* 60 */
+ NULL,NULL,NULL,NULL, /* 68 */
+ NULL,NULL,NULL,NULL, /* 70 */
+ NULL,NULL,NULL,NULL, /* 78 */
+ "LSYM","BINCL","SOL",NULL, /* 80 */
+ NULL,NULL,NULL,NULL, /* 88 */
+ NULL,NULL,NULL,NULL, /* 90 */
+ NULL,NULL,NULL,NULL, /* 98 */
+ "PSYM","EINCL","ENTRY",NULL, /* a0 */
+ NULL,NULL,NULL,NULL, /* a8 */
+ NULL,NULL,NULL,NULL, /* b0 */
+ NULL,NULL,NULL,NULL, /* b8 */
+ "LBRAC","EXCL","SCOPE",NULL, /* c0 */
+ NULL,NULL,NULL,NULL, /* c8 */
+ NULL,NULL,NULL,NULL, /* d0 */
+ NULL,NULL,NULL,NULL, /* d8 */
+ "RBRAC","BCOMM","ECOMM",NULL, /* e0 */
+ "ECOML","WITH",NULL,NULL, /* e8 */
+ "NBTEXT","NBDATA","NBBSS","NBSTS", /* f0 */
+ "NBLCS",NULL,NULL,NULL /* f8 */
+};
+
+void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr)
+{
+ int i;
+ int nstab;
+ const char* ptr;
+ char* stabbuff;
+ unsigned int stabbufflen;
+ const struct stab_nlist* stab_ptr = pv_stabs;
+ const char* strs_end;
+ char n_buffer[16];
+
+ nstab = szstabs / sizeof(struct stab_nlist);
+ strs_end = stabstr + szstr;
+
+ /*
+ * Allocate a buffer into which we can build stab strings for cases
+ * where the stab is continued over multiple lines.
+ */
+ stabbufflen = 65536;
+ stabbuff = malloc(stabbufflen);
+
+ stabbuff[0] = '\0';
+
+ printf("#Sym n_type n_othr n_desc n_value n_strx String\n");
+
+ for (i = 0; i < nstab; i++, stab_ptr++)
+ {
+ ptr = stabstr + stab_ptr->n_un.n_strx;
+ if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end))
+ {
+ ptr = "[[*** bad string ***]]";
+ }
+ else if (ptr[strlen(ptr) - 1] == '\\')
+ {
+ /*
+ * Indicates continuation. Append this to the buffer, and go onto the
+ * next record. Repeat the process until we find a stab without the
+ * '/' character, as this indicates we have the whole thing.
+ */
+ unsigned len = strlen(ptr);
+ if (strlen(stabbuff) + len > stabbufflen)
+ {
+ stabbufflen += 65536;
+ stabbuff = realloc(stabbuff, stabbufflen);
+ }
+ strncat(stabbuff, ptr, len - 1);
+ continue;
+ }
+ else if (stabbuff[0] != '\0')
+ {
+ strcat(stabbuff, ptr);
+ ptr = stabbuff;
+ }
+ if ((stab_ptr->n_type & 1) || !stabs_defs[stab_ptr->n_type / 2])
+ sprintf(n_buffer, "<0x%02x>", stab_ptr->n_type);
+ else
+ sprintf(n_buffer, "%-6s", stabs_defs[stab_ptr->n_type / 2]);
+ printf("%4d %s %-8x % 6d %-8lx %-6lx %s\n",
+ i, n_buffer, stab_ptr->n_other, stab_ptr->n_desc, stab_ptr->n_value,
+ stab_ptr->n_un.n_strx, ptr);
+ }
+ free(stabbuff);
+}
diff --git a/tools/winedump/main.c b/tools/winedump/main.c
index 8d90187..36a105b 100644
--- a/tools/winedump/main.c
+++ b/tools/winedump/main.c
@@ -192,6 +192,11 @@ static void do_dumpsect (const char* arg
globals.dumpsect = arg;
}
+static void do_rawdebug (void)
+{
+ globals.do_debug = 1;
+}
+
static void do_dumpall(void)
{
globals.do_dumpheader = 1;
@@ -228,6 +233,7 @@ static const struct my_option option_tab
{"dump", DUMP, 0, do_dump, "dump <mod> Dumps the content of the module (dll, exe...) named <mod>"},
{"-C", DUMP, 0, do_symdmngl, "-C Turns on symbol demangling"},
{"-f", DUMP, 0, do_dumphead, "-f Dumps file header information"},
+ {"-G", DUMP, 0, do_rawdebug, "-G Dumps raw debug information"},
{"-j", DUMP, 1, do_dumpsect, "-j sect_name Dumps only the content of section sect_name (import, export, debug, resource, tls)"},
{"-x", DUMP, 0, do_dumpall, "-x Dumps everything"},
{"emf", EMF, 0, do_dumpemf, "emf Dumps an Enhanced Meta File"},
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c
index da55f63..8951642 100644
--- a/tools/winedump/pe.c
+++ b/tools/winedump/pe.c
@@ -1076,6 +1076,36 @@ static void dump_dir_resource(void)
printf( "\n\n" );
}
+static void dump_debug(void)
+{
+ const char* stabs = NULL;
+ unsigned szstabs = 0;
+ const char* stabstr = NULL;
+ unsigned szstr = 0;
+ unsigned i;
+ const IMAGE_SECTION_HEADER* sectHead;
+
+ sectHead = (const IMAGE_SECTION_HEADER*)
+ ((const char*)PE_nt_headers + sizeof(DWORD) +
+ sizeof(IMAGE_FILE_HEADER) + PE_nt_headers->FileHeader.SizeOfOptionalHeader);
+
+ for (i = 0; i < PE_nt_headers->FileHeader.NumberOfSections; i++, sectHead++)
+ {
+ if (!strcmp(sectHead->Name, ".stab"))
+ {
+ stabs = RVA(sectHead->VirtualAddress, sectHead->Misc.VirtualSize);
+ szstabs = sectHead->Misc.VirtualSize;
+ }
+ if (!strncmp(sectHead->Name, ".stabstr", 8))
+ {
+ stabstr = RVA(sectHead->VirtualAddress, sectHead->Misc.VirtualSize);
+ szstr = sectHead->Misc.VirtualSize;
+ }
+ }
+ if (stabs && stabstr)
+ dump_stabs(stabs, szstabs, stabstr, szstr);
+}
+
void pe_dump(const void* pmt)
{
int all = (globals.dumpsect != NULL) && strcmp(globals.dumpsect, "ALL") == 0;
@@ -1118,6 +1148,8 @@ #if 0
dump_dir_reloc();
#endif
}
+ if (globals.do_debug)
+ dump_debug();
}
typedef struct _dll_symbol {
diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h
index 93de9a8..a677471 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -123,6 +123,7 @@ typedef struct __globals
/* Options: dump mode */
int do_demangle; /* -d */
int do_dumpheader; /* -f */
+ int do_debug; /* -G == 1, -g == 2 */
/* Option arguments: spec mode */
int start_ordinal; /* -s */
diff --git a/tools/winedump/winedump.man.in b/tools/winedump/winedump.man.in
index 19fd8de..f1b2e9e 100644
--- a/tools/winedump/winedump.man.in
+++ b/tools/winedump/winedump.man.in
@@ -80,6 +80,9 @@ Dumps everything.
This command prints all available information about the
file. You may wish to pipe the output through more/less or
into a file, since a lot of output will be produced.
+.IP \fB-G\fR
+Dumps contents of debug section if any (for now, only stabs
+information is supported).
.PP
.B Spec mode:
.IP \fI<dll>\fR
More information about the wine-patches
mailing list