This is the mail archive of the gdb-patches@sourceware.cygnus.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]

Re: Linux sigtramp detection code moved to its proper place



I'm sorry --- this is obviously a tdep issue.  Does the following
change look better?


2000-03-17  Jim Blandy  <jimb@redhat.com>

	* i386-linux-nat.c: No need to #include "frame.h" any more.
	(LINUX_SIGTRAMP_INSN0, LINUX_SIGTRAMP_OFFSET0,
	LINUX_SIGTRAMP_INSN1, LINUX_SIGTRAMP_OFFSET1,
	LINUX_SIGTRAMP_INSN2, LINUX_SIGTRAMP_OFFSET2, linux_sigtramp_code,
	LINUX_SIGTRAMP_LEN, i386_linux_sigtramp_start,
	LINUX_RT_SIGTRAMP_INSN0, LINUX_RT_SIGTRAMP_OFFSET0,
	LINUX_RT_SIGTRAMP_INSN1, LINUX_RT_SIGTRAMP_OFFSET1,
	linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN,
	i386_linux_rt_sigtramp_start, i386_linux_in_sigtramp,
	i386_linux_sigcontext_addr, LINUX_SIGCONTEXT_PC_OFFSET,
	i386_linux_sigtramp_saved_pc, LINUX_SIGCONTEXT_SP_OFFSET,
	i386_linux_sigtramp_saved_sp):	Deleted.  Folks rightly pointed
	out that these are target-dependent, and useful in non-native
	configurations.  Moved to...
	* i386-linux-tdep.c: ... Here, a new file.
	* Makefile.in (ALLDEPFILES): Add i386-linux-tdep.c.
	(i386-linux-tdep.o): New rule.
	(i386-linux-nat.o): We no longer depend on frame.h.
	* config/i386/linux.mt (TDEPFILES): Add i386-linux-tdep.o.

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.13
diff -c -r1.13 Makefile.in
*** gdb/Makefile.in	2000/03/16 10:23:38	1.13
--- gdb/Makefile.in	2000/03/17 19:59:40
***************
*** 1063,1068 ****
--- 1063,1069 ----
  	i386-tdep.c i386b-nat.c i386mach-nat.c i386v-nat.c i386-linux-nat.c \
  	i386aix-nat.c i386m3-nat.c i386v4-nat.c i386ly-tdep.c \
  	i387-tdep.c \
+ 	i386-linux-tdep.c \
  	i960-tdep.c \
  	infptrace.c inftarg.c irix4-nat.c irix5-nat.c isi-xdep.c \
  	lynx-nat.c m3-nat.c \
***************
*** 1395,1401 ****
  	$(inferior_h) language.h target.h
  
  i386-linux-nat.o: i386-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
! 	$(symtab_h) $(frame_h) symfile.h objfiles.h
  
  i386v4-nat.o: i386v4-nat.c $(defs_h)
  
--- 1396,1405 ----
  	$(inferior_h) language.h target.h
  
  i386-linux-nat.o: i386-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
! 	$(symtab_h) symfile.h objfiles.h
! 
! i386-linux-tdep.o: i386-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
! 	$(value_h)
  
  i386v4-nat.o: i386v4-nat.c $(defs_h)
  
Index: gdb/i386-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-linux-nat.c,v
retrieving revision 1.7
diff -c -r1.7 i386-linux-nat.c
*** gdb/i386-linux-nat.c	2000/03/16 23:53:35	1.7
--- gdb/i386-linux-nat.c	2000/03/17 19:59:41
***************
*** 23,29 ****
  
  /* For i386_linux_skip_solib_resolver.  */
  #include "symtab.h"
- #include "frame.h"
  #include "symfile.h"
  #include "objfiles.h"
  
--- 23,28 ----
***************
*** 1041,1303 ****
      return result;
  
    return 0;
