* gdbarch.sh (PC_IN_SIGTRAMP): Add.
* gdbarch.h, gdbarch.c: Re-generate.
* inferior.h (IN_SIGTRAMP): Delete definition.
* arch-utils.c (legacy_pc_in_sigtramp): New function.
* arch-utils.h (legacy_pc_in_sigtramp): Declare.
* mips-tdep.c (mips_init_extra_frame_info): Use PC_IN_SIGTRAMP.
(mips_dump_tdep): Do not print value of IN_SIGTRAMP.
* hppa-tdep.c (pc_in_interrupt_handler): Use PC_IN_SIGTRAMP.
(find_proc_framesize): Ditto.
* alpha-tdep.c (alpha_osf_skip_sigtramp_frame): Ditto.
(alpha_init_extra_frame_info): Ditto.
* infrun.c (handle_inferior_event): Ditto.
(handle_inferior_event): Ditto.
(check_sigtramp2): Ditto.
* blockframe.c (create_new_frame): Ditto.
(get_prev_frame): Ditto.
* ppc-linux-tdep.c: Update comments.
* i386-linux-tdep.c: Update comments.
* breakpoint.c (bpstat_what): Update comment.
* gdbint.texinfo (Target Architecture Definition): Replace
IN_SIGTRAMP with PC_IN_SIGTRAMP.
+2002-04-24 Andrew Cagney <ac131313@redhat.com>
+
+ * arch-utils.h: Update copyright.
+
+ * gdbarch.sh (PC_IN_SIGTRAMP): Add.
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+ * inferior.h (IN_SIGTRAMP): Delete definition.
+ * arch-utils.c (legacy_pc_in_sigtramp): New function.
+ * arch-utils.h (legacy_pc_in_sigtramp): Declare.
+
+ * mips-tdep.c (mips_init_extra_frame_info): Use PC_IN_SIGTRAMP.
+ (mips_dump_tdep): Do not print value of IN_SIGTRAMP.
+ * hppa-tdep.c (pc_in_interrupt_handler): Use PC_IN_SIGTRAMP.
+ (find_proc_framesize): Ditto.
+ * alpha-tdep.c (alpha_osf_skip_sigtramp_frame): Ditto.
+ (alpha_init_extra_frame_info): Ditto.
+ * infrun.c (handle_inferior_event): Ditto.
+ (handle_inferior_event): Ditto.
+ (check_sigtramp2): Ditto.
+ * blockframe.c (create_new_frame): Ditto.
+ (get_prev_frame): Ditto.
+ * ppc-linux-tdep.c: Update comments.
+ * i386-linux-tdep.c: Update comments.
+ * breakpoint.c (bpstat_what): Update comment.
+
2002-04-24 Michal Ludvig <mludvig@suse.cz>
* gdbserver/linux-low.c (regsets_fetch_inferior_registers),
{
char *name;
find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (IN_SIGTRAMP (pc, name))
+ if (PC_IN_SIGTRAMP (pc, name))
return frame->frame;
else
return 0;
We can't use frame->signal_handler_caller, it is not yet set. */
find_pc_partial_function (frame->pc, &name,
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (!IN_SIGTRAMP (frame->pc, name))
+ if (!PC_IN_SIGTRAMP (frame->pc, name))
{
frame->saved_regs = (CORE_ADDR *)
frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
}
+#if !defined (IN_SIGTRAMP)
+#if defined (SIGTRAMP_START)
+#define IN_SIGTRAMP(pc, name) \
+ ((pc) >= SIGTRAMP_START(pc) \
+ && (pc) < SIGTRAMP_END(pc) \
+ )
+#else
+#define IN_SIGTRAMP(pc, name) \
+ (name && STREQ ("_sigtramp", name))
+#endif
+#endif
+\f
+int
+legacy_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ return IN_SIGTRAMP(pc, name);
+}
+
\f
/* Functions to manipulate the endianness of the target. */
/* Dynamic architecture support for GDB, the GNU debugger.
- Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of GDB.
extern int generic_register_virtual_size (int regnum);
+/* Prop up old targets that use various IN_SIGTRAMP() macros. */
+extern int legacy_pc_in_sigtramp (CORE_ADDR pc, char *name);
+
/* Initialize a ``struct info''. Can't use memset(0) since some
default values are not zero. */
extern void gdbarch_info_init (struct gdbarch_info *info);
sp = (fi->next->frame - fi->next->extra_info->frameoffset
+ fi->next->extra_info->framesize);
- /* Determine whether or not we're in a sigtramp frame.
+ /* Determine whether or not we're in a sigtramp frame.
Unfortunately, it isn't sufficient to test
fi->signal_handler_caller because this value is sometimes set
after invoking INIT_EXTRA_FRAME_INFO. So we test *both*
- fi->signal_handler_caller and IN_SIGTRAMP to determine if we need
- to use the sigcontext addresses for the saved registers.
+ fi->signal_handler_caller and PC_IN_SIGTRAMP to determine if we
+ need to use the sigcontext addresses for the saved registers.
- Note: If an ARM IN_SIGTRAMP method ever needs to compare against
- the name of the function, the code below will have to be changed
- to first fetch the name of the function and then pass this name
- to IN_SIGTRAMP. */
+ Note: If an ARM PC_IN_SIGTRAMP method ever needs to compare
+ against the name of the function, the code below will have to be
+ changed to first fetch the name of the function and then pass
+ this name to PC_IN_SIGTRAMP. */
if (SIGCONTEXT_REGISTER_ADDRESS_P ()
- && (fi->signal_handler_caller || IN_SIGTRAMP (fi->pc, (char *)0)))
+ && (fi->signal_handler_caller || PC_IN_SIGTRAMP (fi->pc, (char *)0)))
{
for (reg = 0; reg < NUM_REGS; reg++)
fi->saved_regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, fi->pc, reg);
fi->frame = addr;
fi->pc = pc;
find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- fi->signal_handler_caller = IN_SIGTRAMP (fi->pc, name);
+ fi->signal_handler_caller = PC_IN_SIGTRAMP (fi->pc, name);
if (INIT_EXTRA_FRAME_INFO_P ())
INIT_EXTRA_FRAME_INFO (0, fi);
find_pc_partial_function (prev->pc, &name,
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (IN_SIGTRAMP (prev->pc, name))
+ if (PC_IN_SIGTRAMP (prev->pc, name))
prev->signal_handler_caller = 1;
return prev;
/* If sigtramp is in the u area, it counts as a function (especially
important for step_1). */
#if defined SIGTRAMP_START
- if (IN_SIGTRAMP (mapped_pc, (char *) NULL))
+ if (PC_IN_SIGTRAMP (mapped_pc, (char *) NULL))
{
cache_pc_function_low = SIGTRAMP_START (mapped_pc);
cache_pc_function_high = SIGTRAMP_END (mapped_pc);
/* step_resume entries: a step resume breakpoint overrides another
breakpoint of signal handling (see comment in wait_for_inferior
- at first IN_SIGTRAMP where we set the step_resume breakpoint). */
+ at first PC_IN_SIGTRAMP where we set the step_resume breakpoint). */
/* We handle the through_sigtramp_breakpoint the same way; having both
one of those and a step_resume_breakpoint is probably very rare (?). */
+2002-04-24 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbint.texinfo (Target Architecture Definition): Replace
+ IN_SIGTRAMP with PC_IN_SIGTRAMP.
+
2002-04-24 David S. Miller <davem@redhat.com>
* gdbint.texinfo (REGISTER_IN_WINDOW): Delete definition.
the stack frame of the function already has been destroyed up to the
final `return from function call' instruction.
-@item IN_SIGTRAMP (@var{pc}, @var{name})
-@findex IN_SIGTRAMP
-Define this to return non-zero if the given @var{pc} and/or @var{name}
-indicates that the current function is a @code{sigtramp}.
-
@item SIGTRAMP_START (@var{pc})
@findex SIGTRAMP_START
@itemx SIGTRAMP_END (@var{pc})
@findex PC_IN_CALL_DUMMY
See @file{inferior.h}.
+@item PC_IN_SIGTRAMP (@var{pc}, @var{name})
+@findex PC_IN_SIGTRAMP
+@cindex sigtramp
+The @dfn{sigtramp} is a routine that the kernel calls (which then calls
+the signal handler). On most machines it is a library routine that is
+linked into the executable.
+
+This function, given a program counter value in @var{pc} and the
+(possibly NULL) name of the function in which that @var{pc} resides,
+returns nonzero if the @var{pc} and/or @var{name} show that we are in
+sigtramp.
+
@item PC_LOAD_SEGMENT
@findex PC_LOAD_SEGMENT
If defined, print information about the load segment for the program
gdbarch_print_insn_ftype *print_insn;
gdbarch_skip_trampoline_code_ftype *skip_trampoline_code;
gdbarch_in_solib_call_trampoline_ftype *in_solib_call_trampoline;
+ gdbarch_pc_in_sigtramp_ftype *pc_in_sigtramp;
gdbarch_in_function_epilogue_p_ftype *in_function_epilogue_p;
gdbarch_construct_inferior_arguments_ftype *construct_inferior_arguments;
gdbarch_dwarf2_build_frame_info_ftype *dwarf2_build_frame_info;
0,
0,
0,
+ 0,
generic_in_function_epilogue_p,
construct_inferior_arguments,
0,
current_gdbarch->print_insn = legacy_print_insn;
current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code;
current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline;
+ current_gdbarch->pc_in_sigtramp = legacy_pc_in_sigtramp;
current_gdbarch->in_function_epilogue_p = generic_in_function_epilogue_p;
current_gdbarch->construct_inferior_arguments = construct_inferior_arguments;
current_gdbarch->elf_make_msymbol_special = default_elf_make_msymbol_special;
/* Skip verify of print_insn, invalid_p == 0 */
/* Skip verify of skip_trampoline_code, invalid_p == 0 */
/* Skip verify of in_solib_call_trampoline, invalid_p == 0 */
+ /* Skip verify of pc_in_sigtramp, invalid_p == 0 */
/* Skip verify of in_function_epilogue_p, invalid_p == 0 */
/* Skip verify of construct_inferior_arguments, invalid_p == 0 */
/* Skip verify of dwarf2_build_frame_info, has predicate */
(long) current_gdbarch->pc_in_call_dummy
/*PC_IN_CALL_DUMMY ()*/);
#endif
+#ifdef PC_IN_SIGTRAMP
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "PC_IN_SIGTRAMP(pc, name)",
+ XSTRING (PC_IN_SIGTRAMP (pc, name)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: PC_IN_SIGTRAMP = 0x%08lx\n",
+ (long) current_gdbarch->pc_in_sigtramp
+ /*PC_IN_SIGTRAMP ()*/);
+#endif
#ifdef PC_REGNUM
fprintf_unfiltered (file,
"gdbarch_dump: PC_REGNUM # %s\n",
gdbarch->in_solib_call_trampoline = in_solib_call_trampoline;
}
+int
+gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc, char *name)
+{
+ if (gdbarch->pc_in_sigtramp == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_pc_in_sigtramp invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_pc_in_sigtramp called\n");
+ return gdbarch->pc_in_sigtramp (pc, name);
+}
+
+void
+set_gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch,
+ gdbarch_pc_in_sigtramp_ftype pc_in_sigtramp)
+{
+ gdbarch->pc_in_sigtramp = pc_in_sigtramp;
+}
+
int
gdbarch_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR addr)
{
#endif
#endif
+/* Sigtramp is a routine that the kernel calls (which then calls the
+ signal handler). On most machines it is a library routine that is
+ linked into the executable.
+
+ This macro, given a program counter value and the name of the
+ function in which that PC resides (which can be null if the name is
+ not known), returns nonzero if the PC and name show that we are in
+ sigtramp.
+
+ On most machines just see if the name is sigtramp (and if we have
+ no name, assume we are not in sigtramp).
+
+ FIXME: cagney/2002-04-21: The function find_pc_partial_function
+ calls find_pc_sect_partial_function() which calls PC_IN_SIGTRAMP.
+ This means PC_IN_SIGTRAMP function can't be implemented by doing its
+ own local NAME lookup.
+
+ FIXME: cagney/2002-04-21: PC_IN_SIGTRAMP is something of a mess.
+ Some code also depends on SIGTRAMP_START and SIGTRAMP_END but other
+ does not. */
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PC_IN_SIGTRAMP)
+#define PC_IN_SIGTRAMP(pc, name) (legacy_pc_in_sigtramp (pc, name))
+#endif
+
+typedef int (gdbarch_pc_in_sigtramp_ftype) (CORE_ADDR pc, char *name);
+extern int gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc, char *name);
+extern void set_gdbarch_pc_in_sigtramp (struct gdbarch *gdbarch, gdbarch_pc_in_sigtramp_ftype *pc_in_sigtramp);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PC_IN_SIGTRAMP)
+#error "Non multi-arch definition of PC_IN_SIGTRAMP"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PC_IN_SIGTRAMP)
+#define PC_IN_SIGTRAMP(pc, name) (gdbarch_pc_in_sigtramp (current_gdbarch, pc, name))
+#endif
+#endif
+
/* A target might have problems with watchpoints as soon as the stack
frame of the current function has been destroyed. This mostly happens
as the first action in a funtion's epilogue. in_function_epilogue_p()
# trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
# to nonzero if we are current stopped in one of these.
f:2:IN_SOLIB_CALL_TRAMPOLINE:int:in_solib_call_trampoline:CORE_ADDR pc, char *name:pc, name:::generic_in_solib_call_trampoline::0
+# Sigtramp is a routine that the kernel calls (which then calls the
+# signal handler). On most machines it is a library routine that is
+# linked into the executable.
+#
+# This macro, given a program counter value and the name of the
+# function in which that PC resides (which can be null if the name is
+# not known), returns nonzero if the PC and name show that we are in
+# sigtramp.
+#
+# On most machines just see if the name is sigtramp (and if we have
+# no name, assume we are not in sigtramp).
+#
+# FIXME: cagney/2002-04-21: The function find_pc_partial_function
+# calls find_pc_sect_partial_function() which calls PC_IN_SIGTRAMP.
+# This means PC_IN_SIGTRAMP function can't be implemented by doing its
+# own local NAME lookup.
+#
+# FIXME: cagney/2002-04-21: PC_IN_SIGTRAMP is something of a mess.
+# Some code also depends on SIGTRAMP_START and SIGTRAMP_END but other
+# does not.
+f:2:PC_IN_SIGTRAMP:int:pc_in_sigtramp:CORE_ADDR pc, char *name:pc, name:::legacy_pc_in_sigtramp::0
# A target might have problems with watchpoints as soon as the stack
# frame of the current function has been destroyed. This mostly happens
# as the first action in a funtion's epilogue. in_function_epilogue_p()
its frame isn't a pure interrupt frame. Deal with this. */
msym_us = lookup_minimal_symbol_by_pc (pc);
- return u->HP_UX_interrupt_marker && !IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us));
+ return (u->HP_UX_interrupt_marker
+ && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)));
}
/* Called when no unwind descriptor was found for PC. Returns 1 if it
if (u->Save_SP
&& !pc_in_interrupt_handler (pc)
&& msym_us
- && !IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)))
+ && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)))
return -1;
return u->Total_frame_size << 3;
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
+ any other way. The PC_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.
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 IN_SIGTRAMP.
+ 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,
extern int attach_flag;
\f
-/* Sigtramp is a routine that the kernel calls (which then calls the
- signal handler). On most machines it is a library routine that
- is linked into the executable.
-
- This macro, given a program counter value and the name of the
- function in which that PC resides (which can be null if the
- name is not known), returns nonzero if the PC and name show
- that we are in sigtramp.
-
- On most machines just see if the name is sigtramp (and if we have
- no name, assume we are not in sigtramp). */
-#if !defined (IN_SIGTRAMP)
-#if defined (SIGTRAMP_START)
-#define IN_SIGTRAMP(pc, name) \
- ((pc) >= SIGTRAMP_START(pc) \
- && (pc) < SIGTRAMP_END(pc) \
- )
-#else
-#define IN_SIGTRAMP(pc, name) \
- (name && STREQ ("_sigtramp", name))
-#endif
-#endif
-\f
/* Possible values for CALL_DUMMY_LOCATION. */
#define ON_STACK 1
#define BEFORE_TEXT_END 2
ecs->update_step_sp = 1;
/* Did we just take a signal? */
- if (IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
- && !IN_SIGTRAMP (prev_pc, prev_func_name)
+ if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ && !PC_IN_SIGTRAMP (prev_pc, prev_func_name)
&& INNER_THAN (read_sp (), step_sp))
{
/* We've just taken a signal; go until we are back to
{
/* We're doing a "next". */
- if (IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
&& INNER_THAN (step_frame_address, read_sp()))
/* We stepped out of a signal handler, and into its
calling trampoline. This is misdetected as a
check_sigtramp2 (struct execution_control_state *ecs)
{
if (trap_expected
- && IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
- && !IN_SIGTRAMP (prev_pc, prev_func_name)
+ && PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ && !PC_IN_SIGTRAMP (prev_pc, prev_func_name)
&& INNER_THAN (read_sp (), step_sp))
{
/* What has happened here is that we have just stepped the
We can't use fci->signal_handler_caller, it is not yet set. */
find_pc_partial_function (fci->pc, &name,
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (!IN_SIGTRAMP (fci->pc, name))
+ if (!PC_IN_SIGTRAMP (fci->pc, name))
{
frame_saved_regs_zalloc (fci);
memcpy (fci->saved_regs, temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
fprintf_unfiltered (file,
"mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
XSTRING (IGNORE_HELPER_CALL (PC)));
- fprintf_unfiltered (file,
- "mips_dump_tdep: IN_SIGTRAMP # %s\n",
- XSTRING (IN_SIGTRAMP (PC, NAME)));
fprintf_unfiltered (file,
"mips_dump_tdep: IN_SOLIB_CALL_TRAMPOLINE # %s\n",
XSTRING (IN_SOLIB_CALL_TRAMPOLINE (PC, NAME)));
/* Determine if pc is in a signal trampoline...
Ha! That's not what this does at all. wait_for_inferior in
- infrun.c calls IN_SIGTRAMP in order to detect entry into a signal
- trampoline just after delivery of a signal. But on GNU/Linux,
- signal trampolines are used for the return path only. The kernel
- sets things up so that the signal handler is called directly.
+ infrun.c calls PC_IN_SIGTRAMP in order to detect entry into a
+ signal trampoline just after delivery of a signal. But on
+ GNU/Linux, signal trampolines are used for the return path only.
+ The kernel sets things up so that the signal handler is called
+ directly.
If we use in_sigtramp2() in place of in_sigtramp() (see below)
we'll (often) end up with stop_pc in the trampoline and prev_pc in
first instruction long after the fact, just in case the observed
behavior is ever fixed.)
- IN_SIGTRAMP is called from blockframe.c as well in order to set
+ PC_IN_SIGTRAMP is called from blockframe.c as well in order to set
the signal_handler_caller flag. Because of our strange definition
- of in_sigtramp below, we can't rely on signal_handler_caller getting
- set correctly from within blockframe.c. This is why we take pains
- to set it in init_extra_frame_info(). */
+ of in_sigtramp below, we can't rely on signal_handler_caller
+ getting set correctly from within blockframe.c. This is why we
+ take pains to set it in init_extra_frame_info(). */
int
ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name)