=?UTF-8?Q?Andr=C3=A9=20Hentschel=20?=: winedump: Dump exception info on ARM .
Alexandre Julliard
julliard at winehq.org
Mon Mar 25 14:19:38 CDT 2013
Module: wine
Branch: master
Commit: 18c95cf165a09ee0fe77f431ec31a5b101affd15
URL: http://source.winehq.org/git/wine.git/?a=commit;h=18c95cf165a09ee0fe77f431ec31a5b101affd15
Author: André Hentschel <nerv at dawncrow.de>
Date: Sat Mar 23 17:17:45 2013 +0100
winedump: Dump exception info on ARM.
---
tools/winedump/main.c | 2 +-
tools/winedump/pe.c | 82 +++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 74 insertions(+), 10 deletions(-)
diff --git a/tools/winedump/main.c b/tools/winedump/main.c
index 4186044..dbc2d67 100644
--- a/tools/winedump/main.c
+++ b/tools/winedump/main.c
@@ -228,7 +228,7 @@ static const struct my_option option_table[] = {
{"-C", DUMP, 0, do_symdmngl, "-C Turns on symbol demangling"},
{"-f", DUMP, 0, do_dumphead, "-f Dumps file header information"},
{"-G", DUMP, 0, do_rawdebug, "-G Dumps raw debug information"},
- {"-j", DUMP, 1, do_dumpsect, "-j sect_name Dumps only the content of section sect_name (import, export, debug, resource, tls, clr)"},
+ {"-j", DUMP, 1, do_dumpsect, "-j sect_name Dumps only the content of section sect_name (import, export, debug, resource, tls, clr, reloc, except)"},
{"-t", DUMP, 0, do_symtable, "-t Dumps symbol table"},
{"-x", DUMP, 0, do_dumpall, "-x Dumps everything"},
{NULL, NONE, 0, NULL, NULL}
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c
index bf29082..2029ef2 100644
--- a/tools/winedump/pe.c
+++ b/tools/winedump/pe.c
@@ -547,16 +547,35 @@ static void dump_dir_exported_functions(void)
}
-struct runtime_function
+struct runtime_function_x86_64
{
DWORD BeginAddress;
DWORD EndAddress;
DWORD UnwindData;
};
+struct runtime_function_armnt
+{
+ DWORD BeginAddress;
+ union {
+ DWORD UnwindData;
+ struct {
+ DWORD Flag : 2;
+ DWORD FunctionLength : 11;
+ DWORD Ret : 2;
+ DWORD H : 1;
+ DWORD Reg : 3;
+ DWORD R : 1;
+ DWORD L : 1;
+ DWORD C : 1;
+ DWORD StackAdjust : 10;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+};
+
union handler_data
{
- struct runtime_function chain;
+ struct runtime_function_x86_64 chain;
DWORD handler;
};
@@ -567,7 +586,7 @@ struct opcode
BYTE info : 4;
};
-struct unwind_info
+struct unwind_info_x86_64
{
BYTE version : 3;
BYTE flags : 5;
@@ -579,6 +598,14 @@ struct unwind_info
/* followed by union handler_data */
};
+struct unwind_info_armnt
+{
+ WORD function_length;
+ WORD unknown1 : 7;
+ WORD count : 5;
+ WORD unknown2 : 4;
+};
+
#define UWOP_PUSH_NONVOL 0
#define UWOP_ALLOC_LARGE 1
#define UWOP_ALLOC_SMALL 2
@@ -593,20 +620,20 @@ struct unwind_info
#define UNW_FLAG_UHANDLER 2
#define UNW_FLAG_CHAININFO 4
-static void dump_x86_64_unwind_info( const struct runtime_function *function )
+static void dump_x86_64_unwind_info( const struct runtime_function_x86_64 *function )
{
static const char * const reg_names[16] =
{ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" };
const union handler_data *handler_data;
- const struct unwind_info *info;
+ const struct unwind_info_x86_64 *info;
unsigned int i, count;
printf( "\nFunction %08x-%08x:\n", function->BeginAddress, function->EndAddress );
if (function->UnwindData & 1)
{
- const struct runtime_function *next = RVA( function->UnwindData & ~1, sizeof(*next) );
+ const struct runtime_function_x86_64 *next = RVA( function->UnwindData & ~1, sizeof(*next) );
printf( " -> function %08x-%08x\n", next->BeginAddress, next->EndAddress );
return;
}
@@ -698,19 +725,56 @@ static void dump_x86_64_unwind_info( const struct runtime_function *function )
(ULONG)(function->UnwindData + (const char *)(&handler_data->handler + 1) - (const char *)info ));
}
+static void dump_armnt_unwind_info( const struct runtime_function_armnt *function )
+{
+ const struct unwind_info_armnt *info;
+ if (function->u.s.Flag)
+ {
+ printf( "\nFunction %08x-%08x:\n", function->BeginAddress & ~1,
+ (function->BeginAddress & ~1) + function->u.s.FunctionLength * 2 );
+ printf( " Flag %x\n", function->u.s.Flag );
+ printf( " FunctionLength %x\n", function->u.s.FunctionLength );
+ printf( " Ret %x\n", function->u.s.Ret );
+ printf( " H %x\n", function->u.s.H );
+ printf( " Reg %x\n", function->u.s.Reg );
+ printf( " R %x\n", function->u.s.R );
+ printf( " L %x\n", function->u.s.L );
+ printf( " C %x\n", function->u.s.C );
+ printf( " StackAdjust %x\n", function->u.s.StackAdjust );
+ return;
+ }
+
+ info = RVA( function->u.UnwindData, sizeof(*info) );
+
+ printf( "\nFunction %08x-%08x:\n", function->BeginAddress & ~1,
+ (function->BeginAddress & ~1) + info->function_length * 2 );
+ printf( " unwind info at %08x\n", function->u.UnwindData );
+ printf( " Flag %x\n", function->u.s.Flag );
+ printf( " FunctionLength %x\n", info->function_length );
+ printf( " Unknown1 %x\n", info->unknown1 );
+ printf( " Count %x\n", info->count );
+ printf( " Unknown2 %x\n", info->unknown2 );
+}
+
static void dump_dir_exceptions(void)
{
unsigned int i, size = 0;
- const struct runtime_function *funcs = get_dir_and_size(IMAGE_FILE_EXCEPTION_DIRECTORY, &size);
+ const void *funcs = get_dir_and_size(IMAGE_FILE_EXCEPTION_DIRECTORY, &size);
const IMAGE_FILE_HEADER *file_header = &PE_nt_headers->FileHeader;
if (!funcs) return;
if (file_header->Machine == IMAGE_FILE_MACHINE_AMD64)
{
- size /= sizeof(*funcs);
+ size /= sizeof(struct runtime_function_x86_64);
+ printf( "Exception info (%u functions):\n", size );
+ for (i = 0; i < size; i++) dump_x86_64_unwind_info( (struct runtime_function_x86_64*)funcs + i );
+ }
+ else if (file_header->Machine == IMAGE_FILE_MACHINE_ARMNT)
+ {
+ size /= sizeof(struct runtime_function_armnt);
printf( "Exception info (%u functions):\n", size );
- for (i = 0; i < size; i++) dump_x86_64_unwind_info( funcs + i );
+ for (i = 0; i < size; i++) dump_armnt_unwind_info( (struct runtime_function_armnt*)funcs + i );
}
else printf( "Exception information not supported for %s binaries\n",
get_machine_str(file_header->Machine));
More information about the wine-cvs
mailing list