1 | /* internal.h -- Internal header file for stack backtrace library. |
2 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
3 | Written by Ian Lance Taylor, Google. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are |
7 | met: |
8 | |
9 | (1) Redistributions of source code must retain the above copyright |
10 | notice, this list of conditions and the following disclaimer. |
11 | |
12 | (2) Redistributions in binary form must reproduce the above copyright |
13 | notice, this list of conditions and the following disclaimer in |
14 | the documentation and/or other materials provided with the |
15 | distribution. |
16 | |
17 | (3) The name of the author may not be used to |
18 | endorse or promote products derived from this software without |
19 | specific prior written permission. |
20 | |
21 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
22 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
24 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
25 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
28 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
29 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
30 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 | POSSIBILITY OF SUCH DAMAGE. */ |
32 | |
33 | #ifndef BACKTRACE_INTERNAL_H |
34 | #define BACKTRACE_INTERNAL_H |
35 | |
36 | /* We assume that <sys/types.h> and "backtrace.h" have already been |
37 | included. */ |
38 | |
39 | #ifndef GCC_VERSION |
40 | # define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) |
41 | #endif |
42 | |
43 | #if (GCC_VERSION < 2007) |
44 | # define __attribute__(x) |
45 | #endif |
46 | |
47 | #ifndef ATTRIBUTE_UNUSED |
48 | # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) |
49 | #endif |
50 | |
51 | #ifndef ATTRIBUTE_MALLOC |
52 | # if (GCC_VERSION >= 2096) |
53 | # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) |
54 | # else |
55 | # define ATTRIBUTE_MALLOC |
56 | # endif |
57 | #endif |
58 | |
59 | #ifdef __has_attribute |
60 | # if __has_attribute(fallthrough) |
61 | # define ATTRIBUTE_FALLTHROUGH __attribute__ ((fallthrough)) |
62 | # endif |
63 | #endif |
64 | #ifndef ATTRIBUTE_FALLTHROUGH |
65 | # if (GCC_VERSION >= 7000) |
66 | # define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__)) |
67 | # else |
68 | # define ATTRIBUTE_FALLTHROUGH |
69 | # endif |
70 | #endif |
71 | |
72 | #ifndef HAVE_SYNC_FUNCTIONS |
73 | |
74 | /* Define out the sync functions. These should never be called if |
75 | they are not available. */ |
76 | |
77 | #define __sync_bool_compare_and_swap(A, B, C) (abort(), 1) |
78 | #define __sync_lock_test_and_set(A, B) (abort(), 0) |
79 | #define __sync_lock_release(A) abort() |
80 | |
81 | #endif /* !defined (HAVE_SYNC_FUNCTIONS) */ |
82 | |
83 | #ifdef HAVE_ATOMIC_FUNCTIONS |
84 | |
85 | /* We have the atomic builtin functions. */ |
86 | |
87 | #define backtrace_atomic_load_pointer(p) \ |
88 | __atomic_load_n ((p), __ATOMIC_ACQUIRE) |
89 | #define backtrace_atomic_load_int(p) \ |
90 | __atomic_load_n ((p), __ATOMIC_ACQUIRE) |
91 | #define backtrace_atomic_store_pointer(p, v) \ |
92 | __atomic_store_n ((p), (v), __ATOMIC_RELEASE) |
93 | #define backtrace_atomic_store_size_t(p, v) \ |
94 | __atomic_store_n ((p), (v), __ATOMIC_RELEASE) |
95 | #define backtrace_atomic_store_int(p, v) \ |
96 | __atomic_store_n ((p), (v), __ATOMIC_RELEASE) |
97 | |
98 | #else /* !defined (HAVE_ATOMIC_FUNCTIONS) */ |
99 | #ifdef HAVE_SYNC_FUNCTIONS |
100 | |
101 | /* We have the sync functions but not the atomic functions. Define |
102 | the atomic ones in terms of the sync ones. */ |
103 | |
104 | extern void *backtrace_atomic_load_pointer (void *); |
105 | extern int backtrace_atomic_load_int (int *); |
106 | extern void backtrace_atomic_store_pointer (void *, void *); |
107 | extern void backtrace_atomic_store_size_t (size_t *, size_t); |
108 | extern void backtrace_atomic_store_int (int *, int); |
109 | |
110 | #else /* !defined (HAVE_SYNC_FUNCTIONS) */ |
111 | |
112 | /* We have neither the sync nor the atomic functions. These will |
113 | never be called. */ |
114 | |
115 | #define backtrace_atomic_load_pointer(p) (abort(), (void *) NULL) |
116 | #define backtrace_atomic_load_int(p) (abort(), 0) |
117 | #define backtrace_atomic_store_pointer(p, v) abort() |
118 | #define backtrace_atomic_store_size_t(p, v) abort() |
119 | #define backtrace_atomic_store_int(p, v) abort() |
120 | |
121 | #endif /* !defined (HAVE_SYNC_FUNCTIONS) */ |
122 | #endif /* !defined (HAVE_ATOMIC_FUNCTIONS) */ |
123 | |
124 | /* The type of the function that collects file/line information. This |
125 | is like backtrace_pcinfo. */ |
126 | |
127 | typedef int (*fileline) (struct backtrace_state *state, uintptr_t pc, |
128 | backtrace_full_callback callback, |
129 | backtrace_error_callback error_callback, void *data); |
130 | |
131 | /* The type of the function that collects symbol information. This is |
132 | like backtrace_syminfo. */ |
133 | |
134 | typedef void (*syminfo) (struct backtrace_state *state, uintptr_t pc, |
135 | backtrace_syminfo_callback callback, |
136 | backtrace_error_callback error_callback, void *data); |
137 | |
138 | /* What the backtrace state pointer points to. */ |
139 | |
140 | struct backtrace_state |
141 | { |
142 | /* The name of the executable. */ |
143 | const char *filename; |
144 | /* Non-zero if threaded. */ |
145 | int threaded; |
146 | /* The master lock for fileline_fn, fileline_data, syminfo_fn, |
147 | syminfo_data, fileline_initialization_failed and everything the |
148 | data pointers point to. */ |
149 | void *lock; |
150 | /* The function that returns file/line information. */ |
151 | fileline fileline_fn; |
152 | /* The data to pass to FILELINE_FN. */ |
153 | void *fileline_data; |
154 | /* The function that returns symbol information. */ |
155 | syminfo syminfo_fn; |
156 | /* The data to pass to SYMINFO_FN. */ |
157 | void *syminfo_data; |
158 | /* Whether initializing the file/line information failed. */ |
159 | int fileline_initialization_failed; |
160 | /* The lock for the freelist. */ |
161 | int lock_alloc; |
162 | /* The freelist when using mmap. */ |
163 | struct backtrace_freelist_struct *freelist; |
164 | }; |
165 | |
166 | /* Open a file for reading. Returns -1 on error. If DOES_NOT_EXIST |
167 | is not NULL, *DOES_NOT_EXIST will be set to 0 normally and set to 1 |
168 | if the file does not exist. If the file does not exist and |
169 | DOES_NOT_EXIST is not NULL, the function will return -1 and will |
170 | not call ERROR_CALLBACK. On other errors, or if DOES_NOT_EXIST is |
171 | NULL, the function will call ERROR_CALLBACK before returning. */ |
172 | extern int backtrace_open (const char *filename, |
173 | backtrace_error_callback error_callback, |
174 | void *data, |
175 | int *does_not_exist); |
176 | |
177 | /* A view of the contents of a file. This supports mmap when |
178 | available. A view will remain in memory even after backtrace_close |
179 | is called on the file descriptor from which the view was |
180 | obtained. */ |
181 | |
182 | struct backtrace_view |
183 | { |
184 | /* The data that the caller requested. */ |
185 | const void *data; |
186 | /* The base of the view. */ |
187 | void *base; |
188 | /* The total length of the view. */ |
189 | size_t len; |
190 | }; |
191 | |
192 | /* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. Store the |
193 | result in *VIEW. Returns 1 on success, 0 on error. */ |
194 | extern int backtrace_get_view (struct backtrace_state *state, int descriptor, |
195 | off_t offset, uint64_t size, |
196 | backtrace_error_callback error_callback, |
197 | void *data, struct backtrace_view *view); |
198 | |
199 | /* Release a view created by backtrace_get_view. */ |
200 | extern void backtrace_release_view (struct backtrace_state *state, |
201 | struct backtrace_view *view, |
202 | backtrace_error_callback error_callback, |
203 | void *data); |
204 | |
205 | /* Close a file opened by backtrace_open. Returns 1 on success, 0 on |
206 | error. */ |
207 | |
208 | extern int backtrace_close (int descriptor, |
209 | backtrace_error_callback error_callback, |
210 | void *data); |
211 | |
212 | /* Sort without using memory. */ |
213 | |
214 | extern void backtrace_qsort (void *base, size_t count, size_t size, |
215 | int (*compar) (const void *, const void *)); |
216 | |
217 | /* Allocate memory. This is like malloc. If ERROR_CALLBACK is NULL, |
218 | this does not report an error, it just returns NULL. */ |
219 | |
220 | extern void *backtrace_alloc (struct backtrace_state *state, size_t size, |
221 | backtrace_error_callback error_callback, |
222 | void *data) ATTRIBUTE_MALLOC; |
223 | |
224 | /* Free memory allocated by backtrace_alloc. If ERROR_CALLBACK is |
225 | NULL, this does not report an error. */ |
226 | |
227 | extern void backtrace_free (struct backtrace_state *state, void *mem, |
228 | size_t size, |
229 | backtrace_error_callback error_callback, |
230 | void *data); |
231 | |
232 | /* A growable vector of some struct. This is used for more efficient |
233 | allocation when we don't know the final size of some group of data |
234 | that we want to represent as an array. */ |
235 | |
236 | struct backtrace_vector |
237 | { |
238 | /* The base of the vector. */ |
239 | void *base; |
240 | /* The number of bytes in the vector. */ |
241 | size_t size; |
242 | /* The number of bytes available at the current allocation. */ |
243 | size_t alc; |
244 | }; |
245 | |
246 | /* Grow VEC by SIZE bytes. Return a pointer to the newly allocated |
247 | bytes. Note that this may move the entire vector to a new memory |
248 | location. Returns NULL on failure. */ |
249 | |
250 | extern void *backtrace_vector_grow (struct backtrace_state *state, size_t size, |
251 | backtrace_error_callback error_callback, |
252 | void *data, |
253 | struct backtrace_vector *vec); |
254 | |
255 | /* Finish the current allocation on VEC. Prepare to start a new |
256 | allocation. The finished allocation will never be freed. Returns |
257 | a pointer to the base of the finished entries, or NULL on |
258 | failure. */ |
259 | |
260 | extern void* backtrace_vector_finish (struct backtrace_state *state, |
261 | struct backtrace_vector *vec, |
262 | backtrace_error_callback error_callback, |
263 | void *data); |
264 | |
265 | /* Release any extra space allocated for VEC. This may change |
266 | VEC->base. Returns 1 on success, 0 on failure. */ |
267 | |
268 | extern int backtrace_vector_release (struct backtrace_state *state, |
269 | struct backtrace_vector *vec, |
270 | backtrace_error_callback error_callback, |
271 | void *data); |
272 | |
273 | /* Free the space managed by VEC. This will reset VEC. */ |
274 | |
275 | static inline void |
276 | backtrace_vector_free (struct backtrace_state *state, |
277 | struct backtrace_vector *vec, |
278 | backtrace_error_callback error_callback, void *data) |
279 | { |
280 | vec->alc += vec->size; |
281 | vec->size = 0; |
282 | backtrace_vector_release (state, vec, error_callback, data); |
283 | } |
284 | |
285 | /* Read initial debug data from a descriptor, and set the |
286 | fileline_data, syminfo_fn, and syminfo_data fields of STATE. |
287 | Return the fileln_fn field in *FILELN_FN--this is done this way so |
288 | that the synchronization code is only implemented once. This is |
289 | called after the descriptor has first been opened. It will close |
290 | the descriptor if it is no longer needed. Returns 1 on success, 0 |
291 | on error. There will be multiple implementations of this function, |
292 | for different file formats. Each system will compile the |
293 | appropriate one. */ |
294 | |
295 | extern int backtrace_initialize (struct backtrace_state *state, |
296 | const char *filename, |
297 | int descriptor, |
298 | backtrace_error_callback error_callback, |
299 | void *data, |
300 | fileline *fileline_fn); |
301 | |
302 | /* An enum for the DWARF sections we care about. */ |
303 | |
304 | enum dwarf_section |
305 | { |
306 | DEBUG_INFO, |
307 | DEBUG_LINE, |
308 | DEBUG_ABBREV, |
309 | DEBUG_RANGES, |
310 | DEBUG_STR, |
311 | DEBUG_ADDR, |
312 | DEBUG_STR_OFFSETS, |
313 | DEBUG_LINE_STR, |
314 | DEBUG_RNGLISTS, |
315 | |
316 | DEBUG_MAX |
317 | }; |
318 | |
319 | /* Data for the DWARF sections we care about. */ |
320 | |
321 | struct dwarf_sections |
322 | { |
323 | const unsigned char *data[DEBUG_MAX]; |
324 | size_t size[DEBUG_MAX]; |
325 | }; |
326 | |
327 | /* DWARF data read from a file, used for .gnu_debugaltlink. */ |
328 | |
329 | struct dwarf_data; |
330 | |
331 | /* The load address mapping. */ |
332 | |
333 | #if defined(__FDPIC__) && defined(HAVE_DL_ITERATE_PHDR) && (defined(HAVE_LINK_H) || defined(HAVE_SYS_LINK_H)) |
334 | |
335 | #ifdef HAVE_LINK_H |
336 | #include <link.h> |
337 | #endif |
338 | #ifdef HAVE_SYS_LINK_H |
339 | #include <sys/link.h> |
340 | #endif |
341 | |
342 | #define libbacktrace_using_fdpic() (1) |
343 | |
344 | struct libbacktrace_base_address |
345 | { |
346 | struct elf32_fdpic_loadaddr m; |
347 | }; |
348 | |
349 | #define libbacktrace_add_base(pc, base) \ |
350 | ((uintptr_t) (__RELOC_POINTER ((pc), (base).m))) |
351 | |
352 | #else /* not _FDPIC__ */ |
353 | |
354 | #define libbacktrace_using_fdpic() (0) |
355 | |
356 | struct libbacktrace_base_address |
357 | { |
358 | uintptr_t m; |
359 | }; |
360 | |
361 | #define libbacktrace_add_base(pc, base) ((pc) + (base).m) |
362 | |
363 | #endif /* not _FDPIC__ */ |
364 | |
365 | /* Add file/line information for a DWARF module. */ |
366 | |
367 | extern int backtrace_dwarf_add (struct backtrace_state *state, |
368 | struct libbacktrace_base_address base_address, |
369 | const struct dwarf_sections *dwarf_sections, |
370 | int is_bigendian, |
371 | struct dwarf_data *fileline_altlink, |
372 | backtrace_error_callback error_callback, |
373 | void *data, fileline *fileline_fn, |
374 | struct dwarf_data **fileline_entry); |
375 | |
376 | /* A data structure to pass to backtrace_syminfo_to_full. */ |
377 | |
378 | struct backtrace_call_full |
379 | { |
380 | backtrace_full_callback full_callback; |
381 | backtrace_error_callback full_error_callback; |
382 | void *full_data; |
383 | int ret; |
384 | }; |
385 | |
386 | /* A backtrace_syminfo_callback that can call into a |
387 | backtrace_full_callback, used when we have a symbol table but no |
388 | debug info. */ |
389 | |
390 | extern void backtrace_syminfo_to_full_callback (void *data, uintptr_t pc, |
391 | const char *symname, |
392 | uintptr_t symval, |
393 | uintptr_t symsize); |
394 | |
395 | /* An error callback that corresponds to |
396 | backtrace_syminfo_to_full_callback. */ |
397 | |
398 | extern void backtrace_syminfo_to_full_error_callback (void *, const char *, |
399 | int); |
400 | |
401 | /* A test-only hook for elf_uncompress_zdebug. */ |
402 | |
403 | extern int backtrace_uncompress_zdebug (struct backtrace_state *, |
404 | const unsigned char *compressed, |
405 | size_t compressed_size, |
406 | backtrace_error_callback, void *data, |
407 | unsigned char **uncompressed, |
408 | size_t *uncompressed_size); |
409 | |
410 | /* A test-only hook for elf_zstd_decompress. */ |
411 | |
412 | extern int backtrace_uncompress_zstd (struct backtrace_state *, |
413 | const unsigned char *compressed, |
414 | size_t compressed_size, |
415 | backtrace_error_callback, void *data, |
416 | unsigned char *uncompressed, |
417 | size_t uncompressed_size); |
418 | |
419 | /* A test-only hook for elf_uncompress_lzma. */ |
420 | |
421 | extern int backtrace_uncompress_lzma (struct backtrace_state *, |
422 | const unsigned char *compressed, |
423 | size_t compressed_size, |
424 | backtrace_error_callback, void *data, |
425 | unsigned char **uncompressed, |
426 | size_t *uncompressed_size); |
427 | |
428 | #endif |
429 | |