1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "BacktraceOffline.h" 18 19 extern "C" { 20 #define UNW_REMOTE_ONLY 21 #include <dwarf.h> 22 } 23 24 #include <pthread.h> 25 #include <stdint.h> 26 #include <stdio.h> 27 #include <string.h> 28 #include <sys/stat.h> 29 #include <sys/types.h> 30 #include <ucontext.h> 31 #include <unistd.h> 32 33 #include <memory> 34 #include <mutex> 35 #include <string> 36 #include <vector> 37 38 #include <android-base/file.h> 39 #include <android-base/macros.h> 40 #include <backtrace/Backtrace.h> 41 #include <backtrace/BacktraceMap.h> 42 #include <ziparchive/zip_archive.h> 43 44 #pragma clang diagnostic push 45 #pragma clang diagnostic ignored "-Wunused-parameter" 46 47 #include <llvm/ADT/StringRef.h> 48 #include <llvm/Object/Binary.h> 49 #include <llvm/Object/ELFObjectFile.h> 50 #include <llvm/Object/ObjectFile.h> 51 52 #pragma clang diagnostic pop 53 54 #include "BacktraceLog.h" 55 56 struct EhFrame { 57 uint64_t hdr_vaddr; 58 uint64_t vaddr; 59 uint64_t fde_table_offset; 60 uintptr_t min_func_vaddr; 61 std::vector<uint8_t> hdr_data; 62 std::vector<uint8_t> data; 63 }; 64 65 struct ArmIdxEntry { 66 uint32_t func_offset; 67 uint32_t value; 68 }; 69 70 struct ArmExidx { 71 uint64_t exidx_vaddr; 72 uint64_t extab_vaddr; 73 std::vector<ArmIdxEntry> exidx_data; 74 std::vector<uint8_t> extab_data; 75 // There is a one-to-one map from exidx_data.func_offset to func_vaddr_array. 76 std::vector<uint32_t> func_vaddr_array; 77 }; 78 79 struct DebugFrameInfo { 80 bool has_arm_exidx; 81 bool has_eh_frame; 82 bool has_debug_frame; 83 bool has_gnu_debugdata; 84 85 EhFrame eh_frame; 86 ArmExidx arm_exidx; 87 88 uint64_t min_vaddr; 89 uint64_t text_end_vaddr; 90 91 DebugFrameInfo() : has_arm_exidx(false), has_eh_frame(false), 92 has_debug_frame(false), has_gnu_debugdata(false) { } 93 }; 94 95 void Space::Clear() { 96 start = 0; 97 end = 0; 98 data = nullptr; 99 } 100 101 size_t Space::Read(uint64_t addr, uint8_t* buffer, size_t size) { 102 if (addr >= start && addr < end) { 103 size_t read_size = std::min(size, static_cast<size_t>(end - addr)); 104 memcpy(buffer, data + (addr - start), read_size); 105 return read_size; 106 } 107 return 0; 108 } 109 110 static int FindProcInfo(unw_addr_space_t addr_space, unw_word_t ip, unw_proc_info* proc_info, 111 int need_unwind_info, void* arg) { 112 BacktraceOffline* backtrace = reinterpret_cast<BacktraceOffline*>(arg); 113 bool result = backtrace->FindProcInfo(addr_space, ip, proc_info, need_unwind_info); 114 return result ? 0 : -UNW_EINVAL; 115 } 116 117 static void PutUnwindInfo(unw_addr_space_t, unw_proc_info_t*, void*) { 118 } 119 120 static int GetDynInfoListAddr(unw_addr_space_t, unw_word_t*, void*) { 121 return -UNW_ENOINFO; 122 } 123 124 static int AccessMem(unw_addr_space_t, unw_word_t addr, unw_word_t* value, int write, void* arg) { 125 if (write == 1) { 126 return -UNW_EINVAL; 127 } 128 BacktraceOffline* backtrace = reinterpret_cast<BacktraceOffline*>(arg); 129 *value = 0; 130 size_t read_size = backtrace->Read(addr, reinterpret_cast<uint8_t*>(value), sizeof(unw_word_t)); 131 // Strictly we should check if read_size matches sizeof(unw_word_t), but it is possible in 132 // .eh_frame_hdr that the section can end at a position not aligned in sizeof(unw_word_t), and 133 // we should permit the read at the end of the section. 134 return (read_size > 0u ? 0 : -UNW_EINVAL); 135 } 136 137 static int AccessReg(unw_addr_space_t, unw_regnum_t unwind_reg, unw_word_t* value, int write, 138 void* arg) { 139 if (write == 1) { 140 return -UNW_EINVAL; 141 } 142 BacktraceOffline* backtrace = reinterpret_cast<BacktraceOffline*>(arg); 143 uint64_t reg_value; 144 bool result = backtrace->ReadReg(unwind_reg, ®_value); 145 if (result) { 146 *value = static_cast<unw_word_t>(reg_value); 147 } 148 return result ? 0 : -UNW_EINVAL; 149 } 150 151 static int AccessFpReg(unw_addr_space_t, unw_regnum_t, unw_fpreg_t*, int, void*) { 152 return -UNW_EINVAL; 153 } 154 155 static int Resume(unw_addr_space_t, unw_cursor_t*, void*) { 156 return -UNW_EINVAL; 157 } 158 159 static int GetProcName(unw_addr_space_t, unw_word_t, char*, size_t, unw_word_t*, void*) { 160 return -UNW_EINVAL; 161 } 162 163 static unw_accessors_t accessors = { 164 .find_proc_info = FindProcInfo, 165 .put_unwind_info = PutUnwindInfo, 166 .get_dyn_info_list_addr = GetDynInfoListAddr, 167 .access_mem = AccessMem, 168 .access_reg = AccessReg, 169 .access_fpreg = AccessFpReg, 170 .resume = Resume, 171 .get_proc_name = GetProcName, 172 }; 173 174 bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { 175 if (context == nullptr) { 176 BACK_LOGW("The context is needed for offline backtracing."); 177 error_ = BACKTRACE_UNWIND_ERROR_NO_CONTEXT; 178 return false; 179 } 180 context_ = context; 181 error_ = BACKTRACE_UNWIND_NO_ERROR; 182 183 unw_addr_space_t addr_space = unw_create_addr_space(&accessors, 0); 184 unw_cursor_t cursor; 185 int ret = unw_init_remote(&cursor, addr_space, this); 186 if (ret != 0) { 187 BACK_LOGW("unw_init_remote failed %d", ret); 188 unw_destroy_addr_space(addr_space); 189 error_ = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; 190 return false; 191 } 192 size_t num_frames = 0; 193 do { 194 unw_word_t pc; 195 ret = unw_get_reg(&cursor, UNW_REG_IP, &pc); 196 if (ret < 0) { 197 BACK_LOGW("Failed to read IP %d", ret); 198 break; 199 } 200 unw_word_t sp; 201 ret = unw_get_reg(&cursor, UNW_REG_SP, &sp); 202 if (ret < 0) { 203 BACK_LOGW("Failed to read SP %d", ret); 204 break; 205 } 206 207 if (num_ignore_frames == 0) { 208 frames_.resize(num_frames + 1); 209 backtrace_frame_data_t* frame = &frames_[num_frames]; 210 frame->num = num_frames; 211 frame->pc = static_cast<uintptr_t>(pc); 212 frame->sp = static_cast<uintptr_t>(sp); 213 frame->stack_size = 0; 214 215 if (num_frames > 0) { 216 backtrace_frame_data_t* prev = &frames_[num_frames - 1]; 217 prev->stack_size = frame->sp - prev->sp; 218 } 219 frame->func_name = GetFunctionName(frame->pc, &frame->func_offset); 220 FillInMap(frame->pc, &frame->map); 221 num_frames++; 222 } else { 223 num_ignore_frames--; 224 } 225 ret = unw_step(&cursor); 226 } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES); 227 228 unw_destroy_addr_space(addr_space); 229 context_ = nullptr; 230 return true; 231 } 232 233 bool BacktraceOffline::ReadWord(uintptr_t ptr, word_t* out_value) { 234 size_t bytes_read = Read(ptr, reinterpret_cast<uint8_t*>(out_value), sizeof(word_t)); 235 return bytes_read == sizeof(word_t); 236 } 237 238 size_t BacktraceOffline::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { 239 // Normally, libunwind needs stack information and call frame information to do remote unwinding. 240 // If call frame information is stored in .debug_frame, libunwind can read it from file 241 // by itself. If call frame information is stored in .eh_frame, we need to provide data in 242 // .eh_frame/.eh_frame_hdr sections. 243 // The order of readings below doesn't matter, as the spaces don't overlap with each other. 244 size_t read_size = eh_frame_hdr_space_.Read(addr, buffer, bytes); 245 if (read_size != 0) { 246 return read_size; 247 } 248 read_size = eh_frame_space_.Read(addr, buffer, bytes); 249 if (read_size != 0) { 250 return read_size; 251 } 252 read_size = arm_exidx_space_.Read(addr, buffer, bytes); 253 if (read_size != 0) { 254 return read_size; 255 } 256 read_size = arm_extab_space_.Read(addr, buffer, bytes); 257 if (read_size != 0) { 258 return read_size; 259 } 260 read_size = stack_space_.Read(addr, buffer, bytes); 261 return read_size; 262 } 263 264 bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, 265 unw_proc_info_t* proc_info, int need_unwind_info) { 266 backtrace_map_t map; 267 FillInMap(ip, &map); 268 if (!BacktraceMap::IsValid(map)) { 269 return false; 270 } 271 const std::string& filename = map.name; 272 DebugFrameInfo* debug_frame = GetDebugFrameInFile(filename); 273 if (debug_frame == nullptr) { 274 return false; 275 } 276 277 eh_frame_hdr_space_.Clear(); 278 eh_frame_space_.Clear(); 279 arm_exidx_space_.Clear(); 280 arm_extab_space_.Clear(); 281 282 // vaddr in the elf file. 283 uint64_t ip_vaddr = ip - map.start + debug_frame->min_vaddr; 284 285 // The unwind info can come from .ARM.exidx or .eh_frame, or .debug_frame/.gnu_debugdata. 286 // First check .eh_frame/.debug_frame, then check .ARM.exidx. Because .eh_frame/.debug_frame has 287 // function range for each entry, by matching ip address with the function range, we know exactly 288 // whether the ip address hits an entry. But .ARM.exidx doesn't have function range for each 289 // entry, it thinks that an ip address hits an entry when (entry.addr <= ip < next_entry.addr). 290 // To prevent ip addresses hit in .eh_frame/.debug_frame being regarded as addresses hit in 291 // .ARM.exidx, we need to check .eh_frame/.debug_frame first. 292 if (debug_frame->has_eh_frame) { 293 if (ip_vaddr >= debug_frame->eh_frame.min_func_vaddr && 294 ip_vaddr < debug_frame->text_end_vaddr) { 295 // Prepare eh_frame_hdr space and eh_frame space. 296 eh_frame_hdr_space_.start = ip - ip_vaddr + debug_frame->eh_frame.hdr_vaddr; 297 eh_frame_hdr_space_.end = 298 eh_frame_hdr_space_.start + debug_frame->eh_frame.hdr_data.size(); 299 eh_frame_hdr_space_.data = debug_frame->eh_frame.hdr_data.data(); 300 eh_frame_space_.start = ip - ip_vaddr + debug_frame->eh_frame.vaddr; 301 eh_frame_space_.end = eh_frame_space_.start + debug_frame->eh_frame.data.size(); 302 eh_frame_space_.data = debug_frame->eh_frame.data.data(); 303 304 unw_dyn_info di; 305 memset(&di, '\0', sizeof(di)); 306 di.start_ip = map.start; 307 di.end_ip = map.end; 308 di.format = UNW_INFO_FORMAT_REMOTE_TABLE; 309 di.u.rti.name_ptr = 0; 310 di.u.rti.segbase = eh_frame_hdr_space_.start; 311 di.u.rti.table_data = 312 eh_frame_hdr_space_.start + debug_frame->eh_frame.fde_table_offset; 313 di.u.rti.table_len = (eh_frame_hdr_space_.end - di.u.rti.table_data) / sizeof(unw_word_t); 314 // TODO: Do it ourselves is more efficient than calling this function. 315 int ret = dwarf_search_unwind_table(addr_space, ip, &di, proc_info, need_unwind_info, this); 316 if (ret == 0) { 317 return true; 318 } 319 } 320 } 321 if (debug_frame->has_debug_frame || debug_frame->has_gnu_debugdata) { 322 unw_dyn_info_t di; 323 unw_word_t segbase = map.start - map.offset; 324 // TODO: http://b/32916571 325 // TODO: Do it ourselves is more efficient than calling libunwind functions. 326 int found = dwarf_find_debug_frame(0, &di, ip, segbase, filename.c_str(), map.start, map.end); 327 if (found == 1) { 328 int ret = dwarf_search_unwind_table(addr_space, ip, &di, proc_info, need_unwind_info, this); 329 if (ret == 0) { 330 return true; 331 } 332 } 333 } 334 335 if (debug_frame->has_arm_exidx) { 336 auto& func_vaddrs = debug_frame->arm_exidx.func_vaddr_array; 337 if (ip_vaddr >= func_vaddrs[0] && ip_vaddr < debug_frame->text_end_vaddr) { 338 // Use binary search to find the correct function. 339 auto it = std::upper_bound(func_vaddrs.begin(), func_vaddrs.end(), 340 static_cast<uint32_t>(ip_vaddr)); 341 if (it != func_vaddrs.begin()) { 342 --it; 343 // Found the exidx entry. 344 size_t index = it - func_vaddrs.begin(); 345 proc_info->start_ip = *it; 346 proc_info->format = UNW_INFO_FORMAT_ARM_EXIDX; 347 proc_info->unwind_info = reinterpret_cast<void*>( 348 static_cast<uintptr_t>(index * sizeof(ArmIdxEntry) + 349 debug_frame->arm_exidx.exidx_vaddr + 350 debug_frame->min_vaddr)); 351 eh_frame_hdr_space_.Clear(); 352 eh_frame_space_.Clear(); 353 // Prepare arm_exidx space and arm_extab space. 354 arm_exidx_space_.start = debug_frame->min_vaddr + debug_frame->arm_exidx.exidx_vaddr; 355 arm_exidx_space_.end = arm_exidx_space_.start + 356 debug_frame->arm_exidx.exidx_data.size() * sizeof(ArmIdxEntry); 357 arm_exidx_space_.data = reinterpret_cast<const uint8_t*>( 358 debug_frame->arm_exidx.exidx_data.data()); 359 360 arm_extab_space_.start = debug_frame->min_vaddr + debug_frame->arm_exidx.extab_vaddr; 361 arm_extab_space_.end = arm_extab_space_.start + 362 debug_frame->arm_exidx.extab_data.size(); 363 arm_extab_space_.data = debug_frame->arm_exidx.extab_data.data(); 364 return true; 365 } 366 } 367 } 368 return false; 369 } 370 371 bool BacktraceOffline::ReadReg(size_t reg, uint64_t* value) { 372 bool result = true; 373 #if defined(__arm__) 374 switch (reg) { 375 case UNW_ARM_R0: 376 *value = context_->uc_mcontext.arm_r0; 377 break; 378 case UNW_ARM_R1: 379 *value = context_->uc_mcontext.arm_r1; 380 break; 381 case UNW_ARM_R2: 382 *value = context_->uc_mcontext.arm_r2; 383 break; 384 case UNW_ARM_R3: 385 *value = context_->uc_mcontext.arm_r3; 386 break; 387 case UNW_ARM_R4: 388 *value = context_->uc_mcontext.arm_r4; 389 break; 390 case UNW_ARM_R5: 391 *value = context_->uc_mcontext.arm_r5; 392 break; 393 case UNW_ARM_R6: 394 *value = context_->uc_mcontext.arm_r6; 395 break; 396 case UNW_ARM_R7: 397 *value = context_->uc_mcontext.arm_r7; 398 break; 399 case UNW_ARM_R8: 400 *value = context_->uc_mcontext.arm_r8; 401 break; 402 case UNW_ARM_R9: 403 *value = context_->uc_mcontext.arm_r9; 404 break; 405 case UNW_ARM_R10: 406 *value = context_->uc_mcontext.arm_r10; 407 break; 408 case UNW_ARM_R11: 409 *value = context_->uc_mcontext.arm_fp; 410 break; 411 case UNW_ARM_R12: 412 *value = context_->uc_mcontext.arm_ip; 413 break; 414 case UNW_ARM_R13: 415 *value = context_->uc_mcontext.arm_sp; 416 break; 417 case UNW_ARM_R14: 418 *value = context_->uc_mcontext.arm_lr; 419 break; 420 case UNW_ARM_R15: 421 *value = context_->uc_mcontext.arm_pc; 422 break; 423 default: 424 result = false; 425 } 426 #elif defined(__aarch64__) 427 if (reg <= UNW_AARCH64_PC) { 428 *value = context_->uc_mcontext.regs[reg]; 429 } else { 430 result = false; 431 } 432 #elif defined(__x86_64__) 433 switch (reg) { 434 case UNW_X86_64_R8: 435 *value = context_->uc_mcontext.gregs[REG_R8]; 436 break; 437 case UNW_X86_64_R9: 438 *value = context_->uc_mcontext.gregs[REG_R9]; 439 break; 440 case UNW_X86_64_R10: 441 *value = context_->uc_mcontext.gregs[REG_R10]; 442 break; 443 case UNW_X86_64_R11: 444 *value = context_->uc_mcontext.gregs[REG_R11]; 445 break; 446 case UNW_X86_64_R12: 447 *value = context_->uc_mcontext.gregs[REG_R12]; 448 break; 449 case UNW_X86_64_R13: 450 *value = context_->uc_mcontext.gregs[REG_R13]; 451 break; 452 case UNW_X86_64_R14: 453 *value = context_->uc_mcontext.gregs[REG_R14]; 454 break; 455 case UNW_X86_64_R15: 456 *value = context_->uc_mcontext.gregs[REG_R15]; 457 break; 458 case UNW_X86_64_RDI: 459 *value = context_->uc_mcontext.gregs[REG_RDI]; 460 break; 461 case UNW_X86_64_RSI: 462 *value = context_->uc_mcontext.gregs[REG_RSI]; 463 break; 464 case UNW_X86_64_RBP: 465 *value = context_->uc_mcontext.gregs[REG_RBP]; 466 break; 467 case UNW_X86_64_RBX: 468 *value = context_->uc_mcontext.gregs[REG_RBX]; 469 break; 470 case UNW_X86_64_RDX: 471 *value = context_->uc_mcontext.gregs[REG_RDX]; 472 break; 473 case UNW_X86_64_RAX: 474 *value = context_->uc_mcontext.gregs[REG_RAX]; 475 break; 476 case UNW_X86_64_RCX: 477 *value = context_->uc_mcontext.gregs[REG_RCX]; 478 break; 479 case UNW_X86_64_RSP: 480 *value = context_->uc_mcontext.gregs[REG_RSP]; 481 break; 482 case UNW_X86_64_RIP: 483 *value = context_->uc_mcontext.gregs[REG_RIP]; 484 break; 485 default: 486 result = false; 487 } 488 #elif defined(__i386__) 489 switch (reg) { 490 case UNW_X86_GS: 491 *value = context_->uc_mcontext.gregs[REG_GS]; 492 break; 493 case UNW_X86_FS: 494 *value = context_->uc_mcontext.gregs[REG_FS]; 495 break; 496 case UNW_X86_ES: 497 *value = context_->uc_mcontext.gregs[REG_ES]; 498 break; 499 case UNW_X86_DS: 500 *value = context_->uc_mcontext.gregs[REG_DS]; 501 break; 502 case UNW_X86_EAX: 503 *value = context_->uc_mcontext.gregs[REG_EAX]; 504 break; 505 case UNW_X86_EBX: 506 *value = context_->uc_mcontext.gregs[REG_EBX]; 507 break; 508 case UNW_X86_ECX: 509 *value = context_->uc_mcontext.gregs[REG_ECX]; 510 break; 511 case UNW_X86_EDX: 512 *value = context_->uc_mcontext.gregs[REG_EDX]; 513 break; 514 case UNW_X86_ESI: 515 *value = context_->uc_mcontext.gregs[REG_ESI]; 516 break; 517 case UNW_X86_EDI: 518 *value = context_->uc_mcontext.gregs[REG_EDI]; 519 break; 520 case UNW_X86_EBP: 521 *value = context_->uc_mcontext.gregs[REG_EBP]; 522 break; 523 case UNW_X86_EIP: 524 *value = context_->uc_mcontext.gregs[REG_EIP]; 525 break; 526 case UNW_X86_ESP: 527 *value = context_->uc_mcontext.gregs[REG_ESP]; 528 break; 529 case UNW_X86_TRAPNO: 530 *value = context_->uc_mcontext.gregs[REG_TRAPNO]; 531 break; 532 case UNW_X86_CS: 533 *value = context_->uc_mcontext.gregs[REG_CS]; 534 break; 535 case UNW_X86_EFLAGS: 536 *value = context_->uc_mcontext.gregs[REG_EFL]; 537 break; 538 case UNW_X86_SS: 539 *value = context_->uc_mcontext.gregs[REG_SS]; 540 break; 541 default: 542 result = false; 543 } 544 #else 545 UNUSED(reg); 546 UNUSED(value); 547 result = false; 548 #endif 549 return result; 550 } 551 552 std::string BacktraceOffline::GetFunctionNameRaw(uintptr_t, uintptr_t* offset) { 553 // We don't have enough information to support this. And it is expensive. 554 *offset = 0; 555 return ""; 556 } 557 558 static std::mutex g_lock; 559 static std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>* g_debug_frames = nullptr; 560 561 static DebugFrameInfo* ReadDebugFrameFromFile(const std::string& filename); 562 563 DebugFrameInfo* BacktraceOffline::GetDebugFrameInFile(const std::string& filename) { 564 if (cache_file_) { 565 std::lock_guard<std::mutex> lock(g_lock); 566 if (g_debug_frames != nullptr) { 567 auto it = g_debug_frames->find(filename); 568 if (it != g_debug_frames->end()) { 569 return it->second.get(); 570 } 571 } 572 } 573 DebugFrameInfo* debug_frame = ReadDebugFrameFromFile(filename); 574 if (cache_file_) { 575 std::lock_guard<std::mutex> lock(g_lock); 576 if (g_debug_frames == nullptr) { 577 g_debug_frames = new std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>; 578 } 579 auto pair = g_debug_frames->emplace(filename, std::unique_ptr<DebugFrameInfo>(debug_frame)); 580 if (!pair.second) { 581 debug_frame = pair.first->second.get(); 582 } 583 } 584 return debug_frame; 585 } 586 587 static bool OmitEncodedValue(uint8_t encode, const uint8_t*& p) { 588 if (encode == DW_EH_PE_omit) { 589 return 0; 590 } 591 uint8_t format = encode & 0x0f; 592 switch (format) { 593 case DW_EH_PE_ptr: 594 p += sizeof(unw_word_t); 595 break; 596 case DW_EH_PE_uleb128: 597 case DW_EH_PE_sleb128: 598 while ((*p & 0x80) != 0) { 599 ++p; 600 } 601 ++p; 602 break; 603 case DW_EH_PE_udata2: 604 case DW_EH_PE_sdata2: 605 p += 2; 606 break; 607 case DW_EH_PE_udata4: 608 case DW_EH_PE_sdata4: 609 p += 4; 610 break; 611 case DW_EH_PE_udata8: 612 case DW_EH_PE_sdata8: 613 p += 8; 614 break; 615 default: 616 return false; 617 } 618 return true; 619 } 620 621 static bool GetFdeTableOffsetInEhFrameHdr(const std::vector<uint8_t>& data, 622 uint64_t* table_offset_in_eh_frame_hdr) { 623 const uint8_t* p = data.data(); 624 const uint8_t* end = p + data.size(); 625 if (p + 4 > end) { 626 return false; 627 } 628 uint8_t version = *p++; 629 if (version != 1) { 630 return false; 631 } 632 uint8_t eh_frame_ptr_encode = *p++; 633 uint8_t fde_count_encode = *p++; 634 uint8_t fde_table_encode = *p++; 635 636 if (fde_table_encode != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) { 637 return false; 638 } 639 640 if (!OmitEncodedValue(eh_frame_ptr_encode, p) || !OmitEncodedValue(fde_count_encode, p)) { 641 return false; 642 } 643 if (p >= end) { 644 return false; 645 } 646 *table_offset_in_eh_frame_hdr = p - data.data(); 647 return true; 648 } 649 650 template <class ELFT> 651 DebugFrameInfo* ReadDebugFrameFromELFFile(const llvm::object::ELFFile<ELFT>* elf) { 652 DebugFrameInfo* result = new DebugFrameInfo; 653 result->text_end_vaddr = std::numeric_limits<uint64_t>::max(); 654 655 bool has_eh_frame_hdr = false; 656 bool has_eh_frame = false; 657 658 for (auto it = elf->section_begin(); it != elf->section_end(); ++it) { 659 llvm::ErrorOr<llvm::StringRef> name = elf->getSectionName(&*it); 660 if (name) { 661 std::string s = name.get(); 662 if (s == ".debug_frame") { 663 result->has_debug_frame = true; 664 } else if (s == ".gnu_debugdata") { 665 result->has_gnu_debugdata = true; 666 } else if (s == ".eh_frame_hdr") { 667 result->eh_frame.hdr_vaddr = it->sh_addr; 668 llvm::ErrorOr<llvm::ArrayRef<uint8_t>> data = elf->getSectionContents(&*it); 669 if (data) { 670 result->eh_frame.hdr_data.insert(result->eh_frame.hdr_data.end(), 671 data->data(), data->data() + data->size()); 672 673 uint64_t fde_table_offset; 674 if (GetFdeTableOffsetInEhFrameHdr(result->eh_frame.hdr_data, 675 &fde_table_offset)) { 676 result->eh_frame.fde_table_offset = fde_table_offset; 677 // Make sure we have at least one entry in fde_table. 678 if (fde_table_offset + 2 * sizeof(int32_t) <= data->size()) { 679 intptr_t eh_frame_hdr_vaddr = it->sh_addr; 680 int32_t sdata; 681 uint8_t* p = result->eh_frame.hdr_data.data() + fde_table_offset; 682 memcpy(&sdata, p, sizeof(sdata)); 683 result->eh_frame.min_func_vaddr = eh_frame_hdr_vaddr + sdata; 684 has_eh_frame_hdr = true; 685 } 686 } 687 } 688 } else if (s == ".eh_frame") { 689 result->eh_frame.vaddr = it->sh_addr; 690 llvm::ErrorOr<llvm::ArrayRef<uint8_t>> data = elf->getSectionContents(&*it); 691 if (data) { 692 result->eh_frame.data.insert(result->eh_frame.data.end(), 693 data->data(), data->data() + data->size()); 694 has_eh_frame = true; 695 } 696 } else if (s == ".ARM.exidx") { 697 result->arm_exidx.exidx_vaddr = it->sh_addr; 698 llvm::ErrorOr<llvm::ArrayRef<uint8_t>> data = elf->getSectionContents(&*it); 699 if (data) { 700 size_t entry_count = data->size() / sizeof(ArmIdxEntry); 701 result->arm_exidx.exidx_data.resize(entry_count); 702 memcpy(result->arm_exidx.exidx_data.data(), data->data(), 703 entry_count * sizeof(ArmIdxEntry)); 704 if (entry_count > 0u) { 705 // Change IdxEntry.func_offset into vaddr. 706 result->arm_exidx.func_vaddr_array.reserve(entry_count); 707 uint32_t vaddr = it->sh_addr; 708 for (auto& entry : result->arm_exidx.exidx_data) { 709 uint32_t func_offset = entry.func_offset + vaddr; 710 // Clear bit 31 for the prel31 offset. 711 // Arm sets bit 0 to mark it as thumb code, remove the flag. 712 result->arm_exidx.func_vaddr_array.push_back( 713 func_offset & 0x7ffffffe); 714 vaddr += 8; 715 } 716 result->has_arm_exidx = true; 717 } 718 } 719 } else if (s == ".ARM.extab") { 720 result->arm_exidx.extab_vaddr = it->sh_addr; 721 llvm::ErrorOr<llvm::ArrayRef<uint8_t>> data = elf->getSectionContents(&*it); 722 if (data) { 723 result->arm_exidx.extab_data.insert(result->arm_exidx.extab_data.end(), 724 data->data(), data->data() + data->size()); 725 } 726 } else if (s == ".text") { 727 result->text_end_vaddr = it->sh_addr + it->sh_size; 728 } 729 } 730 } 731 732 if (has_eh_frame_hdr && has_eh_frame) { 733 result->has_eh_frame = true; 734 } 735 736 result->min_vaddr = std::numeric_limits<uint64_t>::max(); 737 for (auto it = elf->program_header_begin(); it != elf->program_header_end(); ++it) { 738 if ((it->p_type == llvm::ELF::PT_LOAD) && (it->p_flags & llvm::ELF::PF_X)) { 739 if (it->p_vaddr < result->min_vaddr) { 740 result->min_vaddr = it->p_vaddr; 741 } 742 } 743 } 744 if (!result->has_eh_frame && !result->has_arm_exidx && !result->has_debug_frame && 745 !result->has_gnu_debugdata) { 746 delete result; 747 return nullptr; 748 } 749 return result; 750 } 751 752 static bool IsValidElfPath(const std::string& filename) { 753 static const char elf_magic[] = {0x7f, 'E', 'L', 'F'}; 754 755 struct stat st; 756 if (stat(filename.c_str(), &st) != 0 || !S_ISREG(st.st_mode)) { 757 return false; 758 } 759 FILE* fp = fopen(filename.c_str(), "reb"); 760 if (fp == nullptr) { 761 return false; 762 } 763 char buf[4]; 764 if (fread(buf, 4, 1, fp) != 1) { 765 fclose(fp); 766 return false; 767 } 768 fclose(fp); 769 return memcmp(buf, elf_magic, 4) == 0; 770 } 771 772 static bool IsValidApkPath(const std::string& apk_path) { 773 static const char zip_preamble[] = {0x50, 0x4b, 0x03, 0x04}; 774 struct stat st; 775 if (stat(apk_path.c_str(), &st) != 0 || !S_ISREG(st.st_mode)) { 776 return false; 777 } 778 FILE* fp = fopen(apk_path.c_str(), "reb"); 779 if (fp == nullptr) { 780 return false; 781 } 782 char buf[4]; 783 if (fread(buf, 4, 1, fp) != 1) { 784 fclose(fp); 785 return false; 786 } 787 fclose(fp); 788 return memcmp(buf, zip_preamble, 4) == 0; 789 } 790 791 class ScopedZiparchiveHandle { 792 public: 793 explicit ScopedZiparchiveHandle(ZipArchiveHandle handle) : handle_(handle) { 794 } 795 796 ~ScopedZiparchiveHandle() { 797 CloseArchive(handle_); 798 } 799 800 private: 801 ZipArchiveHandle handle_; 802 }; 803 804 llvm::object::OwningBinary<llvm::object::Binary> OpenEmbeddedElfFile(const std::string& filename) { 805 llvm::object::OwningBinary<llvm::object::Binary> nothing; 806 size_t pos = filename.find("!/"); 807 if (pos == std::string::npos) { 808 return nothing; 809 } 810 std::string apk_file = filename.substr(0, pos); 811 std::string elf_file = filename.substr(pos + 2); 812 if (!IsValidApkPath(apk_file)) { 813 BACK_LOGW("%s is not a valid apk file", apk_file.c_str()); 814 return nothing; 815 } 816 ZipArchiveHandle handle; 817 int32_t ret_code = OpenArchive(apk_file.c_str(), &handle); 818 if (ret_code != 0) { 819 CloseArchive(handle); 820 BACK_LOGW("failed to open archive %s: %s", apk_file.c_str(), ErrorCodeString(ret_code)); 821 return nothing; 822 } 823 ScopedZiparchiveHandle scoped_handle(handle); 824 ZipEntry zentry; 825 ret_code = FindEntry(handle, ZipString(elf_file.c_str()), &zentry); 826 if (ret_code != 0) { 827 BACK_LOGW("failed to find %s in %s: %s", elf_file.c_str(), apk_file.c_str(), 828 ErrorCodeString(ret_code)); 829 return nothing; 830 } 831 if (zentry.method != kCompressStored || zentry.compressed_length != zentry.uncompressed_length) { 832 BACK_LOGW("%s is compressed in %s, which doesn't support running directly", elf_file.c_str(), 833 apk_file.c_str()); 834 return nothing; 835 } 836 auto buffer_or_err = llvm::MemoryBuffer::getOpenFileSlice(GetFileDescriptor(handle), apk_file, 837 zentry.uncompressed_length, 838 zentry.offset); 839 if (!buffer_or_err) { 840 BACK_LOGW("failed to read %s in %s: %s", elf_file.c_str(), apk_file.c_str(), 841 buffer_or_err.getError().message().c_str()); 842 return nothing; 843 } 844 auto binary_or_err = llvm::object::createBinary(buffer_or_err.get()->getMemBufferRef()); 845 if (!binary_or_err) { 846 BACK_LOGW("failed to create binary for %s in %s: %s", elf_file.c_str(), apk_file.c_str(), 847 llvm::toString(binary_or_err.takeError()).c_str()); 848 return nothing; 849 } 850 return llvm::object::OwningBinary<llvm::object::Binary>(std::move(binary_or_err.get()), 851 std::move(buffer_or_err.get())); 852 } 853 854 static DebugFrameInfo* ReadDebugFrameFromFile(const std::string& filename) { 855 llvm::object::OwningBinary<llvm::object::Binary> owning_binary; 856 if (filename.find("!/") != std::string::npos) { 857 owning_binary = OpenEmbeddedElfFile(filename); 858 } else { 859 if (!IsValidElfPath(filename)) { 860 return nullptr; 861 } 862 auto binary_or_err = llvm::object::createBinary(llvm::StringRef(filename)); 863 if (!binary_or_err) { 864 return nullptr; 865 } 866 owning_binary = std::move(binary_or_err.get()); 867 } 868 llvm::object::Binary* binary = owning_binary.getBinary(); 869 auto obj = llvm::dyn_cast<llvm::object::ObjectFile>(binary); 870 if (obj == nullptr) { 871 return nullptr; 872 } 873 if (auto elf = llvm::dyn_cast<llvm::object::ELF32LEObjectFile>(obj)) { 874 return ReadDebugFrameFromELFFile(elf->getELFFile()); 875 } 876 if (auto elf = llvm::dyn_cast<llvm::object::ELF64LEObjectFile>(obj)) { 877 return ReadDebugFrameFromELFFile(elf->getELFFile()); 878 } 879 return nullptr; 880 } 881 882 Backtrace* Backtrace::CreateOffline(pid_t pid, pid_t tid, BacktraceMap* map, 883 const backtrace_stackinfo_t& stack, bool cache_file) { 884 return new BacktraceOffline(pid, tid, map, stack, cache_file); 885 } 886