This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[RFA] new BASEREG_ADDRESS macro


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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]