objc-act.c (synth_module_prologue): Use TREE_NO_WARNING instead of DECL_IN_SYSTEM_HEADER.
[official-gcc.git] / gcc / ada / tb-alvxw.c
blob52d9e1643f6610214c0d968ebc081bb62ab901d2
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * T R A C E B A C K - A l p h a / V x W o r k s *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 2000-2006, AdaCore *
10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 2, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 51 Franklin Street, Fifth Floor, *
20 * Boston, MA 02110-1301, USA. *
21 * *
22 * As a special exception, if you link this file with other files to *
23 * produce an executable, this file does not by itself cause the resulting *
24 * executable to be covered by the GNU General Public License. This except- *
25 * ion does not however invalidate any other reasons why the executable *
26 * file might be covered by the GNU Public License. *
27 * *
28 * GNAT was originally developed by the GNAT team at New York University. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
30 * *
31 ****************************************************************************/
33 /* Alpha vxWorks requires a special, complex treatment that is extracted
34 from GDB. This file is #included within tracebak.c in the appropriate
35 case. */
37 #include <stddef.h>
38 #include <stdlib.h>
39 #include <limits.h>
40 #include <string.h>
42 extern void kerTaskEntry(void);
44 /* We still use a number of macros similar to the ones for the generic
45 __gnat_backtrace implementation. */
46 #define SKIP_FRAME 1
47 #define PC_ADJUST -4
49 #define STOP_FRAME \
50 (current == NULL \
51 || ((CORE_ADDR) &kerTaskEntry >= PROC_LOW_ADDR (current->proc_desc) \
52 && current->pc >= (CORE_ADDR) &kerTaskEntry))
54 /* Register numbers of various important registers.
55 Note that most of these values are "real" register numbers,
56 and correspond to the general registers of the machine,
57 and FP_REGNUM is a "phony" register number which is too large
58 to be an actual register number as far as the user is concerned
59 but serves to get the desired value when passed to read_register. */
61 #define T7_REGNUM 8 /* Return address register for OSF/1 __add* */
62 #define GCC_FP_REGNUM 15 /* Used by gcc as frame register */
63 #define T9_REGNUM 23 /* Return address register for OSF/1 __div* */
64 #define SP_REGNUM 30 /* Contains address of top of stack */
65 #define RA_REGNUM 26 /* Contains return address value */
66 #define FP0_REGNUM 32 /* Floating point register 0 */
67 #define PC_REGNUM 64 /* Contains program counter */
68 #define NUM_REGS 66
70 #define VM_MIN_ADDRESS (CORE_ADDR)0x120000000
72 #define SIZEOF_FRAME_SAVED_REGS (sizeof (CORE_ADDR) * (NUM_REGS))
73 #define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci)
75 #define FRAME_CHAIN(thisframe) (CORE_ADDR) alpha_frame_chain (thisframe)
77 #define FRAME_CHAIN_VALID(CHAIN, THISFRAME) \
78 ((CHAIN) != 0 \
79 && !inside_entry_file (FRAME_SAVED_PC (THISFRAME)))
81 #define FRAME_SAVED_PC(FRAME) (alpha_frame_saved_pc (FRAME))
83 #define FRAME_CHAIN_COMBINE(CHAIN, THISFRAME) (CHAIN)
85 #define INIT_FRAME_PC(FROMLEAF, PREV)
87 #define INIT_FRAME_PC_FIRST(FROMLEAF, PREV) \
88 (PREV)->pc = ((FROMLEAF) ? SAVED_PC_AFTER_CALL ((PREV)->next) \
89 : (PREV)->next ? FRAME_SAVED_PC ((PREV)->next) : read_pc ());
91 #define SAVED_PC_AFTER_CALL(FRAME) alpha_saved_pc_after_call (FRAME)
93 typedef unsigned long long int bfd_vma;
95 typedef bfd_vma CORE_ADDR;
97 typedef struct pdr
99 bfd_vma adr; /* memory address of start of procedure */
100 long isym; /* start of local symbol entries */
101 long iline; /* start of line number entries*/
102 long regmask; /* save register mask */
103 long regoffset; /* save register offset */
104 long iopt; /* start of optimization symbol entries*/
105 long fregmask; /* save floating point register mask */
106 long fregoffset; /* save floating point register offset */
107 long frameoffset; /* frame size */
108 short framereg; /* frame pointer register */
109 short pcreg; /* offset or reg of return pc */
110 long lnLow; /* lowest line in the procedure */
111 long lnHigh; /* highest line in the procedure */
112 bfd_vma cbLineOffset; /* byte offset for this procedure from the fd base */
113 /* These fields are new for 64 bit ECOFF. */
114 unsigned gp_prologue : 8; /* byte size of GP prologue */
115 unsigned gp_used : 1; /* true if the procedure uses GP */
116 unsigned reg_frame : 1; /* true if register frame procedure */
117 unsigned prof : 1; /* true if compiled with -pg */
118 unsigned reserved : 13; /* reserved: must be zero */
119 unsigned localoff : 8; /* offset of local variables from vfp */
120 } PDR;
122 typedef struct alpha_extra_func_info
124 long numargs; /* number of args to procedure (was iopt) */
125 PDR pdr; /* Procedure descriptor record */
127 *alpha_extra_func_info_t;
129 struct frame_info
131 /* Nominal address of the frame described. See comments at FRAME_FP
132 about what this means outside the *FRAME* macros; in the *FRAME*
133 macros, it can mean whatever makes most sense for this machine. */
134 CORE_ADDR frame;
136 /* Address at which execution is occurring in this frame. For the
137 innermost frame, it's the current pc. For other frames, it is a
138 pc saved in the next frame. */
139 CORE_ADDR pc;
141 /* For each register, address of where it was saved on entry to the
142 frame, or zero if it was not saved on entry to this frame. This
143 includes special registers such as pc and fp saved in special
144 ways in the stack frame. The SP_REGNUM is even more special, the
145 address here is the sp for the next frame, not the address where
146 the sp was saved. Allocated by frame_saved_regs_zalloc () which
147 is called and initialized by FRAME_INIT_SAVED_REGS. */
148 CORE_ADDR *saved_regs; /*NUM_REGS */
150 int localoff;
151 int pc_reg;
152 alpha_extra_func_info_t proc_desc;
154 /* Pointers to the next and previous frame_info's in the frame cache. */
155 struct frame_info *next, *prev;
158 struct frame_saved_regs
160 /* For each register R (except the SP), regs[R] is the address at
161 which it was saved on entry to the frame, or zero if it was not
162 saved on entry to this frame. This includes special registers
163 such as pc and fp saved in special ways in the stack frame.
165 regs[SP_REGNUM] is different. It holds the actual SP, not the
166 address at which it was saved. */
168 CORE_ADDR regs[NUM_REGS];
171 static CORE_ADDR theRegisters[32];
173 /* Prototypes for local functions. */
175 static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
176 static CORE_ADDR heuristic_proc_start (CORE_ADDR);
177 static int alpha_about_to_return (CORE_ADDR pc);
178 static void init_extra_frame_info (struct frame_info *);
179 static CORE_ADDR alpha_frame_chain (struct frame_info *);
180 static CORE_ADDR alpha_frame_saved_pc (struct frame_info *frame);
181 static void *trace_alloc (unsigned int);
182 static struct frame_info *create_new_frame (CORE_ADDR, CORE_ADDR);
184 static alpha_extra_func_info_t
185 heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *,
186 struct frame_saved_regs *);
188 static alpha_extra_func_info_t
189 find_proc_desc (CORE_ADDR, struct frame_info *, struct frame_saved_regs *);
191 /* Heuristic_proc_start may hunt through the text section for a long
192 time across a 2400 baud serial line. Allows the user to limit this
193 search. */
194 static unsigned int heuristic_fence_post = 1<<16;
196 /* Layout of a stack frame on the alpha:
199 pdr members: | 7th ... nth arg, |
200 | `pushed' by caller. |
202 ----------------|-------------------------------|<-- old_sp == vfp
203 ^ ^ ^ ^ | |
204 | | | | | |
205 | |localoff | Copies of 1st .. 6th |
206 | | | | | argument if necessary. |
207 | | | v | |
208 | | | --- |-------------------------------|<-- FRAME_LOCALS_ADDRESS
209 | | | | |
210 | | | | Locals and temporaries. |
211 | | | | |
212 | | | |-------------------------------|
213 | | | | |
214 |-fregoffset | Saved float registers. |
215 | | | | F9 |
216 | | | | . |
217 | | | | . |
218 | | | | F2 |
219 | | v | |
220 | | -------|-------------------------------|
221 | | | |
222 | | | Saved registers. |
223 | | | S6 |
224 |-regoffset | . |
225 | | | . |
226 | | | S0 |
227 | | | pdr.pcreg |
228 | v | |
229 | ----------|-------------------------------|
230 | | |
231 frameoffset | Argument build area, gets |
232 | | 7th ... nth arg for any |
233 | | called procedure. |
234 v | |
235 -------------|-------------------------------|<-- sp
236 | | */
238 #define PROC_LOW_ADDR(PROC) ((PROC)->pdr.adr) /* least address */
239 #define PROC_HIGH_ADDR(PROC) ((PROC)->pdr.iline) /* upper address bound */
240 #define PROC_DUMMY_FRAME(PROC) ((PROC)->pdr.cbLineOffset) /*CALL_DUMMY frame */
241 #define PROC_FRAME_OFFSET(PROC) ((PROC)->pdr.frameoffset)
242 #define PROC_FRAME_REG(PROC) ((PROC)->pdr.framereg)
243 #define PROC_REG_MASK(PROC) ((PROC)->pdr.regmask)
244 #define PROC_FREG_MASK(PROC) ((PROC)->pdr.fregmask)
245 #define PROC_REG_OFFSET(PROC) ((PROC)->pdr.regoffset)
246 #define PROC_FREG_OFFSET(PROC) ((PROC)->pdr.fregoffset)
247 #define PROC_PC_REG(PROC) ((PROC)->pdr.pcreg)
248 #define PROC_LOCALOFF(PROC) ((PROC)->pdr.localoff)
250 /* Local storage allocation/deallocation functions. trace_alloc does
251 a malloc, but also chains allocated blocks on trace_alloc_chain, so
252 they may all be freed on exit from __gnat_backtrace. */
254 struct alloc_chain
256 struct alloc_chain *next;
257 double x[0];
259 struct alloc_chain *trace_alloc_chain;
261 static void *
262 trace_alloc (unsigned int n)
264 struct alloc_chain * result = malloc (n + sizeof(struct alloc_chain));
266 result->next = trace_alloc_chain;
267 trace_alloc_chain = result;
268 return (void*) result->x;
271 static void
272 free_trace_alloc (void)
274 while (trace_alloc_chain != 0)
276 struct alloc_chain *old = trace_alloc_chain;
278 trace_alloc_chain = trace_alloc_chain->next;
279 free (old);
283 /* Read value at ADDR into *DEST, returning 0 if this is valid, != 0
284 otherwise. */
286 static int
287 read_memory_safe4 (CORE_ADDR addr, unsigned int *dest)
289 *dest = *((unsigned int*) addr);
290 return 0;
293 /* Read value at ADDR into *DEST, returning 0 if this is valid, != 0
294 otherwise. */
296 static int
297 read_memory_safe8 (CORE_ADDR addr, CORE_ADDR *dest)
299 *dest = *((CORE_ADDR*) addr);
300 return 0;
303 static CORE_ADDR
304 read_register (int regno)
306 if (regno >= 0 && regno < 31)
307 return theRegisters[regno];
309 return (CORE_ADDR) 0;
312 static void
313 frame_saved_regs_zalloc (struct frame_info *fi)
315 fi->saved_regs = (CORE_ADDR *) trace_alloc (SIZEOF_FRAME_SAVED_REGS);
316 memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
319 static void *
320 frame_obstack_alloc (unsigned long size)
322 return (void *) trace_alloc (size);
325 static int
326 inside_entry_file (CORE_ADDR addr)
328 if (addr == 0)
329 return 1;
330 else
331 return 0;
334 static CORE_ADDR
335 alpha_saved_pc_after_call (struct frame_info *frame)
337 CORE_ADDR pc = frame->pc;
338 alpha_extra_func_info_t proc_desc;
339 int pcreg;
341 proc_desc = find_proc_desc (pc, frame->next, NULL);
342 pcreg = proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM;
344 return read_register (pcreg);
347 /* Guaranteed to set frame->saved_regs to some values (it never leaves it
348 NULL). */
350 static void
351 alpha_find_saved_regs (struct frame_info *frame)
353 int ireg;
354 CORE_ADDR reg_position;
355 unsigned long mask;
356 alpha_extra_func_info_t proc_desc;
357 int returnreg;
359 frame_saved_regs_zalloc (frame);
361 /* If it is the frame for __sigtramp, the saved registers are located in a
362 sigcontext structure somewhere on the stack. __sigtramp passes a pointer
363 to the sigcontext structure on the stack. If the stack layout for
364 __sigtramp changes, or if sigcontext offsets change, we might have to
365 update this code. */
367 #ifndef SIGFRAME_PC_OFF
368 #define SIGFRAME_PC_OFF (2 * 8)
369 #define SIGFRAME_REGSAVE_OFF (4 * 8)
370 #define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
371 #endif
373 proc_desc = frame->proc_desc;
374 if (proc_desc == NULL)
375 /* I'm not sure how/whether this can happen. Normally when we can't
376 find a proc_desc, we "synthesize" one using heuristic_proc_desc
377 and set the saved_regs right away. */
378 return;
380 /* Fill in the offsets for the registers which gen_mask says
381 were saved. */
383 reg_position = frame->frame + PROC_REG_OFFSET (proc_desc);
384 mask = PROC_REG_MASK (proc_desc);
386 returnreg = PROC_PC_REG (proc_desc);
388 /* Note that RA is always saved first, regardless of its actual
389 register number. */
390 if (mask & (1 << returnreg))
392 frame->saved_regs[returnreg] = reg_position;
393 reg_position += 8;
394 mask &= ~(1 << returnreg); /* Clear bit for RA so we
395 don't save again later. */
398 for (ireg = 0; ireg <= 31; ireg++)
399 if (mask & (1 << ireg))
401 frame->saved_regs[ireg] = reg_position;
402 reg_position += 8;
405 /* Fill in the offsets for the registers which float_mask says
406 were saved. */
408 reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc);
409 mask = PROC_FREG_MASK (proc_desc);
411 for (ireg = 0; ireg <= 31; ireg++)
412 if (mask & (1 << ireg))
414 frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
415 reg_position += 8;
418 frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg];
421 static CORE_ADDR
422 read_next_frame_reg (struct frame_info *fi, int regno)
424 CORE_ADDR result;
425 for (; fi; fi = fi->next)
427 /* We have to get the saved sp from the sigcontext
428 if it is a signal handler frame. */
429 if (regno == SP_REGNUM)
430 return fi->frame;
431 else
433 if (fi->saved_regs == 0)
434 alpha_find_saved_regs (fi);
436 if (fi->saved_regs[regno])
438 if (read_memory_safe8 (fi->saved_regs[regno], &result) == 0)
439 return result;
440 else
441 return 0;
446 return read_register (regno);
449 static CORE_ADDR
450 alpha_frame_saved_pc (struct frame_info *frame)
452 return read_next_frame_reg (frame, frame->pc_reg);
455 static struct alpha_extra_func_info temp_proc_desc;
457 /* Nonzero if instruction at PC is a return instruction. "ret
458 $zero,($ra),1" on alpha. */
460 static int
461 alpha_about_to_return (CORE_ADDR pc)
463 int inst;
465 read_memory_safe4 (pc, &inst);
466 return inst == 0x6bfa8001;
469 /* A heuristically computed start address for the subprogram
470 containing address PC. Returns 0 if none detected. */
472 static CORE_ADDR
473 heuristic_proc_start (CORE_ADDR pc)
475 CORE_ADDR start_pc = pc;
476 CORE_ADDR fence = start_pc - heuristic_fence_post;
478 if (start_pc == 0)
479 return 0;
481 if (heuristic_fence_post == UINT_MAX
482 || fence < VM_MIN_ADDRESS)
483 fence = VM_MIN_ADDRESS;
485 /* search back for previous return */
486 for (start_pc -= 4; ; start_pc -= 4)
488 if (start_pc < fence)
489 return 0;
490 else if (alpha_about_to_return (start_pc))
491 break;
494 start_pc += 4; /* skip return */
495 return start_pc;
498 static alpha_extra_func_info_t
499 heuristic_proc_desc (CORE_ADDR start_pc,
500 CORE_ADDR limit_pc,
501 struct frame_info *next_frame,
502 struct frame_saved_regs *saved_regs_p)
504 CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
505 CORE_ADDR cur_pc;
506 int frame_size;
507 int has_frame_reg = 0;
508 unsigned long reg_mask = 0;
509 int pcreg = -1;
511 if (start_pc == 0)
512 return 0;
514 memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
515 if (saved_regs_p != 0)
516 memset (saved_regs_p, '\0', sizeof (struct frame_saved_regs));
518 PROC_LOW_ADDR (&temp_proc_desc) = start_pc;
520 if (start_pc + 200 < limit_pc)
521 limit_pc = start_pc + 200;
523 frame_size = 0;
524 for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4)
526 unsigned int word;
527 int status;
529 status = read_memory_safe4 (cur_pc, &word);
530 if (status)
531 return 0;
533 if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
535 if (word & 0x8000)
536 frame_size += (-word) & 0xffff;
537 else
538 /* Exit loop if a positive stack adjustment is found, which
539 usually means that the stack cleanup code in the function
540 epilogue is reached. */
541 break;
543 else if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
544 && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
546 int reg = (word & 0x03e00000) >> 21;
548 reg_mask |= 1 << reg;
549 if (saved_regs_p != 0)
550 saved_regs_p->regs[reg] = sp + (short) word;
552 /* Starting with OSF/1-3.2C, the system libraries are shipped
553 without local symbols, but they still contain procedure
554 descriptors without a symbol reference. GDB is currently
555 unable to find these procedure descriptors and uses
556 heuristic_proc_desc instead.
557 As some low level compiler support routines (__div*, __add*)
558 use a non-standard return address register, we have to
559 add some heuristics to determine the return address register,
560 or stepping over these routines will fail.
561 Usually the return address register is the first register
562 saved on the stack, but assembler optimization might
563 rearrange the register saves.
564 So we recognize only a few registers (t7, t9, ra) within
565 the procedure prologue as valid return address registers.
566 If we encounter a return instruction, we extract the
567 the return address register from it.
569 FIXME: Rewriting GDB to access the procedure descriptors,
570 e.g. via the minimal symbol table, might obviate this hack. */
571 if (pcreg == -1
572 && cur_pc < (start_pc + 80)
573 && (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM))
574 pcreg = reg;
576 else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
577 pcreg = (word >> 16) & 0x1f;
578 else if (word == 0x47de040f) /* bis sp,sp fp */
579 has_frame_reg = 1;
582 if (pcreg == -1)
584 /* If we haven't found a valid return address register yet,
585 keep searching in the procedure prologue. */
586 while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
588 unsigned int word;
590 if (read_memory_safe4 (cur_pc, &word))
591 break;
592 cur_pc += 4;
594 if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
595 && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
597 int reg = (word & 0x03e00000) >> 21;
599 if (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM)
601 pcreg = reg;
602 break;
605 else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
607 pcreg = (word >> 16) & 0x1f;
608 break;
613 if (has_frame_reg)
614 PROC_FRAME_REG (&temp_proc_desc) = GCC_FP_REGNUM;
615 else
616 PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
618 PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
619 PROC_REG_MASK (&temp_proc_desc) = reg_mask;
620 PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? RA_REGNUM : pcreg;
621 PROC_LOCALOFF (&temp_proc_desc) = 0; /* XXX - bogus */
623 return &temp_proc_desc;
626 static alpha_extra_func_info_t
627 find_proc_desc (CORE_ADDR pc,
628 struct frame_info *next_frame,
629 struct frame_saved_regs *saved_regs)
631 CORE_ADDR startaddr;
633 /* If heuristic_fence_post is nonzero, determine the procedure
634 start address by examining the instructions.
635 This allows us to find the start address of static functions which
636 have no symbolic information, as startaddr would have been set to
637 the preceding global function start address by the
638 find_pc_partial_function call above. */
639 startaddr = heuristic_proc_start (pc);
641 return heuristic_proc_desc (startaddr, pc, next_frame, saved_regs);
644 static CORE_ADDR
645 alpha_frame_chain (struct frame_info *frame)
647 alpha_extra_func_info_t proc_desc;
648 CORE_ADDR saved_pc = FRAME_SAVED_PC (frame);
650 if (saved_pc == 0 || inside_entry_file (saved_pc))
651 return 0;
653 proc_desc = find_proc_desc (saved_pc, frame, NULL);
654 if (!proc_desc)
655 return 0;
657 /* If no frame pointer and frame size is zero, we must be at end
658 of stack (or otherwise hosed). If we don't check frame size,
659 we loop forever if we see a zero size frame. */
660 if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
661 && PROC_FRAME_OFFSET (proc_desc) == 0)
662 return 0;
663 else
664 return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
665 + PROC_FRAME_OFFSET (proc_desc);
668 static void
669 init_extra_frame_info (struct frame_info *frame)
671 struct frame_saved_regs temp_saved_regs;
672 alpha_extra_func_info_t proc_desc =
673 find_proc_desc (frame->pc, frame->next, &temp_saved_regs);
675 frame->saved_regs = NULL;
676 frame->localoff = 0;
677 frame->pc_reg = RA_REGNUM;
678 frame->proc_desc = proc_desc;
680 if (proc_desc)
682 /* Get the locals offset and the saved pc register from the
683 procedure descriptor, they are valid even if we are in the
684 middle of the prologue. */
685 frame->localoff = PROC_LOCALOFF (proc_desc);
686 frame->pc_reg = PROC_PC_REG (proc_desc);
688 /* Fixup frame-pointer - only needed for top frame */
690 /* This may not be quite right, if proc has a real frame register.
691 Get the value of the frame relative sp, procedure might have been
692 interrupted by a signal at it's very start. */
693 if (frame->pc == PROC_LOW_ADDR (proc_desc))
694 frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
695 else
696 frame->frame
697 = (read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc))
698 + PROC_FRAME_OFFSET (proc_desc));
700 frame->saved_regs
701 = (CORE_ADDR *) frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
702 memcpy
703 (frame->saved_regs, temp_saved_regs.regs, SIZEOF_FRAME_SAVED_REGS);
704 frame->saved_regs[PC_REGNUM] = frame->saved_regs[RA_REGNUM];
708 /* Create an arbitrary (i.e. address specified by user) or innermost frame.
709 Always returns a non-NULL value. */
711 static struct frame_info *
712 create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
714 struct frame_info *fi;
716 fi = (struct frame_info *)
717 trace_alloc (sizeof (struct frame_info));
719 /* Arbitrary frame */
720 fi->next = NULL;
721 fi->prev = NULL;
722 fi->frame = addr;
723 fi->pc = pc;
725 #ifdef INIT_EXTRA_FRAME_INFO
726 INIT_EXTRA_FRAME_INFO (0, fi);
727 #endif
729 return fi;
732 static CORE_ADDR current_pc;
734 static void
735 set_current_pc (void)
737 current_pc = (CORE_ADDR) __builtin_return_address (0);
740 static CORE_ADDR
741 read_pc (void)
743 return current_pc;
746 static struct frame_info *
747 get_current_frame (void)
749 return create_new_frame (0, read_pc ());
752 /* Return the frame that called FI.
753 If FI is the original frame (it has no caller), return 0. */
755 static struct frame_info *
756 get_prev_frame (struct frame_info *next_frame)
758 CORE_ADDR address = 0;
759 struct frame_info *prev;
760 int fromleaf = 0;
762 /* If we have the prev one, return it */
763 if (next_frame->prev)
764 return next_frame->prev;
766 /* On some machines it is possible to call a function without
767 setting up a stack frame for it. On these machines, we
768 define this macro to take two args; a frameinfo pointer
769 identifying a frame and a variable to set or clear if it is
770 or isn't leafless. */
772 /* Two macros defined in tm.h specify the machine-dependent
773 actions to be performed here.
775 First, get the frame's chain-pointer. If that is zero, the frame
776 is the outermost frame or a leaf called by the outermost frame.
777 This means that if start calls main without a frame, we'll return
778 0 (which is fine anyway).
780 Nope; there's a problem. This also returns when the current
781 routine is a leaf of main. This is unacceptable. We move
782 this to after the ffi test; I'd rather have backtraces from
783 start go curfluy than have an abort called from main not show
784 main. */
786 address = FRAME_CHAIN (next_frame);
787 if (!FRAME_CHAIN_VALID (address, next_frame))
788 return 0;
789 address = FRAME_CHAIN_COMBINE (address, next_frame);
791 if (address == 0)
792 return 0;
794 prev = (struct frame_info *) trace_alloc (sizeof (struct frame_info));
796 prev->saved_regs = NULL;
797 if (next_frame)
798 next_frame->prev = prev;
800 prev->next = next_frame;
801 prev->prev = (struct frame_info *) 0;
802 prev->frame = address;
804 /* This change should not be needed, FIXME! We should
805 determine whether any targets *need* INIT_FRAME_PC to happen
806 after INIT_EXTRA_FRAME_INFO and come up with a simple way to
807 express what goes on here.
809 INIT_EXTRA_FRAME_INFO is called from two places: create_new_frame
810 (where the PC is already set up) and here (where it isn't).
811 INIT_FRAME_PC is only called from here, always after
812 INIT_EXTRA_FRAME_INFO.
814 The catch is the MIPS, where INIT_EXTRA_FRAME_INFO requires the PC
815 value (which hasn't been set yet). Some other machines appear to
816 require INIT_EXTRA_FRAME_INFO before they can do INIT_FRAME_PC. Phoo.
818 We shouldn't need INIT_FRAME_PC_FIRST to add more complication to
819 an already overcomplicated part of GDB. gnu@cygnus.com, 15Sep92.
821 Assuming that some machines need INIT_FRAME_PC after
822 INIT_EXTRA_FRAME_INFO, one possible scheme:
824 SETUP_INNERMOST_FRAME()
825 Default version is just create_new_frame (read_fp ()),
826 read_pc ()). Machines with extra frame info would do that (or the
827 local equivalent) and then set the extra fields.
828 INIT_PREV_FRAME(fromleaf, prev)
829 Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC. This should
830 also return a flag saying whether to keep the new frame, or
831 whether to discard it, because on some machines (e.g. mips) it
832 is really awkward to have FRAME_CHAIN_VALID called *before*
833 INIT_EXTRA_FRAME_INFO (there is no good way to get information
834 deduced in FRAME_CHAIN_VALID into the extra fields of the new frame).
835 std_frame_pc(fromleaf, prev)
836 This is the default setting for INIT_PREV_FRAME. It just does what
837 the default INIT_FRAME_PC does. Some machines will call it from
838 INIT_PREV_FRAME (either at the beginning, the end, or in the middle).
839 Some machines won't use it.
840 kingdon@cygnus.com, 13Apr93, 31Jan94, 14Dec94. */
842 #ifdef INIT_FRAME_PC_FIRST
843 INIT_FRAME_PC_FIRST (fromleaf, prev);
844 #endif
846 #ifdef INIT_EXTRA_FRAME_INFO
847 INIT_EXTRA_FRAME_INFO (fromleaf, prev);
848 #endif
850 /* This entry is in the frame queue now, which is good since
851 FRAME_SAVED_PC may use that queue to figure out its value
852 (see tm-sparc.h). We want the pc saved in the inferior frame. */
853 INIT_FRAME_PC (fromleaf, prev);
855 /* If ->frame and ->pc are unchanged, we are in the process of getting
856 ourselves into an infinite backtrace. Some architectures check this
857 in FRAME_CHAIN or thereabouts, but it seems like there is no reason
858 this can't be an architecture-independent check. */
859 if (next_frame != NULL)
861 if (prev->frame == next_frame->frame
862 && prev->pc == next_frame->pc)
864 next_frame->prev = NULL;
865 free (prev);
866 return NULL;
870 return prev;
873 #define SAVE(regno,disp) \
874 "stq $" #regno ", " #disp "(%0)\n"
877 __gnat_backtrace (void **array,
878 int size,
879 void *exclude_min,
880 void *exclude_max,
881 int skip_frames)
883 struct frame_info* top;
884 struct frame_info* current;
885 int cnt;
887 /* This function is not thread safe, protect it */
888 (*Lock_Task) ();
889 asm volatile (
890 SAVE (9,72)
891 SAVE (10,80)
892 SAVE (11,88)
893 SAVE (12,96)
894 SAVE (13,104)
895 SAVE (14,112)
896 SAVE (15,120)
897 SAVE (16,128)
898 SAVE (17,136)
899 SAVE (18,144)
900 SAVE (19,152)
901 SAVE (20,160)
902 SAVE (21,168)
903 SAVE (22,176)
904 SAVE (23,184)
905 SAVE (24,192)
906 SAVE (25,200)
907 SAVE (26,208)
908 SAVE (27,216)
909 SAVE (28,224)
910 SAVE (29,232)
911 SAVE (30,240)
912 : : "r" (&theRegisters));
914 trace_alloc_chain = NULL;
915 set_current_pc ();
917 top = current = get_current_frame ();
918 cnt = 0;
920 for (cnt = 0; cnt < skip_frames; cnt += 1) {
921 current = get_prev_frame (current);
924 cnt = 0;
925 while (cnt < size)
927 if (STOP_FRAME)
928 break;
930 if (current->pc < (CORE_ADDR) exclude_min
931 || current->pc > (CORE_ADDR) exclude_max)
932 array[cnt++] = (void*) (current->pc + PC_ADJUST);
934 current = get_prev_frame (current);
937 free_trace_alloc ();
938 (*Unlock_Task) ();
940 return cnt;