[PATCH 1/2] [WineDump]: larger usage of symbol demangling while
dumping
Eric Pouech
eric.pouech at wanadoo.fr
Sat Feb 10 02:10:07 CST 2007
A+
---
tools/winedump/dump.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
tools/winedump/main.c | 14 ++-------
tools/winedump/msc.c | 11 ++++---
tools/winedump/pe.c | 23 +--------------
tools/winedump/winedump.h | 1 +
5 files changed, 81 insertions(+), 37 deletions(-)
diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c
index bdd9e93..1d15995 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 @@ #endif
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..b135cca 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -854,7 +854,7 @@ int codeview_dump_symbols(const void* ro
case S_LDATA_V2:
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,
+ 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;
@@ -1128,7 +1128,8 @@ int codeview_dump_symbols(const void* ro
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);
+ 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-patches
mailing list