1b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===------------------------- UnwindCursor.hpp ---------------------------===// 2b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 3b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// The LLVM Compiler Infrastructure 4b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 5b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// This file is dual licensed under the MIT and the University of Illinois Open 6b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// Source Licenses. See LICENSE.TXT for details. 7b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 8b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 9b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// C++ interface to lower levels of libuwind 10b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===----------------------------------------------------------------------===// 11b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 12b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifndef __UNWINDCURSOR_HPP__ 13b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#define __UNWINDCURSOR_HPP__ 14b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 15e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include <algorithm> 16b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdint.h> 17b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdio.h> 18b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdlib.h> 19b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <pthread.h> 20e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include <unwind.h> 21b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 226dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik#if __APPLE__ 236dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik #include <mach-o/dyld.h> 246dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik#endif 256dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik 26b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "libunwind.h" 27b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 28b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "AddressSpace.hpp" 29b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "Registers.hpp" 30b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "DwarfInstructions.hpp" 31b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "CompactUnwinder.hpp" 32b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "config.h" 33b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 34b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziknamespace libunwind { 35b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 36b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 37b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Cache of recently found FDEs. 38b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 39b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass _LIBUNWIND_HIDDEN DwarfFDECache { 40b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typedef typename A::pint_t pint_t; 41b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 42b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static pint_t findFDE(pint_t mh, pint_t pc); 43b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde); 44b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static void removeAllIn(pint_t mh); 45b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static void iterateCacheEntries(void (*func)(unw_word_t ip_start, 46b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_word_t ip_end, 47b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_word_t fde, unw_word_t mh)); 48b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 49b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 50b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 51b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik struct entry { 52b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t mh; 53b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t ip_start; 54b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t ip_end; 55b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t fde; 56b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik }; 57b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 58b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // These fields are all static to avoid needing an initializer. 59b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // There is only one instance of this class per process. 60b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static pthread_rwlock_t _lock; 61b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__ 62b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide); 63b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static bool _registeredForDyldUnloads; 64b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 65b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Can't use std::vector<> here because this code is below libc++. 66b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static entry *_buffer; 67b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static entry *_bufferUsed; 68b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static entry *_bufferEnd; 69b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static entry _initialBuffer[64]; 70b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 71b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 72b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 73b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry * 74b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikDwarfFDECache<A>::_buffer = _initialBuffer; 75b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 76b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 77b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry * 78b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikDwarfFDECache<A>::_bufferUsed = _initialBuffer; 79b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 80b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 81b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry * 82b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikDwarfFDECache<A>::_bufferEnd = &_initialBuffer[64]; 83b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 84b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 85b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64]; 86b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 87b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 88b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER; 89b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 90b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__ 91b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 92b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool DwarfFDECache<A>::_registeredForDyldUnloads = false; 93b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 94b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 95b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 96b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) { 97b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t result = 0; 98b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_rdlock(&_lock)); 99b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik for (entry *p = _buffer; p < _bufferUsed; ++p) { 100b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((mh == p->mh) || (mh == 0)) { 101b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((p->ip_start <= pc) && (pc < p->ip_end)) { 102b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = p->fde; 103b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 104b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 105b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 106b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 107b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock)); 108b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return result; 109b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 110b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 111b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 112b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end, 113b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t fde) { 114b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_wrlock(&_lock)); 115b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_bufferUsed >= _bufferEnd) { 116b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik size_t oldSize = (size_t)(_bufferEnd - _buffer); 117b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik size_t newSize = oldSize * 4; 118b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Can't use operator new (we are below it). 119b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik entry *newBuffer = (entry *)malloc(newSize * sizeof(entry)); 120b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik memcpy(newBuffer, _buffer, oldSize * sizeof(entry)); 121b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_buffer != _initialBuffer) 122b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik free(_buffer); 123b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _buffer = newBuffer; 124b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _bufferUsed = &newBuffer[oldSize]; 125b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _bufferEnd = &newBuffer[newSize]; 126b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 127b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _bufferUsed->mh = mh; 128b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _bufferUsed->ip_start = ip_start; 129b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _bufferUsed->ip_end = ip_end; 130b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _bufferUsed->fde = fde; 131b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik ++_bufferUsed; 132b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__ 133b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (!_registeredForDyldUnloads) { 134b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _dyld_register_func_for_remove_image(&dyldUnloadHook); 135b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _registeredForDyldUnloads = true; 136b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 137b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 138b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock)); 139b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 140b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 141b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 142b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::removeAllIn(pint_t mh) { 143b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_wrlock(&_lock)); 144b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik entry *d = _buffer; 145b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik for (const entry *s = _buffer; s < _bufferUsed; ++s) { 146b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (s->mh != mh) { 147b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (d != s) 148b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *d = *s; 149b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik ++d; 150b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 151b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 152b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _bufferUsed = d; 153b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock)); 154b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 155b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 156e085735cbedc82b1064f05ff796e32e906a95036Dan Albert#if __APPLE__ 157b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 158b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) { 159b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik removeAllIn((pint_t) mh); 160b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 161e085735cbedc82b1064f05ff796e32e906a95036Dan Albert#endif 162b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 163b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> 164b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::iterateCacheEntries(void (*func)( 165b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) { 166b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_wrlock(&_lock)); 167b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik for (entry *p = _buffer; p < _bufferUsed; ++p) { 168b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (*func)(p->ip_start, p->ip_end, p->fde, p->mh); 169b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 170b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock)); 171b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 172b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND 173b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 174b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 175b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field)) 176b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 177b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND 178b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionHeader { 179b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 180b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionHeader(A &addressSpace, typename A::pint_t addr) 181b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(addressSpace), _addr(addr) {} 182b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 183b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t version() const { 184b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32(_addr + 185b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik offsetof(unwind_info_section_header, version)); 186b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 187b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t commonEncodingsArraySectionOffset() const { 188b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32(_addr + 189b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik offsetof(unwind_info_section_header, 190b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik commonEncodingsArraySectionOffset)); 191b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 192b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t commonEncodingsArrayCount() const { 193b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32(_addr + offsetof(unwind_info_section_header, 194b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik commonEncodingsArrayCount)); 195b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 196b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t personalityArraySectionOffset() const { 197b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32(_addr + offsetof(unwind_info_section_header, 198b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik personalityArraySectionOffset)); 199b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 200b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t personalityArrayCount() const { 201b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 202b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_section_header, personalityArrayCount)); 203b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 204b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t indexSectionOffset() const { 205b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 206b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_section_header, indexSectionOffset)); 207b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 208b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t indexCount() const { 209b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 210b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_section_header, indexCount)); 211b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 212b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 213b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 214b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 215b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename A::pint_t _addr; 216b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 217b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 218b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionIndexArray { 219b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 220b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionIndexArray(A &addressSpace, typename A::pint_t addr) 221b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(addressSpace), _addr(addr) {} 222b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 223b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t functionOffset(uint32_t index) const { 224b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 225b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + arrayoffsetof(unwind_info_section_header_index_entry, index, 226b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik functionOffset)); 227b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 228b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t secondLevelPagesSectionOffset(uint32_t index) const { 229b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 230b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + arrayoffsetof(unwind_info_section_header_index_entry, index, 231b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik secondLevelPagesSectionOffset)); 232b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 233b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t lsdaIndexArraySectionOffset(uint32_t index) const { 234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + arrayoffsetof(unwind_info_section_header_index_entry, index, 236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik lsdaIndexArraySectionOffset)); 237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 239b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 240b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename A::pint_t _addr; 242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 244b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionRegularPageHeader { 245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 246b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionRegularPageHeader(A &addressSpace, typename A::pint_t addr) 247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(addressSpace), _addr(addr) {} 248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t kind() const { 250b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_regular_second_level_page_header, kind)); 252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t entryPageOffset() const { 254b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get16( 255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_regular_second_level_page_header, 256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik entryPageOffset)); 257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t entryCount() const { 259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get16( 260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + 261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik offsetof(unwind_info_regular_second_level_page_header, entryCount)); 262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 265b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename A::pint_t _addr; 267b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 269b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionRegularArray { 270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionRegularArray(A &addressSpace, typename A::pint_t addr) 272b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(addressSpace), _addr(addr) {} 273b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 274b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t functionOffset(uint32_t index) const { 275b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 276b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + arrayoffsetof(unwind_info_regular_second_level_entry, index, 277b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik functionOffset)); 278b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 279b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t encoding(uint32_t index) const { 280b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 281b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + 282b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik arrayoffsetof(unwind_info_regular_second_level_entry, index, encoding)); 283b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 284b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 285b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 286b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 287b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename A::pint_t _addr; 288b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 289b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 290b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionCompressedPageHeader { 291b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 292b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionCompressedPageHeader(A &addressSpace, typename A::pint_t addr) 293b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(addressSpace), _addr(addr) {} 294b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 295b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t kind() const { 296b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 297b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + 298b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik offsetof(unwind_info_compressed_second_level_page_header, kind)); 299b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 300b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t entryPageOffset() const { 301b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get16( 302b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_compressed_second_level_page_header, 303b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik entryPageOffset)); 304b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 305b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t entryCount() const { 306b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get16( 307b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + 308b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik offsetof(unwind_info_compressed_second_level_page_header, entryCount)); 309b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 310b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t encodingsPageOffset() const { 311b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get16( 312b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_compressed_second_level_page_header, 313b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encodingsPageOffset)); 314b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 315b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t encodingsCount() const { 316b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get16( 317b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + offsetof(unwind_info_compressed_second_level_page_header, 318b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encodingsCount)); 319b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 320b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 321b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 322b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 323b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename A::pint_t _addr; 324b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 325b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 326b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionCompressedArray { 327b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 328b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionCompressedArray(A &addressSpace, typename A::pint_t addr) 329b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(addressSpace), _addr(addr) {} 330b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 331b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t functionOffset(uint32_t index) const { 332b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET( 333b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addressSpace.get32(_addr + index * sizeof(uint32_t))); 334b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 335b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t encodingIndex(uint32_t index) const { 336b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX( 337b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addressSpace.get32(_addr + index * sizeof(uint32_t))); 338b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 339b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 340b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 341b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 342b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename A::pint_t _addr; 343b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 344b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 345b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionLsdaArray { 346b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 347b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionLsdaArray(A &addressSpace, typename A::pint_t addr) 348b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(addressSpace), _addr(addr) {} 349b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 350b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t functionOffset(uint32_t index) const { 351b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 352b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry, 353b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik index, functionOffset)); 354b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 355b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t lsdaOffset(uint32_t index) const { 356b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.get32( 357b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry, 358b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik index, lsdaOffset)); 359b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 360b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 361b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 362b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 363b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename A::pint_t _addr; 364b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 365b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND 366b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 367b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 368b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass _LIBUNWIND_HIDDEN AbstractUnwindCursor { 369b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 370e085735cbedc82b1064f05ff796e32e906a95036Dan Albert virtual ~AbstractUnwindCursor() {} 371b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool validReg(int) = 0; 372b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual unw_word_t getReg(int) = 0; 373b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void setReg(int, unw_word_t) = 0; 374b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool validFloatReg(int) = 0; 375e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert virtual unw_fpreg_t getFloatReg(int) = 0; 376e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert virtual void setFloatReg(int, unw_fpreg_t) = 0; 377b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual int step() = 0; 378b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void getInfo(unw_proc_info_t *) = 0; 379b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void jumpto() = 0; 380b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool isSignalFrame() = 0; 381b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool getFunctionName(char *bf, size_t ln, unw_word_t *off) = 0; 382b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void setInfoBasedOnIPRegister(bool isReturnAddr = false) = 0; 383b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual const char *getRegisterName(int num) = 0; 384e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __arm__ 385e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert virtual void saveVFPAsX() = 0; 386e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 387b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 388b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 389b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 390b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// UnwindCursor contains all state (including all register values) during 391b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// an unwind. This is normally stack allocated inside a unw_cursor_t. 392b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 393b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass UnwindCursor : public AbstractUnwindCursor{ 394b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typedef typename A::pint_t pint_t; 395b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 396b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindCursor(unw_context_t *context, A &as); 3976dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik UnwindCursor(A &as, void *threadArg); 398b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual ~UnwindCursor() {} 399b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool validReg(int); 400b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual unw_word_t getReg(int); 401b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void setReg(int, unw_word_t); 402b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool validFloatReg(int); 403e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert virtual unw_fpreg_t getFloatReg(int); 404e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert virtual void setFloatReg(int, unw_fpreg_t); 405b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual int step(); 406b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void getInfo(unw_proc_info_t *); 407b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void jumpto(); 408b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool isSignalFrame(); 409b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off); 410b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false); 411b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik virtual const char *getRegisterName(int num); 412e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __arm__ 413e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert virtual void saveVFPAsX(); 414e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 415b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 416b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik void operator delete(void *, size_t) {} 417b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 418b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 419b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 420e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 421e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections §s); 422e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 423e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 424b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 425b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s, 426b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t fdeSectionOffsetHint=0); 427b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int stepWithDwarfFDE() { 428b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace, 429b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (pint_t)this->getReg(UNW_REG_IP), 430b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (pint_t)_info.unwind_info, 431b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _registers); 432b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 433b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 434b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 435b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND 436b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool getInfoFromCompactEncodingSection(pint_t pc, 437b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const UnwindInfoSections §s); 438b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int stepWithCompactEncoding() { 439b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #if _LIBUNWIND_SUPPORT_DWARF_UNWIND 440b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ( compactSaysUseDwarf() ) 441b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return stepWithDwarfFDE(); 442b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #endif 443b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik R dummy; 444b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return stepWithCompactEncoding(dummy); 445b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 446b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 447b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int stepWithCompactEncoding(Registers_x86_64 &) { 448b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return CompactUnwinder_x86_64<A>::stepWithCompactEncoding( 449b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.format, _info.start_ip, _addressSpace, _registers); 450b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 451b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 452b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int stepWithCompactEncoding(Registers_x86 &) { 453b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return CompactUnwinder_x86<A>::stepWithCompactEncoding( 454b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers); 455b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 456b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 457b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int stepWithCompactEncoding(Registers_ppc &) { 458b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNW_EINVAL; 459b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 460b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 461b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int stepWithCompactEncoding(Registers_arm64 &) { 462b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return CompactUnwinder_arm64<A>::stepWithCompactEncoding( 463b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.format, _info.start_ip, _addressSpace, _registers); 464b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 465b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 466b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool compactSaysUseDwarf(uint32_t *offset=NULL) const { 467b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik R dummy; 468b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return compactSaysUseDwarf(dummy, offset); 469b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 470b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 471b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const { 472b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) { 473b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (offset) 474b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *offset = (_info.format & UNWIND_X86_64_DWARF_SECTION_OFFSET); 475b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 476b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 477b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 478b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 479b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 480b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const { 481b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) { 482b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (offset) 483b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *offset = (_info.format & UNWIND_X86_DWARF_SECTION_OFFSET); 484b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 485b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 486b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 487b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 488b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 489b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const { 490b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 491b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 492b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 493b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const { 494b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) { 495b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (offset) 496b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *offset = (_info.format & UNWIND_ARM64_DWARF_SECTION_OFFSET); 497b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 498b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 499b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 500b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 501e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND 502b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 503e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 504b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik compact_unwind_encoding_t dwarfEncoding() const { 505b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik R dummy; 506b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return dwarfEncoding(dummy); 507b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 508b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 509b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const { 510b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNWIND_X86_64_MODE_DWARF; 511b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 512b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 513b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const { 514b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNWIND_X86_MODE_DWARF; 515b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 516b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 517b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const { 518b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return 0; 519b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 520b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 521b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const { 522b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNWIND_ARM64_MODE_DWARF; 523b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 524e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND 525b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 526b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 527b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik A &_addressSpace; 528b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik R _registers; 529b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_proc_info_t _info; 530b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool _unwindInfoMissing; 531b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool _isSignalFrame; 532b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 533b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 534b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 535b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 536b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikUnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) 537b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(as), _registers(context), _unwindInfoMissing(false), 538b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _isSignalFrame(false) { 539b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static_assert(sizeof(UnwindCursor<A, R>) < sizeof(unw_cursor_t), 540b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "UnwindCursor<> does not fit in unw_cursor_t"); 541e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memset(&_info, 0, sizeof(_info)); 542b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 543b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 544b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 5456dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick KledzikUnwindCursor<A, R>::UnwindCursor(A &as, void *) 546b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) { 547e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memset(&_info, 0, sizeof(_info)); 548b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // FIXME 5496dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik // fill in _registers from thread arg 550b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 551b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 5526dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik 553b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 554b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::validReg(int regNum) { 555b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _registers.validRegister(regNum); 556b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 557b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 558b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 559b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikunw_word_t UnwindCursor<A, R>::getReg(int regNum) { 560b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _registers.getRegister(regNum); 561b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 562b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 563b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 564b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { 565b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _registers.setRegister(regNum, (typename A::pint_t)value); 566b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 567b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 568b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 569b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::validFloatReg(int regNum) { 570b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _registers.validFloatRegister(regNum); 571b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 572b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 573b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 574e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertunw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { 575b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _registers.getFloatRegister(regNum); 576b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 577b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 578b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 579e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertvoid UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { 580b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _registers.setFloatRegister(regNum, value); 581b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 582b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 583b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> void UnwindCursor<A, R>::jumpto() { 584b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _registers.jumpto(); 585b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 586b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 587e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __arm__ 588e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttemplate <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() { 589e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _registers.saveVFPAsX(); 590e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} 591e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 592e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 593b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 594b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikconst char *UnwindCursor<A, R>::getRegisterName(int regNum) { 595b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _registers.getRegisterName(regNum); 596b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 597b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 598b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() { 599b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _isSignalFrame; 600b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 601b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 602e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 603e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstruct EHABIIndexEntry { 604e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t functionOffset; 605e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t data; 606e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}; 607e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 608e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// Unable to unwind in the ARM index table (section 5 EHABI). 609e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#define UNW_EXIDX_CANTUNWIND 0x1 610e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 611e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline uint32_t signExtendPrel31(uint32_t data) { 612e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return data | ((data & 0x40000000u) << 1); 613e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} 614e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 615e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr0( 616e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context); 617e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr1( 618e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context); 619e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr2( 620e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context); 621e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 622e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttemplate<typename A> 623e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstruct EHABISectionIterator { 624e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typedef EHABISectionIterator _Self; 625e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 626e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typedef std::random_access_iterator_tag iterator_category; 627e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typedef typename A::pint_t value_type; 628e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typedef typename A::pint_t* pointer; 629e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typedef typename A::pint_t& reference; 630e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typedef size_t size_type; 631e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typedef size_t difference_type; 632e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 633e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert static _Self begin(A& addressSpace, const UnwindInfoSections& sects) { 634e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return _Self(addressSpace, sects, 0); 635e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 636e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert static _Self end(A& addressSpace, const UnwindInfoSections& sects) { 637e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return _Self(addressSpace, sects, sects.arm_section_length); 638e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 639e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 640e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i) 641e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert : _addressSpace(&addressSpace), _sects(§s), _i(i) {} 642e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 643e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Self& operator++() { ++_i; return *this; } 644e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Self& operator+=(size_t a) { _i += a; return *this; } 645e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Self& operator--() { assert(_i > 0); --_i; return *this; } 646e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Self& operator-=(size_t a) { assert(_i >= a); _i -= a; return *this; } 647e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 648e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Self operator+(size_t a) { _Self out = *this; out._i += a; return out; } 649e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Self operator-(size_t a) { assert(_i >= a); _Self out = *this; out._i -= a; return out; } 650e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 651e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert size_t operator-(const _Self& other) { return _i - other._i; } 652e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 653e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert bool operator==(const _Self& other) const { 654e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert assert(_addressSpace == other._addressSpace); 655e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert assert(_sects == other._sects); 656e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return _i == other._i; 657e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 658e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 659e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typename A::pint_t operator*() const { return functionAddress(); } 660e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 661e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typename A::pint_t functionAddress() const { 662e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof( 663e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABIIndexEntry, _i, functionOffset); 664e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return indexAddr + signExtendPrel31(_addressSpace->get32(indexAddr)); 665e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 666e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 667e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typename A::pint_t dataAddress() { 668e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof( 669e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABIIndexEntry, _i, data); 670e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return indexAddr; 671e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 672e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 673e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert private: 674e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert size_t _i; 675e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert A* _addressSpace; 676e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert const UnwindInfoSections* _sects; 677e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}; 678e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 679e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttemplate <typename A, typename R> 680e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertbool UnwindCursor<A, R>::getInfoFromEHABISection( 681e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert pint_t pc, 682e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert const UnwindInfoSections §s) { 683e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABISectionIterator<A> begin = 684e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABISectionIterator<A>::begin(_addressSpace, sects); 685e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABISectionIterator<A> end = 686e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABISectionIterator<A>::end(_addressSpace, sects); 687e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 688e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABISectionIterator<A> itNextPC = std::upper_bound(begin, end, pc); 689e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (itNextPC == begin || itNextPC == end) 690e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return false; 691e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert EHABISectionIterator<A> itThisPC = itNextPC - 1; 692e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 693e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert pint_t thisPC = itThisPC.functionAddress(); 694e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert pint_t nextPC = itNextPC.functionAddress(); 695e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert pint_t indexDataAddr = itThisPC.dataAddress(); 696e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 697e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (indexDataAddr == 0) 698e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return false; 699e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 700e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t indexData = _addressSpace.get32(indexDataAddr); 701e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (indexData == UNW_EXIDX_CANTUNWIND) 702e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return false; 703e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 704e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // If the high bit is set, the exception handling table entry is inline inside 705e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // the index table entry on the second word (aka |indexDataAddr|). Otherwise, 706e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // the table points at an offset in the exception handling table (section 5 EHABI). 707e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert pint_t exceptionTableAddr; 708e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t exceptionTableData; 709e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert bool isSingleWordEHT; 710e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (indexData & 0x80000000) { 711e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert exceptionTableAddr = indexDataAddr; 712e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // TODO(ajwong): Should this data be 0? 713e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert exceptionTableData = indexData; 714e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert isSingleWordEHT = true; 715e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } else { 716e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert exceptionTableAddr = indexDataAddr + signExtendPrel31(indexData); 717e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert exceptionTableData = _addressSpace.get32(exceptionTableAddr); 718e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert isSingleWordEHT = false; 719e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 720e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 721e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // Now we know the 3 things: 722e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // exceptionTableAddr -- exception handler table entry. 723e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // exceptionTableData -- the data inside the first word of the eht entry. 724e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // isSingleWordEHT -- whether the entry is in the index. 725e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert unw_word_t personalityRoutine = 0xbadf00d; 726e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert bool scope32 = false; 727e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t lsda = 0xbadf00d; 728e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 729e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // If the high bit in the exception handling table entry is set, the entry is 730e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // in compact form (section 6.3 EHABI). 731e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (exceptionTableData & 0x80000000) { 732e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // Grab the index of the personality routine from the compact form. 733e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert int choice = (exceptionTableData & 0x0f000000) >> 24; 734e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert int extraWords = 0; 735e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert switch (choice) { 736e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert case 0: 737e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0; 738e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert extraWords = 0; 739e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert scope32 = false; 740e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert break; 741e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert case 1: 742e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr1; 743e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert extraWords = (exceptionTableData & 0x00ff0000) >> 16; 744e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert scope32 = false; 745e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert break; 746e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert case 2: 747e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr2; 748e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert extraWords = (exceptionTableData & 0x00ff0000) >> 16; 749e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert scope32 = true; 750e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert break; 751e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert default: 752e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _LIBUNWIND_ABORT("unknown personality routine"); 753e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return false; 754e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 755e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 756e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (isSingleWordEHT) { 757e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (extraWords != 0) { 758e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _LIBUNWIND_ABORT("index inlined table detected but pr function " 759e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert "requires extra words"); 760e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return false; 761e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 762e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 763e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } else { 764e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert pint_t personalityAddr = 765e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert exceptionTableAddr + signExtendPrel31(exceptionTableData); 766e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert personalityRoutine = personalityAddr; 767e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 768e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // ARM EHABI # 6.2, # 9.2 769e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // 770e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // +---- ehtp 771e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // v 772e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // +--------------------------------------+ 773e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | +--------+--------+--------+-------+ | 774e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | |0| prel31 to personalityRoutine | | 775e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | +--------+--------+--------+-------+ | 776e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | | N | unwind opcodes | | <-- UnwindData 777e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | +--------+--------+--------+-------+ | 778e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | | Word 2 unwind opcodes | | 779e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | +--------+--------+--------+-------+ | 780e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | ... | 781e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | +--------+--------+--------+-------+ | 782e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | | Word N unwind opcodes | | 783e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | +--------+--------+--------+-------+ | 784e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | | LSDA | | <-- lsda 785e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | | ... | | 786e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // | +--------+--------+--------+-------+ | 787e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // +--------------------------------------+ 788e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 789e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t *UnwindData = reinterpret_cast<uint32_t*>(exceptionTableAddr) + 1; 790e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t FirstDataWord = *UnwindData; 791e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert size_t N = ((FirstDataWord >> 24) & 0xff); 792e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert size_t NDataWords = N + 1; 793e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert lsda = reinterpret_cast<uintptr_t>(UnwindData + NDataWords); 794e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 795e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 796e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _info.start_ip = thisPC; 797e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _info.end_ip = nextPC; 798e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _info.handler = personalityRoutine; 799e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _info.unwind_info = exceptionTableAddr; 800e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _info.lsda = lsda; 801e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // flags is pr_cache.additional. See EHABI #7.2 for definition of bit 0. 802e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _info.flags = isSingleWordEHT ? 1 : 0 | scope32 ? 0x2 : 0; // Use enum? 803e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 804e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return true; 805e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} 806e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 807e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 808b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 809b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 810b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, 811b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const UnwindInfoSections §s, 812b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t fdeSectionOffsetHint) { 813b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename CFI_Parser<A>::FDE_Info fdeInfo; 814b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename CFI_Parser<A>::CIE_Info cieInfo; 815b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool foundFDE = false; 816b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool foundInCache = false; 817b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // If compact encoding table gave offset into dwarf section, go directly there 818b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (fdeSectionOffsetHint != 0) { 819b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, 820b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint32_t)sects.dwarf_section_length, 821b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sects.dwarf_section + fdeSectionOffsetHint, 822b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik &fdeInfo, &cieInfo); 823b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 824b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_INDEX 825b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (!foundFDE && (sects.dwarf_index_section != 0)) { 826b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Have eh_frame_hdr section which is index into dwarf section. 827b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // TO DO: implement index search 828b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 829b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 830b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (!foundFDE) { 831b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // otherwise, search cache of previously found FDEs. 832b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc); 833b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (cachedFDE != 0) { 834b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik foundFDE = 835b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, 836b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint32_t)sects.dwarf_section_length, 837b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik cachedFDE, &fdeInfo, &cieInfo); 838b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik foundInCache = foundFDE; 839b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 840b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 841b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (!foundFDE) { 842b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Still not found, do full scan of __eh_frame section. 843b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, 844b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint32_t)sects.dwarf_section_length, 0, 845b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik &fdeInfo, &cieInfo); 846b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 847b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (foundFDE) { 848b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename CFI_Parser<A>::PrologInfo prolog; 849b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc, 850b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik &prolog)) { 851b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Save off parsed FDE info 852b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.start_ip = fdeInfo.pcStart; 853b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.end_ip = fdeInfo.pcEnd; 854b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.lsda = fdeInfo.lsda; 855b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.handler = cieInfo.personality; 856b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.gp = prolog.spExtraArgSize; 857b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.flags = 0; 858b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.format = dwarfEncoding(); 859b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info = fdeInfo.fdeStart; 860b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength; 861b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.extra = (unw_word_t) sects.dso_base; 862b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 863b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Add to cache (to make next lookup faster) if we had no hint 864b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // and there was no index. 865b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (!foundInCache && (fdeSectionOffsetHint == 0)) { 866b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #if _LIBUNWIND_SUPPORT_DWARF_INDEX 867b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (sects.dwarf_index_section == 0) 868b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #endif 869b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd, 870b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fdeInfo.fdeStart); 871b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 872b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 873b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 874b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 875b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX\n", (uint64_t)pc); 876b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 877b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 878b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND 879b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 880b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 881b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND 882b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 883b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc, 884b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const UnwindInfoSections §s) { 885b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const bool log = false; 886b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 887b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, mh=0x%llX)\n", 888b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t)pc, (uint64_t)sects.dso_base); 889b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 890b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const UnwindSectionHeader<A> sectionHeader(_addressSpace, 891b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sects.compact_unwind_section); 892b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (sectionHeader.version() != UNWIND_SECTION_VERSION) 893b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 894b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 895b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // do a binary search of top level index to find page with unwind info 896b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t targetFunctionOffset = pc - sects.dso_base; 897b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const UnwindSectionIndexArray<A> topIndex(_addressSpace, 898b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sects.compact_unwind_section 899b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik + sectionHeader.indexSectionOffset()); 900b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t low = 0; 901b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t high = sectionHeader.indexCount(); 902b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t last = high - 1; 903b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik while (low < high) { 904b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t mid = (low + high) / 2; 905b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik //if ( log ) fprintf(stderr, "\tmid=%d, low=%d, high=%d, *mid=0x%08X\n", 906b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik //mid, low, high, topIndex.functionOffset(mid)); 907b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (topIndex.functionOffset(mid) <= targetFunctionOffset) { 908b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((mid == last) || 909b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (topIndex.functionOffset(mid + 1) > targetFunctionOffset)) { 910b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid; 911b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 912b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 913b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid + 1; 914b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 915b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 916b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik high = mid; 917b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 918b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 919b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint32_t firstLevelFunctionOffset = topIndex.functionOffset(low); 920b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint32_t firstLevelNextPageFunctionOffset = 921b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik topIndex.functionOffset(low + 1); 922b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const pint_t secondLevelAddr = 923b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sects.compact_unwind_section + topIndex.secondLevelPagesSectionOffset(low); 924b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const pint_t lsdaArrayStartAddr = 925b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low); 926b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const pint_t lsdaArrayEndAddr = 927b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low+1); 928b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 929b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "\tfirst level search for result index=%d " 930b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "to secondLevelAddr=0x%llX\n", 931b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low, (uint64_t) secondLevelAddr); 932b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // do a binary search of second level page index 933b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t encoding = 0; 934b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t funcStart = 0; 935b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t funcEnd = 0; 936b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t lsda = 0; 937b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t personality = 0; 938b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t pageKind = _addressSpace.get32(secondLevelAddr); 939b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (pageKind == UNWIND_SECOND_LEVEL_REGULAR) { 940b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // regular page 941b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionRegularPageHeader<A> pageHeader(_addressSpace, 942b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik secondLevelAddr); 943b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionRegularArray<A> pageIndex( 944b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addressSpace, secondLevelAddr + pageHeader.entryPageOffset()); 945b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // binary search looks for entry with e where index[e].offset <= pc < 946b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // index[e+1].offset 947b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 948b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "\tbinary search for targetFunctionOffset=0x%08llX in " 949b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "regular page starting at secondLevelAddr=0x%llX\n", 950b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) targetFunctionOffset, (uint64_t) secondLevelAddr); 951b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = 0; 952b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik high = pageHeader.entryCount(); 953b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik while (low < high) { 954b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t mid = (low + high) / 2; 955b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (pageIndex.functionOffset(mid) <= targetFunctionOffset) { 956b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (mid == (uint32_t)(pageHeader.entryCount() - 1)) { 957b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // at end of table 958b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid; 959b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base; 960b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 961b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else if (pageIndex.functionOffset(mid + 1) > targetFunctionOffset) { 962b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // next is too big, so we found it 963b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid; 964b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik funcEnd = pageIndex.functionOffset(low + 1) + sects.dso_base; 965b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 966b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 967b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid + 1; 968b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 969b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 970b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik high = mid; 971b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 972b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 973b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encoding = pageIndex.encoding(low); 974b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik funcStart = pageIndex.functionOffset(low) + sects.dso_base; 975b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (pc < funcStart) { 976b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 977b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf( 978b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik stderr, 979b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n", 980b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd); 981b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 982b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 983b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (pc > funcEnd) { 984b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 985b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf( 986b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik stderr, 987b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n", 988b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd); 989b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 990b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 991b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) { 992b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // compressed page 993b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionCompressedPageHeader<A> pageHeader(_addressSpace, 994b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik secondLevelAddr); 995b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionCompressedArray<A> pageIndex( 996b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _addressSpace, secondLevelAddr + pageHeader.entryPageOffset()); 997b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint32_t targetFunctionPageOffset = 998b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint32_t)(targetFunctionOffset - firstLevelFunctionOffset); 999b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // binary search looks for entry with e where index[e].offset <= pc < 1000b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // index[e+1].offset 1001b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 1002b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "\tbinary search of compressed page starting at " 1003b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "secondLevelAddr=0x%llX\n", 1004b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) secondLevelAddr); 1005b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = 0; 1006b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik last = pageHeader.entryCount() - 1; 1007b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik high = pageHeader.entryCount(); 1008b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik while (low < high) { 1009b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t mid = (low + high) / 2; 1010b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (pageIndex.functionOffset(mid) <= targetFunctionPageOffset) { 1011b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((mid == last) || 1012b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (pageIndex.functionOffset(mid + 1) > targetFunctionPageOffset)) { 1013b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid; 1014b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 1015b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 1016b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid + 1; 1017b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1018b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 1019b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik high = mid; 1020b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1021b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1022b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset 1023b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik + sects.dso_base; 1024b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (low < last) 1025b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik funcEnd = 1026b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pageIndex.functionOffset(low + 1) + firstLevelFunctionOffset 1027b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik + sects.dso_base; 1028b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik else 1029b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base; 1030b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (pc < funcStart) { 1031b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second " 1032b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "level compressed unwind table. funcStart=0x%llX\n", 1033b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) pc, (uint64_t) funcStart); 1034b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 1035b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1036b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (pc > funcEnd) { 1037b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second " 1038b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "level compressed unwind table. funcEnd=0x%llX\n", 1039b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) pc, (uint64_t) funcEnd); 1040b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 1041b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1042b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t encodingIndex = pageIndex.encodingIndex(low); 1043b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (encodingIndex < sectionHeader.commonEncodingsArrayCount()) { 1044b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // encoding is in common table in section header 1045b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encoding = _addressSpace.get32( 1046b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sects.compact_unwind_section + 1047b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sectionHeader.commonEncodingsArraySectionOffset() + 1048b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encodingIndex * sizeof(uint32_t)); 1049b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 1050b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // encoding is in page specific table 1051b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t pageEncodingIndex = 1052b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount(); 1053b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encoding = _addressSpace.get32(secondLevelAddr + 1054b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pageHeader.encodingsPageOffset() + 1055b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pageEncodingIndex * sizeof(uint32_t)); 1056b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1057b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 1058b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second " 1059b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "level page\n", 1060b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) sects.compact_unwind_section); 1061b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 1062b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1063b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1064b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // look up LSDA, if encoding says function has one 1065b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (encoding & UNWIND_HAS_LSDA) { 1066b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindSectionLsdaArray<A> lsdaIndex(_addressSpace, lsdaArrayStartAddr); 1067b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t funcStartOffset = (uint32_t)(funcStart - sects.dso_base); 1068b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = 0; 1069b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik high = (uint32_t)(lsdaArrayEndAddr - lsdaArrayStartAddr) / 1070b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sizeof(unwind_info_section_header_lsda_index_entry); 1071b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // binary search looks for entry with exact match for functionOffset 1072b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 1073b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, 1074b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "\tbinary search of lsda table for targetFunctionOffset=0x%08X\n", 1075b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik funcStartOffset); 1076b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik while (low < high) { 1077b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t mid = (low + high) / 2; 1078b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (lsdaIndex.functionOffset(mid) == funcStartOffset) { 1079b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik lsda = lsdaIndex.lsdaOffset(mid) + sects.dso_base; 1080b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 1081b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else if (lsdaIndex.functionOffset(mid) < funcStartOffset) { 1082b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik low = mid + 1; 1083b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 1084b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik high = mid; 1085b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1086b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1087b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (lsda == 0) { 1088b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for " 1089b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "pc=0x%0llX, but lsda table has no entry\n", 1090b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encoding, (uint64_t) pc); 1091b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 1092b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1093b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1094b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1095b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // extact personality routine, if encoding says function has one 1096b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >> 1097b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (__builtin_ctz(UNWIND_PERSONALITY_MASK)); 1098b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (personalityIndex != 0) { 1099b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik --personalityIndex; // change 1-based to zero-based index 1100b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (personalityIndex > sectionHeader.personalityArrayCount()) { 1101b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, " 1102b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "but personality table has only %d entires\n", 1103b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik encoding, personalityIndex, 1104b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sectionHeader.personalityArrayCount()); 1105b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 1106b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1107e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert int32_t personalityDelta = (int32_t)_addressSpace.get32( 1108e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert sects.compact_unwind_section + 1109e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert sectionHeader.personalityArraySectionOffset() + 1110b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik personalityIndex * sizeof(uint32_t)); 1111b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t personalityPointer = sects.dso_base + (pint_t)personalityDelta; 1112b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik personality = _addressSpace.getP(personalityPointer); 1113b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 1114b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), " 1115b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "personalityDelta=0x%08X, personality=0x%08llX\n", 1116b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) pc, personalityDelta, (uint64_t) personality); 1117b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1118b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1119b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 1120b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), " 1121b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n", 1122b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart); 1123b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.start_ip = funcStart; 1124b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.end_ip = funcEnd; 1125b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.lsda = lsda; 1126b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.handler = personality; 1127b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.gp = 0; 1128b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.flags = 0; 1129b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.format = encoding; 1130b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info = 0; 1131b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info_size = 0; 1132b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.extra = sects.dso_base; 1133b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 1134b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 1135b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1136b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1137b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1138b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 1139b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { 1140b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t pc = (pint_t)this->getReg(UNW_REG_IP); 1141e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 1142e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // Remove the thumb bit so the IP represents the actual instruction address. 1143e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // This matches the behaviour of _Unwind_GetIP on arm. 1144e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert pc &= (pint_t)~0x1; 1145e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 1146b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1147b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // If the last line of a function is a "throw" the compiler sometimes 1148b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // emits no instructions after the call to __cxa_throw. This means 1149b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // the return address is actually the start of the next function. 1150b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // To disambiguate this, back up the pc when we know it is a return 1151b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // address. 1152b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (isReturnAddress) 1153b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik --pc; 1154b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1155b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Ask address space object to find unwind sections for this pc. 1156b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindInfoSections sects; 1157b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_addressSpace.findUnwindSections(pc, sects)) { 1158b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1159b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // If there is a compact unwind encoding table, look there first. 1160b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (sects.compact_unwind_section != 0) { 1161b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (this->getInfoFromCompactEncodingSection(pc, sects)) { 1162b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #if _LIBUNWIND_SUPPORT_DWARF_UNWIND 1163b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Found info in table, done unless encoding says to use dwarf. 1164b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t dwarfOffset; 1165b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((sects.dwarf_section != 0) && compactSaysUseDwarf(&dwarfOffset)) { 1166b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (this->getInfoFromDwarfSection(pc, sects, dwarfOffset)) { 1167b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // found info in dwarf, done 1168b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return; 1169b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1170b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1171b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #endif 1172b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // If unwind table has entry, but entry says there is no unwind info, 1173b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // record that we have no unwind info. 1174b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_info.format == 0) 1175b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _unwindInfoMissing = true; 1176b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return; 1177b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1178b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1179b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1180b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1181b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 1182b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // If there is dwarf unwind info, look there next. 1183b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (sects.dwarf_section != 0) { 1184b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (this->getInfoFromDwarfSection(pc, sects)) { 1185b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // found info in dwarf, done 1186b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return; 1187b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1188b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1189b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 1190e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 1191e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 1192e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // If there is ARM EHABI unwind info, look there next. 1193e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (sects.arm_section != 0 && this->getInfoFromEHABISection(pc, sects)) 1194e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return; 1195e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 1196b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1197b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1198b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 1199b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // There is no static unwind info for this pc. Look to see if an FDE was 1200b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // dynamically registered for it. 1201b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc); 1202b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (cachedFDE != 0) { 1203b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; 1204b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; 1205b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace, 1206b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik cachedFDE, &fdeInfo, &cieInfo); 1207b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (msg == NULL) { 1208b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename CFI_Parser<A>::PrologInfo prolog; 1209b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, 1210b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pc, &prolog)) { 1211b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // save off parsed FDE info 1212b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.start_ip = fdeInfo.pcStart; 1213b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.end_ip = fdeInfo.pcEnd; 1214b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.lsda = fdeInfo.lsda; 1215b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.handler = cieInfo.personality; 1216b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.gp = prolog.spExtraArgSize; 1217b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Some frameless functions need SP 1218b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // altered when resuming in function. 1219b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.flags = 0; 1220b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.format = dwarfEncoding(); 1221b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info = fdeInfo.fdeStart; 1222b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength; 1223b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.extra = 0; 1224b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return; 1225b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1226b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1227b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1228b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1229b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Lastly, ask AddressSpace object about platform specific ways to locate 1230b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // other FDEs. 1231b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t fde; 1232b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_addressSpace.findOtherFDE(pc, fde)) { 1233b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; 1234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; 1235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) { 1236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Double check this FDE is for a function that includes the pc. 1237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) { 1238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typename CFI_Parser<A>::PrologInfo prolog; 1239b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, 1240b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik cieInfo, pc, &prolog)) { 1241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // save off parsed FDE info 1242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.start_ip = fdeInfo.pcStart; 1243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.end_ip = fdeInfo.pcEnd; 1244b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.lsda = fdeInfo.lsda; 1245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.handler = cieInfo.personality; 1246b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.gp = prolog.spExtraArgSize; 1247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.flags = 0; 1248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.format = dwarfEncoding(); 1249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info = fdeInfo.fdeStart; 1250b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength; 1251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _info.extra = 0; 1252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return; 1253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1254b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // #if _LIBUNWIND_SUPPORT_DWARF_UNWIND 1258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // no unwind info, flag that we can't reliably unwind 1260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _unwindInfoMissing = true; 1261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 1262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 1264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikint UnwindCursor<A, R>::step() { 1265e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // Bottom of stack is defined is when unwind info cannot be found. 1266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_unwindInfoMissing) 1267b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNW_STEP_END; 1268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1269b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // Use unwinding info to modify register set as if function returned. 1270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int result; 1271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1272b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = this->stepWithCompactEncoding(); 1273b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#elif _LIBUNWIND_SUPPORT_DWARF_UNWIND 1274b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = this->stepWithDwarfFDE(); 1275e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#elif LIBCXXABI_ARM_EHABI 1276e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert result = UNW_STEP_SUCCESS; 1277b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else 1278e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert #error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \ 1279e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _LIBUNWIND_SUPPORT_DWARF_UNWIND or \ 1280e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert LIBCXXABI_ARM_EHABI 1281b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 1282b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1283b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // update info based on new PC 1284b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (result == UNW_STEP_SUCCESS) { 1285b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik this->setInfoBasedOnIPRegister(true); 1286b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_unwindInfoMissing) 1287b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return UNW_STEP_END; 12887dfc5215ff08e992ffe88c577ba15d641e610d75Joerg Sonnenberger if (_info.gp) 12897dfc5215ff08e992ffe88c577ba15d641e610d75Joerg Sonnenberger setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp); 1290b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 1291b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1292b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return result; 1293b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 1294b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1295b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 1296b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) { 1297b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *info = _info; 1298b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 1299b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1300b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> 1301b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen, 1302b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_word_t *offset) { 1303b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return _addressSpace.findFunctionName((pint_t)this->getReg(UNW_REG_IP), 1304b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik buf, bufLen, offset); 1305b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 1306b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1307b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; // namespace libunwind 1308b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 1309b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // __UNWINDCURSOR_HPP__ 1310