xref: /openbsd-src/gnu/usr.bin/binutils/gdb/sparc-tdep.c (revision 5e948f2af243398623e78f182fceb2b49a31aa05)
1b725ae77Skettenis /* Target-dependent code for SPARC.
2b725ae77Skettenis 
3*5e948f2aSkettenis    Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
4e93f7393Sniklas 
5e93f7393Sniklas    This file is part of GDB.
6e93f7393Sniklas 
7e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
8e93f7393Sniklas    it under the terms of the GNU General Public License as published by
9e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
10e93f7393Sniklas    (at your option) any later version.
11e93f7393Sniklas 
12e93f7393Sniklas    This program is distributed in the hope that it will be useful,
13e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
14e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15e93f7393Sniklas    GNU General Public License for more details.
16e93f7393Sniklas 
17e93f7393Sniklas    You should have received a copy of the GNU General Public License
18e93f7393Sniklas    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21e93f7393Sniklas 
22e93f7393Sniklas #include "defs.h"
23b725ae77Skettenis #include "arch-utils.h"
24b725ae77Skettenis #include "dis-asm.h"
25b725ae77Skettenis #include "floatformat.h"
26e93f7393Sniklas #include "frame.h"
27b725ae77Skettenis #include "frame-base.h"
28b725ae77Skettenis #include "frame-unwind.h"
29b725ae77Skettenis #include "gdbcore.h"
30b725ae77Skettenis #include "gdbtypes.h"
31e93f7393Sniklas #include "inferior.h"
32b725ae77Skettenis #include "symtab.h"
33b725ae77Skettenis #include "objfiles.h"
34b725ae77Skettenis #include "osabi.h"
35b725ae77Skettenis #include "regcache.h"
36e93f7393Sniklas #include "target.h"
37e93f7393Sniklas #include "value.h"
38b725ae77Skettenis 
39b725ae77Skettenis #include "gdb_assert.h"
40e93f7393Sniklas #include "gdb_string.h"
41e93f7393Sniklas 
42b725ae77Skettenis #include "sparc-tdep.h"
43e93f7393Sniklas 
44b725ae77Skettenis struct regset;
45e93f7393Sniklas 
4663addd46Skettenis /* This file implements the SPARC 32-bit ABI as defined by the section
4763addd46Skettenis    "Low-Level System Information" of the SPARC Compliance Definition
4863addd46Skettenis    (SCD) 2.4.1, which is the 32-bit System V psABI for SPARC.  The SCD
4963addd46Skettenis    lists changes with respect to the original 32-bit psABI as defined
5063addd46Skettenis    in the "System V ABI, SPARC Processor Supplement".
51e93f7393Sniklas 
52b725ae77Skettenis    Note that if we talk about SunOS, we mean SunOS 4.x, which was
53b725ae77Skettenis    BSD-based, which is sometimes (retroactively?) referred to as
54b725ae77Skettenis    Solaris 1.x.  If we talk about Solaris we mean Solaris 2.x and
55b725ae77Skettenis    above (Solaris 7, 8 and 9 are nothing but Solaris 2.7, 2.8 and 2.9
56b725ae77Skettenis    suffering from severe version number inflation).  Solaris 2.x is
57b725ae77Skettenis    also known as SunOS 5.x, since that's what uname(1) says.  Solaris
58b725ae77Skettenis    2.x is SVR4-based.  */
59e93f7393Sniklas 
60b725ae77Skettenis /* Please use the sparc32_-prefix for 32-bit specific code, the
61b725ae77Skettenis    sparc64_-prefix for 64-bit specific code and the sparc_-prefix for
62b725ae77Skettenis    code that can handle both.  The 64-bit specific code lives in
63b725ae77Skettenis    sparc64-tdep.c; don't add any here.  */
64e93f7393Sniklas 
65b725ae77Skettenis /* The SPARC Floating-Point Quad-Precision format is similar to
66b725ae77Skettenis    big-endian IA-64 Quad-recision format.  */
67b725ae77Skettenis #define floatformat_sparc_quad floatformat_ia64_quad_big
68e93f7393Sniklas 
69b725ae77Skettenis /* The stack pointer is offset from the stack frame by a BIAS of 2047
70b725ae77Skettenis    (0x7ff) for 64-bit code.  BIAS is likely to be defined on SPARC
71b725ae77Skettenis    hosts, so undefine it first.  */
72b725ae77Skettenis #undef BIAS
73b725ae77Skettenis #define BIAS 2047
74e93f7393Sniklas 
75b725ae77Skettenis /* Macros to extract fields from SPARC instructions.  */
76e93f7393Sniklas #define X_OP(i) (((i) >> 30) & 0x3)
77e93f7393Sniklas #define X_RD(i) (((i) >> 25) & 0x1f)
78e93f7393Sniklas #define X_A(i) (((i) >> 29) & 1)
79e93f7393Sniklas #define X_COND(i) (((i) >> 25) & 0xf)
80e93f7393Sniklas #define X_OP2(i) (((i) >> 22) & 0x7)
81e93f7393Sniklas #define X_IMM22(i) ((i) & 0x3fffff)
82e93f7393Sniklas #define X_OP3(i) (((i) >> 19) & 0x3f)
83*5e948f2aSkettenis #define X_RS1(i) (((i) >> 14) & 0x1f)
84*5e948f2aSkettenis #define X_RS2(i) ((i) & 0x1f)
85e93f7393Sniklas #define X_I(i) (((i) >> 13) & 1)
86e93f7393Sniklas /* Sign extension macros.  */
87e93f7393Sniklas #define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000)
88e93f7393Sniklas #define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000)
89e93f7393Sniklas 
90b725ae77Skettenis /* Fetch the instruction at PC.  Instructions are always big-endian
91b725ae77Skettenis    even if the processor operates in little-endian mode.  */
92e93f7393Sniklas 
93b725ae77Skettenis unsigned long
sparc_fetch_instruction(CORE_ADDR pc)94b725ae77Skettenis sparc_fetch_instruction (CORE_ADDR pc)
95e93f7393Sniklas {
96b725ae77Skettenis   unsigned char buf[4];
97e93f7393Sniklas   unsigned long insn;
98b725ae77Skettenis   int i;
99e93f7393Sniklas 
100b725ae77Skettenis   /* If we can't read the instruction at PC, return zero.  */
101b725ae77Skettenis   if (target_read_memory (pc, buf, sizeof (buf)))
102e93f7393Sniklas     return 0;
103e93f7393Sniklas 
104b725ae77Skettenis   insn = 0;
105b725ae77Skettenis   for (i = 0; i < sizeof (buf); i++)
106b725ae77Skettenis     insn = (insn << 8) | buf[i];
107b725ae77Skettenis   return insn;
108b725ae77Skettenis }
109b725ae77Skettenis 
110e93f7393Sniklas 
111b725ae77Skettenis /* OpenBSD/sparc includes StackGhost, which according to the author's
112b725ae77Skettenis    website http://stackghost.cerias.purdue.edu "... transparently and
113b725ae77Skettenis    automatically protects applications' stack frames; more
114b725ae77Skettenis    specifically, it guards the return pointers.  The protection
115b725ae77Skettenis    mechanisms require no application source or binary modification and
116b725ae77Skettenis    imposes only a negligible performance penalty."
117b725ae77Skettenis 
118b725ae77Skettenis    The same website provides the following description of how
119b725ae77Skettenis    StackGhost works:
120b725ae77Skettenis 
121b725ae77Skettenis    "StackGhost interfaces with the kernel trap handler that would
122b725ae77Skettenis    normally write out registers to the stack and the handler that
123b725ae77Skettenis    would read them back in.  By XORing a cookie into the
124b725ae77Skettenis    return-address saved in the user stack when it is actually written
125b725ae77Skettenis    to the stack, and then XOR it out when the return-address is pulled
126b725ae77Skettenis    from the stack, StackGhost can cause attacker corrupted return
127b725ae77Skettenis    pointers to behave in a manner the attacker cannot predict.
128b725ae77Skettenis    StackGhost can also use several unused bits in the return pointer
129b725ae77Skettenis    to detect a smashed return pointer and abort the process."
130b725ae77Skettenis 
131b725ae77Skettenis    For GDB this means that whenever we're reading %i7 from a stack
132b725ae77Skettenis    frame's window save area, we'll have to XOR the cookie.
133b725ae77Skettenis 
134b725ae77Skettenis    More information on StackGuard can be found on in:
135b725ae77Skettenis 
136b725ae77Skettenis    Mike Frantzen and Mike Shuey. "StackGhost: Hardware Facilitated
137b725ae77Skettenis    Stack Protection."  2001.  Published in USENIX Security Symposium
138b725ae77Skettenis    '01.  */
139b725ae77Skettenis 
140b725ae77Skettenis /* Fetch StackGhost Per-Process XOR cookie.  */
141b725ae77Skettenis 
142b725ae77Skettenis ULONGEST
sparc_fetch_wcookie(void)143b725ae77Skettenis sparc_fetch_wcookie (void)
144b725ae77Skettenis {
145b725ae77Skettenis   struct target_ops *ops = &current_target;
146b725ae77Skettenis   char buf[8];
147b725ae77Skettenis   int len;
148b725ae77Skettenis 
149b725ae77Skettenis   len = target_read_partial (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
150b725ae77Skettenis   if (len == -1)
151b725ae77Skettenis     return 0;
152b725ae77Skettenis 
153b725ae77Skettenis   /* We should have either an 32-bit or an 64-bit cookie.  */
154b725ae77Skettenis   gdb_assert (len == 4 || len == 8);
155b725ae77Skettenis 
156b725ae77Skettenis   return extract_unsigned_integer (buf, len);
157b725ae77Skettenis }
158b725ae77Skettenis 
159b725ae77Skettenis 
160b725ae77Skettenis /* Return the contents if register REGNUM as an address.  */
161b725ae77Skettenis 
162b725ae77Skettenis static CORE_ADDR
sparc_address_from_register(int regnum)163b725ae77Skettenis sparc_address_from_register (int regnum)
164b725ae77Skettenis {
165b725ae77Skettenis   ULONGEST addr;
166b725ae77Skettenis 
167b725ae77Skettenis   regcache_cooked_read_unsigned (current_regcache, regnum, &addr);
168b725ae77Skettenis   return addr;
169b725ae77Skettenis }
170b725ae77Skettenis 
171b725ae77Skettenis 
172b725ae77Skettenis /* The functions on this page are intended to be used to classify
173b725ae77Skettenis    function arguments.  */
174b725ae77Skettenis 
175b725ae77Skettenis /* Check whether TYPE is "Integral or Pointer".  */
176b725ae77Skettenis 
177b725ae77Skettenis static int
sparc_integral_or_pointer_p(const struct type * type)178b725ae77Skettenis sparc_integral_or_pointer_p (const struct type *type)
179b725ae77Skettenis {
180b725ae77Skettenis   switch (TYPE_CODE (type))
181b725ae77Skettenis     {
182b725ae77Skettenis     case TYPE_CODE_INT:
183b725ae77Skettenis     case TYPE_CODE_BOOL:
184b725ae77Skettenis     case TYPE_CODE_CHAR:
185b725ae77Skettenis     case TYPE_CODE_ENUM:
186b725ae77Skettenis     case TYPE_CODE_RANGE:
187b725ae77Skettenis       {
188b725ae77Skettenis 	/* We have byte, half-word, word and extended-word/doubleword
189b725ae77Skettenis            integral types.  The doubleword is an extension to the
19063addd46Skettenis            original 32-bit ABI by the SCD 2.4.x.  */
191b725ae77Skettenis 	int len = TYPE_LENGTH (type);
192b725ae77Skettenis 	return (len == 1 || len == 2 || len == 4 || len == 8);
193b725ae77Skettenis       }
194e93f7393Sniklas       return 1;
195b725ae77Skettenis     case TYPE_CODE_PTR:
196b725ae77Skettenis     case TYPE_CODE_REF:
197e93f7393Sniklas       {
198b725ae77Skettenis 	/* Allow either 32-bit or 64-bit pointers.  */
199b725ae77Skettenis 	int len = TYPE_LENGTH (type);
200b725ae77Skettenis 	return (len == 4 || len == 8);
201b725ae77Skettenis       }
202b725ae77Skettenis       return 1;
203b725ae77Skettenis     default:
204b725ae77Skettenis       break;
205b725ae77Skettenis     }
206b725ae77Skettenis 
207b725ae77Skettenis   return 0;
208b725ae77Skettenis }
209b725ae77Skettenis 
210b725ae77Skettenis /* Check whether TYPE is "Floating".  */
211b725ae77Skettenis 
212b725ae77Skettenis static int
sparc_floating_p(const struct type * type)213b725ae77Skettenis sparc_floating_p (const struct type *type)
214e93f7393Sniklas {
215b725ae77Skettenis   switch (TYPE_CODE (type))
216b725ae77Skettenis     {
217b725ae77Skettenis     case TYPE_CODE_FLT:
218b725ae77Skettenis       {
219b725ae77Skettenis 	int len = TYPE_LENGTH (type);
220b725ae77Skettenis 	return (len == 4 || len == 8 || len == 16);
221e93f7393Sniklas       }
222b725ae77Skettenis     default:
223b725ae77Skettenis       break;
224e93f7393Sniklas     }
225e93f7393Sniklas 
226b725ae77Skettenis   return 0;
227b725ae77Skettenis }
228e93f7393Sniklas 
229b725ae77Skettenis /* Check whether TYPE is "Structure or Union".  */
230b725ae77Skettenis 
231b725ae77Skettenis static int
sparc_structure_or_union_p(const struct type * type)232b725ae77Skettenis sparc_structure_or_union_p (const struct type *type)
233b725ae77Skettenis {
234b725ae77Skettenis   switch (TYPE_CODE (type))
235b725ae77Skettenis     {
236b725ae77Skettenis     case TYPE_CODE_STRUCT:
237b725ae77Skettenis     case TYPE_CODE_UNION:
238b725ae77Skettenis       return 1;
239b725ae77Skettenis     default:
240b725ae77Skettenis       break;
241b725ae77Skettenis     }
242b725ae77Skettenis 
243b725ae77Skettenis   return 0;
244b725ae77Skettenis }
245b725ae77Skettenis 
246b725ae77Skettenis /* Register information.  */
247b725ae77Skettenis 
248b725ae77Skettenis static const char *sparc32_register_names[] =
249b725ae77Skettenis {
250b725ae77Skettenis   "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
251b725ae77Skettenis   "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
252b725ae77Skettenis   "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
253b725ae77Skettenis   "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
254b725ae77Skettenis 
255b725ae77Skettenis   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
256b725ae77Skettenis   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
257b725ae77Skettenis   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
258b725ae77Skettenis   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
259b725ae77Skettenis 
260b725ae77Skettenis   "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr"
261b725ae77Skettenis };
262b725ae77Skettenis 
263b725ae77Skettenis /* Total number of registers.  */
264b725ae77Skettenis #define SPARC32_NUM_REGS ARRAY_SIZE (sparc32_register_names)
265b725ae77Skettenis 
266b725ae77Skettenis /* We provide the aliases %d0..%d30 for the floating registers as
267b725ae77Skettenis    "psuedo" registers.  */
268b725ae77Skettenis 
269b725ae77Skettenis static const char *sparc32_pseudo_register_names[] =
270b725ae77Skettenis {
271b725ae77Skettenis   "d0", "d2", "d4", "d6", "d8", "d10", "d12", "d14",
272b725ae77Skettenis   "d16", "d18", "d20", "d22", "d24", "d26", "d28", "d30"
273b725ae77Skettenis };
274b725ae77Skettenis 
275b725ae77Skettenis /* Total number of pseudo registers.  */
276b725ae77Skettenis #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names)
277b725ae77Skettenis 
278b725ae77Skettenis /* Return the name of register REGNUM.  */
279b725ae77Skettenis 
280b725ae77Skettenis static const char *
sparc32_register_name(int regnum)281b725ae77Skettenis sparc32_register_name (int regnum)
282b725ae77Skettenis {
283b725ae77Skettenis   if (regnum >= 0 && regnum < SPARC32_NUM_REGS)
284b725ae77Skettenis     return sparc32_register_names[regnum];
285b725ae77Skettenis 
286b725ae77Skettenis   if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS)
287b725ae77Skettenis     return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS];
288b725ae77Skettenis 
289b725ae77Skettenis   return NULL;
290b725ae77Skettenis }
291b725ae77Skettenis 
292b725ae77Skettenis /* Return the GDB type object for the "standard" data type of data in
293b725ae77Skettenis    register REGNUM. */
294b725ae77Skettenis 
295b725ae77Skettenis static struct type *
sparc32_register_type(struct gdbarch * gdbarch,int regnum)296b725ae77Skettenis sparc32_register_type (struct gdbarch *gdbarch, int regnum)
297b725ae77Skettenis {
298b725ae77Skettenis   if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
299b725ae77Skettenis     return builtin_type_float;
300b725ae77Skettenis 
301b725ae77Skettenis   if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
302b725ae77Skettenis     return builtin_type_double;
303b725ae77Skettenis 
304b725ae77Skettenis   if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
305b725ae77Skettenis     return builtin_type_void_data_ptr;
306b725ae77Skettenis 
307b725ae77Skettenis   if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
308b725ae77Skettenis     return builtin_type_void_func_ptr;
309b725ae77Skettenis 
310b725ae77Skettenis   return builtin_type_int32;
311b725ae77Skettenis }
312e93f7393Sniklas 
313e93f7393Sniklas static void
sparc32_pseudo_register_read(struct gdbarch * gdbarch,struct regcache * regcache,int regnum,void * buf)314b725ae77Skettenis sparc32_pseudo_register_read (struct gdbarch *gdbarch,
315b725ae77Skettenis 			      struct regcache *regcache,
316b725ae77Skettenis 			      int regnum, void *buf)
317e93f7393Sniklas {
318b725ae77Skettenis   gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
319b725ae77Skettenis 
320b725ae77Skettenis   regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
321b725ae77Skettenis   regcache_raw_read (regcache, regnum, buf);
322b725ae77Skettenis   regcache_raw_read (regcache, regnum + 1, ((char *)buf) + 4);
323e93f7393Sniklas }
324e93f7393Sniklas 
325b725ae77Skettenis static void
sparc32_pseudo_register_write(struct gdbarch * gdbarch,struct regcache * regcache,int regnum,const void * buf)326b725ae77Skettenis sparc32_pseudo_register_write (struct gdbarch *gdbarch,
327b725ae77Skettenis 			       struct regcache *regcache,
328b725ae77Skettenis 			       int regnum, const void *buf)
329e93f7393Sniklas {
330b725ae77Skettenis   gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
331e93f7393Sniklas 
332b725ae77Skettenis   regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
333b725ae77Skettenis   regcache_raw_write (regcache, regnum, buf);
334b725ae77Skettenis   regcache_raw_write (regcache, regnum + 1, ((const char *)buf) + 4);
335e93f7393Sniklas }
336e93f7393Sniklas 
337b725ae77Skettenis 
338b725ae77Skettenis static CORE_ADDR
sparc32_push_dummy_code(struct gdbarch * gdbarch,CORE_ADDR sp,CORE_ADDR funcaddr,int using_gcc,struct value ** args,int nargs,struct type * value_type,CORE_ADDR * real_pc,CORE_ADDR * bp_addr)339b725ae77Skettenis sparc32_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
340b725ae77Skettenis 			 CORE_ADDR funcaddr, int using_gcc,
341b725ae77Skettenis 			 struct value **args, int nargs,
342b725ae77Skettenis 			 struct type *value_type,
343b725ae77Skettenis 			 CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
344e93f7393Sniklas {
345b725ae77Skettenis   *bp_addr = sp - 4;
346b725ae77Skettenis   *real_pc = funcaddr;
347b725ae77Skettenis 
348b725ae77Skettenis   if (using_struct_return (value_type, using_gcc))
349b725ae77Skettenis     {
350b725ae77Skettenis       char buf[4];
351b725ae77Skettenis 
352b725ae77Skettenis       /* This is an UNIMP instruction.  */
353b725ae77Skettenis       store_unsigned_integer (buf, 4, TYPE_LENGTH (value_type) & 0x1fff);
354b725ae77Skettenis       write_memory (sp - 8, buf, 4);
355b725ae77Skettenis       return sp - 8;
356e93f7393Sniklas     }
357772be053Sfgsch 
358b725ae77Skettenis   return sp - 4;
359b725ae77Skettenis }
3603ee1684eSfgsch 
361b725ae77Skettenis static CORE_ADDR
sparc32_store_arguments(struct regcache * regcache,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)362b725ae77Skettenis sparc32_store_arguments (struct regcache *regcache, int nargs,
363b725ae77Skettenis 			 struct value **args, CORE_ADDR sp,
364b725ae77Skettenis 			 int struct_return, CORE_ADDR struct_addr)
365772be053Sfgsch {
366b725ae77Skettenis   /* Number of words in the "parameter array".  */
367b725ae77Skettenis   int num_elements = 0;
368b725ae77Skettenis   int element = 0;
369b725ae77Skettenis   int i;
370772be053Sfgsch 
371b725ae77Skettenis   for (i = 0; i < nargs; i++)
372b725ae77Skettenis     {
373b725ae77Skettenis       struct type *type = VALUE_TYPE (args[i]);
374b725ae77Skettenis       int len = TYPE_LENGTH (type);
375b725ae77Skettenis 
376b725ae77Skettenis       if (sparc_structure_or_union_p (type)
377b725ae77Skettenis 	  || (sparc_floating_p (type) && len == 16))
378b725ae77Skettenis 	{
379b725ae77Skettenis 	  /* Structure, Union and Quad-Precision Arguments.  */
380b725ae77Skettenis 	  sp -= len;
381b725ae77Skettenis 
382b725ae77Skettenis 	  /* Use doubleword alignment for these values.  That's always
383b725ae77Skettenis              correct, and wasting a few bytes shouldn't be a problem.  */
384b725ae77Skettenis 	  sp &= ~0x7;
385b725ae77Skettenis 
386b725ae77Skettenis 	  write_memory (sp, VALUE_CONTENTS (args[i]), len);
387b725ae77Skettenis 	  args[i] = value_from_pointer (lookup_pointer_type (type), sp);
388b725ae77Skettenis 	  num_elements++;
389b725ae77Skettenis 	}
390b725ae77Skettenis       else if (sparc_floating_p (type))
391b725ae77Skettenis 	{
392b725ae77Skettenis 	  /* Floating arguments.  */
393b725ae77Skettenis 	  gdb_assert (len == 4 || len == 8);
394b725ae77Skettenis 	  num_elements += (len / 4);
395b725ae77Skettenis 	}
396b725ae77Skettenis       else
397b725ae77Skettenis 	{
398b725ae77Skettenis 	  /* Integral and pointer arguments.  */
399b725ae77Skettenis 	  gdb_assert (sparc_integral_or_pointer_p (type));
400b725ae77Skettenis 
401b725ae77Skettenis 	  if (len < 4)
402b725ae77Skettenis 	    args[i] = value_cast (builtin_type_int32, args[i]);
403b725ae77Skettenis 	  num_elements += ((len + 3) / 4);
404b725ae77Skettenis 	}
405b725ae77Skettenis     }
406b725ae77Skettenis 
407b725ae77Skettenis   /* Always allocate at least six words.  */
408b725ae77Skettenis   sp -= max (6, num_elements) * 4;
409b725ae77Skettenis 
410b725ae77Skettenis   /* The psABI says that "Software convention requires space for the
411b725ae77Skettenis      struct/union return value pointer, even if the word is unused."  */
412b725ae77Skettenis   sp -= 4;
413b725ae77Skettenis 
414b725ae77Skettenis   /* The psABI says that "Although software convention and the
415b725ae77Skettenis      operating system require every stack frame to be doubleword
416b725ae77Skettenis      aligned."  */
417b725ae77Skettenis   sp &= ~0x7;
418b725ae77Skettenis 
419b725ae77Skettenis   for (i = 0; i < nargs; i++)
420b725ae77Skettenis     {
421b725ae77Skettenis       char *valbuf = VALUE_CONTENTS (args[i]);
422b725ae77Skettenis       struct type *type = VALUE_TYPE (args[i]);
423b725ae77Skettenis       int len = TYPE_LENGTH (type);
424b725ae77Skettenis 
425b725ae77Skettenis       gdb_assert (len == 4 || len == 8);
426b725ae77Skettenis 
427b725ae77Skettenis       if (element < 6)
428b725ae77Skettenis 	{
429b725ae77Skettenis 	  int regnum = SPARC_O0_REGNUM + element;
430b725ae77Skettenis 
431b725ae77Skettenis 	  regcache_cooked_write (regcache, regnum, valbuf);
432b725ae77Skettenis 	  if (len > 4 && element < 5)
433b725ae77Skettenis 	    regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
434b725ae77Skettenis 	}
435b725ae77Skettenis 
436b725ae77Skettenis       /* Always store the argument in memory.  */
437b725ae77Skettenis       write_memory (sp + 4 + element * 4, valbuf, len);
438b725ae77Skettenis       element += len / 4;
439b725ae77Skettenis     }
440b725ae77Skettenis 
441b725ae77Skettenis   gdb_assert (element == num_elements);
442b725ae77Skettenis 
443b725ae77Skettenis   if (struct_return)
444b725ae77Skettenis     {
445b725ae77Skettenis       char buf[4];
446b725ae77Skettenis 
447b725ae77Skettenis       store_unsigned_integer (buf, 4, struct_addr);
448b725ae77Skettenis       write_memory (sp, buf, 4);
449b725ae77Skettenis     }
450b725ae77Skettenis 
451772be053Sfgsch   return sp;
452772be053Sfgsch }
453772be053Sfgsch 
454b725ae77Skettenis static CORE_ADDR
sparc32_push_dummy_call(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)45563addd46Skettenis sparc32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
456b725ae77Skettenis 			 struct regcache *regcache, CORE_ADDR bp_addr,
457b725ae77Skettenis 			 int nargs, struct value **args, CORE_ADDR sp,
458b725ae77Skettenis 			 int struct_return, CORE_ADDR struct_addr)
459b725ae77Skettenis {
460b725ae77Skettenis   CORE_ADDR call_pc = (struct_return ? (bp_addr - 12) : (bp_addr - 8));
461b725ae77Skettenis 
462b725ae77Skettenis   /* Set return address.  */
463b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, SPARC_O7_REGNUM, call_pc);
464b725ae77Skettenis 
465b725ae77Skettenis   /* Set up function arguments.  */
466b725ae77Skettenis   sp = sparc32_store_arguments (regcache, nargs, args, sp,
467b725ae77Skettenis 				struct_return, struct_addr);
468b725ae77Skettenis 
469b725ae77Skettenis   /* Allocate the 16-word window save area.  */
470b725ae77Skettenis   sp -= 16 * 4;
471b725ae77Skettenis 
472b725ae77Skettenis   /* Stack should be doubleword aligned at this point.  */
473b725ae77Skettenis   gdb_assert (sp % 8 == 0);
474b725ae77Skettenis 
475b725ae77Skettenis   /* Finally, update the stack pointer.  */
476b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, SPARC_SP_REGNUM, sp);
477b725ae77Skettenis 
478b725ae77Skettenis   return sp;
479b725ae77Skettenis }
480b725ae77Skettenis 
481b725ae77Skettenis 
482b725ae77Skettenis /* Use the program counter to determine the contents and size of a
483b725ae77Skettenis    breakpoint instruction.  Return a pointer to a string of bytes that
484b725ae77Skettenis    encode a breakpoint instruction, store the length of the string in
485b725ae77Skettenis    *LEN and optionally adjust *PC to point to the correct memory
486b725ae77Skettenis    location for inserting the breakpoint.  */
487b725ae77Skettenis 
488b725ae77Skettenis static const unsigned char *
sparc_breakpoint_from_pc(CORE_ADDR * pc,int * len)489b725ae77Skettenis sparc_breakpoint_from_pc (CORE_ADDR *pc, int *len)
490b725ae77Skettenis {
491b725ae77Skettenis   static unsigned char break_insn[] = { 0x91, 0xd0, 0x20, 0x01 };
492b725ae77Skettenis 
493b725ae77Skettenis   *len = sizeof (break_insn);
494b725ae77Skettenis   return break_insn;
495b725ae77Skettenis }
496b725ae77Skettenis 
497b725ae77Skettenis 
498b725ae77Skettenis /* Allocate and initialize a frame cache.  */
499b725ae77Skettenis 
500b725ae77Skettenis static struct sparc_frame_cache *
sparc_alloc_frame_cache(void)501b725ae77Skettenis sparc_alloc_frame_cache (void)
502b725ae77Skettenis {
503b725ae77Skettenis   struct sparc_frame_cache *cache;
504b725ae77Skettenis   int i;
505b725ae77Skettenis 
506b725ae77Skettenis   cache = FRAME_OBSTACK_ZALLOC (struct sparc_frame_cache);
507b725ae77Skettenis 
508b725ae77Skettenis   /* Base address.  */
509b725ae77Skettenis   cache->base = 0;
510b725ae77Skettenis   cache->pc = 0;
511b725ae77Skettenis 
512b725ae77Skettenis   /* Frameless until proven otherwise.  */
513b725ae77Skettenis   cache->frameless_p = 1;
514b725ae77Skettenis 
515b725ae77Skettenis   cache->struct_return_p = 0;
516b725ae77Skettenis 
517b725ae77Skettenis   return cache;
518b725ae77Skettenis }
519b725ae77Skettenis 
520772be053Sfgsch CORE_ADDR
sparc_analyze_prologue(CORE_ADDR pc,CORE_ADDR current_pc,struct sparc_frame_cache * cache)521b725ae77Skettenis sparc_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
522b725ae77Skettenis 			struct sparc_frame_cache *cache)
523772be053Sfgsch {
524b725ae77Skettenis   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
525b725ae77Skettenis   unsigned long insn;
526b725ae77Skettenis   int offset = 0;
527b725ae77Skettenis   int dest = -1;
528772be053Sfgsch 
529b725ae77Skettenis   if (current_pc <= pc)
530b725ae77Skettenis     return current_pc;
531b725ae77Skettenis 
532b725ae77Skettenis   /* We have to handle to "Procedure Linkage Table" (PLT) special.  On
533b725ae77Skettenis      SPARC the linker usually defines a symbol (typically
534b725ae77Skettenis      _PROCEDURE_LINKAGE_TABLE_) at the start of the .plt section.
535b725ae77Skettenis      This symbol makes us end up here with PC pointing at the start of
536b725ae77Skettenis      the PLT and CURRENT_PC probably pointing at a PLT entry.  If we
537b725ae77Skettenis      would do our normal prologue analysis, we would probably conclude
538b725ae77Skettenis      that we've got a frame when in reality we don't, since the
539b725ae77Skettenis      dynamic linker patches up the first PLT with some code that
540b725ae77Skettenis      starts with a SAVE instruction.  Patch up PC such that it points
541b725ae77Skettenis      at the start of our PLT entry.  */
542b725ae77Skettenis   if (tdep->plt_entry_size > 0 && in_plt_section (current_pc, NULL))
543b725ae77Skettenis     pc = current_pc - ((current_pc - pc) % tdep->plt_entry_size);
544b725ae77Skettenis 
545b725ae77Skettenis   insn = sparc_fetch_instruction (pc);
546b725ae77Skettenis 
547b725ae77Skettenis   /* Recognize a SETHI insn and record its destination.  */
548b725ae77Skettenis   if (X_OP (insn) == 0 && X_OP2 (insn) == 0x04)
549b725ae77Skettenis     {
550b725ae77Skettenis       dest = X_RD (insn);
551b725ae77Skettenis       offset += 4;
552b725ae77Skettenis 
553b725ae77Skettenis       insn = sparc_fetch_instruction (pc + 4);
554772be053Sfgsch     }
555772be053Sfgsch 
556b725ae77Skettenis   /* Allow for an arithmetic operation on DEST or %g1.  */
557b725ae77Skettenis   if (X_OP (insn) == 2 && X_I (insn)
558b725ae77Skettenis       && (X_RD (insn) == 1 || X_RD (insn) == dest))
559772be053Sfgsch     {
560b725ae77Skettenis       offset += 4;
561b725ae77Skettenis 
562b725ae77Skettenis       insn = sparc_fetch_instruction (pc + 8);
563b725ae77Skettenis     }
564b725ae77Skettenis 
565b725ae77Skettenis   /* Check for the SAVE instruction that sets up the frame.  */
566b725ae77Skettenis   if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
567b725ae77Skettenis     {
568b725ae77Skettenis       cache->frameless_p = 0;
569b725ae77Skettenis       return pc + offset + 4;
570b725ae77Skettenis     }
571b725ae77Skettenis 
572b725ae77Skettenis   return pc;
573b725ae77Skettenis }
574b725ae77Skettenis 
575b725ae77Skettenis static CORE_ADDR
sparc_unwind_pc(struct gdbarch * gdbarch,struct frame_info * next_frame)576b725ae77Skettenis sparc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
577b725ae77Skettenis {
578b725ae77Skettenis   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
579b725ae77Skettenis   return frame_unwind_register_unsigned (next_frame, tdep->pc_regnum);
580b725ae77Skettenis }
581b725ae77Skettenis 
582b725ae77Skettenis /* Return PC of first real instruction of the function starting at
583b725ae77Skettenis    START_PC.  */
584b725ae77Skettenis 
585b725ae77Skettenis static CORE_ADDR
sparc32_skip_prologue(CORE_ADDR start_pc)586b725ae77Skettenis sparc32_skip_prologue (CORE_ADDR start_pc)
587b725ae77Skettenis {
588b725ae77Skettenis   struct symtab_and_line sal;
589b725ae77Skettenis   CORE_ADDR func_start, func_end;
590b725ae77Skettenis   struct sparc_frame_cache cache;
591b725ae77Skettenis 
592b725ae77Skettenis   /* This is the preferred method, find the end of the prologue by
593b725ae77Skettenis      using the debugging information.  */
594b725ae77Skettenis   if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
595b725ae77Skettenis     {
596b725ae77Skettenis       sal = find_pc_line (func_start, 0);
597b725ae77Skettenis 
598b725ae77Skettenis       if (sal.end < func_end
599b725ae77Skettenis 	  && start_pc <= sal.end)
600b725ae77Skettenis 	return sal.end;
601b725ae77Skettenis     }
602b725ae77Skettenis 
603b725ae77Skettenis   return sparc_analyze_prologue (start_pc, 0xffffffffUL, &cache);
604b725ae77Skettenis }
605b725ae77Skettenis 
606b725ae77Skettenis /* Normal frames.  */
607b725ae77Skettenis 
608b725ae77Skettenis struct sparc_frame_cache *
sparc_frame_cache(struct frame_info * next_frame,void ** this_cache)609b725ae77Skettenis sparc_frame_cache (struct frame_info *next_frame, void **this_cache)
610b725ae77Skettenis {
611b725ae77Skettenis   struct sparc_frame_cache *cache;
612b725ae77Skettenis 
613b725ae77Skettenis   if (*this_cache)
614b725ae77Skettenis     return *this_cache;
615b725ae77Skettenis 
616b725ae77Skettenis   cache = sparc_alloc_frame_cache ();
617b725ae77Skettenis   *this_cache = cache;
618b725ae77Skettenis 
619b725ae77Skettenis   cache->pc = frame_func_unwind (next_frame);
620b725ae77Skettenis   if (cache->pc != 0)
621b725ae77Skettenis     {
622b725ae77Skettenis       CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame);
623b725ae77Skettenis       sparc_analyze_prologue (cache->pc, addr_in_block, cache);
624b725ae77Skettenis     }
625b725ae77Skettenis 
626b725ae77Skettenis   if (cache->frameless_p)
627b725ae77Skettenis     {
628b725ae77Skettenis       /* This function is frameless, so %fp (%i6) holds the frame
629b725ae77Skettenis          pointer for our calling frame.  Use %sp (%o6) as this frame's
630b725ae77Skettenis          base address.  */
631b725ae77Skettenis       cache->base =
632b725ae77Skettenis 	frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
633b725ae77Skettenis     }
634772be053Sfgsch   else
635772be053Sfgsch     {
636b725ae77Skettenis       /* For normal frames, %fp (%i6) holds the frame pointer, the
637b725ae77Skettenis          base address for the current stack frame.  */
638b725ae77Skettenis       cache->base =
639b725ae77Skettenis 	frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
640772be053Sfgsch     }
641772be053Sfgsch 
642b725ae77Skettenis   return cache;
643b725ae77Skettenis }
644b725ae77Skettenis 
645b725ae77Skettenis struct sparc_frame_cache *
sparc32_frame_cache(struct frame_info * next_frame,void ** this_cache)646b725ae77Skettenis sparc32_frame_cache (struct frame_info *next_frame, void **this_cache)
647b725ae77Skettenis {
648b725ae77Skettenis   struct sparc_frame_cache *cache;
649b725ae77Skettenis   struct symbol *sym;
650b725ae77Skettenis 
651b725ae77Skettenis   if (*this_cache)
652b725ae77Skettenis     return *this_cache;
653b725ae77Skettenis 
654b725ae77Skettenis   cache = sparc_frame_cache (next_frame, this_cache);
655b725ae77Skettenis 
656b725ae77Skettenis   sym = find_pc_function (cache->pc);
657b725ae77Skettenis   if (sym)
658b725ae77Skettenis     {
659b725ae77Skettenis       struct type *type = check_typedef (SYMBOL_TYPE (sym));
660b725ae77Skettenis       enum type_code code = TYPE_CODE (type);
661b725ae77Skettenis 
662b725ae77Skettenis       if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
663b725ae77Skettenis 	{
664b725ae77Skettenis 	  type = check_typedef (TYPE_TARGET_TYPE (type));
665b725ae77Skettenis 	  if (sparc_structure_or_union_p (type)
666b725ae77Skettenis 	      || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
667b725ae77Skettenis 	    cache->struct_return_p = 1;
668b725ae77Skettenis 	}
669b725ae77Skettenis     }
670b725ae77Skettenis 
671b725ae77Skettenis   return cache;
672b725ae77Skettenis }
673b725ae77Skettenis 
674b725ae77Skettenis static void
sparc32_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)675b725ae77Skettenis sparc32_frame_this_id (struct frame_info *next_frame, void **this_cache,
676b725ae77Skettenis 		       struct frame_id *this_id)
677b725ae77Skettenis {
678b725ae77Skettenis   struct sparc_frame_cache *cache =
679b725ae77Skettenis     sparc32_frame_cache (next_frame, this_cache);
680b725ae77Skettenis 
681b725ae77Skettenis   /* This marks the outermost frame.  */
682b725ae77Skettenis   if (cache->base == 0)
683b725ae77Skettenis     return;
684b725ae77Skettenis 
685b725ae77Skettenis   (*this_id) = frame_id_build (cache->base, cache->pc);
686b725ae77Skettenis }
687b725ae77Skettenis 
688b725ae77Skettenis static void
sparc32_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)689b725ae77Skettenis sparc32_frame_prev_register (struct frame_info *next_frame, void **this_cache,
690b725ae77Skettenis 			     int regnum, int *optimizedp,
691b725ae77Skettenis 			     enum lval_type *lvalp, CORE_ADDR *addrp,
692b725ae77Skettenis 			     int *realnump, void *valuep)
693b725ae77Skettenis {
694b725ae77Skettenis   struct sparc_frame_cache *cache =
695b725ae77Skettenis     sparc32_frame_cache (next_frame, this_cache);
696b725ae77Skettenis 
697b725ae77Skettenis   if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
698b725ae77Skettenis     {
699b725ae77Skettenis       *optimizedp = 0;
700b725ae77Skettenis       *lvalp = not_lval;
701b725ae77Skettenis       *addrp = 0;
702b725ae77Skettenis       *realnump = -1;
703b725ae77Skettenis       if (valuep)
704b725ae77Skettenis 	{
705b725ae77Skettenis 	  CORE_ADDR pc = (regnum == SPARC32_NPC_REGNUM) ? 4 : 0;
706b725ae77Skettenis 
707b725ae77Skettenis 	  /* If this functions has a Structure, Union or
708b725ae77Skettenis              Quad-Precision return value, we have to skip the UNIMP
709b725ae77Skettenis              instruction that encodes the size of the structure.  */
710b725ae77Skettenis 	  if (cache->struct_return_p)
711b725ae77Skettenis 	    pc += 4;
712b725ae77Skettenis 
713b725ae77Skettenis 	  regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
714b725ae77Skettenis 	  pc += frame_unwind_register_unsigned (next_frame, regnum) + 8;
715b725ae77Skettenis 	  store_unsigned_integer (valuep, 4, pc);
716b725ae77Skettenis 	}
717b725ae77Skettenis       return;
718b725ae77Skettenis     }
719b725ae77Skettenis 
720b725ae77Skettenis   /* Handle StackGhost.  */
721b725ae77Skettenis   {
722b725ae77Skettenis     ULONGEST wcookie = sparc_fetch_wcookie ();
723b725ae77Skettenis 
724b725ae77Skettenis     if (wcookie != 0 && !cache->frameless_p && regnum == SPARC_I7_REGNUM)
725b725ae77Skettenis       {
726b725ae77Skettenis 	*optimizedp = 0;
727b725ae77Skettenis 	*lvalp = not_lval;
728b725ae77Skettenis 	*addrp = 0;
729b725ae77Skettenis 	*realnump = -1;
730b725ae77Skettenis 	if (valuep)
731b725ae77Skettenis 	  {
732b725ae77Skettenis 	    CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
733b725ae77Skettenis 	    ULONGEST i7;
734b725ae77Skettenis 
735b725ae77Skettenis 	    /* Read the value in from memory.  */
736b725ae77Skettenis 	    i7 = get_frame_memory_unsigned (next_frame, addr, 4);
737b725ae77Skettenis 	    store_unsigned_integer (valuep, 4, i7 ^ wcookie);
738b725ae77Skettenis 	  }
739b725ae77Skettenis 	return;
740b725ae77Skettenis       }
741b725ae77Skettenis   }
742b725ae77Skettenis 
743b725ae77Skettenis   /* The previous frame's `local' and `in' registers have been saved
744b725ae77Skettenis      in the register save area.  */
745b725ae77Skettenis   if (!cache->frameless_p
746b725ae77Skettenis       && regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)
747b725ae77Skettenis     {
748b725ae77Skettenis       *optimizedp = 0;
749b725ae77Skettenis       *lvalp = lval_memory;
750b725ae77Skettenis       *addrp = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
751b725ae77Skettenis       *realnump = -1;
752b725ae77Skettenis       if (valuep)
753b725ae77Skettenis 	{
754b725ae77Skettenis 	  struct gdbarch *gdbarch = get_frame_arch (next_frame);
755b725ae77Skettenis 
756b725ae77Skettenis 	  /* Read the value in from memory.  */
757b725ae77Skettenis 	  read_memory (*addrp, valuep, register_size (gdbarch, regnum));
758b725ae77Skettenis 	}
759b725ae77Skettenis       return;
760b725ae77Skettenis     }
761b725ae77Skettenis 
762b725ae77Skettenis   /* The previous frame's `out' registers are accessable as the
763b725ae77Skettenis      current frame's `in' registers.  */
764b725ae77Skettenis   if (!cache->frameless_p
765b725ae77Skettenis       && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
766b725ae77Skettenis     regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
767b725ae77Skettenis 
768b725ae77Skettenis   frame_register_unwind (next_frame, regnum,
769b725ae77Skettenis 			 optimizedp, lvalp, addrp, realnump, valuep);
770b725ae77Skettenis }
771b725ae77Skettenis 
772b725ae77Skettenis static const struct frame_unwind sparc32_frame_unwind =
773b725ae77Skettenis {
774b725ae77Skettenis   NORMAL_FRAME,
775b725ae77Skettenis   sparc32_frame_this_id,
776b725ae77Skettenis   sparc32_frame_prev_register
777b725ae77Skettenis };
778b725ae77Skettenis 
779b725ae77Skettenis static const struct frame_unwind *
sparc32_frame_sniffer(struct frame_info * next_frame)780b725ae77Skettenis sparc32_frame_sniffer (struct frame_info *next_frame)
781b725ae77Skettenis {
782b725ae77Skettenis   return &sparc32_frame_unwind;
783b725ae77Skettenis }
784b725ae77Skettenis 
785b725ae77Skettenis 
786b725ae77Skettenis static CORE_ADDR
sparc32_frame_base_address(struct frame_info * next_frame,void ** this_cache)787b725ae77Skettenis sparc32_frame_base_address (struct frame_info *next_frame, void **this_cache)
788b725ae77Skettenis {
789b725ae77Skettenis   struct sparc_frame_cache *cache =
790b725ae77Skettenis     sparc32_frame_cache (next_frame, this_cache);
791b725ae77Skettenis 
792b725ae77Skettenis   return cache->base;
793b725ae77Skettenis }
794b725ae77Skettenis 
795b725ae77Skettenis static const struct frame_base sparc32_frame_base =
796b725ae77Skettenis {
797b725ae77Skettenis   &sparc32_frame_unwind,
798b725ae77Skettenis   sparc32_frame_base_address,
799b725ae77Skettenis   sparc32_frame_base_address,
800b725ae77Skettenis   sparc32_frame_base_address
801b725ae77Skettenis };
802b725ae77Skettenis 
803b725ae77Skettenis static struct frame_id
sparc_unwind_dummy_id(struct gdbarch * gdbarch,struct frame_info * next_frame)804b725ae77Skettenis sparc_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
805b725ae77Skettenis {
806b725ae77Skettenis   CORE_ADDR sp;
807b725ae77Skettenis 
808b725ae77Skettenis   sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
809b725ae77Skettenis   return frame_id_build (sp, frame_pc_unwind (next_frame));
810b725ae77Skettenis }
811b725ae77Skettenis 
812b725ae77Skettenis 
813b725ae77Skettenis /* Extract from an array REGBUF containing the (raw) register state, a
814b725ae77Skettenis    function return value of TYPE, and copy that into VALBUF.  */
815b725ae77Skettenis 
816b725ae77Skettenis static void
sparc32_extract_return_value(struct type * type,struct regcache * regcache,void * valbuf)817b725ae77Skettenis sparc32_extract_return_value (struct type *type, struct regcache *regcache,
818b725ae77Skettenis 			      void *valbuf)
819b725ae77Skettenis {
820b725ae77Skettenis   int len = TYPE_LENGTH (type);
821b725ae77Skettenis   char buf[8];
822b725ae77Skettenis 
823b725ae77Skettenis   gdb_assert (!sparc_structure_or_union_p (type));
824b725ae77Skettenis   gdb_assert (!(sparc_floating_p (type) && len == 16));
825b725ae77Skettenis 
826b725ae77Skettenis   if (sparc_floating_p (type))
827b725ae77Skettenis     {
828b725ae77Skettenis       /* Floating return values.  */
829b725ae77Skettenis       regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf);
830b725ae77Skettenis       if (len > 4)
831b725ae77Skettenis 	regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4);
832b725ae77Skettenis       memcpy (valbuf, buf, len);
833b725ae77Skettenis     }
834b725ae77Skettenis   else
835b725ae77Skettenis     {
836b725ae77Skettenis       /* Integral and pointer return values.  */
837b725ae77Skettenis       gdb_assert (sparc_integral_or_pointer_p (type));
838b725ae77Skettenis 
839b725ae77Skettenis       regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
840b725ae77Skettenis       if (len > 4)
841b725ae77Skettenis 	{
842b725ae77Skettenis 	  regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + 4);
843b725ae77Skettenis 	  gdb_assert (len == 8);
844b725ae77Skettenis 	  memcpy (valbuf, buf, 8);
845b725ae77Skettenis 	}
846b725ae77Skettenis       else
847b725ae77Skettenis 	{
848b725ae77Skettenis 	  /* Just stripping off any unused bytes should preserve the
849b725ae77Skettenis 	     signed-ness just fine.  */
850b725ae77Skettenis 	  memcpy (valbuf, buf + 4 - len, len);
851b725ae77Skettenis 	}
852b725ae77Skettenis     }
853b725ae77Skettenis }
854b725ae77Skettenis 
855b725ae77Skettenis /* Write into the appropriate registers a function return value stored
856b725ae77Skettenis    in VALBUF of type TYPE.  */
857b725ae77Skettenis 
858b725ae77Skettenis static void
sparc32_store_return_value(struct type * type,struct regcache * regcache,const void * valbuf)859b725ae77Skettenis sparc32_store_return_value (struct type *type, struct regcache *regcache,
860b725ae77Skettenis 			    const void *valbuf)
861b725ae77Skettenis {
862b725ae77Skettenis   int len = TYPE_LENGTH (type);
863b725ae77Skettenis   char buf[8];
864b725ae77Skettenis 
865b725ae77Skettenis   gdb_assert (!sparc_structure_or_union_p (type));
866b725ae77Skettenis   gdb_assert (!(sparc_floating_p (type) && len == 16));
867b725ae77Skettenis 
868b725ae77Skettenis   if (sparc_floating_p (type))
869b725ae77Skettenis     {
870b725ae77Skettenis       /* Floating return values.  */
871b725ae77Skettenis       memcpy (buf, valbuf, len);
872b725ae77Skettenis       regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf);
873b725ae77Skettenis       if (len > 4)
874b725ae77Skettenis 	regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4);
875b725ae77Skettenis     }
876b725ae77Skettenis   else
877b725ae77Skettenis     {
878b725ae77Skettenis       /* Integral and pointer return values.  */
879b725ae77Skettenis       gdb_assert (sparc_integral_or_pointer_p (type));
880b725ae77Skettenis 
881b725ae77Skettenis       if (len > 4)
882b725ae77Skettenis 	{
883b725ae77Skettenis 	  gdb_assert (len == 8);
884b725ae77Skettenis 	  memcpy (buf, valbuf, 8);
885b725ae77Skettenis 	  regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + 4);
886b725ae77Skettenis 	}
887b725ae77Skettenis       else
888b725ae77Skettenis 	{
889b725ae77Skettenis 	  /* ??? Do we need to do any sign-extension here?  */
890b725ae77Skettenis 	  memcpy (buf + 4 - len, valbuf, len);
891b725ae77Skettenis 	}
892b725ae77Skettenis       regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
893b725ae77Skettenis     }
894b725ae77Skettenis }
895b725ae77Skettenis 
896b725ae77Skettenis static enum return_value_convention
sparc32_return_value(struct gdbarch * gdbarch,struct type * type,struct regcache * regcache,void * readbuf,const void * writebuf)897b725ae77Skettenis sparc32_return_value (struct gdbarch *gdbarch, struct type *type,
898b725ae77Skettenis 		      struct regcache *regcache, void *readbuf,
899b725ae77Skettenis 		      const void *writebuf)
900b725ae77Skettenis {
901b725ae77Skettenis   if (sparc_structure_or_union_p (type)
902b725ae77Skettenis       || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
903b725ae77Skettenis     return RETURN_VALUE_STRUCT_CONVENTION;
904b725ae77Skettenis 
905b725ae77Skettenis   if (readbuf)
906b725ae77Skettenis     sparc32_extract_return_value (type, regcache, readbuf);
907b725ae77Skettenis   if (writebuf)
908b725ae77Skettenis     sparc32_store_return_value (type, regcache, writebuf);
909b725ae77Skettenis 
910b725ae77Skettenis   return RETURN_VALUE_REGISTER_CONVENTION;
911b725ae77Skettenis }
912b725ae77Skettenis 
913b725ae77Skettenis #if 0
914b725ae77Skettenis /* NOTE: cagney/2004-01-17: For the moment disable this method.  The
915b725ae77Skettenis    architecture and CORE-gdb will need new code (and a replacement for
916b725ae77Skettenis    DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS) before this can be made to
917b725ae77Skettenis    work robustly.  Here is a possible function signature: */
918b725ae77Skettenis /* NOTE: cagney/2004-01-17: So far only the 32-bit SPARC ABI has been
919b725ae77Skettenis    identifed as having a way to robustly recover the address of a
920b725ae77Skettenis    struct-convention return-value (after the function has returned).
921b725ae77Skettenis    For all other ABIs so far examined, the calling convention makes no
922b725ae77Skettenis    guarenteed that the register containing the return-value will be
923b725ae77Skettenis    preserved and hence that the return-value's address can be
924b725ae77Skettenis    recovered.  */
925b725ae77Skettenis /* Extract from REGCACHE, which contains the (raw) register state, the
926b725ae77Skettenis    address in which a function should return its structure value, as a
927b725ae77Skettenis    CORE_ADDR.  */
928b725ae77Skettenis 
929b725ae77Skettenis static CORE_ADDR
930b725ae77Skettenis sparc32_extract_struct_value_address (struct regcache *regcache)
931b725ae77Skettenis {
932b725ae77Skettenis   ULONGEST sp;
933b725ae77Skettenis 
934b725ae77Skettenis   regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
935b725ae77Skettenis   return read_memory_unsigned_integer (sp + 64, 4);
936b725ae77Skettenis }
9373ee1684eSfgsch #endif
938b725ae77Skettenis 
939b725ae77Skettenis static int
sparc32_stabs_argument_has_addr(struct gdbarch * gdbarch,struct type * type)940b725ae77Skettenis sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
941b725ae77Skettenis {
942b725ae77Skettenis   return (sparc_structure_or_union_p (type)
943b725ae77Skettenis 	  || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16));
944b725ae77Skettenis }
945b725ae77Skettenis 
946b725ae77Skettenis 
947b725ae77Skettenis /* The SPARC Architecture doesn't have hardware single-step support,
948b725ae77Skettenis    and most operating systems don't implement it either, so we provide
949b725ae77Skettenis    software single-step mechanism.  */
950b725ae77Skettenis 
951b725ae77Skettenis static CORE_ADDR
sparc_analyze_control_transfer(CORE_ADDR pc,CORE_ADDR * npc)952b725ae77Skettenis sparc_analyze_control_transfer (CORE_ADDR pc, CORE_ADDR *npc)
953b725ae77Skettenis {
954b725ae77Skettenis   unsigned long insn = sparc_fetch_instruction (pc);
955b725ae77Skettenis   int conditional_p = X_COND (insn) & 0x7;
956b725ae77Skettenis   int branch_p = 0;
957b725ae77Skettenis   long offset = 0;			/* Must be signed for sign-extend.  */
958b725ae77Skettenis 
959b725ae77Skettenis   if (X_OP (insn) == 0 && X_OP2 (insn) == 3 && (insn & 0x1000000) == 0)
960b725ae77Skettenis     {
961b725ae77Skettenis       /* Branch on Integer Register with Prediction (BPr).  */
962b725ae77Skettenis       branch_p = 1;
963b725ae77Skettenis       conditional_p = 1;
964b725ae77Skettenis     }
965b725ae77Skettenis   else if (X_OP (insn) == 0 && X_OP2 (insn) == 6)
966b725ae77Skettenis     {
967b725ae77Skettenis       /* Branch on Floating-Point Condition Codes (FBfcc).  */
968b725ae77Skettenis       branch_p = 1;
969b725ae77Skettenis       offset = 4 * X_DISP22 (insn);
970b725ae77Skettenis     }
971b725ae77Skettenis   else if (X_OP (insn) == 0 && X_OP2 (insn) == 5)
972b725ae77Skettenis     {
973b725ae77Skettenis       /* Branch on Floating-Point Condition Codes with Prediction
974b725ae77Skettenis          (FBPfcc).  */
975b725ae77Skettenis       branch_p = 1;
976b725ae77Skettenis       offset = 4 * X_DISP19 (insn);
977b725ae77Skettenis     }
978b725ae77Skettenis   else if (X_OP (insn) == 0 && X_OP2 (insn) == 2)
979b725ae77Skettenis     {
980b725ae77Skettenis       /* Branch on Integer Condition Codes (Bicc).  */
981b725ae77Skettenis       branch_p = 1;
982b725ae77Skettenis       offset = 4 * X_DISP22 (insn);
983b725ae77Skettenis     }
984b725ae77Skettenis   else if (X_OP (insn) == 0 && X_OP2 (insn) == 1)
985b725ae77Skettenis     {
986b725ae77Skettenis       /* Branch on Integer Condition Codes with Prediction (BPcc).  */
987b725ae77Skettenis       branch_p = 1;
988b725ae77Skettenis       offset = 4 * X_DISP19 (insn);
989b725ae77Skettenis     }
990*5e948f2aSkettenis   else if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3a)
991*5e948f2aSkettenis     {
992*5e948f2aSkettenis       if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
993*5e948f2aSkettenis 	  || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
994*5e948f2aSkettenis 	{
995*5e948f2aSkettenis 	  /* OpenBSD system call.  */
996*5e948f2aSkettenis 	  ULONGEST number;
997*5e948f2aSkettenis 
998*5e948f2aSkettenis 	  regcache_cooked_read_unsigned (current_regcache,
999*5e948f2aSkettenis 					 SPARC_G1_REGNUM, &number);
1000*5e948f2aSkettenis 
1001*5e948f2aSkettenis 	  if (number & 0x400)
1002*5e948f2aSkettenis 	    return sparc_address_from_register (SPARC_G2_REGNUM);
1003*5e948f2aSkettenis 	  if (number & 0x800)
1004*5e948f2aSkettenis 	    return sparc_address_from_register (SPARC_G7_REGNUM);
1005*5e948f2aSkettenis 	}
1006*5e948f2aSkettenis     }
1007b725ae77Skettenis 
1008b725ae77Skettenis   /* FIXME: Handle DONE and RETRY instructions.  */
1009b725ae77Skettenis 
1010b725ae77Skettenis   /* FIXME: Handle the Trap instruction.  */
1011b725ae77Skettenis 
1012b725ae77Skettenis   if (branch_p)
1013b725ae77Skettenis     {
1014b725ae77Skettenis       if (conditional_p)
1015b725ae77Skettenis 	{
1016b725ae77Skettenis 	  /* For conditional branches, return nPC + 4 iff the annul
1017b725ae77Skettenis 	     bit is 1.  */
1018b725ae77Skettenis 	  return (X_A (insn) ? *npc + 4 : 0);
1019b725ae77Skettenis 	}
1020b725ae77Skettenis       else
1021b725ae77Skettenis 	{
1022b725ae77Skettenis 	  /* For unconditional branches, return the target if its
1023b725ae77Skettenis 	     specified condition is "always" and return nPC + 4 if the
1024b725ae77Skettenis 	     condition is "never".  If the annul bit is 1, set *NPC to
1025b725ae77Skettenis 	     zero.  */
1026b725ae77Skettenis 	  if (X_COND (insn) == 0x0)
1027b725ae77Skettenis 	    pc = *npc, offset = 4;
1028b725ae77Skettenis 	  if (X_A (insn))
1029b725ae77Skettenis 	    *npc = 0;
1030b725ae77Skettenis 
1031b725ae77Skettenis 	  gdb_assert (offset != 0);
1032b725ae77Skettenis 	  return pc + offset;
1033b725ae77Skettenis 	}
1034b725ae77Skettenis     }
1035b725ae77Skettenis 
1036b725ae77Skettenis   return 0;
1037b725ae77Skettenis }
1038b725ae77Skettenis 
1039b725ae77Skettenis void
sparc_software_single_step(enum target_signal sig,int insert_breakpoints_p)1040b725ae77Skettenis sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
1041b725ae77Skettenis {
1042b725ae77Skettenis   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1043b725ae77Skettenis   static CORE_ADDR npc, nnpc;
1044b725ae77Skettenis   static char npc_save[4], nnpc_save[4];
1045b725ae77Skettenis 
1046b725ae77Skettenis   if (insert_breakpoints_p)
1047b725ae77Skettenis     {
1048b297fcd9Skettenis       CORE_ADDR pc, orig_npc;
1049b725ae77Skettenis 
1050b725ae77Skettenis       pc = sparc_address_from_register (tdep->pc_regnum);
1051b297fcd9Skettenis       orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
1052b725ae77Skettenis 
1053b725ae77Skettenis       /* Analyze the instruction at PC.  */
1054b725ae77Skettenis       nnpc = sparc_analyze_control_transfer (pc, &npc);
1055b725ae77Skettenis       if (npc != 0)
1056b725ae77Skettenis 	target_insert_breakpoint (npc, npc_save);
1057b725ae77Skettenis       if (nnpc != 0)
1058b725ae77Skettenis 	target_insert_breakpoint (nnpc, nnpc_save);
1059b725ae77Skettenis 
1060b725ae77Skettenis       /* Assert that we have set at least one breakpoint, and that
1061b297fcd9Skettenis 	 they're not set at the same spot - unless we're going
1062b297fcd9Skettenis 	 from here straight to NULL, i.e. a call or jump to 0.  */
1063b297fcd9Skettenis       gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
1064b297fcd9Skettenis       gdb_assert (nnpc != npc || orig_npc == 0);
1065b725ae77Skettenis     }
1066b725ae77Skettenis   else
1067b725ae77Skettenis     {
1068b725ae77Skettenis       if (npc != 0)
1069b725ae77Skettenis 	target_remove_breakpoint (npc, npc_save);
1070b725ae77Skettenis       if (nnpc != 0)
1071b725ae77Skettenis 	target_remove_breakpoint (nnpc, nnpc_save);
1072b725ae77Skettenis     }
1073b725ae77Skettenis }
1074b725ae77Skettenis 
1075b725ae77Skettenis static void
sparc_write_pc(CORE_ADDR pc,ptid_t ptid)1076b725ae77Skettenis sparc_write_pc (CORE_ADDR pc, ptid_t ptid)
1077b725ae77Skettenis {
1078b725ae77Skettenis   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1079b725ae77Skettenis 
1080b725ae77Skettenis   write_register_pid (tdep->pc_regnum, pc, ptid);
1081b725ae77Skettenis   write_register_pid (tdep->npc_regnum, pc + 4, ptid);
1082b725ae77Skettenis }
1083b725ae77Skettenis 
1084b725ae77Skettenis /* Unglobalize NAME.  */
1085b725ae77Skettenis 
1086b725ae77Skettenis char *
sparc_stabs_unglobalize_name(char * name)1087b725ae77Skettenis sparc_stabs_unglobalize_name (char *name)
1088b725ae77Skettenis {
1089b725ae77Skettenis   /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop,
1090b725ae77Skettenis      SunPRO) convert file static variables into global values, a
1091b725ae77Skettenis      process known as globalization.  In order to do this, the
1092b725ae77Skettenis      compiler will create a unique prefix and prepend it to each file
1093b725ae77Skettenis      static variable.  For static variables within a function, this
1094b725ae77Skettenis      globalization prefix is followed by the function name (nested
1095b725ae77Skettenis      static variables within a function are supposed to generate a
1096b725ae77Skettenis      warning message, and are left alone).  The procedure is
1097b725ae77Skettenis      documented in the Stabs Interface Manual, which is distrubuted
1098b725ae77Skettenis      with the compilers, although version 4.0 of the manual seems to
1099b725ae77Skettenis      be incorrect in some places, at least for SPARC.  The
1100b725ae77Skettenis      globalization prefix is encoded into an N_OPT stab, with the form
1101b725ae77Skettenis      "G=<prefix>".  The globalization prefix always seems to start
1102b725ae77Skettenis      with a dollar sign '$'; a dot '.' is used as a seperator.  So we
1103b725ae77Skettenis      simply strip everything up until the last dot.  */
1104b725ae77Skettenis 
1105b725ae77Skettenis   if (name[0] == '$')
1106b725ae77Skettenis     {
1107b725ae77Skettenis       char *p = strrchr (name, '.');
1108b725ae77Skettenis       if (p)
1109b725ae77Skettenis 	return p + 1;
1110b725ae77Skettenis     }
1111b725ae77Skettenis 
1112b725ae77Skettenis   return name;
1113b725ae77Skettenis }
1114b725ae77Skettenis 
1115b725ae77Skettenis 
1116b725ae77Skettenis /* Return the appropriate register set for the core section identified
1117b725ae77Skettenis    by SECT_NAME and SECT_SIZE.  */
1118b725ae77Skettenis 
1119b725ae77Skettenis const struct regset *
sparc_regset_from_core_section(struct gdbarch * gdbarch,const char * sect_name,size_t sect_size)1120b725ae77Skettenis sparc_regset_from_core_section (struct gdbarch *gdbarch,
1121b725ae77Skettenis 				const char *sect_name, size_t sect_size)
1122b725ae77Skettenis {
1123b725ae77Skettenis   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1124b725ae77Skettenis 
1125b725ae77Skettenis   if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset)
1126b725ae77Skettenis     return tdep->gregset;
1127b725ae77Skettenis 
1128b725ae77Skettenis   if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset)
1129b725ae77Skettenis     return tdep->fpregset;
1130b725ae77Skettenis 
1131b725ae77Skettenis   return NULL;
1132b725ae77Skettenis }
1133b725ae77Skettenis 
1134b725ae77Skettenis 
1135b725ae77Skettenis static struct gdbarch *
sparc32_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)1136b725ae77Skettenis sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1137b725ae77Skettenis {
1138b725ae77Skettenis   struct gdbarch_tdep *tdep;
1139b725ae77Skettenis   struct gdbarch *gdbarch;
1140b725ae77Skettenis 
1141b725ae77Skettenis   /* If there is already a candidate, use it.  */
1142b725ae77Skettenis   arches = gdbarch_list_lookup_by_info (arches, &info);
1143b725ae77Skettenis   if (arches != NULL)
1144b725ae77Skettenis     return arches->gdbarch;
1145b725ae77Skettenis 
1146b725ae77Skettenis   /* Allocate space for the new architecture.  */
1147b725ae77Skettenis   tdep = XMALLOC (struct gdbarch_tdep);
1148b725ae77Skettenis   gdbarch = gdbarch_alloc (&info, tdep);
1149b725ae77Skettenis 
1150b725ae77Skettenis   tdep->pc_regnum = SPARC32_PC_REGNUM;
1151b725ae77Skettenis   tdep->npc_regnum = SPARC32_NPC_REGNUM;
1152b725ae77Skettenis   tdep->gregset = NULL;
1153b725ae77Skettenis   tdep->sizeof_gregset = 0;
1154b725ae77Skettenis   tdep->fpregset = NULL;
1155b725ae77Skettenis   tdep->sizeof_fpregset = 0;
1156b725ae77Skettenis   tdep->plt_entry_size = 0;
1157b725ae77Skettenis 
1158b725ae77Skettenis   set_gdbarch_long_double_bit (gdbarch, 128);
1159b725ae77Skettenis   set_gdbarch_long_double_format (gdbarch, &floatformat_sparc_quad);
1160b725ae77Skettenis 
1161b725ae77Skettenis   set_gdbarch_num_regs (gdbarch, SPARC32_NUM_REGS);
1162b725ae77Skettenis   set_gdbarch_register_name (gdbarch, sparc32_register_name);
1163b725ae77Skettenis   set_gdbarch_register_type (gdbarch, sparc32_register_type);
1164b725ae77Skettenis   set_gdbarch_num_pseudo_regs (gdbarch, SPARC32_NUM_PSEUDO_REGS);
1165b725ae77Skettenis   set_gdbarch_pseudo_register_read (gdbarch, sparc32_pseudo_register_read);
1166b725ae77Skettenis   set_gdbarch_pseudo_register_write (gdbarch, sparc32_pseudo_register_write);
1167b725ae77Skettenis 
1168b725ae77Skettenis   /* Register numbers of various important registers.  */
1169b725ae77Skettenis   set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM); /* %sp */
1170b725ae77Skettenis   set_gdbarch_pc_regnum (gdbarch, SPARC32_PC_REGNUM); /* %pc */
1171b725ae77Skettenis   set_gdbarch_fp0_regnum (gdbarch, SPARC_F0_REGNUM); /* %f0 */
1172b725ae77Skettenis 
1173b725ae77Skettenis   /* Call dummy code.  */
1174b725ae77Skettenis   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
1175b725ae77Skettenis   set_gdbarch_push_dummy_code (gdbarch, sparc32_push_dummy_code);
1176b725ae77Skettenis   set_gdbarch_push_dummy_call (gdbarch, sparc32_push_dummy_call);
1177b725ae77Skettenis 
1178b725ae77Skettenis   set_gdbarch_return_value (gdbarch, sparc32_return_value);
1179b725ae77Skettenis   set_gdbarch_stabs_argument_has_addr
1180b725ae77Skettenis     (gdbarch, sparc32_stabs_argument_has_addr);
1181b725ae77Skettenis 
1182b725ae77Skettenis   set_gdbarch_skip_prologue (gdbarch, sparc32_skip_prologue);
1183b725ae77Skettenis 
1184b725ae77Skettenis   /* Stack grows downward.  */
1185b725ae77Skettenis   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1186b725ae77Skettenis 
1187b725ae77Skettenis   set_gdbarch_breakpoint_from_pc (gdbarch, sparc_breakpoint_from_pc);
1188b725ae77Skettenis 
1189b725ae77Skettenis   set_gdbarch_frame_args_skip (gdbarch, 8);
1190b725ae77Skettenis 
1191b725ae77Skettenis   set_gdbarch_print_insn (gdbarch, print_insn_sparc);
1192b725ae77Skettenis 
1193b725ae77Skettenis   set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
1194b725ae77Skettenis   set_gdbarch_write_pc (gdbarch, sparc_write_pc);
1195b725ae77Skettenis 
1196b725ae77Skettenis   set_gdbarch_unwind_dummy_id (gdbarch, sparc_unwind_dummy_id);
1197b725ae77Skettenis 
1198b725ae77Skettenis   set_gdbarch_unwind_pc (gdbarch, sparc_unwind_pc);
1199b725ae77Skettenis 
1200b725ae77Skettenis   frame_base_set_default (gdbarch, &sparc32_frame_base);
1201b725ae77Skettenis 
1202b725ae77Skettenis   /* Hook in ABI-specific overrides, if they have been registered.  */
1203b725ae77Skettenis   gdbarch_init_osabi (info, gdbarch);
1204b725ae77Skettenis 
1205b725ae77Skettenis   frame_unwind_append_sniffer (gdbarch, sparc32_frame_sniffer);
1206b725ae77Skettenis 
1207b725ae77Skettenis   /* If we have register sets, enable the generic core file support.  */
1208b725ae77Skettenis   if (tdep->gregset)
1209b725ae77Skettenis     set_gdbarch_regset_from_core_section (gdbarch,
1210b725ae77Skettenis 					  sparc_regset_from_core_section);
1211b725ae77Skettenis 
1212b725ae77Skettenis   return gdbarch;
1213b725ae77Skettenis }
1214b725ae77Skettenis 
1215b725ae77Skettenis /* Helper functions for dealing with register windows.  */
1216b725ae77Skettenis 
1217b725ae77Skettenis void
sparc_supply_rwindow(struct regcache * regcache,CORE_ADDR sp,int regnum)1218b725ae77Skettenis sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum)
1219b725ae77Skettenis {
1220b725ae77Skettenis   int offset = 0;
1221b725ae77Skettenis   char buf[8];
1222b725ae77Skettenis   int i;
1223b725ae77Skettenis 
1224b725ae77Skettenis   if (sp & 1)
1225b725ae77Skettenis     {
1226b725ae77Skettenis       /* Registers are 64-bit.  */
1227b725ae77Skettenis       sp += BIAS;
1228b725ae77Skettenis 
1229b725ae77Skettenis       for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1230b725ae77Skettenis 	{
1231b725ae77Skettenis 	  if (regnum == i || regnum == -1)
1232b725ae77Skettenis 	    {
1233b725ae77Skettenis 	      target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
123462d8eb49Skettenis 
123562d8eb49Skettenis 	      /* Handle StackGhost.  */
123662d8eb49Skettenis 	      if (i == SPARC_I7_REGNUM)
123762d8eb49Skettenis 		{
123862d8eb49Skettenis 		  ULONGEST wcookie = sparc_fetch_wcookie ();
123962d8eb49Skettenis 		  ULONGEST i7 = extract_unsigned_integer (buf + offset, 8);
124062d8eb49Skettenis 
124162d8eb49Skettenis 		  store_unsigned_integer (buf + offset, 8, i7 ^ wcookie);
124262d8eb49Skettenis 		}
124362d8eb49Skettenis 
1244b725ae77Skettenis 	      regcache_raw_supply (regcache, i, buf);
1245b725ae77Skettenis 	    }
1246b725ae77Skettenis 	}
1247b725ae77Skettenis     }
1248b725ae77Skettenis   else
1249b725ae77Skettenis     {
1250b725ae77Skettenis       /* Registers are 32-bit.  Toss any sign-extension of the stack
1251b725ae77Skettenis 	 pointer.  */
1252b725ae77Skettenis       sp &= 0xffffffffUL;
1253b725ae77Skettenis 
1254b725ae77Skettenis       /* Clear out the top half of the temporary buffer, and put the
1255b725ae77Skettenis 	 register value in the bottom half if we're in 64-bit mode.  */
1256b725ae77Skettenis       if (gdbarch_ptr_bit (current_gdbarch) == 64)
1257b725ae77Skettenis 	{
1258b725ae77Skettenis 	  memset (buf, 0, 4);
1259b725ae77Skettenis 	  offset = 4;
1260b725ae77Skettenis 	}
1261b725ae77Skettenis 
1262b725ae77Skettenis       for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1263b725ae77Skettenis 	{
1264b725ae77Skettenis 	  if (regnum == i || regnum == -1)
1265b725ae77Skettenis 	    {
1266b725ae77Skettenis 	      target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 4),
1267b725ae77Skettenis 				  buf + offset, 4);
1268b725ae77Skettenis 
1269b725ae77Skettenis 	      /* Handle StackGhost.  */
1270b725ae77Skettenis 	      if (i == SPARC_I7_REGNUM)
1271b725ae77Skettenis 		{
1272b725ae77Skettenis 		  ULONGEST wcookie = sparc_fetch_wcookie ();
1273b725ae77Skettenis 		  ULONGEST i7 = extract_unsigned_integer (buf + offset, 4);
1274b725ae77Skettenis 
1275b725ae77Skettenis 		  store_unsigned_integer (buf + offset, 4, i7 ^ wcookie);
1276b725ae77Skettenis 		}
1277b725ae77Skettenis 
1278b725ae77Skettenis 	      regcache_raw_supply (regcache, i, buf);
1279b725ae77Skettenis 	    }
1280b725ae77Skettenis 	}
1281b725ae77Skettenis     }
1282b725ae77Skettenis }
1283b725ae77Skettenis 
1284b725ae77Skettenis void
sparc_collect_rwindow(const struct regcache * regcache,CORE_ADDR sp,int regnum)1285b725ae77Skettenis sparc_collect_rwindow (const struct regcache *regcache,
1286b725ae77Skettenis 		       CORE_ADDR sp, int regnum)
1287b725ae77Skettenis {
1288b725ae77Skettenis   int offset = 0;
1289b725ae77Skettenis   char buf[8];
1290b725ae77Skettenis   int i;
1291b725ae77Skettenis 
1292b725ae77Skettenis   if (sp & 1)
1293b725ae77Skettenis     {
1294b725ae77Skettenis       /* Registers are 64-bit.  */
1295b725ae77Skettenis       sp += BIAS;
1296b725ae77Skettenis 
1297b725ae77Skettenis       for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1298b725ae77Skettenis 	{
1299b725ae77Skettenis 	  if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
1300b725ae77Skettenis 	    {
1301b725ae77Skettenis 	      regcache_raw_collect (regcache, i, buf);
130262d8eb49Skettenis 
130362d8eb49Skettenis 	      /* Handle StackGhost.  */
130462d8eb49Skettenis 	      if (i == SPARC_I7_REGNUM)
130562d8eb49Skettenis 		{
130662d8eb49Skettenis 		  ULONGEST wcookie = sparc_fetch_wcookie ();
130762d8eb49Skettenis 		  ULONGEST i7 = extract_unsigned_integer (buf + offset, 8);
130862d8eb49Skettenis 
130962d8eb49Skettenis 		  store_unsigned_integer (buf, 8, i7 ^ wcookie);
131062d8eb49Skettenis 		}
131162d8eb49Skettenis 
1312b725ae77Skettenis 	      target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 8), buf, 8);
1313b725ae77Skettenis 	    }
1314b725ae77Skettenis 	}
1315b725ae77Skettenis     }
1316b725ae77Skettenis   else
1317b725ae77Skettenis     {
1318b725ae77Skettenis       /* Registers are 32-bit.  Toss any sign-extension of the stack
1319b725ae77Skettenis 	 pointer.  */
1320b725ae77Skettenis       sp &= 0xffffffffUL;
1321b725ae77Skettenis 
1322b725ae77Skettenis       /* Only use the bottom half if we're in 64-bit mode.  */
1323b725ae77Skettenis       if (gdbarch_ptr_bit (current_gdbarch) == 64)
1324b725ae77Skettenis 	offset = 4;
1325b725ae77Skettenis 
1326b725ae77Skettenis       for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1327b725ae77Skettenis 	{
1328b725ae77Skettenis 	  if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i)
1329b725ae77Skettenis 	    {
1330b725ae77Skettenis 	      regcache_raw_collect (regcache, i, buf);
1331b725ae77Skettenis 
1332b725ae77Skettenis 	      /* Handle StackGhost.  */
1333b725ae77Skettenis 	      if (i == SPARC_I7_REGNUM)
1334b725ae77Skettenis 		{
1335b725ae77Skettenis 		  ULONGEST wcookie = sparc_fetch_wcookie ();
1336b725ae77Skettenis 		  ULONGEST i7 = extract_unsigned_integer (buf + offset, 4);
1337b725ae77Skettenis 
1338b725ae77Skettenis 		  store_unsigned_integer (buf + offset, 4, i7 ^ wcookie);
1339b725ae77Skettenis 		}
1340b725ae77Skettenis 
1341b725ae77Skettenis 	      target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 4),
1342b725ae77Skettenis 				   buf + offset, 4);
1343b725ae77Skettenis 	    }
1344b725ae77Skettenis 	}
1345b725ae77Skettenis     }
1346b725ae77Skettenis }
1347b725ae77Skettenis 
1348b725ae77Skettenis /* Helper functions for dealing with register sets.  */
1349b725ae77Skettenis 
1350b725ae77Skettenis void
sparc32_supply_gregset(const struct sparc_gregset * gregset,struct regcache * regcache,int regnum,const void * gregs)1351b725ae77Skettenis sparc32_supply_gregset (const struct sparc_gregset *gregset,
1352b725ae77Skettenis 			struct regcache *regcache,
1353b725ae77Skettenis 			int regnum, const void *gregs)
1354b725ae77Skettenis {
1355b725ae77Skettenis   const char *regs = gregs;
1356b725ae77Skettenis   int i;
1357b725ae77Skettenis 
1358b725ae77Skettenis   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
1359b725ae77Skettenis     regcache_raw_supply (regcache, SPARC32_PSR_REGNUM,
1360b725ae77Skettenis 			 regs + gregset->r_psr_offset);
1361b725ae77Skettenis 
1362b725ae77Skettenis   if (regnum == SPARC32_PC_REGNUM || regnum == -1)
1363b725ae77Skettenis     regcache_raw_supply (regcache, SPARC32_PC_REGNUM,
1364b725ae77Skettenis 			 regs + gregset->r_pc_offset);
1365b725ae77Skettenis 
1366b725ae77Skettenis   if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
1367b725ae77Skettenis     regcache_raw_supply (regcache, SPARC32_NPC_REGNUM,
1368b725ae77Skettenis 			 regs + gregset->r_npc_offset);
1369b725ae77Skettenis 
1370b725ae77Skettenis   if (regnum == SPARC32_Y_REGNUM || regnum == -1)
1371b725ae77Skettenis     regcache_raw_supply (regcache, SPARC32_Y_REGNUM,
1372b725ae77Skettenis 			 regs + gregset->r_y_offset);
1373b725ae77Skettenis 
1374b725ae77Skettenis   if (regnum == SPARC_G0_REGNUM || regnum == -1)
1375b725ae77Skettenis     regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL);
1376b725ae77Skettenis 
1377b725ae77Skettenis   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
1378b725ae77Skettenis     {
1379b725ae77Skettenis       int offset = gregset->r_g1_offset;
1380b725ae77Skettenis 
1381b725ae77Skettenis       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
1382b725ae77Skettenis 	{
1383b725ae77Skettenis 	  if (regnum == i || regnum == -1)
1384b725ae77Skettenis 	    regcache_raw_supply (regcache, i, regs + offset);
1385b725ae77Skettenis 	  offset += 4;
1386b725ae77Skettenis 	}
1387b725ae77Skettenis     }
1388b725ae77Skettenis 
1389b725ae77Skettenis   if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
1390b725ae77Skettenis     {
1391b725ae77Skettenis       /* Not all of the register set variants include Locals and
1392b725ae77Skettenis          Inputs.  For those that don't, we read them off the stack.  */
1393b725ae77Skettenis       if (gregset->r_l0_offset == -1)
1394b725ae77Skettenis 	{
1395b725ae77Skettenis 	  ULONGEST sp;
1396b725ae77Skettenis 
1397b725ae77Skettenis 	  regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
1398b725ae77Skettenis 	  sparc_supply_rwindow (regcache, sp, regnum);
1399b725ae77Skettenis 	}
1400b725ae77Skettenis       else
1401b725ae77Skettenis 	{
1402b725ae77Skettenis 	  int offset = gregset->r_l0_offset;
1403b725ae77Skettenis 
1404b725ae77Skettenis 	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1405b725ae77Skettenis 	    {
1406b725ae77Skettenis 	      if (regnum == i || regnum == -1)
1407b725ae77Skettenis 		regcache_raw_supply (regcache, i, regs + offset);
1408b725ae77Skettenis 	      offset += 4;
1409b725ae77Skettenis 	    }
1410b725ae77Skettenis 	}
1411b725ae77Skettenis     }
1412b725ae77Skettenis }
1413b725ae77Skettenis 
1414b725ae77Skettenis void
sparc32_collect_gregset(const struct sparc_gregset * gregset,const struct regcache * regcache,int regnum,void * gregs)1415b725ae77Skettenis sparc32_collect_gregset (const struct sparc_gregset *gregset,
1416b725ae77Skettenis 			 const struct regcache *regcache,
1417b725ae77Skettenis 			 int regnum, void *gregs)
1418b725ae77Skettenis {
1419b725ae77Skettenis   char *regs = gregs;
1420b725ae77Skettenis   int i;
1421b725ae77Skettenis 
1422b725ae77Skettenis   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
1423b725ae77Skettenis     regcache_raw_collect (regcache, SPARC32_PSR_REGNUM,
1424b725ae77Skettenis 			  regs + gregset->r_psr_offset);
1425b725ae77Skettenis 
1426b725ae77Skettenis   if (regnum == SPARC32_PC_REGNUM || regnum == -1)
1427b725ae77Skettenis     regcache_raw_collect (regcache, SPARC32_PC_REGNUM,
1428b725ae77Skettenis 			  regs + gregset->r_pc_offset);
1429b725ae77Skettenis 
1430b725ae77Skettenis   if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
1431b725ae77Skettenis     regcache_raw_collect (regcache, SPARC32_NPC_REGNUM,
1432b725ae77Skettenis 			  regs + gregset->r_npc_offset);
1433b725ae77Skettenis 
1434b725ae77Skettenis   if (regnum == SPARC32_Y_REGNUM || regnum == -1)
1435b725ae77Skettenis     regcache_raw_collect (regcache, SPARC32_Y_REGNUM,
1436b725ae77Skettenis 			  regs + gregset->r_y_offset);
1437b725ae77Skettenis 
1438b725ae77Skettenis   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
1439b725ae77Skettenis     {
1440b725ae77Skettenis       int offset = gregset->r_g1_offset;
1441b725ae77Skettenis 
1442b725ae77Skettenis       /* %g0 is always zero.  */
1443b725ae77Skettenis       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
1444b725ae77Skettenis 	{
1445b725ae77Skettenis 	  if (regnum == i || regnum == -1)
1446b725ae77Skettenis 	    regcache_raw_collect (regcache, i, regs + offset);
1447b725ae77Skettenis 	  offset += 4;
1448b725ae77Skettenis 	}
1449b725ae77Skettenis     }
1450b725ae77Skettenis 
1451b725ae77Skettenis   if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1)
1452b725ae77Skettenis     {
1453b725ae77Skettenis       /* Not all of the register set variants include Locals and
1454b725ae77Skettenis          Inputs.  For those that don't, we read them off the stack.  */
1455b725ae77Skettenis       if (gregset->r_l0_offset != -1)
1456b725ae77Skettenis 	{
1457b725ae77Skettenis 	  int offset = gregset->r_l0_offset;
1458b725ae77Skettenis 
1459b725ae77Skettenis 	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
1460b725ae77Skettenis 	    {
1461b725ae77Skettenis 	      if (regnum == i || regnum == -1)
1462b725ae77Skettenis 		regcache_raw_collect (regcache, i, regs + offset);
1463b725ae77Skettenis 	      offset += 4;
1464b725ae77Skettenis 	    }
1465b725ae77Skettenis 	}
1466b725ae77Skettenis     }
1467b725ae77Skettenis }
1468b725ae77Skettenis 
1469b725ae77Skettenis void
sparc32_supply_fpregset(struct regcache * regcache,int regnum,const void * fpregs)1470b725ae77Skettenis sparc32_supply_fpregset (struct regcache *regcache,
1471b725ae77Skettenis 			 int regnum, const void *fpregs)
1472b725ae77Skettenis {
1473b725ae77Skettenis   const char *regs = fpregs;
1474b725ae77Skettenis   int i;
1475b725ae77Skettenis 
1476b725ae77Skettenis   for (i = 0; i < 32; i++)
1477b725ae77Skettenis     {
1478b725ae77Skettenis       if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
1479b725ae77Skettenis 	regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
1480b725ae77Skettenis     }
1481b725ae77Skettenis 
1482b725ae77Skettenis   if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
1483b725ae77Skettenis     regcache_raw_supply (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4);
1484b725ae77Skettenis }
1485b725ae77Skettenis 
1486b725ae77Skettenis void
sparc32_collect_fpregset(const struct regcache * regcache,int regnum,void * fpregs)1487b725ae77Skettenis sparc32_collect_fpregset (const struct regcache *regcache,
1488b725ae77Skettenis 			  int regnum, void *fpregs)
1489b725ae77Skettenis {
1490b725ae77Skettenis   char *regs = fpregs;
1491b725ae77Skettenis   int i;
1492b725ae77Skettenis 
1493b725ae77Skettenis   for (i = 0; i < 32; i++)
1494b725ae77Skettenis     {
1495b725ae77Skettenis       if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1)
1496b725ae77Skettenis 	regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4));
1497b725ae77Skettenis     }
1498b725ae77Skettenis 
1499b725ae77Skettenis   if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
1500b725ae77Skettenis     regcache_raw_collect (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4);
1501b725ae77Skettenis }
1502b725ae77Skettenis 
1503b725ae77Skettenis 
1504b725ae77Skettenis /* SunOS 4.  */
1505b725ae77Skettenis 
1506b725ae77Skettenis /* From <machine/reg.h>.  */
1507b725ae77Skettenis const struct sparc_gregset sparc32_sunos4_gregset =
1508b725ae77Skettenis {
1509b725ae77Skettenis   0 * 4,			/* %psr */
1510b725ae77Skettenis   1 * 4,			/* %pc */
1511b725ae77Skettenis   2 * 4,			/* %npc */
1512b725ae77Skettenis   3 * 4,			/* %y */
1513b725ae77Skettenis   -1,				/* %wim */
1514b725ae77Skettenis   -1,				/* %tbr */
1515b725ae77Skettenis   4 * 4,			/* %g1 */
1516b725ae77Skettenis   -1				/* %l0 */
1517b725ae77Skettenis };
1518b725ae77Skettenis 
1519b725ae77Skettenis 
1520b725ae77Skettenis /* Provide a prototype to silence -Wmissing-prototypes.  */
1521b725ae77Skettenis void _initialize_sparc_tdep (void);
1522b725ae77Skettenis 
1523b725ae77Skettenis void
_initialize_sparc_tdep(void)1524b725ae77Skettenis _initialize_sparc_tdep (void)
1525b725ae77Skettenis {
1526b725ae77Skettenis   register_gdbarch_init (bfd_arch_sparc, sparc32_gdbarch_init);
1527b725ae77Skettenis }
1528