msvcrt: symbol undecoration: Now correctly parsing the template forms.
This commit is contained in:
parent
961f5fa67a
commit
2e47a3a4f8
|
@ -981,6 +981,9 @@ static void test_demangle(void)
|
||||||
{ "??0?$Foo@P6GHPAX0@Z@@QAE@PAD@Z", "__thiscall Foo<int (__stdcall*)(void *,void *)>::Foo<int (__stdcall*)(void *,void *)>(char *)", 0x880},
|
{ "??0?$Foo@P6GHPAX0@Z@@QAE@PAD@Z", "__thiscall Foo<int (__stdcall*)(void *,void *)>::Foo<int (__stdcall*)(void *,void *)>(char *)", 0x880},
|
||||||
{ "?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA", "private: static int (__cdecl** Bar::Qux)(class Bar *,int &,int &,int *)" },
|
{ "?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA", "private: static int (__cdecl** Bar::Qux)(class Bar *,int &,int &,int *)" },
|
||||||
{ "?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA", "Bar::Qux", 0x1800},
|
{ "?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA", "Bar::Qux", 0x1800},
|
||||||
|
{"?$AAA@$DBAB@", "AAA<`template-parameter257'>"},
|
||||||
|
{"?$AAA@$D?4@", "AAA<`template-parameter-5'>"},
|
||||||
|
{"?$AAA@PAUBBB@@", "AAA<struct BBB *>"},
|
||||||
};
|
};
|
||||||
int i, num_test = (sizeof(test)/sizeof(test[0]));
|
int i, num_test = (sizeof(test)/sizeof(test[0]));
|
||||||
char* name;
|
char* name;
|
||||||
|
|
|
@ -289,6 +289,52 @@ static char* str_printf(struct parsed_symbol* sym, const char* format, ...)
|
||||||
static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct,
|
static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct,
|
||||||
struct array* pmt, BOOL in_args);
|
struct array* pmt, BOOL in_args);
|
||||||
|
|
||||||
|
static const char* get_number(struct parsed_symbol* sym)
|
||||||
|
{
|
||||||
|
char* ptr;
|
||||||
|
BOOL sgn = FALSE;
|
||||||
|
|
||||||
|
if (*sym->current == '?')
|
||||||
|
{
|
||||||
|
sgn = TRUE;
|
||||||
|
sym->current++;
|
||||||
|
}
|
||||||
|
if (*sym->current >= '0' && *sym->current <= '8')
|
||||||
|
{
|
||||||
|
ptr = und_alloc(sym, 3);
|
||||||
|
if (sgn) ptr[0] = '-';
|
||||||
|
ptr[sgn ? 1 : 0] = *sym->current + 1;
|
||||||
|
ptr[sgn ? 2 : 1] = '\0';
|
||||||
|
sym->current++;
|
||||||
|
}
|
||||||
|
else if (*sym->current == '9')
|
||||||
|
{
|
||||||
|
ptr = und_alloc(sym, 4);
|
||||||
|
if (sgn) ptr[0] = '-';
|
||||||
|
ptr[sgn ? 1 : 0] = '1';
|
||||||
|
ptr[sgn ? 2 : 1] = '0';
|
||||||
|
ptr[sgn ? 3 : 2] = '\0';
|
||||||
|
sym->current++;
|
||||||
|
}
|
||||||
|
else if (*sym->current >= 'A' && *sym->current <= 'P')
|
||||||
|
{
|
||||||
|
long ret = 0;
|
||||||
|
|
||||||
|
while (*sym->current >= 'A' && *sym->current <= 'P')
|
||||||
|
{
|
||||||
|
ret *= 16;
|
||||||
|
ret += *sym->current++ - 'A';
|
||||||
|
}
|
||||||
|
if (*sym->current != '@') return NULL;
|
||||||
|
|
||||||
|
ptr = und_alloc(sym, 17);
|
||||||
|
sprintf(ptr, "%s%ld", sgn ? "-" : "", ret);
|
||||||
|
sym->current++;
|
||||||
|
}
|
||||||
|
else return NULL;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* get_args
|
* get_args
|
||||||
* Parses a list of function/method arguments, creates a string corresponding
|
* Parses a list of function/method arguments, creates a string corresponding
|
||||||
|
@ -672,7 +718,6 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct,
|
||||||
{
|
{
|
||||||
char dt;
|
char dt;
|
||||||
BOOL add_pmt = TRUE;
|
BOOL add_pmt = TRUE;
|
||||||
int num_args=0;
|
|
||||||
|
|
||||||
assert(ct);
|
assert(ct);
|
||||||
ct->left = ct->right = NULL;
|
ct->left = ct->right = NULL;
|
||||||
|
@ -779,34 +824,46 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct,
|
||||||
add_pmt = FALSE;
|
add_pmt = FALSE;
|
||||||
break;
|
break;
|
||||||
case '$':
|
case '$':
|
||||||
if (sym->current[0] != '0') goto done;
|
switch (*sym->current++)
|
||||||
if (sym->current[1] >= '0' && sym->current[1] <= '9')
|
|
||||||
{
|
{
|
||||||
char* ptr;
|
case '0':
|
||||||
ptr = und_alloc(sym, 2);
|
if (!(ct->left = get_number(sym))) goto done;
|
||||||
ptr[0] = sym->current[1] + 1;
|
break;
|
||||||
ptr[1] = 0;
|
case 'D':
|
||||||
ct->left = ptr;
|
|
||||||
sym->current += 2;
|
|
||||||
}
|
|
||||||
else if (sym->current[1] >= 'A' && sym->current[1] <= 'P')
|
|
||||||
{
|
|
||||||
while (sym->current[1] >= 'A' && sym->current[1] <= 'P')
|
|
||||||
{
|
{
|
||||||
num_args *= 16;
|
const char* ptr;
|
||||||
num_args += sym->current[1] - 'A';
|
if (!(ptr = get_number(sym))) goto done;
|
||||||
sym->current += 1;
|
ct->left = str_printf(sym, "`template-parameter%s'", ptr);
|
||||||
}
|
}
|
||||||
if(sym->current[1] == '@')
|
break;
|
||||||
|
case 'F':
|
||||||
{
|
{
|
||||||
char *ptr;
|
const char* p1;
|
||||||
ptr = und_alloc(sym, 17);
|
const char* p2;
|
||||||
sprintf(ptr,"%d",num_args);
|
if (!(p1 = get_number(sym))) goto done;
|
||||||
ct->left = ptr;
|
if (!(p2 = get_number(sym))) goto done;
|
||||||
sym->current += 1;
|
ct->left = str_printf(sym, "{%s,%s}", p1, p2);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
{
|
||||||
|
const char* p1;
|
||||||
|
const char* p2;
|
||||||
|
const char* p3;
|
||||||
|
if (!(p1 = get_number(sym))) goto done;
|
||||||
|
if (!(p2 = get_number(sym))) goto done;
|
||||||
|
if (!(p3 = get_number(sym))) goto done;
|
||||||
|
ct->left = str_printf(sym, "{%s,%s,%s}", p1, p2, p3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
{
|
||||||
|
const char* ptr;
|
||||||
|
if (!(ptr = get_number(sym))) goto done;
|
||||||
|
ct->left = str_printf(sym, "`non-type-template-parameter%s'", ptr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else goto done;
|
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
ERR("Unknown type %c\n", dt);
|
ERR("Unknown type %c\n", dt);
|
||||||
|
@ -1036,6 +1093,22 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* handle_template
|
||||||
|
* Does the final parsing and handling for a name with templates
|
||||||
|
*/
|
||||||
|
static BOOL handle_template(struct parsed_symbol* sym)
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
const char* args;
|
||||||
|
|
||||||
|
assert(*sym->current++ == '$');
|
||||||
|
if (!(name = get_literal_string(sym))) return FALSE;
|
||||||
|
if (!(args = get_args(sym, NULL, FALSE, '<', '>'))) return FALSE;
|
||||||
|
sym->result = str_printf(sym, "%s%s", name, args);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* symbol_demangle
|
* symbol_demangle
|
||||||
* Demangle a C++ linker symbol
|
* Demangle a C++ linker symbol
|
||||||
|
@ -1181,12 +1254,15 @@ static BOOL symbol_demangle(struct parsed_symbol* sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Either a class name, or '@' if the symbol is not a class member */
|
/* Either a class name, or '@' if the symbol is not a class member */
|
||||||
if (*sym->current != '@')
|
switch (*sym->current)
|
||||||
{
|
{
|
||||||
|
case '@': sym->current++; break;
|
||||||
|
case '$': break;
|
||||||
|
default:
|
||||||
/* Class the function is associated with, terminated by '@@' */
|
/* Class the function is associated with, terminated by '@@' */
|
||||||
if (!get_class(sym)) goto done;
|
if (!get_class(sym)) goto done;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else sym->current++;
|
|
||||||
|
|
||||||
switch (do_after)
|
switch (do_after)
|
||||||
{
|
{
|
||||||
|
@ -1211,6 +1287,8 @@ static BOOL symbol_demangle(struct parsed_symbol* sym)
|
||||||
ret = handle_data(sym);
|
ret = handle_data(sym);
|
||||||
else if (*sym->current >= 'A' && *sym->current <= 'Z')
|
else if (*sym->current >= 'A' && *sym->current <= 'Z')
|
||||||
ret = handle_method(sym, do_after == 3);
|
ret = handle_method(sym, do_after == 3);
|
||||||
|
else if (*sym->current == '$')
|
||||||
|
ret = handle_template(sym);
|
||||||
else ret = FALSE;
|
else ret = FALSE;
|
||||||
done:
|
done:
|
||||||
if (ret) assert(sym->result);
|
if (ret) assert(sym->result);
|
||||||
|
|
Loading…
Reference in New Issue