* i386-tdep.c (i386_frameless_signal_p): New function.
(i386_frame_chain): Deal with frameless signals. (i386_sigtramp_saved_sp): New function. (i386_frame_saved_pc): Deal with frameless signals. (i386_saved_pc_after_call): Make sure the correct value is returned just after entry into a sigtramp. * i386bsd-tdep.c (i386bsd_sc_sp_offset, i386nbsd_sc_sp_offset, i386fbsd4_sc_sp_offset): New variables. (i386bsd_init_abi, i386nbsd_init_abi, i386fbsd4_init_abi): Use these variables to initialize tdep->sc_sp_offset. * i386bsd-nat.c (_initialize_i386bsd_nat): Add sanity check for sc_sp_offset similiar to what we already did for sc_pc_offset. * i386-sol2-tdep.c (i386_sol2_init_abi): Initialize tdep->sc_sp_offset.
This commit is contained in:
parent
99881371eb
commit
6bff26defb
5 changed files with 98 additions and 1 deletions
|
@ -1,5 +1,20 @@
|
|||
2002-07-02 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* i386-tdep.c (i386_frameless_signal_p): New function.
|
||||
(i386_frame_chain): Deal with frameless signals.
|
||||
(i386_sigtramp_saved_sp): New function.
|
||||
(i386_frame_saved_pc): Deal with frameless signals.
|
||||
(i386_saved_pc_after_call): Make sure the correct value is
|
||||
returned just after entry into a sigtramp.
|
||||
* i386bsd-tdep.c (i386bsd_sc_sp_offset, i386nbsd_sc_sp_offset,
|
||||
i386fbsd4_sc_sp_offset): New variables.
|
||||
(i386bsd_init_abi, i386nbsd_init_abi, i386fbsd4_init_abi): Use
|
||||
these variables to initialize tdep->sc_sp_offset. * i386bsd-nat.c
|
||||
(_initialize_i386bsd_nat): Add sanity check for sc_sp_offset
|
||||
similiar to what we already did for sc_pc_offset.
|
||||
* i386-sol2-tdep.c (i386_sol2_init_abi): Initialize
|
||||
tdep->sc_sp_offset.
|
||||
|
||||
* i386nbsd-tdep.c (fetch_elfcore_registers): Wrap long line.
|
||||
|
||||
2002-07-02 Michal Ludvig <mludvig@suse.cz>
|
||||
|
|
|
@ -46,6 +46,7 @@ i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
set_gdbarch_pc_in_sigtramp (gdbarch, i386_sol2_pc_in_sigtramp);
|
||||
tdep->sigcontext_addr = i386bsd_sigcontext_addr;
|
||||
tdep->sc_pc_offset = 36 + 14 * 4;
|
||||
tdep->sc_sp_offset = 36 + 7 * 4;
|
||||
|
||||
/* Assume that the prototype flag can be trusted. */
|
||||
set_gdbarch_coerce_float_to_double (gdbarch,
|
||||
|
|
|
@ -452,6 +452,38 @@ i386_get_frame_setup (CORE_ADDR pc)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
/* Signal trampolines don't have a meaningful frame. The frame
|
||||
pointer value we use is actually the frame pointer of the calling
|
||||
frame -- that is, the frame which was in progress when the signal
|
||||
trampoline was entered. GDB mostly treats this frame pointer value
|
||||
as a magic cookie. We detect the case of a signal trampoline by
|
||||
looking at the SIGNAL_HANDLER_CALLER field, which is set based on
|
||||
PC_IN_SIGTRAMP.
|
||||
|
||||
When a signal trampoline is invoked from a frameless function, we
|
||||
essentially have two frameless functions in a row. In this case,
|
||||
we use the same magic cookie for three frames in a row. We detect
|
||||
this case by seeing whether the next frame has
|
||||
SIGNAL_HANDLER_CALLER set, and, if it does, checking whether the
|
||||
current frame is actually frameless. In this case, we need to get
|
||||
the PC by looking at the SP register value stored in the signal
|
||||
context.
|
||||
|
||||
This should work in most cases except in horrible situations where
|
||||
a signal occurs just as we enter a function but before the frame
|
||||
has been set up. */
|
||||
|
||||
/* Return non-zero if we're dealing with a frameless signal, that is,
|
||||
a signal trampoline invoked from a frameless function. */
|
||||
|
||||
static int
|
||||
i386_frameless_signal_p (struct frame_info *frame)
|
||||
{
|
||||
return (frame->next
|
||||
&& frame->next->signal_handler_caller
|
||||
&& frameless_look_for_prologue);
|
||||
}
|
||||
|
||||
/* Return the chain-pointer for FRAME. In the case of the i386, the
|
||||
frame's nominal address is the address of a 4-byte word containing
|
||||
the calling frame's address. */
|
||||
|
@ -459,7 +491,8 @@ i386_get_frame_setup (CORE_ADDR pc)
|
|||
static CORE_ADDR
|
||||
i386_frame_chain (struct frame_info *frame)
|
||||
{
|
||||
if (frame->signal_handler_caller)
|
||||
if (frame->signal_handler_caller
|
||||
|| i386_frameless_signal_p (frame))
|
||||
return frame->frame;
|
||||
|
||||
if (! inside_entry_file (frame->pc))
|
||||
|
@ -494,6 +527,19 @@ i386_sigtramp_saved_pc (struct frame_info *frame)
|
|||
return read_memory_unsigned_integer (addr + tdep->sc_pc_offset, 4);
|
||||
}
|
||||
|
||||
/* Assuming FRAME is for a sigtramp routine, return the saved stack
|
||||
pointer. */
|
||||
|
||||
static CORE_ADDR
|
||||
i386_sigtramp_saved_sp (struct frame_info *frame)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
|
||||
CORE_ADDR addr;
|
||||
|
||||
addr = tdep->sigcontext_addr (frame);
|
||||
return read_memory_unsigned_integer (addr + tdep->sc_sp_offset, 4);
|
||||
}
|
||||
|
||||
/* Return the saved program counter for FRAME. */
|
||||
|
||||
static CORE_ADDR
|
||||
|
@ -502,6 +548,12 @@ i386_frame_saved_pc (struct frame_info *frame)
|
|||
if (frame->signal_handler_caller)
|
||||
return i386_sigtramp_saved_pc (frame);
|
||||
|
||||
if (i386_frameless_signal_p (frame))
|
||||
{
|
||||
CORE_ADDR sp = i386_sigtramp_saved_sp (frame->next);
|
||||
return read_memory_unsigned_integer (sp, 4);
|
||||
}
|
||||
|
||||
return read_memory_unsigned_integer (frame->frame + 4, 4);
|
||||
}
|
||||
|
||||
|
@ -510,6 +562,9 @@ i386_frame_saved_pc (struct frame_info *frame)
|
|||
static CORE_ADDR
|
||||
i386_saved_pc_after_call (struct frame_info *frame)
|
||||
{
|
||||
if (frame->signal_handler_caller)
|
||||
return i386_sigtramp_saved_pc (frame);
|
||||
|
||||
return read_memory_unsigned_integer (read_register (SP_REGNUM), 4);
|
||||
}
|
||||
|
||||
|
|
|
@ -387,6 +387,7 @@ void
|
|||
_initialize_i386bsd_nat (void)
|
||||
{
|
||||
int sc_pc_offset;
|
||||
int sc_sp_offset;
|
||||
|
||||
/* To support the recognition of signal handlers, i386bsd-tdep.c
|
||||
hardcodes some constants. Inclusion of this file means that we
|
||||
|
@ -396,13 +397,19 @@ _initialize_i386bsd_nat (void)
|
|||
|
||||
#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
|
||||
extern int i386fbsd4_sc_pc_offset;
|
||||
extern int i386fbsd4_sc_sp_offset;
|
||||
#define SC_PC_OFFSET i386fbsd4_sc_pc_offset
|
||||
#define SC_SP_OFFSET i386fbsd4_sc_sp_offset
|
||||
#elif defined (NetBSD) || defined (__NetBSD_Version__) || defined (OpenBSD)
|
||||
extern int i386nbsd_sc_pc_offset;
|
||||
extern int i386nbsd_sc_sp_offset;
|
||||
#define SC_PC_OFFSET i386nbsd_sc_pc_offset
|
||||
#define SC_SP_OFFSET i386nbsd_sc_sp_offset
|
||||
#else
|
||||
extern int i386bsd_sc_pc_offset;
|
||||
extern int i386bsd_sc_sp_offset;
|
||||
#define SC_PC_OFFSET i386bsd_sc_pc_offset
|
||||
#define SC_SP_OFFSET i386bsd_sc_sp_offset
|
||||
#endif
|
||||
|
||||
/* Override the default value for the offset of the program counter
|
||||
|
@ -418,4 +425,17 @@ Please report this to <bug-gdb@gnu.org>.",
|
|||
}
|
||||
|
||||
SC_PC_OFFSET = sc_pc_offset;
|
||||
|
||||
/* Likewise for the stack pointer. */
|
||||
sc_sp_offset = offsetof (struct sigcontext, sc_sp);
|
||||
|
||||
if (SC_SP_OFFSET != sc_sp_offset)
|
||||
{
|
||||
warning ("\
|
||||
offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
|
||||
Please report this to <bug-gdb@gnu.org>.",
|
||||
sc_sp_offset, SC_SP_OFFSET);
|
||||
}
|
||||
|
||||
SC_SP_OFFSET = sc_sp_offset;
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ i386bsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
|
|||
|
||||
/* From <machine/signal.h>. */
|
||||
int i386bsd_sc_pc_offset = 20;
|
||||
int i386bsd_sc_sp_offset = 8;
|
||||
|
||||
static void
|
||||
i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
|
@ -107,12 +108,14 @@ i386bsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
tdep->sigtramp_end = 0xfdbfe000;
|
||||
tdep->sigcontext_addr = i386bsd_sigcontext_addr;
|
||||
tdep->sc_pc_offset = i386bsd_sc_pc_offset;
|
||||
tdep->sc_sp_offset = i386bsd_sc_sp_offset;
|
||||
}
|
||||
|
||||
/* NetBSD 1.0 or later. */
|
||||
|
||||
/* From <machine/signal.h>. */
|
||||
int i386nbsd_sc_pc_offset = 44;
|
||||
int i386nbsd_sc_sp_offset = 56;
|
||||
|
||||
static void
|
||||
i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
|
@ -132,6 +135,7 @@ i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
/* NetBSD has a `struct sigcontext' that's different from the
|
||||
origional 4.3 BSD. */
|
||||
tdep->sc_pc_offset = i386nbsd_sc_pc_offset;
|
||||
tdep->sc_sp_offset = i386nbsd_sc_sp_offset;
|
||||
}
|
||||
|
||||
/* NetBSD ELF. */
|
||||
|
@ -198,6 +202,7 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
|
||||
/* From <machine/signal.h>. */
|
||||
int i386fbsd4_sc_pc_offset = 76;
|
||||
int i386fbsd4_sc_sp_offset = 88;
|
||||
|
||||
static void
|
||||
i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
|
@ -210,6 +215,7 @@ i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
|
||||
/* FreeBSD 4.0 introduced a new `struct sigcontext'. */
|
||||
tdep->sc_pc_offset = i386fbsd4_sc_pc_offset;
|
||||
tdep->sc_sp_offset = i386fbsd4_sc_sp_offset;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue