Eric Pouech : winedump: Larger usage of symbol demangling while dumping.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Feb 12 09:24:00 CST 2007


Module: wine
Branch: master
Commit: 72c52d6d9e6b05302dfeee4a60121c412a3847e4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=72c52d6d9e6b05302dfeee4a60121c412a3847e4

Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date:   Sat Feb 10 09:10:07 2007 +0100

winedump: Larger usage of symbol demangling while dumping.

---

 tools/winedump/dump.c     |   69 +++++++++++++++++++++++++++++++++++++++++++++
 tools/winedump/main.c     |   14 ++-------
 tools/winedump/msc.c      |   17 ++++++-----
 tools/winedump/pe.c       |   23 +-------------
 tools/winedump/winedump.h |    1 +
 5 files changed, 84 insertions(+), 40 deletions(-)

diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c
index bdd9e93..2ed838c 100644
--- a/tools/winedump/dump.c
+++ b/tools/winedump/dump.c
@@ -78,6 +78,19 @@ void dump_data( const unsigned char *ptr
     printf( "\n" );
 }
 
+static char* dump_want_n(unsigned sz)
+{
+    static char         buffer[4 * 1024];
+    static unsigned     idx;
+    char*               ret;
+
+    assert(sz < sizeof(buffer));
+    if (idx + sz >= sizeof(buffer)) idx = 0;
+    ret = &buffer[idx];
+    idx += sz;
+    return ret;
+}
+
 const char *get_time_str(unsigned long _t)
 {
     const time_t    t = (const time_t)_t;
@@ -131,6 +144,62 @@ void dump_unicode_str( const WCHAR *str,
     printf( "\"" );
 }
 
+const char* get_symbol_str(const char* symname)
+{
+    char*       tmp;
+    const char* ret;
+
+    if (!symname) return "(nil)";
+    if (globals.do_demangle)
+    {
+        parsed_symbol   symbol;
+
+        symbol_init(&symbol, symname);
+        if (symbol_demangle(&symbol) == -1)
+            ret = symname;
+        else if (symbol.flags & SYM_DATA)
+        {
+            ret = tmp = dump_want_n(strlen(symbol.arg_text[0]) + 1);
+            if (tmp) strcpy(tmp, symbol.arg_text[0]);
+        }
+        else
+        {
+            unsigned int i, len, start = symbol.flags & SYM_THISCALL ? 1 : 0;
+
+            len = strlen(symbol.return_text) + 3 /* ' __' */ +
+                strlen(symbol_get_call_convention(&symbol)) + 1 /* ' ' */+
+                strlen(symbol.function_name) + 1 /* ')' */;
+            if (!symbol.argc || (symbol.argc == 1 && symbol.flags & SYM_THISCALL))
+                len += 4 /* "void" */;
+            else for (i = start; i < symbol.argc; i++)
+                len += (i > start ? 2 /* ", " */ : 0 /* "" */) + strlen(symbol.arg_text[i]);
+            if (symbol.varargs) len += 5 /* ", ..." */;
+            len += 2; /* ")\0" */
+
+            ret = tmp = dump_want_n(len);
+            if (tmp)
+            {
+                sprintf(tmp, "%s __%s %s(",
+                        symbol.return_text,
+                        symbol_get_call_convention(&symbol),
+                        symbol.function_name);
+                if (!symbol.argc || (symbol.argc == 1 && symbol.flags & SYM_THISCALL))
+                    strcat(tmp, "void");
+                else for (i = start; i < symbol.argc; i++)
+                {
+                    if (i > start) strcat(tmp, ", ");
+                    strcat(tmp, symbol.arg_text[i]);
+                }
+                if (symbol.varargs) strcat(tmp, ", ...");
+                strcat(tmp, ")");
+            }
+        }
+        symbol_clear(&symbol);
+    }
+    else ret = symname;
+    return ret;
+}
+
 char* guid_to_string(const GUID* guid, char* str, size_t sz)
 {
     snprintf(str, sz, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
diff --git a/tools/winedump/main.c b/tools/winedump/main.c
index 93cd074..2aba30a 100644
--- a/tools/winedump/main.c
+++ b/tools/winedump/main.c
@@ -407,19 +407,11 @@ int   main (int argc, char *argv[])
     switch (globals.mode)
     {
     case DMGL:
-	globals.uc_dll_name = "";
 	VERBOSE = 1;
 
-	symbol_init (&symbol, globals.input_name);
-	globals.input_module = "";
-	if (symbol_demangle (&symbol) == -1)
-	    fatal( "Symbol hasn't got a mangled name\n");
-	if (symbol.flags & SYM_DATA)
-	    printf (symbol.arg_text[0]);
-	else
-	    output_prototype (stdout, &symbol);
-	fputc ('\n', stdout);
-	symbol_clear(&symbol);
+        if (globals.input_name == NULL)
+            fatal("No symbol name has been given\n");
+        printf("%s\n", get_symbol_str(globals.input_name));
 	break;
 
     case SPEC:
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index 91ad8c1..4ef3387 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -852,9 +852,9 @@ int codeview_dump_symbols(const void* ro
          */
 	case S_GDATA_V2:
 	case S_LDATA_V2:
-            printf("\tS-%s-Data V2 '%s' %04x:%08x type:%08x\n", 
+            printf("\tS-%s-Data V2 '%s' %04x:%08x type:%08x\n",
                    sym->generic.id == S_GDATA_V2 ? "Global" : "Local",
-                   p_string(&sym->data_v2.p_name),
+                   get_symbol_str(p_string(&sym->data_v2.p_name)),
                    sym->data_v2.segment, sym->data_v2.offset, sym->data_v2.symtype);
 	    break;
 
@@ -863,14 +863,14 @@ int codeview_dump_symbols(const void* ro
 /* EPP         case S_DATA_V3: */
             printf("\tS-%s-Data V3 '%s' (%04x:%08x) type:%08x\n",
                    sym->generic.id == S_GDATA_V3 ? "Global" : "Local",
-                   sym->data_v3.name, 
-                   sym->data_v3.segment, sym->data_v3.offset, 
+                   get_symbol_str(sym->data_v3.name),
+                   sym->data_v3.segment, sym->data_v3.offset,
                    sym->data_v3.symtype);
             break;
 
 	case S_PUB_V2:
             printf("\tS-Public V2 '%s' %04x:%08x type:%08x\n",
-                   p_string(&sym->public_v2.p_name),
+                   get_symbol_str(p_string(&sym->public_v2.p_name)),
                    sym->public_v2.segment, sym->public_v2.offset,
                    sym->public_v2.symtype);
 	    break;
@@ -882,7 +882,7 @@ int codeview_dump_symbols(const void* ro
             printf("\tS-Public%s V3 '%s' %04x:%08x type:%08x\n",
                    sym->generic.id == S_PUB_V3 ? "" :
                                       (sym->generic.id == S_PUB_FUNC1_V3 ? "<subkind1" : "<subkind2"),
-                   sym->public_v3.name,
+                   get_symbol_str(sym->public_v3.name),
                    sym->public_v3.segment,
                    sym->public_v3.offset, sym->public_v3.symtype);
 	    break;
@@ -1127,8 +1127,9 @@ int codeview_dump_symbols(const void* ro
                 int             val, vlen;
 
                 vlen = numeric_leaf(&val, &sym->constant_v2.cvalue);
-                printf("\tS-Constant V2 '%s' = %u type:%x\n", 
-                       p_string(PSTRING(&sym->constant_v2.cvalue, vlen)), val, sym->constant_v2.type);
+                printf("\tS-Constant V2 '%s' = %u type:%x\n",
+                       p_string(PSTRING(&sym->constant_v2.cvalue, vlen)),
+                       val, sym->constant_v2.type);
             }
             break;
 
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c
index cbebba9..887a119 100644
--- a/tools/winedump/pe.c
+++ b/tools/winedump/pe.c
@@ -470,7 +470,6 @@ static	void	dump_dir_exported_functions(
     const DWORD*		pName;
     const WORD* 		pOrdl;
     DWORD*		        map;
-    parsed_symbol		symbol;
 
     if (!exportDir) return;
 
@@ -503,28 +502,10 @@ static	void	dump_dir_exported_functions(
 
     for (i = 0; i < exportDir->NumberOfNames; i++, pName++, pOrdl++)
     {
-	const char*	name;
-
 	map[*pOrdl / 32] |= 1 << (*pOrdl % 32);
 
-	name = (const char*)RVA(*pName, sizeof(DWORD));
-	if (name && globals.do_demangle)
-	{
-            printf("  %08X  %4u ", pFunc[*pOrdl], exportDir->Base + *pOrdl);
-
-	    symbol_init(&symbol, name);
-	    if (symbol_demangle(&symbol) == -1)
-		printf(name);
-	    else if (symbol.flags & SYM_DATA)
-		printf(symbol.arg_text[0]);
-	    else
-		output_prototype(stdout, &symbol);
-	    symbol_clear(&symbol);
-	}
-	else
-	{
-            printf("  %08X  %4u %s", pFunc[*pOrdl], exportDir->Base + *pOrdl, name);
-	}
+        printf("  %08X  %4u %s", pFunc[*pOrdl], exportDir->Base + *pOrdl,
+               get_symbol_str((const char*)RVA(*pName, sizeof(DWORD))));
         /* check for forwarded function */
         if ((const char *)RVA(pFunc[*pOrdl],sizeof(void*)) >= (const char *)exportDir &&
             (const char *)RVA(pFunc[*pOrdl],sizeof(void*)) < (const char *)exportDir + size)
diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h
index d6c1507..55406ab 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -236,6 +236,7 @@ void            dump_data( const unsigne
 const char*	get_time_str( unsigned long );
 unsigned int    strlenW( const unsigned short *str );
 void            dump_unicode_str( const unsigned short *str, int len );
+const char*     get_symbol_str(const char* symname);
 void            dump_file_header(const IMAGE_FILE_HEADER *);
 void            dump_optional_header(const IMAGE_OPTIONAL_HEADER32 *, UINT);
 void            dump_section(const IMAGE_SECTION_HEADER *);




More information about the wine-cvs mailing list