From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18922 invoked by alias); 30 Apr 2010 18:54:41 -0000 Received: (qmail 18747 invoked by uid 22791); 30 Apr 2010 18:54:35 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 30 Apr 2010 18:54:28 +0000 Received: (qmail 31803 invoked from network); 30 Apr 2010 18:54:26 -0000 Received: from unknown (HELO orlando.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 30 Apr 2010 18:54:26 -0000 From: Pedro Alves To: gdb-patches@sourceware.org, Doug Evans Subject: Move amd64_insn_length to common code Date: Fri, 30 Apr 2010 18:54:00 -0000 User-Agent: KMail/1.12.2 (Linux/2.6.31-20-generic; KDE/4.3.2; x86_64; ; ) MIME-Version: 1.0 Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <201004301954.22310.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg01014.txt.bz2 I'll be posting a patch that adds code to i386-tdep.c that will need to know the length of an instruction. We already have code for that in amd64-tdep.c. I don't suppose you see a problem with moving it to a more common/reusable place? -- Pedro Alves 2010-04-30 Pedro Alves gdb/ * amd64-tdep.c: Include disasm.h. (amd64_insn_length_fprintf, amd64_insn_length_init_dis) (amd64_insn_length): Moved to disasm.c and renamed. (fixup_riprel): Adjust. * disasm.c (do_ui_file_delete): New. (gdb_insn_length): New. (gdb_buffered_insn_length_fprintf) (gdb_buffered_insn_length_init_dis) (gdb_buffered_insn_length): New, moved from amd64-tdep.c, and renamed. * disasm.h (gdb_insn_length): Declare. (gdb_buffered_insn_length): Declare. --- gdb/amd64-tdep.c | 56 ++---------------------------------------- gdb/disasm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/disasm.h | 12 +++++++++ 3 files changed, 88 insertions(+), 53 deletions(-) Index: src/gdb/amd64-tdep.c =================================================================== --- src.orig/gdb/amd64-tdep.c 2010-04-30 17:58:22.000000000 +0100 +++ src/gdb/amd64-tdep.c 2010-04-30 18:11:34.000000000 +0100 @@ -36,7 +36,7 @@ #include "regcache.h" #include "regset.h" #include "symfile.h" - +#include "disasm.h" #include "gdb_assert.h" #include "amd64-tdep.h" @@ -1022,57 +1022,6 @@ amd64_skip_prefixes (gdb_byte *insn) return insn; } -/* fprintf-function for amd64_insn_length. - This function is a nop, we don't want to print anything, we just want to - compute the length of the insn. */ - -static int ATTR_FORMAT (printf, 2, 3) -amd64_insn_length_fprintf (void *stream, const char *format, ...) -{ - return 0; -} - -/* Initialize a struct disassemble_info for amd64_insn_length. */ - -static void -amd64_insn_length_init_dis (struct gdbarch *gdbarch, - struct disassemble_info *di, - const gdb_byte *insn, int max_len, - CORE_ADDR addr) -{ - init_disassemble_info (di, NULL, amd64_insn_length_fprintf); - - /* init_disassemble_info installs buffer_read_memory, etc. - so we don't need to do that here. - The cast is necessary until disassemble_info is const-ified. */ - di->buffer = (gdb_byte *) insn; - di->buffer_length = max_len; - di->buffer_vma = addr; - - di->arch = gdbarch_bfd_arch_info (gdbarch)->arch; - di->mach = gdbarch_bfd_arch_info (gdbarch)->mach; - di->endian = gdbarch_byte_order (gdbarch); - di->endian_code = gdbarch_byte_order_for_code (gdbarch); - - disassemble_init_for_target (di); -} - -/* Return the length in bytes of INSN. - MAX_LEN is the size of the buffer containing INSN. - libopcodes currently doesn't export a utility to compute the - instruction length, so use the disassembler until then. */ - -static int -amd64_insn_length (struct gdbarch *gdbarch, - const gdb_byte *insn, int max_len, CORE_ADDR addr) -{ - struct disassemble_info di; - - amd64_insn_length_init_dis (gdbarch, &di, insn, max_len, addr); - - return gdbarch_print_insn (gdbarch, addr, &di); -} - /* Return an integer register (other than RSP) that is unused as an input operand in INSN. In order to not require adding a rex prefix if the insn doesn't already @@ -1238,7 +1187,8 @@ fixup_riprel (struct gdbarch *gdbarch, s /* Compute the rip-relative address. */ disp = extract_signed_integer (insn, sizeof (int32_t), byte_order); - insn_length = amd64_insn_length (gdbarch, dsc->insn_buf, dsc->max_len, from); + insn_length = gdb_buffered_insn_length (gdbarch, dsc->insn_buf, + dsc->max_len, from); rip_base = from + insn_length; /* We need a register to hold the address. Index: src/gdb/disasm.c =================================================================== --- src.orig/gdb/disasm.c 2010-04-30 17:58:22.000000000 +0100 +++ src/gdb/disasm.c 2010-04-30 19:52:45.000000000 +0100 @@ -429,3 +429,76 @@ gdb_print_insn (struct gdbarch *gdbarch, } return length; } + +static void +do_ui_file_delete (void *arg) +{ + ui_file_delete (arg); +} + +/* Return the length in bytes of the instruction at address MEMADDR in + debugged memory. */ + +int +gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + static struct ui_file *null_stream = NULL; + + /* Dummy file descriptor for the disassembler. */ + if (!null_stream) + { + null_stream = ui_file_new (); + make_final_cleanup (do_ui_file_delete, null_stream); + } + + return gdb_print_insn (gdbarch, addr, null_stream, NULL); +} + +/* fprintf-function for gdb_buffered_insn_length. This function is a + nop, we don't want to print anything, we just want to compute the + length of the insn. */ + +static int ATTR_FORMAT (printf, 2, 3) +gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...) +{ + return 0; +} + +/* Initialize a struct disassemble_info for gdb_buffered_insn_length. */ + +static void +gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch, + struct disassemble_info *di, + const gdb_byte *insn, int max_len, + CORE_ADDR addr) +{ + init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf); + + /* init_disassemble_info installs buffer_read_memory, etc. + so we don't need to do that here. + The cast is necessary until disassemble_info is const-ified. */ + di->buffer = (gdb_byte *) insn; + di->buffer_length = max_len; + di->buffer_vma = addr; + + di->arch = gdbarch_bfd_arch_info (gdbarch)->arch; + di->mach = gdbarch_bfd_arch_info (gdbarch)->mach; + di->endian = gdbarch_byte_order (gdbarch); + di->endian_code = gdbarch_byte_order_for_code (gdbarch); + + disassemble_init_for_target (di); +} + +/* Return the length in bytes of INSN. MAX_LEN is the size of the + buffer containing INSN. */ + +int +gdb_buffered_insn_length (struct gdbarch *gdbarch, + const gdb_byte *insn, int max_len, CORE_ADDR addr) +{ + struct disassemble_info di; + + gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr); + + return gdbarch_print_insn (gdbarch, addr, &di); +} Index: src/gdb/disasm.h =================================================================== --- src.orig/gdb/disasm.h 2010-04-30 17:58:22.000000000 +0100 +++ src/gdb/disasm.h 2010-04-30 18:15:20.000000000 +0100 @@ -37,4 +37,16 @@ extern void gdb_disassembly (struct gdba extern int gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr, struct ui_file *stream, int *branch_delay_insns); +/* Return the length in bytes of the instruction at address MEMADDR in + debugged memory. */ + +extern int gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR memaddr); + +/* Return the length in bytes of INSN, originally at MEMADDR. MAX_LEN + is the size of the buffer containing INSN. */ + +extern int gdb_buffered_insn_length (struct gdbarch *gdbarch, + const gdb_byte *insn, int max_len, + CORE_ADDR memaddr); + #endif