This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
RFC/RFA: Move new disassembler to libgdb proper
- From: Fernando Nasser <fnasser at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 26 Sep 2002 19:14:02 -0400
- Subject: RFC/RFA: Move new disassembler to libgdb proper
- Organization: Red Hat Canada
This is the first step in the disassembler unification.
As Elena mentioned, we want to use a single disassembler code.
Next step is to make the CLI use this one and get rid of the old one in
printcmd.c.
2002-09-22 Fernando Nasser <fnasser@redhat.com>
* disasm.c: New file.
* disasm.h: New file.
* mi/mi-cmd-disas.c (gdb_dis_asm_read_memory): Moved to disasm.c.
(compare_lines): Ditto.
(dump_insns): Ditto.
(do_mixed_source_and_assembly): Ditto.
(do_assembly_only): Ditto.
(do_disassembly): Renamed to gdb_disassembly and moved to disasm.c.
* Makefile.in: Add new files. Reorder SFILES list. Update dependencies. Include
libgdb.a later in the insight executable.
--
Fernando Nasser
Red Hat Canada Ltd. E-Mail: fnasser@redhat.com
2323 Yonge Street, Suite #300
Toronto, Ontario M4P 2C9
Index: mi/mi-cmd-disas.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-disas.c,v
retrieving revision 1.19
diff -c -p -r1.19 mi-cmd-disas.c
*** mi/mi-cmd-disas.c 26 Sep 2002 18:35:21 -0000 1.19
--- mi/mi-cmd-disas.c 26 Sep 2002 22:37:24 -0000
***************
*** 24,376 ****
#include "value.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
- #include "ui-out.h"
#include "gdb_string.h"
!
! /* Disassemble functions. FIXME: these do not really belong here. We
! should get rid of all the duplicate code in gdb that does the same
! thing: disassemble_command() and the gdbtk variation. */
!
! /* This Structure is used in mi_cmd_disassemble.
! We need a different sort of line table from the normal one cuz we can't
! depend upon implicit line-end pc's for lines to do the
! reordering in this function. */
!
! struct dis_line_entry
! {
! int line;
! CORE_ADDR start_pc;
! CORE_ADDR end_pc;
! };
!
! /* This variable determines where memory used for disassembly is read from. */
! int gdb_disassemble_from_exec = -1;
!
! /* This is the memory_read_func for gdb_disassemble when we are
! disassembling from the exec file. */
! static int
! gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
! unsigned int len, disassemble_info * info)
! {
! extern struct target_ops exec_ops;
! int res;
!
! errno = 0;
! res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops);
!
! if (res == len)
! return 0;
! else if (errno == 0)
! return EIO;
! else
! return errno;
! }
!
! static int
! compare_lines (const PTR mle1p, const PTR mle2p)
! {
! struct dis_line_entry *mle1, *mle2;
! int val;
!
! mle1 = (struct dis_line_entry *) mle1p;
! mle2 = (struct dis_line_entry *) mle2p;
!
! val = mle1->line - mle2->line;
!
! if (val != 0)
! return val;
!
! return mle1->start_pc - mle2->start_pc;
! }
!
! static int
! dump_insns (disassemble_info * di, CORE_ADDR low, CORE_ADDR high,
! int how_many, struct ui_stream *stb)
! {
! int num_displayed = 0;
! CORE_ADDR pc;
!
! /* parts of the symbolic representation of the address */
! int unmapped;
! char *filename = NULL;
! char *name = NULL;
! int offset;
! int line;
!
! for (pc = low; pc < high;)
! {
! QUIT;
! if (how_many >= 0)
! {
! if (num_displayed >= how_many)
! break;
! else
! num_displayed++;
! }
! ui_out_tuple_begin (uiout, NULL);
! ui_out_field_core_addr (uiout, "address", pc);
!
! if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
! &line, &unmapped))
! {
! /* We don't care now about line, filename and
! unmapped. But we might in the future. */
! ui_out_text (uiout, " <");
! ui_out_field_string (uiout, "func-name", name);
! ui_out_text (uiout, "+");
! ui_out_field_int (uiout, "offset", offset);
! ui_out_text (uiout, ">:\t");
! }
! if (filename != NULL)
! xfree (filename);
! if (name != NULL)
! xfree (name);
!
! ui_file_rewind (stb->stream);
! pc += TARGET_PRINT_INSN (pc, di);
! ui_out_field_stream (uiout, "inst", stb);
! ui_file_rewind (stb->stream);
! ui_out_tuple_end (uiout);
! ui_out_text (uiout, "\n");
! }
! return num_displayed;
! }
!
! /* The idea here is to present a source-O-centric view of a
! function to the user. This means that things are presented
! in source order, with (possibly) out of order assembly
! immediately following. */
! static void
! do_mixed_source_and_assembly (struct disassemble_info *di, int nlines,
! struct linetable_entry *le,
! CORE_ADDR low, CORE_ADDR high,
! struct symtab *symtab,
! int how_many, struct ui_stream *stb)
! {
! int newlines = 0;
! struct dis_line_entry *mle;
! struct symtab_and_line sal;
! int i;
! int out_of_order = 0;
! int next_line = 0;
! CORE_ADDR pc;
! int num_displayed = 0;
!
! mle = (struct dis_line_entry *) alloca (nlines
! * sizeof (struct dis_line_entry));
!
! /* Copy linetable entries for this function into our data
! structure, creating end_pc's and setting out_of_order as
! appropriate. */
!
! /* First, skip all the preceding functions. */
!
! for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
!
! /* Now, copy all entries before the end of this function. */
!
! for (; i < nlines - 1 && le[i].pc < high; i++)
! {
! if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
! continue; /* Ignore duplicates */
!
! /* Skip any end-of-function markers. */
! if (le[i].line == 0)
! continue;
!
! mle[newlines].line = le[i].line;
! if (le[i].line > le[i + 1].line)
! out_of_order = 1;
! mle[newlines].start_pc = le[i].pc;
! mle[newlines].end_pc = le[i + 1].pc;
! newlines++;
! }
!
! /* If we're on the last line, and it's part of the function,
! then we need to get the end pc in a special way. */
!
! if (i == nlines - 1 && le[i].pc < high)
! {
! mle[newlines].line = le[i].line;
! mle[newlines].start_pc = le[i].pc;
! sal = find_pc_line (le[i].pc, 0);
! mle[newlines].end_pc = sal.end;
! newlines++;
! }
!
! /* Now, sort mle by line #s (and, then by addresses within
! lines). */
!
! if (out_of_order)
! qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
!
! /* Now, for each line entry, emit the specified lines (unless
! they have been emitted before), followed by the assembly code
! for that line. */
!
! ui_out_list_begin (uiout, "asm_insns");
!
! for (i = 0; i < newlines; i++)
! {
! int close_list = 1;
! /* Print out everything from next_line to the current line. */
! if (mle[i].line >= next_line)
! {
! if (next_line != 0)
! {
! /* Just one line to print. */
! if (next_line == mle[i].line)
! {
! ui_out_tuple_begin (uiout, "src_and_asm_line");
! print_source_lines (symtab, next_line, mle[i].line + 1, 0);
! }
! else
! {
! /* Several source lines w/o asm instructions associated. */
! for (; next_line < mle[i].line; next_line++)
! {
! ui_out_tuple_begin (uiout, "src_and_asm_line");
! print_source_lines (symtab, next_line, next_line + 1,
! 0);
! ui_out_list_begin (uiout, "line_asm_insn");
! ui_out_list_end (uiout);
! ui_out_tuple_end (uiout);
! }
! /* Print the last line and leave list open for
! asm instructions to be added. */
! ui_out_tuple_begin (uiout, "src_and_asm_line");
! print_source_lines (symtab, next_line, mle[i].line + 1, 0);
! }
! }
! else
! {
! ui_out_tuple_begin (uiout, "src_and_asm_line");
! print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
! }
!
! next_line = mle[i].line + 1;
! ui_out_list_begin (uiout, "line_asm_insn");
! /* Don't close the list if the lines are not in order. */
! if (i < (newlines - 1) && mle[i + 1].line <= mle[i].line)
! close_list = 0;
! }
!
! num_displayed += dump_insns (di, mle[i].start_pc, mle[i].end_pc,
! how_many, stb);
! if (close_list)
! {
! ui_out_list_end (uiout);
! ui_out_tuple_end (uiout);
! ui_out_text (uiout, "\n");
! close_list = 0;
! }
! if (how_many >= 0)
! if (num_displayed >= how_many)
! break;
! }
! ui_out_list_end (uiout);
! }
!
!
! static void
! do_assembly_only (disassemble_info * di, CORE_ADDR low,
! CORE_ADDR high, int how_many, struct ui_stream *stb)
! {
! int num_displayed = 0;
!
! ui_out_list_begin (uiout, "asm_insns");
!
! num_displayed = dump_insns (di, low, high, how_many, stb);
!
! ui_out_list_end (uiout);
! }
!
! enum mi_cmd_result
! do_disassembly (char *file_string,
! int line_num,
! int mixed_source_and_assembly,
! int how_many, CORE_ADDR low, CORE_ADDR high)
! {
! static disassemble_info di;
! static int di_initialized;
! /* To collect the instruction outputted from opcodes. */
! static struct ui_stream *stb = NULL;
! struct symtab *symtab = NULL;
! struct linetable_entry *le = NULL;
! int nlines = -1;
!
! if (!di_initialized)
! {
! /* We don't add a cleanup for this, because the allocation of
! the stream is done once only for each gdb run, and we need to
! keep it around until the end. Hopefully there won't be any
! errors in the init code below, that make this function bail
! out. */
! stb = ui_out_stream_new (uiout);
! INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
! (fprintf_ftype) fprintf_unfiltered);
! di.flavour = bfd_target_unknown_flavour;
! di.memory_error_func = dis_asm_memory_error;
! di.print_address_func = dis_asm_print_address;
! di_initialized = 1;
! }
!
! di.mach = TARGET_PRINT_INSN_INFO->mach;
! if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
! di.endian = BFD_ENDIAN_BIG;
! else
! di.endian = BFD_ENDIAN_LITTLE;
!
! /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
! determine whether or not to do disassembly from target memory or from the
! exec file:
!
! If we're debugging a local process, read target memory, instead of the
! exec file. This makes disassembly of functions in shared libs work
! correctly. Also, read target memory if we are debugging native threads.
!
! Else, we're debugging a remote process, and should disassemble from the
! exec file for speed. However, this is no good if the target modifies its
! code (for relocation, or whatever). */
!
! if (gdb_disassemble_from_exec == -1)
! {
! if (strcmp (target_shortname, "child") == 0
! || strcmp (target_shortname, "procfs") == 0
! || strcmp (target_shortname, "vxprocess") == 0
! || strstr (target_shortname, "-threads") != NULL)
! gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */
! else
! gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */
! }
!
! if (gdb_disassemble_from_exec)
! di.read_memory_func = gdb_dis_asm_read_memory;
! else
! di.read_memory_func = dis_asm_read_memory;
!
! /* Assume symtab is valid for whole PC range */
! symtab = find_pc_symtab (low);
!
! if (symtab != NULL && symtab->linetable != NULL)
! {
! /* Convert the linetable to a bunch of my_line_entry's. */
! le = symtab->linetable->item;
! nlines = symtab->linetable->nitems;
! }
!
! if (!mixed_source_and_assembly || nlines <= 0
! || symtab == NULL || symtab->linetable == NULL)
! do_assembly_only (&di, low, high, how_many, stb);
!
! else if (mixed_source_and_assembly)
! do_mixed_source_and_assembly (&di, nlines, le, low,
! high, symtab, how_many, stb);
!
! gdb_flush (gdb_stdout);
!
! return MI_CMD_DONE;
! }
/* The arguments to be passed on the command line and parsed here are:
--- 24,31 ----
#include "value.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
#include "gdb_string.h"
! #include "disasm.h"
/* The arguments to be passed on the command line and parsed here are:
*************** mi_cmd_disassemble (char *command, char
*** 498,505 ****
error ("mi_cmd_disassemble: No function contains specified address");
}
! retval = do_disassembly (file_string,
! line_num,
! mixed_source_and_assembly, how_many, low, high);
! return retval;
}
--- 153,161 ----
error ("mi_cmd_disassemble: No function contains specified address");
}
! gdb_disassembly (file_string,
! line_num,
! mixed_source_and_assembly, how_many, low, high);
!
! return MI_CMD_DONE;
}
Index: disasm.c
===================================================================
RCS file: disasm.c
diff -N disasm.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- disasm.c 26 Sep 2002 22:52:16 -0000
***************
*** 0 ****
--- 1,371 ----
+ /* Disassemble support for GDB.
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+ #include "defs.h"
+ #include "target.h"
+ #include "value.h"
+ #include "ui-out.h"
+ #include "gdb_string.h"
+
+ #include "disasm.h"
+
+ /* Disassemble functions.
+ FIXME: We should get rid of all the duplicate code in gdb that does
+ the same thing: disassemble_command() and the gdbtk variation. */
+
+ /* This Structure is used to store line number information.
+ We need a different sort of line table from the normal one cuz we can't
+ depend upon implicit line-end pc's for lines to do the
+ reordering in this function. */
+
+ struct dis_line_entry
+ {
+ int line;
+ CORE_ADDR start_pc;
+ CORE_ADDR end_pc;
+ };
+
+ /* This variable determines where memory used for disassembly is read from. */
+ int gdb_disassemble_from_exec = -1;
+
+ /* This is the memory_read_func for gdb_disassemble when we are
+ disassembling from the exec file. */
+ static int
+ gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
+ unsigned int len, disassemble_info * info)
+ {
+ extern struct target_ops exec_ops;
+ int res;
+
+ errno = 0;
+ res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops);
+
+ if (res == len)
+ return 0;
+ else if (errno == 0)
+ return EIO;
+ else
+ return errno;
+ }
+
+ static int
+ compare_lines (const PTR mle1p, const PTR mle2p)
+ {
+ struct dis_line_entry *mle1, *mle2;
+ int val;
+
+ mle1 = (struct dis_line_entry *) mle1p;
+ mle2 = (struct dis_line_entry *) mle2p;
+
+ val = mle1->line - mle2->line;
+
+ if (val != 0)
+ return val;
+
+ return mle1->start_pc - mle2->start_pc;
+ }
+
+ static int
+ dump_insns (disassemble_info * di, CORE_ADDR low, CORE_ADDR high,
+ int how_many, struct ui_stream *stb)
+ {
+ int num_displayed = 0;
+ CORE_ADDR pc;
+
+ /* parts of the symbolic representation of the address */
+ int unmapped;
+ char *filename = NULL;
+ char *name = NULL;
+ int offset;
+ int line;
+
+ for (pc = low; pc < high;)
+ {
+ QUIT;
+ if (how_many >= 0)
+ {
+ if (num_displayed >= how_many)
+ break;
+ else
+ num_displayed++;
+ }
+ ui_out_tuple_begin (uiout, NULL);
+ ui_out_field_core_addr (uiout, "address", pc);
+
+ if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
+ &line, &unmapped))
+ {
+ /* We don't care now about line, filename and
+ unmapped. But we might in the future. */
+ ui_out_text (uiout, " <");
+ ui_out_field_string (uiout, "func-name", name);
+ ui_out_text (uiout, "+");
+ ui_out_field_int (uiout, "offset", offset);
+ ui_out_text (uiout, ">:\t");
+ }
+ if (filename != NULL)
+ xfree (filename);
+ if (name != NULL)
+ xfree (name);
+
+ ui_file_rewind (stb->stream);
+ pc += TARGET_PRINT_INSN (pc, di);
+ ui_out_field_stream (uiout, "inst", stb);
+ ui_file_rewind (stb->stream);
+ ui_out_tuple_end (uiout);
+ ui_out_text (uiout, "\n");
+ }
+ return num_displayed;
+ }
+
+ /* The idea here is to present a source-O-centric view of a
+ function to the user. This means that things are presented
+ in source order, with (possibly) out of order assembly
+ immediately following. */
+ static void
+ do_mixed_source_and_assembly (struct disassemble_info *di, int nlines,
+ struct linetable_entry *le,
+ CORE_ADDR low, CORE_ADDR high,
+ struct symtab *symtab,
+ int how_many, struct ui_stream *stb)
+ {
+ int newlines = 0;
+ struct dis_line_entry *mle;
+ struct symtab_and_line sal;
+ int i;
+ int out_of_order = 0;
+ int next_line = 0;
+ CORE_ADDR pc;
+ int num_displayed = 0;
+
+ mle = (struct dis_line_entry *) alloca (nlines
+ * sizeof (struct dis_line_entry));
+
+ /* Copy linetable entries for this function into our data
+ structure, creating end_pc's and setting out_of_order as
+ appropriate. */
+
+ /* First, skip all the preceding functions. */
+
+ for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
+
+ /* Now, copy all entries before the end of this function. */
+
+ for (; i < nlines - 1 && le[i].pc < high; i++)
+ {
+ if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
+ continue; /* Ignore duplicates */
+
+ /* Skip any end-of-function markers. */
+ if (le[i].line == 0)
+ continue;
+
+ mle[newlines].line = le[i].line;
+ if (le[i].line > le[i + 1].line)
+ out_of_order = 1;
+ mle[newlines].start_pc = le[i].pc;
+ mle[newlines].end_pc = le[i + 1].pc;
+ newlines++;
+ }
+
+ /* If we're on the last line, and it's part of the function,
+ then we need to get the end pc in a special way. */
+
+ if (i == nlines - 1 && le[i].pc < high)
+ {
+ mle[newlines].line = le[i].line;
+ mle[newlines].start_pc = le[i].pc;
+ sal = find_pc_line (le[i].pc, 0);
+ mle[newlines].end_pc = sal.end;
+ newlines++;
+ }
+
+ /* Now, sort mle by line #s (and, then by addresses within
+ lines). */
+
+ if (out_of_order)
+ qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
+
+ /* Now, for each line entry, emit the specified lines (unless
+ they have been emitted before), followed by the assembly code
+ for that line. */
+
+ ui_out_list_begin (uiout, "asm_insns");
+
+ for (i = 0; i < newlines; i++)
+ {
+ int close_list = 1;
+ /* Print out everything from next_line to the current line. */
+ if (mle[i].line >= next_line)
+ {
+ if (next_line != 0)
+ {
+ /* Just one line to print. */
+ if (next_line == mle[i].line)
+ {
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ }
+ else
+ {
+ /* Several source lines w/o asm instructions associated. */
+ for (; next_line < mle[i].line; next_line++)
+ {
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, next_line + 1,
+ 0);
+ ui_out_list_begin (uiout, "line_asm_insn");
+ ui_out_list_end (uiout);
+ ui_out_tuple_end (uiout);
+ }
+ /* Print the last line and leave list open for
+ asm instructions to be added. */
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ }
+ }
+ else
+ {
+ ui_out_tuple_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
+ }
+
+ next_line = mle[i].line + 1;
+ ui_out_list_begin (uiout, "line_asm_insn");
+ /* Don't close the list if the lines are not in order. */
+ if (i < (newlines - 1) && mle[i + 1].line <= mle[i].line)
+ close_list = 0;
+ }
+
+ num_displayed += dump_insns (di, mle[i].start_pc, mle[i].end_pc,
+ how_many, stb);
+ if (close_list)
+ {
+ ui_out_list_end (uiout);
+ ui_out_tuple_end (uiout);
+ ui_out_text (uiout, "\n");
+ close_list = 0;
+ }
+ if (how_many >= 0)
+ if (num_displayed >= how_many)
+ break;
+ }
+ ui_out_list_end (uiout);
+ }
+
+
+ static void
+ do_assembly_only (disassemble_info * di, CORE_ADDR low,
+ CORE_ADDR high, int how_many, struct ui_stream *stb)
+ {
+ int num_displayed = 0;
+
+ ui_out_list_begin (uiout, "asm_insns");
+
+ num_displayed = dump_insns (di, low, high, how_many, stb);
+
+ ui_out_list_end (uiout);
+ }
+
+ void
+ gdb_disassembly (char *file_string,
+ int line_num,
+ int mixed_source_and_assembly,
+ int how_many, CORE_ADDR low, CORE_ADDR high)
+ {
+ static disassemble_info di;
+ static int di_initialized;
+ /* To collect the instruction outputted from opcodes. */
+ static struct ui_stream *stb = NULL;
+ struct symtab *symtab = NULL;
+ struct linetable_entry *le = NULL;
+ int nlines = -1;
+
+ if (!di_initialized)
+ {
+ /* We don't add a cleanup for this, because the allocation of
+ the stream is done once only for each gdb run, and we need to
+ keep it around until the end. Hopefully there won't be any
+ errors in the init code below, that make this function bail
+ out. */
+ stb = ui_out_stream_new (uiout);
+ INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
+ (fprintf_ftype) fprintf_unfiltered);
+ di.flavour = bfd_target_unknown_flavour;
+ di.memory_error_func = dis_asm_memory_error;
+ di.print_address_func = dis_asm_print_address;
+ di_initialized = 1;
+ }
+
+ di.mach = TARGET_PRINT_INSN_INFO->mach;
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ di.endian = BFD_ENDIAN_BIG;
+ else
+ di.endian = BFD_ENDIAN_LITTLE;
+
+ /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
+ determine whether or not to do disassembly from target memory or from the
+ exec file:
+
+ If we're debugging a local process, read target memory, instead of the
+ exec file. This makes disassembly of functions in shared libs work
+ correctly. Also, read target memory if we are debugging native threads.
+
+ Else, we're debugging a remote process, and should disassemble from the
+ exec file for speed. However, this is no good if the target modifies its
+ code (for relocation, or whatever). */
+
+ if (gdb_disassemble_from_exec == -1)
+ {
+ if (strcmp (target_shortname, "child") == 0
+ || strcmp (target_shortname, "procfs") == 0
+ || strcmp (target_shortname, "vxprocess") == 0
+ || strstr (target_shortname, "-threads") != NULL)
+ gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */
+ else
+ gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */
+ }
+
+ if (gdb_disassemble_from_exec)
+ di.read_memory_func = gdb_dis_asm_read_memory;
+ else
+ di.read_memory_func = dis_asm_read_memory;
+
+ /* Assume symtab is valid for whole PC range */
+ symtab = find_pc_symtab (low);
+
+ if (symtab != NULL && symtab->linetable != NULL)
+ {
+ /* Convert the linetable to a bunch of my_line_entry's. */
+ le = symtab->linetable->item;
+ nlines = symtab->linetable->nitems;
+ }
+
+ if (!mixed_source_and_assembly || nlines <= 0
+ || symtab == NULL || symtab->linetable == NULL)
+ do_assembly_only (&di, low, high, how_many, stb);
+
+ else if (mixed_source_and_assembly)
+ do_mixed_source_and_assembly (&di, nlines, le, low,
+ high, symtab, how_many, stb);
+
+ gdb_flush (gdb_stdout);
+ }
Index: disasm.h
===================================================================
RCS file: disasm.h
diff -N disasm.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- disasm.h 26 Sep 2002 22:52:16 -0000
***************
*** 0 ****
--- 1,25 ----
+ /* Disassemble support for GDB.
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions (a Red Hat company).
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+ extern void gdb_disassembly (char *file_string,
+ int line_num,
+ int mixed_source_and_assembly,
+ int how_many, CORE_ADDR low, CORE_ADDR high);
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.264
diff -c -p -r1.264 Makefile.in
*** Makefile.in 26 Sep 2002 17:46:04 -0000 1.264
--- Makefile.in 26 Sep 2002 22:37:23 -0000
*************** TARGET_FLAGS_TO_PASS = \
*** 530,558 ****
# SFILES is used in building the distribution archive.
SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
! ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
! charset.c \
! buildsym.c c-exp.y c-lang.c c-typeprint.c c-valprint.c \
! coffread.c \
! complaints.c completer.c corefile.c cp-valprint.c dbxread.c \
! demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \
! event-loop.c event-top.c \
! expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
! findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c osabi.c \
! inf-loop.c infcmd.c inflow.c infrun.c language.c \
! kod.c kod-cisco.c \
! ui-out.c cli-out.c \
! varobj.c wrapper.c \
jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
! m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
! memattr.c mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c \
! p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c \
! macrotab.c macroexp.c macrocmd.c macroscope.c \
! printcmd.c remote.c scm-exp.c scm-lang.c \
! scm-valprint.c source.c stabsread.c stack.c symfile.c \
! symmisc.c symtab.c linespec.c target.c thread.c top.c tracepoint.c \
! typeprint.c utils.c valarith.c valops.c valprint.c values.c \
! serial.c ser-unix.c mdebugread.c \
tui/tui.c tui/tui.h tui/tuiCommand.c tui/tuiCommand.h \
tui/tuiData.c tui/tuiData.h tui/tuiDataWin.c tui/tuiDataWin.h \
tui/tuiDisassem.c tui/tuiDisassem.h tui/tuiGeneralWin.c \
--- 530,559 ----
# SFILES is used in building the distribution archive.
SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
! ax-general.c ax-gdb.c \
! bcache.c blockframe.c breakpoint.c buildsym.c builtin-regs.c \
! c-exp.y c-lang.c c-typeprint.c c-valprint.c \
! charset.c cli-out.c coffread.c complaints.c completer.c corefile.c \
! cp-abi.c cp-support.c cp-valprint.c \
! dbxread.c demangle.c disasm.c doublest.c dwarfread.c dwarf2read.c \
! elfread.c environ.c eval.c event-loop.c event-top.c expprint.c \
! f-exp.y f-lang.c f-typeprint.c f-valprint.c findvar.c frame.c \
! gdbarch.c arch-utils.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \
! hpacc-abi.c \
! inf-loop.c infcmd.c inflow.c infrun.c \
jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
! kod.c kod-cisco.c \
! language.c linespec.c \
! m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c \
! macrotab.c macroexp.c macrocmd.c macroscope.c main.c maint.c \
! mdebugread.c memattr.c mem-break.c minsyms.c mipsread.c \
! nlmread.c \
! objfiles.c osabi.c \
! p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
! regcache.c remote.c \
! scm-exp.c scm-lang.c scm-valprint.c serial.c ser-unix.c source.c \
! stabsread.c stack.c std-regs.c symfile.c symmisc.c symtab.c \
! target.c thread.c top.c tracepoint.c typeprint.c \
tui/tui.c tui/tui.h tui/tuiCommand.c tui/tuiCommand.h \
tui/tuiData.c tui/tuiData.h tui/tuiDataWin.c tui/tuiDataWin.h \
tui/tuiDisassem.c tui/tuiDisassem.h tui/tuiGeneralWin.c \
*************** SFILES = ada-exp.y ada-lang.c ada-typepr
*** 561,570 ****
tui/tuiSource.h tui/tuiSourceWin.c tui/tuiSourceWin.h \
tui/tuiStack.c tui/tuiStack.h tui/tuiWin.c tui/tuiWin.h \
tui/tui-file.h tui/tui-file.c tui/tui-out.c tui/tui-hooks.c \
! ui-file.h ui-file.c \
! frame.c doublest.c \
! builtin-regs.c std-regs.c \
! gnu-v2-abi.c gnu-v3-abi.c hpacc-abi.c cp-abi.c cp-support.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
--- 562,570 ----
tui/tuiSource.h tui/tuiSourceWin.c tui/tuiSourceWin.h \
tui/tuiStack.c tui/tuiStack.h tui/tuiWin.c tui/tuiWin.h \
tui/tui-file.h tui/tui-file.c tui/tui-out.c tui/tui-hooks.c \
! ui-out.c utils.c ui-file.h ui-file.c \
! valarith.c valops.c valprint.c values.c varobj.c \
! wrapper.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
*************** dcache_h = dcache.h
*** 637,642 ****
--- 637,643 ----
defs_h = defs.h $(config_h) $(gdb_locale_h) $(gdb_signals_h) $(ansidecl_h) \
$(libiberty_h) $(progress_h) $(bfd_h) $(tui_h) $(ui_file_h) $(xm_h) \
$(nm_h) $(tm_h) $(fopen_same_h) $(gdbarch_h) $(arch_utils_h)
+ disasm_h = disasm.h
doublest_h = doublest.h $(floatformat_h)
dst_h = dst.h
dwarf2cfi_h = dwarf2cfi.h
*************** TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_
*** 827,833 ****
TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
! charset.o \
source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \
expprint.o environ.o stack.o thread.o \
--- 828,834 ----
TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
! charset.o disasm.o \
source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \
expprint.o environ.o stack.o thread.o \
*************** demangle.o: demangle.c $(defs_h) $(comma
*** 1617,1622 ****
--- 1618,1625 ----
$(gdb_string_h)
dink32-rom.o: dink32-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
$(serial_h) $(symfile_h) $(inferior_h) $(regcache_h)
+ disasm.o: disasm.c $(defs_h) $(gdb_string_h) $(target_h) $(value_h) \
+ $(disasm_h) $(ui_out_h)
doublest.o: doublest.c $(defs_h) $(doublest_h) $(floatformat_h) \
$(gdb_assert_h) $(gdb_string_h) $(gdbtypes_h)
dpx2-nat.o: dpx2-nat.c $(defs_h) $(gdbcore_h) $(gdb_string_h)
*************** insight$(EXEEXT): gdbtk-main.o main.o li
*** 2373,2379 ****
$(CDEPS) $(TDEPLIBS)
rm -f insight$(EXEEXT)
$(HLDENV) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
! -o insight$(EXEEXT) gdbtk-main.o main.o libgdb.a $(CONFIG_OBS)\
$(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
gdbres.o: $(srcdir)/gdbtk/gdb.rc $(srcdir)/gdbtk/gdbtool.ico
--- 2376,2382 ----
$(CDEPS) $(TDEPLIBS)
rm -f insight$(EXEEXT)
$(HLDENV) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
! -o insight$(EXEEXT) gdbtk-main.o main.o $(CONFIG_OBS) libgdb.a \
$(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
gdbres.o: $(srcdir)/gdbtk/gdb.rc $(srcdir)/gdbtk/gdbtool.ico
*************** mi-cmd-break.o: $(srcdir)/mi/mi-cmd-brea
*** 2468,2474 ****
$(mi_getopt_h) $(gdb_events_h) $(gdb_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-break.c
mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(defs_h) $(target_h) $(value_h) \
! $(mi_cmds_h) $(mi_getopt_h) $(ui_out_h) $(gdb_string_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-disas.c
mi-cmd-stack.o: $(srcdir)/mi/mi-cmd-stack.c $(defs_h) $(target_h) $(frame_h) \
$(value_h) $(mi_cmds_h) $(ui_out_h) $(symtab_h)
--- 2471,2477 ----
$(mi_getopt_h) $(gdb_events_h) $(gdb_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-break.c
mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(defs_h) $(target_h) $(value_h) \
! $(mi_cmds_h) $(mi_getopt_h) $(ui_out_h) $(gdb_string_h) $(disasm_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-disas.c
mi-cmd-stack.o: $(srcdir)/mi/mi-cmd-stack.c $(defs_h) $(target_h) $(frame_h) \
$(value_h) $(mi_cmds_h) $(ui_out_h) $(symtab_h)