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 <string.h> 20 21 #ifndef _LIBUNWIND_IS_BAREMETAL 22 #include <dlfcn.h> 23 #endif 24 25 #ifdef __APPLE__ 26 #include <mach-o/getsect.h> 27 namespace libunwind { 28 bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde); 29 } 30 #endif 31 32 #include "libunwind.h" 33 #include "config.h" 34 #include "dwarf2.h" 35 #include "EHHeaderParser.hpp" 36 #include "Registers.hpp" 37 38 namespace libunwind { 39 40 /// Used by findUnwindSections() to return info about needed sections. 41 struct UnwindInfoSections { 42 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) || \ 43 defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) 44 // No dso_base for ARM EHABI. 45 uintptr_t dso_base; 46 #endif 47 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) 48 uintptr_t dwarf_section; 49 uintptr_t dwarf_section_length; 50 #endif 51 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) 52 uintptr_t dwarf_index_section; 53 uintptr_t dwarf_index_section_length; 54 #endif 55 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) 56 uintptr_t compact_unwind_section; 57 uintptr_t compact_unwind_section_length; 58 #endif 59 #if defined(_LIBUNWIND_ARM_EHABI) 60 uintptr_t arm_section; 61 uintptr_t arm_section_length; 62 #endif 63 }; 64 65 66 /// LocalAddressSpace is used as a template parameter to UnwindCursor when 67 /// unwinding a thread in the same process. The wrappers compile away, 68 /// making local unwinds fast. 69 class __attribute__((visibility("hidden"))) LocalAddressSpace { 70 public: 71 #ifdef __LP64__ 72 typedef uint64_t pint_t; 73 typedef int64_t sint_t; 74 #else 75 typedef uint32_t pint_t; 76 typedef int32_t sint_t; 77 #endif 78 uint8_t get8(pint_t addr) { 79 uint8_t val; 80 memcpy(&val, (void *)addr, sizeof(val)); 81 return val; 82 } 83 uint16_t get16(pint_t addr) { 84 uint16_t val; 85 memcpy(&val, (void *)addr, sizeof(val)); 86 return val; 87 } 88 uint32_t get32(pint_t addr) { 89 uint32_t val; 90 memcpy(&val, (void *)addr, sizeof(val)); 91 return val; 92 } 93 uint64_t get64(pint_t addr) { 94 uint64_t val; 95 memcpy(&val, (void *)addr, sizeof(val)); 96 return val; 97 } 98 double getDouble(pint_t addr) { 99 double val; 100 memcpy(&val, (void *)addr, sizeof(val)); 101 return val; 102 } 103 v128 getVector(pint_t addr) { 104 v128 val; 105 memcpy(&val, (void *)addr, sizeof(val)); 106 return val; 107 } 108 uintptr_t getP(pint_t addr); 109 static uint64_t getULEB128(pint_t &addr, pint_t end); 110 static int64_t getSLEB128(pint_t &addr, pint_t end); 111 112 pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, 113 pint_t datarelBase = 0); 114 bool findFunctionName(pint_t addr, char *buf, size_t bufLen, 115 unw_word_t *offset); 116 bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); 117 bool findOtherFDE(pint_t targetAddr, pint_t &fde); 118 119 static LocalAddressSpace sThisAddressSpace; 120 }; 121 122 inline uintptr_t LocalAddressSpace::getP(pint_t addr) { 123 #ifdef __LP64__ 124 return get64(addr); 125 #else 126 return get32(addr); 127 #endif 128 } 129 130 /// Read a ULEB128 into a 64-bit word. 131 inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { 132 const uint8_t *p = (uint8_t *)addr; 133 const uint8_t *pend = (uint8_t *)end; 134 uint64_t result = 0; 135 int bit = 0; 136 do { 137 uint64_t b; 138 139 if (p == pend) 140 _LIBUNWIND_ABORT("truncated uleb128 expression"); 141 142 b = *p & 0x7f; 143 144 if (bit >= 64 || b << bit >> bit != b) { 145 _LIBUNWIND_ABORT("malformed uleb128 expression"); 146 } else { 147 result |= b << bit; 148 bit += 7; 149 } 150 } while (*p++ >= 0x80); 151 addr = (pint_t) p; 152 return result; 153 } 154 155 /// Read a SLEB128 into a 64-bit word. 156 inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) { 157 const uint8_t *p = (uint8_t *)addr; 158 const uint8_t *pend = (uint8_t *)end; 159 int64_t result = 0; 160 int bit = 0; 161 uint8_t byte; 162 do { 163 if (p == pend) 164 _LIBUNWIND_ABORT("truncated sleb128 expression"); 165 byte = *p++; 166 result |= ((byte & 0x7f) << bit); 167 bit += 7; 168 } while (byte & 0x80); 169 // sign extend negative numbers 170 if ((byte & 0x40) != 0) 171 result |= (-1LL) << bit; 172 addr = (pint_t) p; 173 return result; 174 } 175 176 inline LocalAddressSpace::pint_t 177 LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, 178 pint_t datarelBase) { 179 pint_t startAddr = addr; 180 const uint8_t *p = (uint8_t *)addr; 181 pint_t result; 182 183 // first get value 184 switch (encoding & 0x0F) { 185 case DW_EH_PE_ptr: 186 result = getP(addr); 187 p += sizeof(pint_t); 188 addr = (pint_t) p; 189 break; 190 case DW_EH_PE_uleb128: 191 result = (pint_t)getULEB128(addr, end); 192 break; 193 case DW_EH_PE_udata2: 194 result = get16(addr); 195 p += 2; 196 addr = (pint_t) p; 197 break; 198 case DW_EH_PE_udata4: 199 result = get32(addr); 200 p += 4; 201 addr = (pint_t) p; 202 break; 203 case DW_EH_PE_udata8: 204 result = (pint_t)get64(addr); 205 p += 8; 206 addr = (pint_t) p; 207 break; 208 case DW_EH_PE_sleb128: 209 result = (pint_t)getSLEB128(addr, end); 210 break; 211 case DW_EH_PE_sdata2: 212 // Sign extend from signed 16-bit value. 213 result = (pint_t)(int16_t)get16(addr); 214 p += 2; 215 addr = (pint_t) p; 216 break; 217 case DW_EH_PE_sdata4: 218 // Sign extend from signed 32-bit value. 219 result = (pint_t)(int32_t)get32(addr); 220 p += 4; 221 addr = (pint_t) p; 222 break; 223 case DW_EH_PE_sdata8: 224 result = (pint_t)get64(addr); 225 p += 8; 226 addr = (pint_t) p; 227 break; 228 default: 229 _LIBUNWIND_ABORT("unknown pointer encoding"); 230 } 231 232 // then add relative offset 233 switch (encoding & 0x70) { 234 case DW_EH_PE_absptr: 235 // do nothing 236 break; 237 case DW_EH_PE_pcrel: 238 result += startAddr; 239 break; 240 case DW_EH_PE_textrel: 241 _LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported"); 242 break; 243 case DW_EH_PE_datarel: 244 // DW_EH_PE_datarel is only valid in a few places, so the parameter has a 245 // default value of 0, and we abort in the event that someone calls this 246 // function with a datarelBase of 0 and DW_EH_PE_datarel encoding. 247 if (datarelBase == 0) 248 _LIBUNWIND_ABORT("DW_EH_PE_datarel is invalid with a datarelBase of 0"); 249 result += datarelBase; 250 break; 251 case DW_EH_PE_funcrel: 252 _LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported"); 253 break; 254 case DW_EH_PE_aligned: 255 _LIBUNWIND_ABORT("DW_EH_PE_aligned pointer encoding not supported"); 256 break; 257 default: 258 _LIBUNWIND_ABORT("unknown pointer encoding"); 259 break; 260 } 261 262 if (encoding & DW_EH_PE_indirect) 263 result = getP(result); 264 265 return result; 266 } 267 268 #ifdef __APPLE__ 269 270 struct dyld_unwind_sections 271 { 272 const struct mach_header* mh; 273 const void* dwarf_section; 274 uintptr_t dwarf_section_length; 275 const void* compact_unwind_section; 276 uintptr_t compact_unwind_section_length; 277 }; 278 #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \ 279 && (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) \ 280 || defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 281 // In 10.7.0 or later, libSystem.dylib implements this function. 282 extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); 283 #else 284 // In 10.6.x and earlier, we need to implement this functionality. Note 285 // that this requires a newer version of libmacho (from cctools) than is 286 // present in libSystem on 10.6.x (for getsectiondata). 287 static inline bool _dyld_find_unwind_sections(void* addr, 288 dyld_unwind_sections* info) { 289 // Find mach-o image containing address. 290 Dl_info dlinfo; 291 if (!dladdr(addr, &dlinfo)) 292 return false; 293 #if __LP64__ 294 const struct mach_header_64 *mh = (const struct mach_header_64 *)dlinfo.dli_fbase; 295 #else 296 const struct mach_header *mh = (const struct mach_header *)dlinfo.dli_fbase; 297 #endif 298 299 // Initialize the return struct 300 info->mh = (const struct mach_header *)mh; 301 info->dwarf_section = getsectiondata(mh, "__TEXT", "__eh_frame", &info->dwarf_section_length); 302 info->compact_unwind_section = getsectiondata(mh, "__TEXT", "__unwind_info", &info->compact_unwind_section_length); 303 304 if (!info->dwarf_section) { 305 info->dwarf_section_length = 0; 306 } 307 308 if (!info->compact_unwind_section) { 309 info->compact_unwind_section_length = 0; 310 } 311 312 return true; 313 } 314 #endif 315 316 #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) 317 318 // When statically linked on bare-metal, the symbols for the EH table are looked 319 // up without going through the dynamic loader. 320 extern char __exidx_start; 321 extern char __exidx_end; 322 323 #elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) 324 325 // ELF-based systems may use dl_iterate_phdr() to access sections 326 // containing unwinding information. The ElfW() macro for pointer-size 327 // independent ELF header traversal is not provided by <link.h> on some 328 // systems (e.g., FreeBSD). On these systems the data structures are 329 // just called Elf_XXX. Define ElfW() locally. 330 #include <link.h> 331 #if !defined(ElfW) 332 #define ElfW(type) Elf_##type 333 #endif 334 335 #endif 336 337 inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, 338 UnwindInfoSections &info) { 339 #ifdef __APPLE__ 340 dyld_unwind_sections dyldInfo; 341 if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) { 342 info.dso_base = (uintptr_t)dyldInfo.mh; 343 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) 344 info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section; 345 info.dwarf_section_length = dyldInfo.dwarf_section_length; 346 #endif 347 info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_section; 348 info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; 349 return true; 350 } 351 #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) 352 // Bare metal is statically linked, so no need to ask the dynamic loader 353 info.arm_section = (uintptr_t)(&__exidx_start); 354 info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start); 355 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x", 356 info.arm_section, info.arm_section_length); 357 if (info.arm_section && info.arm_section_length) 358 return true; 359 #elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) 360 struct dl_iterate_cb_data { 361 LocalAddressSpace *addressSpace; 362 UnwindInfoSections *sects; 363 uintptr_t targetAddr; 364 }; 365 366 dl_iterate_cb_data cb_data = {this, &info, targetAddr}; 367 int found = dl_iterate_phdr( 368 [](struct dl_phdr_info *pinfo, size_t, void *data) -> int { 369 auto cbdata = static_cast<dl_iterate_cb_data *>(data); 370 bool found_obj = false; 371 bool found_hdr = false; 372 373 assert(cbdata); 374 assert(cbdata->sects); 375 376 if (cbdata->targetAddr < pinfo->dlpi_addr) { 377 return false; 378 } 379 380 #if !defined(Elf_Half) 381 typedef ElfW(Half) Elf_Half; 382 #endif 383 #if !defined(Elf_Phdr) 384 typedef ElfW(Phdr) Elf_Phdr; 385 #endif 386 #if !defined(Elf_Addr) && defined(__ANDROID__) 387 typedef ElfW(Addr) Elf_Addr; 388 #endif 389 390 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) 391 #if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) 392 #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform." 393 #endif 394 size_t object_length; 395 #if defined(__ANDROID__) 396 Elf_Addr image_base = 397 pinfo->dlpi_phnum 398 ? reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) - 399 reinterpret_cast<const Elf_Phdr *>(pinfo->dlpi_phdr) 400 ->p_offset 401 : 0; 402 #endif 403 404 for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { 405 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; 406 if (phdr->p_type == PT_LOAD) { 407 uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr; 408 #if defined(__ANDROID__) 409 if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base) 410 begin = begin + image_base; 411 #endif 412 uintptr_t end = begin + phdr->p_memsz; 413 if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) { 414 cbdata->sects->dso_base = begin; 415 object_length = phdr->p_memsz; 416 found_obj = true; 417 } 418 } else if (phdr->p_type == PT_GNU_EH_FRAME) { 419 EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo; 420 uintptr_t eh_frame_hdr_start = pinfo->dlpi_addr + phdr->p_vaddr; 421 #if defined(__ANDROID__) 422 if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base) 423 eh_frame_hdr_start = eh_frame_hdr_start + image_base; 424 #endif 425 cbdata->sects->dwarf_index_section = eh_frame_hdr_start; 426 cbdata->sects->dwarf_index_section_length = phdr->p_memsz; 427 EHHeaderParser<LocalAddressSpace>::decodeEHHdr( 428 *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, 429 hdrInfo); 430 cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; 431 found_hdr = true; 432 } 433 } 434 435 if (found_obj && found_hdr) { 436 cbdata->sects->dwarf_section_length = object_length; 437 return true; 438 } else { 439 return false; 440 } 441 #else // defined(_LIBUNWIND_ARM_EHABI) 442 for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { 443 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; 444 if (phdr->p_type == PT_LOAD) { 445 uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr; 446 uintptr_t end = begin + phdr->p_memsz; 447 if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) 448 found_obj = true; 449 } else if (phdr->p_type == PT_ARM_EXIDX) { 450 uintptr_t exidx_start = pinfo->dlpi_addr + phdr->p_vaddr; 451 cbdata->sects->arm_section = exidx_start; 452 cbdata->sects->arm_section_length = phdr->p_memsz; 453 found_hdr = true; 454 } 455 } 456 return found_obj && found_hdr; 457 #endif 458 }, 459 &cb_data); 460 return static_cast<bool>(found); 461 #endif 462 463 return false; 464 } 465 466 467 inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { 468 #ifdef __APPLE__ 469 return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde)); 470 #else 471 // TO DO: if OS has way to dynamically register FDEs, check that. 472 (void)targetAddr; 473 (void)fde; 474 return false; 475 #endif 476 } 477 478 inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, 479 size_t bufLen, 480 unw_word_t *offset) { 481 #ifndef _LIBUNWIND_IS_BAREMETAL 482 Dl_info dyldInfo; 483 if (dladdr((void *)addr, &dyldInfo)) { 484 if (dyldInfo.dli_sname != NULL) { 485 snprintf(buf, bufLen, "%s", dyldInfo.dli_sname); 486 *offset = (addr - (pint_t) dyldInfo.dli_saddr); 487 return true; 488 } 489 } 490 #endif 491 return false; 492 } 493 494 495 496 #ifdef UNW_REMOTE 497 498 /// RemoteAddressSpace is used as a template parameter to UnwindCursor when 499 /// unwinding a thread in the another process. The other process can be a 500 /// different endianness and a different pointer size which is handled by 501 /// the P template parameter. 502 template <typename P> 503 class RemoteAddressSpace { 504 public: 505 RemoteAddressSpace(task_t task) : fTask(task) {} 506 507 typedef typename P::uint_t pint_t; 508 509 uint8_t get8(pint_t addr); 510 uint16_t get16(pint_t addr); 511 uint32_t get32(pint_t addr); 512 uint64_t get64(pint_t addr); 513 pint_t getP(pint_t addr); 514 uint64_t getULEB128(pint_t &addr, pint_t end); 515 int64_t getSLEB128(pint_t &addr, pint_t end); 516 pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, 517 pint_t datarelBase = 0); 518 bool findFunctionName(pint_t addr, char *buf, size_t bufLen, 519 unw_word_t *offset); 520 bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); 521 bool findOtherFDE(pint_t targetAddr, pint_t &fde); 522 private: 523 void *localCopy(pint_t addr); 524 525 task_t fTask; 526 }; 527 528 template <typename P> uint8_t RemoteAddressSpace<P>::get8(pint_t addr) { 529 return *((uint8_t *)localCopy(addr)); 530 } 531 532 template <typename P> uint16_t RemoteAddressSpace<P>::get16(pint_t addr) { 533 return P::E::get16(*(uint16_t *)localCopy(addr)); 534 } 535 536 template <typename P> uint32_t RemoteAddressSpace<P>::get32(pint_t addr) { 537 return P::E::get32(*(uint32_t *)localCopy(addr)); 538 } 539 540 template <typename P> uint64_t RemoteAddressSpace<P>::get64(pint_t addr) { 541 return P::E::get64(*(uint64_t *)localCopy(addr)); 542 } 543 544 template <typename P> 545 typename P::uint_t RemoteAddressSpace<P>::getP(pint_t addr) { 546 return P::getP(*(uint64_t *)localCopy(addr)); 547 } 548 549 template <typename P> 550 uint64_t RemoteAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) { 551 uintptr_t size = (end - addr); 552 LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); 553 LocalAddressSpace::pint_t sladdr = laddr; 554 uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size); 555 addr += (laddr - sladdr); 556 return result; 557 } 558 559 template <typename P> 560 int64_t RemoteAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) { 561 uintptr_t size = (end - addr); 562 LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); 563 LocalAddressSpace::pint_t sladdr = laddr; 564 uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size); 565 addr += (laddr - sladdr); 566 return result; 567 } 568 569 template <typename P> void *RemoteAddressSpace<P>::localCopy(pint_t addr) { 570 // FIX ME 571 } 572 573 template <typename P> 574 bool RemoteAddressSpace<P>::findFunctionName(pint_t addr, char *buf, 575 size_t bufLen, 576 unw_word_t *offset) { 577 // FIX ME 578 } 579 580 /// unw_addr_space is the base class that abstract unw_addr_space_t type in 581 /// libunwind.h points to. 582 struct unw_addr_space { 583 cpu_type_t cpuType; 584 task_t taskPort; 585 }; 586 587 /// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points 588 /// to when examining 589 /// a 32-bit intel process. 590 struct unw_addr_space_i386 : public unw_addr_space { 591 unw_addr_space_i386(task_t task) : oas(task) {} 592 RemoteAddressSpace<Pointer32<LittleEndian>> oas; 593 }; 594 595 /// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t 596 /// points to when examining 597 /// a 64-bit intel process. 598 struct unw_addr_space_x86_64 : public unw_addr_space { 599 unw_addr_space_x86_64(task_t task) : oas(task) {} 600 RemoteAddressSpace<Pointer64<LittleEndian>> oas; 601 }; 602 603 /// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points 604 /// to when examining 605 /// a 32-bit PowerPC process. 606 struct unw_addr_space_ppc : public unw_addr_space { 607 unw_addr_space_ppc(task_t task) : oas(task) {} 608 RemoteAddressSpace<Pointer32<BigEndian>> oas; 609 }; 610 611 #endif // UNW_REMOTE 612 613 } // namespace libunwind 614 615 #endif // __ADDRESSSPACE_HPP__ 616