annotate gcc/ada/tracebak.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /****************************************************************************
kono
parents:
diff changeset
2 * *
kono
parents:
diff changeset
3 * GNAT RUN-TIME COMPONENTS *
kono
parents:
diff changeset
4 * *
kono
parents:
diff changeset
5 * T R A C E B A C K *
kono
parents:
diff changeset
6 * *
kono
parents:
diff changeset
7 * C Implementation File *
kono
parents:
diff changeset
8 * *
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 * Copyright (C) 2000-2019, Free Software Foundation, Inc. *
111
kono
parents:
diff changeset
10 * *
kono
parents:
diff changeset
11 * GNAT is free software; you can redistribute it and/or modify it under *
kono
parents:
diff changeset
12 * terms of the GNU General Public License as published by the Free Soft- *
kono
parents:
diff changeset
13 * ware Foundation; either version 3, or (at your option) any later ver- *
kono
parents:
diff changeset
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
kono
parents:
diff changeset
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
kono
parents:
diff changeset
16 * or FITNESS FOR A PARTICULAR PURPOSE. *
kono
parents:
diff changeset
17 * *
kono
parents:
diff changeset
18 * As a special exception under Section 7 of GPL version 3, you are granted *
kono
parents:
diff changeset
19 * additional permissions described in the GCC Runtime Library Exception, *
kono
parents:
diff changeset
20 * version 3.1, as published by the Free Software Foundation. *
kono
parents:
diff changeset
21 * *
kono
parents:
diff changeset
22 * You should have received a copy of the GNU General Public License and *
kono
parents:
diff changeset
23 * a copy of the GCC Runtime Library Exception along with this program; *
kono
parents:
diff changeset
24 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
kono
parents:
diff changeset
25 * <http://www.gnu.org/licenses/>. *
kono
parents:
diff changeset
26 * *
kono
parents:
diff changeset
27 * GNAT was originally developed by the GNAT team at New York University. *
kono
parents:
diff changeset
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
kono
parents:
diff changeset
29 * *
kono
parents:
diff changeset
30 ****************************************************************************/
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 /* This file contains low level support for stack unwinding using GCC intrinsic
kono
parents:
diff changeset
33 functions.
kono
parents:
diff changeset
34 It has been tested on the following configurations:
kono
parents:
diff changeset
35 PowerPC/AiX
kono
parents:
diff changeset
36 PowerPC/Darwin
kono
parents:
diff changeset
37 PowerPC/VxWorks
kono
parents:
diff changeset
38 PowerPC/LynxOS-178
kono
parents:
diff changeset
39 SPARC/Solaris
kono
parents:
diff changeset
40 i386/GNU/Linux
kono
parents:
diff changeset
41 i386/Solaris
kono
parents:
diff changeset
42 i386/NT
kono
parents:
diff changeset
43 i386/OS2
kono
parents:
diff changeset
44 i386/LynxOS
kono
parents:
diff changeset
45 Alpha/VxWorks
kono
parents:
diff changeset
46 Alpha/VMS
kono
parents:
diff changeset
47 */
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 #ifdef __cplusplus
kono
parents:
diff changeset
50 extern "C" {
kono
parents:
diff changeset
51 #endif
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 #ifdef IN_RTS
kono
parents:
diff changeset
54 #define POSIX
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
55 #include "runtime.h"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
56 #include <stddef.h>
111
kono
parents:
diff changeset
57 #else
kono
parents:
diff changeset
58 #include "config.h"
kono
parents:
diff changeset
59 #include "system.h"
kono
parents:
diff changeset
60 /* We don't want fancy_abort here. */
kono
parents:
diff changeset
61 #undef abort
kono
parents:
diff changeset
62 #endif
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 extern int __gnat_backtrace (void **, int, void *, void *, int);
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 /* The point is to provide an implementation of the __gnat_backtrace function
kono
parents:
diff changeset
67 above, called by the default implementation of the System.Traceback package.
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 We first have a series of target specific implementations, each included
kono
parents:
diff changeset
70 from a separate C file for readability purposes.
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 Then come two flavors of a generic implementation: one relying on static
kono
parents:
diff changeset
73 assumptions about the frame layout, and the other one using the GCC EH
kono
parents:
diff changeset
74 infrastructure. The former uses a whole set of macros and structures which
kono
parents:
diff changeset
75 may be tailored on a per target basis, and is activated as soon as
kono
parents:
diff changeset
76 USE_GENERIC_UNWINDER is defined. The latter uses a small subset of the
kono
parents:
diff changeset
77 macro definitions and is activated when USE_GCC_UNWINDER is defined. It is
kono
parents:
diff changeset
78 only available post GCC 3.3.
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 Finally, there is a default dummy implementation, necessary to make the
kono
parents:
diff changeset
81 linker happy on platforms where the feature is not supported, but where the
kono
parents:
diff changeset
82 function is still referenced by the default System.Traceback. */
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 #define Lock_Task system__soft_links__lock_task
kono
parents:
diff changeset
85 extern void (*Lock_Task) (void);
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 #define Unlock_Task system__soft_links__unlock_task
kono
parents:
diff changeset
88 extern void (*Unlock_Task) (void);
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 /*-------------------------------------*
kono
parents:
diff changeset
91 *-- Target specific implementations --*
kono
parents:
diff changeset
92 *-------------------------------------*/
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 #if defined (_WIN64) && defined (__SEH__)
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 #include <windows.h>
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 #define IS_BAD_PTR(ptr) (IsBadCodePtr((FARPROC)ptr))
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 int
kono
parents:
diff changeset
101 __gnat_backtrace (void **array,
kono
parents:
diff changeset
102 int size,
kono
parents:
diff changeset
103 void *exclude_min,
kono
parents:
diff changeset
104 void *exclude_max,
kono
parents:
diff changeset
105 int skip_frames)
kono
parents:
diff changeset
106 {
kono
parents:
diff changeset
107 CONTEXT context;
kono
parents:
diff changeset
108 UNWIND_HISTORY_TABLE history;
kono
parents:
diff changeset
109 int i;
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 /* Get the context. */
kono
parents:
diff changeset
112 RtlCaptureContext (&context);
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 /* Setup unwind history table (a cached to speed-up unwinding). */
kono
parents:
diff changeset
115 memset (&history, 0, sizeof (history));
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 i = 0;
kono
parents:
diff changeset
118 while (1)
kono
parents:
diff changeset
119 {
kono
parents:
diff changeset
120 PRUNTIME_FUNCTION RuntimeFunction;
kono
parents:
diff changeset
121 KNONVOLATILE_CONTEXT_POINTERS NvContext;
kono
parents:
diff changeset
122 ULONG64 ImageBase;
kono
parents:
diff changeset
123 VOID *HandlerData;
kono
parents:
diff changeset
124 ULONG64 EstablisherFrame;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 /* Get function metadata. */
kono
parents:
diff changeset
127 RuntimeFunction = RtlLookupFunctionEntry
kono
parents:
diff changeset
128 (context.Rip, &ImageBase, &history);
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 if (!RuntimeFunction)
kono
parents:
diff changeset
131 {
kono
parents:
diff changeset
132 /* In case of failure, assume this is a leaf function. */
kono
parents:
diff changeset
133 context.Rip = *(ULONG64 *) context.Rsp;
kono
parents:
diff changeset
134 context.Rsp += 8;
kono
parents:
diff changeset
135 }
kono
parents:
diff changeset
136 else
kono
parents:
diff changeset
137 {
kono
parents:
diff changeset
138 /* If the last unwinding step failed somehow, stop here. */
kono
parents:
diff changeset
139 if (IS_BAD_PTR(context.Rip))
kono
parents:
diff changeset
140 break;
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 /* Unwind. */
kono
parents:
diff changeset
143 memset (&NvContext, 0, sizeof (KNONVOLATILE_CONTEXT_POINTERS));
kono
parents:
diff changeset
144 RtlVirtualUnwind (0, ImageBase, context.Rip, RuntimeFunction,
kono
parents:
diff changeset
145 &context, &HandlerData, &EstablisherFrame,
kono
parents:
diff changeset
146 &NvContext);
kono
parents:
diff changeset
147 }
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 /* 0 means bottom of the stack. */
kono
parents:
diff changeset
150 if (context.Rip == 0)
kono
parents:
diff changeset
151 break;
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 /* Skip frames. */
kono
parents:
diff changeset
154 if (skip_frames > 1)
kono
parents:
diff changeset
155 {
kono
parents:
diff changeset
156 skip_frames--;
kono
parents:
diff changeset
157 continue;
kono
parents:
diff changeset
158 }
kono
parents:
diff changeset
159 /* Excluded frames. */
kono
parents:
diff changeset
160 if ((void *)context.Rip >= exclude_min
kono
parents:
diff changeset
161 && (void *)context.Rip <= exclude_max)
kono
parents:
diff changeset
162 continue;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 array[i++] = (void *)(context.Rip - 2);
kono
parents:
diff changeset
165 if (i >= size)
kono
parents:
diff changeset
166 break;
kono
parents:
diff changeset
167 }
kono
parents:
diff changeset
168 return i;
kono
parents:
diff changeset
169 }
kono
parents:
diff changeset
170 #else
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 /* No target specific implementation. */
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 /*----------------------------------------------------------------*
kono
parents:
diff changeset
175 *-- Target specific definitions for the generic implementation --*
kono
parents:
diff changeset
176 *----------------------------------------------------------------*/
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 /* The stack layout is specified by the target ABI. The "generic" scheme is
kono
parents:
diff changeset
179 based on the following assumption:
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 The stack layout from some frame pointer is such that the information
kono
parents:
diff changeset
182 required to compute the backtrace is available at static offsets.
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 For a given frame, the information we are interested in is the saved return
kono
parents:
diff changeset
185 address (somewhere after the call instruction in the caller) and a pointer
kono
parents:
diff changeset
186 to the caller's frame. The former is the base of the call chain information
kono
parents:
diff changeset
187 we store in the tracebacks array. The latter allows us to loop over the
kono
parents:
diff changeset
188 successive frames in the chain.
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 To initiate the process, we retrieve an initial frame address using the
kono
parents:
diff changeset
191 appropriate GCC builtin (__builtin_frame_address).
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 This scheme is unfortunately not applicable on every target because the
kono
parents:
diff changeset
194 stack layout is not necessarily regular (static) enough. On targets where
kono
parents:
diff changeset
195 this scheme applies, the implementation relies on the following items:
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 o struct layout, describing the expected stack data layout relevant to the
kono
parents:
diff changeset
198 information we are interested in,
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 o FRAME_OFFSET, the offset, from a given frame address or frame pointer
kono
parents:
diff changeset
201 value, at which this layout will be found,
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 o FRAME_LEVEL, controls how many frames up we get at to start with,
kono
parents:
diff changeset
204 from the initial frame pointer we compute by way of the GCC builtin,
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 0 is most often the appropriate value. 1 may be necessary on targets
kono
parents:
diff changeset
207 where return addresses are saved by a function in it's caller's frame
kono
parents:
diff changeset
208 (e.g. PPC).
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 o PC_ADJUST, to account for the difference between a call point (address
kono
parents:
diff changeset
211 of a call instruction), which is what we want in the output array, and
kono
parents:
diff changeset
212 the associated return address, which is what we retrieve from the stack.
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 o STOP_FRAME, to decide whether we reached the top of the call chain, and
kono
parents:
diff changeset
215 thus if the process shall stop.
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 :
kono
parents:
diff changeset
218 : stack
kono
parents:
diff changeset
219 | +----------------+
kono
parents:
diff changeset
220 | +-------->| : |
kono
parents:
diff changeset
221 | | | (FRAME_OFFSET) |
kono
parents:
diff changeset
222 | | | : | (PC_ADJUST)
kono
parents:
diff changeset
223 | | layout:| return_address ----------------+
kono
parents:
diff changeset
224 | | | .... | |
kono
parents:
diff changeset
225 +--------------- next_frame | |
kono
parents:
diff changeset
226 | | .... | |
kono
parents:
diff changeset
227 | | | |
kono
parents:
diff changeset
228 | +----------------+ | +-----+
kono
parents:
diff changeset
229 | | : |<- Base fp | | : |
kono
parents:
diff changeset
230 | | (FRAME_OFFSET) | (FRAME_LEVEL) | | : |
kono
parents:
diff changeset
231 | | : | +---> | [1]
kono
parents:
diff changeset
232 | layout:| return_address --------------------> | [0]
kono
parents:
diff changeset
233 | | ... | (PC_ADJUST) +-----+
kono
parents:
diff changeset
234 +---------- next_frame | traceback[]
kono
parents:
diff changeset
235 | ... |
kono
parents:
diff changeset
236 | |
kono
parents:
diff changeset
237 +----------------+
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 o BASE_SKIP,
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 Since we inherently deal with return addresses, there is an implicit shift
kono
parents:
diff changeset
242 by at least one for the initial point we are able to observe in the chain.
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 On some targets (e.g. sparc-solaris), the first return address we can
kono
parents:
diff changeset
245 easily get without special code is even our caller's return address, so
kono
parents:
diff changeset
246 there is a initial shift of two.
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 BASE_SKIP represents this initial shift, which is the minimal "skip_frames"
kono
parents:
diff changeset
249 value we support. We could add special code for the skip_frames < BASE_SKIP
kono
parents:
diff changeset
250 cases. This is not done currently because there is virtually no situation
kono
parents:
diff changeset
251 in which this would be useful.
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 Finally, to account for some ABI specificities, a target may (but does
kono
parents:
diff changeset
254 not have to) define:
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 o FORCE_CALL, to force a call to a dummy function at the very beginning
kono
parents:
diff changeset
257 of the computation. See the PPC AIX target for an example where this
kono
parents:
diff changeset
258 is useful.
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 o FETCH_UP_FRAME, to force an invocation of __builtin_frame_address with a
kono
parents:
diff changeset
261 positive argument right after a possibly forced call even if FRAME_LEVEL
kono
parents:
diff changeset
262 is 0. See the SPARC Solaris case for an example where this is useful.
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 */
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 /*------------------- Darwin 8 (OSX 10.4) or newer ----------------------*/
kono
parents:
diff changeset
267 #if defined (__APPLE__) \
kono
parents:
diff changeset
268 && defined (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \
kono
parents:
diff changeset
269 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1040
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 #define USE_GCC_UNWINDER
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 #if defined (__i386__) || defined (__x86_64__)
kono
parents:
diff changeset
274 #define PC_ADJUST -2
kono
parents:
diff changeset
275 #elif defined (__ppc__) || defined (__ppc64__)
kono
parents:
diff changeset
276 #define PC_ADJUST -4
kono
parents:
diff changeset
277 #elif defined (__arm__)
kono
parents:
diff changeset
278 #define PC_ADJUST -2
kono
parents:
diff changeset
279 #elif defined (__arm64__)
kono
parents:
diff changeset
280 #define PC_ADJUST -4
kono
parents:
diff changeset
281 #else
kono
parents:
diff changeset
282 #error Unhandled darwin architecture.
kono
parents:
diff changeset
283 #endif
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 /*---------------------------- x86 *BSD --------------------------------*/
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 #elif defined (__i386__) && \
kono
parents:
diff changeset
288 ( defined (__NetBSD__) || defined (__FreeBSD__) || defined (__OpenBSD__) )
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 #define USE_GCC_UNWINDER
kono
parents:
diff changeset
291 /* The generic unwinder is not used for this target because the default
kono
parents:
diff changeset
292 implementation doesn't unwind on the BSD platforms. AMD64 targets use the
kono
parents:
diff changeset
293 gcc unwinder for all platforms, so let's keep i386 consistent with that.
kono
parents:
diff changeset
294 */
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 #define PC_ADJUST -2
kono
parents:
diff changeset
297 /* The minimum size of call instructions on this architecture is 2 bytes */
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 /*---------------------- ARM VxWorks ------------------------------------*/
kono
parents:
diff changeset
300 #elif (defined (ARMEL) && defined (__vxworks))
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 #include "vxWorks.h"
kono
parents:
diff changeset
303 #include "version.h"
kono
parents:
diff changeset
304
kono
parents:
diff changeset
305 #define USE_GCC_UNWINDER
kono
parents:
diff changeset
306 #define PC_ADJUST -2
kono
parents:
diff changeset
307
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
308 #if ((_WRS_VXWORKS_MAJOR >= 7) && (_VX_CPU != ARMARCH8A))
111
kono
parents:
diff changeset
309 #define USING_ARM_UNWINDING 1
kono
parents:
diff changeset
310 #endif
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 /*---------------------- PPC AIX/PPC Lynx 178/Older Darwin --------------*/
kono
parents:
diff changeset
313 #elif ((defined (_POWER) && defined (_AIX)) || \
kono
parents:
diff changeset
314 (defined (__powerpc__) && defined (__Lynx__) && !defined(__ELF__)) || \
kono
parents:
diff changeset
315 (defined (__ppc__) && defined (__APPLE__)))
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 #define USE_GENERIC_UNWINDER
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 struct layout
kono
parents:
diff changeset
320 {
kono
parents:
diff changeset
321 struct layout *next;
kono
parents:
diff changeset
322 void *pad;
kono
parents:
diff changeset
323 void *return_address;
kono
parents:
diff changeset
324 };
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 #define FRAME_OFFSET(FP) 0
kono
parents:
diff changeset
327 #define PC_ADJUST -4
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 /* Eventhough the base PPC ABI states that a toplevel frame entry
kono
parents:
diff changeset
330 should to feature a null backchain, AIX might expose a null return
kono
parents:
diff changeset
331 address instead. */
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 /* Then LynxOS-178 features yet another variation, with return_address
kono
parents:
diff changeset
334 == &<entrypoint>, with two possible entry points (one for the main
kono
parents:
diff changeset
335 process and one for threads). Beware that &bla returns the address
kono
parents:
diff changeset
336 of a descriptor when "bla" is a function. Getting the code address
kono
parents:
diff changeset
337 requires an extra dereference. */
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 #if defined (__Lynx__)
kono
parents:
diff changeset
340 extern void __start(); /* process entry point. */
kono
parents:
diff changeset
341 extern void __runnit(); /* thread entry point. */
kono
parents:
diff changeset
342 #define EXTRA_STOP_CONDITION(CURRENT) \
kono
parents:
diff changeset
343 ((CURRENT)->return_address == *(void**)&__start \
kono
parents:
diff changeset
344 || (CURRENT)->return_address == *(void**)&__runnit)
kono
parents:
diff changeset
345 #else
kono
parents:
diff changeset
346 #define EXTRA_STOP_CONDITION(CURRENT) (0)
kono
parents:
diff changeset
347 #endif
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 #define STOP_FRAME(CURRENT, TOP_STACK) \
kono
parents:
diff changeset
350 (((void *) (CURRENT) < (TOP_STACK)) \
kono
parents:
diff changeset
351 || (CURRENT)->return_address == NULL \
kono
parents:
diff changeset
352 || EXTRA_STOP_CONDITION(CURRENT))
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 /* The PPC ABI has an interesting specificity: the return address saved by a
kono
parents:
diff changeset
355 function is located in it's caller's frame, and the save operation only
kono
parents:
diff changeset
356 takes place if the function performs a call.
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 To have __gnat_backtrace retrieve its own return address, we then
kono
parents:
diff changeset
359 define ... */
kono
parents:
diff changeset
360
kono
parents:
diff changeset
361 #define FORCE_CALL 1
kono
parents:
diff changeset
362 #define FRAME_LEVEL 1
kono
parents:
diff changeset
363
kono
parents:
diff changeset
364 #define BASE_SKIP 1
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 /*----------- PPC ELF (GNU/Linux & VxWorks & Lynx178e) -------------------*/
kono
parents:
diff changeset
367
kono
parents:
diff changeset
368 #elif (defined (_ARCH_PPC) && defined (__vxworks)) || \
kono
parents:
diff changeset
369 (defined (__powerpc__) && defined (__Lynx__) && defined(__ELF__)) || \
kono
parents:
diff changeset
370 (defined (__linux__) && defined (__powerpc__))
kono
parents:
diff changeset
371
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
372 #if defined (_ARCH_PPC64) && !defined (__USING_SJLJ_EXCEPTIONS__)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
373 #define USE_GCC_UNWINDER
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
374 #else
111
kono
parents:
diff changeset
375 #define USE_GENERIC_UNWINDER
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
376 #endif
111
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 struct layout
kono
parents:
diff changeset
379 {
kono
parents:
diff changeset
380 struct layout *next;
kono
parents:
diff changeset
381 void *return_address;
kono
parents:
diff changeset
382 };
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 #define FORCE_CALL 1
kono
parents:
diff changeset
385 #define FRAME_LEVEL 1
kono
parents:
diff changeset
386 /* See the PPC AIX case for an explanation of these values. */
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 #define FRAME_OFFSET(FP) 0
kono
parents:
diff changeset
389 #define PC_ADJUST -4
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 /* According to the base PPC ABI, a toplevel frame entry should feature
kono
parents:
diff changeset
392 a null backchain. What happens at signal handler frontiers isn't so
kono
parents:
diff changeset
393 well specified, so we add a safety guard on top. */
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 #define STOP_FRAME(CURRENT, TOP_STACK) \
kono
parents:
diff changeset
396 ((CURRENT)->next == 0 || ((long)(CURRENT)->next % __alignof__(void*)) != 0)
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 #define BASE_SKIP 1
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 /*-------------------------- SPARC Solaris -----------------------------*/
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 #elif defined (__sun__) && defined (__sparc__)
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 #define USE_GENERIC_UNWINDER
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 /* These definitions are inspired from the Appendix D (Software
kono
parents:
diff changeset
407 Considerations) of the SPARC V8 architecture manual. */
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 struct layout
kono
parents:
diff changeset
410 {
kono
parents:
diff changeset
411 struct layout *next;
kono
parents:
diff changeset
412 void *return_address;
kono
parents:
diff changeset
413 };
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 #ifdef __arch64__
kono
parents:
diff changeset
416 #define STACK_BIAS 2047 /* V9 ABI */
kono
parents:
diff changeset
417 #else
kono
parents:
diff changeset
418 #define STACK_BIAS 0 /* V8 ABI */
kono
parents:
diff changeset
419 #endif
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 #define FRAME_LEVEL 0
kono
parents:
diff changeset
422 #define FRAME_OFFSET(FP) (14 * sizeof (void*) + (FP ? STACK_BIAS : 0))
kono
parents:
diff changeset
423 #define PC_ADJUST 0
kono
parents:
diff changeset
424 #define STOP_FRAME(CURRENT, TOP_STACK) \
kono
parents:
diff changeset
425 ((CURRENT)->return_address == 0|| (CURRENT)->next == 0 \
kono
parents:
diff changeset
426 || (void *) (CURRENT) < (TOP_STACK))
kono
parents:
diff changeset
427
kono
parents:
diff changeset
428 /* The SPARC register windows need to be flushed before we may access them
kono
parents:
diff changeset
429 from the stack. This is achieved by way of builtin_frame_address only
kono
parents:
diff changeset
430 when the "count" argument is positive, so force at least one such call. */
kono
parents:
diff changeset
431 #define FETCH_UP_FRAME_ADDRESS
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 #define BASE_SKIP 2
kono
parents:
diff changeset
434 /* From the frame pointer of frame N, we are accessing the flushed register
kono
parents:
diff changeset
435 window of frame N-1 (positive offset from fp), in which we retrieve the
kono
parents:
diff changeset
436 saved return address. We then end up with our caller's return address. */
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 /*---------------------------- x86 & x86_64 ---------------------------------*/
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 #elif defined (__i386__) || defined (__x86_64__)
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 #if defined (__WIN32)
kono
parents:
diff changeset
443 #include <windows.h>
kono
parents:
diff changeset
444 #define IS_BAD_PTR(ptr) (IsBadCodePtr((FARPROC)ptr))
kono
parents:
diff changeset
445 #elif defined (__sun__)
kono
parents:
diff changeset
446 #define IS_BAD_PTR(ptr) ((unsigned long)ptr == -1UL)
kono
parents:
diff changeset
447 #else
kono
parents:
diff changeset
448 #define IS_BAD_PTR(ptr) 0
kono
parents:
diff changeset
449 #endif
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 /* Use the dwarf2 unwinder when we expect to have dwarf2 tables at
kono
parents:
diff changeset
452 hand. Backtraces will reliably stop on frames missing such tables,
kono
parents:
diff changeset
453 but our only alternative is the generic unwinder which requires
kono
parents:
diff changeset
454 compilation forcing a frame pointer to be reliable. */
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 #if (defined (__x86_64__) || defined (__linux__)) && !defined (__USING_SJLJ_EXCEPTIONS__)
kono
parents:
diff changeset
457 #define USE_GCC_UNWINDER
kono
parents:
diff changeset
458 #else
kono
parents:
diff changeset
459 #define USE_GENERIC_UNWINDER
kono
parents:
diff changeset
460 #endif
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 struct layout
kono
parents:
diff changeset
463 {
kono
parents:
diff changeset
464 struct layout *next;
kono
parents:
diff changeset
465 void *return_address;
kono
parents:
diff changeset
466 };
kono
parents:
diff changeset
467
kono
parents:
diff changeset
468 #define FRAME_LEVEL 1
kono
parents:
diff changeset
469 /* builtin_frame_address (1) is expected to work on this family of targets,
kono
parents:
diff changeset
470 and (0) might return the soft stack pointer, which does not designate a
kono
parents:
diff changeset
471 location where a backchain and a return address might be found. */
kono
parents:
diff changeset
472
kono
parents:
diff changeset
473 #define FRAME_OFFSET(FP) 0
kono
parents:
diff changeset
474 #define PC_ADJUST -2
kono
parents:
diff changeset
475 #define STOP_FRAME(CURRENT, TOP_STACK) \
kono
parents:
diff changeset
476 (IS_BAD_PTR((long)(CURRENT)) \
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
477 || (void *) (CURRENT) < (TOP_STACK) \
111
kono
parents:
diff changeset
478 || IS_BAD_PTR((long)(CURRENT)->return_address) \
kono
parents:
diff changeset
479 || (CURRENT)->return_address == 0 \
kono
parents:
diff changeset
480 || (void *) ((CURRENT)->next) < (TOP_STACK) \
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
481 || EXTRA_STOP_CONDITION(CURRENT))
111
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483 #define BASE_SKIP (1+FRAME_LEVEL)
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 /* On i386 architecture we check that at the call point we really have a call
kono
parents:
diff changeset
486 insn. Possible call instructions are:
kono
parents:
diff changeset
487
kono
parents:
diff changeset
488 call addr16 E8 xx xx xx xx
kono
parents:
diff changeset
489 call reg FF Dx
kono
parents:
diff changeset
490 call off(reg) FF xx xx
kono
parents:
diff changeset
491 lcall addr seg 9A xx xx xx xx xx xx
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 This check will not catch all cases but it will increase the backtrace
kono
parents:
diff changeset
494 reliability on this architecture.
kono
parents:
diff changeset
495 */
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 #define VALID_STACK_FRAME(ptr) \
kono
parents:
diff changeset
498 (!IS_BAD_PTR(ptr) \
kono
parents:
diff changeset
499 && (((*((ptr) - 3) & 0xff) == 0xe8) \
kono
parents:
diff changeset
500 || ((*((ptr) - 5) & 0xff) == 0x9a) \
kono
parents:
diff changeset
501 || ((*((ptr) - 1) & 0xff) == 0xff) \
kono
parents:
diff changeset
502 || (((*(ptr) & 0xd0ff) == 0xd0ff))))
kono
parents:
diff changeset
503
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
504 #if defined (__vxworks) && defined (__RTP__)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
505
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
506 /* For VxWorks following backchains past the "main" frame gets us into the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
507 kernel space, where it can't be dereferenced. So lets stop at the main
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
508 symbol. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
509 extern void main();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
510
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
511 static int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
512 is_return_from(void *symbol_addr, void *ret_addr)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
513 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
514 int ret = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
515 char *ptr = (char *)ret_addr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
516
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
517 if ((*(ptr - 5) & 0xff) == 0xe8)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
518 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
519 /* call addr16 E8 xx xx xx xx */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
520 int32_t offset = *(int32_t *)(ptr - 4);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
521 ret = (ptr + offset) == symbol_addr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
522 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
523
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
524 /* Others not implemented yet... But it is very likely that call addr16
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
525 is used here. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
526 return ret;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
527 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
528
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
529 #define EXTRA_STOP_CONDITION(CURRENT) \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
530 (is_return_from(&main, (CURRENT)->return_address))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
531 #else /* not (defined (__vxworks) && defined (__RTP__)) */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
532 #define EXTRA_STOP_CONDITION(CURRENT) (0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
533 #endif /* not (defined (__vxworks) && defined (__RTP__)) */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
534
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
535 /*----------------------------- qnx ----------------------------------*/
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
536
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
537 #elif defined (__QNX__)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
538
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
539 #define USE_GCC_UNWINDER
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
540
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
541 #if defined (__aarch64__)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
542 #define PC_ADJUST -4
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
543 #else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
544 #error Unhandled QNX architecture.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
545 #endif
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
546
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
547 /*------------------- aarch64-linux ----------------------------------*/
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
548
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
549 #elif (defined (__aarch64__) && defined (__linux__))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
550
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
551 #define USE_GCC_UNWINDER
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
552 #define PC_ADJUST -4
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
553
111
kono
parents:
diff changeset
554 /*----------------------------- ia64 ---------------------------------*/
kono
parents:
diff changeset
555
kono
parents:
diff changeset
556 #elif defined (__ia64__) && (defined (__linux__) || defined (__hpux__))
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 #define USE_GCC_UNWINDER
kono
parents:
diff changeset
559 /* Use _Unwind_Backtrace driven exceptions on ia64 HP-UX and ia64
kono
parents:
diff changeset
560 GNU/Linux, where _Unwind_Backtrace is provided by the system unwind
kono
parents:
diff changeset
561 library. On HP-UX 11.23 this requires patch PHSS_33352, which adds
kono
parents:
diff changeset
562 _Unwind_Backtrace to the system unwind library. */
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 #define PC_ADJUST -4
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566
kono
parents:
diff changeset
567 #endif
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 /*---------------------------------------------------------------------*
kono
parents:
diff changeset
570 *-- The post GCC 3.3 infrastructure based implementation --*
kono
parents:
diff changeset
571 *---------------------------------------------------------------------*/
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 #if defined (USE_GCC_UNWINDER) && (__GNUC__ * 10 + __GNUC_MINOR__ > 33)
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 /* Conditioning the inclusion on the GCC version is useful to avoid bootstrap
kono
parents:
diff changeset
576 path problems, since the included file refers to post 3.3 functions in
kono
parents:
diff changeset
577 libgcc, and the stage1 compiler is unlikely to be linked against a post 3.3
kono
parents:
diff changeset
578 library. It actually disables the support for backtraces in this compiler
kono
parents:
diff changeset
579 for targets defining USE_GCC_UNWINDER, which is OK since we don't use the
kono
parents:
diff changeset
580 traceback capability in the compiler anyway.
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 The condition is expressed the way above because we cannot reliably rely on
kono
parents:
diff changeset
583 any other macro from the base compiler when compiling stage1. */
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 #ifdef USING_ARM_UNWINDING
kono
parents:
diff changeset
586 /* This value is not part of the enumerated reason codes defined in unwind.h
kono
parents:
diff changeset
587 for ARM style unwinding, but is used in the included "C" code, so we
kono
parents:
diff changeset
588 define it to a reasonable value to avoid a compilation error. */
kono
parents:
diff changeset
589 #define _URC_NORMAL_STOP 0
kono
parents:
diff changeset
590 #endif
kono
parents:
diff changeset
591 #include "tb-gcc.c"
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 /*------------------------------------------------------------------*
kono
parents:
diff changeset
594 *-- The generic implementation based on frame layout assumptions --*
kono
parents:
diff changeset
595 *------------------------------------------------------------------*/
kono
parents:
diff changeset
596
kono
parents:
diff changeset
597 #elif defined (USE_GENERIC_UNWINDER)
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 #ifndef CURRENT_STACK_FRAME
kono
parents:
diff changeset
600 # define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
kono
parents:
diff changeset
601 #endif
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 #ifndef VALID_STACK_FRAME
kono
parents:
diff changeset
604 #define VALID_STACK_FRAME(ptr) 1
kono
parents:
diff changeset
605 #endif
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 #ifndef MAX
kono
parents:
diff changeset
608 #define MAX(x,y) ((x) > (y) ? (x) : (y))
kono
parents:
diff changeset
609 #endif
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 #ifndef FORCE_CALL
kono
parents:
diff changeset
612 #define FORCE_CALL 0
kono
parents:
diff changeset
613 #endif
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 /* Make sure the function is not inlined. */
kono
parents:
diff changeset
616 static void forced_callee (void) __attribute__ ((noinline));
kono
parents:
diff changeset
617
kono
parents:
diff changeset
618 static void forced_callee (void)
kono
parents:
diff changeset
619 {
kono
parents:
diff changeset
620 /* Make sure the function is not pure. */
kono
parents:
diff changeset
621 volatile int i __attribute__ ((unused)) = 0;
kono
parents:
diff changeset
622 }
kono
parents:
diff changeset
623
kono
parents:
diff changeset
624 int
kono
parents:
diff changeset
625 __gnat_backtrace (void **array,
kono
parents:
diff changeset
626 int size,
kono
parents:
diff changeset
627 void *exclude_min,
kono
parents:
diff changeset
628 void *exclude_max,
kono
parents:
diff changeset
629 int skip_frames)
kono
parents:
diff changeset
630 {
kono
parents:
diff changeset
631 struct layout *current;
kono
parents:
diff changeset
632 void *top_frame;
kono
parents:
diff changeset
633 void *top_stack ATTRIBUTE_UNUSED;
kono
parents:
diff changeset
634 int cnt = 0;
kono
parents:
diff changeset
635
kono
parents:
diff changeset
636 if (FORCE_CALL)
kono
parents:
diff changeset
637 forced_callee ();
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 /* Force a call to builtin_frame_address with a positive argument
kono
parents:
diff changeset
640 if required. This is necessary e.g. on SPARC to have the register
kono
parents:
diff changeset
641 windows flushed before we attempt to access them on the stack. */
kono
parents:
diff changeset
642 #if defined (FETCH_UP_FRAME_ADDRESS) && (FRAME_LEVEL == 0)
kono
parents:
diff changeset
643 __builtin_frame_address (1);
kono
parents:
diff changeset
644 #endif
kono
parents:
diff changeset
645
kono
parents:
diff changeset
646 top_frame = __builtin_frame_address (FRAME_LEVEL);
kono
parents:
diff changeset
647 top_stack = CURRENT_STACK_FRAME;
kono
parents:
diff changeset
648 current = (struct layout *) ((size_t) top_frame + FRAME_OFFSET (0));
kono
parents:
diff changeset
649
kono
parents:
diff changeset
650 /* Skip the number of calls we have been requested to skip, accounting for
kono
parents:
diff changeset
651 the BASE_SKIP parameter.
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 FRAME_LEVEL is meaningless for the count adjustment. It impacts where we
kono
parents:
diff changeset
654 start retrieving data from, but how many frames "up" we start at is in
kono
parents:
diff changeset
655 BASE_SKIP by definition. */
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 skip_frames = MAX (0, skip_frames - BASE_SKIP);
kono
parents:
diff changeset
658
kono
parents:
diff changeset
659 while (cnt < skip_frames)
kono
parents:
diff changeset
660 {
kono
parents:
diff changeset
661 current = (struct layout *) ((size_t) current->next + FRAME_OFFSET (1));
kono
parents:
diff changeset
662 cnt++;
kono
parents:
diff changeset
663 }
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 cnt = 0;
kono
parents:
diff changeset
666 while (cnt < size)
kono
parents:
diff changeset
667 {
kono
parents:
diff changeset
668 if (STOP_FRAME (current, top_stack) ||
kono
parents:
diff changeset
669 !VALID_STACK_FRAME(((char *) current->return_address) + PC_ADJUST))
kono
parents:
diff changeset
670 break;
kono
parents:
diff changeset
671
kono
parents:
diff changeset
672 if (current->return_address < exclude_min
kono
parents:
diff changeset
673 || current->return_address > exclude_max)
kono
parents:
diff changeset
674 array[cnt++] = ((char *) current->return_address) + PC_ADJUST;
kono
parents:
diff changeset
675
kono
parents:
diff changeset
676 current = (struct layout *) ((size_t) current->next + FRAME_OFFSET (1));
kono
parents:
diff changeset
677 }
kono
parents:
diff changeset
678
kono
parents:
diff changeset
679 return cnt;
kono
parents:
diff changeset
680 }
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 #else
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 /* No target specific implementation and neither USE_GCC_UNWINDER nor
kono
parents:
diff changeset
685 USE_GENERIC_UNWINDER defined. */
kono
parents:
diff changeset
686
kono
parents:
diff changeset
687 /*------------------------------*
kono
parents:
diff changeset
688 *-- The dummy implementation --*
kono
parents:
diff changeset
689 *------------------------------*/
kono
parents:
diff changeset
690
kono
parents:
diff changeset
691 int
kono
parents:
diff changeset
692 __gnat_backtrace (void **array ATTRIBUTE_UNUSED,
kono
parents:
diff changeset
693 int size ATTRIBUTE_UNUSED,
kono
parents:
diff changeset
694 void *exclude_min ATTRIBUTE_UNUSED,
kono
parents:
diff changeset
695 void *exclude_max ATTRIBUTE_UNUSED,
kono
parents:
diff changeset
696 int skip_frames ATTRIBUTE_UNUSED)
kono
parents:
diff changeset
697 {
kono
parents:
diff changeset
698 return 0;
kono
parents:
diff changeset
699 }
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 #endif
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 #endif
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 #ifdef __cplusplus
kono
parents:
diff changeset
706 }
kono
parents:
diff changeset
707 #endif