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/DwarfLocation.h>
     20 #include <unwindstack/DwarfMemory.h>
     21 #include <unwindstack/DwarfSection.h>
     22 #include <unwindstack/DwarfStructs.h>
     23 #include <unwindstack/Log.h>
     24 #include <unwindstack/Memory.h>
     25 #include <unwindstack/Regs.h>
     26 
     27 #include "DwarfCfa.h"
     28 #include "DwarfEncoding.h"
     29 #include "DwarfError.h"
     30 #include "DwarfOp.h"
     31 
     32 namespace unwindstack {
     33 
     34 DwarfSection::DwarfSection(Memory* memory) : memory_(memory), last_error_(DWARF_ERROR_NONE) {}
     35 
     36 const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) {
     37   uint64_t fde_offset;
     38   if (!GetFdeOffsetFromPc(pc, &fde_offset)) {
     39     return nullptr;
     40   }
     41   const DwarfFde* fde = GetFdeFromOffset(fde_offset);
     42   // Guaranteed pc >= pc_start, need to check pc in the fde range.
     43   if (pc < fde->pc_end) {
     44     return fde;
     45   }
     46   last_error_ = DWARF_ERROR_ILLEGAL_STATE;
     47   return nullptr;
     48 }
     49 
     50 bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory) {
     51   last_error_ = DWARF_ERROR_NONE;
     52   const DwarfFde* fde = GetFdeFromPc(pc);
     53   if (fde == nullptr || fde->cie == nullptr) {
     54     last_error_ = DWARF_ERROR_ILLEGAL_STATE;
     55     return false;
     56   }
     57 
     58   // Now get the location information for this pc.
     59   dwarf_loc_regs_t loc_regs;
     60   if (!GetCfaLocationInfo(pc, fde, &loc_regs)) {
     61     return false;
     62   }
     63 
     64   // Now eval the actual registers.
     65   return Eval(fde->cie, process_memory, loc_regs, regs);
     66 }
     67 
     68 template <typename AddressType>
     69 bool DwarfSectionImpl<AddressType>::EvalExpression(const DwarfLocation& loc, uint8_t version,
     70                                                    Memory* regular_memory, AddressType* value) {
     71   DwarfOp<AddressType> op(&memory_, regular_memory);
     72 
     73   // Need to evaluate the op data.
     74   uint64_t start = loc.values[1];
     75   uint64_t end = start + loc.values[0];
     76   if (!op.Eval(start, end, version)) {
     77     last_error_ = op.last_error();
     78     return false;
     79   }
     80   if (op.StackSize() == 0) {
     81     last_error_ = DWARF_ERROR_ILLEGAL_STATE;
     82     return false;
     83   }
     84   // We don't support an expression that evaluates to a register number.
     85   if (op.is_register()) {
     86     last_error_ = DWARF_ERROR_NOT_IMPLEMENTED;
     87     return false;
     88   }
     89   *value = op.StackAt(0);
     90   return true;
     91 }
     92 
     93 template <typename AddressType>
     94 bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_memory,
     95                                          const dwarf_loc_regs_t& loc_regs, Regs* regs) {
     96   RegsImpl<AddressType>* cur_regs = reinterpret_cast<RegsImpl<AddressType>*>(regs);
     97   if (cie->return_address_register >= cur_regs->total_regs()) {
     98     last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
     99     return false;
    100   }
    101 
    102   // Get the cfa value;
    103   auto cfa_entry = loc_regs.find(CFA_REG);
    104   if (cfa_entry == loc_regs.end()) {
    105     last_error_ = DWARF_ERROR_CFA_NOT_DEFINED;
    106     return false;
    107   }
    108 
    109   AddressType prev_pc = regs->pc();
    110   AddressType prev_cfa = regs->sp();
    111 
    112   AddressType cfa;
    113   const DwarfLocation* loc = &cfa_entry->second;
    114   // Only a few location types are valid for the cfa.
    115   switch (loc->type) {
    116     case DWARF_LOCATION_REGISTER:
    117       if (loc->values[0] >= cur_regs->total_regs()) {
    118         last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
    119         return false;
    120       }
    121       // If the stack pointer register is the CFA, and the stack
    122       // pointer register does not have any associated location
    123       // information, use the current cfa value.
    124       if (regs->sp_reg() == loc->values[0] && loc_regs.count(regs->sp_reg()) == 0) {
    125         cfa = prev_cfa;
    126       } else {
    127         cfa = (*cur_regs)[loc->values[0]];
    128       }
    129       cfa += loc->values[1];
    130       break;
    131     case DWARF_LOCATION_EXPRESSION:
    132     case DWARF_LOCATION_VAL_EXPRESSION: {
    133       AddressType value;
    134       if (!EvalExpression(*loc, cie->version, regular_memory, &value)) {
    135         return false;
    136       }
    137       if (loc->type == DWARF_LOCATION_EXPRESSION) {
    138         if (!regular_memory->Read(value, &cfa, sizeof(AddressType))) {
    139           last_error_ = DWARF_ERROR_MEMORY_INVALID;
    140           return false;
    141         }
    142       } else {
    143         cfa = value;
    144       }
    145       break;
    146     }
    147     default:
    148       last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
    149       return false;
    150   }
    151 
    152   // This code is not guaranteed to work in cases where a register location
    153   // is a double indirection to the actual value. For example, if r3 is set
    154   // to r5 + 4, and r5 is set to CFA + 4, then this won't necessarily work
    155   // because it does not guarantee that r5 is evaluated before r3.
    156   // Check that this case does not exist, and error if it does.
    157   bool return_address_undefined = false;
    158   for (const auto& entry : loc_regs) {
    159     uint16_t reg = entry.first;
    160     // Already handled the CFA register.
    161     if (reg == CFA_REG) continue;
    162 
    163     if (reg >= cur_regs->total_regs()) {
    164       // Skip this unknown register.
    165       continue;
    166     }
    167 
    168     const DwarfLocation* loc = &entry.second;
    169     switch (loc->type) {
    170       case DWARF_LOCATION_OFFSET:
    171         if (!regular_memory->Read(cfa + loc->values[0], &(*cur_regs)[reg], sizeof(AddressType))) {
    172           last_error_ = DWARF_ERROR_MEMORY_INVALID;
    173           return false;
    174         }
    175         break;
    176       case DWARF_LOCATION_VAL_OFFSET:
    177         (*cur_regs)[reg] = cfa + loc->values[0];
    178         break;
    179       case DWARF_LOCATION_REGISTER: {
    180         uint16_t cur_reg = loc->values[0];
    181         if (cur_reg >= cur_regs->total_regs()) {
    182           last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
    183           return false;
    184         }
    185         if (loc_regs.find(cur_reg) != loc_regs.end()) {
    186           // This is a double indirection, a register definition references
    187           // another register which is also defined as something other
    188           // than a register.
    189           log(0,
    190               "Invalid indirection: register %d references register %d which is "
    191               "not a plain register.\n",
    192               reg, cur_reg);
    193           last_error_ = DWARF_ERROR_ILLEGAL_STATE;
    194           return false;
    195         }
    196         (*cur_regs)[reg] = (*cur_regs)[cur_reg] + loc->values[1];
    197         break;
    198       }
    199       case DWARF_LOCATION_EXPRESSION:
    200       case DWARF_LOCATION_VAL_EXPRESSION: {
    201         AddressType value;
    202         if (!EvalExpression(*loc, cie->version, regular_memory, &value)) {
    203           return false;
    204         }
    205         if (loc->type == DWARF_LOCATION_EXPRESSION) {
    206           if (!regular_memory->Read(value, &(*cur_regs)[reg], sizeof(AddressType))) {
    207             last_error_ = DWARF_ERROR_MEMORY_INVALID;
    208             return false;
    209           }
    210         } else {
    211           (*cur_regs)[reg] = value;
    212         }
    213         break;
    214       }
    215       case DWARF_LOCATION_UNDEFINED:
    216         if (reg == cie->return_address_register) {
    217           return_address_undefined = true;
    218         }
    219       default:
    220         break;
    221     }
    222   }
    223 
    224   // Find the return address location.
    225   if (return_address_undefined) {
    226     cur_regs->set_pc(0);
    227   } else {
    228     cur_regs->set_pc((*cur_regs)[cie->return_address_register]);
    229   }
    230   cur_regs->set_sp(cfa);
    231   // Stop if the cfa and pc are the same.
    232   return prev_cfa != cfa || prev_pc != cur_regs->pc();
    233 }
    234 
    235 template <typename AddressType>
    236 const DwarfCie* DwarfSectionImpl<AddressType>::GetCie(uint64_t offset) {
    237   auto cie_entry = cie_entries_.find(offset);
    238   if (cie_entry != cie_entries_.end()) {
    239     return &cie_entry->second;
    240   }
    241   DwarfCie* cie = &cie_entries_[offset];
    242   memory_.set_cur_offset(offset);
    243   if (!FillInCie(cie)) {
    244     // Erase the cached entry.
    245     cie_entries_.erase(offset);
    246     return nullptr;
    247   }
    248   return cie;
    249 }
    250 
    251 template <typename AddressType>
    252 bool DwarfSectionImpl<AddressType>::FillInCie(DwarfCie* cie) {
    253   uint32_t length32;
    254   if (!memory_.ReadBytes(&length32, sizeof(length32))) {
    255     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    256     return false;
    257   }
    258   // Set the default for the lsda encoding.
    259   cie->lsda_encoding = DW_EH_PE_omit;
    260 
    261   if (length32 == static_cast<uint32_t>(-1)) {
    262     // 64 bit Cie
    263     uint64_t length64;
    264     if (!memory_.ReadBytes(&length64, sizeof(length64))) {
    265       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    266       return false;
    267     }
    268 
    269     cie->cfa_instructions_end = memory_.cur_offset() + length64;
    270     cie->fde_address_encoding = DW_EH_PE_sdata8;
    271 
    272     uint64_t cie_id;
    273     if (!memory_.ReadBytes(&cie_id, sizeof(cie_id))) {
    274       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    275       return false;
    276     }
    277     if (!IsCie64(cie_id)) {
    278       // This is not a Cie, something has gone horribly wrong.
    279       last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
    280       return false;
    281     }
    282   } else {
    283     // 32 bit Cie
    284     cie->cfa_instructions_end = memory_.cur_offset() + length32;
    285     cie->fde_address_encoding = DW_EH_PE_sdata4;
    286 
    287     uint32_t cie_id;
    288     if (!memory_.ReadBytes(&cie_id, sizeof(cie_id))) {
    289       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    290       return false;
    291     }
    292     if (!IsCie32(cie_id)) {
    293       // This is not a Cie, something has gone horribly wrong.
    294       last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
    295       return false;
    296     }
    297   }
    298 
    299   if (!memory_.ReadBytes(&cie->version, sizeof(cie->version))) {
    300     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    301     return false;
    302   }
    303 
    304   if (cie->version != 1 && cie->version != 3 && cie->version != 4) {
    305     // Unrecognized version.
    306     last_error_ = DWARF_ERROR_UNSUPPORTED_VERSION;
    307     return false;
    308   }
    309 
    310   // Read the augmentation string.
    311   char aug_value;
    312   do {
    313     if (!memory_.ReadBytes(&aug_value, 1)) {
    314       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    315       return false;
    316     }
    317     cie->augmentation_string.push_back(aug_value);
    318   } while (aug_value != '\0');
    319 
    320   if (cie->version == 4) {
    321     // Skip the Address Size field since we only use it for validation.
    322     memory_.set_cur_offset(memory_.cur_offset() + 1);
    323 
    324     // Segment Size
    325     if (!memory_.ReadBytes(&cie->segment_size, 1)) {
    326       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    327       return false;
    328     }
    329   }
    330 
    331   // Code Alignment Factor
    332   if (!memory_.ReadULEB128(&cie->code_alignment_factor)) {
    333     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    334     return false;
    335   }
    336 
    337   // Data Alignment Factor
    338   if (!memory_.ReadSLEB128(&cie->data_alignment_factor)) {
    339     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    340     return false;
    341   }
    342 
    343   if (cie->version == 1) {
    344     // Return Address is a single byte.
    345     uint8_t return_address_register;
    346     if (!memory_.ReadBytes(&return_address_register, 1)) {
    347       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    348       return false;
    349     }
    350     cie->return_address_register = return_address_register;
    351   } else if (!memory_.ReadULEB128(&cie->return_address_register)) {
    352     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    353     return false;
    354   }
    355 
    356   if (cie->augmentation_string[0] != 'z') {
    357     cie->cfa_instructions_offset = memory_.cur_offset();
    358     return true;
    359   }
    360 
    361   uint64_t aug_length;
    362   if (!memory_.ReadULEB128(&aug_length)) {
    363     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    364     return false;
    365   }
    366   cie->cfa_instructions_offset = memory_.cur_offset() + aug_length;
    367 
    368   for (size_t i = 1; i < cie->augmentation_string.size(); i++) {
    369     switch (cie->augmentation_string[i]) {
    370       case 'L':
    371         if (!memory_.ReadBytes(&cie->lsda_encoding, 1)) {
    372           last_error_ = DWARF_ERROR_MEMORY_INVALID;
    373           return false;
    374         }
    375         break;
    376       case 'P': {
    377         uint8_t encoding;
    378         if (!memory_.ReadBytes(&encoding, 1)) {
    379           last_error_ = DWARF_ERROR_MEMORY_INVALID;
    380           return false;
    381         }
    382         if (!memory_.ReadEncodedValue<AddressType>(encoding, &cie->personality_handler)) {
    383           last_error_ = DWARF_ERROR_MEMORY_INVALID;
    384           return false;
    385         }
    386       } break;
    387       case 'R':
    388         if (!memory_.ReadBytes(&cie->fde_address_encoding, 1)) {
    389           last_error_ = DWARF_ERROR_MEMORY_INVALID;
    390           return false;
    391         }
    392         break;
    393     }
    394   }
    395   return true;
    396 }
    397 
    398 template <typename AddressType>
    399 const DwarfFde* DwarfSectionImpl<AddressType>::GetFdeFromOffset(uint64_t offset) {
    400   auto fde_entry = fde_entries_.find(offset);
    401   if (fde_entry != fde_entries_.end()) {
    402     return &fde_entry->second;
    403   }
    404   DwarfFde* fde = &fde_entries_[offset];
    405   memory_.set_cur_offset(offset);
    406   if (!FillInFde(fde)) {
    407     fde_entries_.erase(offset);
    408     return nullptr;
    409   }
    410   return fde;
    411 }
    412 
    413 template <typename AddressType>
    414 bool DwarfSectionImpl<AddressType>::FillInFde(DwarfFde* fde) {
    415   uint32_t length32;
    416   if (!memory_.ReadBytes(&length32, sizeof(length32))) {
    417     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    418     return false;
    419   }
    420 
    421   if (length32 == static_cast<uint32_t>(-1)) {
    422     // 64 bit Fde.
    423     uint64_t length64;
    424     if (!memory_.ReadBytes(&length64, sizeof(length64))) {
    425       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    426       return false;
    427     }
    428     fde->cfa_instructions_end = memory_.cur_offset() + length64;
    429 
    430     uint64_t value64;
    431     if (!memory_.ReadBytes(&value64, sizeof(value64))) {
    432       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    433       return false;
    434     }
    435     if (IsCie64(value64)) {
    436       // This is a Cie, this means something has gone wrong.
    437       last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
    438       return false;
    439     }
    440 
    441     // Get the Cie pointer, which is necessary to properly read the rest of
    442     // of the Fde information.
    443     fde->cie_offset = GetCieOffsetFromFde64(value64);
    444   } else {
    445     // 32 bit Fde.
    446     fde->cfa_instructions_end = memory_.cur_offset() + length32;
    447 
    448     uint32_t value32;
    449     if (!memory_.ReadBytes(&value32, sizeof(value32))) {
    450       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    451       return false;
    452     }
    453     if (IsCie32(value32)) {
    454       // This is a Cie, this means something has gone wrong.
    455       last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
    456       return false;
    457     }
    458 
    459     // Get the Cie pointer, which is necessary to properly read the rest of
    460     // of the Fde information.
    461     fde->cie_offset = GetCieOffsetFromFde32(value32);
    462   }
    463   uint64_t cur_offset = memory_.cur_offset();
    464 
    465   const DwarfCie* cie = GetCie(fde->cie_offset);
    466   if (cie == nullptr) {
    467     return false;
    468   }
    469   fde->cie = cie;
    470 
    471   if (cie->segment_size != 0) {
    472     // Skip over the segment selector for now.
    473     cur_offset += cie->segment_size;
    474   }
    475   memory_.set_cur_offset(cur_offset);
    476 
    477   if (!memory_.ReadEncodedValue<AddressType>(cie->fde_address_encoding & 0xf, &fde->pc_start)) {
    478     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    479     return false;
    480   }
    481   fde->pc_start = AdjustPcFromFde(fde->pc_start);
    482 
    483   if (!memory_.ReadEncodedValue<AddressType>(cie->fde_address_encoding & 0xf, &fde->pc_end)) {
    484     last_error_ = DWARF_ERROR_MEMORY_INVALID;
    485     return false;
    486   }
    487   fde->pc_end += fde->pc_start;
    488   if (cie->augmentation_string.size() > 0 && cie->augmentation_string[0] == 'z') {
    489     // Augmentation Size
    490     uint64_t aug_length;
    491     if (!memory_.ReadULEB128(&aug_length)) {
    492       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    493       return false;
    494     }
    495     uint64_t cur_offset = memory_.cur_offset();
    496 
    497     if (!memory_.ReadEncodedValue<AddressType>(cie->lsda_encoding, &fde->lsda_address)) {
    498       last_error_ = DWARF_ERROR_MEMORY_INVALID;
    499       return false;
    500     }
    501 
    502     // Set our position to after all of the augmentation data.
    503     memory_.set_cur_offset(cur_offset + aug_length);
    504   }
    505   fde->cfa_instructions_offset = memory_.cur_offset();
    506 
    507   return true;
    508 }
    509 
    510 template <typename AddressType>
    511 bool DwarfSectionImpl<AddressType>::GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde,
    512                                                        dwarf_loc_regs_t* loc_regs) {
    513   DwarfCfa<AddressType> cfa(&memory_, fde);
    514 
    515   // Look for the cached copy of the cie data.
    516   auto reg_entry = cie_loc_regs_.find(fde->cie_offset);
    517   if (reg_entry == cie_loc_regs_.end()) {
    518     if (!cfa.GetLocationInfo(pc, fde->cie->cfa_instructions_offset, fde->cie->cfa_instructions_end,
    519                              loc_regs)) {
    520       last_error_ = cfa.last_error();
    521       return false;
    522     }
    523     cie_loc_regs_[fde->cie_offset] = *loc_regs;
    524   }
    525   cfa.set_cie_loc_regs(&cie_loc_regs_[fde->cie_offset]);
    526   if (!cfa.GetLocationInfo(pc, fde->cfa_instructions_offset, fde->cfa_instructions_end, loc_regs)) {
    527     last_error_ = cfa.last_error();
    528     return false;
    529   }
    530   return true;
    531 }
    532 
    533 template <typename AddressType>
    534 bool DwarfSectionImpl<AddressType>::Log(uint8_t indent, uint64_t pc, uint64_t load_bias,
    535                                         const DwarfFde* fde) {
    536   DwarfCfa<AddressType> cfa(&memory_, fde);
    537 
    538   // Always print the cie information.
    539   const DwarfCie* cie = fde->cie;
    540   if (!cfa.Log(indent, pc, load_bias, cie->cfa_instructions_offset, cie->cfa_instructions_end)) {
    541     last_error_ = cfa.last_error();
    542     return false;
    543   }
    544   if (!cfa.Log(indent, pc, load_bias, fde->cfa_instructions_offset, fde->cfa_instructions_end)) {
    545     last_error_ = cfa.last_error();
    546     return false;
    547   }
    548   return true;
    549 }
    550 
    551 // Explicitly instantiate DwarfSectionImpl
    552 template class DwarfSectionImpl<uint32_t>;
    553 template class DwarfSectionImpl<uint64_t>;
    554 
    555 }  // namespace unwindstack
    556