From: "Changhui LIU" Subject: winedbg: Add disassembly_flavor option to use the intel disassembly style like gdb's disassembly-flavor option. (try 3) Message-Id: Date: Mon, 11 Jan 2016 17:07:11 +0800 Superseded patch 117913 . Try3: 1, Let configure.ac auto check udis86 library, and enable Intel disassembly style if found libudis86 has installed. 2, Add _i386_ and _x86_64 compile macro to limited use libudis86 only on i386 and amd64 platform. Thanks for Michael. Usage: The default disassembly style is att. 1) Set the disassembly style to intel . Wine-dbg> set !disassembly_flavor intel 2) Set the disassembly style to att . Wine-dbg> set !disassembly_flavor att ------------------ Regards, Changhui Liu
Superseded patch 117913 .
Try3:
1, Let configure.ac auto check udis86 library, and enable Intel disassembly style if found libudis86 has installed.
2, Add _i386_ and _x86_64 compile macro to limited use libudis86 only on i386 and amd64 platform.

Thanks  for Michael.

Usage:
The default disassembly style is att.

1) Set the disassembly style to intel .
Wine-dbg> set !disassembly_flavor intel

2) Set the disassembly style to att .
Wine-dbg> set !disassembly_flavor att




------------------
Regards,
Changhui Liu
 
