Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: third_party/libc++abi/src/Unwind/AddressSpace.hpp

Issue 75213003: Add libc++ and libc++abi to third-party. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===------------------------- AddressSpace.hpp ---------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 // Abstracts accessing local vs remote address spaces.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef __ADDRESSSPACE_HPP__
14 #define __ADDRESSSPACE_HPP__
15
16 #include <stdint.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <dlfcn.h>
20
21 #if __APPLE__
22 #include <mach-o/dyld_priv.h>
23 namespace libunwind {
24 bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde);
25 }
26 #endif
27
28 #include "libunwind.h"
29 #include "config.h"
30 #include "dwarf2.h"
31 #include "Registers.hpp"
32
33 namespace libunwind {
34
35 /// Used by findUnwindSections() to return info about needed sections.
36 struct UnwindInfoSections {
37 uintptr_t dso_base;
38 #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
39 uintptr_t dwarf_section;
40 uintptr_t dwarf_section_length;
41 #endif
42 #if _LIBUNWIND_SUPPORT_DWARF_INDEX
43 uintptr_t dwarf_index_section;
44 uintptr_t dwarf_index_section_length;
45 #endif
46 #if _LIBUNWIND_SUPPORT_COMPACT_UNWIND
47 uintptr_t compact_unwind_section;
48 uintptr_t compact_unwind_section_length;
49 #endif
50 };
51
52
53 /// LocalAddressSpace is used as a template parameter to UnwindCursor when
54 /// unwinding a thread in the same process. The wrappers compile away,
55 /// making local unwinds fast.
56 class __attribute__((visibility("hidden"))) LocalAddressSpace {
57 public:
58 #if __LP64__
59 typedef uint64_t pint_t;
60 typedef int64_t sint_t;
61 #else
62 typedef uint32_t pint_t;
63 typedef int32_t sint_t;
64 #endif
65 uint8_t get8(pint_t addr) { return *((uint8_t *)addr); }
66 uint16_t get16(pint_t addr) { return *((uint16_t *)addr); }
67 uint32_t get32(pint_t addr) { return *((uint32_t *)addr); }
68 uint64_t get64(pint_t addr) { return *((uint64_t *)addr); }
69 double getDouble(pint_t addr) { return *((double *)addr); }
70 v128 getVector(pint_t addr) { return *((v128 *)addr); }
71 uintptr_t getP(pint_t addr);
72 static uint64_t getULEB128(pint_t &addr, pint_t end);
73 static int64_t getSLEB128(pint_t &addr, pint_t end);
74
75 pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
76 bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
77 unw_word_t *offset);
78 bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
79 bool findOtherFDE(pint_t targetAddr, pint_t &fde);
80
81 static LocalAddressSpace sThisAddressSpace;
82 };
83
84
85 inline uintptr_t LocalAddressSpace::getP(pint_t addr) {
86 #if __LP64__
87 return get64(addr);
88 #else
89 return get32(addr);
90 #endif
91 }
92
93 /// Read a ULEB128 into a 64-bit word.
94 inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) {
95 const uint8_t *p = (uint8_t *)addr;
96 const uint8_t *pend = (uint8_t *)end;
97 uint64_t result = 0;
98 int bit = 0;
99 do {
100 uint64_t b;
101
102 if (p == pend)
103 _LIBUNWIND_ABORT("truncated uleb128 expression");
104
105 b = *p & 0x7f;
106
107 if (bit >= 64 || b << bit >> bit != b) {
108 _LIBUNWIND_ABORT("malformed uleb128 expression");
109 } else {
110 result |= b << bit;
111 bit += 7;
112 }
113 } while (*p++ >= 0x80);
114 addr = (pint_t) p;
115 return result;
116 }
117
118 /// Read a SLEB128 into a 64-bit word.
119 inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
120 const uint8_t *p = (uint8_t *)addr;
121 const uint8_t *pend = (uint8_t *)end;
122 int64_t result = 0;
123 int bit = 0;
124 uint8_t byte;
125 do {
126 if (p == pend)
127 _LIBUNWIND_ABORT("truncated sleb128 expression");
128 byte = *p++;
129 result |= ((byte & 0x7f) << bit);
130 bit += 7;
131 } while (byte & 0x80);
132 // sign extend negative numbers
133 if ((byte & 0x40) != 0)
134 result |= (-1LL) << bit;
135 addr = (pint_t) p;
136 return result;
137 }
138
139 inline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
140 pint_t end,
141 uint8_t encoding) {
142 pint_t startAddr = addr;
143 const uint8_t *p = (uint8_t *)addr;
144 pint_t result;
145
146 // first get value
147 switch (encoding & 0x0F) {
148 case DW_EH_PE_ptr:
149 result = getP(addr);
150 p += sizeof(pint_t);
151 addr = (pint_t) p;
152 break;
153 case DW_EH_PE_uleb128:
154 result = (pint_t)getULEB128(addr, end);
155 break;
156 case DW_EH_PE_udata2:
157 result = get16(addr);
158 p += 2;
159 addr = (pint_t) p;
160 break;
161 case DW_EH_PE_udata4:
162 result = get32(addr);
163 p += 4;
164 addr = (pint_t) p;
165 break;
166 case DW_EH_PE_udata8:
167 result = (pint_t)get64(addr);
168 p += 8;
169 addr = (pint_t) p;
170 break;
171 case DW_EH_PE_sleb128:
172 result = (pint_t)getSLEB128(addr, end);
173 break;
174 case DW_EH_PE_sdata2:
175 result = (uint16_t)get16(addr);
176 p += 2;
177 addr = (pint_t) p;
178 break;
179 case DW_EH_PE_sdata4:
180 result = (uint32_t)get32(addr);
181 p += 4;
182 addr = (pint_t) p;
183 break;
184 case DW_EH_PE_sdata8:
185 result = (pint_t)get64(addr);
186 p += 8;
187 addr = (pint_t) p;
188 break;
189 default:
190 _LIBUNWIND_ABORT("unknown pointer encoding");
191 }
192
193 // then add relative offset
194 switch (encoding & 0x70) {
195 case DW_EH_PE_absptr:
196 // do nothing
197 break;
198 case DW_EH_PE_pcrel:
199 result += startAddr;
200 break;
201 case DW_EH_PE_textrel:
202 _LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported");
203 break;
204 case DW_EH_PE_datarel:
205 _LIBUNWIND_ABORT("DW_EH_PE_datarel pointer encoding not supported");
206 break;
207 case DW_EH_PE_funcrel:
208 _LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported");
209 break;
210 case DW_EH_PE_aligned:
211 _LIBUNWIND_ABORT("DW_EH_PE_aligned pointer encoding not supported");
212 break;
213 default:
214 _LIBUNWIND_ABORT("unknown pointer encoding");
215 break;
216 }
217
218 if (encoding & DW_EH_PE_indirect)
219 result = getP(result);
220
221 return result;
222 }
223
224 inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
225 UnwindInfoSections &info) {
226 #if __APPLE__
227 dyld_unwind_sections dyldInfo;
228 if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
229 info.dso_base = (uintptr_t)dyldInfo.mh;
230 #if _LIBUNWIND_SUPPORT_DWARF_UNWIND
231 info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section;
232 info.dwarf_section_length = dyldInfo.dwarf_section_length;
233 #endif
234 info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_sect ion;
235 info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length;
236 return true;
237 }
238 #else
239 // TO DO
240
241 #endif
242
243 return false;
244 }
245
246
247 inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
248 #if __APPLE__
249 return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde));
250 #else
251 // TO DO: if OS has way to dynamically register FDEs, check that.
252 return false;
253 #endif
254 }
255
256 inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
257 size_t bufLen,
258 unw_word_t *offset) {
259 dl_info dyldInfo;
260 if (dladdr((void *)addr, &dyldInfo)) {
261 if (dyldInfo.dli_sname != NULL) {
262 strlcpy(buf, dyldInfo.dli_sname, bufLen);
263 *offset = (addr - (pint_t) dyldInfo.dli_saddr);
264 return true;
265 }
266 }
267 return false;
268 }
269
270
271
272 #if UNW_REMOTE
273
274 /// OtherAddressSpace is used as a template parameter to UnwindCursor when
275 /// unwinding a thread in the another process. The other process can be a
276 /// different endianness and a different pointer size which is handled by
277 /// the P template parameter.
278 template <typename P>
279 class OtherAddressSpace {
280 public:
281 OtherAddressSpace(task_t task) : fTask(task) {}
282
283 typedef typename P::uint_t pint_t;
284
285 uint8_t get8(pint_t addr);
286 uint16_t get16(pint_t addr);
287 uint32_t get32(pint_t addr);
288 uint64_t get64(pint_t addr);
289 pint_t getP(pint_t addr);
290 uint64_t getULEB128(pint_t &addr, pint_t end);
291 int64_t getSLEB128(pint_t &addr, pint_t end);
292 pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
293 bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
294 unw_word_t *offset);
295 bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
296 bool findOtherFDE(pint_t targetAddr, pint_t &fde);
297 private:
298 void *localCopy(pint_t addr);
299
300 task_t fTask;
301 };
302
303 template <typename P> uint8_t OtherAddressSpace<P>::get8(pint_t addr) {
304 return *((uint8_t *)localCopy(addr));
305 }
306
307 template <typename P> uint16_t OtherAddressSpace<P>::get16(pint_t addr) {
308 return P::E::get16(*(uint16_t *)localCopy(addr));
309 }
310
311 template <typename P> uint32_t OtherAddressSpace<P>::get32(pint_t addr) {
312 return P::E::get32(*(uint32_t *)localCopy(addr));
313 }
314
315 template <typename P> uint64_t OtherAddressSpace<P>::get64(pint_t addr) {
316 return P::E::get64(*(uint64_t *)localCopy(addr));
317 }
318
319 template <typename P>
320 typename P::uint_t OtherAddressSpace<P>::getP(pint_t addr) {
321 return P::getP(*(uint64_t *)localCopy(addr));
322 }
323
324 template <typename P>
325 uint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) {
326 uintptr_t size = (end - addr);
327 LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
328 LocalAddressSpace::pint_t sladdr = laddr;
329 uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size);
330 addr += (laddr - sladdr);
331 return result;
332 }
333
334 template <typename P>
335 int64_t OtherAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) {
336 uintptr_t size = (end - addr);
337 LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
338 LocalAddressSpace::pint_t sladdr = laddr;
339 uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size);
340 addr += (laddr - sladdr);
341 return result;
342 }
343
344 template <typename P> void *OtherAddressSpace<P>::localCopy(pint_t addr) {
345 // FIX ME
346 }
347
348 template <typename P>
349 bool OtherAddressSpace<P>::findFunctionName(pint_t addr, char *buf,
350 size_t bufLen, unw_word_t *offset) {
351 // FIX ME
352 }
353
354 /// unw_addr_space is the base class that abstract unw_addr_space_t type in
355 /// libunwind.h points to.
356 struct unw_addr_space {
357 cpu_type_t cpuType;
358 task_t taskPort;
359 };
360
361 /// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points
362 /// to when examining
363 /// a 32-bit intel process.
364 struct unw_addr_space_i386 : public unw_addr_space {
365 unw_addr_space_i386(task_t task) : oas(task) {}
366 OtherAddressSpace<Pointer32<LittleEndian> > oas;
367 };
368
369 /// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t
370 /// points to when examining
371 /// a 64-bit intel process.
372 struct unw_addr_space_x86_64 : public unw_addr_space {
373 unw_addr_space_x86_64(task_t task) : oas(task) {}
374 OtherAddressSpace<Pointer64<LittleEndian> > oas;
375 };
376
377 /// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points
378 /// to when examining
379 /// a 32-bit PowerPC process.
380 struct unw_addr_space_ppc : public unw_addr_space {
381 unw_addr_space_ppc(task_t task) : oas(task) {}
382 OtherAddressSpace<Pointer32<BigEndian> > oas;
383 };
384
385 #endif // UNW_REMOTE
386
387 } // namespace libunwind
388
389 #endif // __ADDRESSSPACE_HPP__
OLDNEW
« no previous file with comments | « third_party/libc++abi/libc++abi.gyp ('k') | third_party/libc++abi/src/Unwind/CompactUnwinder.hpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698