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