This is the mail archive of the
insight@sources.redhat.com
mailing list for the Insight project.
[patch] address cleanup
- From: "Martin M. Hunt" <hunt at redhat dot com>
- To: "insight at sources dot redhat dot com" <insight at sources dot redhat dot com>
- Date: 05 Mar 2003 17:25:31 -0800
- Subject: [patch] address cleanup
Executive Summary: I've checked in this patch which fixes long-standing
problems with Insight and Mips.
Long Story:
GDB internally represents an addresses as a "CORE_ADDR". This may be
the same as a target address, or on some architectures it will be quite
different. For example some architectures (like Harvard CPUs) have
separate instruction and data addresses. In the case of Mips, a
CORE_ADDR is always 64-bits even when the ABI is 32-bits. This means
that GDB is passing around addresses like 0xffffffff90000000 instead of
0x90000000. You will see this in GDB sometimes:
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0xffffffffa0020310 in main at pi1.c:36
(gdb) info line 36
Line 36 of "pi1.c" starts at address 0xa0020310 <main+24> and ends at
0xa0020314 <main+28>.
Insight is trying to layer a GUI on top of GDB and it gets really
annoyed at little inconsistencies like this. In other words it didn't
work well.
In this patch, I change all (I hope) the glue code between GDB and
Insight to exchange only CORE_ADDRs. However, the user doesn't really
want to see CORE_ADDRs, so I create a new tcl function gdb_CA_to_TAS()
that converts a CORE_ADDR to a target address string. Every Insight
function that displays an address should call it.
2003-03-05 Martin M. Hunt <hunt at redhat dot com>
* generic/gdbtk-cmds.c (Gdbtk_Init): Create gdb_CA_to_TAS.
(gdb_load_disassembly): Now takes CORE_ADDRs. Returns CORE_ADDRs
for low and high.
(gdbtk_load_asm): Use CORE_ADDRs.
(gdb_loc): Return CORE_ADDRs.
(gdb_entry_point): Return CORE_ADDR.
(gdb_incr_addr): Update description.
(gdb_CA_to_TAS): New function. Takes a CORE_ADDR and returns
a target sddress string.
* generic/gdbtk-bp.c (gdb_find_bp_at_addr): Change to
take a CORE_ADDR.
(gdb_get_breakpoint_info): Returns a CORE_ADDR.
(gdb_set_bp_addr): Takes a CORE_ADDR.
* library/bpwin.itb (bp_add): Call gdb_CA_to_TAS before
displaying address.
(bp_modify): Ditto.
* library/srcwin.itb (location): Call gdb_CA_to_TAS before
displaying address. Don't add "0x" in front of address.
(set_execution_status): Call gdb_CA_to_TAS before
displaying address. Don't call [gdb_cmd printf] to format
output. Weird.
Index: generic/gdbtk-bp.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/generic/gdbtk-bp.c,v
retrieving revision 1.17
diff -u -u -r1.17 gdbtk-bp.c
--- generic/gdbtk-bp.c 3 Aug 2002 16:22:07 -0000 1.17
+++ generic/gdbtk-bp.c 6 Mar 2003 01:08:20 -0000
@@ -194,7 +194,7 @@
/* This implements the tcl command "gdb_find_bp_at_addr"
* Tcl Arguments:
-* addr: address
+* addr: CORE_ADDR
* Tcl Result:
* It returns a list of breakpoint numbers
*/
@@ -204,14 +204,17 @@
{
int i;
CORE_ADDR addr;
+ Tcl_WideInt waddr;
if (objc != 2)
{
Tcl_WrongNumArgs (interp, 1, objv, "address");
return TCL_ERROR;
}
-
- addr = string_to_core_addr (Tcl_GetStringFromObj (objv[1], NULL));
+
+ if (Tcl_GetWideIntFromObj (interp, objv[1], &waddr) != TCL_OK)
+ return TCL_ERROR;
+ addr = waddr;
Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL);
for (i = 0; i < breakpoint_list_size; i++)
@@ -323,8 +326,8 @@
Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
Tcl_NewIntObj (b->line_number));
- sprintf_append_element_to_obj (result_ptr->obj_ptr, "0x%s",
- paddr_nz (b->address));
+ Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
+ Tcl_NewStringObj (core_addr_to_string (b->address), -1));
Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
Tcl_NewStringObj (bptypes[b->type], -1));
Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
@@ -540,7 +543,7 @@
* It sets breakpoints, and notifies the GUI.
*
* Tcl Arguments:
- * addr: the address at which to set the breakpoint
+ * addr: the CORE_ADDR at which to set the breakpoint
* type: the type of the breakpoint
* thread: optional thread number
* Tcl Result:
@@ -554,6 +557,7 @@
struct symtab_and_line sal;
int thread = -1;
CORE_ADDR addr;
+ Tcl_WideInt waddr;
struct breakpoint *b;
char *saddr, *typestr;
enum bpdisp disp;
@@ -564,9 +568,11 @@
return TCL_ERROR;
}
+ if (Tcl_GetWideIntFromObj (interp, objv[1], &waddr) != TCL_OK)
+ return TCL_ERROR;
+ addr = waddr;
saddr = Tcl_GetStringFromObj (objv[1], NULL);
- addr = string_to_core_addr (saddr);
-
+
typestr = Tcl_GetStringFromObj (objv[2], NULL);
if (strncmp (typestr, "temp", 4) == 0)
disp = disp_del;
Index: generic/gdbtk-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/generic/gdbtk-cmds.c,v
retrieving revision 1.69
diff -u -u -r1.69 gdbtk-cmds.c
--- generic/gdbtk-cmds.c 25 Feb 2003 21:36:22 -0000 1.69
+++ generic/gdbtk-cmds.c 6 Mar 2003 01:08:21 -0000
@@ -151,6 +151,7 @@
static int gdb_immediate_command (ClientData, Tcl_Interp *, int,
Tcl_Obj * CONST[]);
static int gdb_incr_addr (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]);
+static int gdb_CA_to_TAS (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]);
static int gdb_listfiles (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]);
static int gdb_listfuncs (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]);
static int gdb_loadfile (ClientData, Tcl_Interp *, int,
@@ -242,6 +243,7 @@
gdb_disassemble, NULL);
Tcl_CreateObjCommand (interp, "gdb_eval", gdbtk_call_wrapper, gdb_eval, NULL);
Tcl_CreateObjCommand (interp, "gdb_incr_addr", gdbtk_call_wrapper, gdb_incr_addr, NULL);
+ Tcl_CreateObjCommand (interp, "gdb_CA_to_TAS", gdbtk_call_wrapper, gdb_CA_to_TAS, NULL);
Tcl_CreateObjCommand (interp, "gdb_clear_file", gdbtk_call_wrapper,
gdb_clear_file, NULL);
Tcl_CreateObjCommand (interp, "gdb_confirm_quit", gdbtk_call_wrapper,
@@ -1571,8 +1573,8 @@
* Arguments:
* widget - the name of a text widget into which to load the data
* source_with_assm - must be "source" or "nosource"
- * low_address - the address from which to start disassembly
- * ?hi_address? - the address to which to disassemble, defaults
+ * low_address - the CORE_ADDR from which to start disassembly
+ * ?hi_address? - the CORE_ADDR to which to disassemble, defaults
* to the end of the function containing low_address.
* Tcl Result:
* The text widget is loaded with the data, and a list is returned.
@@ -1592,6 +1594,7 @@
int mixed_source_and_assembly, ret_val, i;
char *arg_ptr;
char *map_name;
+ Tcl_WideInt waddr;
if (objc != 6 && objc != 7)
{
@@ -1677,20 +1680,24 @@
}
/* Now parse the addresses */
-
- low = string_to_core_addr (Tcl_GetStringFromObj (objv[5], NULL));
+ if (Tcl_GetWideIntFromObj (interp, objv[5], &waddr) != TCL_OK)
+ return TCL_ERROR;
+ low = waddr;
+
orig = low;
if (objc == 6)
{
if (find_pc_partial_function (low, NULL, &low, &high) == 0)
- error ("No function contains address 0x%s (%s)",
- paddr_nz (orig), Tcl_GetStringFromObj (objv[5], NULL));
+ error ("No function contains address 0x%s", core_addr_to_string (orig));
}
else
- high = string_to_core_addr (Tcl_GetStringFromObj (objv[6], NULL));
-
-
+ {
+ if (Tcl_GetWideIntFromObj (interp, objv[6], &waddr) != TCL_OK)
+ return TCL_ERROR;
+ high = waddr;
+ }
+
/* Setup the client_data structure, and call the driver function. */
client_data.file_opened_p = 0;
@@ -1755,19 +1762,10 @@
if (ret_val == TCL_OK)
{
- char *buffer;
- Tcl_Obj *limits_obj[2];
-
- xasprintf (&buffer, "0x%s", paddr_nz (low));
- limits_obj[0] = Tcl_NewStringObj (buffer, -1);
- free(buffer);
-
- xasprintf (&buffer, "0x%s", paddr_nz (high));
- limits_obj[1] = Tcl_NewStringObj (buffer, -1);
- free(buffer);
-
- Tcl_DecrRefCount (result_ptr->obj_ptr);
- result_ptr->obj_ptr = Tcl_NewListObj (2, limits_obj);
+ Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
+ Tcl_NewStringObj (core_addr_to_string (low), -1));
+ Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
+ Tcl_NewStringObj (core_addr_to_string (high), -1));
}
return ret_val;
}
@@ -1914,6 +1912,7 @@
const char **text_argv;
int i, pc_to_line_len, line_to_pc_len;
gdbtk_result new_result;
+ int insn;
struct cleanup *old_chain = NULL;
pc_to_line_len = Tcl_DStringLength (&client_data->pc_to_line_prefix);
@@ -1933,17 +1932,16 @@
for (i = 0; i < 3; i++)
Tcl_SetObjLength (client_data->result_obj[i], 0);
-
+
print_address_numeric (pc, 1, gdb_stdout);
gdb_flush (gdb_stdout);
result_ptr->obj_ptr = client_data->result_obj[1];
-
print_address_symbolic (pc, gdb_stdout, 1, "\t");
gdb_flush (gdb_stdout);
result_ptr->obj_ptr = client_data->result_obj[2];
- pc += TARGET_PRINT_INSN (pc, di);
+ insn = TARGET_PRINT_INSN (pc, di);
gdb_flush (gdb_stdout);
client_data->widget_line_no++;
@@ -1962,7 +1960,7 @@
/* Run the command, then add an entry to the map array in
the caller's scope. */
- Tcl_DStringAppend (&client_data->pc_to_line_prefix, text_argv[5], -1);
+ Tcl_DStringAppend (&client_data->pc_to_line_prefix, core_addr_to_string (pc), -1);
/* FIXME: Convert to Tcl_SetVar2Ex when we move to 8.2. This
will allow us avoid converting widget_line_no into a string. */
@@ -1975,10 +1973,11 @@
Tcl_DStringAppend (&client_data->line_to_pc_prefix, buffer, -1);
+
Tcl_SetVar2 (client_data->interp, client_data->map_arr,
Tcl_DStringValue (&client_data->line_to_pc_prefix),
- text_argv[5], 0);
-
+ core_addr_to_string (pc), 0);
+
/* Restore the prefixes to their initial state. */
Tcl_DStringSetLength (&client_data->pc_to_line_prefix, pc_to_line_len);
@@ -1988,8 +1987,8 @@
}
do_cleanups (old_chain);
-
- return pc;
+
+ return pc + insn;
}
static void
@@ -2322,17 +2321,15 @@
filename = "";
/* file name */
- Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
- Tcl_NewStringObj (filename, -1));
+ Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj (filename, -1));
/* line number */
- Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
- Tcl_NewIntObj (sal.line));
+ Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewIntObj (sal.line));
/* PC in current frame */
- sprintf_append_element_to_obj (result_ptr->obj_ptr, "0x%s", paddr_nz (pc));
+ Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
+ Tcl_NewStringObj (core_addr_to_string (pc), -1));
/* Real PC */
- sprintf_append_element_to_obj (result_ptr->obj_ptr, "0x%s",
- paddr_nz (stop_pc));
-
+ Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
+ Tcl_NewStringObj (core_addr_to_string (stop_pc), -1));
/* shared library */
#ifdef PC_SOLIB
Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
@@ -2357,7 +2354,7 @@
entry point, so return an empty string.*/
if ((int) current_target.to_stratum > (int) dummy_stratum)
{
- addrstr = paddr_nz (entry_point_address ());
+ addrstr = (char *)core_addr_to_string (entry_point_address ());
Tcl_SetStringObj (result_ptr->obj_ptr, addrstr, -1);
}
else
@@ -3040,16 +3037,22 @@
/* This implements the tcl command 'gdb_incr_addr'.
- * It increments addresses, which must be implemented
- * this way because tcl cannot handle 64-bit values.
+ * It does address arithmetic and outputs a proper
+ * hex string. This was originally implemented
+ * when tcl did not support 64-bit values, but we keep
+ * it because it saves us from having to call incr
+ * followed by format to get the result in hex.
+ * Also, it may be true in the future that CORE_ADDRs
+ * will have their own ALU to deal properly with
+ * architecture-specific address arithmetic.
*
* Tcl Arguments:
- * addr - 32 or 64-bit address
+ * addr - CORE_ADDR
* number - optional number to add to the address
* default is 1.
*
* Tcl Result:
- * addr + number
+ * hex string containing the result of addr + number
*/
static int
@@ -3061,7 +3064,7 @@
if (objc != 2 && objc != 3)
{
- Tcl_WrongNumArgs (interp, 1, objv, "address [number]");
+ Tcl_WrongNumArgs (interp, 1, objv, "CORE_ADDR [number]");
return TCL_ERROR;
}
@@ -3077,5 +3080,50 @@
Tcl_SetStringObj (result_ptr->obj_ptr, (char *)core_addr_to_string (address), -1);
+ return TCL_OK;
+}
+
+/* This implements the tcl command 'gdb_CAS_to_TAS'.
+ * It takes a CORE_ADDR and outputs a string suitable
+ * for displaying as the target address.
+ *
+ * Note that CORE_ADDRs are internal addresses which map
+ * to target addresses in different ways depending on the
+ * architecture. The target address string is a user-readable
+ * string may be quite different than the CORE_ADDR. For example,
+ * a CORE_ADDR of 0x02001234 might indicate a data address of
+ * 0x1234 which this function might someday output as something
+ * like "D:1234".
+ *
+ * Tcl Arguments:
+ * address - CORE_ADDR
+ *
+ * Tcl Result:
+ * string
+ */
+
+static int
+gdb_CA_to_TAS (ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[])
+{
+ CORE_ADDR address;
+ Tcl_WideInt wide_addr;
+
+ if (objc != 2)
+ {
+ Tcl_WrongNumArgs (interp, 1, objv, "CORE_ADDR");
+ return TCL_ERROR;
+ }
+
+ /* Read address into a wideint, which is the largest tcl supports
+ then convert to a CORE_ADDR */
+ if (Tcl_GetWideIntFromObj (interp, objv[1], &wide_addr) != TCL_OK)
+ return TCL_ERROR;
+ address = wide_addr;
+
+ /* This is not really correct. Using paddr_nz() will convert to hex and truncate
+ to 32-bits when required but will otherwise not do what we really want. */
+ Tcl_SetStringObj (result_ptr->obj_ptr, paddr_nz (address), -1);
+
return TCL_OK;
}
Index: library/bpwin.itb
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/library/bpwin.itb,v
retrieving revision 1.16
diff -u -u -r1.16 bpwin.itb
--- library/bpwin.itb 21 Jan 2003 21:58:20 -0000 1.16
+++ library/bpwin.itb 6 Mar 2003 01:08:21 -0000
@@ -239,7 +239,7 @@
if {$tracepoints} {
label $twin.num$i -text "$number " -relief flat -anchor w -font global/fixed
}
- label $twin.addr$i -text "[$bp_event get address] " -relief flat -anchor w -font global/fixed -bg $bg1
+ label $twin.addr$i -text "[gdb_CA_to_TAS [$bp_event get address]] " -relief flat -anchor w -font global/fixed -bg $bg1
if {[info exists _files(short,$file)]} {
set file $_files(short,$file)
} else {
@@ -493,7 +493,7 @@
if {$tracepoints} {
$twin.num$i configure -text "$number "
}
- $twin.addr$i configure -text "[$bp_event get address] "
+ $twin.addr$i configure -text "[gdb_CA_to_TAS [$bp_event get address]] "
if {[info exists _files(short,$file)]} {
set file $_files(short,$file)
} else {
Index: library/srcwin.itb
===================================================================
RCS file: /cvs/src/src/gdb/gdbtk/library/srcwin.itb,v
retrieving revision 1.29
diff -u -u -r1.29 srcwin.itb
--- library/srcwin.itb 4 Feb 2003 07:43:32 -0000 1.29
+++ library/srcwin.itb 6 Mar 2003 01:08:21 -0000
@@ -416,8 +416,8 @@
# 3: source line number
# 4: address
# 5: current PC - which will often be the same as address, but not when
+# we are browsing, or walking the stack.
# 6: shared library name if the pc is in a shared lib
-# we are browsing, or walking the stack.
#
# linespec will be "{} {} {} 0 0x0 0x0" when GDB has not started debugging.
# ------------------------------------------------------------------
@@ -465,15 +465,18 @@
fillFuncCB $name
}
+ # get a proper address string to display
+ set textaddr [gdb_CA_to_TAS $addr]
+
# set address and line widgets
- if {[string length $addr] > 10} {
- # 64-bit address plus "0x"
- set width 18
+ if {[string length $textaddr] > 8} {
+ # 64-bit address
+ set width 16
} else {
- # 32-bit address plus "0x"
- set width 10
+ # 32-bit address
+ set width 8
}
- $_statusframe.addr configure -text $addr -font global/fixed -width $width
+ $_statusframe.addr configure -text $textaddr -font global/fixed -width $width
$_statusframe.line configure -text $line
# set function combobox
@@ -669,6 +672,8 @@
}
}
+ set pc [gdb_CA_to_TAS $pc]
+
if {$line == "" || $line == 0} {
if {$pc == "" || $pc == 0} {
if {$Tracing} {
@@ -677,7 +682,7 @@
set message "Program stopped."
}
} else {
- set message [gdb_cmd "printf \"Program stopped at %lx\",$pc"]
+ set message "Program stopped at 0x$pc"
}
} else {
if {$Tracing} {
@@ -686,9 +691,9 @@
set msg "Program stopped"
}
switch [$twin mode_get] {
- ASSEMBLY {set message [gdb_cmd "printf \"$msg at 0x%lx\",$pc"] }
- MIXED {set message [gdb_cmd "printf \"$msg at line $line, 0x%lx\",$pc"] }
- SRC+ASM {set message [gdb_cmd "printf \"$msg at line $line, 0x%lx\",$pc"] }
+ ASSEMBLY {set message "$msg at 0x$pc" }
+ MIXED {set message "$msg at line $line, 0x$pc" }
+ SRC+ASM {set message "$msg at line $line, 0x$pc" }
default {set message "$msg at line $line" }
}
}