Home | History | Annotate | Download | only in libunwindstack
      1 /*
      2  * Copyright (C) 2017 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 <stdint.h>
     18 
     19 #include <unwindstack/DwarfError.h>
     20 #include <unwindstack/DwarfLocation.h>
     21 #include <unwindstack/DwarfMemory.h>
     22 #include <unwindstack/DwarfSection.h>
     23 #include <unwindstack/DwarfStructs.h>
     24 #include <unwindstack/Log.h>
     25 #include <unwindstack/Memory.h>
     26 #include <unwindstack/Regs.h>
     27 
     28 #include "DwarfCfa.h"
     29 #include "DwarfDebugFrame.h"
     30 #include "DwarfEhFrame.h"
     31 #include "DwarfEncoding.h"
     32 #include "DwarfOp.h"
     33 #include "RegsInfo.h"
     34 
     35 namespace unwindstack {
     36 
     37 DwarfSection::DwarfSection(Memory* memory) : memory_(memory) {}
     38 
     39 const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) {
     40   uint64_t fde_offset;
     41   if (!GetFdeOffsetFromPc(pc, &fde_offset)) {
     42     return nullptr;
     43   }
     44   const DwarfFde* fde = GetFdeFromOffset(fde_offset);
     45   if (fde == nullptr) {
     46     return nullptr;
     47   }
     48 
     49   // Guaranteed pc >= pc_start, need to check pc in the fde range.
     50   if (pc < fde->pc_end) {
     51     return fde;
     52   }
     53   last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
     54   return nullptr;
     55 }
     56 
     57 bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
     58   // Lookup the pc in the cache.
     59   auto it = loc_regs_.upper_bound(pc);
     60   if (it == loc_regs_.end() || pc < it->second.pc_start) {
     61     last_error_.code = DWARF_ERROR_NONE;
     62     const DwarfFde* fde = GetFdeFromPc(pc);
     63     if (fde == nullptr || fde->cie == nullptr) {
     64       last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
     65       return false;
     66     }
     67 
     68     // Now get the location information for this pc.
     69     dwarf_loc_regs_t loc_regs;
     70     if (!GetCfaLocationInfo(pc, fde, &loc_regs)) {
     71       return false;
     72     }
     73     loc_regs.cie = fde->cie;
     74 
     75     // Store it in the cache.
     76     it = loc_regs_.emplace(loc_regs.pc_end, std::move(loc_regs)).first;
     77   }
     78 
     79   // Now eval the actual registers.
     80   return Eval(it->second.cie, process_memory, it->second, regs, finished);
     81 }
     82 
     83 template <typename AddressType>
     84 bool DwarfSectionImpl<AddressType>::EvalExpression(const DwarfLocation& loc, Memory* regular_memory,
     85                                                    AddressType* value,
     86                                                    RegsInfo<AddressType>* regs_info,
     87                                                    bool* is_dex_pc) {
     88   DwarfOp<AddressType> op(&memory_, regular_memory);
     89   op.set_regs_info(regs_info);
     90 
     91   // Need to evaluate the op data.
     92   uint64_t end = loc.values[1];
     93   uint64_t start = end - loc.values[0];
     94   if (!op.Eval(start, end)) {
     95     last_error_ = op.last_error();
     96     return false;
     97   }
     98   if (op.StackSize() == 0) {
     99     last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
    100     return false;
    101   }
    102   // We don't support an expression that evaluates to a register number.
    103   if (op.is_register()) {
    104     last_error_.code = DWARF_ERROR_NOT_IMPLEMENTED;
    105     return false;
    106   }
    107   *value = op.StackAt(0);
    108   if (is_dex_pc != nullptr && op.dex_pc_set()) {
    109     *is_dex_pc = true;
    110   }
    111   return true;
    112 }
    113 
    114 template <typename AddressType>
    115 struct EvalInfo {
    116   const dwarf_loc_regs_t* loc_regs;
    117   const DwarfCie* cie;
    118   Memory* regular_memory;
    119   AddressType cfa;
    120   bool return_address_undefined = false;
    121   RegsInfo<AddressType> regs_info;
    122 };
    123 
    124 template <typename AddressType>
    125 bool DwarfSectionImpl<AddressType>::EvalRegister(const DwarfLocation* loc, uint32_t reg,
    126                                                  AddressType* reg_ptr, void* info) {
    127   EvalInfo<AddressType>* eval_info = reinterpret_cast<EvalInfo<AddressType>*>(info);
    128   Memory* regular_memory = eval_info->regular_memory;
    129   switch (loc->type) {
    130     case DWARF_LOCATION_OFFSET:
    131       if (!regular_memory->ReadFully(eval_info->cfa + loc->values[0], reg_ptr, sizeof(AddressType))) {
    132         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    133         last_error_.address = eval_info->cfa + loc->values[0];
    134         return false;
    135       }
    136       break;
    137     case DWARF_LOCATION_VAL_OFFSET:
    138       *reg_ptr = eval_info->cfa + loc->values[0];
    139       break;
    140     case DWARF_LOCATION_REGISTER: {
    141       uint32_t cur_reg = loc->values[0];
    142       if (cur_reg >= eval_info->regs_info.Total()) {
    143         last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    144         return false;
    145       }
    146       *reg_ptr = eval_info->regs_info.Get(cur_reg) + loc->values[1];
    147       break;
    148     }
    149     case DWARF_LOCATION_EXPRESSION:
    150     case DWARF_LOCATION_VAL_EXPRESSION: {
    151       AddressType value;
    152       bool is_dex_pc = false;
    153       if (!EvalExpression(*loc, regular_memory, &value, &eval_info->regs_info, &is_dex_pc)) {
    154         return false;
    155       }
    156       if (loc->type == DWARF_LOCATION_EXPRESSION) {
    157         if (!regular_memory->ReadFully(value, reg_ptr, sizeof(AddressType))) {
    158           last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    159           last_error_.address = value;
    160           return false;
    161         }
    162       } else {
    163         *reg_ptr = value;
    164         if (is_dex_pc) {
    165           eval_info->regs_info.regs->set_dex_pc(value);
    166         }
    167       }
    168       break;
    169     }
    170     case DWARF_LOCATION_UNDEFINED:
    171       if (reg == eval_info->cie->return_address_register) {
    172         eval_info->return_address_undefined = true;
    173       }
    174     default:
    175       break;
    176   }
    177 
    178   return true;
    179 }
    180 
    181 template <typename AddressType>
    182 bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_memory,
    183                                          const dwarf_loc_regs_t& loc_regs, Regs* regs,
    184                                          bool* finished) {
    185   RegsImpl<AddressType>* cur_regs = reinterpret_cast<RegsImpl<AddressType>*>(regs);
    186   if (cie->return_address_register >= cur_regs->total_regs()) {
    187     last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    188     return false;
    189   }
    190 
    191   // Get the cfa value;
    192   auto cfa_entry = loc_regs.find(CFA_REG);
    193   if (cfa_entry == loc_regs.end()) {
    194     last_error_.code = DWARF_ERROR_CFA_NOT_DEFINED;
    195     return false;
    196   }
    197 
    198   // Always set the dex pc to zero when evaluating.
    199   cur_regs->set_dex_pc(0);
    200 
    201   EvalInfo<AddressType> eval_info{.loc_regs = &loc_regs,
    202                                   .cie = cie,
    203                                   .regular_memory = regular_memory,
    204                                   .regs_info = RegsInfo<AddressType>(cur_regs)};
    205   const DwarfLocation* loc = &cfa_entry->second;
    206   // Only a few location types are valid for the cfa.
    207   switch (loc->type) {
    208     case DWARF_LOCATION_REGISTER:
    209       if (loc->values[0] >= cur_regs->total_regs()) {
    210         last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    211         return false;
    212       }
    213       eval_info.cfa = (*cur_regs)[loc->values[0]];
    214       eval_info.cfa += loc->values[1];
    215       break;
    216     case DWARF_LOCATION_VAL_EXPRESSION: {
    217       AddressType value;
    218       if (!EvalExpression(*loc, regular_memory, &value, &eval_info.regs_info, nullptr)) {
    219         return false;
    220       }
    221       // There is only one type of valid expression for CFA evaluation.
    222       eval_info.cfa = value;
    223       break;
    224     }
    225     default:
    226       last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    227       return false;
    228   }
    229 
    230   for (const auto& entry : loc_regs) {
    231     uint32_t reg = entry.first;
    232     // Already handled the CFA register.
    233     if (reg == CFA_REG) continue;
    234 
    235     AddressType* reg_ptr;
    236     if (reg >= cur_regs->total_regs()) {
    237       // Skip this unknown register.
    238       continue;
    239     }
    240 
    241     reg_ptr = eval_info.regs_info.Save(reg);
    242     if (!EvalRegister(&entry.second, reg, reg_ptr, &eval_info)) {
    243       return false;
    244     }
    245   }
    246 
    247   // Find the return address location.
    248   if (eval_info.return_address_undefined) {
    249     cur_regs->set_pc(0);
    250   } else {
    251     cur_regs->set_pc((*cur_regs)[cie->return_address_register]);
    252   }
    253 
    254   // If the pc was set to zero, consider this the final frame.
    255   *finished = (cur_regs->pc() == 0) ? true : false;
    256 
    257   cur_regs->set_sp(eval_info.cfa);
    258 
    259   return true;
    260 }
    261 
    262 template <typename AddressType>
    263 const DwarfCie* DwarfSectionImpl<AddressType>::GetCie(uint64_t offset) {
    264   auto cie_entry = cie_entries_.find(offset);
    265   if (cie_entry != cie_entries_.end()) {
    266     return &cie_entry->second;
    267   }
    268   DwarfCie* cie = &cie_entries_[offset];
    269   memory_.set_cur_offset(offset);
    270   if (!FillInCie(cie)) {
    271     // Erase the cached entry.
    272     cie_entries_.erase(offset);
    273     return nullptr;
    274   }
    275   return cie;
    276 }
    277 
    278 template <typename AddressType>
    279 bool DwarfSectionImpl<AddressType>::FillInCie(DwarfCie* cie) {
    280   uint32_t length32;
    281   if (!memory_.ReadBytes(&length32, sizeof(length32))) {
    282     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    283     last_error_.address = memory_.cur_offset();
    284     return false;
    285   }
    286   // Set the default for the lsda encoding.
    287   cie->lsda_encoding = DW_EH_PE_omit;
    288 
    289   if (length32 == static_cast<uint32_t>(-1)) {
    290     // 64 bit Cie
    291     uint64_t length64;
    292     if (!memory_.ReadBytes(&length64, sizeof(length64))) {
    293       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    294       last_error_.address = memory_.cur_offset();
    295       return false;
    296     }
    297 
    298     cie->cfa_instructions_end = memory_.cur_offset() + length64;
    299     cie->fde_address_encoding = DW_EH_PE_sdata8;
    300 
    301     uint64_t cie_id;
    302     if (!memory_.ReadBytes(&cie_id, sizeof(cie_id))) {
    303       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    304       last_error_.address = memory_.cur_offset();
    305       return false;
    306     }
    307     if (cie_id != cie64_value_) {
    308       // This is not a Cie, something has gone horribly wrong.
    309       last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    310       return false;
    311     }
    312   } else {
    313     // 32 bit Cie
    314     cie->cfa_instructions_end = memory_.cur_offset() + length32;
    315     cie->fde_address_encoding = DW_EH_PE_sdata4;
    316 
    317     uint32_t cie_id;
    318     if (!memory_.ReadBytes(&cie_id, sizeof(cie_id))) {
    319       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    320       last_error_.address = memory_.cur_offset();
    321       return false;
    322     }
    323     if (cie_id != cie32_value_) {
    324       // This is not a Cie, something has gone horribly wrong.
    325       last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    326       return false;
    327     }
    328   }
    329 
    330   if (!memory_.ReadBytes(&cie->version, sizeof(cie->version))) {
    331     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    332     last_error_.address = memory_.cur_offset();
    333     return false;
    334   }
    335 
    336   if (cie->version != 1 && cie->version != 3 && cie->version != 4) {
    337     // Unrecognized version.
    338     last_error_.code = DWARF_ERROR_UNSUPPORTED_VERSION;
    339     return false;
    340   }
    341 
    342   // Read the augmentation string.
    343   char aug_value;
    344   do {
    345     if (!memory_.ReadBytes(&aug_value, 1)) {
    346       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    347       last_error_.address = memory_.cur_offset();
    348       return false;
    349     }
    350     cie->augmentation_string.push_back(aug_value);
    351   } while (aug_value != '\0');
    352 
    353   if (cie->version == 4) {
    354     // Skip the Address Size field since we only use it for validation.
    355     memory_.set_cur_offset(memory_.cur_offset() + 1);
    356 
    357     // Segment Size
    358     if (!memory_.ReadBytes(&cie->segment_size, 1)) {
    359       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    360       last_error_.address = memory_.cur_offset();
    361       return false;
    362     }
    363   }
    364 
    365   // Code Alignment Factor
    366   if (!memory_.ReadULEB128(&cie->code_alignment_factor)) {
    367     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    368     last_error_.address = memory_.cur_offset();
    369     return false;
    370   }
    371 
    372   // Data Alignment Factor
    373   if (!memory_.ReadSLEB128(&cie->data_alignment_factor)) {
    374     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    375     last_error_.address = memory_.cur_offset();
    376     return false;
    377   }
    378 
    379   if (cie->version == 1) {
    380     // Return Address is a single byte.
    381     uint8_t return_address_register;
    382     if (!memory_.ReadBytes(&return_address_register, 1)) {
    383       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    384       last_error_.address = memory_.cur_offset();
    385       return false;
    386     }
    387     cie->return_address_register = return_address_register;
    388   } else if (!memory_.ReadULEB128(&cie->return_address_register)) {
    389     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    390     last_error_.address = memory_.cur_offset();
    391     return false;
    392   }
    393 
    394   if (cie->augmentation_string[0] != 'z') {
    395     cie->cfa_instructions_offset = memory_.cur_offset();
    396     return true;
    397   }
    398 
    399   uint64_t aug_length;
    400   if (!memory_.ReadULEB128(&aug_length)) {
    401     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    402     last_error_.address = memory_.cur_offset();
    403     return false;
    404   }
    405   cie->cfa_instructions_offset = memory_.cur_offset() + aug_length;
    406 
    407   for (size_t i = 1; i < cie->augmentation_string.size(); i++) {
    408     switch (cie->augmentation_string[i]) {
    409       case 'L':
    410         if (!memory_.ReadBytes(&cie->lsda_encoding, 1)) {
    411           last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    412           last_error_.address = memory_.cur_offset();
    413           return false;
    414         }
    415         break;
    416       case 'P': {
    417         uint8_t encoding;
    418         if (!memory_.ReadBytes(&encoding, 1)) {
    419           last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    420           last_error_.address = memory_.cur_offset();
    421           return false;
    422         }
    423         if (!memory_.ReadEncodedValue<AddressType>(encoding, &cie->personality_handler)) {
    424           last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    425           last_error_.address = memory_.cur_offset();
    426           return false;
    427         }
    428       } break;
    429       case 'R':
    430         if (!memory_.ReadBytes(&cie->fde_address_encoding, 1)) {
    431           last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    432           last_error_.address = memory_.cur_offset();
    433           return false;
    434         }
    435         break;
    436     }
    437   }
    438   return true;
    439 }
    440 
    441 template <typename AddressType>
    442 const DwarfFde* DwarfSectionImpl<AddressType>::GetFdeFromOffset(uint64_t offset) {
    443   auto fde_entry = fde_entries_.find(offset);
    444   if (fde_entry != fde_entries_.end()) {
    445     return &fde_entry->second;
    446   }
    447   DwarfFde* fde = &fde_entries_[offset];
    448   memory_.set_cur_offset(offset);
    449   if (!FillInFde(fde)) {
    450     fde_entries_.erase(offset);
    451     return nullptr;
    452   }
    453   return fde;
    454 }
    455 
    456 template <typename AddressType>
    457 bool DwarfSectionImpl<AddressType>::FillInFde(DwarfFde* fde) {
    458   uint32_t length32;
    459   if (!memory_.ReadBytes(&length32, sizeof(length32))) {
    460     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    461     last_error_.address = memory_.cur_offset();
    462     return false;
    463   }
    464 
    465   if (length32 == static_cast<uint32_t>(-1)) {
    466     // 64 bit Fde.
    467     uint64_t length64;
    468     if (!memory_.ReadBytes(&length64, sizeof(length64))) {
    469       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    470       last_error_.address = memory_.cur_offset();
    471       return false;
    472     }
    473     fde->cfa_instructions_end = memory_.cur_offset() + length64;
    474 
    475     uint64_t value64;
    476     if (!memory_.ReadBytes(&value64, sizeof(value64))) {
    477       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    478       last_error_.address = memory_.cur_offset();
    479       return false;
    480     }
    481     if (value64 == cie64_value_) {
    482       // This is a Cie, this means something has gone wrong.
    483       last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    484       return false;
    485     }
    486 
    487     // Get the Cie pointer, which is necessary to properly read the rest of
    488     // of the Fde information.
    489     fde->cie_offset = GetCieOffsetFromFde64(value64);
    490   } else {
    491     // 32 bit Fde.
    492     fde->cfa_instructions_end = memory_.cur_offset() + length32;
    493 
    494     uint32_t value32;
    495     if (!memory_.ReadBytes(&value32, sizeof(value32))) {
    496       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    497       last_error_.address = memory_.cur_offset();
    498       return false;
    499     }
    500     if (value32 == cie32_value_) {
    501       // This is a Cie, this means something has gone wrong.
    502       last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    503       return false;
    504     }
    505 
    506     // Get the Cie pointer, which is necessary to properly read the rest of
    507     // of the Fde information.
    508     fde->cie_offset = GetCieOffsetFromFde32(value32);
    509   }
    510   uint64_t cur_offset = memory_.cur_offset();
    511 
    512   const DwarfCie* cie = GetCie(fde->cie_offset);
    513   if (cie == nullptr) {
    514     return false;
    515   }
    516   fde->cie = cie;
    517 
    518   if (cie->segment_size != 0) {
    519     // Skip over the segment selector for now.
    520     cur_offset += cie->segment_size;
    521   }
    522   memory_.set_cur_offset(cur_offset);
    523 
    524   if (!memory_.ReadEncodedValue<AddressType>(cie->fde_address_encoding & 0xf, &fde->pc_start)) {
    525     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    526     last_error_.address = memory_.cur_offset();
    527     return false;
    528   }
    529   fde->pc_start = AdjustPcFromFde(fde->pc_start);
    530 
    531   if (!memory_.ReadEncodedValue<AddressType>(cie->fde_address_encoding & 0xf, &fde->pc_end)) {
    532     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    533     last_error_.address = memory_.cur_offset();
    534     return false;
    535   }
    536   fde->pc_end += fde->pc_start;
    537   if (cie->augmentation_string.size() > 0 && cie->augmentation_string[0] == 'z') {
    538     // Augmentation Size
    539     uint64_t aug_length;
    540     if (!memory_.ReadULEB128(&aug_length)) {
    541       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    542       last_error_.address = memory_.cur_offset();
    543       return false;
    544     }
    545     uint64_t cur_offset = memory_.cur_offset();
    546 
    547     if (!memory_.ReadEncodedValue<AddressType>(cie->lsda_encoding, &fde->lsda_address)) {
    548       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    549       last_error_.address = memory_.cur_offset();
    550       return false;
    551     }
    552 
    553     // Set our position to after all of the augmentation data.
    554     memory_.set_cur_offset(cur_offset + aug_length);
    555   }
    556   fde->cfa_instructions_offset = memory_.cur_offset();
    557 
    558   return true;
    559 }
    560 
    561 template <typename AddressType>
    562 bool DwarfSectionImpl<AddressType>::GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde,
    563                                                        dwarf_loc_regs_t* loc_regs) {
    564   DwarfCfa<AddressType> cfa(&memory_, fde);
    565 
    566   // Look for the cached copy of the cie data.
    567   auto reg_entry = cie_loc_regs_.find(fde->cie_offset);
    568   if (reg_entry == cie_loc_regs_.end()) {
    569     if (!cfa.GetLocationInfo(pc, fde->cie->cfa_instructions_offset, fde->cie->cfa_instructions_end,
    570                              loc_regs)) {
    571       last_error_ = cfa.last_error();
    572       return false;
    573     }
    574     cie_loc_regs_[fde->cie_offset] = *loc_regs;
    575   }
    576   cfa.set_cie_loc_regs(&cie_loc_regs_[fde->cie_offset]);
    577   if (!cfa.GetLocationInfo(pc, fde->cfa_instructions_offset, fde->cfa_instructions_end, loc_regs)) {
    578     last_error_ = cfa.last_error();
    579     return false;
    580   }
    581   return true;
    582 }
    583 
    584 template <typename AddressType>
    585 bool DwarfSectionImpl<AddressType>::Log(uint8_t indent, uint64_t pc, uint64_t load_bias,
    586                                         const DwarfFde* fde) {
    587   DwarfCfa<AddressType> cfa(&memory_, fde);
    588 
    589   // Always print the cie information.
    590   const DwarfCie* cie = fde->cie;
    591   if (!cfa.Log(indent, pc, load_bias, cie->cfa_instructions_offset, cie->cfa_instructions_end)) {
    592     last_error_ = cfa.last_error();
    593     return false;
    594   }
    595   if (!cfa.Log(indent, pc, load_bias, fde->cfa_instructions_offset, fde->cfa_instructions_end)) {
    596     last_error_ = cfa.last_error();
    597     return false;
    598   }
    599   return true;
    600 }
    601 
    602 template <typename AddressType>
    603 bool DwarfSectionImpl<AddressType>::Init(uint64_t offset, uint64_t size) {
    604   entries_offset_ = offset;
    605   entries_end_ = offset + size;
    606 
    607   memory_.clear_func_offset();
    608   memory_.clear_text_offset();
    609   memory_.set_data_offset(offset);
    610   memory_.set_cur_offset(offset);
    611   memory_.set_pc_offset(offset);
    612 
    613   return CreateSortedFdeList();
    614 }
    615 
    616 template <typename AddressType>
    617 bool DwarfSectionImpl<AddressType>::GetCieInfo(uint8_t* segment_size, uint8_t* encoding) {
    618   uint8_t version;
    619   if (!memory_.ReadBytes(&version, 1)) {
    620     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    621     last_error_.address = memory_.cur_offset();
    622     return false;
    623   }
    624   // Read the augmentation string.
    625   std::vector<char> aug_string;
    626   char aug_value;
    627   bool get_encoding = false;
    628   do {
    629     if (!memory_.ReadBytes(&aug_value, 1)) {
    630       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    631       last_error_.address = memory_.cur_offset();
    632       return false;
    633     }
    634     if (aug_value == 'R') {
    635       get_encoding = true;
    636     }
    637     aug_string.push_back(aug_value);
    638   } while (aug_value != '\0');
    639 
    640   if (version == 4) {
    641     // Skip the Address Size field.
    642     memory_.set_cur_offset(memory_.cur_offset() + 1);
    643 
    644     // Read the segment size.
    645     if (!memory_.ReadBytes(segment_size, 1)) {
    646       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    647       last_error_.address = memory_.cur_offset();
    648       return false;
    649     }
    650   } else {
    651     *segment_size = 0;
    652   }
    653 
    654   if (aug_string[0] != 'z' || !get_encoding) {
    655     // No encoding
    656     return true;
    657   }
    658 
    659   // Skip code alignment factor
    660   uint8_t value;
    661   do {
    662     if (!memory_.ReadBytes(&value, 1)) {
    663       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    664       last_error_.address = memory_.cur_offset();
    665       return false;
    666     }
    667   } while (value & 0x80);
    668 
    669   // Skip data alignment factor
    670   do {
    671     if (!memory_.ReadBytes(&value, 1)) {
    672       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    673       last_error_.address = memory_.cur_offset();
    674       return false;
    675     }
    676   } while (value & 0x80);
    677 
    678   if (version == 1) {
    679     // Skip return address register.
    680     memory_.set_cur_offset(memory_.cur_offset() + 1);
    681   } else {
    682     // Skip return address register.
    683     do {
    684       if (!memory_.ReadBytes(&value, 1)) {
    685         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    686         last_error_.address = memory_.cur_offset();
    687         return false;
    688       }
    689     } while (value & 0x80);
    690   }
    691 
    692   // Skip the augmentation length.
    693   do {
    694     if (!memory_.ReadBytes(&value, 1)) {
    695       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    696       last_error_.address = memory_.cur_offset();
    697       return false;
    698     }
    699   } while (value & 0x80);
    700 
    701   for (size_t i = 1; i < aug_string.size(); i++) {
    702     if (aug_string[i] == 'R') {
    703       if (!memory_.ReadBytes(encoding, 1)) {
    704         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    705         last_error_.address = memory_.cur_offset();
    706         return false;
    707       }
    708       // Got the encoding, that's all we are looking for.
    709       return true;
    710     } else if (aug_string[i] == 'L') {
    711       memory_.set_cur_offset(memory_.cur_offset() + 1);
    712     } else if (aug_string[i] == 'P') {
    713       uint8_t encoding;
    714       if (!memory_.ReadBytes(&encoding, 1)) {
    715         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    716         last_error_.address = memory_.cur_offset();
    717         return false;
    718       }
    719       uint64_t value;
    720       if (!memory_.template ReadEncodedValue<AddressType>(encoding, &value)) {
    721         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    722         last_error_.address = memory_.cur_offset();
    723         return false;
    724       }
    725     }
    726   }
    727 
    728   // It should be impossible to get here.
    729   abort();
    730 }
    731 
    732 template <typename AddressType>
    733 bool DwarfSectionImpl<AddressType>::AddFdeInfo(uint64_t entry_offset, uint8_t segment_size,
    734                                                uint8_t encoding) {
    735   if (segment_size != 0) {
    736     memory_.set_cur_offset(memory_.cur_offset() + 1);
    737   }
    738 
    739   uint64_t start;
    740   if (!memory_.template ReadEncodedValue<AddressType>(encoding & 0xf, &start)) {
    741     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    742     last_error_.address = memory_.cur_offset();
    743     return false;
    744   }
    745   start = AdjustPcFromFde(start);
    746 
    747   uint64_t length;
    748   if (!memory_.template ReadEncodedValue<AddressType>(encoding & 0xf, &length)) {
    749     last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    750     last_error_.address = memory_.cur_offset();
    751     return false;
    752   }
    753   if (length != 0) {
    754     fdes_.emplace_back(entry_offset, start, length);
    755   }
    756 
    757   return true;
    758 }
    759 
    760 template <typename AddressType>
    761 bool DwarfSectionImpl<AddressType>::CreateSortedFdeList() {
    762   memory_.set_cur_offset(entries_offset_);
    763 
    764   // Loop through all of the entries and read just enough to create
    765   // a sorted list of pcs.
    766   // This code assumes that first comes the cie, then the fdes that
    767   // it applies to.
    768   uint64_t cie_offset = 0;
    769   uint8_t address_encoding;
    770   uint8_t segment_size;
    771   while (memory_.cur_offset() < entries_end_) {
    772     uint64_t cur_entry_offset = memory_.cur_offset();
    773 
    774     // Figure out the entry length and type.
    775     uint32_t value32;
    776     if (!memory_.ReadBytes(&value32, sizeof(value32))) {
    777       last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    778       last_error_.address = memory_.cur_offset();
    779       return false;
    780     }
    781 
    782     uint64_t next_entry_offset;
    783     if (value32 == static_cast<uint32_t>(-1)) {
    784       uint64_t value64;
    785       if (!memory_.ReadBytes(&value64, sizeof(value64))) {
    786         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    787         last_error_.address = memory_.cur_offset();
    788         return false;
    789       }
    790       next_entry_offset = memory_.cur_offset() + value64;
    791 
    792       // Read the Cie Id of a Cie or the pointer of the Fde.
    793       if (!memory_.ReadBytes(&value64, sizeof(value64))) {
    794         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    795         last_error_.address = memory_.cur_offset();
    796         return false;
    797       }
    798 
    799       if (value64 == cie64_value_) {
    800         // Cie 64 bit
    801         address_encoding = DW_EH_PE_sdata8;
    802         if (!GetCieInfo(&segment_size, &address_encoding)) {
    803           return false;
    804         }
    805         cie_offset = cur_entry_offset;
    806       } else {
    807         uint64_t last_cie_offset = GetCieOffsetFromFde64(value64);
    808         if (last_cie_offset != cie_offset) {
    809           // This means that this Fde is not following the Cie.
    810           last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    811           return false;
    812         }
    813 
    814         // Fde 64 bit
    815         if (!AddFdeInfo(cur_entry_offset, segment_size, address_encoding)) {
    816           return false;
    817         }
    818       }
    819     } else {
    820       next_entry_offset = memory_.cur_offset() + value32;
    821 
    822       // Read the Cie Id of a Cie or the pointer of the Fde.
    823       if (!memory_.ReadBytes(&value32, sizeof(value32))) {
    824         last_error_.code = DWARF_ERROR_MEMORY_INVALID;
    825         last_error_.address = memory_.cur_offset();
    826         return false;
    827       }
    828 
    829       if (value32 == cie32_value_) {
    830         // Cie 32 bit
    831         address_encoding = DW_EH_PE_sdata4;
    832         if (!GetCieInfo(&segment_size, &address_encoding)) {
    833           return false;
    834         }
    835         cie_offset = cur_entry_offset;
    836       } else {
    837         uint64_t last_cie_offset = GetCieOffsetFromFde32(value32);
    838         if (last_cie_offset != cie_offset) {
    839           // This means that this Fde is not following the Cie.
    840           last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
    841           return false;
    842         }
    843 
    844         // Fde 32 bit
    845         if (!AddFdeInfo(cur_entry_offset, segment_size, address_encoding)) {
    846           return false;
    847         }
    848       }
    849     }
    850 
    851     if (next_entry_offset < memory_.cur_offset()) {
    852       // Simply consider the processing done in this case.
    853       break;
    854     }
    855     memory_.set_cur_offset(next_entry_offset);
    856   }
    857 
    858   // Sort the entries.
    859   std::sort(fdes_.begin(), fdes_.end(), [](const FdeInfo& a, const FdeInfo& b) {
    860     if (a.start == b.start) return a.end < b.end;
    861     return a.start < b.start;
    862   });
    863 
    864   fde_count_ = fdes_.size();
    865 
    866   return true;
    867 }
    868 
    869 template <typename AddressType>
    870 bool DwarfSectionImpl<AddressType>::GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) {
    871   if (fde_count_ == 0) {
    872     return false;
    873   }
    874 
    875   size_t first = 0;
    876   size_t last = fde_count_;
    877   while (first < last) {
    878     size_t current = (first + last) / 2;
    879     const FdeInfo* info = &fdes_[current];
    880     if (pc >= info->start && pc <= info->end) {
    881       *fde_offset = info->offset;
    882       return true;
    883     }
    884 
    885     if (pc < info->start) {
    886       last = current;
    887     } else {
    888       first = current + 1;
    889     }
    890   }
    891   return false;
    892 }
    893 
    894 template <typename AddressType>
    895 const DwarfFde* DwarfSectionImpl<AddressType>::GetFdeFromIndex(size_t index) {
    896   if (index >= fdes_.size()) {
    897     return nullptr;
    898   }
    899   return this->GetFdeFromOffset(fdes_[index].offset);
    900 }
    901 
    902 // Explicitly instantiate DwarfSectionImpl
    903 template class DwarfSectionImpl<uint32_t>;
    904 template class DwarfSectionImpl<uint64_t>;
    905 
    906 // Explicitly instantiate DwarfDebugFrame
    907 template class DwarfDebugFrame<uint32_t>;
    908 template class DwarfDebugFrame<uint64_t>;
    909 
    910 // Explicitly instantiate DwarfEhFrame
    911 template class DwarfEhFrame<uint32_t>;
    912 template class DwarfEhFrame<uint64_t>;
    913 
    914 }  // namespace unwindstack
    915