winedump: Better handle display of nested symbol entries.

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2021-11-10 16:43:36 +01:00 committed by Alexandre Julliard
parent 2447b0131b
commit 8de547d3e6
1 changed files with 101 additions and 41 deletions

View File

@ -1303,11 +1303,61 @@ static void dump_binannot(const unsigned char* ba, const char* last, unsigned in
}
}
struct symbol_dumper
{
unsigned depth;
unsigned alloc;
struct
{
unsigned end;
const union codeview_symbol* sym;
}* stack;
};
static void init_symbol_dumper(struct symbol_dumper* sd)
{
sd->depth = 0;
sd->alloc = 16;
sd->stack = malloc(sd->alloc * sizeof(sd->stack[0]));
}
static void push_symbol_dumper(struct symbol_dumper* sd, const union codeview_symbol* sym, unsigned end)
{
if (!sd->stack) return;
if (sd->depth >= sd->alloc &&
!(sd->stack = realloc(sd->stack, (sd->alloc *= 2) * sizeof(sd->stack[0]))))
return;
sd->stack[sd->depth].end = end;
sd->stack[sd->depth].sym = sym;
sd->depth++;
}
static unsigned short pop_symbol_dumper(struct symbol_dumper* sd, unsigned end)
{
if (!sd->stack) return 0;
if (!sd->depth)
{
printf(">>> Error in stack\n");
return 0;
}
sd->depth--;
if (sd->stack[sd->depth].end != end)
printf(">>> Wrong end reference\n");
return sd->stack[sd->depth].sym->generic.id;
}
static void dispose_symbol_dumper(struct symbol_dumper* sd)
{
free(sd->stack);
}
BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long size)
{
unsigned int i;
int length;
int nest_block = 0;
struct symbol_dumper sd;
init_symbol_dumper(&sd);
/*
* Loop over the different types of records and whenever we
* find something we are interested in, record it and move on.
@ -1315,12 +1365,23 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
for (i = start; i < size; i += length)
{
const union codeview_symbol* sym = (const union codeview_symbol*)((const char*)root + i);
unsigned indent;
unsigned indent, ref;
length = sym->generic.len + 2;
if (!sym->generic.id || length < 4) break;
indent = printf(" %04x => ", i);
switch (sym->generic.id)
{
case S_END:
case S_INLINESITE_END:
indent += printf("%*s", 2 * sd.depth - 2, "");
break;
default:
indent += printf("%*s", 2 * sd.depth, "");
break;
}
switch (sym->generic.id)
{
/*
@ -1386,6 +1447,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
p_string(&sym->thunk_v1.p_name),
sym->thunk_v1.segment, sym->thunk_v1.offset,
sym->thunk_v1.thunk_len, sym->thunk_v1.thtype);
push_symbol_dumper(&sd, sym, sym->thunk_v1.pend);
break;
case S_THUNK32:
@ -1393,47 +1455,38 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
sym->thunk_v3.name,
sym->thunk_v3.segment, sym->thunk_v3.offset,
sym->thunk_v3.thunk_len, sym->thunk_v3.thtype);
push_symbol_dumper(&sd, sym, sym->thunk_v3.pend);
break;
/* Global and static functions */
case S_GPROC32_16t:
case S_LPROC32_16t:
printf("%s-Proc V1: '%s' (%04x:%08x#%x) type:%x attr:%x\n",
sym->generic.id == S_GPROC32_16t ? "Global" : "-Local",
sym->generic.id == S_GPROC32_16t ? "Global" : "Local",
p_string(&sym->proc_v1.p_name),
sym->proc_v1.segment, sym->proc_v1.offset,
sym->proc_v1.proc_len, sym->proc_v1.proctype,
sym->proc_v1.flags);
printf("%*s\\- Debug: start=%08x end=%08x\n",
indent, "", sym->proc_v1.debug_start, sym->proc_v1.debug_end);
if (nest_block)
{
printf(">>> prev func still has nest_block %u count\n", nest_block);
nest_block = 0;
}
/* EPP unsigned int pparent; */
/* EPP unsigned int pend; */
/* EPP unsigned int next; */
printf("%*s\\- parent:<%x> end:<%x> next<%x>\n",
indent, "", sym->proc_v1.pparent, sym->proc_v1.pend, sym->proc_v1.next);
push_symbol_dumper(&sd, sym, sym->proc_v1.pend);
break;
case S_GPROC32_ST:
case S_LPROC32_ST:
printf("%s-Proc V2: '%s' (%04x:%08x#%x) type:%x attr:%x\n",
sym->generic.id == S_GPROC32_ST ? "Global" : "-Local",
sym->generic.id == S_GPROC32_ST ? "Global" : "Local",
p_string(&sym->proc_v2.p_name),
sym->proc_v2.segment, sym->proc_v2.offset,
sym->proc_v2.proc_len, sym->proc_v2.proctype,
sym->proc_v2.flags);
printf("%*s\\- Debug: start=%08x end=%08x\n",
indent, "", sym->proc_v2.debug_start, sym->proc_v2.debug_end);
if (nest_block)
{
printf(">>> prev func still has nest_block %u count\n", nest_block);
nest_block = 0;
}
/* EPP unsigned int pparent; */
/* EPP unsigned int pend; */
/* EPP unsigned int next; */
printf("%*s\\- parent:<%x> end:<%x> next<%x>\n",
indent, "", sym->proc_v2.pparent, sym->proc_v2.pend, sym->proc_v2.next);
push_symbol_dumper(&sd, sym, sym->proc_v2.pend);
break;
case S_LPROC32:
@ -1446,14 +1499,9 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
sym->proc_v3.flags);
printf("%*s\\- Debug: start=%08x end=%08x\n",
indent, "", sym->proc_v3.debug_start, sym->proc_v3.debug_end);
if (nest_block)
{
printf(">>> prev func still has nest_block %u count\n", nest_block);
nest_block = 0;
}
/* EPP unsigned int pparent; */
/* EPP unsigned int pend; */
/* EPP unsigned int next; */
printf("%*s\\- parent:<%x> end:<%x> next<%x>\n",
indent, "", sym->proc_v3.pparent, sym->proc_v3.pend, sym->proc_v3.next);
push_symbol_dumper(&sd, sym, sym->proc_v3.pend);
break;
/* Function parameters and stack variables */
@ -1503,15 +1551,15 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
p_string(&sym->block_v1.p_name),
sym->block_v1.segment, sym->block_v1.offset,
sym->block_v1.length);
nest_block++;
push_symbol_dumper(&sd, sym, sym->block_v1.end);
break;
case S_BLOCK32:
printf("Block V3 '%s' (%04x:%08x#%08x) parent:%u end:%x\n",
printf("Block V3 '%s' (%04x:%08x#%08x) parent:<%u> end:<%x>\n",
sym->block_v3.name,
sym->block_v3.segment, sym->block_v3.offset, sym->block_v3.length,
sym->block_v3.parent, sym->block_v3.end);
nest_block++;
push_symbol_dumper(&sd, sym, sym->block_v3.end);
break;
/* Additional function information */
@ -1532,13 +1580,17 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
break;
case S_END:
if (nest_block)
ref = sd.depth ? (const char*)sd.stack[sd.depth - 1].sym - (const char*)root : 0;
switch (pop_symbol_dumper(&sd, i))
{
nest_block--;
printf("End-Of block (%u)\n", nest_block);
case S_BLOCK32_ST:
case S_BLOCK32:
printf("End-Of block <%x>\n", ref);
break;
default:
printf("End-Of <%x>\n", ref);
break;
}
else
printf("End-Of function\n");
break;
case S_COMPILE:
@ -1813,18 +1865,24 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
break;
case S_INLINESITE:
printf("Inline-site V3 parent:%x end:%x inlinee:%x\n",
printf("Inline-site V3 parent:<%x> end:<%x> inlinee:%x\n",
sym->inline_site_v3.pParent, sym->inline_site_v3.pEnd, sym->inline_site_v3.inlinee);
dump_binannot(sym->inline_site_v3.binaryAnnotations, get_last(sym), indent);
push_symbol_dumper(&sd, sym, sym->inline_site_v3.pEnd);
break;
case S_INLINESITE2:
printf("Inline-site2 V3 parent:%x end:%x inlinee:%x #inv:%u\n",
printf("Inline-site2 V3 parent:<%x> end:<%x> inlinee:%x #inv:%u\n",
sym->inline_site2_v3.pParent, sym->inline_site2_v3.pEnd, sym->inline_site2_v3.inlinee,
sym->inline_site2_v3.invocations);
dump_binannot(sym->inline_site2_v3.binaryAnnotations, get_last(sym), indent);
push_symbol_dumper(&sd, sym, sym->inline_site2_v3.pEnd);
break;
case S_INLINESITE_END:
printf("Inline-site-end\n");
ref = sd.depth ? (const char*)sd.stack[sd.depth - 1].sym - (const char*)root : 0;
pop_symbol_dumper(&sd, i);
printf("Inline-site-end <%x>\n", ref);
break;
case S_CALLEES:
@ -1843,7 +1901,8 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
ninvoc = (const unsigned*)get_last(sym) - invoc;
for (i = 0; i < sym->function_list_v3.count; ++i)
printf("%*s| func:%x invoc:%u\n", indent, "", sym->function_list_v3.funcs[i], i < ninvoc ? invoc[i] : 0);
printf("%*s| func:%x invoc:%u\n",
indent, "", sym->function_list_v3.funcs[i], i < ninvoc ? invoc[i] : 0);
}
break;
@ -1872,7 +1931,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
break;
case S_SEPCODE:
printf("SepCode V3 pParent:%x pEnd:%x separated:%04x:%08x (#%u) from %04x:%08x\n",
printf("SepCode V3 parent:<%x> end:<%x> separated:%04x:%08x (#%u) from %04x:%08x\n",
sym->sepcode_v3.pParent, sym->sepcode_v3.pEnd,
sym->sepcode_v3.sect, sym->sepcode_v3.off, sym->sepcode_v3.length,
sym->sepcode_v3.sectParent, sym->sepcode_v3.offParent);
@ -1894,6 +1953,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long start, unsigned long
dump_data((const void*)sym, sym->generic.len + 2, " ");
}
}
dispose_symbol_dumper(&sd);
return TRUE;
}