summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/disasm.c202
1 files changed, 114 insertions, 88 deletions
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 2b65c6acbbb..981ab7e781a 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -170,101 +170,89 @@ compare_lines (const void *mle1p, const void *mle2p)
return val;
}
+/* Prints the instruction at PC into UIOUT and returns the length of the
+ printed instruction in bytes. */
+
static int
-dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
- struct disassemble_info * di,
- CORE_ADDR low, CORE_ADDR high,
- int how_many, int flags, struct ui_file *stb,
- CORE_ADDR *end_pc)
+dump_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
+ struct disassemble_info * di, CORE_ADDR pc, int flags,
+ struct ui_file *stb)
{
- int num_displayed = 0;
- CORE_ADDR pc;
-
/* parts of the symbolic representation of the address */
int unmapped;
int offset;
int line;
+ int size;
struct cleanup *ui_out_chain;
+ char *filename = NULL;
+ char *name = NULL;
+
+ ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+ if ((flags & DISASSEMBLY_OMIT_PC) == 0)
+ ui_out_text (uiout, pc_prefix (pc));
+ ui_out_field_core_addr (uiout, "address", gdbarch, pc);
- for (pc = low; pc < high;)
+ if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
+ &line, &unmapped))
{
- char *filename = NULL;
- char *name = NULL;
+ /* We don't care now about line, filename and unmapped. But we might in
+ the future. */
+ ui_out_text (uiout, " <");
+ if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
+ ui_out_field_string (uiout, "func-name", name);
+ ui_out_text (uiout, "+");
+ ui_out_field_int (uiout, "offset", offset);
+ ui_out_text (uiout, ">:\t");
+ }
+ else
+ ui_out_text (uiout, ":\t");
- QUIT;
- if (how_many >= 0)
- {
- if (num_displayed >= how_many)
- break;
- else
- num_displayed++;
- }
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+ if (filename != NULL)
+ xfree (filename);
+ if (name != NULL)
+ xfree (name);
+
+ ui_file_rewind (stb);
+ if (flags & DISASSEMBLY_RAW_INSN)
+ {
+ CORE_ADDR end_pc;
+ bfd_byte data;
+ int status;
+ const char *spacer = "";
+
+ /* Build the opcodes using a temporary stream so we can
+ write them out in a single go for the MI. */
+ struct ui_file *opcode_stream = mem_fileopen ();
+ struct cleanup *cleanups =
+ make_cleanup_ui_file_delete (opcode_stream);
- if ((flags & DISASSEMBLY_OMIT_PC) == 0)
- ui_out_text (uiout, pc_prefix (pc));
- ui_out_field_core_addr (uiout, "address", gdbarch, pc);
+ size = gdbarch_print_insn (gdbarch, pc, di);
+ end_pc = pc + size;
- if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
- &line, &unmapped))
+ for (;pc < end_pc; ++pc)
{
- /* We don't care now about line, filename and
- unmapped. But we might in the future. */
- ui_out_text (uiout, " <");
- if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
- ui_out_field_string (uiout, "func-name", name);
- ui_out_text (uiout, "+");
- ui_out_field_int (uiout, "offset", offset);
- ui_out_text (uiout, ">:\t");
+ status = (*di->read_memory_func) (pc, &data, 1, di);
+ if (status != 0)
+ (*di->memory_error_func) (status, pc, di);
+ fprintf_filtered (opcode_stream, "%s%02x",
+ spacer, (unsigned) data);
+ spacer = " ";
}
- else
- ui_out_text (uiout, ":\t");
-
- if (filename != NULL)
- xfree (filename);
- if (name != NULL)
- xfree (name);
-
- ui_file_rewind (stb);
- if (flags & DISASSEMBLY_RAW_INSN)
- {
- CORE_ADDR old_pc = pc;
- bfd_byte data;
- int status;
- const char *spacer = "";
-
- /* Build the opcodes using a temporary stream so we can
- write them out in a single go for the MI. */
- struct ui_file *opcode_stream = mem_fileopen ();
- struct cleanup *cleanups =
- make_cleanup_ui_file_delete (opcode_stream);
-
- pc += gdbarch_print_insn (gdbarch, pc, di);
- for (;old_pc < pc; old_pc++)
- {
- status = (*di->read_memory_func) (old_pc, &data, 1, di);
- if (status != 0)
- (*di->memory_error_func) (status, old_pc, di);
- fprintf_filtered (opcode_stream, "%s%02x",
- spacer, (unsigned) data);
- spacer = " ";
- }
- ui_out_field_stream (uiout, "opcodes", opcode_stream);
- ui_out_text (uiout, "\t");
-
- do_cleanups (cleanups);
- }
- else
- pc += gdbarch_print_insn (gdbarch, pc, di);
- ui_out_field_stream (uiout, "inst", stb);
- ui_file_rewind (stb);
- do_cleanups (ui_out_chain);
- ui_out_text (uiout, "\n");
+ ui_out_field_stream (uiout, "opcodes", opcode_stream);
+ ui_out_text (uiout, "\t");
+
+ do_cleanups (cleanups);
}
+ else
+ size = gdbarch_print_insn (gdbarch, pc, di);
+
+ ui_out_field_stream (uiout, "inst", stb);
+ ui_file_rewind (stb);
+ do_cleanups (ui_out_chain);
+ ui_out_text (uiout, "\n");
- if (end_pc != NULL)
- *end_pc = pc;
- return num_displayed;
+ return size;
}
/* The idea here is to present a source-O-centric view of a
@@ -359,6 +347,8 @@ do_mixed_source_and_assembly_deprecated
for (i = 0; i < newlines; i++)
{
+ CORE_ADDR pc;
+
/* Print out everything from next_line to the current line. */
if (mle[i].line >= next_line)
{
@@ -412,9 +402,21 @@ do_mixed_source_and_assembly_deprecated
= make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
}
- num_displayed += dump_insns (gdbarch, uiout, di,
- mle[i].start_pc, mle[i].end_pc,
- how_many, flags, stb, NULL);
+ pc = mle[i].start_pc;
+ while (pc < mle[i].end_pc && (how_many < 0 || num_displayed < how_many))
+ {
+ int size;
+
+ size = dump_insn (gdbarch, uiout, di, pc, flags, stb);
+ if (size <= 0)
+ break;
+
+ num_displayed += 1;
+ pc += size;
+
+ /* Allow user to bail out with ^C. */
+ QUIT;
+ }
/* When we've reached the end of the mle array, or we've seen the last
assembly range for this source line, close out the list/tuple. */
@@ -672,9 +674,21 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
end_pc = min (sal.end, high);
else
end_pc = pc + 1;
- num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
- how_many, flags, stb, &end_pc);
- pc = end_pc;
+
+ while (pc < end_pc && (how_many < 0 || num_displayed < how_many))
+ {
+ int size;
+
+ size = dump_insn (gdbarch, uiout, di, pc, flags, stb);
+ if (size <= 0)
+ break;
+
+ num_displayed += 1;
+ pc += size;
+
+ /* Allow user to bail out with ^C. */
+ QUIT;
+ }
if (how_many >= 0 && num_displayed >= how_many)
break;
@@ -693,13 +707,25 @@ do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
CORE_ADDR low, CORE_ADDR high,
int how_many, int flags, struct ui_file *stb)
{
- int num_displayed = 0;
struct cleanup *ui_out_chain;
+ int num_displayed = 0;
ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
- num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
- flags, stb, NULL);
+ while (low < high && (how_many < 0 || num_displayed < how_many))
+ {
+ int size;
+
+ size = dump_insn (gdbarch, uiout, di, low, flags, stb);
+ if (size <= 0)
+ break;
+
+ num_displayed += 1;
+ low += size;
+
+ /* Allow user to bail out with ^C. */
+ QUIT;
+ }
do_cleanups (ui_out_chain);
}