UnwindCursor.hpp revision e085735cbedc82b1064f05ff796e32e906a95036
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
15b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdint.h>
16b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdio.h>
17b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdlib.h>
18b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <pthread.h>
19b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
206dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik#if __APPLE__
216dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik  #include <mach-o/dyld.h>
226dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik#endif
236dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik
24b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "libunwind.h"
25b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
26b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "AddressSpace.hpp"
27b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "Registers.hpp"
28b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "DwarfInstructions.hpp"
29b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "CompactUnwinder.hpp"
30b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "config.h"
31b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
32b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziknamespace libunwind {
33b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
34b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
35b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Cache of recently found FDEs.
36b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
37b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass _LIBUNWIND_HIDDEN DwarfFDECache {
38b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typedef typename A::pint_t pint_t;
39b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
40b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static pint_t findFDE(pint_t mh, pint_t pc);
41b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
42b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static void removeAllIn(pint_t mh);
43b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static void iterateCacheEntries(void (*func)(unw_word_t ip_start,
44b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                               unw_word_t ip_end,
45b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                               unw_word_t fde, unw_word_t mh));
46b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
47b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
48b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
49b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  struct entry {
50b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    pint_t mh;
51b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    pint_t ip_start;
52b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    pint_t ip_end;
53b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    pint_t fde;
54b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  };
55b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
56b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // These fields are all static to avoid needing an initializer.
57b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // There is only one instance of this class per process.
58b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static pthread_rwlock_t _lock;
59b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__
60b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide);
61b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static bool _registeredForDyldUnloads;
62b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
63b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // Can't use std::vector<> here because this code is below libc++.
64b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static entry *_buffer;
65b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static entry *_bufferUsed;
66b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static entry *_bufferEnd;
67b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static entry _initialBuffer[64];
68b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
69b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
70b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
71b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry *
72b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikDwarfFDECache<A>::_buffer = _initialBuffer;
73b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
74b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
75b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry *
76b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikDwarfFDECache<A>::_bufferUsed = _initialBuffer;
77b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
78b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
79b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry *
80b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikDwarfFDECache<A>::_bufferEnd = &_initialBuffer[64];
81b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
82b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
83b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64];
84b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
85b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
86b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER;
87b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
88b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__
89b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
90b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool DwarfFDECache<A>::_registeredForDyldUnloads = false;
91b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
92b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
93b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
94b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
95b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t result = 0;
96b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_rdlock(&_lock));
97b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  for (entry *p = _buffer; p < _bufferUsed; ++p) {
98b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if ((mh == p->mh) || (mh == 0)) {
99b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if ((p->ip_start <= pc) && (pc < p->ip_end)) {
100b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        result = p->fde;
101b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        break;
102b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
103b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
104b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
105b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock));
106b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return result;
107b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
108b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
109b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
110b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
111b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                           pint_t fde) {
112b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_wrlock(&_lock));
113b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (_bufferUsed >= _bufferEnd) {
114b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    size_t oldSize = (size_t)(_bufferEnd - _buffer);
115b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    size_t newSize = oldSize * 4;
116b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // Can't use operator new (we are below it).
117b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    entry *newBuffer = (entry *)malloc(newSize * sizeof(entry));
118b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    memcpy(newBuffer, _buffer, oldSize * sizeof(entry));
119b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (_buffer != _initialBuffer)
120b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      free(_buffer);
121b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _buffer = newBuffer;
122b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _bufferUsed = &newBuffer[oldSize];
123b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _bufferEnd = &newBuffer[newSize];
124b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
125b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _bufferUsed->mh = mh;
126b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _bufferUsed->ip_start = ip_start;
127b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _bufferUsed->ip_end = ip_end;
128b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _bufferUsed->fde = fde;
129b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  ++_bufferUsed;
130b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__
131b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (!_registeredForDyldUnloads) {
132b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _dyld_register_func_for_remove_image(&dyldUnloadHook);
133b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _registeredForDyldUnloads = true;
134b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
135b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
136b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock));
137b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
138b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
139b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
140b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::removeAllIn(pint_t mh) {
141b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_wrlock(&_lock));
142b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  entry *d = _buffer;
143b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  for (const entry *s = _buffer; s < _bufferUsed; ++s) {
144b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (s->mh != mh) {
145b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (d != s)
146b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        *d = *s;
147b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      ++d;
148b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
149b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
150b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _bufferUsed = d;
151b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock));
152b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
153b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
154e085735cbedc82b1064f05ff796e32e906a95036Dan Albert#if __APPLE__
155b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
156b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) {
157b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  removeAllIn((pint_t) mh);
158b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
159e085735cbedc82b1064f05ff796e32e906a95036Dan Albert#endif
160b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
161b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A>
162b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid DwarfFDECache<A>::iterateCacheEntries(void (*func)(
163b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
164b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_wrlock(&_lock));
165b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  for (entry *p = _buffer; p < _bufferUsed; ++p) {
166b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    (*func)(p->ip_start, p->ip_end, p->fde, p->mh);
167b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
168b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock));
169b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
170b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
171b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
172b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
173b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field))
174b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
175b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
176b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionHeader {
177b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
178b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindSectionHeader(A &addressSpace, typename A::pint_t addr)
179b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      : _addressSpace(addressSpace), _addr(addr) {}
180b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
181b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t version() const {
182b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(_addr +
183b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                               offsetof(unwind_info_section_header, version));
184b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
185b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t commonEncodingsArraySectionOffset() const {
186b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(_addr +
187b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                               offsetof(unwind_info_section_header,
188b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                        commonEncodingsArraySectionOffset));
189b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
190b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t commonEncodingsArrayCount() const {
191b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(_addr + offsetof(unwind_info_section_header,
192b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                commonEncodingsArrayCount));
193b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
194b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t personalityArraySectionOffset() const {
195b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(_addr + offsetof(unwind_info_section_header,
196b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                personalityArraySectionOffset));
197b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
198b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t personalityArrayCount() const {
199b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
200b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_section_header, personalityArrayCount));
201b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
202b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t indexSectionOffset() const {
203b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
204b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_section_header, indexSectionOffset));
205b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
206b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t indexCount() const {
207b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
208b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_section_header, indexCount));
209b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
210b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
211b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
212b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A                     &_addressSpace;
213b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename A::pint_t     _addr;
214b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
215b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
216b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionIndexArray {
217b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
218b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindSectionIndexArray(A &addressSpace, typename A::pint_t addr)
219b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      : _addressSpace(addressSpace), _addr(addr) {}
220b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
221b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t functionOffset(uint32_t index) const {
222b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
223b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
224b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              functionOffset));
225b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
226b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t secondLevelPagesSectionOffset(uint32_t index) const {
227b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
228b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
229b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              secondLevelPagesSectionOffset));
230b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
231b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t lsdaIndexArraySectionOffset(uint32_t index) const {
232b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
233b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + arrayoffsetof(unwind_info_section_header_index_entry, index,
234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              lsdaIndexArraySectionOffset));
235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A                   &_addressSpace;
239b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename A::pint_t   _addr;
240b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionRegularPageHeader {
243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
244b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindSectionRegularPageHeader(A &addressSpace, typename A::pint_t addr)
245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      : _addressSpace(addressSpace), _addr(addr) {}
246b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t kind() const {
248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_regular_second_level_page_header, kind));
250b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t entryPageOffset() const {
252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get16(
253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_regular_second_level_page_header,
254b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                         entryPageOffset));
255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t entryCount() const {
257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get16(
258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr +
259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        offsetof(unwind_info_regular_second_level_page_header, entryCount));
260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A &_addressSpace;
264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename A::pint_t _addr;
265b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
267b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionRegularArray {
268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
269b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindSectionRegularArray(A &addressSpace, typename A::pint_t addr)
270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      : _addressSpace(addressSpace), _addr(addr) {}
271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
272b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t functionOffset(uint32_t index) const {
273b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
274b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + arrayoffsetof(unwind_info_regular_second_level_entry, index,
275b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              functionOffset));
276b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
277b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t encoding(uint32_t index) const {
278b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
279b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr +
280b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        arrayoffsetof(unwind_info_regular_second_level_entry, index, encoding));
281b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
282b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
283b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
284b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A &_addressSpace;
285b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename A::pint_t _addr;
286b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
287b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
288b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionCompressedPageHeader {
289b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
290b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindSectionCompressedPageHeader(A &addressSpace, typename A::pint_t addr)
291b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      : _addressSpace(addressSpace), _addr(addr) {}
292b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
293b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t kind() const {
294b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
295b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr +
296b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        offsetof(unwind_info_compressed_second_level_page_header, kind));
297b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
298b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t entryPageOffset() const {
299b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get16(
300b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_compressed_second_level_page_header,
301b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                         entryPageOffset));
302b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
303b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t entryCount() const {
304b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get16(
305b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr +
306b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        offsetof(unwind_info_compressed_second_level_page_header, entryCount));
307b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
308b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t encodingsPageOffset() const {
309b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get16(
310b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_compressed_second_level_page_header,
311b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                         encodingsPageOffset));
312b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
313b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t encodingsCount() const {
314b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get16(
315b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + offsetof(unwind_info_compressed_second_level_page_header,
316b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                         encodingsCount));
317b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
318b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
319b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
320b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A &_addressSpace;
321b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename A::pint_t _addr;
322b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
323b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
324b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionCompressedArray {
325b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
326b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindSectionCompressedArray(A &addressSpace, typename A::pint_t addr)
327b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      : _addressSpace(addressSpace), _addr(addr) {}
328b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
329b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t functionOffset(uint32_t index) const {
330b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(
331b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addressSpace.get32(_addr + index * sizeof(uint32_t)));
332b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
333b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t encodingIndex(uint32_t index) const {
334b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(
335b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addressSpace.get32(_addr + index * sizeof(uint32_t)));
336b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
337b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
338b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
339b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A &_addressSpace;
340b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename A::pint_t _addr;
341b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
342b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
343b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A> class UnwindSectionLsdaArray {
344b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
345b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindSectionLsdaArray(A &addressSpace, typename A::pint_t addr)
346b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      : _addressSpace(addressSpace), _addr(addr) {}
347b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
348b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t functionOffset(uint32_t index) const {
349b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
350b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry,
351b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              index, functionOffset));
352b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
353b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t lsdaOffset(uint32_t index) const {
354b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return _addressSpace.get32(
355b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry,
356b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              index, lsdaOffset));
357b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
358b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
359b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
360b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A                   &_addressSpace;
361b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename A::pint_t   _addr;
362b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
363b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
364b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
365b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
366b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass _LIBUNWIND_HIDDEN AbstractUnwindCursor {
367b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
368e085735cbedc82b1064f05ff796e32e906a95036Dan Albert  virtual             ~AbstractUnwindCursor() {}
369b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        validReg(int) = 0;
370b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual unw_word_t  getReg(int) = 0;
371b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        setReg(int, unw_word_t) = 0;
372b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        validFloatReg(int) = 0;
373b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual double      getFloatReg(int) = 0;
374b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        setFloatReg(int, double) = 0;
375b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual int         step() = 0;
376b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        getInfo(unw_proc_info_t *) = 0;
377b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        jumpto() = 0;
378b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        isSignalFrame() = 0;
379b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        getFunctionName(char *bf, size_t ln, unw_word_t *off) = 0;
380b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        setInfoBasedOnIPRegister(bool isReturnAddr = false) = 0;
381b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual const char *getRegisterName(int num) = 0;
382b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
383b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
384b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
385b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// UnwindCursor contains all state (including all register values) during
386b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// an unwind.  This is normally stack allocated inside a unw_cursor_t.
387b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
388b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass UnwindCursor : public AbstractUnwindCursor{
389b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typedef typename A::pint_t pint_t;
390b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
391b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                      UnwindCursor(unw_context_t *context, A &as);
3926dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik                      UnwindCursor(A &as, void *threadArg);
393b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual             ~UnwindCursor() {}
394b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        validReg(int);
395b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual unw_word_t  getReg(int);
396b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        setReg(int, unw_word_t);
397b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        validFloatReg(int);
398b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual double      getFloatReg(int);
399b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        setFloatReg(int, double);
400b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual int         step();
401b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        getInfo(unw_proc_info_t *);
402b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        jumpto();
403b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        isSignalFrame();
404b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual bool        getFunctionName(char *buf, size_t len, unw_word_t *off);
405b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual void        setInfoBasedOnIPRegister(bool isReturnAddress = false);
406b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  virtual const char *getRegisterName(int num);
407b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
408b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  void            operator delete(void *, size_t) {}
409b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
410b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
411b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
412b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
413b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections &sects,
414b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                            uint32_t fdeSectionOffsetHint=0);
415b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int stepWithDwarfFDE() {
416b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace,
417b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                              (pint_t)this->getReg(UNW_REG_IP),
418b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                              (pint_t)_info.unwind_info,
419b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                              _registers);
420b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
421b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
422b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
423b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
424b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool getInfoFromCompactEncodingSection(pint_t pc,
425b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                            const UnwindInfoSections &sects);
426b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int stepWithCompactEncoding() {
427b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
428b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if ( compactSaysUseDwarf() )
429b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return stepWithDwarfFDE();
430b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  #endif
431b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    R dummy;
432b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return stepWithCompactEncoding(dummy);
433b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
434b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
435b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int stepWithCompactEncoding(Registers_x86_64 &) {
436b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return CompactUnwinder_x86_64<A>::stepWithCompactEncoding(
437b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.format, _info.start_ip, _addressSpace, _registers);
438b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
439b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
440b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int stepWithCompactEncoding(Registers_x86 &) {
441b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return CompactUnwinder_x86<A>::stepWithCompactEncoding(
442b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers);
443b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
444b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
445b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int stepWithCompactEncoding(Registers_ppc &) {
446b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return UNW_EINVAL;
447b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
448b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
449b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int stepWithCompactEncoding(Registers_arm64 &) {
450b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return CompactUnwinder_arm64<A>::stepWithCompactEncoding(
451b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.format, _info.start_ip, _addressSpace, _registers);
452b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
453b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
454b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
455b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    R dummy;
456b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return compactSaysUseDwarf(dummy, offset);
457b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
458b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
459b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const {
460b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) {
461b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (offset)
462b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        *offset = (_info.format & UNWIND_X86_64_DWARF_SECTION_OFFSET);
463b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return true;
464b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
465b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return false;
466b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
467b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
468b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const {
469b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) {
470b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (offset)
471b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        *offset = (_info.format & UNWIND_X86_DWARF_SECTION_OFFSET);
472b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return true;
473b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
474b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return false;
475b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
476b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
477b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const {
478b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return true;
479b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
480b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
481b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
482b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
483b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (offset)
484b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        *offset = (_info.format & UNWIND_ARM64_DWARF_SECTION_OFFSET);
485b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return true;
486b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
487b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return false;
488b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
489b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
490b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  compact_unwind_encoding_t dwarfEncoding() const {
491b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    R dummy;
492b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return dwarfEncoding(dummy);
493b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
494b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
495b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const {
496b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return UNWIND_X86_64_MODE_DWARF;
497b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
498b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
499b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const {
500b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return UNWIND_X86_MODE_DWARF;
501b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
502b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
503b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const {
504b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return 0;
505b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
506b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
507b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
508b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return UNWIND_ARM64_MODE_DWARF;
509b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
510b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
511b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
512b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
513b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  A               &_addressSpace;
514b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  R                _registers;
515b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  unw_proc_info_t  _info;
516b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool             _unwindInfoMissing;
517b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool             _isSignalFrame;
518b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
519b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
520b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
521b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
522b78da9875b6e35187b5d584746c78faaf3230a3dNick KledzikUnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
523b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    : _addressSpace(as), _registers(context), _unwindInfoMissing(false),
524b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _isSignalFrame(false) {
525b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static_assert(sizeof(UnwindCursor<A, R>) < sizeof(unw_cursor_t),
526b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                "UnwindCursor<> does not fit in unw_cursor_t");
527b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
528b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bzero(&_info, sizeof(_info));
529b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
530b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
531b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
5326dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick KledzikUnwindCursor<A, R>::UnwindCursor(A &as, void *)
533b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) {
534b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bzero(&_info, sizeof(_info));
535b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // FIXME
5366dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik  // fill in _registers from thread arg
537b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
538b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
5396dc154019d5f0997d7df1d9e9f3ba1425396dcd8Nick Kledzik
540b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
541b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::validReg(int regNum) {
542b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return _registers.validRegister(regNum);
543b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
544b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
545b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
546b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikunw_word_t UnwindCursor<A, R>::getReg(int regNum) {
547b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return _registers.getRegister(regNum);
548b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
549b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
550b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
551b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
552b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _registers.setRegister(regNum, (typename A::pint_t)value);
553b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
554b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
555b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
556b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::validFloatReg(int regNum) {
557b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return _registers.validFloatRegister(regNum);
558b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
559b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
560b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
561b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikdouble UnwindCursor<A, R>::getFloatReg(int regNum) {
562b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return _registers.getFloatRegister(regNum);
563b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
564b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
565b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
566b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid UnwindCursor<A, R>::setFloatReg(int regNum, double value) {
567b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _registers.setFloatRegister(regNum, value);
568b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
569b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
570b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
571b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _registers.jumpto();
572b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
573b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
574b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
575b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikconst char *UnwindCursor<A, R>::getRegisterName(int regNum) {
576b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return _registers.getRegisterName(regNum);
577b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
578b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
579b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() {
580b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return _isSignalFrame;
581b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
582b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
583b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
584b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
585b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
586b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                const UnwindInfoSections &sects,
587b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                uint32_t fdeSectionOffsetHint) {
588b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename CFI_Parser<A>::FDE_Info fdeInfo;
589b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typename CFI_Parser<A>::CIE_Info cieInfo;
590b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool foundFDE = false;
591b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool foundInCache = false;
592b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // If compact encoding table gave offset into dwarf section, go directly there
593b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (fdeSectionOffsetHint != 0) {
594b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
595b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                    (uint32_t)sects.dwarf_section_length,
596b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                    sects.dwarf_section + fdeSectionOffsetHint,
597b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                    &fdeInfo, &cieInfo);
598b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
599b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_INDEX
600b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (!foundFDE && (sects.dwarf_index_section != 0)) {
601b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // Have eh_frame_hdr section which is index into dwarf section.
602b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // TO DO: implement index search
603b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
604b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
605b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (!foundFDE) {
606b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // otherwise, search cache of previously found FDEs.
607b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc);
608b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (cachedFDE != 0) {
609b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      foundFDE =
610b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
611b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                 (uint32_t)sects.dwarf_section_length,
612b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                 cachedFDE, &fdeInfo, &cieInfo);
613b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      foundInCache = foundFDE;
614b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
615b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
616b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (!foundFDE) {
617b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // Still not found, do full scan of __eh_frame section.
618b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
619b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                      (uint32_t)sects.dwarf_section_length, 0,
620b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                      &fdeInfo, &cieInfo);
621b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
622b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (foundFDE) {
623b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    typename CFI_Parser<A>::PrologInfo prolog;
624b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
625b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                            &prolog)) {
626b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      // Save off parsed FDE info
627b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.start_ip          = fdeInfo.pcStart;
628b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.end_ip            = fdeInfo.pcEnd;
629b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.lsda              = fdeInfo.lsda;
630b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.handler           = cieInfo.personality;
631b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.gp                = prolog.spExtraArgSize;
632b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.flags             = 0;
633b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.format            = dwarfEncoding();
634b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.unwind_info       = fdeInfo.fdeStart;
635b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.unwind_info_size  = (uint32_t)fdeInfo.fdeLength;
636b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _info.extra             = (unw_word_t) sects.dso_base;
637b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
638b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      // Add to cache (to make next lookup faster) if we had no hint
639b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      // and there was no index.
640b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (!foundInCache && (fdeSectionOffsetHint == 0)) {
641b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  #if _LIBUNWIND_SUPPORT_DWARF_INDEX
642b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        if (sects.dwarf_index_section == 0)
643b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  #endif
644b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd,
645b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              fdeInfo.fdeStart);
646b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
647b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return true;
648b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
649b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
650b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX\n", (uint64_t)pc);
651b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return false;
652b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
653b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
654b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
655b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
656b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
657b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
658b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
659b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                              const UnwindInfoSections &sects) {
660b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const bool log = false;
661b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (log)
662b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, mh=0x%llX)\n",
663b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            (uint64_t)pc, (uint64_t)sects.dso_base);
664b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
665b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const UnwindSectionHeader<A> sectionHeader(_addressSpace,
666b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                sects.compact_unwind_section);
667b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (sectionHeader.version() != UNWIND_SECTION_VERSION)
668b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return false;
669b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
670b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // do a binary search of top level index to find page with unwind info
671b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t targetFunctionOffset = pc - sects.dso_base;
672b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const UnwindSectionIndexArray<A> topIndex(_addressSpace,
673b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                           sects.compact_unwind_section
674b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                         + sectionHeader.indexSectionOffset());
675b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t low = 0;
676b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t high = sectionHeader.indexCount();
677b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t last = high - 1;
678b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  while (low < high) {
679b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    uint32_t mid = (low + high) / 2;
680b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    //if ( log ) fprintf(stderr, "\tmid=%d, low=%d, high=%d, *mid=0x%08X\n",
681b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    //mid, low, high, topIndex.functionOffset(mid));
682b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (topIndex.functionOffset(mid) <= targetFunctionOffset) {
683b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if ((mid == last) ||
684b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          (topIndex.functionOffset(mid + 1) > targetFunctionOffset)) {
685b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        low = mid;
686b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        break;
687b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      } else {
688b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        low = mid + 1;
689b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
690b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    } else {
691b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      high = mid;
692b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
693b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
694b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const uint32_t firstLevelFunctionOffset = topIndex.functionOffset(low);
695b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const uint32_t firstLevelNextPageFunctionOffset =
696b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      topIndex.functionOffset(low + 1);
697b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const pint_t secondLevelAddr =
698b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      sects.compact_unwind_section + topIndex.secondLevelPagesSectionOffset(low);
699b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const pint_t lsdaArrayStartAddr =
700b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low);
701b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const pint_t lsdaArrayEndAddr =
702b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low+1);
703b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (log)
704b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    fprintf(stderr, "\tfirst level search for result index=%d "
705b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                    "to secondLevelAddr=0x%llX\n",
706b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                    low, (uint64_t) secondLevelAddr);
707b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // do a binary search of second level page index
708b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t encoding = 0;
709b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t funcStart = 0;
710b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t funcEnd = 0;
711b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t lsda = 0;
712b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t personality = 0;
713b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t pageKind = _addressSpace.get32(secondLevelAddr);
714b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (pageKind == UNWIND_SECOND_LEVEL_REGULAR) {
715b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // regular page
716b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    UnwindSectionRegularPageHeader<A> pageHeader(_addressSpace,
717b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                 secondLevelAddr);
718b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    UnwindSectionRegularArray<A> pageIndex(
719b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
720b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // binary search looks for entry with e where index[e].offset <= pc <
721b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // index[e+1].offset
722b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (log)
723b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      fprintf(stderr, "\tbinary search for targetFunctionOffset=0x%08llX in "
724b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                      "regular page starting at secondLevelAddr=0x%llX\n",
725b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik              (uint64_t) targetFunctionOffset, (uint64_t) secondLevelAddr);
726b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    low = 0;
727b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    high = pageHeader.entryCount();
728b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    while (low < high) {
729b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      uint32_t mid = (low + high) / 2;
730b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (pageIndex.functionOffset(mid) <= targetFunctionOffset) {
731b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        if (mid == (uint32_t)(pageHeader.entryCount() - 1)) {
732b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          // at end of table
733b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          low = mid;
734b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
735b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          break;
736b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        } else if (pageIndex.functionOffset(mid + 1) > targetFunctionOffset) {
737b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          // next is too big, so we found it
738b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          low = mid;
739b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          funcEnd = pageIndex.functionOffset(low + 1) + sects.dso_base;
740b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          break;
741b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        } else {
742b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          low = mid + 1;
743b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        }
744b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      } else {
745b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        high = mid;
746b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
747b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
748b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    encoding = pageIndex.encoding(low);
749b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    funcStart = pageIndex.functionOffset(low) + sects.dso_base;
750b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (pc < funcStart) {
751b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (log)
752b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        fprintf(
753b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            stderr,
754b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
755b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
756b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return false;
757b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
758b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (pc > funcEnd) {
759b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (log)
760b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        fprintf(
761b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            stderr,
762b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n",
763b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd);
764b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return false;
765b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
766b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) {
767b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // compressed page
768b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    UnwindSectionCompressedPageHeader<A> pageHeader(_addressSpace,
769b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                    secondLevelAddr);
770b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    UnwindSectionCompressedArray<A> pageIndex(
771b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _addressSpace, secondLevelAddr + pageHeader.entryPageOffset());
772b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    const uint32_t targetFunctionPageOffset =
773b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        (uint32_t)(targetFunctionOffset - firstLevelFunctionOffset);
774b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // binary search looks for entry with e where index[e].offset <= pc <
775b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // index[e+1].offset
776b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (log)
777b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      fprintf(stderr, "\tbinary search of compressed page starting at "
778b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                      "secondLevelAddr=0x%llX\n",
779b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik              (uint64_t) secondLevelAddr);
780b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    low = 0;
781b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    last = pageHeader.entryCount() - 1;
782b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    high = pageHeader.entryCount();
783b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    while (low < high) {
784b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      uint32_t mid = (low + high) / 2;
785b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (pageIndex.functionOffset(mid) <= targetFunctionPageOffset) {
786b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        if ((mid == last) ||
787b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            (pageIndex.functionOffset(mid + 1) > targetFunctionPageOffset)) {
788b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          low = mid;
789b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          break;
790b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        } else {
791b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          low = mid + 1;
792b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        }
793b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      } else {
794b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        high = mid;
795b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
796b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
797b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset
798b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                              + sects.dso_base;
799b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (low < last)
800b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      funcEnd =
801b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          pageIndex.functionOffset(low + 1) + firstLevelFunctionOffset
802b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                              + sects.dso_base;
803b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    else
804b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
805b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (pc < funcStart) {
806b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second  "
807b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                           "level compressed unwind table. funcStart=0x%llX\n",
808b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                            (uint64_t) pc, (uint64_t) funcStart);
809b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return false;
810b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
811b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (pc > funcEnd) {
812b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second  "
813b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                          "level compressed unwind table. funcEnd=0x%llX\n",
814b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                           (uint64_t) pc, (uint64_t) funcEnd);
815b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return false;
816b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
817b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    uint16_t encodingIndex = pageIndex.encodingIndex(low);
818b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (encodingIndex < sectionHeader.commonEncodingsArrayCount()) {
819b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      // encoding is in common table in section header
820b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      encoding = _addressSpace.get32(
821b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          sects.compact_unwind_section +
822b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          sectionHeader.commonEncodingsArraySectionOffset() +
823b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          encodingIndex * sizeof(uint32_t));
824b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    } else {
825b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      // encoding is in page specific table
826b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      uint16_t pageEncodingIndex =
827b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount();
828b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      encoding = _addressSpace.get32(secondLevelAddr +
829b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                     pageHeader.encodingsPageOffset() +
830b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                     pageEncodingIndex * sizeof(uint32_t));
831b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
832b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  } else {
833b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second "
834b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                         "level page\n",
835b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                          (uint64_t) sects.compact_unwind_section);
836b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return false;
837b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
838b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
839b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // look up LSDA, if encoding says function has one
840b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (encoding & UNWIND_HAS_LSDA) {
841b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    UnwindSectionLsdaArray<A> lsdaIndex(_addressSpace, lsdaArrayStartAddr);
842b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    uint32_t funcStartOffset = (uint32_t)(funcStart - sects.dso_base);
843b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    low = 0;
844b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    high = (uint32_t)(lsdaArrayEndAddr - lsdaArrayStartAddr) /
845b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                    sizeof(unwind_info_section_header_lsda_index_entry);
846b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // binary search looks for entry with exact match for functionOffset
847b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (log)
848b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      fprintf(stderr,
849b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik              "\tbinary search of lsda table for targetFunctionOffset=0x%08X\n",
850b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik              funcStartOffset);
851b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    while (low < high) {
852b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      uint32_t mid = (low + high) / 2;
853b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (lsdaIndex.functionOffset(mid) == funcStartOffset) {
854b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        lsda = lsdaIndex.lsdaOffset(mid) + sects.dso_base;
855b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        break;
856b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      } else if (lsdaIndex.functionOffset(mid) < funcStartOffset) {
857b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        low = mid + 1;
858b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      } else {
859b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        high = mid;
860b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
861b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
862b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (lsda == 0) {
863b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for "
864b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                    "pc=0x%0llX, but lsda table has no entry\n",
865b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                    encoding, (uint64_t) pc);
866b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return false;
867b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
868b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
869b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
870b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // extact personality routine, if encoding says function has one
871b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >>
872b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                              (__builtin_ctz(UNWIND_PERSONALITY_MASK));
873b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (personalityIndex != 0) {
874b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    --personalityIndex; // change 1-based to zero-based index
875b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (personalityIndex > sectionHeader.personalityArrayCount()) {
876b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d,  "
877b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                            "but personality table has only %d entires\n",
878b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                            encoding, personalityIndex,
879b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                            sectionHeader.personalityArrayCount());
880b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return false;
881b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
882b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    uint32_t personalityDelta = _addressSpace.get32(
883b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        sects.compact_unwind_section + sectionHeader.personalityArraySectionOffset() +
884b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        personalityIndex * sizeof(uint32_t));
885b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    pint_t personalityPointer = sects.dso_base + (pint_t)personalityDelta;
886b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    personality = _addressSpace.getP(personalityPointer);
887b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (log)
888b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
889b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                      "personalityDelta=0x%08X, personality=0x%08llX\n",
890b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik              (uint64_t) pc, personalityDelta, (uint64_t) personality);
891b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
892b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
893b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (log)
894b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), "
895b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                    "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n",
896b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart);
897b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.start_ip = funcStart;
898b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.end_ip = funcEnd;
899b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.lsda = lsda;
900b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.handler = personality;
901b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.gp = 0;
902b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.flags = 0;
903b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.format = encoding;
904b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.unwind_info = 0;
905b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.unwind_info_size = 0;
906b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _info.extra = sects.dso_base;
907b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return true;
908b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
909b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
910b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
911b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
912b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
913b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
914b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t pc = (pint_t)this->getReg(UNW_REG_IP);
915b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
916b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // If the last line of a function is a "throw" the compiler sometimes
917b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // emits no instructions after the call to __cxa_throw.  This means
918b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // the return address is actually the start of the next function.
919b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // To disambiguate this, back up the pc when we know it is a return
920b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // address.
921b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (isReturnAddress)
922b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    --pc;
923b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
924b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // Ask address space object to find unwind sections for this pc.
925b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  UnwindInfoSections sects;
926b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (_addressSpace.findUnwindSections(pc, sects)) {
927b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
928b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // If there is a compact unwind encoding table, look there first.
929b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (sects.compact_unwind_section != 0) {
930b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (this->getInfoFromCompactEncodingSection(pc, sects)) {
931b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
932b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        // Found info in table, done unless encoding says to use dwarf.
933b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        uint32_t dwarfOffset;
934b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        if ((sects.dwarf_section != 0) && compactSaysUseDwarf(&dwarfOffset)) {
935b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          if (this->getInfoFromDwarfSection(pc, sects, dwarfOffset)) {
936b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            // found info in dwarf, done
937b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik            return;
938b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          }
939b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        }
940b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  #endif
941b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        // If unwind table has entry, but entry says there is no unwind info,
942b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        // record that we have no unwind info.
943b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        if (_info.format == 0)
944b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _unwindInfoMissing = true;
945b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        return;
946b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
947b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
948b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
949b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
950b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
951b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // If there is dwarf unwind info, look there next.
952b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (sects.dwarf_section != 0) {
953b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (this->getInfoFromDwarfSection(pc, sects)) {
954b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        // found info in dwarf, done
955b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        return;
956b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
957b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
958b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
959b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
960b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
961b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
962b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // There is no static unwind info for this pc. Look to see if an FDE was
963b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // dynamically registered for it.
964b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);
965b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (cachedFDE != 0) {
966b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
967b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
968b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace,
969b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                cachedFDE, &fdeInfo, &cieInfo);
970b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (msg == NULL) {
971b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      typename CFI_Parser<A>::PrologInfo prolog;
972b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
973b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                                pc, &prolog)) {
974b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        // save off parsed FDE info
975b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.start_ip         = fdeInfo.pcStart;
976b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.end_ip           = fdeInfo.pcEnd;
977b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.lsda             = fdeInfo.lsda;
978b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.handler          = cieInfo.personality;
979b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.gp               = prolog.spExtraArgSize;
980b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                  // Some frameless functions need SP
981b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                  // altered when resuming in function.
982b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.flags            = 0;
983b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.format           = dwarfEncoding();
984b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.unwind_info      = fdeInfo.fdeStart;
985b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
986b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        _info.extra            = 0;
987b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        return;
988b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
989b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
990b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
991b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
992b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // Lastly, ask AddressSpace object about platform specific ways to locate
993b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // other FDEs.
994b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t fde;
995b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (_addressSpace.findOtherFDE(pc, fde)) {
996b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
997b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
998b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
999b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      // Double check this FDE is for a function that includes the pc.
1000b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
1001b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        typename CFI_Parser<A>::PrologInfo prolog;
1002b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo,
1003b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                cieInfo, pc, &prolog)) {
1004b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          // save off parsed FDE info
1005b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.start_ip         = fdeInfo.pcStart;
1006b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.end_ip           = fdeInfo.pcEnd;
1007b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.lsda             = fdeInfo.lsda;
1008b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.handler          = cieInfo.personality;
1009b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.gp               = prolog.spExtraArgSize;
1010b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.flags            = 0;
1011b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.format           = dwarfEncoding();
1012b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.unwind_info      = fdeInfo.fdeStart;
1013b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
1014b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          _info.extra            = 0;
1015b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik          return;
1016b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik        }
1017b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      }
1018b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
1019b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
1020b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
1021b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1022b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // no unwind info, flag that we can't reliably unwind
1023b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  _unwindInfoMissing = true;
1024b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
1025b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1026b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
1027b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikint UnwindCursor<A, R>::step() {
1028b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // Bottom of stack is defined is when no unwind info cannot be found.
1029b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (_unwindInfoMissing)
1030b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return UNW_STEP_END;
1031b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1032b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // Use unwinding info to modify register set as if function returned.
1033b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int result;
1034b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
1035b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  result = this->stepWithCompactEncoding();
1036b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#elif _LIBUNWIND_SUPPORT_DWARF_UNWIND
1037b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  result = this->stepWithDwarfFDE();
1038b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else
1039b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  #error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or _LIBUNWIND_SUPPORT_DWARF_UNWIND
1040b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
1041b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1042b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // update info based on new PC
1043b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (result == UNW_STEP_SUCCESS) {
1044b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    this->setInfoBasedOnIPRegister(true);
1045b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (_unwindInfoMissing)
1046b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return UNW_STEP_END;
10477dfc5215ff08e992ffe88c577ba15d641e610d75Joerg Sonnenberger    if (_info.gp)
10487dfc5215ff08e992ffe88c577ba15d641e610d75Joerg Sonnenberger      setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp);
1049b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
1050b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1051b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return result;
1052b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
1053b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1054b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
1055b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikvoid UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) {
1056b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  *info = _info;
1057b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
1058b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1059b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename A, typename R>
1060b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
1061b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                           unw_word_t *offset) {
1062b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return _addressSpace.findFunctionName((pint_t)this->getReg(UNW_REG_IP),
1063b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                         buf, bufLen, offset);
1064b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
1065b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1066b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; // namespace libunwind
1067b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
1068b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // __UNWINDCURSOR_HPP__
1069