1b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===------------------------- AddressSpace.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// Abstracts accessing local vs remote address spaces.
10b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//
11b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===----------------------------------------------------------------------===//
12b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
13b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifndef __ADDRESSSPACE_HPP__
14b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#define __ADDRESSSPACE_HPP__
15b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
16b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdint.h>
17b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdio.h>
18b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdlib.h>
19e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include <string.h>
20b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <dlfcn.h>
21b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
22b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__
23034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik#include <mach-o/getsect.h>
24b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziknamespace libunwind {
25b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik   bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde);
26b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
27b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
28b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
29b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "libunwind.h"
30b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "config.h"
31b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "dwarf2.h"
32b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "Registers.hpp"
33b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
34e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI
35e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __linux__
36e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
37e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef long unsigned int *_Unwind_Ptr;
38e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr addr, int *len);
39e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
40e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system.
41e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#define dl_unwind_find_exidx __gnu_Unwind_Find_exidx
42e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
43e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else
44e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include <link.h>
45e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
46e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif  // LIBCXXABI_ARM_EHABI
47e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert
48b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziknamespace libunwind {
49b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
50b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Used by findUnwindSections() to return info about needed sections.
51b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct UnwindInfoSections {
52e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if _LIBUNWIND_SUPPORT_DWARF_UNWIND || _LIBUNWIND_SUPPORT_DWARF_INDEX ||       \
53e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    _LIBUNWIND_SUPPORT_COMPACT_UNWIND
54e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  // No dso_base for ARM EHABI.
55e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uintptr_t       dso_base;
56e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
57b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
58b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t       dwarf_section;
59b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t       dwarf_section_length;
60b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
61b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_INDEX
62b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t       dwarf_index_section;
63b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t       dwarf_index_section_length;
64b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
65b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
66b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t       compact_unwind_section;
67b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t       compact_unwind_section_length;
68b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
69e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI
70e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uintptr_t       arm_section;
71e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uintptr_t       arm_section_length;
72e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif
73b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
74b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
75b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
76b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// LocalAddressSpace is used as a template parameter to UnwindCursor when
77b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unwinding a thread in the same process.  The wrappers compile away,
78b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// making local unwinds fast.
79b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass __attribute__((visibility("hidden"))) LocalAddressSpace {
80b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
81b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __LP64__
82b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typedef uint64_t pint_t;
83b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typedef int64_t  sint_t;
84b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else
85b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typedef uint32_t pint_t;
86b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typedef int32_t  sint_t;
87b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
88e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uint8_t         get8(pint_t addr) {
89e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint8_t val;
90e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    memcpy(&val, (void *)addr, sizeof(val));
91e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return val;
92e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  }
93e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uint16_t         get16(pint_t addr) {
94e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint16_t val;
95e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    memcpy(&val, (void *)addr, sizeof(val));
96e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return val;
97e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  }
98e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uint32_t         get32(pint_t addr) {
99e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint32_t val;
100e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    memcpy(&val, (void *)addr, sizeof(val));
101e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return val;
102e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  }
103e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  uint64_t         get64(pint_t addr) {
104e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    uint64_t val;
105e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    memcpy(&val, (void *)addr, sizeof(val));
106e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return val;
107e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  }
108e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  double           getDouble(pint_t addr) {
109e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    double val;
110e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    memcpy(&val, (void *)addr, sizeof(val));
111e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return val;
112e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  }
113e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  v128             getVector(pint_t addr) {
114e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    v128 val;
115e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    memcpy(&val, (void *)addr, sizeof(val));
116e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return val;
117e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  }
118b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t       getP(pint_t addr);
119b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static uint64_t getULEB128(pint_t &addr, pint_t end);
120b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static int64_t  getSLEB128(pint_t &addr, pint_t end);
121b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
122b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
123b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
124b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                        unw_word_t *offset);
125b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
126b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool findOtherFDE(pint_t targetAddr, pint_t &fde);
127b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
128b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  static LocalAddressSpace sThisAddressSpace;
129b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
130b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
131b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline uintptr_t LocalAddressSpace::getP(pint_t addr) {
132b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __LP64__
133b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return get64(addr);
134b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else
135b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return get32(addr);
136b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
137b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
138b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
139b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Read a ULEB128 into a 64-bit word.
140b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) {
141b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const uint8_t *p = (uint8_t *)addr;
142b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const uint8_t *pend = (uint8_t *)end;
143b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint64_t result = 0;
144b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int bit = 0;
145b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  do {
146b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    uint64_t b;
147b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
148b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (p == pend)
149b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _LIBUNWIND_ABORT("truncated uleb128 expression");
150b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
151b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    b = *p & 0x7f;
152b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
153b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (bit >= 64 || b << bit >> bit != b) {
154b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _LIBUNWIND_ABORT("malformed uleb128 expression");
155b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    } else {
156b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      result |= b << bit;
157b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      bit += 7;
158b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
159b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  } while (*p++ >= 0x80);
160b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  addr = (pint_t) p;
161b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return result;
162b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
163b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
164b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Read a SLEB128 into a 64-bit word.
165b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
166b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const uint8_t *p = (uint8_t *)addr;
167b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const uint8_t *pend = (uint8_t *)end;
168b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int64_t result = 0;
169b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int bit = 0;
170b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint8_t byte;
171b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  do {
172b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (p == pend)
173b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      _LIBUNWIND_ABORT("truncated sleb128 expression");
174b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    byte = *p++;
175b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result |= ((byte & 0x7f) << bit);
176b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    bit += 7;
177b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  } while (byte & 0x80);
178b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // sign extend negative numbers
179b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if ((byte & 0x40) != 0)
180b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result |= (-1LL) << bit;
181b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  addr = (pint_t) p;
182b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return result;
183b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
184b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
185b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
186b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                         pint_t end,
187b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                         uint8_t encoding) {
188b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t startAddr = addr;
189b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  const uint8_t *p = (uint8_t *)addr;
190b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t result;
191b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
192b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // first get value
193b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  switch (encoding & 0x0F) {
194b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_ptr:
195b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = getP(addr);
196b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    p += sizeof(pint_t);
197b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    addr = (pint_t) p;
198b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
199b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_uleb128:
200b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = (pint_t)getULEB128(addr, end);
201b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
202b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_udata2:
203b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = get16(addr);
204b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    p += 2;
205b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    addr = (pint_t) p;
206b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
207b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_udata4:
208b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = get32(addr);
209b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    p += 4;
210b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    addr = (pint_t) p;
211b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
212b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_udata8:
213b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = (pint_t)get64(addr);
214b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    p += 8;
215b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    addr = (pint_t) p;
216b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
217b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_sleb128:
218b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = (pint_t)getSLEB128(addr, end);
219b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
220b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_sdata2:
221e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    // Sign extend from signed 16-bit value.
222e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    result = (pint_t)(int16_t)get16(addr);
223b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    p += 2;
224b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    addr = (pint_t) p;
225b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
226b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_sdata4:
227e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    // Sign extend from signed 32-bit value.
228e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    result = (pint_t)(int32_t)get32(addr);
229b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    p += 4;
230b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    addr = (pint_t) p;
231b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
232b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_sdata8:
233b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = (pint_t)get64(addr);
234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    p += 8;
235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    addr = (pint_t) p;
236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  default:
238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _LIBUNWIND_ABORT("unknown pointer encoding");
239b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
240b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // then add relative offset
242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  switch (encoding & 0x70) {
243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_absptr:
244b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    // do nothing
245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
246b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_pcrel:
247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result += startAddr;
248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_textrel:
250b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported");
251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_datarel:
253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _LIBUNWIND_ABORT("DW_EH_PE_datarel pointer encoding not supported");
254b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_funcrel:
256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported");
257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  case DW_EH_PE_aligned:
259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _LIBUNWIND_ABORT("DW_EH_PE_aligned pointer encoding not supported");
260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  default:
262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    _LIBUNWIND_ABORT("unknown pointer encoding");
263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    break;
264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
265b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (encoding & DW_EH_PE_indirect)
267b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    result = getP(result);
268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
269b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return result;
270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
272034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik#if __APPLE__
273034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik  struct dyld_unwind_sections
274034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik  {
275034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    const struct mach_header*   mh;
276034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    const void*                 dwarf_section;
277034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    uintptr_t                   dwarf_section_length;
278034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    const void*                 compact_unwind_section;
279034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    uintptr_t                   compact_unwind_section_length;
280034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik  };
28165b726605835d1b3947d648497729a4be05deddeNick Kledzik  #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \
28265b726605835d1b3947d648497729a4be05deddeNick Kledzik                                 && (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) \
28365b726605835d1b3947d648497729a4be05deddeNick Kledzik      || defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
284034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    // In 10.7.0 or later, libSystem.dylib implements this function.
285034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
286034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik  #else
287034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    // In 10.6.x and earlier, we need to implement this functionality.
288034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    static inline bool _dyld_find_unwind_sections(void* addr,
289034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik                                                    dyld_unwind_sections* info) {
290034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      // Find mach-o image containing address.
291034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      Dl_info dlinfo;
292034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      if (!dladdr(addr, &dlinfo))
293034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik        return false;
294034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      const mach_header *mh = (const mach_header *)dlinfo.dli_saddr;
295034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik
296034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      // Find dwarf unwind section in that image.
297034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      unsigned long size;
298034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      const uint8_t *p = getsectiondata(mh, "__TEXT", "__eh_frame", &size);
299034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      if (!p)
300034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik        return false;
301034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik
302034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      // Fill in return struct.
303034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      info->mh = mh;
304034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      info->dwarf_section = p;
305034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      info->dwarf_section_length = size;
306034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      info->compact_unwind_section = 0;
307034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      info->compact_unwind_section_length = 0;
308034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik
309034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik      return true;
310034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik    }
311034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik  #endif
312034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik#endif
313034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik
314b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
315b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                  UnwindInfoSections &info) {
316b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__
317b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  dyld_unwind_sections dyldInfo;
318b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
319b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    info.dso_base                      = (uintptr_t)dyldInfo.mh;
320b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
321b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    info.dwarf_section                 = (uintptr_t)dyldInfo.dwarf_section;
322b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    info.dwarf_section_length          = dyldInfo.dwarf_section_length;
323b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #endif
324b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    info.compact_unwind_section        = (uintptr_t)dyldInfo.compact_unwind_section;
325b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length;
326b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    return true;
327b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
328e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#elif LIBCXXABI_ARM_EHABI
329e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  int length = 0;
330e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  info.arm_section = (uintptr_t) dl_unwind_find_exidx(
331e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert      (_Unwind_Ptr) targetAddr, &length);
332e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  info.arm_section_length = (uintptr_t)length;
333e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n",
334e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert                             info.arm_section, info.arm_section_length);
335e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  if (info.arm_section && info.arm_section_length)
336e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert    return true;
337b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
338b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
339b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return false;
340b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
341b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
342b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
343b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
344b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__
345b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde));
346b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else
347b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // TO DO: if OS has way to dynamically register FDEs, check that.
348e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  (void)targetAddr;
349e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert  (void)fde;
350b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return false;
351b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif
352b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
353b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
354b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
355b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                size_t bufLen,
356b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                                unw_word_t *offset) {
357e085735cbedc82b1064f05ff796e32e906a95036Dan Albert  Dl_info dyldInfo;
358b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  if (dladdr((void *)addr, &dyldInfo)) {
359b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    if (dyldInfo.dli_sname != NULL) {
360e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert      snprintf(buf, bufLen, "%s", dyldInfo.dli_sname);
361b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      *offset = (addr - (pint_t) dyldInfo.dli_saddr);
362b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik      return true;
363b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik    }
364b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  }
365b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return false;
366b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
367b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
368b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
369b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
370b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if UNW_REMOTE
371b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
372b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// OtherAddressSpace is used as a template parameter to UnwindCursor when
373b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unwinding a thread in the another process.  The other process can be a
374b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// different endianness and a different pointer size which is handled by
375b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// the P template parameter.
376b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P>
377b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass OtherAddressSpace {
378b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic:
379b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  OtherAddressSpace(task_t task) : fTask(task) {}
380b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
381b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  typedef typename P::uint_t pint_t;
382b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
383b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint8_t   get8(pint_t addr);
384b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint16_t  get16(pint_t addr);
385b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint32_t  get32(pint_t addr);
386b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint64_t  get64(pint_t addr);
387b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t    getP(pint_t addr);
388b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint64_t  getULEB128(pint_t &addr, pint_t end);
389b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  int64_t   getSLEB128(pint_t &addr, pint_t end);
390b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  pint_t    getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
391b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool      findFunctionName(pint_t addr, char *buf, size_t bufLen,
392b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                        unw_word_t *offset);
393b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool      findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
394b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  bool      findOtherFDE(pint_t targetAddr, pint_t &fde);
395b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate:
396b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  void *localCopy(pint_t addr);
397b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
398b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  task_t fTask;
399b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
400b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
401b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint8_t OtherAddressSpace<P>::get8(pint_t addr) {
402b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return *((uint8_t *)localCopy(addr));
403b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
404b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
405b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint16_t OtherAddressSpace<P>::get16(pint_t addr) {
406b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return P::E::get16(*(uint16_t *)localCopy(addr));
407b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
408b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
409b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint32_t OtherAddressSpace<P>::get32(pint_t addr) {
410b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return P::E::get32(*(uint32_t *)localCopy(addr));
411b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
412b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
413b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint64_t OtherAddressSpace<P>::get64(pint_t addr) {
414b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return P::E::get64(*(uint64_t *)localCopy(addr));
415b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
416b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
417b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P>
418b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename P::uint_t OtherAddressSpace<P>::getP(pint_t addr) {
419b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return P::getP(*(uint64_t *)localCopy(addr));
420b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
421b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
422b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P>
423b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikuint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) {
424b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t size = (end - addr);
425b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
426b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  LocalAddressSpace::pint_t sladdr = laddr;
427b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size);
428b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  addr += (laddr - sladdr);
429b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return result;
430b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
431b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
432b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P>
433b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikint64_t OtherAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) {
434b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uintptr_t size = (end - addr);
435b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
436b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  LocalAddressSpace::pint_t sladdr = laddr;
437b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size);
438b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  addr += (laddr - sladdr);
439b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  return result;
440b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
441b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
442b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> void *OtherAddressSpace<P>::localCopy(pint_t addr) {
443b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // FIX ME
444b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
445b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
446b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P>
447b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool OtherAddressSpace<P>::findFunctionName(pint_t addr, char *buf,
448b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik                                            size_t bufLen, unw_word_t *offset) {
449b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  // FIX ME
450b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}
451b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
452b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space is the base class that abstract unw_addr_space_t type in
453b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// libunwind.h points to.
454b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space {
455b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  cpu_type_t cpuType;
456b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  task_t taskPort;
457b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
458b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
459b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points
460b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// to when examining
461b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// a 32-bit intel process.
462b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space_i386 : public unw_addr_space {
463b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  unw_addr_space_i386(task_t task) : oas(task) {}
464b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  OtherAddressSpace<Pointer32<LittleEndian> > oas;
465b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
466b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
467b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t
468b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// points to when examining
469b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// a 64-bit intel process.
470b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space_x86_64 : public unw_addr_space {
471b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  unw_addr_space_x86_64(task_t task) : oas(task) {}
472b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  OtherAddressSpace<Pointer64<LittleEndian> > oas;
473b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
474b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
475b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points
476b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// to when examining
477b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// a 32-bit PowerPC process.
478b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space_ppc : public unw_addr_space {
479b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  unw_addr_space_ppc(task_t task) : oas(task) {}
480b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik  OtherAddressSpace<Pointer32<BigEndian> > oas;
481b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik};
482b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
483b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // UNW_REMOTE
484b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
485b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} // namespace libunwind
486b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik
487b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // __ADDRESSSPACE_HPP__
488