diff options
| author | Yabin Cui <yabinc@google.com> | 2018-03-14 18:16:22 -0700 |
|---|---|---|
| committer | Christopher Ferris <cferris@google.com> | 2018-03-16 23:38:07 -0700 |
| commit | 11e96fe48a74e6ab97d4de899684d3a61a9d1129 (patch) | |
| tree | 6a056073b680ed6fe25fb406e5f2b316b991ee3e /libunwindstack/RegsX86_64.cpp | |
| parent | a411fc65d1fc4c2c1c44d5d0860b31a018b8c9fd (diff) | |
| download | system_core-11e96fe48a74e6ab97d4de899684d3a61a9d1129.tar.gz system_core-11e96fe48a74e6ab97d4de899684d3a61a9d1129.tar.bz2 system_core-11e96fe48a74e6ab97d4de899684d3a61a9d1129.zip | |
Always set the sp reg to the cfa for DWARF.
There are a few places where it is assumed that this register is
set to the cfa value when interpreting DWARF information.
Add a testcase for unwinding art_quick_osr_stub on ARM.
Bug: 73954823
Test: Ran libunwindstack/libbacktrace unit tests.
Test: Random debuggerd -b of process on a hikey.
Test: Ran the 137 art test on host.
Change-Id: Ida6ccdc38c3cfeea6b57fe861a0cc127b150b790
Diffstat (limited to 'libunwindstack/RegsX86_64.cpp')
| -rw-r--r-- | libunwindstack/RegsX86_64.cpp | 34 |
1 files changed, 21 insertions, 13 deletions
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; } |
