OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [tracebak.c] - Blame information for rev 797

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
/****************************************************************************
2
 *                                                                          *
3
 *                         GNAT RUN-TIME COMPONENTS                         *
4
 *                                                                          *
5
 *                            T R A C E B A C K                             *
6
 *                                                                          *
7
 *                          C Implementation File                           *
8
 *                                                                          *
9
 *            Copyright (C) 2000-2011, Free Software Foundation, Inc.       *
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 3,  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.                                     *
17
 *                                                                          *
18
 * As a special exception under Section 7 of GPL version 3, you are granted *
19
 * additional permissions described in the GCC Runtime Library Exception,   *
20
 * version 3.1, as published by the Free Software Foundation.               *
21
 *                                                                          *
22
 * You should have received a copy of the GNU General Public License and    *
23
 * a copy of the GCC Runtime Library Exception along with this program;     *
24
 * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    *
25
 * <http://www.gnu.org/licenses/>.                                          *
26
 *                                                                          *
27
 * GNAT was originally developed  by the GNAT team at  New York University. *
28
 * Extensive contributions were provided by Ada Core Technologies Inc.      *
29
 *                                                                          *
30
 ****************************************************************************/
31
 
32
/* This file contains low level support for stack unwinding using GCC intrinsic
33
   functions.
34
   It has been tested on the following configurations:
35
   PowerPC/AiX
36
   PowerPC/Darwin
37
   PowerPC/VxWorks
38
   SPARC/Solaris
39
   i386/GNU/Linux
40
   i386/Solaris
41
   i386/NT
42
   i386/OS2
43
   i386/LynxOS
44
   Alpha/VxWorks
45
   Alpha/VMS
46
*/
47
 
