mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-29 06:50:32 +00:00
* 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.
This commit is contained in:
parent
26e4dcae58
commit
0972203902
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
21
gdb/defs.h
21
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 <stdio.h>
|
||||
|
||||
@ -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 */
|
||||
|
350
gdb/gdbtk.c
350
gdb/gdbtk.c
@ -35,6 +35,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "top.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include "dis-asm.h"
|
||||
|
||||
#ifndef FIOASYNC
|
||||
#include <sys/stropts.h>
|
||||
@ -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 () */
|
||||
|
166
gdb/gdbtk.tcl
166
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 <Any-Leave> {}
|
||||
} else {
|
||||
set delete_expr_flag 1
|
||||
bind .expr.delete <Any-Leave> 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 <Any-Leave> {}
|
||||
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 <Enter> {focus .expr.entry}
|
||||
bind .expr.entry <Key-Return> {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 <Leave> {destroy .c}
|
||||
|
||||
update
|
||||
|
@ -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. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user