* i386-linux-tdep.c (i386_linux_sigcontext_addr): Make static.

(LINUX_SIGCONTEXT_PC_OFFSET, LINUX_SIGCONEXT_SP_OFFSET): Remove
macros.
(i386_linux_sigtramp_saved_pc, i386_linux_sigtramp_saved_sp):
Remove functions.
(FRAMELESS_SIGNAL): Remove function.
(i386_linux_frame_chain, i386_linux_frame_saved_pc,
i386_linux_saved_pc_after_call): Removed.
(i386_linux_init_abi): Initialize tdep->sigcontext_addr,
tdep->sc_pc_offset and tdep->sc_sp_offset.  Don't override
frame_chain, frame_saved_pc and saved_pc_after_call any longer.
This commit is contained in:
Mark Kettenis 2002-07-02 13:48:16 +00:00
parent 6bff26defb
commit b7d15bf718
2 changed files with 20 additions and 102 deletions

View File

@ -1,5 +1,17 @@
2002-07-02 Mark Kettenis <kettenis@gnu.org>
* i386-linux-tdep.c (i386_linux_sigcontext_addr): Make static.
(LINUX_SIGCONTEXT_PC_OFFSET, LINUX_SIGCONEXT_SP_OFFSET): Remove
macros.
(i386_linux_sigtramp_saved_pc, i386_linux_sigtramp_saved_sp):
Remove functions.
(FRAMELESS_SIGNAL): Remove function.
(i386_linux_frame_chain, i386_linux_frame_saved_pc,
i386_linux_saved_pc_after_call): Removed.
(i386_linux_init_abi): Initialize tdep->sigcontext_addr,
tdep->sc_pc_offset and tdep->sc_sp_offset. Don't override
frame_chain, frame_saved_pc and saved_pc_after_call any longer.
* i386-tdep.c (i386_frameless_signal_p): New function.
(i386_frame_chain): Deal with frameless signals.
(i386_sigtramp_saved_sp): New function.

View File

@ -240,7 +240,7 @@ i386_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
address of the associated sigcontext structure. */
CORE_ADDR
static CORE_ADDR
i386_linux_sigcontext_addr (struct frame_info *frame)
{
CORE_ADDR pc;
@ -286,100 +286,6 @@ i386_linux_sigcontext_addr (struct frame_info *frame)
return 0;
}
/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */
#define LINUX_SIGCONTEXT_PC_OFFSET (56)
/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
saved program counter. */
static 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 GNU/Linux sigtramp routine, return the
saved stack pointer. */
static 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);
}
/* Signal trampolines don't have a meaningful frame. As in
"i386/tm-i386.h", 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. */
#define FRAMELESS_SIGNAL(frame) \
((frame)->next != NULL \
&& (frame)->next->signal_handler_caller \
&& frameless_look_for_prologue (frame))
CORE_ADDR
i386_linux_frame_chain (struct frame_info *frame)
{
if (frame->signal_handler_caller || FRAMELESS_SIGNAL (frame))
return frame->frame;
if (! inside_entry_file (frame->pc))
return read_memory_unsigned_integer (frame->frame, 4);
return 0;
}
/* Return the saved program counter for FRAME. */
CORE_ADDR
i386_linux_frame_saved_pc (struct frame_info *frame)
{
if (frame->signal_handler_caller)
return i386_linux_sigtramp_saved_pc (frame);
if (FRAMELESS_SIGNAL (frame))
{
CORE_ADDR sp = i386_linux_sigtramp_saved_sp (frame->next);
return read_memory_unsigned_integer (sp, 4);
}
return read_memory_unsigned_integer (frame->frame + 4, 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_unsigned_integer (read_register (SP_REGNUM), 4);
}
/* Set the program counter for process PTID to PC. */
static void
@ -557,15 +463,15 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->jb_pc_offset = 20; /* From <bits/setjmp.h>. */
/* When the i386 Linux kernel calls a signal handler, the return
address points to a bit of code on the stack. These definitions
are used to identify this bit of code as a signal trampoline in
order to support backtracing through calls to signal handlers. */
tdep->sigcontext_addr = i386_linux_sigcontext_addr;
tdep->sc_pc_offset = 14 * 4; /* From <asm/sigcontext.h>. */
tdep->sc_sp_offset = 7 * 4;
/* When the i386 Linux kernel calls a signal handler, the return
address points to a bit of code on the stack. This function is
used to identify this bit of code as a signal trampoline in order
to support backtracing through calls to signal handlers. */
set_gdbarch_pc_in_sigtramp (gdbarch, i386_linux_pc_in_sigtramp);
set_gdbarch_frame_chain (gdbarch, i386_linux_frame_chain);
set_gdbarch_frame_saved_pc (gdbarch, i386_linux_frame_saved_pc);
set_gdbarch_saved_pc_after_call (gdbarch, i386_linux_saved_pc_after_call);
set_solib_svr4_fetch_link_map_offsets (gdbarch,
i386_linux_svr4_fetch_link_map_offsets);