aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog15
-rw-r--r--gdb/amd64-tdep.c56
-rw-r--r--gdb/disasm.c73
-rw-r--r--gdb/disasm.h12
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