diff options
Diffstat (limited to 'libunwindstack')
-rw-r--r-- | libunwindstack/Android.bp | 1 | ||||
-rw-r--r-- | libunwindstack/Elf.cpp | 2 | ||||
-rw-r--r-- | libunwindstack/Regs.cpp | 47 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/Regs.h | 10 | ||||
-rw-r--r-- | libunwindstack/tests/RegsFake.h | 2 | ||||
-rw-r--r-- | libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp | 201 | ||||
-rw-r--r-- | libunwindstack/tests/RegsTest.cpp | 163 |
7 files changed, 240 insertions, 186 deletions
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp index 94f0f8e..04c4cfa 100644 --- a/libunwindstack/Android.bp +++ b/libunwindstack/Android.bp @@ -115,6 +115,7 @@ cc_test { "tests/MemoryRangeTest.cpp", "tests/MemoryRemoteTest.cpp", "tests/MemoryTest.cpp", + "tests/RegsStepIfSignalHandlerTest.cpp", "tests/RegsTest.cpp", "tests/SymbolsTest.cpp", "tests/UnwindTest.cpp", diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp index e962a73..4fc7c67 100644 --- a/libunwindstack/Elf.cpp +++ b/libunwindstack/Elf.cpp @@ -96,7 +96,7 @@ bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offse } bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory) { - return valid_ && (regs->StepIfSignalHandler(process_memory) || + return valid_ && (regs->StepIfSignalHandler(rel_pc, this, process_memory) || interface_->Step(rel_pc, regs, process_memory) || (gnu_debugdata_interface_ && gnu_debugdata_interface_->Step(rel_pc, regs, process_memory))); diff --git a/libunwindstack/Regs.cpp b/libunwindstack/Regs.cpp index 33319b1..dea7b87 100644 --- a/libunwindstack/Regs.cpp +++ b/libunwindstack/Regs.cpp @@ -350,9 +350,12 @@ Regs* Regs::CreateFromLocal() { return regs; } -bool RegsArm::StepIfSignalHandler(Memory* memory) { +bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) { uint32_t data; - if (!memory->Read(pc(), &data, sizeof(data))) { + Memory* elf_memory = elf->memory(); + // Read from elf memory since it is usually more expensive to read from + // process memory. + if (!elf_memory->Read(rel_pc, &data, sizeof(data))) { return false; } @@ -371,7 +374,7 @@ bool RegsArm::StepIfSignalHandler(Memory* memory) { // Form 3 (thumb): // 0x77 0x27 movs r7, #77 // 0x00 0xdf svc 0 - if (!memory->Read(sp(), &data, sizeof(data))) { + if (!process_memory->Read(sp(), &data, sizeof(data))) { return false; } if (data == 0x5ac3c35a) { @@ -395,7 +398,7 @@ bool RegsArm::StepIfSignalHandler(Memory* memory) { // Form 3 (thumb): // 0xad 0x27 movs r7, #ad // 0x00 0xdf svc 0 - if (!memory->Read(sp(), &data, sizeof(data))) { + if (!process_memory->Read(sp(), &data, sizeof(data))) { return false; } if (data == sp() + 8) { @@ -410,16 +413,19 @@ bool RegsArm::StepIfSignalHandler(Memory* memory) { return false; } - if (!memory->Read(offset, regs_.data(), sizeof(uint32_t) * ARM_REG_LAST)) { + if (!process_memory->Read(offset, regs_.data(), sizeof(uint32_t) * ARM_REG_LAST)) { return false; } SetFromRaw(); return true; } -bool RegsArm64::StepIfSignalHandler(Memory* memory) { +bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) { uint64_t data; - if (!memory->Read(pc(), &data, sizeof(data))) { + Memory* elf_memory = elf->memory(); + // Read from elf memory since it is usually more expensive to read from + // process memory. + if (!elf_memory->Read(rel_pc, &data, sizeof(data))) { return false; } @@ -432,7 +438,8 @@ bool RegsArm64::StepIfSignalHandler(Memory* memory) { } // SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset. - if (!memory->Read(sp() + 0x80 + 0xb0 + 0x08, regs_.data(), sizeof(uint64_t) * ARM64_REG_LAST)) { + if (!process_memory->Read(sp() + 0x80 + 0xb0 + 0x08, regs_.data(), + sizeof(uint64_t) * ARM64_REG_LAST)) { return false; } @@ -440,9 +447,12 @@ bool RegsArm64::StepIfSignalHandler(Memory* memory) { return true; } -bool RegsX86::StepIfSignalHandler(Memory* memory) { +bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) { uint64_t data; - if (!memory->Read(pc(), &data, sizeof(data))) { + Memory* elf_memory = elf->memory(); + // Read from elf memory since it is usually more expensive to read from + // process memory. + if (!elf_memory->Read(rel_pc, &data, sizeof(data))) { return false; } @@ -458,7 +468,7 @@ bool RegsX86::StepIfSignalHandler(Memory* memory) { // int signum // struct sigcontext (same format as mcontext) struct x86_mcontext_t context; - if (!memory->Read(sp() + 4, &context, sizeof(context))) { + if (!process_memory->Read(sp() + 4, &context, sizeof(context))) { return false; } regs_[X86_REG_EBP] = context.ebp; @@ -484,12 +494,12 @@ bool RegsX86::StepIfSignalHandler(Memory* memory) { // Get the location of the sigcontext data. uint32_t ptr; - if (!memory->Read(sp() + 8, &ptr, sizeof(ptr))) { + if (!process_memory->Read(sp() + 8, &ptr, sizeof(ptr))) { return false; } // Only read the portion of the data structure we care about. x86_ucontext_t x86_ucontext; - if (!memory->Read(ptr + 0x14, &x86_ucontext.uc_mcontext, sizeof(x86_mcontext_t))) { + if (!process_memory->Read(ptr + 0x14, &x86_ucontext.uc_mcontext, sizeof(x86_mcontext_t))) { return false; } SetFromUcontext(&x86_ucontext); @@ -498,14 +508,17 @@ bool RegsX86::StepIfSignalHandler(Memory* memory) { return false; } -bool RegsX86_64::StepIfSignalHandler(Memory* memory) { +bool RegsX86_64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) { uint64_t data; - if (!memory->Read(pc(), &data, sizeof(data)) || data != 0x0f0000000fc0c748) { + Memory* elf_memory = elf->memory(); + // Read from elf memory since it is usually more expensive to read from + // process memory. + if (!elf_memory->Read(rel_pc, &data, sizeof(data)) || data != 0x0f0000000fc0c748) { return false; } uint16_t data2; - if (!memory->Read(pc() + 8, &data2, sizeof(data2)) || data2 != 0x0f05) { + if (!elf_memory->Read(rel_pc + 8, &data2, sizeof(data2)) || data2 != 0x0f05) { return false; } @@ -517,7 +530,7 @@ bool RegsX86_64::StepIfSignalHandler(Memory* memory) { // 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 (!memory->Read(sp() + 0x28, &x86_64_ucontext.uc_mcontext, sizeof(x86_64_mcontext_t))) { + if (!process_memory->Read(sp() + 0x28, &x86_64_ucontext.uc_mcontext, sizeof(x86_64_mcontext_t))) { return false; } SetFromUcontext(&x86_64_ucontext); diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h index 7623b7d..78e2c0d 100644 --- a/libunwindstack/include/unwindstack/Regs.h +++ b/libunwindstack/include/unwindstack/Regs.h @@ -57,7 +57,7 @@ class Regs { virtual uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) = 0; - virtual bool StepIfSignalHandler(Memory*) = 0; + virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0; virtual void SetFromRaw() = 0; @@ -109,7 +109,7 @@ class RegsArm : public RegsImpl<uint32_t> { void SetFromRaw() override; - bool StepIfSignalHandler(Memory* memory) override; + bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; }; class RegsArm64 : public RegsImpl<uint64_t> { @@ -121,7 +121,7 @@ class RegsArm64 : public RegsImpl<uint64_t> { void SetFromRaw() override; - bool StepIfSignalHandler(Memory* memory) override; + bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; }; class RegsX86 : public RegsImpl<uint32_t> { @@ -133,7 +133,7 @@ class RegsX86 : public RegsImpl<uint32_t> { void SetFromRaw() override; - bool StepIfSignalHandler(Memory* memory) override; + bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; void SetFromUcontext(x86_ucontext_t* ucontext); }; @@ -147,7 +147,7 @@ class RegsX86_64 : public RegsImpl<uint64_t> { void SetFromRaw() override; - bool StepIfSignalHandler(Memory* memory) override; + bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override; void SetFromUcontext(x86_64_ucontext_t* ucontext); }; diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h index f998da7..6669d7d 100644 --- a/libunwindstack/tests/RegsFake.h +++ b/libunwindstack/tests/RegsFake.h @@ -33,7 +33,7 @@ class RegsFake : public RegsImpl<TypeParam> { uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; } void SetFromRaw() override {} - bool StepIfSignalHandler(Memory*) override { return false; } + bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } bool GetReturnAddressFromDefault(Memory*, uint64_t*) { return false; } }; diff --git a/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp new file mode 100644 index 0000000..85192d5 --- /dev/null +++ b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> + +#include <gtest/gtest.h> + +#include <unwindstack/Elf.h> +#include <unwindstack/Regs.h> + +#include "Machine.h" + +#include "MemoryFake.h" + +namespace unwindstack { + +class RegsStepIfSignalHandlerTest : public ::testing::Test { + protected: + void SetUp() override { + elf_memory_ = new MemoryFake; + elf_.reset(new Elf(elf_memory_)); + } + + void ArmStepIfSignalHandlerNonRt(uint32_t pc_data); + void ArmStepIfSignalHandlerRt(uint32_t pc_data); + + MemoryFake* elf_memory_; + MemoryFake process_memory_; + std::unique_ptr<Elf> elf_; +}; + +void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) { + uint64_t addr = 0x1000; + RegsArm regs; + regs[ARM_REG_PC] = 0x5000; + regs[ARM_REG_SP] = addr; + regs.SetFromRaw(); + + elf_memory_->SetData32(0x5000, pc_data); + + for (uint64_t index = 0; index <= 30; index++) { + process_memory_.SetData32(addr + index * 4, index * 0x10); + } + + ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_)); + EXPECT_EQ(0x100U, regs[ARM_REG_SP]); + EXPECT_EQ(0x120U, regs[ARM_REG_PC]); + EXPECT_EQ(0x100U, regs.sp()); + EXPECT_EQ(0x120U, regs.pc()); +} + +TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_non_rt) { + // Form 1 + ArmStepIfSignalHandlerNonRt(0xe3a07077); + + // Form 2 + ArmStepIfSignalHandlerNonRt(0xef900077); + + // Form 3 + ArmStepIfSignalHandlerNonRt(0xdf002777); +} + +void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) { + uint64_t addr = 0x1000; + RegsArm regs; + regs[ARM_REG_PC] = 0x5000; + regs[ARM_REG_SP] = addr; + regs.SetFromRaw(); + + elf_memory_->SetData32(0x5000, pc_data); + + for (uint64_t index = 0; index <= 100; index++) { + process_memory_.SetData32(addr + index * 4, index * 0x10); + } + + ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_)); + EXPECT_EQ(0x350U, regs[ARM_REG_SP]); + EXPECT_EQ(0x370U, regs[ARM_REG_PC]); + EXPECT_EQ(0x350U, regs.sp()); + EXPECT_EQ(0x370U, regs.pc()); +} + +TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_rt) { + // Form 1 + ArmStepIfSignalHandlerRt(0xe3a070ad); + + // Form 2 + ArmStepIfSignalHandlerRt(0xef9000ad); + + // Form 3 + ArmStepIfSignalHandlerRt(0xdf0027ad); +} + +TEST_F(RegsStepIfSignalHandlerTest, arm64_step_if_signal_handler) { + uint64_t addr = 0x1000; + RegsArm64 regs; + regs[ARM64_REG_PC] = 0x8000; + regs[ARM64_REG_SP] = addr; + regs.SetFromRaw(); + + elf_memory_->SetData64(0x8000, 0xd4000001d2801168ULL); + + for (uint64_t index = 0; index <= 100; index++) { + process_memory_.SetData64(addr + index * 8, index * 0x10); + } + + ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_)); + EXPECT_EQ(0x460U, regs[ARM64_REG_SP]); + EXPECT_EQ(0x470U, regs[ARM64_REG_PC]); + EXPECT_EQ(0x460U, regs.sp()); + EXPECT_EQ(0x470U, regs.pc()); +} + +TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_no_siginfo) { + uint64_t addr = 0xa00; + 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++) { + process_memory_.SetData32(addr + index * 4, index * 0x10); + } + + ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_)); + EXPECT_EQ(0x70U, regs[X86_REG_EBP]); + EXPECT_EQ(0x80U, regs[X86_REG_ESP]); + EXPECT_EQ(0x90U, regs[X86_REG_EBX]); + EXPECT_EQ(0xa0U, regs[X86_REG_EDX]); + EXPECT_EQ(0xb0U, regs[X86_REG_ECX]); + EXPECT_EQ(0xc0U, regs[X86_REG_EAX]); + EXPECT_EQ(0xf0U, regs[X86_REG_EIP]); + EXPECT_EQ(0x80U, regs.sp()); + EXPECT_EQ(0xf0U, regs.pc()); +} + +TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_siginfo) { + uint64_t addr = 0xa00; + RegsX86 regs; + regs[X86_REG_EIP] = 0x4100; + regs[X86_REG_ESP] = addr; + regs.SetFromRaw(); + + elf_memory_->SetData64(0x4100, 0x0080cd000000adb8ULL); + addr += 8; + // Pointer to ucontext data. + process_memory_.SetData32(addr, 0x8100); + + addr = 0x8100; + for (uint64_t index = 0; index <= 30; index++) { + process_memory_.SetData32(addr + index * 4, index * 0x10); + } + + ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_)); + EXPECT_EQ(0xb0U, regs[X86_REG_EBP]); + EXPECT_EQ(0xc0U, regs[X86_REG_ESP]); + EXPECT_EQ(0xd0U, regs[X86_REG_EBX]); + EXPECT_EQ(0xe0U, regs[X86_REG_EDX]); + EXPECT_EQ(0xf0U, regs[X86_REG_ECX]); + EXPECT_EQ(0x100U, regs[X86_REG_EAX]); + EXPECT_EQ(0x130U, regs[X86_REG_EIP]); + EXPECT_EQ(0xc0U, regs.sp()); + EXPECT_EQ(0x130U, regs.pc()); +} + +TEST_F(RegsStepIfSignalHandlerTest, x86_64_step_if_signal_handler) { + uint64_t addr = 0x500; + 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); + + for (uint64_t index = 0; index <= 30; index++) { + process_memory_.SetData64(addr + index * 8, index * 0x10); + } + + ASSERT_TRUE(regs.StepIfSignalHandler(0x7000, elf_.get(), &process_memory_)); + EXPECT_EQ(0x140U, regs[X86_64_REG_RSP]); + EXPECT_EQ(0x150U, regs[X86_64_REG_RIP]); + EXPECT_EQ(0x140U, regs.sp()); + EXPECT_EQ(0x150U, regs.pc()); +} + +} // namespace unwindstack diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp index 9622166..e6de56a 100644 --- a/libunwindstack/tests/RegsTest.cpp +++ b/libunwindstack/tests/RegsTest.cpp @@ -23,8 +23,6 @@ #include <unwindstack/MapInfo.h> #include <unwindstack/Regs.h> -#include "Machine.h" - #include "MemoryFake.h" namespace unwindstack { @@ -62,7 +60,7 @@ class RegsTestImpl : public RegsImpl<TypeParam> { uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; } void SetFromRaw() override {} - bool StepIfSignalHandler(Memory*) override { return false; } + bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } }; class RegsTest : public ::testing::Test { @@ -77,9 +75,6 @@ class RegsTest : public ::testing::Test { template <typename AddressType> void RegsReturnAddressRegister(); - void ArmStepIfSignalHandlerNonRt(uint32_t pc_data); - void ArmStepIfSignalHandlerRt(uint32_t pc_data); - ElfInterfaceFake* elf_interface_; MemoryFake* memory_; std::unique_ptr<ElfFake> elf_; @@ -291,160 +286,4 @@ TEST_F(RegsTest, x86_64_set_from_raw) { EXPECT_EQ(0x4900000000U, x86_64.pc()); } -void RegsTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) { - uint64_t addr = 0x1000; - RegsArm regs; - regs[ARM_REG_PC] = 0x5000; - regs[ARM_REG_SP] = addr; - regs.SetFromRaw(); - - memory_->SetData32(0x5000, pc_data); - - for (uint64_t index = 0; index <= 30; index++) { - memory_->SetData32(addr + index * 4, index * 0x10); - } - - ASSERT_TRUE(regs.StepIfSignalHandler(memory_)); - EXPECT_EQ(0x100U, regs[ARM_REG_SP]); - EXPECT_EQ(0x120U, regs[ARM_REG_PC]); - EXPECT_EQ(0x100U, regs.sp()); - EXPECT_EQ(0x120U, regs.pc()); -} - -TEST_F(RegsTest, arm_step_if_signal_handler_non_rt) { - // Form 1 - ArmStepIfSignalHandlerNonRt(0xe3a07077); - - // Form 2 - ArmStepIfSignalHandlerNonRt(0xef900077); - - // Form 3 - ArmStepIfSignalHandlerNonRt(0xdf002777); -} - -void RegsTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) { - uint64_t addr = 0x1000; - RegsArm regs; - regs[ARM_REG_PC] = 0x5000; - regs[ARM_REG_SP] = addr; - regs.SetFromRaw(); - - memory_->SetData32(0x5000, pc_data); - - for (uint64_t index = 0; index <= 100; index++) { - memory_->SetData32(addr + index * 4, index * 0x10); - } - - ASSERT_TRUE(regs.StepIfSignalHandler(memory_)); - EXPECT_EQ(0x350U, regs[ARM_REG_SP]); - EXPECT_EQ(0x370U, regs[ARM_REG_PC]); - EXPECT_EQ(0x350U, regs.sp()); - EXPECT_EQ(0x370U, regs.pc()); -} - -TEST_F(RegsTest, arm_step_if_signal_handler_rt) { - // Form 1 - ArmStepIfSignalHandlerRt(0xe3a070ad); - - // Form 2 - ArmStepIfSignalHandlerRt(0xef9000ad); - - // Form 3 - ArmStepIfSignalHandlerRt(0xdf0027ad); -} - -TEST_F(RegsTest, arm64_step_if_signal_handler) { - uint64_t addr = 0x1000; - RegsArm64 regs; - regs[ARM64_REG_PC] = 0x8000; - regs[ARM64_REG_SP] = addr; - regs.SetFromRaw(); - - memory_->SetData64(0x8000, 0xd4000001d2801168ULL); - - for (uint64_t index = 0; index <= 100; index++) { - memory_->SetData64(addr + index * 8, index * 0x10); - } - - ASSERT_TRUE(regs.StepIfSignalHandler(memory_)); - EXPECT_EQ(0x460U, regs[ARM64_REG_SP]); - EXPECT_EQ(0x470U, regs[ARM64_REG_PC]); - EXPECT_EQ(0x460U, regs.sp()); - EXPECT_EQ(0x470U, regs.pc()); -} - -TEST_F(RegsTest, x86_step_if_signal_handler_no_siginfo) { - uint64_t addr = 0xa00; - RegsX86 regs; - regs[X86_REG_EIP] = 0x4100; - regs[X86_REG_ESP] = addr; - regs.SetFromRaw(); - - memory_->SetData64(0x4100, 0x80cd00000077b858ULL); - for (uint64_t index = 0; index <= 25; index++) { - memory_->SetData32(addr + index * 4, index * 0x10); - } - - ASSERT_TRUE(regs.StepIfSignalHandler(memory_)); - EXPECT_EQ(0x70U, regs[X86_REG_EBP]); - EXPECT_EQ(0x80U, regs[X86_REG_ESP]); - EXPECT_EQ(0x90U, regs[X86_REG_EBX]); - EXPECT_EQ(0xa0U, regs[X86_REG_EDX]); - EXPECT_EQ(0xb0U, regs[X86_REG_ECX]); - EXPECT_EQ(0xc0U, regs[X86_REG_EAX]); - EXPECT_EQ(0xf0U, regs[X86_REG_EIP]); - EXPECT_EQ(0x80U, regs.sp()); - EXPECT_EQ(0xf0U, regs.pc()); -} - -TEST_F(RegsTest, x86_step_if_signal_handler_siginfo) { - uint64_t addr = 0xa00; - RegsX86 regs; - regs[X86_REG_EIP] = 0x4100; - regs[X86_REG_ESP] = addr; - regs.SetFromRaw(); - - memory_->SetData64(0x4100, 0x0080cd000000adb8ULL); - addr += 8; - // Pointer to ucontext data. - memory_->SetData32(addr, 0x8100); - - addr = 0x8100; - for (uint64_t index = 0; index <= 30; index++) { - memory_->SetData32(addr + index * 4, index * 0x10); - } - - ASSERT_TRUE(regs.StepIfSignalHandler(memory_)); - EXPECT_EQ(0xb0U, regs[X86_REG_EBP]); - EXPECT_EQ(0xc0U, regs[X86_REG_ESP]); - EXPECT_EQ(0xd0U, regs[X86_REG_EBX]); - EXPECT_EQ(0xe0U, regs[X86_REG_EDX]); - EXPECT_EQ(0xf0U, regs[X86_REG_ECX]); - EXPECT_EQ(0x100U, regs[X86_REG_EAX]); - EXPECT_EQ(0x130U, regs[X86_REG_EIP]); - EXPECT_EQ(0xc0U, regs.sp()); - EXPECT_EQ(0x130U, regs.pc()); -} - -TEST_F(RegsTest, x86_64_step_if_signal_handler) { - uint64_t addr = 0x500; - RegsX86_64 regs; - regs[X86_64_REG_RIP] = 0x7000; - regs[X86_64_REG_RSP] = addr; - regs.SetFromRaw(); - - memory_->SetData64(0x7000, 0x0f0000000fc0c748); - memory_->SetData16(0x7008, 0x0f05); - - for (uint64_t index = 0; index <= 30; index++) { - memory_->SetData64(addr + index * 8, index * 0x10); - } - - ASSERT_TRUE(regs.StepIfSignalHandler(memory_)); - EXPECT_EQ(0x140U, regs[X86_64_REG_RSP]); - EXPECT_EQ(0x150U, regs[X86_64_REG_RIP]); - EXPECT_EQ(0x140U, regs.sp()); - EXPECT_EQ(0x150U, regs.pc()); -} - } // namespace unwindstack |