xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/sparc64-linux-tdep.c (revision 815e1b14f3a983ea87badb71b7630decacccd7c7)
1 /* Target-dependent code for GNU/Linux UltraSPARC.
2 
3    Copyright (C) 2003-2019 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 "dwarf2-frame.h"
24 #include "regset.h"
25 #include "regcache.h"
26 #include "gdbarch.h"
27 #include "gdbcore.h"
28 #include "osabi.h"
29 #include "solib-svr4.h"
30 #include "symtab.h"
31 #include "trad-frame.h"
32 #include "tramp-frame.h"
33 #include "xml-syscall.h"
34 #include "linux-tdep.h"
35 
36 /* ADI specific si_code */
37 #ifndef SEGV_ACCADI
38 #define SEGV_ACCADI	3
39 #endif
40 #ifndef SEGV_ADIDERR
41 #define SEGV_ADIDERR	4
42 #endif
43 #ifndef SEGV_ADIPERR
44 #define SEGV_ADIPERR	5
45 #endif
46 
47 /* The syscall's XML filename for sparc 64-bit.  */
48 #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml"
49 
50 #include "sparc64-tdep.h"
51 
52 /* Signal trampoline support.  */
53 
54 static void sparc64_linux_sigframe_init (const struct tramp_frame *self,
55 					 struct frame_info *this_frame,
56 					 struct trad_frame_cache *this_cache,
57 					 CORE_ADDR func);
58 
59 /* See sparc-linux-tdep.c for details.  Note that 64-bit binaries only
60    use RT signals.  */
61 
62 static const struct tramp_frame sparc64_linux_rt_sigframe =
63 {
64   SIGTRAMP_FRAME,
65   4,
66   {
67     { 0x82102065, ULONGEST_MAX },		/* mov __NR_rt_sigreturn, %g1 */
68     { 0x91d0206d, ULONGEST_MAX },		/* ta  0x6d */
69     { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
70   },
71   sparc64_linux_sigframe_init
72 };
73 
74 static void
75 sparc64_linux_sigframe_init (const struct tramp_frame *self,
76 			     struct frame_info *this_frame,
77 			     struct trad_frame_cache *this_cache,
78 			     CORE_ADDR func)
79 {
80   CORE_ADDR base, addr, sp_addr;
81   int regnum;
82 
83   base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM);
84   base += 128;
85 
86   /* Offsets from <bits/sigcontext.h>.  */
87 
88   /* Since %g0 is always zero, keep the identity encoding.  */
89   addr = base + 8;
90   sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
91   for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
92     {
93       trad_frame_set_reg_addr (this_cache, regnum, addr);
94       addr += 8;
95     }
96 
97   trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
98   trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
99   trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
100   trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
101   trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);
102 
103   base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
104   if (base & 1)
105     base += BIAS;
106 
107   addr = get_frame_memory_unsigned (this_frame, sp_addr, 8);
108   if (addr & 1)
109     addr += BIAS;
110 
111   for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
112     {
113       trad_frame_set_reg_addr (this_cache, regnum, addr);
114       addr += 8;
115     }
116   trad_frame_set_id (this_cache, frame_id_build (base, func));
117 }
118 
119 /* sparc64 GNU/Linux implementation of the handle_segmentation_fault
120    gdbarch hook.
121    Displays information related to ADI memory corruptions.  */
122 
123 void
124 sparc64_linux_handle_segmentation_fault (struct gdbarch *gdbarch,
125 				      struct ui_out *uiout)
126 {
127   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word != 64)
128     return;
129 
130   CORE_ADDR addr = 0;
131   long si_code = 0;
132 
133   TRY
134     {
135       /* Evaluate si_code to see if the segfault is ADI related.  */
136       si_code = parse_and_eval_long ("$_siginfo.si_code\n");
137 
138       if (si_code >= SEGV_ACCADI && si_code <= SEGV_ADIPERR)
139         addr = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
140     }
141   CATCH (exception, RETURN_MASK_ALL)
142     {
143       return;
144     }
145   END_CATCH
146 
147   /* Print out ADI event based on sig_code value */
148   switch (si_code)
149     {
150     case SEGV_ACCADI:	/* adi not enabled */
151       uiout->text ("\n");
152       uiout->field_string ("sigcode-meaning", _("ADI disabled"));
153       uiout->text (_(" while accessing address "));
154       uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr));
155       break;
156     case SEGV_ADIDERR:	/* disrupting mismatch */
157       uiout->text ("\n");
158       uiout->field_string ("sigcode-meaning", _("ADI deferred mismatch"));
159       uiout->text (_(" while accessing address "));
160       uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr));
161       break;
162     case SEGV_ADIPERR:	/* precise mismatch */
163       uiout->text ("\n");
164       uiout->field_string ("sigcode-meaning", _("ADI precise mismatch"));
165       uiout->text (_(" while accessing address "));
166       uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr));
167       break;
168     default:
169       break;
170     }
171 
172 }
173 
174 
175 /* Return the address of a system call's alternative return
176    address.  */
177 
178 static CORE_ADDR
179 sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
180 {
181   /* __NR_rt_sigreturn is 101  */
182   if ((insn == 0x91d0206d)
183       && (get_frame_register_unsigned (frame, SPARC_G1_REGNUM) == 101))
184     {
185       struct gdbarch *gdbarch = get_frame_arch (frame);
186       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
187 
188       ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
189       if (sp & 1)
190 	sp += BIAS;
191 
192       /* The kernel puts the sigreturn registers on the stack,
193 	 and this is where the signal unwinding state is take from
194 	 when returning from a signal.
195 
196 	 A siginfo_t sits 192 bytes from the base of the stack.  This
197 	 siginfo_t is 128 bytes, and is followed by the sigreturn
198 	 register save area.  The saved PC sits at a 136 byte offset
199 	 into there.  */
200 
201       return read_memory_unsigned_integer (sp + 192 + 128 + 136,
202 					   8, byte_order);
203     }
204 
205   return 0;
206 }
207 
208 
209 const struct sparc_gregmap sparc64_linux_core_gregmap =
210 {
211   32 * 8,			/* %tstate */
212   33 * 8,			/* %tpc */
213   34 * 8,			/* %tnpc */
214   35 * 8,			/* %y */
215   -1,				/* %wim */
216   -1,				/* %tbr */
217   1 * 8,			/* %g1 */
218   16 * 8,			/* %l0 */
219   8,				/* y size */
220 };
221 
222 
223 static void
224 sparc64_linux_supply_core_gregset (const struct regset *regset,
225 				   struct regcache *regcache,
226 				   int regnum, const void *gregs, size_t len)
227 {
228   sparc64_supply_gregset (&sparc64_linux_core_gregmap,
229 			  regcache, regnum, gregs);
230 }
231 
232 static void
233 sparc64_linux_collect_core_gregset (const struct regset *regset,
234 				    const struct regcache *regcache,
235 				    int regnum, void *gregs, size_t len)
236 {
237   sparc64_collect_gregset (&sparc64_linux_core_gregmap,
238 			   regcache, regnum, gregs);
239 }
240 
241 static void
242 sparc64_linux_supply_core_fpregset (const struct regset *regset,
243 				    struct regcache *regcache,
244 				    int regnum, const void *fpregs, size_t len)
245 {
246   sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
247 }
248 
249 static void
250 sparc64_linux_collect_core_fpregset (const struct regset *regset,
251 				     const struct regcache *regcache,
252 				     int regnum, void *fpregs, size_t len)
253 {
254   sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
255 }
256 
257 /* Set the program counter for process PTID to PC.  */
258 
259 #define TSTATE_SYSCALL	0x0000000000000020ULL
260 
261 static void
262 sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
263 {
264   struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
265   ULONGEST state;
266 
267   regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
268   regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
269 
270   /* Clear the "in syscall" bit to prevent the kernel from
271      messing with the PCs we just installed, if we happen to be
272      within an interrupted system call that the kernel wants to
273      restart.
274 
275      Note that after we return from the dummy call, the TSTATE et al.
276      registers will be automatically restored, and the kernel
277      continues to restart the system call at this point.  */
278   regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
279   state &= ~TSTATE_SYSCALL;
280   regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
281 }
282 
283 static LONGEST
284 sparc64_linux_get_syscall_number (struct gdbarch *gdbarch,
285 				  thread_info *thread)
286 {
287   struct regcache *regcache = get_thread_regcache (thread);
288   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
289   /* The content of a register.  */
290   gdb_byte buf[8];
291   /* The result.  */
292   LONGEST ret;
293 
294   /* Getting the system call number from the register.
295      When dealing with the sparc architecture, this information
296      is stored at the %g1 register.  */
297   regcache->cooked_read (SPARC_G1_REGNUM, buf);
298 
299   ret = extract_signed_integer (buf, 8, byte_order);
300 
301   return ret;
302 }
303 
304 
305 /* Implement the "get_longjmp_target" gdbarch method.  */
306 
307 static int
308 sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
309 {
310   struct gdbarch *gdbarch = get_frame_arch (frame);
311   CORE_ADDR jb_addr;
312   gdb_byte buf[8];
313 
314   jb_addr = get_frame_register_unsigned (frame, SPARC_O0_REGNUM);
315 
316   /* setjmp and longjmp in SPARC64 are implemented in glibc using the
317      setcontext and getcontext system calls respectively.  These
318      system calls operate on ucontext_t structures, which happen to
319      partially have the same structure than jmp_buf.  However the
320      ucontext returned by getcontext, and thus the jmp_buf structure
321      returned by setjmp, contains the context of the trap instruction
322      in the glibc __[sig]setjmp wrapper, not the context of the user
323      code calling setjmp.
324 
325      %o7 in the jmp_buf structure is stored at offset 18*8 in the
326      mc_gregs array, which is itself located at offset 32 into
327      jmp_buf.  See bits/setjmp.h.  This register contains the address
328      of the 'call setjmp' instruction in user code.
329 
330      In order to determine the longjmp target address in the
331      initiating frame we need to examine the call instruction itself,
332      in particular whether the annul bit is set.  If it is not set
333      then we need to jump over the instruction at the delay slot.  */
334 
335   if (target_read_memory (jb_addr + 32 + (18 * 8), buf, 8))
336     return 0;
337 
338   *pc = extract_unsigned_integer (buf, 8, gdbarch_byte_order (gdbarch));
339 
340   if (!sparc_is_annulled_branch_insn (*pc))
341       *pc += 4; /* delay slot insn  */
342   *pc += 4; /* call insn  */
343 
344   return 1;
345 }
346 
347 
348 
349 static const struct regset sparc64_linux_gregset =
350   {
351     NULL,
352     sparc64_linux_supply_core_gregset,
353     sparc64_linux_collect_core_gregset
354   };
355 
356 static const struct regset sparc64_linux_fpregset =
357   {
358     NULL,
359     sparc64_linux_supply_core_fpregset,
360     sparc64_linux_collect_core_fpregset
361   };
362 
363 static void
364 sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
365 {
366   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
367 
368   linux_init_abi (info, gdbarch);
369 
370   tdep->gregset = &sparc64_linux_gregset;
371   tdep->sizeof_gregset = 288;
372 
373   tdep->fpregset = &sparc64_linux_fpregset;
374   tdep->sizeof_fpregset = 280;
375 
376   tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe);
377 
378   /* Hook in the DWARF CFI frame unwinder.  */
379   dwarf2_append_unwinders (gdbarch);
380 
381   sparc64_init_abi (info, gdbarch);
382 
383   /* GNU/Linux has SVR4-style shared libraries...  */
384   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
385   set_solib_svr4_fetch_link_map_offsets
386     (gdbarch, svr4_lp64_fetch_link_map_offsets);
387 
388   /* ...which means that we need some special handling when doing
389      prologue analysis.  */
390   tdep->plt_entry_size = 16;
391 
392   /* Enable TLS support.  */
393   set_gdbarch_fetch_tls_load_module_address (gdbarch,
394                                              svr4_fetch_objfile_link_map);
395 
396   /* Make sure we can single-step over signal return system calls.  */
397   tdep->step_trap = sparc64_linux_step_trap;
398 
399   /* Make sure we can single-step over longjmp calls.  */
400   set_gdbarch_get_longjmp_target (gdbarch, sparc64_linux_get_longjmp_target);
401 
402   set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);
403 
404   /* Functions for 'catch syscall'.  */
405   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC64);
406   set_gdbarch_get_syscall_number (gdbarch,
407                                   sparc64_linux_get_syscall_number);
408   set_gdbarch_handle_segmentation_fault (gdbarch,
409 					 sparc64_linux_handle_segmentation_fault);
410 }
411 
412 void
413 _initialize_sparc64_linux_tdep (void)
414 {
415   gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
416 			  GDB_OSABI_LINUX, sparc64_linux_init_abi);
417 }
418