diff options
author | Stu Grossman <grossman@cygnus> | 1994-12-12 20:50:08 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1994-12-12 20:50:08 +0000 |
commit | 746d1df4a9f64da38da324be849beb5fd389135b (patch) | |
tree | d0746436cf6fc747952470d885bb1d47002437e0 /gdb/gdbtk.c | |
parent | d9f1d487a61427dd7cfee0e40bcc8ea41374cd4d (diff) | |
download | gdb-746d1df4a9f64da38da324be849beb5fd389135b.zip gdb-746d1df4a9f64da38da324be849beb5fd389135b.tar.gz gdb-746d1df4a9f64da38da324be849beb5fd389135b.tar.bz2 |
* gdbtk.c: New tcl commands: gdb_fetch_registers,
gdb_changed_register_list, and gdb_regnames.
* gdbtk.tcl: Use monochrome color model for now.
* (delete_breakpoint_tag create_file_win): Add breakdot support.
* (create_file_win create_asm_win update_listing build_framework
create_source_window create_command_window): Re-org window
creation to give all windows consistent look and feel.
* (update_listing update_asm): Change pc pointer to '->'.
* (registers_command reg_config_menu create_registers_window
populate_reg_window update_registers): Revamp register window.
Allow selection of registers to be displayed. Highlight changed
registers.
Diffstat (limited to 'gdb/gdbtk.c')
-rw-r--r-- | gdb/gdbtk.c | 196 |
1 files changed, 190 insertions, 6 deletions
diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c index c2a1e38..290ed64 100644 --- a/gdb/gdbtk.c +++ b/gdb/gdbtk.c @@ -348,6 +348,62 @@ gdb_sourcelines (clientData, interp, argc, argv) return TCL_OK; } +static int +map_arg_registers (argc, argv, func, argp) + int argc; + char *argv[]; + int (*func) PARAMS ((int regnum, void *argp)); + void *argp; +{ + int regnum; + + /* Note that the test for a valid register must include checking the + reg_names array because NUM_REGS may be allocated for the union of the + register sets within a family of related processors. In this case, the + trailing entries of reg_names will change depending upon the particular + processor being debugged. */ + + if (argc == 0) /* No args, just do all the regs */ + { + for (regnum = 0; + regnum < NUM_REGS + && reg_names[regnum] != NULL + && *reg_names[regnum] != '\000'; + regnum++) + func (regnum, argp); + + return TCL_OK; + } + + /* Else, list of register #s, just do listed regs */ + for (; argc > 0; argc--, argv++) + { + regnum = atoi (*argv); + + if (regnum >= 0 + && regnum < NUM_REGS + && reg_names[regnum] != NULL + && *reg_names[regnum] != '\000') + func (regnum, argp); + else + { + Tcl_SetResult (interp, "bad register number", TCL_STATIC); + + return TCL_ERROR; + } + } + + return TCL_OK; +} + +static int +get_register_name (regnum, argp) + int regnum; + void *argp; /* Ignored */ +{ + Tcl_AppendElement (interp, reg_names[regnum]); +} + /* This implements the TCL command `gdb_regnames', which returns a list of all of the register names. */ @@ -358,18 +414,142 @@ gdb_regnames (clientData, interp, argc, argv) int argc; char *argv[]; { - int i; + argc--; + argv++; + + return map_arg_registers (argc, argv, get_register_name, 0); +} + +static char reg_value[200]; +static char *reg_valp = reg_value; + +static void +save_reg_value (ptr) + const char *ptr; +{ + int len; + + len = strlen (ptr); + + strncpy (reg_valp, ptr, len + 1); + + reg_valp += len; +} + +#ifndef REGISTER_CONVERTIBLE +#define REGISTER_CONVERTIBLE(x) (0 != 0) +#endif + +#ifndef REGISTER_CONVERT_TO_VIRTUAL +#define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a) +#endif + +#ifndef INVALID_FLOAT +#define INVALID_FLOAT(x, y) (0 != 0) +#endif + +static int +get_register (regnum, fp) + void *fp; +{ + char raw_buffer[MAX_REGISTER_RAW_SIZE]; + char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; + int format = (int)fp; - if (argc != 1) + if (read_relative_register_raw_bytes (regnum, raw_buffer)) + { + Tcl_AppendElement (interp, "Optimized out"); + return; + } + + fputs_unfiltered_hook = save_reg_value; + flush_hook = 0; + reg_valp = reg_value; + + /* Convert raw data to virtual format if necessary. */ + + if (REGISTER_CONVERTIBLE (regnum)) + { + REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), + raw_buffer, virtual_buffer); + } + else + memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum)); + + val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, + gdb_stdout, format, 1, 0, Val_pretty_default); + + fputs_unfiltered_hook = gdbtk_fputs; + flush_hook = gdbtk_flush; + + Tcl_AppendElement (interp, reg_value); +} + +static int +gdb_fetch_registers (clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + char *argv[]; +{ + int format; + + if (argc < 2) { Tcl_SetResult (interp, "wrong # args", TCL_STATIC); return TCL_ERROR; } - for (i = 0; i < NUM_REGS; i++) - Tcl_AppendElement (interp, reg_names[i]); + argc--; + argv++; - return TCL_OK; + argc--; + format = **argv++; + + return map_arg_registers (argc, argv, get_register, format); +} + +/* This contains the previous values of the registers, since the last call to + gdb_changed_register_list. */ + +static char old_regs[REGISTER_BYTES]; + +static int +register_changed_p (regnum, argp) + void *argp; /* Ignored */ +{ + char raw_buffer[MAX_REGISTER_RAW_SIZE]; + char buf[100]; + + if (read_relative_register_raw_bytes (regnum, raw_buffer)) + return; + + if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, + REGISTER_RAW_SIZE (regnum)) == 0) + return; + + /* Found a changed register. Save new value and return it's number. */ + + memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, + REGISTER_RAW_SIZE (regnum)); + + sprintf (buf, "%d", regnum); + Tcl_AppendElement (interp, buf); +} + +static int +gdb_changed_register_list (clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + char *argv[]; +{ + int format; + + argc--; + argv++; + + return map_arg_registers (argc, argv, register_changed_p, NULL); } static int @@ -563,9 +743,13 @@ gdbtk_init () Tcl_CreateCommand (interp, "gdb_cmd", gdb_cmd, NULL, NULL); Tcl_CreateCommand (interp, "gdb_loc", gdb_loc, NULL, NULL); Tcl_CreateCommand (interp, "gdb_sourcelines", gdb_sourcelines, NULL, NULL); - Tcl_CreateCommand (interp, "gdb_regnames", gdb_regnames, NULL, NULL); Tcl_CreateCommand (interp, "gdb_listfiles", gdb_listfiles, NULL, NULL); Tcl_CreateCommand (interp, "gdb_stop", gdb_stop, NULL, NULL); + Tcl_CreateCommand (interp, "gdb_regnames", gdb_regnames, NULL, NULL); + Tcl_CreateCommand (interp, "gdb_fetch_registers", gdb_fetch_registers, NULL, + NULL); + Tcl_CreateCommand (interp, "gdb_changed_register_list", + gdb_changed_register_list, NULL, NULL); gdbtk_filename = getenv ("GDBTK_FILENAME"); if (!gdbtk_filename) |