- }
- 
- 
- /* Recognizing signal handler frames.  */
- 
- /* Linux has two flavors of signals.  Normal signal handlers, and
-    "realtime" (RT) signals.  The RT signals can provide additional
-    information to the signal handler if the SA_SIGINFO flag is set
-    when establishing a signal handler using `sigaction'.  It is not
-    unlikely that future versions of Linux will support SA_SIGINFO for
-    normal signals too.  */
- 
- /* When the i386 Linux kernel calls a signal handler and the
-    SA_RESTORER flag isn't set, the return address points to a bit of
-    code on the stack.  This function returns whether the PC appears to
-    be within this bit of code.
- 
-    The instruction sequence for normal signals is
-        pop    %eax
-        mov    $0x77,%eax
-        int    $0x80
-    or 0x58 0xb8 0x77 0x00 0x00 0x00 0xcd 0x80.
- 
-    Checking for the code sequence should be somewhat reliable, because
-    the effect is to call the system call sigreturn.  This is unlikely
-    to occur anywhere other than a signal trampoline.
- 
-    It kind of sucks that we have to read memory from the process in
-    order to identify a signal trampoline, but there doesn't seem to be
-    any other way.  The IN_SIGTRAMP macro in tm-linux.h arranges to
-    only call us if no function name could be identified, which should
-    be the case since the code is on the stack.
- 
-    Detection of signal trampolines for handlers that set the
-    SA_RESTORER flag is in general not possible.  Unfortunately this is
-    what the GNU C Library has been doing for quite some time now.
-    However, as of version 2.1.2, the GNU C Library uses signal
-    trampolines (named __restore and __restore_rt) that are identical
-    to the ones used by the kernel.  Therefore, these trampolines are
-    supported too.  */
- 
- #define LINUX_SIGTRAMP_INSN0 (0x58)	/* pop %eax */
- #define LINUX_SIGTRAMP_OFFSET0 (0)
- #define LINUX_SIGTRAMP_INSN1 (0xb8)	/* mov $NNNN,%eax */
- #define LINUX_SIGTRAMP_OFFSET1 (1)
- #define LINUX_SIGTRAMP_INSN2 (0xcd)	/* int */
- #define LINUX_SIGTRAMP_OFFSET2 (6)
- 
- static const unsigned char linux_sigtramp_code[] =
- {
-   LINUX_SIGTRAMP_INSN0,					/* pop %eax */
-   LINUX_SIGTRAMP_INSN1, 0x77, 0x00, 0x00, 0x00,		/* mov $0x77,%eax */
-   LINUX_SIGTRAMP_INSN2, 0x80				/* int $0x80 */
- };
- 
- #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
- 
- /* If PC is in a sigtramp routine, return the address of the start of
-    the routine.  Otherwise, return 0.  */
- 
- static CORE_ADDR
- i386_linux_sigtramp_start (CORE_ADDR pc)
- {
-   unsigned char buf[LINUX_SIGTRAMP_LEN];
- 
-   /* We only recognize a signal trampoline if PC is at the start of
-      one of the three instructions.  We optimize for finding the PC at
-      the start, as will be the case when the trampoline is not the
-      first frame on the stack.  We assume that in the case where the
-      PC is not at the start of the instruction sequence, there will be
-      a few trailing readable bytes on the stack.  */
- 
-   if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
-     return 0;
- 
-   if (buf[0] != LINUX_SIGTRAMP_INSN0)
-     {
-       int adjust;
- 
-       switch (buf[0])
- 	{
- 	case LINUX_SIGTRAMP_INSN1:
- 	  adjust = LINUX_SIGTRAMP_OFFSET1;
- 	  break;
- 	case LINUX_SIGTRAMP_INSN2:
- 	  adjust = LINUX_SIGTRAMP_OFFSET2;
- 	  break;
- 	default:
- 	  return 0;
- 	}
- 
-       pc -= adjust;
- 
-       if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
- 	return 0;
-     }
- 
-   if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
-     return 0;
- 
-   return pc;
- }
- 
- /* This function does the same for RT signals.  Here the instruction
-    sequence is
-        mov    $0xad,%eax
-        int    $0x80
-    or 0xb8 0xad 0x00 0x00 0x00 0xcd 0x80.
- 
-    The effect is to call the system call rt_sigreturn.  */
- 
- #define LINUX_RT_SIGTRAMP_INSN0 (0xb8)	/* mov $NNNN,%eax */
- #define LINUX_RT_SIGTRAMP_OFFSET0 (0)
- #define LINUX_RT_SIGTRAMP_INSN1 (0xcd)	/* int */
- #define LINUX_RT_SIGTRAMP_OFFSET1 (5)
- 
- static const unsigned char linux_rt_sigtramp_code[] =
- {
-   LINUX_RT_SIGTRAMP_INSN0, 0xad, 0x00, 0x00, 0x00,	/* mov $0xad,%eax */
-   LINUX_RT_SIGTRAMP_INSN1, 0x80				/* int $0x80 */
- };
- 
- #define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code)
- 
- /* If PC is in a RT sigtramp routine, return the address of the start
-    of the routine.  Otherwise, return 0.  */
- 
- static CORE_ADDR
- i386_linux_rt_sigtramp_start (CORE_ADDR pc)
- {
-   unsigned char buf[LINUX_RT_SIGTRAMP_LEN];
- 
-   /* We only recognize a signal trampoline if PC is at the start of
-      one of the two instructions.  We optimize for finding the PC at
-      the start, as will be the case when the trampoline is not the
-      first frame on the stack.  We assume that in the case where the
-      PC is not at the start of the instruction sequence, there will be
-      a few trailing readable bytes on the stack.  */
- 
-   if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
-     return 0;
- 
-   if (buf[0] != LINUX_RT_SIGTRAMP_INSN0)
-     {
-       if (buf[0] != LINUX_RT_SIGTRAMP_INSN1)
- 	return 0;
- 
-       pc -= LINUX_RT_SIGTRAMP_OFFSET1;
- 
-       if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
- 	return 0;
-     }
- 
-   if (memcmp (buf, linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN) != 0)
-     return 0;
- 
-   return pc;
- }
- 
- /* Return whether PC is in a Linux sigtramp routine.  */
- 
- int
- i386_linux_in_sigtramp (CORE_ADDR pc, char *name)
- {
-   if (name)
-     return STREQ ("__restore", name) || STREQ ("__restore_rt", name);
-   
-   return (i386_linux_sigtramp_start (pc) != 0
- 	  || i386_linux_rt_sigtramp_start (pc) != 0);
- }
- 
- /* Assuming FRAME is for a Linux sigtramp routine, return the address
-    of the associated sigcontext structure.  */
- 
- CORE_ADDR
- i386_linux_sigcontext_addr (struct frame_info *frame)
- {
-   CORE_ADDR pc;
- 
-   pc = i386_linux_sigtramp_start (frame->pc);
-   if (pc)
-     {
-       CORE_ADDR sp;
- 
-       if (frame->next)
- 	/* If this isn't the top frame, the next frame must be for the
- 	   signal handler itself.  The sigcontext structure lives on
- 	   the stack, right after the signum argument.  */
- 	return frame->next->frame + 12;
- 
-       /* This is the top frame.  We'll have to find the address of the
- 	 sigcontext structure by looking at the stack pointer.  Keep
- 	 in mind that the first instruction of the sigtramp code is
- 	 "pop %eax".  If the PC is at this instruction, adjust the
- 	 returned value accordingly.  */
-       sp = read_register (SP_REGNUM);
-       if (pc == frame->pc)
- 	return sp + 4;
-       return sp;
-     }
- 
-   pc = i386_linux_rt_sigtramp_start (frame->pc);
-   if (pc)
-     {
-       if (frame->next)
- 	/* If this isn't the top frame, the next frame must be for the
- 	   signal handler itself.  The sigcontext structure is part of
- 	   the user context.  A pointer to the user context is passed
- 	   as the third argument to the signal handler.  */
- 	return read_memory_integer (frame->next->frame + 16, 4) + 20;
- 
-       /* This is the top frame.  Again, use the stack pointer to find
- 	 the address of the sigcontext structure.  */
-       return read_memory_integer (read_register (SP_REGNUM) + 8, 4) + 20;
-     }
- 
-   error ("Couldn't recognize signal trampoline.");
-   return 0;
- }
- 
- /* Offset to saved PC in sigcontext, from <asm/sigcontext.h>.  */
- #define LINUX_SIGCONTEXT_PC_OFFSET (56)
- 
- /* Assuming FRAME is for a Linux sigtramp routine, return the saved
-    program counter.  */
- 
- CORE_ADDR
- i386_linux_sigtramp_saved_pc (struct frame_info *frame)
- {
-   CORE_ADDR addr;
-   addr = i386_linux_sigcontext_addr (frame);
-   return read_memory_integer (addr + LINUX_SIGCONTEXT_PC_OFFSET, 4);
- }
- 
- /* Offset to saved SP in sigcontext, from <asm/sigcontext.h>.  */
- #define LINUX_SIGCONTEXT_SP_OFFSET (28)
- 
- /* Assuming FRAME is for a Linux sigtramp routine, return the saved
-    stack pointer.  */
- 
- CORE_ADDR
- i386_linux_sigtramp_saved_sp (struct frame_info *frame)
- {
-   CORE_ADDR addr;
-   addr = i386_linux_sigcontext_addr (frame);
-   return read_memory_integer (addr + LINUX_SIGCONTEXT_SP_OFFSET, 4);
- }
- 
- /* Immediately after a function call, return the saved pc.  */
- 
- CORE_ADDR
- i386_linux_saved_pc_after_call (struct frame_info *frame)
- {
-   if (frame->signal_handler_caller)
-     return i386_linux_sigtramp_saved_pc (frame);
- 
-   return read_memory_integer (read_register (SP_REGNUM), 4);
  }
  
  
