aboutsummaryrefslogtreecommitdiff
path: root/gdb/sol2-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/sol2-tdep.c')
-rw-r--r--gdb/sol2-tdep.c116
1 files changed, 108 insertions, 8 deletions
diff --git a/gdb/sol2-tdep.c b/gdb/sol2-tdep.c
index 03b510c..179c8ae 100644
--- a/gdb/sol2-tdep.c
+++ b/gdb/sol2-tdep.c
@@ -25,7 +25,89 @@
#include "sol2-tdep.h"
-CORE_ADDR
+/* The Solaris signal trampolines reside in libc. For normal signals,
+ the function `sigacthandler' is used. This signal trampoline will
+ call the signal handler using the System V calling convention,
+ where the third argument is a pointer to an instance of
+ `ucontext_t', which has a member `uc_mcontext' that contains the
+ saved registers. Incidentally, the kernel passes the `ucontext_t'
+ pointer as the third argument of the signal trampoline too, and
+ `sigacthandler' simply passes it on. However, if you link your
+ program with "-L/usr/ucblib -R/usr/ucblib -lucb", the function
+ `ucbsigvechandler' will be used, which invokes the using the BSD
+ convention, where the third argument is a pointer to an instance of
+ `struct sigcontext'. It is the `ucbsigvechandler' function that
+ converts the `ucontext_t' to a `sigcontext', and back. Unless the
+ signal handler modifies the `struct sigcontext' we can safely
+ ignore this. */
+
+static int
+sol2_pc_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+ return (name && (strcmp (name, "sigacthandler") == 0
+ || strcmp (name, "ucbsigvechandler") == 0
+ || strcmp (name, "__sighndlr") == 0));
+}
+
+/* Return whether THIS_FRAME corresponds to a Solaris sigtramp routine. */
+
+int
+sol2_sigtramp_p (struct frame_info *this_frame)
+{
+ CORE_ADDR pc = get_frame_pc (this_frame);
+ const char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ return sol2_pc_in_sigtramp (pc, name);
+}
+
+/* Unglobalize NAME. */
+
+static const char *
+sol2_static_transform_name (const char *name)
+{
+ /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop,
+ SunPRO) convert file static variables into global values, a
+ process known as globalization. In order to do this, the
+ compiler will create a unique prefix and prepend it to each file
+ static variable. For static variables within a function, this
+ globalization prefix is followed by the function name (nested
+ static variables within a function are supposed to generate a
+ warning message, and are left alone). The procedure is
+ documented in the Stabs Interface Manual, which is distributed
+ with the compilers, although version 4.0 of the manual seems to
+ be incorrect in some places, at least for SPARC. The
+ globalization prefix is encoded into an N_OPT stab, with the form
+ "G=<prefix>". The globalization prefix always seems to start
+ with a dollar sign '$' (sparc) resp. a dot '.' (x86); a dot '.'
+ is used as a separator. So we simply strip everything up until
+ the last dot. */
+ int prefix;
+
+ switch (gdbarch_bfd_arch_info (target_gdbarch ())->arch)
+ {
+ case bfd_arch_i386:
+ prefix = '.';
+ break;
+ case bfd_arch_sparc:
+ prefix = '$';
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "Unexpected arch");
+ break;
+ }
+
+ if (name[0] == prefix)
+ {
+ const char *p = strrchr (name, '.');
+ if (p)
+ return p + 1;
+ }
+
+ return name;
+}
+
+static CORE_ADDR
sol2_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
{
struct bound_minimal_symbol msym;
@@ -37,17 +119,15 @@ sol2_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
return 0;
}
-/* This is how we want PTIDs from Solaris core files to be
- printed. */
+/* This is how we want PTIDs from Solaris core files to be printed. */
-std::string
+static std::string
sol2_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
{
struct inferior *inf;
int pid;
- /* Check whether we're printing an LWP (gdb thread) or a
- process. */
+ /* Check whether we're printing an LWP (gdb thread) or a process. */
pid = ptid.lwp ();
if (pid != 0)
{
@@ -56,8 +136,7 @@ sol2_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
}
/* GDB didn't use to put a NT_PSTATUS note in Solaris cores. If
- that's missing, then we're dealing with a fake PID corelow.c made
- up. */
+ that's missing, then we're dealing with a fake PID corelow.c made up. */
inf = find_inferior_ptid (current_inferior ()->process_target (), ptid);
if (inf == NULL || inf->fake_pid_p)
return "<core>";
@@ -65,3 +144,24 @@ sol2_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
/* Not fake; print as usual. */
return normal_pid_to_str (ptid);
}
+
+/* To be called from GDB_OSABI_SOLARIS handlers. */
+
+void
+sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop, SunPRO)
+ compiler puts out 0 instead of the address in N_SO stabs. Starting with
+ SunPRO 3.0, the compiler does this for N_FUN stabs too. */
+ set_gdbarch_sofun_address_maybe_missing (gdbarch, 1);
+
+ /* The Sun compilers also do "globalization"; see the comment in
+ sol2_static_transform_name for more information. */
+ set_gdbarch_static_transform_name (gdbarch, sol2_static_transform_name);
+
+ /* Solaris uses SVR4-style shared libraries. */
+ set_gdbarch_skip_solib_resolver (gdbarch, sol2_skip_solib_resolver);
+
+ /* How to print LWP PTIDs from core files. */
+ set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
+}