48
#ifdef __cplusplus
49
extern "C" {
50
#endif
51
 
52
#ifdef __alpha_vxworks
53
#include "vxWorks.h"
54
#endif
55
 
56
#ifdef IN_RTS
57
#define POSIX
58
#include "tconfig.h"
59
#include "tsystem.h"
60
#else
61
#include "config.h"
62
#include "system.h"
63
/* We don't want fancy_abort here.  */
64
#undef abort
65
#endif
66
 
67
extern int __gnat_backtrace (void **, int, void *, void *, int);
68
 
69
/* The point is to provide an implementation of the __gnat_backtrace function
70
   above, called by the default implementation of the System.Traceback package.
71
 
72
   We first have a series of target specific implementations, each included
73
   from a separate C file for readability purposes.
74
 
75
   Then come two flavors of a generic implementation: one relying on static
76
   assumptions about the frame layout, and the other one using the GCC EH
77
   infrastructure.  The former uses a whole set of macros and structures which
78
   may be tailored on a per target basis, and is activated as soon as
79
   USE_GENERIC_UNWINDER is defined.  The latter uses a small subset of the
80
   macro definitions and is activated when USE_GCC_UNWINDER is defined. It is
81
   only available post GCC 3.3.
82
 
83
   Finally, there is a default dummy implementation, necessary to make the
84
   linker happy on platforms where the feature is not supported, but where the
85
   function is still referenced by the default System.Traceback.  */
86
 
87
#define Lock_Task system__soft_links__lock_task
88
extern void (*Lock_Task) (void);
89
 
90
#define Unlock_Task system__soft_links__unlock_task
91
extern void (*Unlock_Task) (void);
92
 
93
/*-------------------------------------*
94
 *-- Target specific implementations --*
95
 *-------------------------------------*/
96
 
97
#if defined (__alpha_vxworks)
98
 
99
#include "tb-alvxw.c"
100
 
101
#elif defined (__ALPHA) && defined (__VMS__)
102
 
103
#include "tb-alvms.c"
104
 
105
#elif defined (__ia64__) && defined (__VMS__)
106
 
107
#include "tb-ivms.c"
108
 
109
#else
110
 
111
/* No target specific implementation.  */
112
 
113
/*----------------------------------------------------------------*
114
 *-- Target specific definitions for the generic implementation --*
115
 *----------------------------------------------------------------*/
116
 
117
/* The stack layout is specified by the target ABI. The "generic" scheme is
118
   based on the following assumption:
119
 
120
     The stack layout from some frame pointer is such that the information
121
     required to compute the backtrace is available at static offsets.
122
 
123
   For a given frame, the information we are interested in is the saved return
124
   address (somewhere after the call instruction in the caller) and a pointer
125
   to the caller's frame. The former is the base of the call chain information
126
   we store in the tracebacks array. The latter allows us to loop over the
127
   successive frames in the chain.
128
 
129
   To initiate the process, we retrieve an initial frame address using the
130
   appropriate GCC builtin (__builtin_frame_address).
131
 
132
   This scheme is unfortunately not applicable on every target because the
133
   stack layout is not necessarily regular (static) enough. On targets where
134
   this scheme applies, the implementation relies on the following items:
135
 
136
   o struct layout, describing the expected stack data layout relevant to the
137
     information we are interested in,
138
 
139
   o FRAME_OFFSET, the offset, from a given frame address or frame pointer
140
     value, at which this layout will be found,
141
 
142
   o FRAME_LEVEL, controls how many frames up we get at to start with,
143
     from the initial frame pointer we compute by way of the GCC builtin,
144
 
145
 
146
     where return addresses are saved by a function in it's caller's frame
147
     (e.g. PPC).
148
 
149
   o PC_ADJUST, to account for the difference between a call point (address
150
     of a call instruction), which is what we want in the output array, and
151
     the associated return address, which is what we retrieve from the stack.
152
 
153
   o STOP_FRAME, to decide whether we reached the top of the call chain, and
154
     thus if the process shall stop.
155
 
156
           :
157
           :                   stack
158
           |             +----------------+
159
           |   +-------->|       :        |
160
           |   |         | (FRAME_OFFSET) |
161
           |   |         |       :        |  (PC_ADJUST)
162
           |   |  layout:| return_address ----------------+
163
           |   |         |     ....       |               |
164
           +---------------  next_frame   |               |
165
               |         |     ....       |               |
166
               |         |                |               |
167
               |         +----------------+               |  +-----+
168
               |         |       :        |<- Base fp     |  |  :  |
169
               |         | (FRAME_OFFSET) | (FRAME_LEVEL) |  |  :  |
170
               |         |       :        |               +--->    | [1]
171
               |  layout:| return_address -------------------->    | [0]
172
               |         |       ...      |  (PC_ADJUST)     +-----+
173
               +----------   next_frame   |                 traceback[]
174
                         |       ...      |
175
                         |                |
176
                         +----------------+
177
 
178
   o BASE_SKIP,
179
 
180
   Since we inherently deal with return addresses, there is an implicit shift
181
   by at least one for the initial point we are able to observe in the chain.
182
 
183
   On some targets (e.g. sparc-solaris), the first return address we can
184
   easily get without special code is even our caller's return address, so
185
   there is a initial shift of two.
186
 
187
   BASE_SKIP represents this initial shift, which is the minimal "skip_frames"
188
   value we support. We could add special code for the skip_frames < BASE_SKIP
189
   cases. This is not done currently because there is virtually no situation
190
   in which this would be useful.
191
 
192
   Finally, to account for some ABI specificities, a target may (but does
193
   not have to) define:
194
 
195
   o FORCE_CALL, to force a call to a dummy function at the very beginning
196
     of the computation. See the PPC AIX target for an example where this
197
     is useful.
198
 
199
   o FETCH_UP_FRAME, to force an invocation of __builtin_frame_address with a
200
     positive argument right after a possibly forced call even if FRAME_LEVEL
201
     is 0. See the SPARC Solaris case for an example where this is useful.
202
 
203
  */
204
 
205
/*------------------- Darwin 8 (OSX 10.4) or newer ----------------------*/
206
#if defined (__APPLE__) \
207
    && defined (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \
208
    && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1040
209
 
210
#define USE_GCC_UNWINDER
211
 
212
#if defined (__i386__) || defined (__x86_64__)
213
#define PC_ADJUST -2
214
#elif defined (__ppc__) || defined (__ppc64__)
215
#define PC_ADJUST -4
216
#else
217
#error Unhandled darwin architecture.
218
#endif
219
 
220
/*------------------------ PPC AIX/Older Darwin -------------------------*/
221
#elif ((defined (_POWER) && defined (_AIX)) || \
222
(defined (__ppc__) && defined (__APPLE__)))
223
 
224
#define USE_GENERIC_UNWINDER
225
 
226
struct layout
227
{
228
  struct layout *next;
229
  void *pad;
230
  void *return_address;
231
};
232
 
233
#define FRAME_OFFSET(FP) 0
234
#define PC_ADJUST -4
235
 
236
/* Eventhough the base PPC ABI states that a toplevel frame entry
237
   should to feature a null backchain, AIX might expose a null return
238
   address instead.  */
239
 
240
#define STOP_FRAME(CURRENT, TOP_STACK) \
241
  (((void *) (CURRENT) < (TOP_STACK)) \
242
   || (CURRENT)->return_address == NULL)
243
 
244
/* The PPC ABI has an interesting specificity: the return address saved by a
245
   function is located in it's caller's frame, and the save operation only
246
   takes place if the function performs a call.
247
 
248
   To have __gnat_backtrace retrieve its own return address, we then
249
   define ... */
250
 
251
#define FORCE_CALL 1
252
#define FRAME_LEVEL 1
253
 
254
#define BASE_SKIP 1
255
 
256
/*-------------------- PPC ELF (GNU/Linux & VxWorks) ---------------------*/
257
 
258
#elif (defined (_ARCH_PPC) && defined (__vxworks)) ||  \
259
  (defined (linux) && defined (__powerpc__))
260
 
261
#define USE_GENERIC_UNWINDER
262
 
263
struct layout
264
{
265
  struct layout *next;
266
  void *return_address;
267
};
268
 
269
#define FORCE_CALL 1
270
#define FRAME_LEVEL 1
271
/* See the PPC AIX case for an explanation of these values.  */
272
 
273
#define FRAME_OFFSET(FP) 0
274
#define PC_ADJUST -4
275
 
276
/* According to the base PPC ABI, a toplevel frame entry should feature
277
   a null backchain.  What happens at signal handler frontiers isn't so
278
   well specified, so we add a safety guard on top.  */
279
 
280
#define STOP_FRAME(CURRENT, TOP_STACK) \
281
 ((CURRENT)->next == 0 || ((long)(CURRENT)->next % __alignof__(void*)) != 0)
282
 
283
#define BASE_SKIP 1
284
 
285
/*-------------------------- SPARC Solaris -----------------------------*/
286
 
287
#elif defined (sun) && defined (sparc)
288
 
289
#define USE_GENERIC_UNWINDER
290
 
291
/* These definitions are inspired from the Appendix D (Software
292
   Considerations) of the SPARC V8 architecture manual.  */
293
 
294
struct layout
295
{
296
  struct layout *next;
297
  void *return_address;
298
};
299
 
300
#ifdef __arch64__
301
#define STACK_BIAS 2047 /* V9 ABI */
302
#else
303
#define STACK_BIAS 0    /* V8 ABI */
304
#endif
305
 
306
#define FRAME_LEVEL 0
307
#define FRAME_OFFSET(FP) (14 * sizeof (void*) + (FP ? STACK_BIAS : 0))
308
#define PC_ADJUST 0
309
#define STOP_FRAME(CURRENT, TOP_STACK) \
310
  ((CURRENT)->return_address == 0|| (CURRENT)->next == 0 \
311
   || (void *) (CURRENT) < (TOP_STACK))
312
 
313
/* The SPARC register windows need to be flushed before we may access them
314
   from the stack. This is achieved by way of builtin_frame_address only
315
   when the "count" argument is positive, so force at least one such call.  */
316
#define FETCH_UP_FRAME_ADDRESS
317
 
318
#define BASE_SKIP 2
319
/* From the frame pointer of frame N, we are accessing the flushed register
320
   window of frame N-1 (positive offset from fp), in which we retrieve the
321
   saved return address. We then end up with our caller's return address.  */
322
 
323
/*------------------------------- x86 ----------------------------------*/
324
 
325
#elif defined (i386)
326
 
327
#if defined (__WIN32)
328
#include <windows.h>
329
#define IS_BAD_PTR(ptr) (IsBadCodePtr((void *)ptr))
330
#elif defined (sun)
331
#define IS_BAD_PTR(ptr) ((unsigned long)ptr == -1UL)
332
#else
333
#define IS_BAD_PTR(ptr) 0
334
#endif
335
 
336
/* Starting with GCC 4.6, -fomit-frame-pointer is turned on by default for
337
   32-bit x86/Linux as well and DWARF 2 unwind tables are emitted instead.
338
   See the x86-64 case below for the drawbacks with this approach.  */
339
#if defined (linux) && (__GNUC__ * 10 + __GNUC_MINOR__ > 45)
340
#define USE_GCC_UNWINDER
341
#else
342
#define USE_GENERIC_UNWINDER
343
#endif
344
 
345
struct layout
346
{
347
  struct layout *next;
348
  void *return_address;
349
};
350
 
351
#define FRAME_LEVEL 1
352
/* builtin_frame_address (1) is expected to work on this target, and (0) might
353
   return the soft stack pointer, which does not designate a location where a
354
   backchain and a return address might be found.  */
355
 
356
#define FRAME_OFFSET(FP) 0
357
#define PC_ADJUST -2
358
#define STOP_FRAME(CURRENT, TOP_STACK) \
359
  (IS_BAD_PTR((long)(CURRENT)) \
360
   || IS_BAD_PTR((long)(CURRENT)->return_address) \
361
   || (CURRENT)->return_address == 0 \
362
   || (void *) ((CURRENT)->next) < (TOP_STACK)  \
363
   || (void *) (CURRENT) < (TOP_STACK))
364
 
365
#define BASE_SKIP (1+FRAME_LEVEL)
366
 
367
/* On i386 architecture we check that at the call point we really have a call
368
   insn. Possible call instructions are:
369
 
370
   call  addr16        E8 xx xx xx xx
371
   call  reg           FF Dx
372
   call  off(reg)      FF xx xx
373
   lcall addr seg      9A xx xx xx xx xx xx
374
 
375
   This check will not catch all cases but it will increase the backtrace
376
   reliability on this architecture.
377
*/
378
 
379
#define VALID_STACK_FRAME(ptr) \
380
   (!IS_BAD_PTR(ptr) \
381
    && (((*((ptr) - 3) & 0xff) == 0xe8) \
382
        || ((*((ptr) - 5) & 0xff) == 0x9a) \
383
        || ((*((ptr) - 1) & 0xff) == 0xff) \
384
        || (((*(ptr) & 0xd0ff) == 0xd0ff))))
385
 
386
/*----------------------------- x86_64 ---------------------------------*/
387
 
388
#elif defined (__x86_64__)
389
 
390
#define USE_GCC_UNWINDER
391
/* The generic unwinder is not used for this target because it is based
392
   on frame layout assumptions that are not reliable on this target (the
393
   rbp register is very likely used for something else than storing the
394
   frame pointer in optimized code). Hence, we use the GCC unwinder
395
   based on DWARF 2 call frame information, although it has the drawback
396
   of not being able to unwind through frames compiled without DWARF 2
397
   information.
398
*/
399
 
400
#define PC_ADJUST -2
401
/* The minimum size of call instructions on this architecture is 2 bytes */
402
 
403
/*----------------------------- ia64 ---------------------------------*/
404
 
405
#elif defined (__ia64__) && (defined (linux) || defined (__hpux__))
406
 
407
#define USE_GCC_UNWINDER
408
/* Use _Unwind_Backtrace driven exceptions on ia64 HP-UX and ia64
409
   GNU/Linux, where _Unwind_Backtrace is provided by the system unwind
410
   library. On HP-UX 11.23 this requires patch PHSS_33352, which adds
411
   _Unwind_Backtrace to the system unwind library. */
412
 
413
#define PC_ADJUST -4
414
 
415
 
416
#endif
417
 
418
/*---------------------------------------------------------------------*
419
 *--      The post GCC 3.3 infrastructure based implementation       --*
420
 *---------------------------------------------------------------------*/
421
 
422
#if defined (USE_GCC_UNWINDER) && (__GNUC__ * 10 + __GNUC_MINOR__ > 33)
423
 
424
/* Conditioning the inclusion on the GCC version is useful to avoid bootstrap
425
   path problems, since the included file refers to post 3.3 functions in
426
   libgcc, and the stage1 compiler is unlikely to be linked against a post 3.3
427
   library.  It actually disables the support for backtraces in this compiler
428
   for targets defining USE_GCC_UNWINDER, which is OK since we don't use the
429
   traceback capability in the compiler anyway.
430
 
431
   The condition is expressed the way above because we cannot reliably rely on
432
   any other macro from the base compiler when compiling stage1.  */
433
 
434
#include "tb-gcc.c"
435
 
436
/*------------------------------------------------------------------*
437
 *-- The generic implementation based on frame layout assumptions --*
438
 *------------------------------------------------------------------*/
439
 
440
#elif defined (USE_GENERIC_UNWINDER)
441
 
442
#ifndef CURRENT_STACK_FRAME
443
# define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
444
#endif
445
 
446
#ifndef VALID_STACK_FRAME
447
#define VALID_STACK_FRAME(ptr) 1
448
#endif
449
 
450
#ifndef MAX
451
#define MAX(x,y) ((x) > (y) ? (x) : (y))
452
#endif
453
 
454
#ifndef FORCE_CALL
455
#define FORCE_CALL 0
456
#endif
457
 
458
/* Make sure the function is not inlined.  */
459
static void forced_callee (void) __attribute__ ((noinline));
460
 
461
static void forced_callee (void)
462
{
463
  /* Make sure the function is not pure.  */
464
  volatile int i __attribute__ ((unused)) = 0;
465
}
466
 
467
int
468
__gnat_backtrace (void **array,
469
                  int size,
470
                  void *exclude_min,
471
                  void *exclude_max,
472
                  int skip_frames)
473
{
474
  struct layout *current;
475
  void *top_frame;
476
  void *top_stack ATTRIBUTE_UNUSED;
477
  int cnt = 0;
478
 
479
  if (FORCE_CALL)
480
    forced_callee ();
481
 
482
  /* Force a call to builtin_frame_address with a positive argument
483
     if required. This is necessary e.g. on SPARC to have the register
484
     windows flushed before we attempt to access them on the stack.  */
485
#if defined (FETCH_UP_FRAME_ADDRESS) && (FRAME_LEVEL == 0)
486
  __builtin_frame_address (1);
487
#endif
488
 
489
  top_frame = __builtin_frame_address (FRAME_LEVEL);
490
  top_stack = CURRENT_STACK_FRAME;
491
  current = (struct layout *) ((size_t) top_frame + FRAME_OFFSET (0));
492
 
493
  /* Skip the number of calls we have been requested to skip, accounting for
494
     the BASE_SKIP parameter.
495
 
496
     FRAME_LEVEL is meaningless for the count adjustment. It impacts where we
497
     start retrieving data from, but how many frames "up" we start at is in
498
     BASE_SKIP by definition.  */
499
 
500
  skip_frames = MAX (0, skip_frames - BASE_SKIP);
501
 
502
  while (cnt < skip_frames)
503
    {
504
      current = (struct layout *) ((size_t) current->next + FRAME_OFFSET (1));
505
      cnt++;
506
    }
507
 
508
  cnt = 0;
509
  while (cnt < size)
510
    {
511
      if (STOP_FRAME (current, top_stack) ||
512
          !VALID_STACK_FRAME(((char *) current->return_address) + PC_ADJUST))
513
        break;
514
 
515
      if (current->return_address < exclude_min
516
          || current->return_address > exclude_max)
517
        array[cnt++] = ((char *) current->return_address) + PC_ADJUST;
518
 
519
      current = (struct layout *) ((size_t) current->next + FRAME_OFFSET (1));
520
    }
521
 
522
  return cnt;
523
}
524
 
525
#else
526
 
527
/* No target specific implementation and neither USE_GCC_UNWINDER nor
528
   USE_GENERIC_UNWINDER defined.  */
529
 
530
/*------------------------------*
531
 *-- The dummy implementation --*
532
 *------------------------------*/
533
 
534
int
535
__gnat_backtrace (void **array ATTRIBUTE_UNUSED,
536
                  int size ATTRIBUTE_UNUSED,
537
                  void *exclude_min ATTRIBUTE_UNUSED,
538
                  void *exclude_max ATTRIBUTE_UNUSED,
539
                  int skip_frames ATTRIBUTE_UNUSED)
540
{
541
  return 0;
542
}
543
 
544
#endif
545
 
546
#endif
547
 
548
#ifdef __cplusplus
549
}
550
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.