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