--- 1040,1045 ----
Index: gdb/i386-linux-tdep.c
===================================================================
RCS file: i386-linux-tdep.c
diff -N i386-linux-tdep.c
*** gdb/i386-linux-tdep.c	Tue May  5 13:32:27 1998
--- gdb/i386-linux-tdep.c	Fri Mar 17 11:59:41 2000
***************
*** 0 ****
--- 1,281 ----
+ /* Target-dependent code for Linux running on i386's, for GDB.
+    Copyright (C) 2000 Free Software Foundation, Inc.
+ 
+    This file is part of GDB.
+ 
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+ 
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include "defs.h"
+ #include "gdbcore.h"
+ #include "frame.h"
+ #include "value.h"
+ 
+ 
+ /* Recognizing signal handler frames.  */
+ 
+ /* Linux has two flavors of signals.  Normal signal handlers, and
+    "realtime" (RT) signals.  The RT signals can provide additional
+    information to the signal handler if the SA_SIGINFO flag is set
+    when establishing a signal handler using `sigaction'.  It is not
+    unlikely that future versions of Linux will support SA_SIGINFO for
+    normal signals too.  */
+ 
+ /* When the i386 Linux kernel calls a signal handler and the
+    SA_RESTORER flag isn't set, the return address points to a bit of
+    code on the stack.  This function returns whether the PC appears to
+    be within this bit of code.
+ 
+    The instruction sequence for normal signals is
+        pop    %eax
+        mov    $0x77,%eax
+        int    $0x80
+    or 0x58 0xb8 0x77 0x00 0x00 0x00 0xcd 0x80.
+ 
+    Checking for the code sequence should be somewhat reliable, because
+    the effect is to call the system call sigreturn.  This is unlikely
+    to occur anywhere other than a signal trampoline.
+ 
+    It kind of sucks that we have to read memory from the process in
+    order to identify a signal trampoline, but there doesn't seem to be
+    any other way.  The IN_SIGTRAMP macro in tm-linux.h arranges to
+    only call us if no function name could be identified, which should
+    be the case since the code is on the stack.
+ 
+    Detection of signal trampolines for handlers that set the
+    SA_RESTORER flag is in general not possible.  Unfortunately this is
+    what the GNU C Library has been doing for quite some time now.
+    However, as of version 2.1.2, the GNU C Library uses signal
+    trampolines (named __restore and __restore_rt) that are identical
+    to the ones used by the kernel.  Therefore, these trampolines are
+    supported too.  */
+ 
+ #define LINUX_SIGTRAMP_INSN0 (0x58)	/* pop %eax */
+ #define LINUX_SIGTRAMP_OFFSET0 (0)
+ #define LINUX_SIGTRAMP_INSN1 (0xb8)	/* mov $NNNN,%eax */
+ #define LINUX_SIGTRAMP_OFFSET1 (1)
+ #define LINUX_SIGTRAMP_INSN2 (0xcd)	/* int */
+ #define LINUX_SIGTRAMP_OFFSET2 (6)
+ 
+ static const unsigned char linux_sigtramp_code[] =
+ {
+   LINUX_SIGTRAMP_INSN0,					/* pop %eax */
+   LINUX_SIGTRAMP_INSN1, 0x77, 0x00, 0x00, 0x00,		/* mov $0x77,%eax */
+   LINUX_SIGTRAMP_INSN2, 0x80				/* int $0x80 */
+ };
+ 
+ #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
+ 
+ /* If PC is in a sigtramp routine, return the address of the start of
+    the routine.  Otherwise, return 0.  */
+ 
+ static CORE_ADDR
+ i386_linux_sigtramp_start (CORE_ADDR pc)
+ {
+   unsigned char buf[LINUX_SIGTRAMP_LEN];
+ 
+   /* We only recognize a signal trampoline if PC is at the start of
+      one of the three instructions.  We optimize for finding the PC at
+      the start, as will be the case when the trampoline is not the
+      first frame on the stack.  We assume that in the case where the
+      PC is not at the start of the instruction sequence, there will be
+      a few trailing readable bytes on the stack.  */
+ 
+   if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
+     return 0;
+ 
+   if (buf[0] != LINUX_SIGTRAMP_INSN0)
+     {
+       int adjust;
+ 
+       switch (buf[0])
+ 	{
+ 	case LINUX_SIGTRAMP_INSN1:
+ 	  adjust = LINUX_SIGTRAMP_OFFSET1;
+ 	  break;
+ 	case LINUX_SIGTRAMP_INSN2:
+ 	  adjust = LINUX_SIGTRAMP_OFFSET2;
+ 	  break;
+ 	default:
+ 	  return 0;
+ 	}
+ 
+       pc -= adjust;
+ 
+       if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
+ 	return 0;
+     }
+ 
+   if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
+     return 0;
+ 
+   return pc;
+ }
+ 
+ /* This function does the same for RT signals.  Here the instruction
+    sequence is
+        mov    $0xad,%eax
+        int    $0x80
+    or 0xb8 0xad 0x00 0x00 0x00 0xcd 0x80.
+ 
+    The effect is to call the system call rt_sigreturn.  */
+ 
+ #define LINUX_RT_SIGTRAMP_INSN0 (0xb8)	/* mov $NNNN,%eax */
+ #define LINUX_RT_SIGTRAMP_OFFSET0 (0)
+ #define LINUX_RT_SIGTRAMP_INSN1 (0xcd)	/* int */
+ #define LINUX_RT_SIGTRAMP_OFFSET1 (5)
+ 
+ static const unsigned char linux_rt_sigtramp_code[] =
+ {
+   LINUX_RT_SIGTRAMP_INSN0, 0xad, 0x00, 0x00, 0x00,	/* mov $0xad,%eax */
+   LINUX_RT_SIGTRAMP_INSN1, 0x80				/* int $0x80 */
+ };
+ 
+ #define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code)
+ 
+ /* If PC is in a RT sigtramp routine, return the address of the start
+    of the routine.  Otherwise, return 0.  */
+ 
+ static CORE_ADDR
+ i386_linux_rt_sigtramp_start (CORE_ADDR pc)
+ {
+   unsigned char buf[LINUX_RT_SIGTRAMP_LEN];
+ 
+   /* We only recognize a signal trampoline if PC is at the start of
+      one of the two instructions.  We optimize for finding the PC at
+      the start, as will be the case when the trampoline is not the
+      first frame on the stack.  We assume that in the case where the
+      PC is not at the start of the instruction sequence, there will be
+      a few trailing readable bytes on the stack.  */
+ 
+   if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
+     return 0;
+ 
+   if (buf[0] != LINUX_RT_SIGTRAMP_INSN0)
+     {
+       if (buf[0] != LINUX_RT_SIGTRAMP_INSN1)
+ 	return 0;
+ 
+       pc -= LINUX_RT_SIGTRAMP_OFFSET1;
+ 
+       if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
+ 	return 0;
+     }
+ 
+   if (memcmp (buf, linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN) != 0)
+     return 0;
+ 
+   return pc;
+ }
+ 
+ /* Return whether PC is in a Linux sigtramp routine.  */
+ 
+ int
+ i386_linux_in_sigtramp (CORE_ADDR pc, char *name)
+ {
+   if (name)
+     return STREQ ("__restore", name) || STREQ ("__restore_rt", name);
+   
+   return (i386_linux_sigtramp_start (pc) != 0
+ 	  || i386_linux_rt_sigtramp_start (pc) != 0);
+ }
+ 
+ /* Assuming FRAME is for a Linux sigtramp routine, return the address
+    of the associated sigcontext structure.  */
+ 
+ CORE_ADDR
+ i386_linux_sigcontext_addr (struct frame_info *frame)
+ {
+   CORE_ADDR pc;
+ 
+   pc = i386_linux_sigtramp_start (frame->pc);
+   if (pc)
+     {
+       CORE_ADDR sp;
+ 
+       if (frame->next)
+ 	/* If this isn't the top frame, the next frame must be for the
+ 	   signal handler itself.  The sigcontext structure lives on
+ 	   the stack, right after the signum argument.  */
+ 	return frame->next->frame + 12;
+ 
+       /* This is the top frame.  We'll have to find the address of the
+ 	 sigcontext structure by looking at the stack pointer.  Keep
+ 	 in mind that the first instruction of the sigtramp code is
+ 	 "pop %eax".  If the PC is at this instruction, adjust the
+ 	 returned value accordingly.  */
+       sp = read_register (SP_REGNUM);
+       if (pc == frame->pc)
+ 	return sp + 4;
+       return sp;
+     }
+ 
+   pc = i386_linux_rt_sigtramp_start (frame->pc);
+   if (pc)
+     {
+       if (frame->next)
+ 	/* If this isn't the top frame, the next frame must be for the
+ 	   signal handler itself.  The sigcontext structure is part of
+ 	   the user context.  A pointer to the user context is passed
+ 	   as the third argument to the signal handler.  */
+ 	return read_memory_integer (frame->next->frame + 16, 4) + 20;
+ 
+       /* This is the top frame.  Again, use the stack pointer to find
+ 	 the address of the sigcontext structure.  */
+       return read_memory_integer (read_register (SP_REGNUM) + 8, 4) + 20;
+     }
+ 
+   error ("Couldn't recognize signal trampoline.");
+   return 0;
+ }
+ 
+ /* Offset to saved PC in sigcontext, from <asm/sigcontext.h>.  */
+ #define LINUX_SIGCONTEXT_PC_OFFSET (56)
+ 
+ /* Assuming FRAME is for a Linux sigtramp routine, return the saved
+    program counter.  */
+ 
+ CORE_ADDR
+ i386_linux_sigtramp_saved_pc (struct frame_info *frame)
+ {
+   CORE_ADDR addr;
+   addr = i386_linux_sigcontext_addr (frame);
+   return read_memory_integer (addr + LINUX_SIGCONTEXT_PC_OFFSET, 4);
+ }
+ 
+ /* Offset to saved SP in sigcontext, from <asm/sigcontext.h>.  */
+ #define LINUX_SIGCONTEXT_SP_OFFSET (28)
+ 
+ /* Assuming FRAME is for a Linux sigtramp routine, return the saved
+    stack pointer.  */
+ 
+ CORE_ADDR
+ i386_linux_sigtramp_saved_sp (struct frame_info *frame)
+ {
+   CORE_ADDR addr;
+   addr = i386_linux_sigcontext_addr (frame);
+   return read_memory_integer (addr + LINUX_SIGCONTEXT_SP_OFFSET, 4);
+ }
+ 
+ /* Immediately after a function call, return the saved pc.  */
+ 
+ CORE_ADDR
+ i386_linux_saved_pc_after_call (struct frame_info *frame)
+ {
+   if (frame->signal_handler_caller)
+     return i386_linux_sigtramp_saved_pc (frame);
+ 
+   return read_memory_integer (read_register (SP_REGNUM), 4);
+ }
Index: gdb/config/i386/linux.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/linux.mt,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 linux.mt
*** gdb/config/i386/linux.mt	1999/04/16 01:34:19	1.1.1.1
--- gdb/config/i386/linux.mt	2000/03/17 19:59:41
***************
*** 1,5 ****
  # Target: Intel 386 running GNU/Linux
! TDEPFILES= i386-tdep.o i387-tdep.o
  TM_FILE= tm-linux.h
  
  GDBSERVER_DEPFILES= low-linux.o
--- 1,5 ----
  # Target: Intel 386 running GNU/Linux
! TDEPFILES= i386-tdep.o i386-linux-tdep.o i387-tdep.o
  TM_FILE= tm-linux.h
  
  GDBSERVER_DEPFILES= low-linux.o

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