diff options
-rw-r--r-- | gdb/ChangeLog | 15 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 56 | ||||
-rw-r--r-- | gdb/disasm.c | 73 | ||||
-rw-r--r-- | gdb/disasm.h | 12 |
4 files changed, 103 insertions, 53 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1bc88cd..6509b84 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,20 @@ 2010-05-06 Pedro Alves <pedro@codesourcery.com> + * 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. + +2010-05-06 Pedro Alves <pedro@codesourcery.com> + * remote.c (clear_threads_parsing_context): New. (remote_threads_info): Delete unused null_cleanup. Install a cleanup to clear the threads_parsing_context in case parsing diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 21d66c5..6336b7a 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -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 ATTRIBUTE_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, struct displaced_step_closure *dsc, /* 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. diff --git a/gdb/disasm.c b/gdb/disasm.c index 0e43b0f..a3fe89a 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -429,3 +429,76 @@ gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr, } 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 ATTRIBUTE_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); +} diff --git a/gdb/disasm.h b/gdb/disasm.h index c2f5ec3..e308985 100644 --- a/gdb/disasm.h +++ b/gdb/disasm.h @@ -37,4 +37,16 @@ extern void gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout, 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 |