This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA] new BASEREG_ADDRESS macro
- To: gdb-patches at sources dot redhat dot com
- Subject: [RFA] new BASEREG_ADDRESS macro
- From: Nicholas Duffek <nsd at redhat dot com>
- Date: Wed, 3 Jan 2001 15:41:49 -0500
Recently I worked on an architecture in which the stack pointer, frame
pointer, and addresses in other address registers are relative to an
offset stored in a special register.
Consequently, when GDB uses an address in one of those registers, e.g. to
read a LOC_BASEREG symbol's value, the address must be modified by the
offset address.
This patch introduces a new multi-arch macro, BASEREG_ADDRESS(addr), which
gives targets the opportunity to adjust addresses retrieved from
SYMBOL_BASEREG(var) registers.
The default value for BASEREG_ADDRESS is core_addr_identity(addr), a new
function that returns its argument unchanged.
ChangeLog:
* arch-utils.c (core_addr_identity): New function.
* arch-utils.h (core_addr_identity): Prototype.
* findvar.c (read_var_value): Call BASEREG_ADDRESS.
* gdbarch.sh (BASEREG_ADDRESS): Define.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
No regressions on i686-pc-linux-gnu. Okay to apply?
Nicholas Duffek
<nsd@redhat.com>
[patch follows]
Index: gdb/arch-utils.c
===================================================================
diff -up gdb/arch-utils.c gdb/arch-utils.c
--- gdb/arch-utils.c Tue Jan 2 15:59:39 2001
+++ gdb/arch-utils.c Tue Jan 2 15:58:19 2001
@@ -163,6 +163,15 @@ core_addr_greaterthan (CORE_ADDR lhs, CO
}
+/* Helper function for BASEREG_ADDRESS. */
+
+CORE_ADDR
+core_addr_identity (CORE_ADDR addr)
+{
+ return addr;
+}
+
+
/* Helper functions for TARGET_{FLOAT,DOUBLE}_FORMAT */
const struct floatformat *
Index: gdb/arch-utils.h
===================================================================
diff -up gdb/arch-utils.h gdb/arch-utils.h
--- gdb/arch-utils.h Tue Jan 2 15:59:46 2001
+++ gdb/arch-utils.h Tue Jan 2 15:58:19 2001
@@ -63,6 +63,9 @@ extern gdbarch_prologue_frameless_p_ftyp
extern int core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs);
extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs);
+/* The usual case for BASEREG_ADDRESS. */
+extern CORE_ADDR core_addr_identity (CORE_ADDR addr);
+
/* Floating point values. */
extern const struct floatformat *default_float_format (struct gdbarch *gdbarch);
extern const struct floatformat *default_double_format (struct gdbarch *gdbarch);
Index: gdb/findvar.c
===================================================================
diff -up gdb/findvar.c gdb/findvar.c
--- gdb/findvar.c Tue Jan 2 15:59:57 2001
+++ gdb/findvar.c Tue Jan 2 15:58:19 2001
@@ -610,6 +610,7 @@ addresses have not been bound by the dyn
get_saved_register (buf, NULL, NULL, frame, SYMBOL_BASEREG (var),
NULL);
addr = extract_address (buf, REGISTER_RAW_SIZE (SYMBOL_BASEREG (var)));
+ addr = BASEREG_ADDRESS (addr);
addr += SYMBOL_VALUE (var);
break;
}
@@ -621,6 +622,7 @@ addresses have not been bound by the dyn
get_saved_register (buf, NULL, NULL, frame, SYMBOL_BASEREG (var),
NULL);
addr = extract_address (buf, REGISTER_RAW_SIZE (SYMBOL_BASEREG (var)));
+ addr = BASEREG_ADDRESS (addr);
addr += SYMBOL_VALUE (var);
break;
}
Index: gdb/gdbarch.sh
===================================================================
diff -up gdb/gdbarch.sh gdb/gdbarch.sh
--- gdb/gdbarch.sh Tue Jan 2 16:00:07 2001
+++ gdb/gdbarch.sh Tue Jan 2 15:58:19 2001
@@ -473,6 +473,8 @@ f:1:FRAME_CHAIN_VALID:int:frame_chain_va
f:2:FRAME_SAVED_PC:CORE_ADDR:frame_saved_pc:struct frame_info *fi:fi::0:0
f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:0
f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:0
+# Hook for modifying addresses retrieved from SYMBOL_BASEREG(var) registers.
+f:2:BASEREG_ADDRESS:CORE_ADDR:basereg_address:CORE_ADDR addr:addr:::core_addr_identity::0
f:2:SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame::0:0
f:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame::0:0
#
Index: gdb/gdbarch.c
===================================================================
diff -up gdb/gdbarch.c gdb/gdbarch.c
--- gdb/gdbarch.c Tue Jan 2 16:00:29 2001
+++ gdb/gdbarch.c Tue Jan 2 15:58:47 2001
@@ -229,6 +229,7 @@ struct gdbarch
gdbarch_frame_saved_pc_ftype *frame_saved_pc;
gdbarch_frame_args_address_ftype *frame_args_address;
gdbarch_frame_locals_address_ftype *frame_locals_address;
+ gdbarch_basereg_address_ftype *basereg_address;
gdbarch_saved_pc_after_call_ftype *saved_pc_after_call;
gdbarch_frame_num_args_ftype *frame_num_args;
gdbarch_stack_align_ftype *stack_align;
@@ -368,6 +369,7 @@ struct gdbarch startup_gdbarch =
0,
0,
0,
+ 0,
/* startup_gdbarch() */
};
@@ -447,6 +449,7 @@ gdbarch_alloc (const struct gdbarch_info
gdbarch->remote_translate_xfer_address = generic_remote_translate_xfer_address;
gdbarch->frame_args_skip = -1;
gdbarch->frameless_function_invocation = generic_frameless_function_invocation_not;
+ gdbarch->basereg_address = core_addr_identity;
gdbarch->extra_stack_alignment_needed = 1;
gdbarch->convert_from_func_ptr_addr = default_convert_from_func_ptr_addr;
/* gdbarch_alloc() */
@@ -675,6 +678,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
if ((GDB_MULTI_ARCH >= 2)
&& (gdbarch->frame_locals_address == 0))
internal_error ("gdbarch: verify_gdbarch: frame_locals_address invalid");
+ /* Skip verify of basereg_address, invalid_p == 0 */
if ((GDB_MULTI_ARCH >= 2)
&& (gdbarch->saved_pc_after_call == 0))
internal_error ("gdbarch: verify_gdbarch: saved_pc_after_call invalid");
@@ -1305,6 +1309,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
"FRAME_LOCALS_ADDRESS(fi)",
XSTRING (FRAME_LOCALS_ADDRESS (fi)));
#endif
+#ifdef BASEREG_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "BASEREG_ADDRESS(addr)",
+ XSTRING (BASEREG_ADDRESS (addr)));
+#endif
#ifdef SAVED_PC_AFTER_CALL
fprintf_unfiltered (file,
"gdbarch_dump: %s # %s\n",
@@ -2005,6 +2015,13 @@ gdbarch_dump (struct gdbarch *gdbarch, s
(long) current_gdbarch->frame_locals_address
/*FRAME_LOCALS_ADDRESS ()*/);
#endif
+#ifdef BASEREG_ADDRESS
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: BASEREG_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->basereg_address
+ /*BASEREG_ADDRESS ()*/);
+#endif
#ifdef SAVED_PC_AFTER_CALL
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@@ -3797,6 +3814,23 @@ set_gdbarch_frame_locals_address (struct
gdbarch_frame_locals_address_ftype frame_locals_address)
{
gdbarch->frame_locals_address = frame_locals_address;
+}
+
+CORE_ADDR
+gdbarch_basereg_address (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ if (gdbarch->basereg_address == 0)
+ internal_error ("gdbarch: gdbarch_basereg_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_basereg_address called\n");
+ return gdbarch->basereg_address (addr);
+}
+
+void
+set_gdbarch_basereg_address (struct gdbarch *gdbarch,
+ gdbarch_basereg_address_ftype basereg_address)
+{
+ gdbarch->basereg_address = basereg_address;
}
CORE_ADDR
Index: gdb/gdbarch.h
===================================================================
diff -up gdb/gdbarch.h gdb/gdbarch.h
--- gdb/gdbarch.h Tue Jan 2 16:00:40 2001
+++ gdb/gdbarch.h Tue Jan 2 15:58:29 2001
@@ -1290,6 +1290,22 @@ extern void set_gdbarch_frame_locals_add
#endif
#endif
+/* Hook for modifying addresses retrieved from SYMBOL_BASEREG(var) registers. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (BASEREG_ADDRESS)
+#define BASEREG_ADDRESS(addr) (core_addr_identity (addr))
+#endif
+
+typedef CORE_ADDR (gdbarch_basereg_address_ftype) (CORE_ADDR addr);
+extern CORE_ADDR gdbarch_basereg_address (struct gdbarch *gdbarch, CORE_ADDR addr);
+extern void set_gdbarch_basereg_address (struct gdbarch *gdbarch, gdbarch_basereg_address_ftype *basereg_address);
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (BASEREG_ADDRESS)
+#define BASEREG_ADDRESS(addr) (gdbarch_basereg_address (current_gdbarch, addr))
+#endif
+#endif
+
typedef CORE_ADDR (gdbarch_saved_pc_after_call_ftype) (struct frame_info *frame);
extern CORE_ADDR gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame);
extern void set_gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, gdbarch_saved_pc_after_call_ftype *saved_pc_after_call);