alpha-mdebug-tdep.c revision 130803
118730Ssteve/* Target-dependent mdebug code for the ALPHA architecture.
294589Sobrien   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
350477Speter   Free Software Foundation, Inc.
41590Srgrimes
51590Srgrimes   This file is part of GDB.
6143657Sharti
7146056Sharti   This program is free software; you can redistribute it and/or modify
8146574Sharti   it under the terms of the GNU General Public License as published by
9146574Sharti   the Free Software Foundation; either version 2 of the License, or
101590Srgrimes   (at your option) any later version.
11139112Sru
1276801Ssobomax   This program is distributed in the hope that it will be useful,
13228157Sfjoe   but WITHOUT ANY WARRANTY; without even the implied warranty of
14228157Sfjoe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15228157Sfjoe   GNU General Public License for more details.
16134843Sjmg
17104475Sphk   You should have received a copy of the GNU General Public License
18104475Sphk   along with this program; if not, write to the Free Software
19146608Sharti   Foundation, Inc., 59 Temple Place - Suite 330,
20146608Sharti   Boston, MA 02111-1307, USA.  */
21146608Sharti
22146608Sharti#include "defs.h"
23146608Sharti#include "frame.h"
24146608Sharti#include "frame-unwind.h"
25146579Sharti#include "frame-base.h"
2697121Sru#include "symtab.h"
27145616Sharti#include "gdbcore.h"
28150598Sphk#include "block.h"
29145616Sharti#include "gdb_assert.h"
30145616Sharti
31145612Sharti#include "alpha-tdep.h"
32145612Sharti
33145612Sharti/* FIXME: Some of this code should perhaps be merged with mips.  */
34145616Sharti
35145616Sharti/* *INDENT-OFF* */
36145612Sharti/* Layout of a stack frame on the alpha:
37145612Sharti
38145612Sharti                |				|
39145612Sharti pdr members:	|  7th ... nth arg,		|
40145612Sharti                |  `pushed' by caller.		|
41145616Sharti                |				|
42145616Sharti----------------|-------------------------------|<--  old_sp == vfp
43145612Sharti   ^  ^  ^  ^	|				|
44145612Sharti   |  |  |  |	|				|
45145612Sharti   |  |localoff	|  Copies of 1st .. 6th		|
46145612Sharti   |  |  |  |	|  argument if necessary.	|
47145612Sharti   |  |  |  v	|				|
48145612Sharti   |  |  |  ---	|-------------------------------|<-- LOCALS_ADDRESS
49145616Sharti   |  |  |      |				|
50145612Sharti   |  |  |      |  Locals and temporaries.	|
51145612Sharti   |  |  |      |				|
52145612Sharti   |  |  |      |-------------------------------|
53145614Sharti   |  |  |      |				|
54145612Sharti   |-fregoffset	|  Saved float registers.	|
55145612Sharti   |  |  |      |  F9				|
56145612Sharti   |  |  |      |   .				|
57145612Sharti   |  |  |      |   .				|
58145612Sharti   |  |  |      |  F2				|
59145612Sharti   |  |  v      |				|
60145612Sharti   |  |  -------|-------------------------------|
61145683Sharti   |  |         |				|
62145612Sharti   |  |         |  Saved registers.		|
63145612Sharti   |  |         |  S6				|
64145612Sharti   |-regoffset	|   .				|
65145612Sharti   |  |         |   .				|
66145612Sharti   |  |         |  S0				|
67145612Sharti   |  |         |  pdr.pcreg			|
68145612Sharti   |  v         |				|
69145612Sharti   |  ----------|-------------------------------|
70145612Sharti   |            |				|
71145612Sharti frameoffset    |  Argument build area, gets	|
72145612Sharti   |            |  7th ... nth arg for any	|
73145612Sharti   |            |  called procedure.		|
74145612Sharti   v            |  				|
75145612Sharti   -------------|-------------------------------|<-- sp
76145612Sharti                |				|
77145612Sharti*/
78145612Sharti/* *INDENT-ON* */
79145616Sharti
80145616Sharti#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr)
81145616Sharti#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
82145616Sharti#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
83145616Sharti#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
84145616Sharti#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
85145616Sharti#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
86145616Sharti#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
87145616Sharti#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
88145616Sharti#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)
89145616Sharti
90145616Sharti/* Locate the mdebug PDR for the given PC.  Return null if one can't
91145616Sharti   be found; you'll have to fall back to other methods in that case.  */
92145616Sharti
93145616Shartistatic alpha_extra_func_info_t
94145616Shartifind_proc_desc (CORE_ADDR pc)
95145616Sharti{
96145683Sharti  struct block *b = block_for_pc (pc);
97145612Sharti  alpha_extra_func_info_t proc_desc = NULL;
9864739Sgreen  struct symbol *sym = NULL;
9964739Sgreen
10064739Sgreen  if (b)
10164739Sgreen    {
10264739Sgreen      CORE_ADDR startaddr;
10364739Sgreen      find_pc_partial_function (pc, NULL, &startaddr, NULL);
104146571Sharti
105146571Sharti      if (startaddr > BLOCK_START (b))
10664739Sgreen	/* This is the "pathological" case referred to in a comment in
10764739Sgreen	   print_frame_info.  It might be better to move this check into
10864739Sgreen	   symbol reading.  */
10964739Sgreen	sym = NULL;
1101590Srgrimes      else
111	sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL);
112    }
113
114  if (sym)
115    {
116      proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym);
117
118      /* If we never found a PDR for this function in symbol reading,
119	 then examine prologues to find the information.  */
120      if (proc_desc->pdr.framereg == -1)
121	proc_desc = NULL;
122    }
123
124  return proc_desc;
125}
126
127/* This returns the PC of the first inst after the prologue.  If we can't
128   find the prologue, then return 0.  */
129
130static CORE_ADDR
131alpha_mdebug_after_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
132{
133  if (proc_desc)
134    {
135      /* If function is frameless, then we need to do it the hard way.  I
136         strongly suspect that frameless always means prologueless... */
137      if (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
138	  && PROC_FRAME_OFFSET (proc_desc) == 0)
139	return 0;
140    }
141
142  return alpha_after_prologue (pc);
143}
144
145/* Return non-zero if we *might* be in a function prologue.  Return zero
146   if we are definitively *not* in a function prologue.  */
147
148static int
149alpha_mdebug_in_prologue (CORE_ADDR pc, alpha_extra_func_info_t proc_desc)
150{
151  CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc);
152  return (after_prologue_pc == 0 || pc < after_prologue_pc);
153}
154
155
156/* Frame unwinder that reads mdebug PDRs.  */
157
158struct alpha_mdebug_unwind_cache
159{
160  alpha_extra_func_info_t proc_desc;
161  CORE_ADDR vfp;
162  CORE_ADDR *saved_regs;
163};
164
165/* Extract all of the information about the frame from PROC_DESC
166   and store the resulting register save locations in the structure.  */
167
168static struct alpha_mdebug_unwind_cache *
169alpha_mdebug_frame_unwind_cache (struct frame_info *next_frame,
170				 void **this_prologue_cache)
171{
172  struct alpha_mdebug_unwind_cache *info;
173  alpha_extra_func_info_t proc_desc;
174  ULONGEST vfp;
175  CORE_ADDR pc, reg_position;
176  unsigned long mask;
177  int ireg, returnreg;
178
179  if (*this_prologue_cache)
180    return *this_prologue_cache;
181
182  info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache);
183  *this_prologue_cache = info;
184  pc = frame_pc_unwind (next_frame);
185
186  /* ??? We don't seem to be able to cache the lookup of the PDR
187     from alpha_mdebug_frame_p.  It'd be nice if we could change
188     the arguments to that function.  Oh well.  */
189  proc_desc = find_proc_desc (pc);
190  info->proc_desc = proc_desc;
191  gdb_assert (proc_desc != NULL);
192
193  info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS);
194
195  /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET.  */
196  frame_unwind_unsigned_register (next_frame, PROC_FRAME_REG (proc_desc), &vfp);
197  vfp += PROC_FRAME_OFFSET (info->proc_desc);
198  info->vfp = vfp;
199
200  /* Fill in the offsets for the registers which gen_mask says were saved.  */
201
202  reg_position = vfp + PROC_REG_OFFSET (proc_desc);
203  mask = PROC_REG_MASK (proc_desc);
204  returnreg = PROC_PC_REG (proc_desc);
205
206  /* Note that RA is always saved first, regardless of its actual
207     register number.  */
208  if (mask & (1 << returnreg))
209    {
210      /* Clear bit for RA so we don't save it again later. */
211      mask &= ~(1 << returnreg);
212
213      info->saved_regs[returnreg] = reg_position;
214      reg_position += 8;
215    }
216
217  for (ireg = 0; ireg <= 31; ++ireg)
218    if (mask & (1 << ireg))
219      {
220	info->saved_regs[ireg] = reg_position;
221	reg_position += 8;
222      }
223
224  reg_position = vfp + PROC_FREG_OFFSET (proc_desc);
225  mask = PROC_FREG_MASK (proc_desc);
226
227  for (ireg = 0; ireg <= 31; ++ireg)
228    if (mask & (1 << ireg))
229      {
230	info->saved_regs[ALPHA_FP0_REGNUM + ireg] = reg_position;
231	reg_position += 8;
232      }
233
234  return info;
235}
236
237/* Given a GDB frame, determine the address of the calling function's
238   frame.  This will be used to create a new GDB frame struct.  */
239
240static void
241alpha_mdebug_frame_this_id (struct frame_info *next_frame,
242			    void **this_prologue_cache,
243			    struct frame_id *this_id)
244{
245  struct alpha_mdebug_unwind_cache *info
246    = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache);
247
248  *this_id = frame_id_build (info->vfp, frame_func_unwind (next_frame));
249}
250
251/* Retrieve the value of REGNUM in FRAME.  Don't give up!  */
252
253static void
254alpha_mdebug_frame_prev_register (struct frame_info *next_frame,
255				  void **this_prologue_cache,
256				  int regnum, int *optimizedp,
257				  enum lval_type *lvalp, CORE_ADDR *addrp,
258				  int *realnump, void *bufferp)
259{
260  struct alpha_mdebug_unwind_cache *info
261    = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache);
262
263  /* The PC of the previous frame is stored in the link register of
264     the current frame.  Frob regnum so that we pull the value from
265     the correct place.  */
266  if (regnum == ALPHA_PC_REGNUM)
267    regnum = PROC_PC_REG (info->proc_desc);
268
269  /* For all registers known to be saved in the current frame,
270     do the obvious and pull the value out.  */
271  if (info->saved_regs[regnum])
272    {
273      *optimizedp = 0;
274      *lvalp = lval_memory;
275      *addrp = info->saved_regs[regnum];
276      *realnump = -1;
277      if (bufferp != NULL)
278	get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE);
279      return;
280    }
281
282  /* The stack pointer of the previous frame is computed by popping
283     the current stack frame.  */
284  if (regnum == ALPHA_SP_REGNUM)
285    {
286      *optimizedp = 0;
287      *lvalp = not_lval;
288      *addrp = 0;
289      *realnump = -1;
290      if (bufferp != NULL)
291	store_unsigned_integer (bufferp, ALPHA_REGISTER_SIZE, info->vfp);
292      return;
293    }
294
295  /* Otherwise assume the next frame has the same register value.  */
296  frame_register (next_frame, regnum, optimizedp, lvalp, addrp,
297  		  realnump, bufferp);
298}
299
300static const struct frame_unwind alpha_mdebug_frame_unwind = {
301  NORMAL_FRAME,
302  alpha_mdebug_frame_this_id,
303  alpha_mdebug_frame_prev_register
304};
305
306const struct frame_unwind *
307alpha_mdebug_frame_sniffer (struct frame_info *next_frame)
308{
309  CORE_ADDR pc = frame_pc_unwind (next_frame);
310  alpha_extra_func_info_t proc_desc;
311
312  /* If this PC does not map to a PDR, then clearly this isn't an
313     mdebug frame.  */
314  proc_desc = find_proc_desc (pc);
315  if (proc_desc == NULL)
316    return NULL;
317
318  /* If we're in the prologue, the PDR for this frame is not yet valid.
319     Say no here and we'll fall back on the heuristic unwinder.  */
320  if (alpha_mdebug_in_prologue (pc, proc_desc))
321    return NULL;
322
323  return &alpha_mdebug_frame_unwind;
324}
325
326static CORE_ADDR
327alpha_mdebug_frame_base_address (struct frame_info *next_frame,
328				 void **this_prologue_cache)
329{
330  struct alpha_mdebug_unwind_cache *info
331    = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache);
332
333  return info->vfp;
334}
335
336static CORE_ADDR
337alpha_mdebug_frame_locals_address (struct frame_info *next_frame,
338				   void **this_prologue_cache)
339{
340  struct alpha_mdebug_unwind_cache *info
341    = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache);
342
343  return info->vfp - PROC_LOCALOFF (info->proc_desc);
344}
345
346static CORE_ADDR
347alpha_mdebug_frame_args_address (struct frame_info *next_frame,
348				 void **this_prologue_cache)
349{
350  struct alpha_mdebug_unwind_cache *info
351    = alpha_mdebug_frame_unwind_cache (next_frame, this_prologue_cache);
352
353  return info->vfp - ALPHA_NUM_ARG_REGS * 8;
354}
355
356static const struct frame_base alpha_mdebug_frame_base = {
357  &alpha_mdebug_frame_unwind,
358  alpha_mdebug_frame_base_address,
359  alpha_mdebug_frame_locals_address,
360  alpha_mdebug_frame_args_address
361};
362
363static const struct frame_base *
364alpha_mdebug_frame_base_sniffer (struct frame_info *next_frame)
365{
366  CORE_ADDR pc = frame_pc_unwind (next_frame);
367  alpha_extra_func_info_t proc_desc;
368
369  /* If this PC does not map to a PDR, then clearly this isn't an
370     mdebug frame.  */
371  proc_desc = find_proc_desc (pc);
372  if (proc_desc == NULL)
373    return NULL;
374
375  return &alpha_mdebug_frame_base;
376}
377
378
379void
380alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
381{
382  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
383
384  frame_unwind_append_sniffer (gdbarch, alpha_mdebug_frame_sniffer);
385  frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer);
386}
387