xref: /freebsd/contrib/llvm-project/libunwind/src/libunwind.cpp (revision 1f1e2261e341e6ca6862f82261066ef1705f0a7a)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //
8 //  Implements unw_* functions from <libunwind.h>
9 //
10 //===----------------------------------------------------------------------===//
11 
12 #include <libunwind.h>
13 
14 #include "config.h"
15 #include "libunwind_ext.h"
16 
17 #include <stdlib.h>
18 
19 // Define the __has_feature extension for compilers that do not support it so
20 // that we can later check for the presence of ASan in a compiler-neutral way.
21 #if !defined(__has_feature)
22 #define __has_feature(feature) 0
23 #endif
24 
25 #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
26 #include <sanitizer/asan_interface.h>
27 #endif
28 
29 #if !defined(__USING_SJLJ_EXCEPTIONS__)
30 #include "AddressSpace.hpp"
31 #include "UnwindCursor.hpp"
32 
33 using namespace libunwind;
34 
35 /// internal object to represent this processes address space
36 LocalAddressSpace LocalAddressSpace::sThisAddressSpace;
37 
38 _LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
39     (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace;
40 
41 /// Create a cursor of a thread in this process given 'context' recorded by
42 /// __unw_getcontext().
43 _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
44                                        unw_context_t *context) {
45   _LIBUNWIND_TRACE_API("__unw_init_local(cursor=%p, context=%p)",
46                        static_cast<void *>(cursor),
47                        static_cast<void *>(context));
48 #if defined(__i386__)
49 # define REGISTER_KIND Registers_x86
50 #elif defined(__x86_64__)
51 # define REGISTER_KIND Registers_x86_64
52 #elif defined(__powerpc64__)
53 # define REGISTER_KIND Registers_ppc64
54 #elif defined(__powerpc__)
55 # define REGISTER_KIND Registers_ppc
56 #elif defined(__aarch64__)
57 # define REGISTER_KIND Registers_arm64
58 #elif defined(__arm__)
59 # define REGISTER_KIND Registers_arm
60 #elif defined(__or1k__)
61 # define REGISTER_KIND Registers_or1k
62 #elif defined(__hexagon__)
63 # define REGISTER_KIND Registers_hexagon
64 #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
65 # define REGISTER_KIND Registers_mips_o32
66 #elif defined(__mips64)
67 # define REGISTER_KIND Registers_mips_newabi
68 #elif defined(__mips__)
69 # warning The MIPS architecture is not supported with this ABI and environment!
70 #elif defined(__sparc__) && defined(__arch64__)
71 #define REGISTER_KIND Registers_sparc64
72 #elif defined(__sparc__)
73 # define REGISTER_KIND Registers_sparc
74 #elif defined(__riscv)
75 # define REGISTER_KIND Registers_riscv
76 #elif defined(__ve__)
77 # define REGISTER_KIND Registers_ve
78 #else
79 # error Architecture not supported
80 #endif
81   // Use "placement new" to allocate UnwindCursor in the cursor buffer.
82   new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor))
83       UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
84           context, LocalAddressSpace::sThisAddressSpace);
85 #undef REGISTER_KIND
86   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
87   co->setInfoBasedOnIPRegister();
88 
89   return UNW_ESUCCESS;
90 }
91 _LIBUNWIND_WEAK_ALIAS(__unw_init_local, unw_init_local)
92 
93 /// Get value of specified register at cursor position in stack frame.
94 _LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
95                                     unw_word_t *value) {
96   _LIBUNWIND_TRACE_API("__unw_get_reg(cursor=%p, regNum=%d, &value=%p)",
97                        static_cast<void *>(cursor), regNum,
98                        static_cast<void *>(value));
99   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
100   if (co->validReg(regNum)) {
101     *value = co->getReg(regNum);
102     return UNW_ESUCCESS;
103   }
104   return UNW_EBADREG;
105 }
106 _LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg)
107 
108 /// Set value of specified register at cursor position in stack frame.
109 _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
110                                     unw_word_t value) {
111   _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR
112                        ")",
113                        static_cast<void *>(cursor), regNum, value);
114   typedef LocalAddressSpace::pint_t pint_t;
115   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
116   if (co->validReg(regNum)) {
117     co->setReg(regNum, (pint_t)value);
118     // specical case altering IP to re-find info (being called by personality
119     // function)
120     if (regNum == UNW_REG_IP) {
121       unw_proc_info_t info;
122       // First, get the FDE for the old location and then update it.
123       co->getInfo(&info);
124       co->setInfoBasedOnIPRegister(false);
125       // If the original call expects stack adjustment, perform this now.
126       // Normal frame unwinding would have included the offset already in the
127       // CFA computation.
128       // Note: for PA-RISC and other platforms where the stack grows up,
129       // this should actually be - info.gp. LLVM doesn't currently support
130       // any such platforms and Clang doesn't export a macro for them.
131       if (info.gp)
132         co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp);
133     }
134     return UNW_ESUCCESS;
135   }
136   return UNW_EBADREG;
137 }
138 _LIBUNWIND_WEAK_ALIAS(__unw_set_reg, unw_set_reg)
139 
140 /// Get value of specified float register at cursor position in stack frame.
141 _LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
142                                       unw_fpreg_t *value) {
143   _LIBUNWIND_TRACE_API("__unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)",
144                        static_cast<void *>(cursor), regNum,
145                        static_cast<void *>(value));
146   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
147   if (co->validFloatReg(regNum)) {
148     *value = co->getFloatReg(regNum);
149     return UNW_ESUCCESS;
150   }
151   return UNW_EBADREG;
152 }
153 _LIBUNWIND_WEAK_ALIAS(__unw_get_fpreg, unw_get_fpreg)
154 
155 /// Set value of specified float register at cursor position in stack frame.
156 _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
157                                       unw_fpreg_t value) {
158 #if defined(_LIBUNWIND_ARM_EHABI)
159   _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)",
160                        static_cast<void *>(cursor), regNum, value);
161 #else
162   _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%g)",
163                        static_cast<void *>(cursor), regNum, value);
164 #endif
165   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
166   if (co->validFloatReg(regNum)) {
167     co->setFloatReg(regNum, value);
168     return UNW_ESUCCESS;
169   }
170   return UNW_EBADREG;
171 }
172 _LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg)
173 
174 /// Move cursor to next frame.
175 _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) {
176   _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast<void *>(cursor));
177   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
178   return co->step();
179 }
180 _LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step)
181 
182 /// Get unwind info at cursor position in stack frame.
183 _LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor,
184                                           unw_proc_info_t *info) {
185   _LIBUNWIND_TRACE_API("__unw_get_proc_info(cursor=%p, &info=%p)",
186                        static_cast<void *>(cursor), static_cast<void *>(info));
187   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
188   co->getInfo(info);
189   if (info->end_ip == 0)
190     return UNW_ENOINFO;
191   return UNW_ESUCCESS;
192 }
193 _LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info)
194 
195 /// Resume execution at cursor position (aka longjump).
196 _LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) {
197   _LIBUNWIND_TRACE_API("__unw_resume(cursor=%p)", static_cast<void *>(cursor));
198 #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
199   // Inform the ASan runtime that now might be a good time to clean stuff up.
200   __asan_handle_no_return();
201 #endif
202   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
203   co->jumpto();
204   return UNW_EUNSPEC;
205 }
206 _LIBUNWIND_WEAK_ALIAS(__unw_resume, unw_resume)
207 
208 /// Get name of function at cursor position in stack frame.
209 _LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf,
210                                           size_t bufLen, unw_word_t *offset) {
211   _LIBUNWIND_TRACE_API("__unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)",
212                        static_cast<void *>(cursor), static_cast<void *>(buf),
213                        static_cast<unsigned long>(bufLen));
214   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
215   if (co->getFunctionName(buf, bufLen, offset))
216     return UNW_ESUCCESS;
217   return UNW_EUNSPEC;
218 }
219 _LIBUNWIND_WEAK_ALIAS(__unw_get_proc_name, unw_get_proc_name)
220 
221 /// Checks if a register is a floating-point register.
222 _LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor,
223                                      unw_regnum_t regNum) {
224   _LIBUNWIND_TRACE_API("__unw_is_fpreg(cursor=%p, regNum=%d)",
225                        static_cast<void *>(cursor), regNum);
226   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
227   return co->validFloatReg(regNum);
228 }
229 _LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg)
230 
231 /// Checks if a register is a floating-point register.
232 _LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor,
233                                             unw_regnum_t regNum) {
234   _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)",
235                        static_cast<void *>(cursor), regNum);
236   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
237   return co->getRegisterName(regNum);
238 }
239 _LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname)
240 
241 /// Checks if current frame is signal trampoline.
242 _LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) {
243   _LIBUNWIND_TRACE_API("__unw_is_signal_frame(cursor=%p)",
244                        static_cast<void *>(cursor));
245   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
246   return co->isSignalFrame();
247 }
248 _LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame)
249 
250 #ifdef __arm__
251 // Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
252 _LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) {
253   _LIBUNWIND_TRACE_API("__unw_get_fpreg_save_vfp_as_X(cursor=%p)",
254                        static_cast<void *>(cursor));
255   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
256   return co->saveVFPAsX();
257 }
258 _LIBUNWIND_WEAK_ALIAS(__unw_save_vfp_as_X, unw_save_vfp_as_X)
259 #endif
260 
261 
262 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
263 /// SPI: walks cached DWARF entries
264 _LIBUNWIND_HIDDEN void __unw_iterate_dwarf_unwind_cache(void (*func)(
265     unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
266   _LIBUNWIND_TRACE_API("__unw_iterate_dwarf_unwind_cache(func=%p)",
267                        reinterpret_cast<void *>(func));
268   DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
269 }
270 _LIBUNWIND_WEAK_ALIAS(__unw_iterate_dwarf_unwind_cache,
271                       unw_iterate_dwarf_unwind_cache)
272 
273 /// IPI: for __register_frame()
274 void __unw_add_dynamic_fde(unw_word_t fde) {
275   CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
276   CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
277   const char *message = CFI_Parser<LocalAddressSpace>::decodeFDE(
278                            LocalAddressSpace::sThisAddressSpace,
279                           (LocalAddressSpace::pint_t) fde, &fdeInfo, &cieInfo);
280   if (message == NULL) {
281     // dynamically registered FDEs don't have a mach_header group they are in.
282     // Use fde as mh_group
283     unw_word_t mh_group = fdeInfo.fdeStart;
284     DwarfFDECache<LocalAddressSpace>::add((LocalAddressSpace::pint_t)mh_group,
285                                           fdeInfo.pcStart, fdeInfo.pcEnd,
286                                           fdeInfo.fdeStart);
287   } else {
288     _LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message);
289   }
290 }
291 
292 /// IPI: for __deregister_frame()
293 void __unw_remove_dynamic_fde(unw_word_t fde) {
294   // fde is own mh_group
295   DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde);
296 }
297 
298 void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
299   // The eh_frame section start serves as the mh_group
300   unw_word_t mh_group = eh_frame_start;
301   CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
302   CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
303   auto p = (LocalAddressSpace::pint_t)eh_frame_start;
304   while (true) {
305     if (CFI_Parser<LocalAddressSpace>::decodeFDE(
306             LocalAddressSpace::sThisAddressSpace, p, &fdeInfo, &cieInfo,
307             true) == NULL) {
308       DwarfFDECache<LocalAddressSpace>::add((LocalAddressSpace::pint_t)mh_group,
309                                             fdeInfo.pcStart, fdeInfo.pcEnd,
310                                             fdeInfo.fdeStart);
311       p += fdeInfo.fdeLength;
312     } else if (CFI_Parser<LocalAddressSpace>::parseCIE(
313                    LocalAddressSpace::sThisAddressSpace, p, &cieInfo) == NULL) {
314       p += cieInfo.cieLength;
315     } else
316       return;
317   }
318 }
319 
320 void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
321   // The eh_frame section start serves as the mh_group
322   DwarfFDECache<LocalAddressSpace>::removeAllIn(
323       (LocalAddressSpace::pint_t)eh_frame_start);
324 }
325 
326 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
327 #endif // !defined(__USING_SJLJ_EXCEPTIONS__)
328 
329 
330 
331 // Add logging hooks in Debug builds only
332 #ifndef NDEBUG
333 #include <stdlib.h>
334 
335 _LIBUNWIND_HIDDEN
336 bool logAPIs() {
337   // do manual lock to avoid use of _cxa_guard_acquire or initializers
338   static bool checked = false;
339   static bool log = false;
340   if (!checked) {
341     log = (getenv("LIBUNWIND_PRINT_APIS") != NULL);
342     checked = true;
343   }
344   return log;
345 }
346 
347 _LIBUNWIND_HIDDEN
348 bool logUnwinding() {
349   // do manual lock to avoid use of _cxa_guard_acquire or initializers
350   static bool checked = false;
351   static bool log = false;
352   if (!checked) {
353     log = (getenv("LIBUNWIND_PRINT_UNWINDING") != NULL);
354     checked = true;
355   }
356   return log;
357 }
358 
359 _LIBUNWIND_HIDDEN
360 bool logDWARF() {
361   // do manual lock to avoid use of _cxa_guard_acquire or initializers
362   static bool checked = false;
363   static bool log = false;
364   if (!checked) {
365     log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL);
366     checked = true;
367   }
368   return log;
369 }
370 
371 #endif // NDEBUG
372 
373