21
21
#include < unwindstack/DwarfMemory.h>
22
22
#include < unwindstack/DwarfSection.h>
23
23
#include < unwindstack/DwarfStructs.h>
24
+ #include < unwindstack/Elf.h>
24
25
#include < unwindstack/Log.h>
25
26
#include < unwindstack/Memory.h>
26
27
#include < unwindstack/Regs.h>
@@ -49,7 +50,7 @@ bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* f
49
50
50
51
// Now get the location information for this pc.
51
52
dwarf_loc_regs_t loc_regs;
52
- if (!GetCfaLocationInfo (pc, fde, &loc_regs)) {
53
+ if (!GetCfaLocationInfo (pc, fde, &loc_regs, regs-> Arch () )) {
53
54
return false ;
54
55
}
55
56
loc_regs.cie = fde->cie ;
@@ -464,6 +465,13 @@ bool DwarfSectionImpl<AddressType>::EvalRegister(const DwarfLocation* loc, uint3
464
465
eval_info->return_address_undefined = true ;
465
466
}
466
467
break ;
468
+ case DWARF_LOCATION_PSEUDO_REGISTER: {
469
+ if (!eval_info->regs_info .regs ->SetPseudoRegister (reg, loc->values [0 ])) {
470
+ last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
471
+ return false ;
472
+ }
473
+ break ;
474
+ }
467
475
default :
468
476
break ;
469
477
}
@@ -491,6 +499,10 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
491
499
// Always set the dex pc to zero when evaluating.
492
500
cur_regs->set_dex_pc (0 );
493
501
502
+ // Reset necessary pseudo registers before evaluation.
503
+ // This is needed for ARM64, for example.
504
+ regs->ResetPseudoRegisters ();
505
+
494
506
EvalInfo<AddressType> eval_info{.loc_regs = &loc_regs,
495
507
.cie = cie,
496
508
.regular_memory = regular_memory,
@@ -527,8 +539,10 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
527
539
528
540
AddressType* reg_ptr;
529
541
if (reg >= cur_regs->total_regs ()) {
530
- // Skip this unknown register.
531
- continue ;
542
+ if (entry.second .type != DWARF_LOCATION_PSEUDO_REGISTER) {
543
+ // Skip this unknown register.
544
+ continue ;
545
+ }
532
546
}
533
547
534
548
reg_ptr = eval_info.regs_info .Save (reg);
@@ -554,8 +568,8 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
554
568
555
569
template <typename AddressType>
556
570
bool DwarfSectionImpl<AddressType>::GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde,
557
- dwarf_loc_regs_t * loc_regs) {
558
- DwarfCfa<AddressType> cfa (&memory_, fde);
571
+ dwarf_loc_regs_t * loc_regs, ArchEnum arch ) {
572
+ DwarfCfa<AddressType> cfa (&memory_, fde, arch );
559
573
560
574
// Look for the cached copy of the cie data.
561
575
auto reg_entry = cie_loc_regs_.find (fde->cie_offset );
@@ -576,8 +590,9 @@ bool DwarfSectionImpl<AddressType>::GetCfaLocationInfo(uint64_t pc, const DwarfF
576
590
}
577
591
578
592
template <typename AddressType>
579
- bool DwarfSectionImpl<AddressType>::Log(uint8_t indent, uint64_t pc, const DwarfFde* fde) {
580
- DwarfCfa<AddressType> cfa (&memory_, fde);
593
+ bool DwarfSectionImpl<AddressType>::Log(uint8_t indent, uint64_t pc, const DwarfFde* fde,
594
+ ArchEnum arch) {
595
+ DwarfCfa<AddressType> cfa (&memory_, fde, arch);
581
596
582
597
// Always print the cie information.
583
598
const DwarfCie* cie = fde->cie ;
0 commit comments