winedump: Make the ARM exception information more compact.

This commit is contained in:
Alexandre Julliard 2024-02-01 11:39:28 +01:00
parent d352b852a9
commit 3825af6041

View file

@ -985,7 +985,7 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
{
const struct unwind_info_armnt *info;
const struct unwind_info_ext_armnt *infoex;
const struct unwind_info_epilogue_armnt *infoepi;
const struct unwind_info_epilogue_armnt *infoepi = NULL;
unsigned int rva;
WORD i, count = 0, words = 0;
@ -993,18 +993,11 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
{
char intregs[32] = {0}, intregspop[32] = {0}, vfpregs[32] = {0};
WORD pf = 0, ef = 0, fpoffset = 0, stack = fnc->StackAdjust;
const char *pfx = " ... ";
printf( "\nFunction %08x-%08x:\n", fnc->BeginAddress & ~1,
(fnc->BeginAddress & ~1) + fnc->FunctionLength * 2 );
printf( " Flag %x\n", fnc->Flag );
printf( " FunctionLength %x\n", fnc->FunctionLength );
printf( " Ret %x\n", fnc->Ret );
printf( " H %x\n", fnc->H );
printf( " Reg %x\n", fnc->Reg );
printf( " R %x\n", fnc->R );
printf( " L %x\n", fnc->L );
printf( " C %x\n", fnc->C );
printf( " StackAdjust %x\n", fnc->StackAdjust );
printf( "\nFunction %08x-%08x: (flag=%u ret=%u H=%u reg=%u R=%u L=%u C=%u)\n",
fnc->BeginAddress & ~1, (fnc->BeginAddress & ~1) + fnc->FunctionLength * 2,
fnc->Flag, fnc->Ret, fnc->H, fnc->Reg, fnc->R, fnc->L, fnc->C );
if (fnc->StackAdjust >= 0x03f4)
{
@ -1075,47 +1068,48 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
strcpy(vfpregs, "d8");
}
printf( " Prologue:\n" );
if (fnc->Flag == 1) {
if (fnc->H)
printf( " Unwind Code\tpush {r0-r3}\n" );
printf( "%s push {r0-r3}\n", pfx );
if (intregs[0])
printf( " Unwind Code\tpush {%s}\n", intregs );
printf( "%s push {%s}\n", pfx, intregs );
if (fnc->C && fpoffset == 0)
printf( " Unwind Code\tmov r11, sp\n" );
printf( "%s mov r11, sp\n", pfx );
else if (fnc->C)
printf( " Unwind Code\tadd r11, sp, #%d\n", fpoffset * 4 );
printf( "%s add r11, sp, #%d\n", pfx, fpoffset * 4 );
if (fnc->R && fnc->Reg != 0x07)
printf( " Unwind Code\tvpush {%s}\n", vfpregs );
printf( "%s vpush {%s}\n", pfx, vfpregs );
if (stack && !pf)
printf( " Unwind Code\tsub sp, sp, #%d\n", stack * 4 );
printf( "%s sub sp, sp, #%d\n", pfx, stack * 4 );
}
if (fnc->Ret == 3)
return;
printf( "Epilogue:\n" );
printf( " Epilogue:\n" );
if (stack && !ef)
printf( " Unwind Code\tadd sp, sp, #%d\n", stack * 4 );
printf( "%s add sp, sp, #%d\n", pfx, stack * 4 );
if (fnc->R && fnc->Reg != 0x07)
printf( " Unwind Code\tvpop {%s}\n", vfpregs );
printf( "%s vpop {%s}\n", pfx, vfpregs );
if (intregspop[0])
printf( " Unwind Code\tpop {%s}\n", intregspop );
printf( "%s pop {%s}\n", pfx, intregspop );
if (fnc->H && !(fnc->L && fnc->Ret == 0))
printf( " Unwind Code\tadd sp, sp, #16\n" );
printf( "%s add sp, sp, #16\n", pfx );
else if (fnc->H && (fnc->L && fnc->Ret == 0))
printf( " Unwind Code\tldr pc, [sp], #20\n" );
printf( "%s ldr pc, [sp], #20\n", pfx );
if (fnc->Ret == 1)
printf( " Unwind Code\tbx <reg>\n" );
printf( "%s bx <reg>\n", pfx );
else if (fnc->Ret == 2)
printf( " Unwind Code\tb <address>\n" );
printf( "%s b <address>\n", pfx );
return;
}
@ -1125,17 +1119,9 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
count = info->count;
words = info->words;
printf( "\nFunction %08x-%08x:\n", fnc->BeginAddress & ~1,
(fnc->BeginAddress & ~1) + info->function_length * 2 );
printf( " unwind info at %08x\n", fnc->UnwindData );
printf( " Flag %x\n", fnc->Flag );
printf( " FunctionLength %x\n", info->function_length );
printf( " Version %x\n", info->version );
printf( " X %x\n", info->x );
printf( " E %x\n", info->e );
printf( " F %x\n", info->f );
printf( " Count %x\n", count );
printf( " Words %x\n", words );
printf( "\nFunction %08x-%08x: (ver=%u X=%u E=%u F=%u)\n", fnc->BeginAddress & ~1,
(fnc->BeginAddress & ~1) + info->function_length * 2,
info->version, info->x, info->e, info->f );
if (!info->count && !info->words)
{
@ -1143,26 +1129,13 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
rva = rva + sizeof(*infoex);
count = infoex->excount;
words = infoex->exwords;
printf( " ExtCount %x\n", count );
printf( " ExtWords %x\n", words );
}
if (!info->e)
if (!info->e)
{
infoepi = RVA( rva, count * sizeof(*infoepi) );
rva = rva + count * sizeof(*infoepi);
for (i = 0; i < count; i++)
{
printf( " Epilogue Scope %x\n", i );
printf( " Offset %x\n", infoepi[i].offset );
printf( " Reserved %x\n", infoepi[i].res );
printf( " Condition %x\n", infoepi[i].cond );
printf( " Index %x\n", infoepi[i].index );
}
}
else
infoepi = NULL;
if (words)
{
@ -1174,6 +1147,7 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
rva = rva + words * sizeof(*codes);
bytes = (BYTE*)codes;
printf( " Prologue:\n" );
for (b = 0; b < words * sizeof(*codes); b++)
{
BYTE code = bytes[b];
@ -1181,7 +1155,7 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
if (info->e && b == count)
{
printf( "Epilogue:\n" );
printf( " Epilogue:\n" );
inepilogue = TRUE;
}
else if (!info->e && infoepi)
@ -1189,16 +1163,17 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
for (i = 0; i < count; i++)
if (b == infoepi[i].index)
{
printf( "Epilogue from Scope %x at %08x:\n", i,
(fnc->BeginAddress & ~1) + infoepi[i].offset * 2 );
printf( " Epilogue %u at %08x: (res=%x cond=%x)\n", i,
(fnc->BeginAddress & ~1) + infoepi[i].offset * 2,
infoepi[i].res, infoepi[i].cond );
inepilogue = TRUE;
}
}
printf( " Unwind Code");
printf( " ");
for (i = 0; i < len; i++)
printf( " %02x", bytes[b+i] );
printf( "\t" );
printf( " %*s", 3 * (3 - len), "" );
if (code == 0x00)
printf( "\n" );
@ -1232,16 +1207,16 @@ static void dump_armnt_unwind_info( const struct runtime_function_armnt *fnc )
printf( "mov sp, r%u\n", code & 0x0f );
else
printf( "mov r%u, sp\n", code & 0x0f );
else if (code <= 0xd3)
printf( "%s {r4-r%u}\n", inepilogue ? "pop" : "push", (code & 0x03) + 4 );
else if (code <= 0xd4)
printf( "%s {r4, %s}\n", inepilogue ? "pop" : "push", inepilogue ? "pc" : "lr" );
else if (code <= 0xd7)
if (inepilogue)
printf( "pop {r4-r%u%s}\n", (code & 0x03) + 4, (code & 0x04) ? ", pc" : "" );
else
printf( "push {r4-r%u%s}\n", (code & 0x03) + 4, (code & 0x04) ? ", lr" : "" );
printf( "%s {r4-r%u, %s}\n", inepilogue ? "pop" : "push", (code & 0x03) + 4, inepilogue ? "pc" : "lr" );
else if (code <= 0xdb)
printf( "%s {r4-r%u}\n", inepilogue ? "pop" : "push", (code & 0x03) + 8 );
else if (code <= 0xdf)
if (inepilogue)
printf( "pop {r4-r%u%s}\n", (code & 0x03) + 8, (code & 0x04) ? ", pc" : "" );
else
printf( "push {r4-r%u%s}\n", (code & 0x03) + 8, (code & 0x04) ? ", lr" : "" );
printf( "%s {r4-r%u, %s}\n", inepilogue ? "pop" : "push", (code & 0x03) + 8, inepilogue ? "pc" : "lr" );
else if (code <= 0xe7)
printf( "%s {d8-d%u}\n", inepilogue ? "vpop" : "vpush", (code & 0x07) + 8 );
else if (code <= 0xeb)