Move common handlers to sol2_init_abi
[deliverable/binutils-gdb.git] / gdb / sol2-tdep.c
index 03b510c9adedbbbad25a6ba95d3190cefaff04ba..179c8aeea5758e98dd8273f9bebfad0b274ad705 100644 (file)
 
 #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);
+}
This page took 0.025739 seconds and 4 git commands to generate.