msvcrt: Use a separate stack for back references to names
Use a separate array/stack for the back references to names as sym->stack is used to push temporary strings to it which breaks back referencing in some occasions (26 symbols in the mfc42 dll). During this cleanup get_class() a little bit.
This commit is contained in:
parent
e367ebbf19
commit
262a5eec78
|
@ -91,6 +91,7 @@ struct parsed_symbol
|
||||||
const char* current; /* pointer in input (mangled) string */
|
const char* current; /* pointer in input (mangled) string */
|
||||||
char* result; /* demangled string */
|
char* result; /* demangled string */
|
||||||
|
|
||||||
|
struct array names; /* array of names for back reference */
|
||||||
struct array stack; /* stack of parsed strings */
|
struct array stack; /* stack of parsed strings */
|
||||||
|
|
||||||
void* alloc_list; /* linked list of allocated blocks */
|
void* alloc_list; /* linked list of allocated blocks */
|
||||||
|
@ -420,9 +421,9 @@ static char* get_literal_string(struct parsed_symbol* sym)
|
||||||
}
|
}
|
||||||
} while (*++sym->current != '@');
|
} while (*++sym->current != '@');
|
||||||
sym->current++;
|
sym->current++;
|
||||||
str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->stack);
|
str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->names);
|
||||||
|
|
||||||
return str_array_get_ref(&sym->stack, sym->stack.num - sym->stack.start - 1);
|
return str_array_get_ref(&sym->names, sym->names.num - sym->names.start - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
@ -440,7 +441,7 @@ static char* get_literal_string(struct parsed_symbol* sym)
|
||||||
*/
|
*/
|
||||||
static BOOL get_class(struct parsed_symbol* sym)
|
static BOOL get_class(struct parsed_symbol* sym)
|
||||||
{
|
{
|
||||||
const char* ptr;
|
const char* name = NULL;
|
||||||
|
|
||||||
while (*sym->current != '@')
|
while (*sym->current != '@')
|
||||||
{
|
{
|
||||||
|
@ -451,39 +452,44 @@ static BOOL get_class(struct parsed_symbol* sym)
|
||||||
case '0': case '1': case '2': case '3':
|
case '0': case '1': case '2': case '3':
|
||||||
case '4': case '5': case '6': case '7':
|
case '4': case '5': case '6': case '7':
|
||||||
case '8': case '9':
|
case '8': case '9':
|
||||||
ptr = str_array_get_ref(&sym->stack, *sym->current++ - '0');
|
name = str_array_get_ref(&sym->names, *sym->current++ - '0');
|
||||||
if (!ptr) return FALSE;
|
|
||||||
str_array_push(sym, ptr, -1, &sym->stack);
|
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
if (*++sym->current == '$')
|
if (*++sym->current == '$')
|
||||||
{
|
{
|
||||||
const char* name;
|
/* In a template argument list the back reference to names
|
||||||
char* full = NULL;
|
table is separately created. '0' points to the class
|
||||||
|
component name with the template arguments. We use the same
|
||||||
|
stack array to hold the names but save/restore the stack
|
||||||
|
state before/after parsing the template argument list. */
|
||||||
char* args = NULL;
|
char* args = NULL;
|
||||||
unsigned num_mark = sym->stack.num;
|
unsigned num_mark = sym->names.num;
|
||||||
unsigned start_mark = sym->stack.start;
|
unsigned start_mark = sym->names.start;
|
||||||
|
unsigned stack_mark = sym->stack.num;
|
||||||
|
|
||||||
|
sym->names.start = sym->names.num;
|
||||||
sym->current++;
|
sym->current++;
|
||||||
sym->stack.start = sym->stack.num;
|
|
||||||
if (!(name = get_literal_string(sym)))
|
if (!(name = get_literal_string(sym)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
args = get_args(sym, NULL, FALSE, '<', '>');
|
args = get_args(sym, NULL, FALSE, '<', '>');
|
||||||
if (args != NULL)
|
if (args != NULL)
|
||||||
{
|
name = str_printf(sym, "%s%s", name, args);
|
||||||
full = str_printf(sym, "%s%s", name, args);
|
sym->names.num = num_mark;
|
||||||
}
|
sym->names.start = start_mark;
|
||||||
if (!full) return FALSE;
|
sym->stack.num = stack_mark;
|
||||||
sym->stack.elts[num_mark] = full;
|
/* Now that we are back to the standard name scope push
|
||||||
sym->stack.num = num_mark + 1;
|
the class component with all its template arguments
|
||||||
sym->stack.start = start_mark;
|
to the names array for back reference. */
|
||||||
|
str_array_push(sym, name, -1, &sym->names);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!get_literal_string(sym))
|
name = get_literal_string(sym);
|
||||||
return FALSE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!name)
|
||||||
|
return FALSE;
|
||||||
|
str_array_push(sym, name, -1, &sym->stack);
|
||||||
}
|
}
|
||||||
sym->current++;
|
sym->current++;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1027,6 +1033,7 @@ static BOOL symbol_demangle(struct parsed_symbol* sym)
|
||||||
|
|
||||||
/* MS mangled names always begin with '?' */
|
/* MS mangled names always begin with '?' */
|
||||||
if (*sym->current != '?') return FALSE;
|
if (*sym->current != '?') return FALSE;
|
||||||
|
str_array_init(&sym->names);
|
||||||
str_array_init(&sym->stack);
|
str_array_init(&sym->stack);
|
||||||
sym->current++;
|
sym->current++;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue