diff options
36 files changed, 417 insertions, 254 deletions
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp index 87172836b..08dcf7724 100644 --- a/libunwindstack/Android.bp +++ b/libunwindstack/Android.bp @@ -188,6 +188,7 @@ cc_test { data: [ "tests/files/elf32.xz", "tests/files/elf64.xz", + "tests/files/offline/art_quick_osr_stub_arm/*", "tests/files/offline/bad_eh_frame_hdr_arm64/*", "tests/files/offline/debug_frame_first_x86/*", "tests/files/offline/eh_frame_hdr_begin_x86_64/*", diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp index ddbc12ef4..5586e725d 100644 --- a/libunwindstack/DwarfSection.cpp +++ b/libunwindstack/DwarfSection.cpp @@ -190,8 +190,6 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me // Always set the dex pc to zero when evaluating. cur_regs->set_dex_pc(0); - AddressType prev_cfa = regs->sp(); - EvalInfo<AddressType> eval_info{.loc_regs = &loc_regs, .cie = cie, .regular_memory = regular_memory, @@ -204,14 +202,7 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; return false; } - // If the stack pointer register is the CFA, and the stack - // pointer register does not have any associated location - // information, use the current cfa value. - if (regs->sp_reg() == loc->values[0] && loc_regs.count(regs->sp_reg()) == 0) { - eval_info.cfa = prev_cfa; - } else { - eval_info.cfa = (*cur_regs)[loc->values[0]]; - } + eval_info.cfa = (*cur_regs)[loc->values[0]]; eval_info.cfa += loc->values[1]; break; case DWARF_LOCATION_VAL_EXPRESSION: { diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp index a5afc7e5d..f93baeb27 100644 --- a/libunwindstack/ElfInterfaceArm.cpp +++ b/libunwindstack/ElfInterfaceArm.cpp @@ -127,13 +127,9 @@ bool ElfInterfaceArm::StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Mem if (arm.ExtractEntryData(entry_offset) && arm.Eval()) { // If the pc was not set, then use the LR registers for the PC. if (!arm.pc_set()) { - regs_arm->set_pc((*regs_arm)[ARM_REG_LR]); - (*regs_arm)[ARM_REG_PC] = regs_arm->pc(); - } else { - regs_arm->set_pc((*regs_arm)[ARM_REG_PC]); + (*regs_arm)[ARM_REG_PC] = (*regs_arm)[ARM_REG_LR]; } - regs_arm->set_sp(arm.cfa()); - (*regs_arm)[ARM_REG_SP] = regs_arm->sp(); + (*regs_arm)[ARM_REG_SP] = arm.cfa(); return_value = true; // If the pc was set to zero, consider this the final frame. diff --git a/libunwindstack/RegsArm.cpp b/libunwindstack/RegsArm.cpp index 5502ce1fe..e2a9cb01f 100644 --- a/libunwindstack/RegsArm.cpp +++ b/libunwindstack/RegsArm.cpp @@ -28,13 +28,28 @@ namespace unwindstack { -RegsArm::RegsArm() - : RegsImpl<uint32_t>(ARM_REG_LAST, ARM_REG_SP, Location(LOCATION_REGISTER, ARM_REG_LR)) {} +RegsArm::RegsArm() : RegsImpl<uint32_t>(ARM_REG_LAST, Location(LOCATION_REGISTER, ARM_REG_LR)) {} ArchEnum RegsArm::Arch() { return ARCH_ARM; } +uint64_t RegsArm::pc() { + return regs_[ARM_REG_PC]; +} + +uint64_t RegsArm::sp() { + return regs_[ARM_REG_SP]; +} + +void RegsArm::set_pc(uint64_t pc) { + regs_[ARM_REG_PC] = pc; +} + +void RegsArm::set_sp(uint64_t sp) { + regs_[ARM_REG_SP] = sp; +} + uint64_t RegsArm::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { uint64_t load_bias = elf->GetLoadBias(); if (rel_pc < load_bias) { @@ -56,17 +71,13 @@ uint64_t RegsArm::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { return 4; } -void RegsArm::SetFromRaw() { - set_pc(regs_[ARM_REG_PC]); - set_sp(regs_[ARM_REG_SP]); -} - bool RegsArm::SetPcFromReturnAddress(Memory*) { - if (pc() == regs_[ARM_REG_LR]) { + uint32_t lr = regs_[ARM_REG_LR]; + if (regs_[ARM_REG_PC] == lr) { return false; } - set_pc(regs_[ARM_REG_LR]); + regs_[ARM_REG_PC] = lr; return true; } @@ -94,7 +105,6 @@ Regs* RegsArm::Read(void* remote_data) { RegsArm* regs = new RegsArm(); memcpy(regs->RawData(), &user->regs[0], ARM_REG_LAST * sizeof(uint32_t)); - regs->SetFromRaw(); return regs; } @@ -103,7 +113,6 @@ Regs* RegsArm::CreateFromUcontext(void* ucontext) { RegsArm* regs = new RegsArm(); memcpy(regs->RawData(), &arm_ucontext->uc_mcontext.regs[0], ARM_REG_LAST * sizeof(uint32_t)); - regs->SetFromRaw(); return regs; } @@ -118,6 +127,7 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem uint64_t offset = 0; if (data == 0xe3a07077 || data == 0xef900077 || data == 0xdf002777) { + uint64_t sp = regs_[ARM_REG_SP]; // non-RT sigreturn call. // __restore: // @@ -131,17 +141,18 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem // Form 3 (thumb): // 0x77 0x27 movs r7, #77 // 0x00 0xdf svc 0 - if (!process_memory->ReadFully(sp(), &data, sizeof(data))) { + if (!process_memory->ReadFully(sp, &data, sizeof(data))) { return false; } if (data == 0x5ac3c35a) { // SP + uc_mcontext offset + r0 offset. - offset = sp() + 0x14 + 0xc; + offset = sp + 0x14 + 0xc; } else { // SP + r0 offset - offset = sp() + 0xc; + offset = sp + 0xc; } } else if (data == 0xe3a070ad || data == 0xef9000ad || data == 0xdf0027ad) { + uint64_t sp = regs_[ARM_REG_SP]; // RT sigreturn call. // __restore_rt: // @@ -155,15 +166,15 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem // Form 3 (thumb): // 0xad 0x27 movs r7, #ad // 0x00 0xdf svc 0 - if (!process_memory->ReadFully(sp(), &data, sizeof(data))) { + if (!process_memory->ReadFully(sp, &data, sizeof(data))) { return false; } - if (data == sp() + 8) { + if (data == sp + 8) { // SP + 8 + sizeof(siginfo_t) + uc_mcontext_offset + r0 offset - offset = sp() + 8 + 0x80 + 0x14 + 0xc; + offset = sp + 8 + 0x80 + 0x14 + 0xc; } else { // SP + sizeof(siginfo_t) + uc_mcontext_offset + r0 offset - offset = sp() + 0x80 + 0x14 + 0xc; + offset = sp + 0x80 + 0x14 + 0xc; } } if (offset == 0) { @@ -173,7 +184,6 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem if (!process_memory->ReadFully(offset, regs_.data(), sizeof(uint32_t) * ARM_REG_LAST)) { return false; } - SetFromRaw(); return true; } diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp index cc6f5ce87..fe24c802c 100644 --- a/libunwindstack/RegsArm64.cpp +++ b/libunwindstack/RegsArm64.cpp @@ -29,12 +29,28 @@ namespace unwindstack { RegsArm64::RegsArm64() - : RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {} + : RegsImpl<uint64_t>(ARM64_REG_LAST, Location(LOCATION_REGISTER, ARM64_REG_LR)) {} ArchEnum RegsArm64::Arch() { return ARCH_ARM64; } +uint64_t RegsArm64::pc() { + return regs_[ARM64_REG_PC]; +} + +uint64_t RegsArm64::sp() { + return regs_[ARM64_REG_SP]; +} + +void RegsArm64::set_pc(uint64_t pc) { + regs_[ARM64_REG_PC] = pc; +} + +void RegsArm64::set_sp(uint64_t sp) { + regs_[ARM64_REG_SP] = sp; +} + uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { if (!elf->valid() || rel_pc < 4) { return 0; @@ -42,17 +58,13 @@ uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { return 4; } -void RegsArm64::SetFromRaw() { - set_pc(regs_[ARM64_REG_PC]); - set_sp(regs_[ARM64_REG_SP]); -} - bool RegsArm64::SetPcFromReturnAddress(Memory*) { - if (pc() == regs_[ARM64_REG_LR]) { + uint64_t lr = regs_[ARM64_REG_LR]; + if (regs_[ARM64_REG_PC] == lr) { return false; } - set_pc(regs_[ARM64_REG_LR]); + regs_[ARM64_REG_PC] = lr; return true; } @@ -100,7 +112,6 @@ Regs* RegsArm64::Read(void* remote_data) { uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData()); reg_data[ARM64_REG_PC] = user->pc; reg_data[ARM64_REG_SP] = user->sp; - regs->SetFromRaw(); return regs; } @@ -109,7 +120,6 @@ Regs* RegsArm64::CreateFromUcontext(void* ucontext) { RegsArm64* regs = new RegsArm64(); memcpy(regs->RawData(), &arm64_ucontext->uc_mcontext.regs[0], ARM64_REG_LAST * sizeof(uint64_t)); - regs->SetFromRaw(); return regs; } @@ -131,12 +141,10 @@ bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_m } // SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset. - if (!process_memory->ReadFully(sp() + 0x80 + 0xb0 + 0x08, regs_.data(), + if (!process_memory->ReadFully(regs_[ARM64_REG_SP] + 0x80 + 0xb0 + 0x08, regs_.data(), sizeof(uint64_t) * ARM64_REG_LAST)) { return false; } - - SetFromRaw(); return true; } diff --git a/libunwindstack/RegsMips.cpp b/libunwindstack/RegsMips.cpp index 5d20bef4a..0b10e2169 100644 --- a/libunwindstack/RegsMips.cpp +++ b/libunwindstack/RegsMips.cpp @@ -29,12 +29,28 @@ namespace unwindstack { RegsMips::RegsMips() - : RegsImpl<uint32_t>(MIPS_REG_LAST, MIPS_REG_SP, Location(LOCATION_REGISTER, MIPS_REG_RA)) {} + : RegsImpl<uint32_t>(MIPS_REG_LAST, Location(LOCATION_REGISTER, MIPS_REG_RA)) {} ArchEnum RegsMips::Arch() { return ARCH_MIPS; } +uint64_t RegsMips::pc() { + return regs_[MIPS_REG_PC]; +} + +uint64_t RegsMips::sp() { + return regs_[MIPS_REG_SP]; +} + +void RegsMips::set_pc(uint64_t pc) { + regs_[MIPS_REG_PC] = static_cast<uint32_t>(pc); +} + +void RegsMips::set_sp(uint64_t sp) { + regs_[MIPS_REG_SP] = static_cast<uint32_t>(sp); +} + uint64_t RegsMips::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { if (!elf->valid() || rel_pc < 8) { return 0; @@ -43,17 +59,13 @@ uint64_t RegsMips::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { return 8; } -void RegsMips::SetFromRaw() { - set_pc(regs_[MIPS_REG_PC]); - set_sp(regs_[MIPS_REG_SP]); -} - bool RegsMips::SetPcFromReturnAddress(Memory*) { - if (pc() == regs_[MIPS_REG_RA]) { + uint32_t ra = regs_[MIPS_REG_RA]; + if (regs_[MIPS_REG_PC] == ra) { return false; } - set_pc(regs_[MIPS_REG_RA]); + regs_[MIPS_REG_PC] = ra; return true; } @@ -101,7 +113,6 @@ Regs* RegsMips::Read(void* remote_data) { memcpy(regs->RawData(), &user->regs[MIPS32_EF_R0], (MIPS_REG_R31 + 1) * sizeof(uint32_t)); reg_data[MIPS_REG_PC] = user->regs[MIPS32_EF_CP0_EPC]; - regs->SetFromRaw(); return regs; } @@ -114,7 +125,6 @@ Regs* RegsMips::CreateFromUcontext(void* ucontext) { (*regs)[MIPS_REG_R0 + i] = mips_ucontext->uc_mcontext.sc_regs[i]; } (*regs)[MIPS_REG_PC] = mips_ucontext->uc_mcontext.sc_pc; - regs->SetFromRaw(); return regs; } @@ -149,7 +159,7 @@ bool RegsMips::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_me // read sc_pc and sc_regs[32] from stack uint64_t values[MIPS_REG_LAST]; - if (!process_memory->Read(sp() + offset, values, sizeof(values))) { + if (!process_memory->Read(regs_[MIPS_REG_SP] + offset, values, sizeof(values))) { return false; } @@ -160,8 +170,6 @@ bool RegsMips::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_me for (int i = 0; i < 32; i++) { regs_[MIPS_REG_R0 + i] = values[1 + i]; } - - SetFromRaw(); return true; } diff --git a/libunwindstack/RegsMips64.cpp b/libunwindstack/RegsMips64.cpp index 4a03538e2..8848e3bab 100644 --- a/libunwindstack/RegsMips64.cpp +++ b/libunwindstack/RegsMips64.cpp @@ -29,13 +29,28 @@ namespace unwindstack { RegsMips64::RegsMips64() - : RegsImpl<uint64_t>(MIPS64_REG_LAST, MIPS64_REG_SP, - Location(LOCATION_REGISTER, MIPS64_REG_RA)) {} + : RegsImpl<uint64_t>(MIPS64_REG_LAST, Location(LOCATION_REGISTER, MIPS64_REG_RA)) {} ArchEnum RegsMips64::Arch() { return ARCH_MIPS64; } +uint64_t RegsMips64::pc() { + return regs_[MIPS64_REG_PC]; +} + +uint64_t RegsMips64::sp() { + return regs_[MIPS64_REG_SP]; +} + +void RegsMips64::set_pc(uint64_t pc) { + regs_[MIPS64_REG_PC] = pc; +} + +void RegsMips64::set_sp(uint64_t sp) { + regs_[MIPS64_REG_SP] = sp; +} + uint64_t RegsMips64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { if (!elf->valid() || rel_pc < 8) { return 0; @@ -44,17 +59,13 @@ uint64_t RegsMips64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { return 8; } -void RegsMips64::SetFromRaw() { - set_pc(regs_[MIPS64_REG_PC]); - set_sp(regs_[MIPS64_REG_SP]); -} - bool RegsMips64::SetPcFromReturnAddress(Memory*) { - if (pc() == regs_[MIPS64_REG_RA]) { + uint64_t ra = regs_[MIPS64_REG_RA]; + if (regs_[MIPS64_REG_PC] == ra) { return false; } - set_pc(regs_[MIPS64_REG_RA]); + regs_[MIPS64_REG_PC] = ra; return true; } @@ -102,7 +113,6 @@ Regs* RegsMips64::Read(void* remote_data) { memcpy(regs->RawData(), &user->regs[MIPS64_EF_R0], (MIPS64_REG_R31 + 1) * sizeof(uint64_t)); reg_data[MIPS64_REG_PC] = user->regs[MIPS64_EF_CP0_EPC]; - regs->SetFromRaw(); return regs; } @@ -113,7 +123,6 @@ Regs* RegsMips64::CreateFromUcontext(void* ucontext) { // Copy 64 bit sc_regs over to 64 bit regs memcpy(regs->RawData(), &mips64_ucontext->uc_mcontext.sc_regs[0], 32 * sizeof(uint64_t)); (*regs)[MIPS64_REG_PC] = mips64_ucontext->uc_mcontext.sc_pc; - regs->SetFromRaw(); return regs; } @@ -137,19 +146,17 @@ bool RegsMips64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_ // vdso_rt_sigreturn => read rt_sigframe // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset // read 64 bit sc_regs[32] from stack into 64 bit regs_ - if (!process_memory->Read(sp() + 24 + 128 + 40, regs_.data(), + uint64_t sp = regs_[MIPS64_REG_SP]; + if (!process_memory->Read(sp + 24 + 128 + 40, regs_.data(), sizeof(uint64_t) * (MIPS64_REG_LAST - 1))) { return false; } // offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset + sc_pc offset // read 64 bit sc_pc from stack into 64 bit regs_[MIPS64_REG_PC] - if (!process_memory->Read(sp() + 24 + 128 + 40 + 576, ®s_[MIPS64_REG_PC], - sizeof(uint64_t))) { + if (!process_memory->Read(sp + 24 + 128 + 40 + 576, ®s_[MIPS64_REG_PC], sizeof(uint64_t))) { return false; } - - SetFromRaw(); return true; } diff --git a/libunwindstack/RegsX86.cpp b/libunwindstack/RegsX86.cpp index 573cb2382..bb95a13f2 100644 --- a/libunwindstack/RegsX86.cpp +++ b/libunwindstack/RegsX86.cpp @@ -28,13 +28,28 @@ namespace unwindstack { -RegsX86::RegsX86() - : RegsImpl<uint32_t>(X86_REG_LAST, X86_REG_SP, Location(LOCATION_SP_OFFSET, -4)) {} +RegsX86::RegsX86() : RegsImpl<uint32_t>(X86_REG_LAST, Location(LOCATION_SP_OFFSET, -4)) {} ArchEnum RegsX86::Arch() { return ARCH_X86; } +uint64_t RegsX86::pc() { + return regs_[X86_REG_PC]; +} + +uint64_t RegsX86::sp() { + return regs_[X86_REG_SP]; +} + +void RegsX86::set_pc(uint64_t pc) { + regs_[X86_REG_PC] = static_cast<uint32_t>(pc); +} + +void RegsX86::set_sp(uint64_t sp) { + regs_[X86_REG_SP] = static_cast<uint32_t>(sp); +} + uint64_t RegsX86::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { if (!elf->valid() || rel_pc == 0) { return 0; @@ -42,19 +57,15 @@ uint64_t RegsX86::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { return 1; } -void RegsX86::SetFromRaw() { - set_pc(regs_[X86_REG_PC]); - set_sp(regs_[X86_REG_SP]); -} - bool RegsX86::SetPcFromReturnAddress(Memory* process_memory) { // Attempt to get the return address from the top of the stack. uint32_t new_pc; - if (!process_memory->ReadFully(sp_, &new_pc, sizeof(new_pc)) || new_pc == pc()) { + if (!process_memory->ReadFully(regs_[X86_REG_SP], &new_pc, sizeof(new_pc)) || + new_pc == regs_[X86_REG_PC]) { return false; } - set_pc(new_pc); + regs_[X86_REG_PC] = new_pc; return true; } @@ -84,7 +95,6 @@ Regs* RegsX86::Read(void* user_data) { (*regs)[X86_REG_ESP] = user->esp; (*regs)[X86_REG_EIP] = user->eip; - regs->SetFromRaw(); return regs; } @@ -99,7 +109,6 @@ void RegsX86::SetFromUcontext(x86_ucontext_t* ucontext) { regs_[X86_REG_ECX] = ucontext->uc_mcontext.ecx; regs_[X86_REG_EAX] = ucontext->uc_mcontext.eax; regs_[X86_REG_EIP] = ucontext->uc_mcontext.eip; - SetFromRaw(); } Regs* RegsX86::CreateFromUcontext(void* ucontext) { @@ -131,7 +140,7 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem // int signum // struct sigcontext (same format as mcontext) struct x86_mcontext_t context; - if (!process_memory->ReadFully(sp() + 4, &context, sizeof(context))) { + if (!process_memory->ReadFully(regs_[X86_REG_SP] + 4, &context, sizeof(context))) { return false; } regs_[X86_REG_EBP] = context.ebp; @@ -141,7 +150,6 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem regs_[X86_REG_ECX] = context.ecx; regs_[X86_REG_EAX] = context.eax; regs_[X86_REG_EIP] = context.eip; - SetFromRaw(); return true; } else if ((data & 0x00ffffffffffffffULL) == 0x0080cd000000adb8ULL) { // With SA_SIGINFO set, the return sequence is: @@ -157,7 +165,7 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem // Get the location of the sigcontext data. uint32_t ptr; - if (!process_memory->ReadFully(sp() + 8, &ptr, sizeof(ptr))) { + if (!process_memory->ReadFully(regs_[X86_REG_SP] + 8, &ptr, sizeof(ptr))) { return false; } // Only read the portion of the data structure we care about. diff --git a/libunwindstack/RegsX86_64.cpp b/libunwindstack/RegsX86_64.cpp index 3175a90c2..e57e2bca1 100644 --- a/libunwindstack/RegsX86_64.cpp +++ b/libunwindstack/RegsX86_64.cpp @@ -28,13 +28,28 @@ namespace unwindstack { -RegsX86_64::RegsX86_64() - : RegsImpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP, Location(LOCATION_SP_OFFSET, -8)) {} +RegsX86_64::RegsX86_64() : RegsImpl<uint64_t>(X86_64_REG_LAST, Location(LOCATION_SP_OFFSET, -8)) {} ArchEnum RegsX86_64::Arch() { return ARCH_X86_64; } +uint64_t RegsX86_64::pc() { + return regs_[X86_64_REG_PC]; +} + +uint64_t RegsX86_64::sp() { + return regs_[X86_64_REG_SP]; +} + +void RegsX86_64::set_pc(uint64_t pc) { + regs_[X86_64_REG_PC] = pc; +} + +void RegsX86_64::set_sp(uint64_t sp) { + regs_[X86_64_REG_SP] = sp; +} + uint64_t RegsX86_64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { if (!elf->valid() || rel_pc == 0) { return 0; @@ -42,19 +57,15 @@ uint64_t RegsX86_64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) { return 1; } -void RegsX86_64::SetFromRaw() { - set_pc(regs_[X86_64_REG_PC]); - set_sp(regs_[X86_64_REG_SP]); -} - bool RegsX86_64::SetPcFromReturnAddress(Memory* process_memory) { // Attempt to get the return address from the top of the stack. uint64_t new_pc; - if (!process_memory->ReadFully(sp_, &new_pc, sizeof(new_pc)) || new_pc == pc()) { + if (!process_memory->ReadFully(regs_[X86_64_REG_SP], &new_pc, sizeof(new_pc)) || + new_pc == regs_[X86_64_REG_PC]) { return false; } - set_pc(new_pc); + regs_[X86_64_REG_PC] = new_pc; return true; } @@ -100,7 +111,6 @@ Regs* RegsX86_64::Read(void* remote_data) { (*regs)[X86_64_REG_RSP] = user->rsp; (*regs)[X86_64_REG_RIP] = user->rip; - regs->SetFromRaw(); return regs; } @@ -118,8 +128,6 @@ void RegsX86_64::SetFromUcontext(x86_64_ucontext_t* ucontext) { regs_[X86_64_REG_RCX] = ucontext->uc_mcontext.rcx; regs_[X86_64_REG_RSP] = ucontext->uc_mcontext.rsp; regs_[X86_64_REG_RIP] = ucontext->uc_mcontext.rip; - - SetFromRaw(); } Regs* RegsX86_64::CreateFromUcontext(void* ucontext) { @@ -152,7 +160,7 @@ bool RegsX86_64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_ // Read the mcontext data from the stack. // sp points to the ucontext data structure, read only the mcontext part. x86_64_ucontext_t x86_64_ucontext; - if (!process_memory->ReadFully(sp() + 0x28, &x86_64_ucontext.uc_mcontext, + if (!process_memory->ReadFully(regs_[X86_64_REG_SP] + 0x28, &x86_64_ucontext.uc_mcontext, sizeof(x86_64_mcontext_t))) { return false; } diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h index b0e7ea152..4bac47313 100644 --- a/libunwindstack/include/unwindstack/Regs.h +++ b/libunwindstack/include/unwindstack/Regs.h @@ -45,8 +45,8 @@ class Regs { int16_t value; }; - Regs(uint16_t total_regs, uint16_t sp_reg, const Location& return_loc) - : total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {} + Regs(uint16_t total_regs, const Location& return_loc) + : total_regs_(total_regs), return_loc_(return_loc) {} virtual ~Regs() = default; virtual ArchEnum Arch() = 0; @@ -57,6 +57,9 @@ class Regs { virtual uint64_t pc() = 0; virtual uint64_t sp() = 0; + virtual void set_pc(uint64_t pc) = 0; + virtual void set_sp(uint64_t sp) = 0; + uint64_t dex_pc() { return dex_pc_; } void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; } @@ -64,13 +67,10 @@ class Regs { virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0; - virtual void SetFromRaw() = 0; - virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0; virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0; - uint16_t sp_reg() { return sp_reg_; } uint16_t total_regs() { return total_regs_; } static ArchEnum CurrentArch(); @@ -80,7 +80,6 @@ class Regs { protected: uint16_t total_regs_; - uint16_t sp_reg_; Location return_loc_; uint64_t dex_pc_ = 0; }; @@ -88,16 +87,10 @@ class Regs { template <typename AddressType> class RegsImpl : public Regs { public: - RegsImpl(uint16_t total_regs, uint16_t sp_reg, Location return_loc) - : Regs(total_regs, sp_reg, return_loc), regs_(total_regs) {} + RegsImpl(uint16_t total_regs, Location return_loc) + : Regs(total_regs, return_loc), regs_(total_regs) {} virtual ~RegsImpl() = default; - uint64_t pc() override { return pc_; } - uint64_t sp() override { return sp_; } - - void set_pc(AddressType pc) { pc_ = pc; } - void set_sp(AddressType sp) { sp_ = sp; } - bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); } inline AddressType& operator[](size_t reg) { return regs_[reg]; } @@ -111,8 +104,6 @@ class RegsImpl : public Regs { } protected: - AddressType pc_; - AddressType sp_; std::vector<AddressType> regs_; }; diff --git a/libunwindstack/include/unwindstack/RegsArm.h b/libunwindstack/include/unwindstack/RegsArm.h index 5af90d3f5..31e6797fa 100644 --- a/libunwindstack/include/unwindstack/RegsArm.h +++ b/libunwindstack/include/unwindstack/RegsArm.h @@ -34,17 +34,21 @@ class RegsArm : public RegsImpl<uint32_t> { RegsArm(); virtual ~RegsArm() = default; - virtual ArchEnum Arch() override final; + ArchEnum Arch() override final; uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; - void SetFromRaw() override; - bool SetPcFromReturnAddress(Memory* process_memory) override; bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; - virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + + uint64_t pc() override; + uint64_t sp() override; + + void set_pc(uint64_t pc) override; + void set_sp(uint64_t sp) override; static Regs* Read(void* data); diff --git a/libunwindstack/include/unwindstack/RegsArm64.h b/libunwindstack/include/unwindstack/RegsArm64.h index cb05732ee..0c45ebab8 100644 --- a/libunwindstack/include/unwindstack/RegsArm64.h +++ b/libunwindstack/include/unwindstack/RegsArm64.h @@ -34,17 +34,21 @@ class RegsArm64 : public RegsImpl<uint64_t> { RegsArm64(); virtual ~RegsArm64() = default; - virtual ArchEnum Arch() override final; + ArchEnum Arch() override final; uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; - void SetFromRaw() override; - bool SetPcFromReturnAddress(Memory* process_memory) override; bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; - virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + + uint64_t pc() override; + uint64_t sp() override; + + void set_pc(uint64_t pc) override; + void set_sp(uint64_t sp) override; static Regs* Read(void* data); diff --git a/libunwindstack/include/unwindstack/RegsGetLocal.h b/libunwindstack/include/unwindstack/RegsGetLocal.h index 557eace32..81c0af374 100644 --- a/libunwindstack/include/unwindstack/RegsGetLocal.h +++ b/libunwindstack/include/unwindstack/RegsGetLocal.h @@ -51,8 +51,6 @@ inline __always_inline void RegsGetLocal(Regs* regs) { : [base] "+r"(reg_data) : : "memory"); - - regs->SetFromRaw(); } #elif defined(__aarch64__) @@ -83,8 +81,6 @@ inline __always_inline void RegsGetLocal(Regs* regs) { : [base] "+r"(reg_data) : : "x12", "x13", "memory"); - - regs->SetFromRaw(); } #elif defined(__i386__) || defined(__x86_64__) || defined(__mips__) @@ -93,8 +89,6 @@ extern "C" void AsmGetRegs(void* regs); inline void RegsGetLocal(Regs* regs) { AsmGetRegs(regs->RawData()); - - regs->SetFromRaw(); } #endif diff --git a/libunwindstack/include/unwindstack/RegsMips.h b/libunwindstack/include/unwindstack/RegsMips.h index 8e3c01f20..709f9e2c7 100644 --- a/libunwindstack/include/unwindstack/RegsMips.h +++ b/libunwindstack/include/unwindstack/RegsMips.h @@ -34,17 +34,21 @@ class RegsMips : public RegsImpl<uint32_t> { RegsMips(); virtual ~RegsMips() = default; - virtual ArchEnum Arch() override final; + ArchEnum Arch() override final; uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; - void SetFromRaw() override; - bool SetPcFromReturnAddress(Memory* process_memory) override; bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; - virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + + uint64_t pc() override; + uint64_t sp() override; + + void set_pc(uint64_t pc) override; + void set_sp(uint64_t sp) override; static Regs* Read(void* data); diff --git a/libunwindstack/include/unwindstack/RegsMips64.h b/libunwindstack/include/unwindstack/RegsMips64.h index 8c2d4437f..1de83ea9d 100644 --- a/libunwindstack/include/unwindstack/RegsMips64.h +++ b/libunwindstack/include/unwindstack/RegsMips64.h @@ -34,17 +34,21 @@ class RegsMips64 : public RegsImpl<uint64_t> { RegsMips64(); virtual ~RegsMips64() = default; - virtual ArchEnum Arch() override final; + ArchEnum Arch() override final; uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; - void SetFromRaw() override; - bool SetPcFromReturnAddress(Memory* process_memory) override; bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; - virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + + uint64_t pc() override; + uint64_t sp() override; + + void set_pc(uint64_t pc) override; + void set_sp(uint64_t sp) override; static Regs* Read(void* data); diff --git a/libunwindstack/include/unwindstack/RegsX86.h b/libunwindstack/include/unwindstack/RegsX86.h index 1bc145d97..586c9d85c 100644 --- a/libunwindstack/include/unwindstack/RegsX86.h +++ b/libunwindstack/include/unwindstack/RegsX86.h @@ -35,19 +35,23 @@ class RegsX86 : public RegsImpl<uint32_t> { RegsX86(); virtual ~RegsX86() = default; - virtual ArchEnum Arch() override final; + ArchEnum Arch() override final; uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; - void SetFromRaw() override; - bool SetPcFromReturnAddress(Memory* process_memory) override; bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; void SetFromUcontext(x86_ucontext_t* ucontext); - virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + + uint64_t pc() override; + uint64_t sp() override; + + void set_pc(uint64_t pc) override; + void set_sp(uint64_t sp) override; static Regs* Read(void* data); diff --git a/libunwindstack/include/unwindstack/RegsX86_64.h b/libunwindstack/include/unwindstack/RegsX86_64.h index 4cd45d4b9..061f479a0 100644 --- a/libunwindstack/include/unwindstack/RegsX86_64.h +++ b/libunwindstack/include/unwindstack/RegsX86_64.h @@ -35,19 +35,23 @@ class RegsX86_64 : public RegsImpl<uint64_t> { RegsX86_64(); virtual ~RegsX86_64() = default; - virtual ArchEnum Arch() override final; + ArchEnum Arch() override final; uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override; - void SetFromRaw() override; - bool SetPcFromReturnAddress(Memory* process_memory) override; bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; void SetFromUcontext(x86_64_ucontext_t* ucontext); - virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + void IterateRegisters(std::function<void(const char*, uint64_t)>) override final; + + uint64_t pc() override; + uint64_t sp() override; + + void set_pc(uint64_t pc) override; + void set_sp(uint64_t sp) override; static Regs* Read(void* data); diff --git a/libunwindstack/tests/DwarfOpTest.cpp b/libunwindstack/tests/DwarfOpTest.cpp index 6e15227b3..d424d5f43 100644 --- a/libunwindstack/tests/DwarfOpTest.cpp +++ b/libunwindstack/tests/DwarfOpTest.cpp @@ -1468,7 +1468,7 @@ TYPED_TEST_P(DwarfOpTest, op_breg) { } this->op_memory_.SetMemory(0, opcode_buffer); - RegsImplFake<TypeParam> regs(32, 10); + RegsImplFake<TypeParam> regs(32); for (size_t i = 0; i < 32; i++) { regs[i] = i + 10; } @@ -1499,7 +1499,7 @@ TYPED_TEST_P(DwarfOpTest, op_breg_invalid_register) { }; this->op_memory_.SetMemory(0, opcode_buffer); - RegsImplFake<TypeParam> regs(16, 10); + RegsImplFake<TypeParam> regs(16); for (size_t i = 0; i < 16; i++) { regs[i] = i + 10; } @@ -1526,7 +1526,7 @@ TYPED_TEST_P(DwarfOpTest, op_bregx) { 0x92, 0x80, 0x15, 0x80, 0x02}; this->op_memory_.SetMemory(0, opcode_buffer); - RegsImplFake<TypeParam> regs(10, 10); + RegsImplFake<TypeParam> regs(10); regs[5] = 0x45; regs[6] = 0x190; RegsInfo<TypeParam> regs_info(®s); diff --git a/libunwindstack/tests/DwarfSectionImplTest.cpp b/libunwindstack/tests/DwarfSectionImplTest.cpp index 99f4d873f..c85764c78 100644 --- a/libunwindstack/tests/DwarfSectionImplTest.cpp +++ b/libunwindstack/tests/DwarfSectionImplTest.cpp @@ -92,7 +92,7 @@ TYPED_TEST_CASE_P(DwarfSectionImplTest); TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { DwarfCie cie{.version = 3, .return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -108,7 +108,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { DwarfCie cie{.version = 3, .return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -124,7 +124,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { DwarfCie cie{.version = 3, .return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -142,7 +142,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { DwarfCie cie{.version = 3, .return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -160,7 +160,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { DwarfCie cie{.version = 3, .return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -176,7 +176,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) { DwarfCie cie{.return_address_register = 60}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; bool finished; @@ -186,7 +186,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) { TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; bool finished; @@ -196,7 +196,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}}; @@ -225,7 +225,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -237,12 +237,12 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) { ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_FALSE(finished); EXPECT_EQ(0x20U, regs.pc()); - EXPECT_EQ(0x2000U, regs.sp()); + EXPECT_EQ(0x3000U, regs.sp()); } TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -260,7 +260,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) { TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -281,7 +281,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) { TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -312,7 +312,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) { TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -331,7 +331,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) { TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -346,7 +346,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) { TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; if (sizeof(TypeParam) == sizeof(uint64_t)) { @@ -380,7 +380,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) { TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -398,7 +398,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) { TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -415,7 +415,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) { TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -432,7 +432,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) { TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) { DwarfCie cie{.return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -451,7 +451,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) { TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) { DwarfCie cie{.version = 3, .return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); @@ -471,7 +471,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) { TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) { DwarfCie cie{.version = 3, .return_address_register = 5}; - RegsImplFake<TypeParam> regs(10, 9); + RegsImplFake<TypeParam> regs(10); dwarf_loc_regs_t loc_regs; regs.set_pc(0x100); diff --git a/libunwindstack/tests/ElfFake.cpp b/libunwindstack/tests/ElfFake.cpp index ae9da5eb4..66207dbd1 100644 --- a/libunwindstack/tests/ElfFake.cpp +++ b/libunwindstack/tests/ElfFake.cpp @@ -65,8 +65,8 @@ bool ElfInterfaceFake::Step(uint64_t, uint64_t, Regs* regs, Memory*, bool* finis } RegsFake* fake_regs = reinterpret_cast<RegsFake*>(regs); - fake_regs->FakeSetPc(entry.pc); - fake_regs->FakeSetSp(entry.sp); + fake_regs->set_pc(entry.pc); + fake_regs->set_sp(entry.sp); *finished = entry.finished; return true; } diff --git a/libunwindstack/tests/ElfTest.cpp b/libunwindstack/tests/ElfTest.cpp index eb850336b..f9028c4a5 100644 --- a/libunwindstack/tests/ElfTest.cpp +++ b/libunwindstack/tests/ElfTest.cpp @@ -316,7 +316,6 @@ TEST_F(ElfTest, step_in_signal_map) { RegsArm regs; regs[13] = 0x50000; regs[15] = 0x8000; - regs.SetFromRaw(); ElfInterfaceFake* interface = new ElfInterfaceFake(memory_); elf.FakeSetInterface(interface); diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h index ab23194e5..ede16b32b 100644 --- a/libunwindstack/tests/RegsFake.h +++ b/libunwindstack/tests/RegsFake.h @@ -27,14 +27,16 @@ namespace unwindstack { class RegsFake : public Regs { public: - RegsFake(uint16_t total_regs, uint16_t sp_reg) - : Regs(total_regs, sp_reg, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} + RegsFake(uint16_t total_regs) : Regs(total_regs, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} virtual ~RegsFake() = default; ArchEnum Arch() override { return fake_arch_; } void* RawData() override { return nullptr; } uint64_t pc() override { return fake_pc_; } uint64_t sp() override { return fake_sp_; } + void set_pc(uint64_t pc) override { fake_pc_ = pc; } + void set_sp(uint64_t sp) override { fake_sp_ = sp; } + bool SetPcFromReturnAddress(Memory*) override { if (!fake_return_address_valid_) { return false; @@ -51,11 +53,7 @@ class RegsFake : public Regs { bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } - void SetFromRaw() override {} - void FakeSetArch(ArchEnum arch) { fake_arch_ = arch; } - void FakeSetPc(uint64_t pc) { fake_pc_ = pc; } - void FakeSetSp(uint64_t sp) { fake_sp_ = sp; } void FakeSetDexPc(uint64_t dex_pc) { dex_pc_ = dex_pc; } void FakeSetReturnAddress(uint64_t return_address) { fake_return_address_ = return_address; } void FakeSetReturnAddressValid(bool valid) { fake_return_address_valid_ = valid; } @@ -71,19 +69,23 @@ class RegsFake : public Regs { template <typename TypeParam> class RegsImplFake : public RegsImpl<TypeParam> { public: - RegsImplFake(uint16_t total_regs, uint16_t sp_reg) - : RegsImpl<TypeParam>(total_regs, sp_reg, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} + RegsImplFake(uint16_t total_regs) + : RegsImpl<TypeParam>(total_regs, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {} virtual ~RegsImplFake() = default; ArchEnum Arch() override { return ARCH_UNKNOWN; } + uint64_t pc() override { return fake_pc_; } + uint64_t sp() override { return fake_sp_; } + void set_pc(uint64_t pc) override { fake_pc_ = pc; } + void set_sp(uint64_t sp) override { fake_sp_ = sp; } uint64_t GetPcAdjustment(uint64_t, Elf*) override { return 0; } - void SetFromRaw() override {} bool SetPcFromReturnAddress(Memory*) override { return false; } bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } - void FakeSetPc(uint64_t pc) { this->pc_ = pc; } - void FakeSetSp(uint64_t sp) { this->sp_ = sp; } + private: + uint64_t fake_pc_ = 0; + uint64_t fake_sp_ = 0; }; } // namespace unwindstack diff --git a/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp index ecd40518b..eac12ca64 100644 --- a/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp +++ b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp @@ -56,7 +56,6 @@ void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) RegsArm regs; regs[ARM_REG_PC] = 0x5000; regs[ARM_REG_SP] = addr; - regs.SetFromRaw(); elf_memory_->SetData32(0x5000, pc_data); @@ -87,7 +86,6 @@ void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) { RegsArm regs; regs[ARM_REG_PC] = 0x5000; regs[ARM_REG_SP] = addr; - regs.SetFromRaw(); elf_memory_->SetData32(0x5000, pc_data); @@ -118,7 +116,6 @@ TEST_F(RegsStepIfSignalHandlerTest, arm64_step_if_signal_handler) { RegsArm64 regs; regs[ARM64_REG_PC] = 0x8000; regs[ARM64_REG_SP] = addr; - regs.SetFromRaw(); elf_memory_->SetData64(0x8000, 0xd4000001d2801168ULL); @@ -138,7 +135,6 @@ TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_no_siginfo) { RegsX86 regs; regs[X86_REG_EIP] = 0x4100; regs[X86_REG_ESP] = addr; - regs.SetFromRaw(); elf_memory_->SetData64(0x4100, 0x80cd00000077b858ULL); for (uint64_t index = 0; index <= 25; index++) { @@ -162,7 +158,6 @@ TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_siginfo) { RegsX86 regs; regs[X86_REG_EIP] = 0x4100; regs[X86_REG_ESP] = addr; - regs.SetFromRaw(); elf_memory_->SetData64(0x4100, 0x0080cd000000adb8ULL); addr += 8; @@ -191,7 +186,6 @@ TEST_F(RegsStepIfSignalHandlerTest, x86_64_step_if_signal_handler) { RegsX86_64 regs; regs[X86_64_REG_RIP] = 0x7000; regs[X86_64_REG_RSP] = addr; - regs.SetFromRaw(); elf_memory_->SetData64(0x7000, 0x0f0000000fc0c748); elf_memory_->SetData16(0x7008, 0x0f05); @@ -212,7 +206,6 @@ TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_non_rt) { RegsMips regs; regs[MIPS_REG_PC] = 0x8000; regs[MIPS_REG_SP] = addr; - regs.SetFromRaw(); elf_memory_->SetData64(0x8000, 0x0000000c24021017ULL); @@ -232,7 +225,6 @@ TEST_F(RegsStepIfSignalHandlerTest, mips_step_if_signal_handler_rt) { RegsMips regs; regs[MIPS_REG_PC] = 0x8000; regs[MIPS_REG_SP] = addr; - regs.SetFromRaw(); elf_memory_->SetData64(0x8000, 0x0000000c24021061ULL); @@ -252,7 +244,6 @@ TEST_F(RegsStepIfSignalHandlerTest, mips64_step_if_signal_handler) { RegsMips64 regs; regs[MIPS64_REG_PC] = 0x8000; regs[MIPS64_REG_SP] = addr; - regs.SetFromRaw(); elf_memory_->SetData64(0x8000, 0x0000000c2402145bULL); diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp index 8b2f6c83f..3e80733bf 100644 --- a/libunwindstack/tests/RegsTest.cpp +++ b/libunwindstack/tests/RegsTest.cpp @@ -49,9 +49,8 @@ class RegsTest : public ::testing::Test { }; TEST_F(RegsTest, regs32) { - RegsImplFake<uint32_t> regs32(50, 10); + RegsImplFake<uint32_t> regs32(50); ASSERT_EQ(50U, regs32.total_regs()); - ASSERT_EQ(10U, regs32.sp_reg()); uint32_t* raw = reinterpret_cast<uint32_t*>(regs32.RawData()); for (size_t i = 0; i < 50; i++) { @@ -72,9 +71,8 @@ TEST_F(RegsTest, regs32) { } TEST_F(RegsTest, regs64) { - RegsImplFake<uint64_t> regs64(30, 12); + RegsImplFake<uint64_t> regs64(30); ASSERT_EQ(30U, regs64.total_regs()); - ASSERT_EQ(12U, regs64.sp_reg()); uint64_t* raw = reinterpret_cast<uint64_t*>(regs64.RawData()); for (size_t i = 0; i < 30; i++) { @@ -211,62 +209,56 @@ TEST_F(RegsTest, elf_invalid) { EXPECT_EQ(0U, regs_mips64.GetPcAdjustment(0xa00U, invalid_elf)); } -TEST_F(RegsTest, arm_set_from_raw) { +TEST_F(RegsTest, arm_verify_sp_pc) { RegsArm arm; uint32_t* regs = reinterpret_cast<uint32_t*>(arm.RawData()); regs[13] = 0x100; regs[15] = 0x200; - arm.SetFromRaw(); EXPECT_EQ(0x100U, arm.sp()); EXPECT_EQ(0x200U, arm.pc()); } -TEST_F(RegsTest, arm64_set_from_raw) { +TEST_F(RegsTest, arm64_verify_sp_pc) { RegsArm64 arm64; uint64_t* regs = reinterpret_cast<uint64_t*>(arm64.RawData()); regs[31] = 0xb100000000ULL; regs[32] = 0xc200000000ULL; - arm64.SetFromRaw(); EXPECT_EQ(0xb100000000U, arm64.sp()); EXPECT_EQ(0xc200000000U, arm64.pc()); } -TEST_F(RegsTest, x86_set_from_raw) { +TEST_F(RegsTest, x86_verify_sp_pc) { RegsX86 x86; uint32_t* regs = reinterpret_cast<uint32_t*>(x86.RawData()); regs[4] = 0x23450000; regs[8] = 0xabcd0000; - x86.SetFromRaw(); EXPECT_EQ(0x23450000U, x86.sp()); EXPECT_EQ(0xabcd0000U, x86.pc()); } -TEST_F(RegsTest, x86_64_set_from_raw) { +TEST_F(RegsTest, x86_64_verify_sp_pc) { RegsX86_64 x86_64; uint64_t* regs = reinterpret_cast<uint64_t*>(x86_64.RawData()); regs[7] = 0x1200000000ULL; regs[16] = 0x4900000000ULL; - x86_64.SetFromRaw(); EXPECT_EQ(0x1200000000U, x86_64.sp()); EXPECT_EQ(0x4900000000U, x86_64.pc()); } -TEST_F(RegsTest, mips_set_from_raw) { +TEST_F(RegsTest, mips_verify_sp_pc) { RegsMips mips; uint32_t* regs = reinterpret_cast<uint32_t*>(mips.RawData()); regs[29] = 0x100; regs[32] = 0x200; - mips.SetFromRaw(); EXPECT_EQ(0x100U, mips.sp()); EXPECT_EQ(0x200U, mips.pc()); } -TEST_F(RegsTest, mips64_set_from_raw) { +TEST_F(RegsTest, mips64_verify_sp_pc) { RegsMips64 mips64; uint64_t* regs = reinterpret_cast<uint64_t*>(mips64.RawData()); regs[29] = 0xb100000000ULL; regs[32] = 0xc200000000ULL; - mips64.SetFromRaw(); EXPECT_EQ(0xb100000000U, mips64.sp()); EXPECT_EQ(0xc200000000U, mips64.pc()); } diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp index 515bc8cc7..532640f38 100644 --- a/libunwindstack/tests/UnwindOfflineTest.cpp +++ b/libunwindstack/tests/UnwindOfflineTest.cpp @@ -122,7 +122,6 @@ class UnwindOfflineTest : public ::testing::Test { (*regs)[entry->second] = value; } fclose(fp); - regs->SetFromRaw(); } static std::unordered_map<std::string, uint32_t> arm_regs_; @@ -956,4 +955,119 @@ TEST_F(UnwindOfflineTest, eh_frame_hdr_begin_x86_64) { EXPECT_EQ(0x7ffcc85971a0U, unwinder.frames()[4].sp); } +TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) { + Init("art_quick_osr_stub_arm/", ARCH_ARM); + + MemoryOfflineParts* memory = new MemoryOfflineParts; + AddMemory(dir_ + "descriptor.data", memory); + AddMemory(dir_ + "stack.data", memory); + for (size_t i = 0; i < 2; i++) { + AddMemory(dir_ + "entry" + std::to_string(i) + ".data", memory); + AddMemory(dir_ + "jit" + std::to_string(i) + ".data", memory); + } + process_memory_.reset(memory); + + JitDebug jit_debug(process_memory_); + Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); + unwinder.SetJitDebug(&jit_debug, regs_->Arch()); + unwinder.Unwind(); + + std::string frame_info(DumpFrames(unwinder)); + ASSERT_EQ(25U, unwinder.NumFrames()) << "Unwind:\n" << frame_info; + EXPECT_EQ( + " #00 pc 0000c788 <anonymous:d0250000> " + "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity.access$000)\n" + " #01 pc 0000cdd5 <anonymous:d0250000> " + "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run+60)\n" + " #02 pc 004135bb libart.so (art_quick_osr_stub+42)\n" + " #03 pc 002657a5 libart.so " + "(_ZN3art3jit3Jit25MaybeDoOnStackReplacementEPNS_6ThreadEPNS_9ArtMethodEjiPNS_6JValueE+876)\n" + " #04 pc 004021a7 libart.so (MterpMaybeDoOnStackReplacement+86)\n" + " #05 pc 00412474 libart.so (ExecuteMterpImpl+66164)\n" + " #06 pc cd8365b0 <unknown>\n" // symbol in dex file + " #07 pc 001d7f1b libart.so " + "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_" + "6JValueEb+374)\n" + " #08 pc 001dc593 libart.so " + "(_ZN3art11interpreter33ArtInterpreterToInterpreterBridgeEPNS_6ThreadERKNS_" + "20CodeItemDataAccessorEPNS_11ShadowFrameEPNS_6JValueE+154)\n" + " #09 pc 001f4d01 libart.so " + "(_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_" + "11InstructionEtPNS_6JValueE+732)\n" + " #10 pc 003fe427 libart.so (MterpInvokeInterface+1354)\n" + " #11 pc 00405b94 libart.so (ExecuteMterpImpl+14740)\n" + " #12 pc 7004873e <unknown>\n" // symbol in dex file + " #13 pc 001d7f1b libart.so " + "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_" + "6JValueEb+374)\n" + " #14 pc 001dc4d5 libart.so " + "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_" + "20CodeItemDataAccessorEPNS_11ShadowFrameE+92)\n" + " #15 pc 003f25ab libart.so (artQuickToInterpreterBridge+970)\n" + " #16 pc 00417aff libart.so (art_quick_to_interpreter_bridge+30)\n" + " #17 pc 00413575 libart.so (art_quick_invoke_stub_internal+68)\n" + " #18 pc 00418531 libart.so (art_quick_invoke_stub+236)\n" + " #19 pc 000b468d libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+136)\n" + " #20 pc 00362f49 libart.so " + "(_ZN3art12_GLOBAL__N_118InvokeWithArgArrayERKNS_33ScopedObjectAccessAlreadyRunnableEPNS_" + "9ArtMethodEPNS0_8ArgArrayEPNS_6JValueEPKc+52)\n" + " #21 pc 00363cd9 libart.so " + "(_ZN3art35InvokeVirtualOrInterfaceWithJValuesERKNS_33ScopedObjectAccessAlreadyRunnableEP8_" + "jobjectP10_jmethodIDP6jvalue+332)\n" + " #22 pc 003851dd libart.so (_ZN3art6Thread14CreateCallbackEPv+868)\n" + " #23 pc 00062925 libc.so (_ZL15__pthread_startPv+22)\n" + " #24 pc 0001de39 libc.so (__start_thread+24)\n", + frame_info); + EXPECT_EQ(0xd025c788U, unwinder.frames()[0].pc); + EXPECT_EQ(0xcd4ff140U, unwinder.frames()[0].sp); + EXPECT_EQ(0xd025cdd5U, unwinder.frames()[1].pc); + EXPECT_EQ(0xcd4ff140U, unwinder.frames()[1].sp); + EXPECT_EQ(0xe4a755bbU, unwinder.frames()[2].pc); + EXPECT_EQ(0xcd4ff160U, unwinder.frames()[2].sp); + EXPECT_EQ(0xe48c77a5U, unwinder.frames()[3].pc); + EXPECT_EQ(0xcd4ff190U, unwinder.frames()[3].sp); + EXPECT_EQ(0xe4a641a7U, unwinder.frames()[4].pc); + EXPECT_EQ(0xcd4ff298U, unwinder.frames()[4].sp); + EXPECT_EQ(0xe4a74474U, unwinder.frames()[5].pc); + EXPECT_EQ(0xcd4ff2b8U, unwinder.frames()[5].sp); + EXPECT_EQ(0xcd8365b0U, unwinder.frames()[6].pc); + EXPECT_EQ(0xcd4ff2e0U, unwinder.frames()[6].sp); + EXPECT_EQ(0xe4839f1bU, unwinder.frames()[7].pc); + EXPECT_EQ(0xcd4ff2e0U, unwinder.frames()[7].sp); + EXPECT_EQ(0xe483e593U, unwinder.frames()[8].pc); + EXPECT_EQ(0xcd4ff330U, unwinder.frames()[8].sp); + EXPECT_EQ(0xe4856d01U, unwinder.frames()[9].pc); + EXPECT_EQ(0xcd4ff380U, unwinder.frames()[9].sp); + EXPECT_EQ(0xe4a60427U, unwinder.frames()[10].pc); + EXPECT_EQ(0xcd4ff430U, unwinder.frames()[10].sp); + EXPECT_EQ(0xe4a67b94U, unwinder.frames()[11].pc); + EXPECT_EQ(0xcd4ff498U, unwinder.frames()[11].sp); + EXPECT_EQ(0x7004873eU, unwinder.frames()[12].pc); + EXPECT_EQ(0xcd4ff4c0U, unwinder.frames()[12].sp); + EXPECT_EQ(0xe4839f1bU, unwinder.frames()[13].pc); + EXPECT_EQ(0xcd4ff4c0U, unwinder.frames()[13].sp); + EXPECT_EQ(0xe483e4d5U, unwinder.frames()[14].pc); + EXPECT_EQ(0xcd4ff510U, unwinder.frames()[14].sp); + EXPECT_EQ(0xe4a545abU, unwinder.frames()[15].pc); + EXPECT_EQ(0xcd4ff538U, unwinder.frames()[15].sp); + EXPECT_EQ(0xe4a79affU, unwinder.frames()[16].pc); + EXPECT_EQ(0xcd4ff640U, unwinder.frames()[16].sp); + EXPECT_EQ(0xe4a75575U, unwinder.frames()[17].pc); + EXPECT_EQ(0xcd4ff6b0U, unwinder.frames()[17].sp); + EXPECT_EQ(0xe4a7a531U, unwinder.frames()[18].pc); + EXPECT_EQ(0xcd4ff6e8U, unwinder.frames()[18].sp); + EXPECT_EQ(0xe471668dU, unwinder.frames()[19].pc); + EXPECT_EQ(0xcd4ff770U, unwinder.frames()[19].sp); + EXPECT_EQ(0xe49c4f49U, unwinder.frames()[20].pc); + EXPECT_EQ(0xcd4ff7c8U, unwinder.frames()[20].sp); + EXPECT_EQ(0xe49c5cd9U, unwinder.frames()[21].pc); + EXPECT_EQ(0xcd4ff850U, unwinder.frames()[21].sp); + EXPECT_EQ(0xe49e71ddU, unwinder.frames()[22].pc); + EXPECT_EQ(0xcd4ff8e8U, unwinder.frames()[22].sp); + EXPECT_EQ(0xe7df3925U, unwinder.frames()[23].pc); + EXPECT_EQ(0xcd4ff958U, unwinder.frames()[23].sp); + EXPECT_EQ(0xe7daee39U, unwinder.frames()[24].pc); + EXPECT_EQ(0xcd4ff960U, unwinder.frames()[24].sp); +} + } // namespace unwindstack diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp index e44b225c5..b38fb5fb5 100644 --- a/libunwindstack/tests/UnwinderTest.cpp +++ b/libunwindstack/tests/UnwinderTest.cpp @@ -133,7 +133,7 @@ class UnwinderTest : public ::testing::Test { }; MapsFake UnwinderTest::maps_; -RegsFake UnwinderTest::regs_(5, 0); +RegsFake UnwinderTest::regs_(5); std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr); TEST_F(UnwinderTest, multiple_frames) { @@ -141,8 +141,8 @@ TEST_F(UnwinderTest, multiple_frames) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); @@ -201,8 +201,8 @@ TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); @@ -260,8 +260,8 @@ TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) { TEST_F(UnwinderTest, non_zero_load_bias) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); - regs_.FakeSetPc(0xa5500); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0xa5500); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); Unwinder unwinder(64, &maps_, ®s_, process_memory_); @@ -288,8 +288,8 @@ TEST_F(UnwinderTest, non_zero_load_bias) { TEST_F(UnwinderTest, non_zero_elf_offset) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); - regs_.FakeSetPc(0xa7500); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0xa7500); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); Unwinder unwinder(64, &maps_, ®s_, process_memory_); @@ -316,8 +316,8 @@ TEST_F(UnwinderTest, non_zero_elf_offset) { TEST_F(UnwinderTest, non_zero_map_offset) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); - regs_.FakeSetPc(0x43000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x43000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); Unwinder unwinder(64, &maps_, ®s_, process_memory_); @@ -349,8 +349,8 @@ TEST_F(UnwinderTest, no_frames_after_finished) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true)); ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false)); @@ -383,8 +383,8 @@ TEST_F(UnwinderTest, max_frames) { ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false)); } - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); Unwinder unwinder(20, &maps_, ®s_, process_memory_); unwinder.Unwind(); @@ -415,8 +415,8 @@ TEST_F(UnwinderTest, verify_frames_skipped) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); - regs_.FakeSetPc(0x20000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x20000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false)); @@ -481,8 +481,8 @@ TEST_F(UnwinderTest, sp_not_in_map) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x63000); + regs_.set_pc(0x1000); + regs_.set_sp(0x63000); ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); @@ -527,8 +527,8 @@ TEST_F(UnwinderTest, pc_in_device_stops_unwind) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); - regs_.FakeSetPc(0x13000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x13000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); @@ -546,8 +546,8 @@ TEST_F(UnwinderTest, sp_in_device_stops_unwind) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x13000); + regs_.set_pc(0x1000); + regs_.set_sp(0x13000); ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); @@ -563,8 +563,8 @@ TEST_F(UnwinderTest, sp_in_device_stops_unwind) { TEST_F(UnwinderTest, pc_without_map) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); - regs_.FakeSetPc(0x41000); - regs_.FakeSetSp(0x13000); + regs_.set_pc(0x41000); + regs_.set_sp(0x13000); Unwinder unwinder(64, &maps_, ®s_, process_memory_); unwinder.Unwind(); @@ -593,8 +593,8 @@ TEST_F(UnwinderTest, speculative_frame) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); // Fake as if code called a nullptr function. - regs_.FakeSetPc(0); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0); + regs_.set_sp(0x10000); regs_.FakeSetReturnAddress(0x1202); regs_.FakeSetReturnAddressValid(true); @@ -657,8 +657,8 @@ TEST_F(UnwinderTest, speculative_frame_removed) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); // Fake as if code called a nullptr function. - regs_.FakeSetPc(0); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0); + regs_.set_sp(0x10000); regs_.FakeSetReturnAddress(0x1202); regs_.FakeSetReturnAddressValid(true); @@ -691,8 +691,8 @@ TEST_F(UnwinderTest, map_ignore_suffixes) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); // Fake as if code called a nullptr function. - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); @@ -745,8 +745,8 @@ TEST_F(UnwinderTest, sp_pc_do_not_change) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false)); ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false)); @@ -805,8 +805,8 @@ TEST_F(UnwinderTest, sp_pc_do_not_change) { TEST_F(UnwinderTest, dex_pc_in_map) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); regs_.FakeSetDexPc(0xa3400); Unwinder unwinder(64, &maps_, ®s_, process_memory_); @@ -846,8 +846,8 @@ TEST_F(UnwinderTest, dex_pc_in_map) { TEST_F(UnwinderTest, dex_pc_not_in_map) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); regs_.FakeSetDexPc(0x50000); Unwinder unwinder(64, &maps_, ®s_, process_memory_); @@ -888,8 +888,8 @@ TEST_F(UnwinderTest, dex_pc_not_in_map) { TEST_F(UnwinderTest, dex_pc_multiple_frames) { ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1)); - regs_.FakeSetPc(0x1000); - regs_.FakeSetSp(0x10000); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); regs_.FakeSetDexPc(0xa3400); ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false)); ElfInterfaceFake::FakePushStepData(StepData(0, 0, true)); diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/descriptor.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/descriptor.data Binary files differnew file mode 100644 index 000000000..300646b7b --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/descriptor.data diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry0.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry0.data Binary files differnew file mode 100644 index 000000000..999cb790a --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry0.data diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry1.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry1.data Binary files differnew file mode 100644 index 000000000..6aa1c824f --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/entry1.data diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit0.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit0.data Binary files differnew file mode 100644 index 000000000..19d7b65cf --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit0.data diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit1.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit1.data Binary files differnew file mode 100644 index 000000000..edcd3e169 --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/jit1.data diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libart.so b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libart.so Binary files differnew file mode 100644 index 000000000..09ba49532 --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libart.so diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libc.so b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libc.so Binary files differnew file mode 100644 index 000000000..39c9025db --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/libc.so diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/maps.txt b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/maps.txt new file mode 100644 index 000000000..55aaaf63f --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/maps.txt @@ -0,0 +1,3 @@ +d0250000-d2600000 r-xp 0 00:00 0 <anonymous:d0250000> +e466e000-e4ae8000 r-xp 0 00:00 0 libart.so +e7d91000-e7e31000 r-xp 0 00:00 0 libc.so diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/regs.txt b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/regs.txt new file mode 100644 index 000000000..0b518143a --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/regs.txt @@ -0,0 +1,16 @@ +r0: e814103c +r1: 12dcf218 +r2: 1a90df75 +r3: ffffffbf +r4: 0 +r5: 12dc0800 +r6: 12dcf218 +r7: 1a90df75 +r8: 0 +r9: dd23cc00 +r10: 1c +r11: cd4ff16c +ip: 0 +sp: cd4ff140 +lr: d025cdd7 +pc: d025c788 diff --git a/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/stack.data b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/stack.data Binary files differnew file mode 100644 index 000000000..f00917b77 --- /dev/null +++ b/libunwindstack/tests/files/offline/art_quick_osr_stub_arm/stack.data |