annotate gcc/ada/tracebak.c @ 131:84e7813d76e9

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