1675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//===------------------------- AddressSpace.hpp ---------------------------===//
2675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//
3675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//                     The LLVM Compiler Infrastructure
4675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//
5675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// This file is dual licensed under the MIT and the University of Illinois Open
6675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// Source Licenses. See LICENSE.TXT for details.
7675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//
8675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//
9675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// Abstracts accessing local vs remote address spaces.
10675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//
11675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//===----------------------------------------------------------------------===//
12675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
13675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifndef __ADDRESSSPACE_HPP__
14675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#define __ADDRESSSPACE_HPP__
15675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
16675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdint.h>
17675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdio.h>
18675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdlib.h>
19675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <string.h>
20675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
21675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifndef _LIBUNWIND_IS_BAREMETAL
22675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <dlfcn.h>
23675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
24675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
25675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__
26675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <mach-o/getsect.h>
27675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolnamespace libunwind {
28675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool   bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde);
29675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
30675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
31675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
32675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "libunwind.h"
33675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "config.h"
34675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "dwarf2.h"
35675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "Registers.hpp"
36675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
3761278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#if _LIBUNWIND_ARM_EHABI
38675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __linux__
39675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
40675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltypedef long unsigned int *_Unwind_Ptr;
41675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolextern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr addr, int *len);
42675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
43675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system.
44675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#define dl_unwind_find_exidx __gnu_Unwind_Find_exidx
45675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
46675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#elif !defined(_LIBUNWIND_IS_BAREMETAL)
47675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <link.h>
48675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else // !defined(_LIBUNWIND_IS_BAREMETAL)
49675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// When statically linked on bare-metal, the symbols for the EH table are looked
50675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// up without going through the dynamic loader.
51675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct EHTEntry {
52675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint32_t functionOffset;
53675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint32_t unwindOpcodes;
54675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
55675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolextern EHTEntry __exidx_start;
56675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolextern EHTEntry __exidx_end;
57675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif // !defined(_LIBUNWIND_IS_BAREMETAL)
5861278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#endif // _LIBUNWIND_ARM_EHABI
59675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
60f67c63591cb6509181f74987578699c51c440b2eEd Schouten#if defined(__CloudABI__) || defined(__FreeBSD__) || defined(__linux__)
61675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_UNWIND && _LIBUNWIND_SUPPORT_DWARF_INDEX
62675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <link.h>
63f67c63591cb6509181f74987578699c51c440b2eEd Schouten// Macro for machine-independent access to the ELF program headers. This
64f67c63591cb6509181f74987578699c51c440b2eEd Schouten// macro is not available on some systems (e.g., FreeBSD). On these
65f67c63591cb6509181f74987578699c51c440b2eEd Schouten// systems the data structures are just called Elf_XXX. Define ElfW()
66f67c63591cb6509181f74987578699c51c440b2eEd Schouten// locally.
67f67c63591cb6509181f74987578699c51c440b2eEd Schouten#if !defined(ElfW)
68f67c63591cb6509181f74987578699c51c440b2eEd Schouten#define ElfW(type) Elf_##type
69f67c63591cb6509181f74987578699c51c440b2eEd Schouten#endif
70675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "EHHeaderParser.hpp"
71675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
72675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
73675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
74675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolnamespace libunwind {
75675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
76675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// Used by findUnwindSections() to return info about needed sections.
77675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct UnwindInfoSections {
78675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_UNWIND || _LIBUNWIND_SUPPORT_DWARF_INDEX ||       \
79675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    _LIBUNWIND_SUPPORT_COMPACT_UNWIND
80675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // No dso_base for ARM EHABI.
81675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       dso_base;
82675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
83675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
84675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       dwarf_section;
85675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       dwarf_section_length;
86675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
87675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_INDEX
88675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       dwarf_index_section;
89675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       dwarf_index_section_length;
90675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
91675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
92675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       compact_unwind_section;
93675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       compact_unwind_section_length;
94675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
9561278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#if _LIBUNWIND_ARM_EHABI
96675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       arm_section;
97675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       arm_section_length;
98675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
99675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
100675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
101675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
102675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// LocalAddressSpace is used as a template parameter to UnwindCursor when
103675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unwinding a thread in the same process.  The wrappers compile away,
104675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// making local unwinds fast.
105675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolclass __attribute__((visibility("hidden"))) LocalAddressSpace {
106675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolpublic:
107675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __LP64__
108675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  typedef uint64_t pint_t;
109675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  typedef int64_t  sint_t;
110675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else
111675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  typedef uint32_t pint_t;
112675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  typedef int32_t  sint_t;
113675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
114675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint8_t         get8(pint_t addr) {
115675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uint8_t val;
116675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    memcpy(&val, (void *)addr, sizeof(val));
117675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return val;
118675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
119675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint16_t         get16(pint_t addr) {
120675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uint16_t val;
121675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    memcpy(&val, (void *)addr, sizeof(val));
122675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return val;
123675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
124675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint32_t         get32(pint_t addr) {
125675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uint32_t val;
126675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    memcpy(&val, (void *)addr, sizeof(val));
127675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return val;
128675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
129675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint64_t         get64(pint_t addr) {
130675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uint64_t val;
131675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    memcpy(&val, (void *)addr, sizeof(val));
132675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return val;
133675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
134675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  double           getDouble(pint_t addr) {
135675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    double val;
136675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    memcpy(&val, (void *)addr, sizeof(val));
137675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return val;
138675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
139675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  v128             getVector(pint_t addr) {
140675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    v128 val;
141675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    memcpy(&val, (void *)addr, sizeof(val));
142675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return val;
143675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
144675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t       getP(pint_t addr);
145675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  static uint64_t getULEB128(pint_t &addr, pint_t end);
146675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  static int64_t  getSLEB128(pint_t &addr, pint_t end);
147675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
148675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
149675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                     pint_t datarelBase = 0);
150675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
151675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                        unw_word_t *offset);
152675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
153675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  bool findOtherFDE(pint_t targetAddr, pint_t &fde);
154675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
155675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  static LocalAddressSpace sThisAddressSpace;
156675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
157675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
158675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline uintptr_t LocalAddressSpace::getP(pint_t addr) {
159675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __LP64__
160675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return get64(addr);
161675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else
162675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return get32(addr);
163675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
164675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
165675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
166675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// Read a ULEB128 into a 64-bit word.
167675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) {
168675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  const uint8_t *p = (uint8_t *)addr;
169675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  const uint8_t *pend = (uint8_t *)end;
170675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint64_t result = 0;
171675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  int bit = 0;
172675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  do {
173675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uint64_t b;
174675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
175675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    if (p == pend)
176675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      _LIBUNWIND_ABORT("truncated uleb128 expression");
177675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
178675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    b = *p & 0x7f;
179675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
180675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    if (bit >= 64 || b << bit >> bit != b) {
181675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      _LIBUNWIND_ABORT("malformed uleb128 expression");
182675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    } else {
183675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      result |= b << bit;
184675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      bit += 7;
185675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    }
186675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  } while (*p++ >= 0x80);
187675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  addr = (pint_t) p;
188675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return result;
189675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
190675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
191675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// Read a SLEB128 into a 64-bit word.
192675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
193675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  const uint8_t *p = (uint8_t *)addr;
194675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  const uint8_t *pend = (uint8_t *)end;
195675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  int64_t result = 0;
196675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  int bit = 0;
197675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint8_t byte;
198675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  do {
199675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    if (p == pend)
200675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      _LIBUNWIND_ABORT("truncated sleb128 expression");
201675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    byte = *p++;
202675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result |= ((byte & 0x7f) << bit);
203675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    bit += 7;
204675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  } while (byte & 0x80);
205675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // sign extend negative numbers
206675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  if ((byte & 0x40) != 0)
207675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result |= (-1LL) << bit;
208675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  addr = (pint_t) p;
209675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return result;
210675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
211675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
212675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline LocalAddressSpace::pint_t
213675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem AbdulrasoolLocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
214675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                               pint_t datarelBase) {
215675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  pint_t startAddr = addr;
216675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  const uint8_t *p = (uint8_t *)addr;
217675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  pint_t result;
218675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
219675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // first get value
220675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  switch (encoding & 0x0F) {
221675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_ptr:
222675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = getP(addr);
223675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    p += sizeof(pint_t);
224675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    addr = (pint_t) p;
225675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
226675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_uleb128:
227675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = (pint_t)getULEB128(addr, end);
228675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
229675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_udata2:
230675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = get16(addr);
231675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    p += 2;
232675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    addr = (pint_t) p;
233675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
234675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_udata4:
235675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = get32(addr);
236675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    p += 4;
237675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    addr = (pint_t) p;
238675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
239675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_udata8:
240675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = (pint_t)get64(addr);
241675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    p += 8;
242675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    addr = (pint_t) p;
243675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
244675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_sleb128:
245675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = (pint_t)getSLEB128(addr, end);
246675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
247675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_sdata2:
248675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // Sign extend from signed 16-bit value.
249675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = (pint_t)(int16_t)get16(addr);
250675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    p += 2;
251675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    addr = (pint_t) p;
252675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
253675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_sdata4:
254675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // Sign extend from signed 32-bit value.
255675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = (pint_t)(int32_t)get32(addr);
256675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    p += 4;
257675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    addr = (pint_t) p;
258675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
259675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_sdata8:
260675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = (pint_t)get64(addr);
261675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    p += 8;
262675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    addr = (pint_t) p;
263675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
264675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  default:
265675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    _LIBUNWIND_ABORT("unknown pointer encoding");
266675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
267675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
268675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // then add relative offset
269675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  switch (encoding & 0x70) {
270675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_absptr:
271675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // do nothing
272675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
273675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_pcrel:
274675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result += startAddr;
275675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
276675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_textrel:
277675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    _LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported");
278675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
279675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_datarel:
280675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // DW_EH_PE_datarel is only valid in a few places, so the parameter has a
281675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // default value of 0, and we abort in the event that someone calls this
282675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // function with a datarelBase of 0 and DW_EH_PE_datarel encoding.
283675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    if (datarelBase == 0)
284675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      _LIBUNWIND_ABORT("DW_EH_PE_datarel is invalid with a datarelBase of 0");
285675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result += datarelBase;
286675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
287675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_funcrel:
288675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    _LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported");
289675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
290675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  case DW_EH_PE_aligned:
291675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    _LIBUNWIND_ABORT("DW_EH_PE_aligned pointer encoding not supported");
292675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
293675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  default:
294675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    _LIBUNWIND_ABORT("unknown pointer encoding");
295675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    break;
296675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
297675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
298675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  if (encoding & DW_EH_PE_indirect)
299675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    result = getP(result);
300675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
301675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return result;
302675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
303675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
304675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__
305675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  struct dyld_unwind_sections
306675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  {
307675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    const struct mach_header*   mh;
308675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    const void*                 dwarf_section;
309675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uintptr_t                   dwarf_section_length;
310675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    const void*                 compact_unwind_section;
311675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uintptr_t                   compact_unwind_section_length;
312675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  };
313675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \
314675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                                 && (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) \
315675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      || defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
316675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // In 10.7.0 or later, libSystem.dylib implements this function.
317675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
318675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  #else
319675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    // In 10.6.x and earlier, we need to implement this functionality.
320675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    static inline bool _dyld_find_unwind_sections(void* addr,
321675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                                                    dyld_unwind_sections* info) {
322675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      // Find mach-o image containing address.
323675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      Dl_info dlinfo;
324675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      if (!dladdr(addr, &dlinfo))
325675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        return false;
326675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      const mach_header *mh = (const mach_header *)dlinfo.dli_saddr;
327675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
328675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      // Find dwarf unwind section in that image.
329675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      unsigned long size;
330675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      const uint8_t *p = getsectiondata(mh, "__TEXT", "__eh_frame", &size);
331675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      if (!p)
332675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        return false;
333675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
334675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      // Fill in return struct.
335675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      info->mh = mh;
336675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      info->dwarf_section = p;
337675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      info->dwarf_section_length = size;
338675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      info->compact_unwind_section = 0;
339675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      info->compact_unwind_section_length = 0;
340675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
341675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      return true;
342675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    }
343675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  #endif
344675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
345675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
346675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
347675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                                                  UnwindInfoSections &info) {
348675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__
349675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  dyld_unwind_sections dyldInfo;
350675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
351675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    info.dso_base                      = (uintptr_t)dyldInfo.mh;
352675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
353675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    info.dwarf_section                 = (uintptr_t)dyldInfo.dwarf_section;
354675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    info.dwarf_section_length          = dyldInfo.dwarf_section_length;
355675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #endif
356675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    info.compact_unwind_section        = (uintptr_t)dyldInfo.compact_unwind_section;
357675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length;
358675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return true;
359675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
36061278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#elif _LIBUNWIND_ARM_EHABI
361675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #ifdef _LIBUNWIND_IS_BAREMETAL
362675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // Bare metal is statically linked, so no need to ask the dynamic loader
363675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  info.arm_section =        (uintptr_t)(&__exidx_start);
364675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start);
365675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #else
366675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  int length = 0;
367675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  info.arm_section = (uintptr_t) dl_unwind_find_exidx(
368675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      (_Unwind_Ptr) targetAddr, &length);
369675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  info.arm_section_length = (uintptr_t)length;
370675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #endif
371675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n",
372675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                             info.arm_section, info.arm_section_length);
373675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  if (info.arm_section && info.arm_section_length)
374675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    return true;
375675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#elif _LIBUNWIND_SUPPORT_DWARF_UNWIND
376675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_INDEX
377675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  struct dl_iterate_cb_data {
378675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    LocalAddressSpace *addressSpace;
379675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    UnwindInfoSections *sects;
380675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    uintptr_t targetAddr;
381675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  };
382675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
383675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  dl_iterate_cb_data cb_data = {this, &info, targetAddr};
384675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  int found = dl_iterate_phdr(
385675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      [](struct dl_phdr_info *pinfo, size_t, void *data) -> int {
386675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        auto cbdata = static_cast<dl_iterate_cb_data *>(data);
387675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        size_t object_length;
388675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        bool found_obj = false;
389675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        bool found_hdr = false;
390675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
391675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        assert(cbdata);
392675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        assert(cbdata->sects);
393675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
394675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        if (cbdata->targetAddr < pinfo->dlpi_addr) {
395675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool          return false;
396675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        }
397675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
3989ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#if !defined(Elf_Half)
3999ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov        typedef ElfW(Half) Elf_Half;
4009ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#endif
4019ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#if !defined(Elf_Phdr)
4029ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov        typedef ElfW(Phdr) Elf_Phdr;
4039ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#endif
4049ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov
4059ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov        for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
4069ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov          const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
407675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool          if (phdr->p_type == PT_LOAD) {
408675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr;
409675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            uintptr_t end = begin + phdr->p_memsz;
410675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
411675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool              cbdata->sects->dso_base = begin;
412675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool              object_length = phdr->p_memsz;
413675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool              found_obj = true;
414675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            }
415675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool          } else if (phdr->p_type == PT_GNU_EH_FRAME) {
416675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
417675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            uintptr_t eh_frame_hdr_start = pinfo->dlpi_addr + phdr->p_vaddr;
418675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
419675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
420675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
421675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
422675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                hdrInfo);
423675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
424675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool            found_hdr = true;
425675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool          }
426675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        }
427675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
428675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        if (found_obj && found_hdr) {
429675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool          cbdata->sects->dwarf_section_length = object_length;
430675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool          return true;
431675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        } else {
432675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool          return false;
433675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool        }
434675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      },
435675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      &cb_data);
436675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return static_cast<bool>(found);
437675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else
438675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
439675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
440675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
441675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
442675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return false;
443675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
444675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
445675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
446675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
447675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__
448675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde));
449675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else
450675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // TO DO: if OS has way to dynamically register FDEs, check that.
451675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  (void)targetAddr;
452675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  (void)fde;
453675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return false;
454675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
455675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
456675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
457675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
458675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                                                size_t bufLen,
459675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                                                unw_word_t *offset) {
460675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifndef _LIBUNWIND_IS_BAREMETAL
461675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  Dl_info dyldInfo;
462675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  if (dladdr((void *)addr, &dyldInfo)) {
463675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    if (dyldInfo.dli_sname != NULL) {
464675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      snprintf(buf, bufLen, "%s", dyldInfo.dli_sname);
465675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      *offset = (addr - (pint_t) dyldInfo.dli_saddr);
466675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool      return true;
467675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool    }
468675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  }
469675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif
470675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return false;
471675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
472675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
473675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
474675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
475675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef UNW_REMOTE
476675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
477675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// OtherAddressSpace is used as a template parameter to UnwindCursor when
478675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unwinding a thread in the another process.  The other process can be a
479675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// different endianness and a different pointer size which is handled by
480675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// the P template parameter.
481675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P>
482675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolclass OtherAddressSpace {
483675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolpublic:
484675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  OtherAddressSpace(task_t task) : fTask(task) {}
485675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
486675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  typedef typename P::uint_t pint_t;
487675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
488675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint8_t   get8(pint_t addr);
489675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint16_t  get16(pint_t addr);
490675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint32_t  get32(pint_t addr);
491675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint64_t  get64(pint_t addr);
492675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  pint_t    getP(pint_t addr);
493675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint64_t  getULEB128(pint_t &addr, pint_t end);
494675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  int64_t   getSLEB128(pint_t &addr, pint_t end);
495675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  pint_t    getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
496675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                        pint_t datarelBase = 0);
497675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  bool      findFunctionName(pint_t addr, char *buf, size_t bufLen,
498675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                        unw_word_t *offset);
499675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  bool      findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
500675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  bool      findOtherFDE(pint_t targetAddr, pint_t &fde);
501675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolprivate:
502675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  void *localCopy(pint_t addr);
503675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
504675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  task_t fTask;
505675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
506675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
507675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint8_t OtherAddressSpace<P>::get8(pint_t addr) {
508675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return *((uint8_t *)localCopy(addr));
509675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
510675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
511675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint16_t OtherAddressSpace<P>::get16(pint_t addr) {
512675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return P::E::get16(*(uint16_t *)localCopy(addr));
513675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
514675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
515675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint32_t OtherAddressSpace<P>::get32(pint_t addr) {
516675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return P::E::get32(*(uint32_t *)localCopy(addr));
517675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
518675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
519675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint64_t OtherAddressSpace<P>::get64(pint_t addr) {
520675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return P::E::get64(*(uint64_t *)localCopy(addr));
521675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
522675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
523675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P>
524675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltypename P::uint_t OtherAddressSpace<P>::getP(pint_t addr) {
525675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return P::getP(*(uint64_t *)localCopy(addr));
526675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
527675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
528675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P>
529675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooluint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) {
530675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t size = (end - addr);
531675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
532675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  LocalAddressSpace::pint_t sladdr = laddr;
533675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size);
534675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  addr += (laddr - sladdr);
535675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return result;
536675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
537675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
538675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P>
539675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolint64_t OtherAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) {
540675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uintptr_t size = (end - addr);
541675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
542675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  LocalAddressSpace::pint_t sladdr = laddr;
543675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size);
544675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  addr += (laddr - sladdr);
545675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  return result;
546675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
547675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
548675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> void *OtherAddressSpace<P>::localCopy(pint_t addr) {
549675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // FIX ME
550675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
551675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
552675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P>
553675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolbool OtherAddressSpace<P>::findFunctionName(pint_t addr, char *buf,
554675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool                                            size_t bufLen, unw_word_t *offset) {
555675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  // FIX ME
556675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}
557675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
558675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space is the base class that abstract unw_addr_space_t type in
559675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// libunwind.h points to.
560675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space {
561675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  cpu_type_t cpuType;
562675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  task_t taskPort;
563675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
564675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
565675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points
566675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// to when examining
567675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// a 32-bit intel process.
568675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space_i386 : public unw_addr_space {
569675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  unw_addr_space_i386(task_t task) : oas(task) {}
570675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  OtherAddressSpace<Pointer32<LittleEndian> > oas;
571675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
572675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
573675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t
574675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// points to when examining
575675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// a 64-bit intel process.
576675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space_x86_64 : public unw_addr_space {
577675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  unw_addr_space_x86_64(task_t task) : oas(task) {}
578675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  OtherAddressSpace<Pointer64<LittleEndian> > oas;
579675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
580675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
581675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points
582675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// to when examining
583675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// a 32-bit PowerPC process.
584675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space_ppc : public unw_addr_space {
585675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  unw_addr_space_ppc(task_t task) : oas(task) {}
586675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool  OtherAddressSpace<Pointer32<BigEndian> > oas;
587675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool};
588675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
589675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif // UNW_REMOTE
590675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
591675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} // namespace libunwind
592675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool
593675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif // __ADDRESSSPACE_HPP__
594