From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17761 invoked by alias); 26 Sep 2002 23:15:37 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 17751 invoked from network); 26 Sep 2002 23:15:34 -0000 Received: from unknown (HELO touchme.toronto.redhat.com) (216.138.202.10) by sources.redhat.com with SMTP; 26 Sep 2002 23:15:34 -0000 Received: from redhat.com (tooth.toronto.redhat.com [172.16.14.29]) by touchme.toronto.redhat.com (Postfix) with ESMTP id 0AD9A800168 for ; Thu, 26 Sep 2002 19:15:34 -0400 (EDT) Message-ID: <3D9394BA.2040605@redhat.com> Date: Thu, 26 Sep 2002 16:15:00 -0000 From: Fernando Nasser Organization: Red Hat Canada User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020607 X-Accept-Language: en-us, en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: RFC/RFA: Move new disassembler to libgdb proper Content-Type: multipart/mixed; boundary="------------070402090304080707090702" X-SW-Source: 2002-09/txt/msg00650.txt.bz2 This is a multi-part message in MIME format. --------------070402090304080707090702 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 828 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 * 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 --------------070402090304080707090702 Content-Type: text/plain; name="DISASM.PATCH" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="DISASM.PATCH" Content-length: 32508 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) --------------070402090304080707090702--