[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