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