GDB (API)
/home/stan/gdb/src/gdb/sparc-sol2-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for Solaris SPARC.
00002 
00003    Copyright (C) 2003-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "frame.h"
00022 #include "frame-unwind.h"
00023 #include "gdbcore.h"
00024 #include "symtab.h"
00025 #include "objfiles.h"
00026 #include "osabi.h"
00027 #include "regcache.h"
00028 #include "target.h"
00029 #include "trad-frame.h"
00030 
00031 #include "gdb_assert.h"
00032 #include "gdb_string.h"
00033 
00034 #include "sol2-tdep.h"
00035 #include "sparc-tdep.h"
00036 #include "solib-svr4.h"
00037 
00038 /* From <sys/regset.h>.  */
00039 const struct sparc_gregset sparc32_sol2_gregset =
00040 {
00041   32 * 4,                       /* %psr */
00042   33 * 4,                       /* %pc */
00043   34 * 4,                       /* %npc */
00044   35 * 4,                       /* %y */
00045   36 * 4,                       /* %wim */
00046   37 * 4,                       /* %tbr */
00047   1 * 4,                        /* %g1 */
00048   16 * 4,                       /* %l0 */
00049 };
00050 
00051 const struct sparc_fpregset sparc32_sol2_fpregset =
00052 {
00053   0 * 4,                        /* %f0 */
00054   33 * 4,                       /* %fsr */
00055 };
00056 
00057 
00058 /* The Solaris signal trampolines reside in libc.  For normal signals,
00059    the function `sigacthandler' is used.  This signal trampoline will
00060    call the signal handler using the System V calling convention,
00061    where the third argument is a pointer to an instance of
00062    `ucontext_t', which has a member `uc_mcontext' that contains the
00063    saved registers.  Incidentally, the kernel passes the `ucontext_t'
00064    pointer as the third argument of the signal trampoline too, and
00065    `sigacthandler' simply passes it on.  However, if you link your
00066    program with "-L/usr/ucblib -R/usr/ucblib -lucb", the function
00067    `ucbsigvechandler' will be used, which invokes the using the BSD
00068    convention, where the third argument is a pointer to an instance of
00069    `struct sigcontext'.  It is the `ucbsigvechandler' function that
00070    converts the `ucontext_t' to a `sigcontext', and back.  Unless the
00071    signal handler modifies the `struct sigcontext' we can safely
00072    ignore this.  */
00073 
00074 int
00075 sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, const char *name)
00076 {
00077   return (name && (strcmp (name, "sigacthandler") == 0
00078                    || strcmp (name, "ucbsigvechandler") == 0
00079                    || strcmp (name, "__sighndlr") == 0));
00080 }
00081 
00082 static struct sparc_frame_cache *
00083 sparc32_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
00084                                    void **this_cache)
00085 {
00086   struct sparc_frame_cache *cache;
00087   CORE_ADDR mcontext_addr, addr;
00088   int regnum;
00089 
00090   if (*this_cache)
00091     return *this_cache;
00092 
00093   cache = sparc_frame_cache (this_frame, this_cache);
00094   gdb_assert (cache == *this_cache);
00095 
00096   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
00097 
00098   /* The third argument is a pointer to an instance of `ucontext_t',
00099      which has a member `uc_mcontext' that contains the saved
00100      registers.  */
00101   regnum =
00102     (cache->copied_regs_mask & 0x04) ? SPARC_I2_REGNUM : SPARC_O2_REGNUM;
00103   mcontext_addr = get_frame_register_unsigned (this_frame, regnum) + 40;
00104 
00105   cache->saved_regs[SPARC32_PSR_REGNUM].addr = mcontext_addr + 0 * 4;
00106   cache->saved_regs[SPARC32_PC_REGNUM].addr = mcontext_addr + 1 * 4;
00107   cache->saved_regs[SPARC32_NPC_REGNUM].addr = mcontext_addr + 2 * 4;
00108   cache->saved_regs[SPARC32_Y_REGNUM].addr = mcontext_addr + 3 * 4;
00109 
00110   /* Since %g0 is always zero, keep the identity encoding.  */
00111   for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4;
00112        regnum <= SPARC_O7_REGNUM; regnum++, addr += 4)
00113     cache->saved_regs[regnum].addr = addr;
00114 
00115   if (get_frame_memory_unsigned (this_frame, mcontext_addr + 19 * 4, 4))
00116     {
00117       /* The register windows haven't been flushed.  */
00118       for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
00119         trad_frame_set_unknown (cache->saved_regs, regnum);
00120     }
00121   else
00122     {
00123       addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
00124       addr = get_frame_memory_unsigned (this_frame, addr, 4);
00125       for (regnum = SPARC_L0_REGNUM;
00126            regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
00127         cache->saved_regs[regnum].addr = addr;
00128     }
00129 
00130   return cache;
00131 }
00132 
00133 static void
00134 sparc32_sol2_sigtramp_frame_this_id (struct frame_info *this_frame,
00135                                      void **this_cache,
00136                                      struct frame_id *this_id)
00137 {
00138   struct sparc_frame_cache *cache =
00139     sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
00140 
00141   (*this_id) = frame_id_build (cache->base, cache->pc);
00142 }
00143 
00144 static struct value *
00145 sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *this_frame,
00146                                            void **this_cache,
00147                                            int regnum)
00148 {
00149   struct sparc_frame_cache *cache =
00150     sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
00151 
00152   return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
00153 }
00154 
00155 static int
00156 sparc32_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
00157                                      struct frame_info *this_frame,
00158                                      void **this_cache)
00159 {
00160   CORE_ADDR pc = get_frame_pc (this_frame);
00161   const char *name;
00162 
00163   find_pc_partial_function (pc, &name, NULL, NULL);
00164   if (sparc_sol2_pc_in_sigtramp (pc, name))
00165     return 1;
00166 
00167   return 0;
00168 }
00169 
00170 static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
00171 {
00172   SIGTRAMP_FRAME,
00173   default_frame_unwind_stop_reason,
00174   sparc32_sol2_sigtramp_frame_this_id,
00175   sparc32_sol2_sigtramp_frame_prev_register,
00176   NULL,
00177   sparc32_sol2_sigtramp_frame_sniffer
00178 };
00179 
00180 /* Unglobalize NAME.  */
00181 
00182 const const char *
00183 sparc_sol2_static_transform_name (const char *name)
00184 {
00185   /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop,
00186      SunPRO) convert file static variables into global values, a
00187      process known as globalization.  In order to do this, the
00188      compiler will create a unique prefix and prepend it to each file
00189      static variable.  For static variables within a function, this
00190      globalization prefix is followed by the function name (nested
00191      static variables within a function are supposed to generate a
00192      warning message, and are left alone).  The procedure is
00193      documented in the Stabs Interface Manual, which is distrubuted
00194      with the compilers, although version 4.0 of the manual seems to
00195      be incorrect in some places, at least for SPARC.  The
00196      globalization prefix is encoded into an N_OPT stab, with the form
00197      "G=<prefix>".  The globalization prefix always seems to start
00198      with a dollar sign '$'; a dot '.' is used as a seperator.  So we
00199      simply strip everything up until the last dot.  */
00200 
00201   if (name[0] == '$')
00202     {
00203       char *p = strrchr (name, '.');
00204       if (p)
00205         return p + 1;
00206     }
00207 
00208   return name;
00209 }
00210 
00211 
00212 void
00213 sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00214 {
00215   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00216 
00217   /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop, SunPRO)
00218      compiler puts out 0 instead of the address in N_SO stabs.  Starting with
00219      SunPRO 3.0, the compiler does this for N_FUN stabs too.  */
00220   set_gdbarch_sofun_address_maybe_missing (gdbarch, 1);
00221 
00222   /* The Sun compilers also do "globalization"; see the comment in
00223      sparc_sol2_static_transform_name for more information.  */
00224   set_gdbarch_static_transform_name
00225     (gdbarch, sparc_sol2_static_transform_name);
00226 
00227   /* Solaris has SVR4-style shared libraries...  */
00228   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
00229   set_gdbarch_skip_solib_resolver (gdbarch, sol2_skip_solib_resolver);
00230   set_solib_svr4_fetch_link_map_offsets
00231     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
00232 
00233   /* ...which means that we need some special handling when doing
00234      prologue analysis.  */
00235   tdep->plt_entry_size = 12;
00236 
00237   /* Solaris has kernel-assisted single-stepping support.  */
00238   set_gdbarch_software_single_step (gdbarch, NULL);
00239 
00240   frame_unwind_append_unwinder (gdbarch, &sparc32_sol2_sigtramp_frame_unwind);
00241 
00242   /* How to print LWP PTIDs from core files.  */
00243   set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
00244 }
00245 
00246 
00247 /* Provide a prototype to silence -Wmissing-prototypes.  */
00248 void _initialize_sparc_sol2_tdep (void);
00249 
00250 void
00251 _initialize_sparc_sol2_tdep (void)
00252 {
00253   gdbarch_register_osabi (bfd_arch_sparc, 0,
00254                           GDB_OSABI_SOLARIS, sparc32_sol2_init_abi);
00255 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines