1 //===--------------------------- libunwind.cpp ----------------------------===//
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 #ifndef NDEBUG
15 #include <cstdlib> // getenv
16 #endif
17 #include <new>
18 #include <algorithm>
19 
20 #include "libunwind_ext.h"
21 #include "config.h"
22 
23 #include <stdlib.h>
24 
25 
26 #if !defined(__USING_SJLJ_EXCEPTIONS__)
27 #include "AddressSpace.hpp"
28 #include "UnwindCursor.hpp"
29 
30 using namespace libunwind;
31 
32 /// internal object to represent this processes address space
33 LocalAddressSpace LocalAddressSpace::sThisAddressSpace;
34 
35 _LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
36     (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace;
37 
38 /// record the registers and stack position of the caller
39 extern int unw_getcontext(unw_context_t *);
40 // note: unw_getcontext() implemented in assembly
41 
42 /// Create a cursor of a thread in this process given 'context' recorded by
43 /// unw_getcontext().
44 _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
45                                      unw_context_t *context) {
46   _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)",
47                        static_cast<void *>(cursor),
48                        static_cast<void *>(context));
49 #if defined(__i386__)
50 # define REGISTER_KIND Registers_x86
51 #elif defined(__x86_64__)
52 # define REGISTER_KIND Registers_x86_64
53 #elif defined(__powerpc64__)
54 # define REGISTER_KIND Registers_ppc64
55 #elif defined(__ppc__)
56 # define REGISTER_KIND Registers_ppc
57 #elif defined(__aarch64__)
58 # define REGISTER_KIND Registers_arm64
59 #elif defined(__arm__)
60 # define REGISTER_KIND Registers_arm
61 #elif defined(__or1k__)
62 # define REGISTER_KIND Registers_or1k
63 #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
64 # define REGISTER_KIND Registers_mips_o32
65 #elif defined(__mips64)
66 # define REGISTER_KIND Registers_mips_newabi
67 #elif defined(__mips__)
68 # warning The MIPS architecture is not supported with this ABI and environment!
69 #elif defined(__sparc__)
70 # define REGISTER_KIND Registers_sparc
71 #else
72 # error Architecture not supported
73 #endif
74   // Use "placement new" to allocate UnwindCursor in the cursor buffer.
75   new ((void *)cursor) UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
76                                  context, LocalAddressSpace::sThisAddressSpace);
77 #undef REGISTER_KIND
78   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
79   co->setInfoBasedOnIPRegister();
80 
81   return UNW_ESUCCESS;
82 }
83 
84 #ifdef UNW_REMOTE
85 /// Create a cursor into a thread in another process.
86 _LIBUNWIND_EXPORT int unw_init_remote_thread(unw_cursor_t *cursor,
87                                              unw_addr_space_t as,
88                                              void *arg) {
89   // special case: unw_init_remote(xx, unw_local_addr_space, xx)
90   if (as == (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace)
91     return unw_init_local(cursor, NULL); //FIXME
92 
93   // use "placement new" to allocate UnwindCursor in the cursor buffer
94   switch (as->cpuType) {
95   case CPU_TYPE_I386:
96     new ((void *)cursor)
97         UnwindCursor<RemoteAddressSpace<Pointer32<LittleEndian>>,
98                      Registers_x86>(((unw_addr_space_i386 *)as)->oas, arg);
99     break;
100   case CPU_TYPE_X86_64:
101     new ((void *)cursor)
102         UnwindCursor<RemoteAddressSpace<Pointer64<LittleEndian>>,
103                      Registers_x86_64>(((unw_addr_space_x86_64 *)as)->oas, arg);
104     break;
105   case CPU_TYPE_POWERPC:
106     new ((void *)cursor)
107         UnwindCursor<RemoteAddressSpace<Pointer32<BigEndian>>,
108                      Registers_ppc>(((unw_addr_space_ppc *)as)->oas, arg);
109     break;
110   default:
111     return UNW_EUNSPEC;
112   }
113   return UNW_ESUCCESS;
114 }
115 
116 
117 static bool is64bit(task_t task) {
118   return false; // FIXME
119 }
120 
121 /// Create an address_space object for use in examining another task.
122 _LIBUNWIND_EXPORT unw_addr_space_t unw_create_addr_space_for_task(task_t task) {
123 #if __i386__
124   if (is64bit(task)) {
125     unw_addr_space_x86_64 *as = new unw_addr_space_x86_64(task);
126     as->taskPort = task;
127     as->cpuType = CPU_TYPE_X86_64;
128     //as->oas
129   } else {
130     unw_addr_space_i386 *as = new unw_addr_space_i386(task);
131     as->taskPort = task;
132     as->cpuType = CPU_TYPE_I386;
133     //as->oas
134   }
135 #else
136 // FIXME
137 #endif
138 }
139 
140 
141 /// Delete an address_space object.
142 _LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) {
143   switch (asp->cpuType) {
144 #if __i386__ || __x86_64__
145   case CPU_TYPE_I386: {
146     unw_addr_space_i386 *as = (unw_addr_space_i386 *)asp;
147     delete as;
148   }
149   break;
150   case CPU_TYPE_X86_64: {
151     unw_addr_space_x86_64 *as = (unw_addr_space_x86_64 *)asp;
152     delete as;
153   }
154   break;
155 #endif
156   case CPU_TYPE_POWERPC: {
157     unw_addr_space_ppc *as = (unw_addr_space_ppc *)asp;
158     delete as;
159   }
160   break;
161   }
162 }
163 #endif // UNW_REMOTE
164 
165 
166 /// Get value of specified register at cursor position in stack frame.
167 _LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
168                                   unw_word_t *value) {
169   _LIBUNWIND_TRACE_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)",
170                        static_cast<void *>(cursor), regNum,
171                        static_cast<void *>(value));
172   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
173   if (co->validReg(regNum)) {
174     *value = co->getReg(regNum);
175     return UNW_ESUCCESS;
176   }
177   return UNW_EBADREG;
178 }
179 
180 
181 /// Set value of specified register at cursor position in stack frame.
182 _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
183                                   unw_word_t value) {
184   _LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR ")",
185                        static_cast<void *>(cursor), regNum, value);
186   typedef LocalAddressSpace::pint_t pint_t;
187   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
188   if (co->validReg(regNum)) {
189     co->setReg(regNum, (pint_t)value);
190     // specical case altering IP to re-find info (being called by personality
191     // function)
192     if (regNum == UNW_REG_IP) {
193       unw_proc_info_t info;
194       // First, get the FDE for the old location and then update it.
195       co->getInfo(&info);
196       co->setInfoBasedOnIPRegister(false);
197       // If the original call expects stack adjustment, perform this now.
198       // Normal frame unwinding would have included the offset already in the
199       // CFA computation.
200       // Note: for PA-RISC and other platforms where the stack grows up,
201       // this should actually be - info.gp. LLVM doesn't currently support
202       // any such platforms and Clang doesn't export a macro for them.
203       if (info.gp)
204         co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp);
205     }
206     return UNW_ESUCCESS;
207   }
208   return UNW_EBADREG;
209 }
210 
211 
212 /// Get value of specified float register at cursor position in stack frame.
213 _LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
214                                     unw_fpreg_t *value) {
215   _LIBUNWIND_TRACE_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)",
216                        static_cast<void *>(cursor), regNum,
217                        static_cast<void *>(value));
218   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
219   if (co->validFloatReg(regNum)) {
220     *value = co->getFloatReg(regNum);
221     return UNW_ESUCCESS;
222   }
223   return UNW_EBADREG;
224 }
225 
226 
227 /// Set value of specified float register at cursor position in stack frame.
228 _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
229                                     unw_fpreg_t value) {
230 #if defined(_LIBUNWIND_ARM_EHABI)
231   _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)",
232                        static_cast<void *>(cursor), regNum, value);
233 #else
234   _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)",
235                        static_cast<void *>(cursor), regNum, value);
236 #endif
237   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
238   if (co->validFloatReg(regNum)) {
239     co->setFloatReg(regNum, value);
240     return UNW_ESUCCESS;
241   }
242   return UNW_EBADREG;
243 }
244 
245 
246 /// Move cursor to next frame.
247 _LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) {
248   _LIBUNWIND_TRACE_API("unw_step(cursor=%p)", static_cast<void *>(cursor));
249   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
250   return co->step();
251 }
252 
253 
254 /// Get unwind info at cursor position in stack frame.
255 _LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor,
256                                         unw_proc_info_t *info) {
257   _LIBUNWIND_TRACE_API("unw_get_proc_info(cursor=%p, &info=%p)",
258                        static_cast<void *>(cursor), static_cast<void *>(info));
259   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
260   co->getInfo(info);
261   if (info->end_ip == 0)
262     return UNW_ENOINFO;
263   else
264     return UNW_ESUCCESS;
265 }
266 
267 
268 /// Resume execution at cursor position (aka longjump).
269 _LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) {
270   _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)", static_cast<void *>(cursor));
271   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
272   co->jumpto();
273   return UNW_EUNSPEC;
274 }
275 
276 
277 /// Get name of function at cursor position in stack frame.
278 _LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf,
279                                         size_t bufLen, unw_word_t *offset) {
280   _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)",
281                        static_cast<void *>(cursor), static_cast<void *>(buf),
282                        static_cast<unsigned long>(bufLen));
283   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
284   if (co->getFunctionName(buf, bufLen, offset))
285     return UNW_ESUCCESS;
286   else
287     return UNW_EUNSPEC;
288 }
289 
290 
291 /// Checks if a register is a floating-point register.
292 _LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) {
293   _LIBUNWIND_TRACE_API("unw_is_fpreg(cursor=%p, regNum=%d)",
294                        static_cast<void *>(cursor), regNum);
295   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
296   return co->validFloatReg(regNum);
297 }
298 
299 
300 /// Checks if a register is a floating-point register.
301 _LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor,
302                                           unw_regnum_t regNum) {
303   _LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)",
304                        static_cast<void *>(cursor), regNum);
305   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
306   return co->getRegisterName(regNum);
307 }
308 
309 
310 /// Checks if current frame is signal trampoline.
311 _LIBUNWIND_EXPORT int unw_is_signal_frame(unw_cursor_t *cursor) {
312   _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)",
313                        static_cast<void *>(cursor));
314   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
315   return co->isSignalFrame();
316 }
317 
318 #ifdef __arm__
319 // Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
320 _LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) {
321   _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)",
322                        static_cast<void *>(cursor));
323   AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
324   return co->saveVFPAsX();
325 }
326 #endif
327 
328 
329 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
330 /// SPI: walks cached DWARF entries
331 _LIBUNWIND_EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)(
332     unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
333   _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)",
334                        reinterpret_cast<void *>(func));
335   DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
336 }
337 
338 
339 /// IPI: for __register_frame()
340 void _unw_add_dynamic_fde(unw_word_t fde) {
341   CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
342   CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
343   const char *message = CFI_Parser<LocalAddressSpace>::decodeFDE(
344                            LocalAddressSpace::sThisAddressSpace,
345                           (LocalAddressSpace::pint_t) fde, &fdeInfo, &cieInfo);
346   if (message == NULL) {
347     // dynamically registered FDEs don't have a mach_header group they are in.
348     // Use fde as mh_group
349     unw_word_t mh_group = fdeInfo.fdeStart;
350     DwarfFDECache<LocalAddressSpace>::add((LocalAddressSpace::pint_t)mh_group,
351                                           fdeInfo.pcStart, fdeInfo.pcEnd,
352                                           fdeInfo.fdeStart);
353   } else {
354     _LIBUNWIND_DEBUG_LOG("_unw_add_dynamic_fde: bad fde: %s", message);
355   }
356 }
357 
358 /// IPI: for __deregister_frame()
359 void _unw_remove_dynamic_fde(unw_word_t fde) {
360   // fde is own mh_group
361   DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde);
362 }
363 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
364 #endif // !defined(__USING_SJLJ_EXCEPTIONS__)
365 
366 
367 
368 // Add logging hooks in Debug builds only
369 #ifndef NDEBUG
370 #include <stdlib.h>
371 
372 _LIBUNWIND_HIDDEN
373 bool logAPIs() {
374   // do manual lock to avoid use of _cxa_guard_acquire or initializers
375   static bool checked = false;
376   static bool log = false;
377   if (!checked) {
378     log = (getenv("LIBUNWIND_PRINT_APIS") != NULL);
379     checked = true;
380   }
381   return log;
382 }
383 
384 _LIBUNWIND_HIDDEN
385 bool logUnwinding() {
386   // do manual lock to avoid use of _cxa_guard_acquire or initializers
387   static bool checked = false;
388   static bool log = false;
389   if (!checked) {
390     log = (getenv("LIBUNWIND_PRINT_UNWINDING") != NULL);
391     checked = true;
392   }
393   return log;
394 }
395 
396 _LIBUNWIND_HIDDEN
397 bool logDWARF() {
398   // do manual lock to avoid use of _cxa_guard_acquire or initializers
399   static bool checked = false;
400   static bool log = false;
401   if (!checked) {
402     log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL);
403     checked = true;
404   }
405   return log;
406 }
407 
408 #endif // NDEBUG
409 
410