Home | History | Annotate | Download | only in libbacktrace
      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, &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