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]
Other format: [Raw text]

RFA: change to ia64-linux-tdep.c


The following changes the code in ia64_linux_sigcontext_register_address to use the fact that the sigframe has the address of the sigcontext area stored at offset 16 from the stack pointer. This change avoids using a magic constant to find the start of the sigcontext area which may change in various kernel versions as fields are added or subtracted to the sigframe.

Code has been tested with signal handling test cases.

The following is an excerpt of the linux kernel sigframe.h code:

struct sigframe {
/*
* Place signal handler args where user-level unwinder can find them easily.
* DO NOT MOVE THESE. They are part of the IA-64 Linux ABI and there is * user-level code that depends on their presence!
*/
unsigned long arg0; /* signum */
unsigned long arg1; /* siginfo pointer */
unsigned long arg2; /* sigcontext pointer */
/*
* End of architected state.
*/


Ok to Commit?

-- Jeff J.

2003-10-15 Jeff Johnston <jjohnstn@redhat.com>

	* ia64-linux-tdep.c: Include gdbcore.h.
	(IA64_LINUX_SIGCONTEXT_OFFSET): Magic constant removed.
	(ia64_linux_sigcontext_register_addr): Find the address of the
	sigcontext area stored in the sigframe instead of using
	a magic offset constant.
Index: ia64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-linux-tdep.c,v
retrieving revision 1.3
diff -u -r1.3 ia64-linux-tdep.c
--- ia64-linux-tdep.c	1 Jun 2001 02:22:01 -0000	1.3
+++ ia64-linux-tdep.c	15 Oct 2003 21:54:26 -0000
@@ -21,6 +21,7 @@
 
 #include "defs.h"
 #include "arch-utils.h"
+#include "gdbcore.h"
 
 /* The sigtramp code is in a non-readable (executable-only) region
    of memory called the ``gate page''.  The addresses in question
@@ -47,40 +48,47 @@
 CORE_ADDR
 ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno)
 {
+  char buf[8];
+  CORE_ADDR sigcontext_addr = 0;
+
+  /* The address of the sigcontext area is found at offset 16 in the sigframe.  */
+  read_memory (sp + 16, buf, 8);
+  sigcontext_addr = extract_unsigned_integer (buf, 8);
+
   if (IA64_GR0_REGNUM <= regno && regno <= IA64_GR31_REGNUM)
-    return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 200 + 8 * (regno - IA64_GR0_REGNUM);
+    return sigcontext_addr + 200 + 8 * (regno - IA64_GR0_REGNUM);
   else if (IA64_BR0_REGNUM <= regno && regno <= IA64_BR7_REGNUM)
-    return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 136 + 8 * (regno - IA64_BR0_REGNUM);
+    return sigcontext_addr + 136 + 8 * (regno - IA64_BR0_REGNUM);
   else if (IA64_FR0_REGNUM <= regno && regno <= IA64_FR127_REGNUM)
-    return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 464 + 16 * (regno - IA64_FR0_REGNUM);
+    return sigcontext_addr + 464 + 16 * (regno - IA64_FR0_REGNUM);
   else
     switch (regno)
       {
       case IA64_IP_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 40;
+	return sigcontext_addr + 40;
       case IA64_CFM_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 48;
+	return sigcontext_addr + 48;
       case IA64_PSR_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 56;		/* user mask only */
+	return sigcontext_addr + 56;		/* user mask only */
       /* sc_ar_rsc is provided, from which we could compute bspstore, but
 	 I don't think it's worth it.  Anyway, if we want it, it's at offset
 	 64 */
       case IA64_BSP_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 72;
+	return sigcontext_addr + 72;
       case IA64_RNAT_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 80;
+	return sigcontext_addr + 80;
       case IA64_CCV_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 88;
+	return sigcontext_addr + 88;
       case IA64_UNAT_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 96;
+	return sigcontext_addr + 96;
       case IA64_FPSR_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 104;
+	return sigcontext_addr + 104;
       case IA64_PFS_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 112;
+	return sigcontext_addr + 112;
       case IA64_LC_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 120;
+	return sigcontext_addr + 120;
       case IA64_PR_REGNUM :
-	return sp + IA64_LINUX_SIGCONTEXT_OFFSET + 128;
+	return sigcontext_addr + 128;
       default :
 	return 0;
       }

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