From 1c2dddd5bfeb6a123952357a62d3f78ed6acd56b Mon Sep 17 00:00:00 2001 From: Changhui Liu Date: Mon, 11 Jan 2016 16:51:27 +0800 Subject: winedbg: Add disassembly_flavor option to use the intel disassembly style like gdb's disassembly-flavor option. To: wine-patches Reply-To: wine-devel The disassembler lib at https://github.com/vmt/udis86, you need build and install it first. The default disassembly style is att, usage: 1) Set the disassembly style to intel . Wine-dbg> set !disassembly_flavor intel 2) Set the disassembly style to att . Wine-dbg> set !disassembly_flavor att Signed-off-by: Changhui Liu --- configure.ac | 12 ++++++++ programs/winedbg/Makefile.in | 2 +- programs/winedbg/db_disasm.c | 66 ++++++++++++++++++++++++++++++++++++++++++ programs/winedbg/db_disasm64.c | 65 ++++++++++++++++++++++++++++++++++++++++- programs/winedbg/debugger.h | 4 +++ programs/winedbg/info.c | 2 ++ programs/winedbg/memory.c | 14 ++++++--- programs/winedbg/winedbg.c | 24 +++++++++++++++ 8 files changed, 183 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index a1d3f97..46d62bc 100644 --- a/configure.ac +++ b/configure.ac @@ -104,6 +104,8 @@ AC_ARG_WITH(zlib, AS_HELP_STRING([--without-zlib],[do not use Zlib (data co AC_ARG_WITH(wine-tools,AS_HELP_STRING([--with-wine-tools=DIR],[use Wine tools from directory DIR])) AC_ARG_WITH(wine64, AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine in DIR for a Wow64 build])) +AC_ARG_WITH(udis86, AS_HELP_STRING([--without-udis86],[do not use the udis86 library(winedbg Intel disassembly style support)])) + AC_CANONICAL_HOST dnl check for out of tree build with unclean source tree @@ -1430,6 +1432,16 @@ then fi WINE_NOTICE_WITH(zlib,[test "x$Z_LIBS" = "x"],[libz ${notice_platform}development files not found, data compression won't be supported.]) +dnl **** Check for libudis86 **** +if test "$with_udis86" != xno +then + AC_CHECK_HEADERS(udis86.h, + [AC_CHECK_LIB(udis86,ud_init,[AC_DEFINE(HAVE_UDIS86,1,[Define to 1 if you have the `udis86' library (-ludis86).]) + AC_SUBST(UDIS86_LIBS,"-ludis86")], [UDIS86_LIBS=""])], [UDIS86_LIBS=""]) +fi +WINE_NOTICE_WITH(udis86,[test "x$UDIS86_LIBS" = "x"], + [libudis86 ${notice_platform}development files not found, winedbg Intel disassembly style won't be supported.]) + dnl **** Check for gettextpo **** if test "x$enable_tools" != xno then diff --git a/programs/winedbg/Makefile.in b/programs/winedbg/Makefile.in index 739c4eb..063e840 100644 --- a/programs/winedbg/Makefile.in +++ b/programs/winedbg/Makefile.in @@ -2,7 +2,7 @@ MODULE = winedbg.exe APPMODE = -mconsole IMPORTS = psapi dbghelp advapi32 DELAYIMPORTS = comdlg32 shell32 comctl32 user32 gdi32 -EXTRALIBS = $(POLL_LIBS) +EXTRALIBS = $(POLL_LIBS) $(UDIS86_LIBS) C_SRCS = \ be_arm.c \ diff --git a/programs/winedbg/db_disasm.c b/programs/winedbg/db_disasm.c index c745617..500fd49 100644 --- a/programs/winedbg/db_disasm.c +++ b/programs/winedbg/db_disasm.c @@ -62,10 +62,15 @@ * Instruction disassembler. */ +#include "config.h" #include "debugger.h" #ifdef __i386__ +#if HAVE_UDIS86 +#include +#endif + /* * Switch to disassemble 16-bit code. */ @@ -1308,6 +1313,8 @@ static void db_disasm_esc( ADDRESS64* addr, int inst, int short_addr, } } +static void be_i386_disasm_one_insn_att(ADDRESS64 *addr, int display); +static void be_i386_disasm_one_insn_intel(ADDRESS64 *addr, int display); /*********************************************************************** * disasm_one_insn @@ -1317,6 +1324,16 @@ static void db_disasm_esc( ADDRESS64* addr, int inst, int short_addr, */ void be_i386_disasm_one_insn(ADDRESS64 *addr, int display) { +#if HAVE_UDIS86 + if (disassembly_flavor_intel == get_disassembly_flavor()) + return be_i386_disasm_one_insn_intel(addr, display); + else +#endif + return be_i386_disasm_one_insn_att(addr, display); +} + +static void be_i386_disasm_one_insn_att(ADDRESS64 *addr, int display) +{ int inst; int size; int short_addr; @@ -1812,4 +1829,53 @@ void be_i386_disasm_one_insn(ADDRESS64 *addr, int display) } } } + +#if HAVE_UDIS86 +static void be_i386_disasm_one_insn_intel(ADDRESS64 *addr, int display) +{ + int len = 0; + ud_t ud_obj; + char buffer[16]; + + db_display = display; + + ud_init(&ud_obj); + ud_set_mode(&ud_obj, AddrModeFlat==addr->Mode? 32:16); + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + ud_set_pc(&ud_obj, addr->Offset); + ud_set_input_buffer(&ud_obj, buffer, sizeof(buffer)); + + dbg_read_memory(addr->Offset, buffer, sizeof(buffer)); + + len = ud_disassemble(&ud_obj); + if (!len) + { + dbg_printf("failed to disassemble\n"); + return; + } + + addr->Offset += len; + + if (db_display) + { + dbg_printf("%s ", ud_insn_asm(&ud_obj)); + if ((UD_Icall == ud_obj.mnemonic) || (UD_Ijmp == ud_obj.mnemonic)) + { + switch (ud_obj.operand[0].type) + { + case UD_OP_JIMM: + { + ADDRESS64 a; + a.Mode = addr->Mode; + a.Offset = addr->Offset + ud_obj.operand[0].lval.sdword; + print_address_symbol(&a, TRUE); + } + default: + break; + } + } + } +} +#endif /* HAVE_UDIS86 */ + #endif /* __i386__ */ diff --git a/programs/winedbg/db_disasm64.c b/programs/winedbg/db_disasm64.c index fe6a538..d957119 100644 --- a/programs/winedbg/db_disasm64.c +++ b/programs/winedbg/db_disasm64.c @@ -29,9 +29,16 @@ */ /* */ +#include "config.h" #include #include "debugger.h" +#if defined(__x86_64__) + +#if HAVE_UDIS86 +#include +#endif + #if defined(__GNUC__) && (__GNUC__ >= 3) static int (*db_printf)(const char* format, ...) __attribute__((format (printf,1,2))); #else @@ -1643,8 +1650,64 @@ db_disasm(db_addr_t loc, boolean_t altfmt) return (loc); } +#if HAVE_UDIS86 +static db_addr_t db_disasm_intel(db_addr_t addr) +{ + int len = 0; + ud_t ud_obj; + char buffer[16]; + + ud_init(&ud_obj); + ud_set_mode(&ud_obj, 64); + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + ud_set_pc(&ud_obj, addr); + ud_set_input_buffer(&ud_obj, buffer, sizeof(buffer)); + + dbg_read_memory(addr, buffer, sizeof(buffer)); + + len = ud_disassemble(&ud_obj); + if (!len) + { + dbg_printf("failed to disassemble\n"); + return addr; + } + + addr += len; + + if (db_printf == dbg_printf) + { + dbg_printf("%s ", ud_insn_asm(&ud_obj)); + if ((UD_Icall == ud_obj.mnemonic) || (UD_Ijmp == ud_obj.mnemonic)) + { + switch (ud_obj.operand[0].type) + { + case UD_OP_JIMM: + { + ADDRESS64 a; + a.Mode = AddrModeFlat; + a.Offset = addr + ud_obj.operand[0].lval.sdword; + print_address_symbol(&a, TRUE); + } + default: + break; + } + } + } + + return addr; +} +#endif /* HAVE_UDIS86 */ + void be_x86_64_disasm_one_insn(ADDRESS64 *addr, int display) { db_printf = display ? dbg_printf : no_printf; - addr->Offset = db_disasm(addr->Offset, TRUE); + +#if HAVE_UDIS86 + if (disassembly_flavor_intel == get_disassembly_flavor()) + addr->Offset = db_disasm_intel(addr->Offset, TRUE); + else +#endif + addr->Offset = db_disasm_att(addr->Offset); } + +#endif /*__x86_64__*/ diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index e8a4d73..9f0efe7 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -376,6 +376,7 @@ extern BOOL memory_disasm_one_insn(ADDRESS64* addr); extern char* memory_offset_to_string(char *str, DWORD64 offset, unsigned mode); extern void print_bare_address(const ADDRESS64* addr); extern void print_address(const ADDRESS64* addr, BOOLEAN with_line); +extern void print_address_symbol(const ADDRESS64* addr, BOOLEAN with_line); extern void print_basic(const struct dbg_lvalue* value, char format); /* source.c */ @@ -471,6 +472,9 @@ extern void dbg_set_option(const char*, const char*); extern void dbg_start_interactive(HANDLE hFile); extern void dbg_init_console(void); +enum disassembly_flavor_type {disassembly_flavor_att = 0, disassembly_flavor_intel}; +extern enum disassembly_flavor_type get_disassembly_flavor(void); + /* gdbproxy.c */ extern int gdb_main(int argc, char* argv[]); diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index 08ac938..f2dcc72 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -65,6 +65,8 @@ void print_help(void) " list disassemble [][,]", " show dir dir ", " set = set * = ", + " set !disassembly_flavor -- Set the disassembly flavor, the valid ", + " values are \"att\" and \"intel\", and the default value is \"att\".", " pass whatis", " info (see 'help info' for options)", diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c index 78a0493..42ba2a4 100644 --- a/programs/winedbg/memory.c +++ b/programs/winedbg/memory.c @@ -586,12 +586,13 @@ void print_bare_address(const ADDRESS64* addr) } } + /*********************************************************************** - * print_address + * print_address_symbol * * Print an 16- or 32-bit address, with the nearest symbol if any. */ -void print_address(const ADDRESS64* addr, BOOLEAN with_line) +void print_address_symbol(const ADDRESS64* addr, BOOLEAN with_line) { char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* si = (SYMBOL_INFO*)buffer; @@ -599,8 +600,6 @@ void print_address(const ADDRESS64* addr, BOOLEAN with_line) DWORD64 disp64; DWORD disp; - print_bare_address(addr); - si->SizeOfStruct = sizeof(*si); si->MaxNameLen = 256; if (!SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si)) return; @@ -620,6 +619,13 @@ void print_address(const ADDRESS64* addr, BOOLEAN with_line) } } +void print_address(const ADDRESS64* addr, BOOLEAN with_line) +{ + print_bare_address(addr); + + print_address_symbol(addr, with_line); +} + BOOL memory_disasm_one_insn(ADDRESS64* addr) { char ch; diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c index 11782fe..3e2812d 100644 --- a/programs/winedbg/winedbg.c +++ b/programs/winedbg/winedbg.c @@ -83,6 +83,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedbg); +#if HAVE_UDIS86 +static enum disassembly_flavor_type disassembly_flavor = disassembly_flavor_att; + +enum disassembly_flavor_type get_disassembly_flavor(void) +{ + return disassembly_flavor; +} +#endif + struct dbg_process* dbg_curr_process = NULL; struct dbg_thread* dbg_curr_thread = NULL; DWORD_PTR dbg_curr_tid = 0; @@ -523,6 +532,21 @@ void dbg_set_option(const char* option, const char* val) return; } } +#if HAVE_UDIS86 + else if (!strcasecmp(option, "disassembly_flavor")) + { + if (!val) + dbg_printf("Option: disassembly_flavor %s\n", + disassembly_flavor == disassembly_flavor_att ? "att":"intel"); + else if(!strcmp(val, "intel")) + disassembly_flavor = disassembly_flavor_intel; + else if(!strcmp(val, "att")) + disassembly_flavor = disassembly_flavor_att; + else + dbg_printf("Syntax: disassembly_flavor [att|intel]\n"); + + } +#endif else dbg_printf("Unknown option '%s'\n", option); } -- 1.9.1