This is the mail archive of the
insight@sources.redhat.com
mailing list for the Insight project.
[PATCH] gdbtk-bp.c consolidation
- To: Insight Maling List <insight at sources dot redhat dot com>
- Subject: [PATCH] gdbtk-bp.c consolidation
- From: Keith Seitz <keiths at cygnus dot com>
- Date: Mon, 13 Aug 2001 11:39:30 -0700 (PDT)
Hi,
On a whim, I've cleaned this file up a little. There are two big changes:
1) Consolidate all the register functions under one tcl command,
"gdb_reginfo".
2) Add one new "gdb_reginfo" subcommand: "size", which tells us the raw
size of the register.
Note that this patch will break the register window, so you will need to
not update until I check in my "new" register window (which should happen
within the hour).
If there are any problems, please let me know.
Keith
ChangeLog
2001-08-13 Keith Seitz <keiths@redhat.com>
* generic/gdbtk-register.c (gdb_register_info): New function.
Consolidates all register handling.
(get_register_size): New function.
(gdb_changed_register_list, gdb_fetch_registers,
gdb_regnames): Deprecate.
(setup_architecture_data): Free old register cache
when necessary.
Patch
Index: generic/gdbtk-register.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/generic/gdbtk-register.c,v
retrieving revision 1.3
diff -u -p -r1.3 gdbtk-register.c
--- gdbtk-register.c 2001/07/31 17:34:56 1.3
+++ gdbtk-register.c 2001/08/13 18:34:49
@@ -30,16 +30,13 @@
/* This contains the previous values of the registers, since the last call to
gdb_changed_register_list. */
-static char *old_regs;
+static char *old_regs = NULL;
-static int gdb_changed_register_list (ClientData, Tcl_Interp *, int,
- Tcl_Obj * CONST[]);
-static int gdb_fetch_registers (ClientData, Tcl_Interp *, int,
- Tcl_Obj * CONST[]);
-static int gdb_regnames (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]);
static int get_pc_register (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]);
+static int gdb_register_info (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]);
static void get_register (int, void *);
static void get_register_name (int, void *);
+static void get_register_size (int regnum, void *arg);
static int map_arg_registers (int, Tcl_Obj * CONST[],
void (*)(int, void *), void *);
static void register_changed_p (int, void *);
@@ -48,12 +45,8 @@ static void setup_architecture_data (voi
int
Gdbtk_Register_Init (Tcl_Interp *interp)
{
- Tcl_CreateObjCommand (interp, "gdb_changed_register_list", gdbtk_call_wrapper,
- gdb_changed_register_list, NULL);
- Tcl_CreateObjCommand (interp, "gdb_fetch_registers", gdbtk_call_wrapper,
- gdb_fetch_registers, NULL);
- Tcl_CreateObjCommand (interp, "gdb_regnames", gdbtk_call_wrapper, gdb_regnames,
- NULL);
+ Tcl_CreateObjCommand (interp, "gdb_reginfo", gdbtk_call_wrapper,
+ gdb_register_info, NULL);
Tcl_CreateObjCommand (interp, "gdb_pc_reg", gdbtk_call_wrapper, get_pc_register,
NULL);
@@ -65,110 +58,127 @@ Gdbtk_Register_Init (Tcl_Interp *interp)
return TCL_OK;
}
-/* This implements the tcl command "gdb_changed_register_list"
- * It takes a list of registers, and returns a list of
- * the registers on that list that have changed since the last
- * time the proc was called.
+/* This implements the tcl command "gdb_reginfo".
+ * It returns the requested information about registers.
*
* Tcl Arguments:
- * A list of registers.
- * Tcl Result:
- * A list of changed registers.
- */
-static int
-gdb_changed_register_list (clientData, interp, objc, objv)
- ClientData clientData;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- objc--;
- objv++;
-
- return map_arg_registers (objc, objv, register_changed_p, NULL);
-}
-
-/* This implements the tcl command gdb_fetch_registers
- * Pass it a list of register names, and it will
- * return their values as a list.
+ * OPTION - "changed", "name", "size", "value" (see below)
+ * REGNUM(S) - the register(s) for which info is requested
*
- * Tcl Arguments:
- * format: The format string for printing the values
- * args: the registers to look for
* Tcl Result:
- * A list of their values.
+ * The requested information
+ *
+ * Options:
+ * changed
+ * Returns a list of registers whose values have changed since the
+ * last time the proc was called.
+ *
+ * usage: gdb_reginfo changed [regnum0, ..., regnumN]
+ *
+ * name
+ * Return a list containing the names of the registers whose numbers
+ * are given by REGNUM ... . If no register numbers are given, return
+ * all the registers' names.
+ *
+ * usage: gdb_reginfo name [-numbers] [regnum0, ..., regnumN]
+ *
+ * Note that some processors have gaps in the register numberings:
+ * even if there is no register numbered N, there may still be a
+ * register numbered N+1. So if you call gdb_regnames with no
+ * arguments, you can't assume that the N'th element of the result is
+ * register number N.
+ *
+ * Given the -numbers option, gdb_regnames returns, not a list of names,
+ * but a list of pairs {NAME NUMBER}, where NAME is the register name,
+ * and NUMBER is its number.
+ *
+ * size
+ * Returns the raw size of the register(s) in bytes.
+ *
+ * usage: gdb_reginfo size [regnum0, ..., regnumN]
+ *
+ * value
+ * Returns a list of register values.
+ *
+ * usage: gdb_reginfo value format [regnum0, ..., regnumN]
+ * format: The format string for printing the values, "N", "x", "d", etc
*/
static int
-gdb_fetch_registers (clientData, interp, objc, objv)
- ClientData clientData;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
+gdb_register_info (ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[])
{
- int format, result;
+ int regnum, index, result;
+ void *argp;
+ void (*func)(int, void *);
+ static char *commands[] = {"changed", "name", "size", "value", NULL};
+ enum commands_enum { REGINFO_CHANGED, REGINFO_NAME, REGINFO_SIZE, REGINFO_VALUE };
if (objc < 2)
{
- Tcl_WrongNumArgs (interp, 1, objv, "format ?register1 register2 ...?");
+ Tcl_WrongNumArgs (interp, 1, objv, "name|size|value [regnum1 ... regnumN]");
return TCL_ERROR;
}
- objc -= 2;
- objv++;
- format = *(Tcl_GetStringFromObj (objv[0], NULL));
- objv++;
-
- if (objc != 1)
- result_ptr->flags |= GDBTK_MAKES_LIST; /* Output the results as a list */
- result = map_arg_registers (objc, objv, get_register, (void *) format);
- if (objc != 1)
- result_ptr->flags &= ~GDBTK_MAKES_LIST;
- return result;
-}
+ if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0,
+ &index) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
-/* This implements the TCL command `gdb_regnames'. Its syntax is:
+ /* Skip the option */
+ objc -= 2;
+ objv += 2;
- gdb_regnames [-numbers] [REGNUM ...]
+ switch ((enum commands_enum) index)
+ {
+ case REGINFO_CHANGED:
+ func = register_changed_p;
+ argp = NULL;
+ break;
- Return a list containing the names of the registers whose numbers
- are given by REGNUM ... . If no register numbers are given, return
- all the registers' names.
-
- Note that some processors have gaps in the register numberings:
- even if there is no register numbered N, there may still be a
- register numbered N+1. So if you call gdb_regnames with no
- arguments, you can't assume that the N'th element of the result is
- register number N.
-
- Given the -numbers option, gdb_regnames returns, not a list of names,
- but a list of pairs {NAME NUMBER}, where NAME is the register name,
- and NUMBER is its number. */
-static int
-gdb_regnames (clientData, interp, objc, objv)
- ClientData clientData;
- Tcl_Interp *interp;
- int objc;
- Tcl_Obj *CONST objv[];
-{
- int numbers = 0;
+ case REGINFO_NAME:
+ {
+ int len;
+ char *s = Tcl_GetStringFromObj (objv[0], &len);
+ if (objc != 0 && strncmp (s, "-numbers", len) == 0)
+ {
+ argp = (void *) 1;
+ objc--;
+ objv++;
+ }
+ else
+ argp = NULL;
- objc--;
- objv++;
+ func = get_register_name;
+ }
+ break;
- if (objc >= 1)
- {
- char *s = Tcl_GetStringFromObj (objv[0], NULL);
- if (STREQ (s, "-numbers"))
- {
- numbers = 1;
- objc--;
- objv++;
- }
+ case REGINFO_SIZE:
+ func = get_register_size;
+ argp = NULL;
+ break;
+
+ case REGINFO_VALUE:
+ func = get_register;
+ argp = (void *) (int) *(Tcl_GetStringFromObj (objv[0], NULL));
+ objc--;
+ objv++;
+ break;
+
+ default:
+ return TCL_ERROR;
}
- return map_arg_registers (objc, objv, get_register_name, &numbers);
+ return map_arg_registers (objc, objv, func, argp);
}
+static void
+get_register_size (int regnum, void *arg)
+{
+ Tcl_ListObjAppendElement (gdbtk_interp, result_ptr->obj_ptr,
+ Tcl_NewIntObj (REGISTER_RAW_SIZE (regnum)));
+}
+
/* This implements the tcl command get_pc_reg
* It returns the value of the PC register
*
@@ -186,7 +196,7 @@ get_pc_register (clientData, interp, obj
{
char *buff;
- xasprintf (&buff, "0x%llx", (long long) read_register (PC_REGNUM));
+ xasprintf (&buff, "0x%s", paddr_nz (read_register (PC_REGNUM)));
Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1);
free(buff);
return TCL_OK;
@@ -265,7 +275,7 @@ get_register_name (regnum, argp)
void *argp;
{
/* Non-zero if the caller wants the register numbers, too. */
- int numbers = * (int *) argp;
+ int numbers = (int) argp;
Tcl_Obj *name = Tcl_NewStringObj (REGISTER_NAME (regnum), -1);
Tcl_Obj *elt;
@@ -303,7 +313,10 @@ map_arg_registers (objc, objv, func, arg
the particular processor being debugged. */
numregs = NUM_REGS + NUM_PSEUDO_REGS;
-
+
+ if (objc == 0 || objc > 1)
+ result_ptr->flags |= GDBTK_MAKES_LIST;
+
if (objc == 0) /* No args, just do all the regs */
{
for (regnum = 0;
@@ -370,6 +383,9 @@ static void
setup_architecture_data ()
{
/* don't trust REGISTER_BYTES to be zero. */
+ if (old_regs != NULL)
+ xfree (old_regs);
+
old_regs = xmalloc (REGISTER_BYTES + 1);
memset (old_regs, 0, REGISTER_BYTES + 1);
}