Add tests for PR ld/16452 and PR ld/16457
[platform/upstream/binutils.git] / gdb / sparc-sol2-tdep.c
1 /* Target-dependent code for Solaris SPARC.
2
3    Copyright (C) 2003-2014 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "frame.h"
22 #include "frame-unwind.h"
23 #include "gdbcore.h"
24 #include "symtab.h"
25 #include "objfiles.h"
26 #include "osabi.h"
27 #include "regcache.h"
28 #include "target.h"
29 #include "trad-frame.h"
30
31 #include "sol2-tdep.h"
32 #include "sparc-tdep.h"
33 #include "solib-svr4.h"
34
35 /* From <sys/regset.h>.  */
36 const struct sparc_gregmap sparc32_sol2_gregmap =
37 {
38   32 * 4,                       /* %psr */
39   33 * 4,                       /* %pc */
40   34 * 4,                       /* %npc */
41   35 * 4,                       /* %y */
42   36 * 4,                       /* %wim */
43   37 * 4,                       /* %tbr */
44   1 * 4,                        /* %g1 */
45   16 * 4,                       /* %l0 */
46 };
47
48 const struct sparc_fpregmap sparc32_sol2_fpregmap =
49 {
50   0 * 4,                        /* %f0 */
51   33 * 4,                       /* %fsr */
52 };
53 \f
54
55 /* The Solaris signal trampolines reside in libc.  For normal signals,
56    the function `sigacthandler' is used.  This signal trampoline will
57    call the signal handler using the System V calling convention,
58    where the third argument is a pointer to an instance of
59    `ucontext_t', which has a member `uc_mcontext' that contains the
60    saved registers.  Incidentally, the kernel passes the `ucontext_t'
61    pointer as the third argument of the signal trampoline too, and
62    `sigacthandler' simply passes it on.  However, if you link your
63    program with "-L/usr/ucblib -R/usr/ucblib -lucb", the function
64    `ucbsigvechandler' will be used, which invokes the using the BSD
65    convention, where the third argument is a pointer to an instance of
66    `struct sigcontext'.  It is the `ucbsigvechandler' function that
67    converts the `ucontext_t' to a `sigcontext', and back.  Unless the
68    signal handler modifies the `struct sigcontext' we can safely
69    ignore this.  */
70
71 int
72 sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, const char *name)
73 {
74   return (name && (strcmp (name, "sigacthandler") == 0
75                    || strcmp (name, "ucbsigvechandler") == 0
76                    || strcmp (name, "__sighndlr") == 0));
77 }
78
79 static struct sparc_frame_cache *
80 sparc32_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
81                                    void **this_cache)
82 {
83   struct sparc_frame_cache *cache;
84   CORE_ADDR mcontext_addr, addr;
85   int regnum;
86
87   if (*this_cache)
88     return *this_cache;
89
90   cache = sparc_frame_cache (this_frame, this_cache);
91   gdb_assert (cache == *this_cache);
92
93   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
94
95   /* The third argument is a pointer to an instance of `ucontext_t',
96      which has a member `uc_mcontext' that contains the saved
97      registers.  */
98   regnum =
99     (cache->copied_regs_mask & 0x04) ? SPARC_I2_REGNUM : SPARC_O2_REGNUM;
100   mcontext_addr = get_frame_register_unsigned (this_frame, regnum) + 40;
101
102   cache->saved_regs[SPARC32_PSR_REGNUM].addr = mcontext_addr + 0 * 4;
103   cache->saved_regs[SPARC32_PC_REGNUM].addr = mcontext_addr + 1 * 4;
104   cache->saved_regs[SPARC32_NPC_REGNUM].addr = mcontext_addr + 2 * 4;
105   cache->saved_regs[SPARC32_Y_REGNUM].addr = mcontext_addr + 3 * 4;
106
107   /* Since %g0 is always zero, keep the identity encoding.  */
108   for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4;
109        regnum <= SPARC_O7_REGNUM; regnum++, addr += 4)
110     cache->saved_regs[regnum].addr = addr;
111
112   if (get_frame_memory_unsigned (this_frame, mcontext_addr + 19 * 4, 4))
113     {
114       /* The register windows haven't been flushed.  */
115       for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
116         trad_frame_set_unknown (cache->saved_regs, regnum);
117     }
118   else
119     {
120       addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
121       addr = get_frame_memory_unsigned (this_frame, addr, 4);
122       for (regnum = SPARC_L0_REGNUM;
123            regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
124         cache->saved_regs[regnum].addr = addr;
125     }
126
127   return cache;
128 }
129
130 static void
131 sparc32_sol2_sigtramp_frame_this_id (struct frame_info *this_frame,
132                                      void **this_cache,
133                                      struct frame_id *this_id)
134 {
135   struct sparc_frame_cache *cache =
136     sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
137
138   (*this_id) = frame_id_build (cache->base, cache->pc);
139 }
140
141 static struct value *
142 sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *this_frame,
143                                            void **this_cache,
144                                            int regnum)
145 {
146   struct sparc_frame_cache *cache =
147     sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
148
149   return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
150 }
151
152 static int
153 sparc32_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
154                                      struct frame_info *this_frame,
155                                      void **this_cache)
156 {
157   CORE_ADDR pc = get_frame_pc (this_frame);
158   const char *name;
159
160   find_pc_partial_function (pc, &name, NULL, NULL);
161   if (sparc_sol2_pc_in_sigtramp (pc, name))
162     return 1;
163
164   return 0;
165 }
166
167 static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
168 {
169   SIGTRAMP_FRAME,
170   default_frame_unwind_stop_reason,
171   sparc32_sol2_sigtramp_frame_this_id,
172   sparc32_sol2_sigtramp_frame_prev_register,
173   NULL,
174   sparc32_sol2_sigtramp_frame_sniffer
175 };
176
177 /* Unglobalize NAME.  */
178
179 const const char *
180 sparc_sol2_static_transform_name (const char *name)
181 {
182   /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop,
183      SunPRO) convert file static variables into global values, a
184      process known as globalization.  In order to do this, the
185      compiler will create a unique prefix and prepend it to each file
186      static variable.  For static variables within a function, this
187      globalization prefix is followed by the function name (nested
188      static variables within a function are supposed to generate a
189      warning message, and are left alone).  The procedure is
190      documented in the Stabs Interface Manual, which is distrubuted
191      with the compilers, although version 4.0 of the manual seems to
192      be incorrect in some places, at least for SPARC.  The
193      globalization prefix is encoded into an N_OPT stab, with the form
194      "G=<prefix>".  The globalization prefix always seems to start
195      with a dollar sign '$'; a dot '.' is used as a seperator.  So we
196      simply strip everything up until the last dot.  */
197
198   if (name[0] == '$')
199     {
200       char *p = strrchr (name, '.');
201       if (p)
202         return p + 1;
203     }
204
205   return name;
206 }
207 \f
208
209 void
210 sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
211 {
212   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
213
214   /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop, SunPRO)
215      compiler puts out 0 instead of the address in N_SO stabs.  Starting with
216      SunPRO 3.0, the compiler does this for N_FUN stabs too.  */
217   set_gdbarch_sofun_address_maybe_missing (gdbarch, 1);
218
219   /* The Sun compilers also do "globalization"; see the comment in
220      sparc_sol2_static_transform_name for more information.  */
221   set_gdbarch_static_transform_name
222     (gdbarch, sparc_sol2_static_transform_name);
223
224   /* Solaris has SVR4-style shared libraries...  */
225   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
226   set_gdbarch_skip_solib_resolver (gdbarch, sol2_skip_solib_resolver);
227   set_solib_svr4_fetch_link_map_offsets
228     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
229
230   /* ...which means that we need some special handling when doing
231      prologue analysis.  */
232   tdep->plt_entry_size = 12;
233
234   /* Solaris has kernel-assisted single-stepping support.  */
235   set_gdbarch_software_single_step (gdbarch, NULL);
236
237   frame_unwind_append_unwinder (gdbarch, &sparc32_sol2_sigtramp_frame_unwind);
238
239   /* How to print LWP PTIDs from core files.  */
240   set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
241 }
242 \f
243
244 /* Provide a prototype to silence -Wmissing-prototypes.  */
245 void _initialize_sparc_sol2_tdep (void);
246
247 void
248 _initialize_sparc_sol2_tdep (void)
249 {
250   gdbarch_register_osabi (bfd_arch_sparc, 0,
251                           GDB_OSABI_SOLARIS, sparc32_sol2_init_abi);
252 }