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