From 09722039025db14916df14dc44fbc093317851c1 Mon Sep 17 00:00:00 2001 From: Stu Grossman Date: Fri, 6 Jan 1995 01:55:45 +0000 Subject: [PATCH] * Makefile.in (install_only uninstall): Indent for clarity * core.c (dis_asm_read_memory): Add call to dis_asm_read_memory_hook to provide alternate way for disassembler to read memory. * defs.h: Protect from multiple inclusion. Add decl for dis_asm_read_memory_hook. * gdbtk.c (finish_saving_output): Don't do anything if not saving output. * (breakpoint_notify): Don't send null filename to tcl. * (gdb_eval): New tcl command to eval an expression. * (gdb_disassemble): New tcl command to do disassembly. This allows tcl code to choose between exec file and target memeory, and can also do mixed source and assembly. * (gdbtk_init): Move reading of gdbtk.tcl to the end to make sure that more of the environment is set up. Also, create link between gdb and tcl vars disassemble{-_}from{-_}exec. * gdbtk.tcl: New expression window support. * Make assembly window be 80 columns wide. * Use new disassembly method. Add menu items to select disassembly from exec file or target. * Change View menubar item to Options. * Get rid of Stack, Breakpoints, Signals, and Variables Windows, since they don't exist yet. * Pop up a copyright window on startup. * top.c: Make window startup be the default. * Add dis_asm_read_memory_hook. --- gdb/ChangeLog | 36 +++++ gdb/Makefile.in | 32 ++--- gdb/core.c | 3 + gdb/defs.h | 21 +-- gdb/gdbtk.c | 350 ++++++++++++++++++++++++++++++++++++++++++++---- gdb/gdbtk.tcl | 166 +++++++++++++++++++---- gdb/top.c | 8 +- 7 files changed, 540 insertions(+), 76 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8457c699354..e70d65e59b6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,39 @@ +Thu Jan 5 17:38:29 1995 Stu Grossman (grossman@cygnus.com) + + * Makefile.in (install_only uninstall): Indent for clarity + + * core.c (dis_asm_read_memory): Add call to + dis_asm_read_memory_hook to provide alternate way for disassembler + to read memory. + + * defs.h: Protect from multiple inclusion. Add decl for + dis_asm_read_memory_hook. + + * gdbtk.c (finish_saving_output): Don't do anything if not saving + output. + * (breakpoint_notify): Don't send null filename to tcl. + * (gdb_eval): New tcl command to eval an expression. + * (gdb_disassemble): New tcl command to do disassembly. This + allows tcl code to choose between exec file and target memeory, + and can also do mixed source and assembly. + * (gdbtk_init): Move reading of gdbtk.tcl to the end to make sure + that more of the environment is set up. Also, create link between + gdb and tcl vars disassemble{-_}from{-_}exec. + + * gdbtk.tcl: New expression window support. + * Make assembly window be 80 columns wide. + * Use new disassembly method. Add menu items to select + disassembly from exec file or target. + * Change View menubar item to Options. + + * Get rid of Stack, Breakpoints, Signals, and Variables Windows, + since they don't exist yet. + + * Pop up a copyright window on startup. + + * top.c: Make window startup be the default. + * Add dis_asm_read_memory_hook. + Thu Jan 5 01:16:40 1995 Jeff Law (law@snake.cs.utah.edu) * stabsread.c (define_symbol): Handle `a' symbol type used for diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 191770335c6..4b7d8eb78f5 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -506,29 +506,31 @@ install: all install-only install-only: transformed_name=`t='$(program_transform_name)'; \ echo gdb | sed -e "s/brokensed/brokensed/" $$t` ; \ - if test "x$$transformed_name" = x; then \ - transformed_name=gdb ; \ - else \ - true ; \ - fi ; \ - $(INSTALL_PROGRAM) gdb $(bindir)/$$transformed_name ; \ - $(INSTALL_DATA) $(srcdir)/gdb.1 $(man1dir)/$$transformed_name.1 + if test "x$$transformed_name" = x; then \ + transformed_name=gdb ; \ + else \ + true ; \ + fi ; \ + $(INSTALL_PROGRAM) gdb $(bindir)/$$transformed_name ; \ + $(INSTALL_DATA) $(srcdir)/gdb.1 $(man1dir)/$$transformed_name.1 # start-sanitize-gdbtk if [ x"$(ENABLE_GDBTK)" != x ] ; then \ - $(INSTALL_DATA) $(srcdir)/gdbtk.tcl $(libdir)/gdbtk.tcl ; \ - fi + $(INSTALL_DATA) $(srcdir)/gdbtk.tcl $(libdir)/gdbtk.tcl ; \ + else \ + true ; \ + fi # end-sanitize-gdbtk @$(MAKE) DO=install "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do uninstall: force transformed_name=`t='$(program_transform_name)'; \ echo gdb | sed -e "s/brokensed/brokensed/" $$t` ; \ - if test "x$$transformed_name" = x; then \ - transformed_name=gdb ; \ - else \ - true ; \ - fi ; \ - rm -f $(bindir)/$$transformed_name $(man1dir)/$$transformed_name.1 + if test "x$$transformed_name" = x; then \ + transformed_name=gdb ; \ + else \ + true ; \ + fi ; \ + rm -f $(bindir)/$$transformed_name $(man1dir)/$$transformed_name.1 @$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do # We do this by grepping through sources. If that turns out to be too slow, diff --git a/gdb/core.c b/gdb/core.c index 974e55c1859..52bb3aaaa19 100644 --- a/gdb/core.c +++ b/gdb/core.c @@ -181,6 +181,9 @@ dis_asm_read_memory (memaddr, myaddr, len, info) int len; disassemble_info *info; { + if (dis_asm_read_memory_hook) + return dis_asm_read_memory_hook (memaddr, myaddr, len, info); + return target_read_memory (memaddr, (char *) myaddr, len); } diff --git a/gdb/defs.h b/gdb/defs.h index b518f64479a..05d591069bf 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -18,8 +18,8 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined (DEFS_H) -#define DEFS_H 1 +#ifndef DEFS_H +#define DEFS_H #include @@ -836,6 +836,13 @@ extern CORE_ADDR push_word PARAMS ((CORE_ADDR, unsigned LONGEST)); /* Hooks for alternate command interfaces. */ +#include "dis-asm.h" /* Get defs for disassemble_info */ + +#ifdef __STDC__ +struct target_waitstatus; +struct cmd_list_element; +#endif + extern void (*init_ui_hook) PARAMS ((void)); extern void (*command_loop_hook) PARAMS ((void)); extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, FILE *stream)); @@ -848,11 +855,9 @@ extern void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); extern void (*enable_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); extern void (*disable_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); extern void (*interactive_hook) PARAMS ((void)); - -#ifdef __STDC__ -struct target_waitstatus; -struct cmd_list_element; -#endif +extern int (*dis_asm_read_memory_hook) PARAMS ((bfd_vma memaddr, + bfd_byte *myaddr, int len, + disassemble_info *info)); extern int (*target_wait_hook) PARAMS ((int pid, struct target_waitstatus *status)); @@ -866,4 +871,4 @@ extern NORETURN void (*error_hook) PARAMS (()); extern int use_windows; -#endif /* !defined (DEFS_H) */ +#endif /* #ifndef DEFS_H */ diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c index 0f7be520164..c97d2444bbb 100644 --- a/gdb/gdbtk.c +++ b/gdb/gdbtk.c @@ -35,6 +35,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "top.h" #include #include +#include "dis-asm.h" #ifndef FIOASYNC #include @@ -55,6 +56,17 @@ static Tk_Window mainWindow = NULL; static int x_fd; /* X network socket */ +/* This variable determines where memory used for disassembly is read from. + + If > 0, then disassembly comes from the exec file rather than the target + (which might be at the other end of a slow serial link). If == 0 then + disassembly comes from target. If < 0 disassembly is automatically switched + to the target if it's an inferior process, otherwise the exec file is + used. + */ + +static int disassemble_from_exec = -1; + static void null_routine(arg) int arg; @@ -95,6 +107,9 @@ start_saving_output () static void finish_saving_output () { + if (!saving_output) + return; + saving_output = 0; Tcl_DStringFree (&stdout_buffer); @@ -201,7 +216,7 @@ breakpoint_notify(b, action) "gdbtk_tcl_breakpoint ", action, " ", bpnum, - " ", filename, + " ", filename ? filename : "{}", " ", line, " ", pc, NULL); @@ -307,6 +322,48 @@ gdb_loc (clientData, interp, argc, argv) return TCL_OK; } +/* This implements the TCL command `gdb_eval'. */ + +static int +gdb_eval (clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + char *argv[]; +{ + struct expression *expr; + struct cleanup *old_chain; + value_ptr val; + + if (argc != 2) + { + Tcl_SetResult (interp, "wrong # args", TCL_STATIC); + return TCL_ERROR; + } + + expr = parse_expression (argv[1]); + + old_chain = make_cleanup (free_current_contents, &expr); + + val = evaluate_expression (expr); + + start_saving_output (); /* Start collecting stdout */ + + val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val), + gdb_stdout, 0, 0, 0, 0); +#if 0 + value_print (val, gdb_stdout, 0, 0); +#endif + + Tcl_AppendElement (interp, get_saved_output ()); + + finish_saving_output (); /* Set stdout back to normal */ + + do_cleanups (old_chain); + + return TCL_OK; +} + /* This implements the TCL command `gdb_sourcelines', which returns a list of all of the lines containing executable code for the specified source file (ie: lines where you can put breakpoints). */ @@ -608,8 +665,12 @@ call_wrapper (clientData, interp, argc, argv) finish_saving_output (); /* Restore stdout to normal */ + dis_asm_read_memory_hook = 0; /* Restore disassembly hook */ + gdb_flush (gdb_stderr); /* Flush error output */ + gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */ + /* In case of an error, we may need to force the GUI into idle mode because gdbtk_call_command may have bombed out while in the command routine. */ @@ -657,7 +718,229 @@ gdb_stop (clientData, interp, argc, argv) return TCL_OK; } + +/* This implements the TCL command `gdb_disassemble'. */ +static int +gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info) + bfd_vma memaddr; + bfd_byte *myaddr; + int len; + disassemble_info *info; +{ + extern struct target_ops exec_ops; + int res; + + errno = 0; + res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops); + + if (res == len) + return 0; + else + if (errno == 0) + return EIO; + else + return errno; +} + +/* 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. This is because of the + reordering we are about to do. */ + +struct my_line_entry { + int line; + CORE_ADDR start_pc; + CORE_ADDR end_pc; +}; + +static int +compare_lines (mle1p, mle2p) + const PTR mle1p; + const PTR mle2p; +{ + struct my_line_entry *mle1, *mle2; + int val; + + mle1 = (struct my_line_entry *) mle1p; + mle2 = (struct my_line_entry *) mle2p; + + val = mle1->line - mle2->line; + + if (val != 0) + return val; + + return mle1->start_pc - mle2->start_pc; +} + +static int +gdb_disassemble (clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + char *argv[]; +{ + CORE_ADDR pc, low, high; + int mixed_source_and_assembly; + + if (argc != 3 && argc != 4) + { + Tcl_SetResult (interp, "wrong # args", TCL_STATIC); + return TCL_ERROR; + } + + if (strcmp (argv[1], "source") == 0) + mixed_source_and_assembly = 1; + else if (strcmp (argv[1], "nosource") == 0) + mixed_source_and_assembly = 0; + else + { + Tcl_SetResult (interp, "First arg must be 'source' or 'nosource'", + TCL_STATIC); + return TCL_ERROR; + } + + low = parse_and_eval_address (argv[2]); + + if (argc == 3) + { + if (find_pc_partial_function (low, NULL, &low, &high) == 0) + { + Tcl_SetResult (interp, "No function contains specified address", + TCL_STATIC); + return TCL_ERROR; + } + } + else + high = parse_and_eval_address (argv[3]); + + /* If 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. + + 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 it's + code (for relocation, or whatever). + */ + + if (disassemble_from_exec == -1) + if (strcmp (target_shortname, "child") == 0 + || strcmp (target_shortname, "procfs") == 0) + disassemble_from_exec = 0; /* It's a child process, read inferior mem */ + else + disassemble_from_exec = 1; /* It's remote, read the exec file */ + + if (disassemble_from_exec) + dis_asm_read_memory_hook = gdbtk_dis_asm_read_memory; + + /* If just doing straight assembly, all we need to do is disassemble + everything between low and high. If doing mixed source/assembly, we've + got a totally different path to follow. */ + + if (mixed_source_and_assembly) + { /* Come here for mixed source/assembly */ + /* 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. */ + struct symtab *symtab; + struct linetable_entry *le; + int nlines; + struct my_line_entry *mle; + struct symtab_and_line sal; + int i; + int out_of_order; + int current_line; + + symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */ + + if (!symtab) + goto assembly_only; + +/* First, convert the linetable to a bunch of my_line_entry's. */ + + le = symtab->linetable->item; + nlines = symtab->linetable->nitems; + + if (nlines <= 0) + goto assembly_only; + + mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry)); + + out_of_order = 0; + + for (i = 0; i < nlines - 1; i++) + { + mle[i].line = le[i].line; + if (le[i].line > le[i + 1].line) + out_of_order = 1; + mle[i].start_pc = le[i].pc; + mle[i].end_pc = le[i + 1].pc; + } + + mle[i].line = le[i].line; + mle[i].start_pc = le[i].pc; + sal = find_pc_line (le[i].pc, 0); + mle[i].end_pc = sal.end; + +/* Now, sort mle by line #s (and, then by addresses within lines). */ + + if (out_of_order) + qsort (mle, nlines, sizeof (struct my_line_entry), compare_lines); + +/* Scan forward until we find the start of the function. */ + + for (i = 0; i < nlines; i++) + if (mle[i].start_pc >= low) + break; + +/* Now, for each line entry, emit the specified lines (unless they have been + emitted before), followed by the assembly code for that line. */ + + current_line = 0; /* Force out first line */ + for (;i < nlines && mle[i].start_pc < high; i++) + { + if (mle[i].line > current_line) + { + if (i == nlines - 1) + print_source_lines (symtab, mle[i].line, INT_MAX, 0); + else + print_source_lines (symtab, mle[i].line, mle[i + 1].line, 0); + current_line = mle[i].line; + } + for (pc = mle[i].start_pc; pc < mle[i].end_pc; ) + { + QUIT; + fputs_unfiltered (" ", gdb_stdout); + print_address (pc, gdb_stdout); + fputs_unfiltered (":\t ", gdb_stdout); + pc += print_insn (pc, gdb_stdout); + fputs_unfiltered ("\n", gdb_stdout); + } + } + } + else + { +assembly_only: + for (pc = low; pc < high; ) + { + QUIT; + fputs_unfiltered (" ", gdb_stdout); + print_address (pc, gdb_stdout); + fputs_unfiltered (":\t ", gdb_stdout); + pc += print_insn (pc, gdb_stdout); + fputs_unfiltered ("\n", gdb_stdout); + } + } + + dis_asm_read_memory_hook = 0; + + gdb_flush (gdb_stdout); + + return TCL_OK; +} static void tk_command (cmd, from_tty) @@ -771,6 +1054,8 @@ gdbtk_init () int i; struct sigaction action; static sigset_t nullsigmask = {0}; + extern struct cmd_list_element *setlist; + extern struct cmd_list_element *showlist; old_chain = make_cleanup (cleanup_init, 0); @@ -806,16 +1091,22 @@ gdbtk_init () gdb_fetch_registers, NULL); Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper, gdb_changed_register_list, NULL); + Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper, + gdb_disassemble, NULL); + Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL); - gdbtk_filename = getenv ("GDBTK_FILENAME"); - if (!gdbtk_filename) - if (access ("gdbtk.tcl", R_OK) == 0) - gdbtk_filename = "gdbtk.tcl"; - else - gdbtk_filename = GDBTK_FILENAME; - - if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK) - error ("Failure reading %s: %s", gdbtk_filename, interp->result); + command_loop_hook = Tk_MainLoop; + fputs_unfiltered_hook = gdbtk_fputs; + print_frame_info_listing_hook = null_routine; + query_hook = gdbtk_query; + flush_hook = gdbtk_flush; + create_breakpoint_hook = gdbtk_create_breakpoint; + delete_breakpoint_hook = gdbtk_delete_breakpoint; + enable_breakpoint_hook = gdbtk_enable_breakpoint; + disable_breakpoint_hook = gdbtk_disable_breakpoint; + interactive_hook = gdbtk_interactive; + target_wait_hook = gdbtk_wait; + call_command_hook = gdbtk_call_command; /* Get the file descriptor for the X server */ @@ -841,23 +1132,32 @@ gdbtk_init () perror_with_name ("gdbtk_init: ioctl I_SETSIG failed"); #endif /* ifndef FIOASYNC */ - command_loop_hook = Tk_MainLoop; - fputs_unfiltered_hook = gdbtk_fputs; - print_frame_info_listing_hook = null_routine; - query_hook = gdbtk_query; - flush_hook = gdbtk_flush; - create_breakpoint_hook = gdbtk_create_breakpoint; - delete_breakpoint_hook = gdbtk_delete_breakpoint; - enable_breakpoint_hook = gdbtk_enable_breakpoint; - disable_breakpoint_hook = gdbtk_disable_breakpoint; - interactive_hook = gdbtk_interactive; - target_wait_hook = gdbtk_wait; - call_command_hook = gdbtk_call_command; - - discard_cleanups (old_chain); - add_com ("tk", class_obscure, tk_command, "Send a command directly into tk."); + +#if 0 + add_show_from_set (add_set_cmd ("disassemble-from-exec", class_support, + var_boolean, (char *)&disassemble_from_exec, + "Set ", &setlist), + &showlist); +#endif + + Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec, + TCL_LINK_INT); + + /* Load up gdbtk.tcl after all the environment stuff has been setup. */ + + gdbtk_filename = getenv ("GDBTK_FILENAME"); + if (!gdbtk_filename) + if (access ("gdbtk.tcl", R_OK) == 0) + gdbtk_filename = "gdbtk.tcl"; + else + gdbtk_filename = GDBTK_FILENAME; + + if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK) + error ("Failure reading %s: %s", gdbtk_filename, interp->result); + + discard_cleanups (old_chain); } /* Come here during initialze_all_files () */ diff --git a/gdb/gdbtk.tcl b/gdb/gdbtk.tcl index b03450a759b..71e338a786b 100644 --- a/gdb/gdbtk.tcl +++ b/gdb/gdbtk.tcl @@ -715,21 +715,110 @@ proc not_implemented_yet {message} { # Create the expression display window. # +set expr_num 0 + +proc add_expr {expr} { + global expr_update_list + global expr_num + + incr expr_num + + set e .expr.e${expr_num} + + frame $e + + checkbutton $e.update -text " " -relief flat \ + -variable expr_update_list($expr_num) + message $e.expr -text $expr -aspect 200 + bind $e.expr <1> "update_expr $expr_num" + message $e.val -aspect 200 + + update_expr $expr_num + + pack $e.update -side left -anchor nw + pack $e.expr $e.val -side left -expand yes -anchor w + + pack $e -side top -fill x -anchor w +} + +set delete_expr_flag 0 + +# This is a krock!!! + +proc delete_expr {} { + global delete_expr_flag + + if {$delete_expr_flag == 1} { + set delete_expr_flag 0 + tk_butUp .expr.delete + bind .expr.delete {} + } else { + set delete_expr_flag 1 + bind .expr.delete do_nothing + tk_butDown .expr.delete + } +} + +proc update_expr {expr_num} { + global delete_expr_flag + + set e .expr.e${expr_num} + + if {$delete_expr_flag == 1} { + set delete_expr_flag 0 + destroy $e + tk_butUp .expr.delete + tk_butLeave .expr.delete + bind .expr.delete {} + return + } + + set expr [lindex [$e.expr configure -text] 4] + + $e.val config -text [gdb_eval $expr] +} + proc create_expr_win {} { toplevel .expr wm minsize .expr 1 1 wm title .expr Expression - canvas .expr.c -yscrollcommand {.expr.scroll set} -cursor hand2 \ - -borderwidth 2 -relief groove - scrollbar .expr.scroll -orient vertical -command {.expr.c yview} - entry .expr.entry -borderwidth 2 -relief groove + wm iconname .expr "Reg config" - pack .expr.entry -side bottom -fill x - pack .expr.c -side left -fill both -expand yes - pack .expr.scroll -side right -fill y + frame .expr.entryframe - .expr.c create text 100 0 -text "Text string" - .expr.c create rectangle 245 195 255 205 -outline black -fill white + entry .expr.entry -borderwidth 2 -relief sunken + bind .expr {focus .expr.entry} + bind .expr.entry {add_expr [.expr.entry get] + .expr.entry delete 0 end } + + label .expr.entrylab -text "Expression: " + + pack .expr.entrylab -in .expr.entryframe -side left + pack .expr.entry -in .expr.entryframe -side left -fill x -expand yes + + frame .expr.buts + + button .expr.delete -text Delete + bind .expr.delete <1> delete_expr + + button .expr.close -text Close -command {destroy .expr} + + pack .expr.delete -side left -fill x -expand yes -in .expr.buts + pack .expr.close -side right -fill x -expand yes -in .expr.buts + + pack .expr.buts -side bottom -fill x + pack .expr.entryframe -side bottom -fill x + + frame .expr.labels + + label .expr.updlab -text Update + label .expr.exprlab -text Expression + label .expr.vallab -text Value + + pack .expr.updlab -side left -in .expr.labels + pack .expr.exprlab .expr.vallab -side left -in .expr.labels -expand yes -anchor w + + pack .expr.labels -side top -fill x -anchor w } # @@ -745,7 +834,7 @@ proc create_expr_win {} { proc display_expression {expression} { if ![winfo exists .expr] {create_expr_win} - + add_expr $expression } # @@ -910,7 +999,7 @@ proc create_asm_win {funcname pc} { # Actually create and do basic configuration on the text widget. - text $win -height 25 -width 88 -relief raised -borderwidth 2 \ + text $win -height 25 -width 80 -relief raised -borderwidth 2 \ -setgrid true -cursor hand2 -yscrollcommand asmscrollproc # Setup all the bindings @@ -929,7 +1018,7 @@ proc create_asm_win {funcname pc} { set temp $current_output_win set current_output_win $win - gdb_cmd "disassemble $pc" + catch "gdb_disassemble source $pc" set current_output_win $temp set numlines [$win index end] @@ -938,9 +1027,9 @@ proc create_asm_win {funcname pc} { # Delete the first and last lines, cuz these contain useless info - $win delete 1.0 2.0 - $win delete {end - 1 lines} end - decr numlines 2 +# $win delete 1.0 2.0 +# $win delete {end - 1 lines} end +# decr numlines 2 # Add margins (for annotations) and note the PC for each line @@ -1129,6 +1218,10 @@ proc create_asm_window {} { build_framework .asm Assembly "*NIL*" +# First, delete all the old menu entries + + .asm.menubar.view.menu delete 0 last + .asm.text configure -yscrollcommand asmscrollproc frame .asm.row1 @@ -1156,6 +1249,15 @@ proc create_asm_window {} { update update_assembly [gdb_loc] + +# We do this update_assembly to get the proper value of disassemble-from-exec. + +# exec file menu item + .asm.menubar.view.menu add radiobutton -label "Exec file" \ + -variable disassemble-from-exec -value 1 +# target memory menu item + .asm.menubar.view.menu add radiobutton -label "Target memory" \ + -variable disassemble-from-exec -value 0 } } @@ -1629,7 +1731,7 @@ proc build_framework {win {title GDBtk} {label {}}} { ${win}.menubar.commands.menu add command -label Nexti \ -command { catch { gdb_cmd nexti } ; update_ptr } - menubutton ${win}.menubar.view -padx 12 -text View \ + menubutton ${win}.menubar.view -padx 12 -text Options \ -menu ${win}.menubar.view.menu -underline 0 menu ${win}.menubar.view.menu @@ -1654,18 +1756,12 @@ proc build_framework {win {title GDBtk} {label {}}} { ${win}.menubar.window.menu add separator ${win}.menubar.window.menu add command -label Registers \ -command {create_registers_window ; update_ptr} - ${win}.menubar.window.menu add command -label Stack \ - -command { not_implemented_yet "stack window" } + ${win}.menubar.window.menu add command -label Expressions \ + -command {create_expr_win ; update_ptr} + ${win}.menubar.window.menu add separator ${win}.menubar.window.menu add command -label Files \ -command { not_implemented_yet "files window" } - ${win}.menubar.window.menu add separator - ${win}.menubar.window.menu add command -label Breakpoints \ - -command { not_implemented_yet "breakpoints window" } - ${win}.menubar.window.menu add command -label Signals \ - -command { not_implemented_yet "signals window" } - ${win}.menubar.window.menu add command -label Variables \ - -command { not_implemented_yet "variables window" } menubutton ${win}.menubar.help -padx 12 -text Help \ -menu ${win}.menubar.help.menu -underline 0 @@ -1680,12 +1776,10 @@ proc build_framework {win {title GDBtk} {label {}}} { tk_menuBar ${win}.menubar \ ${win}.menubar.file \ - ${win}.menubar.commands \ ${win}.menubar.view \ ${win}.menubar.window \ ${win}.menubar.help pack ${win}.menubar.file \ - ${win}.menubar.commands \ ${win}.menubar.view \ ${win}.menubar.window -side left pack ${win}.menubar.help -side right @@ -2495,4 +2589,22 @@ if {[tk colormodel .src.text] == "color"} { } create_command_window + +# Create a copyright window + +toplevel .c +wm geometry .c +300+300 +wm overrideredirect .c true + +text .t +set temp $current_output_win +set current_output_win .t +gdb_cmd "show version" +set current_output_win $temp + +message .c.m -text [.t get 0.0 end] -aspect 500 +destroy .t +pack .c.m +bind .c.m {destroy .c} + update diff --git a/gdb/top.c b/gdb/top.c index 894e42e9206..0c8bae32703 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -166,7 +166,7 @@ int inhibit_gdbinit = 0; /* Disable windows if non-zero */ -int use_windows = 0; /* Defaults to off for now */ +int use_windows = 1; /* Defaults to on for now */ /* Version number of GDB, as a string. */ @@ -410,6 +410,12 @@ int (*target_wait_hook) PARAMS ((int pid, struct target_waitstatus *status)); void (*call_command_hook) PARAMS ((struct cmd_list_element *c, char *cmd, int from_tty)); +/* An alternate way to read memory for disassembly. This is used to provide a + switch that allows disassembly to come from an exec file rather than a + remote target. This is a speed hack. */ + +int (*dis_asm_read_memory_hook) PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, + int len, disassemble_info *info)); /* Takes control from error (). Typically used to prevent longjmps out of the middle of the GUI. Usually used in conjunction with a catch routine. */ -- 2.30.2