diff options
author | Josh Gao <jmgao@google.com> | 2018-04-20 11:51:14 -0700 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2018-04-23 12:11:38 -0700 |
commit | c5b4bea2c6797bc21910ff66067952e07bf3598f (patch) | |
tree | ce04da40ab1934aec496580872432237e1791832 | |
parent | 9ec39228b009924647be3ab7c9a0de1394e0b62f (diff) | |
download | unwinding-c5b4bea2c6797bc21910ff66067952e07bf3598f.tar.gz |
libunwindstack: add Regs::Clone.
Add a way to copy a Regs object.
Bug: http://b/77296294
Test: libunwindstack_test
Change-Id: I28aff510aa3e1b677d5ae46dc3bfe7652817ce52
(cherry picked from commit 2f37a15472945194fed528cb8d3104aa4865fc4c)
-rw-r--r-- | libunwindstack/RegsArm.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsArm64.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsMips.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsMips64.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsX86.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsX86_64.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/Regs.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsArm.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsArm64.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsMips.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsMips64.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsX86.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsX86_64.h | 2 | ||||
-rw-r--r-- | libunwindstack/tests/RegsFake.h | 4 | ||||
-rw-r--r-- | libunwindstack/tests/RegsTest.cpp | 35 |
15 files changed, 77 insertions, 0 deletions
diff --git a/libunwindstack/RegsArm.cpp b/libunwindstack/RegsArm.cpp index 27cab43..de22bde 100644 --- a/libunwindstack/RegsArm.cpp +++ b/libunwindstack/RegsArm.cpp @@ -197,4 +197,8 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem return true; } +Regs* RegsArm::Clone() { + return new RegsArm(*this); +} + } // namespace unwindstack diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp index 4a2a6c4..a68f6e0 100644 --- a/libunwindstack/RegsArm64.cpp +++ b/libunwindstack/RegsArm64.cpp @@ -148,4 +148,8 @@ bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_m return true; } +Regs* RegsArm64::Clone() { + return new RegsArm64(*this); +} + } // namespace unwindstack diff --git a/libunwindstack/RegsMips.cpp b/libunwindstack/RegsMips.cpp index c87e69b..2e6908c 100644 --- a/libunwindstack/RegsMips.cpp +++ b/libunwindstack/RegsMips.cpp @@ -173,4 +173,8 @@ bool RegsMips::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_me return true; } +Regs* RegsMips::Clone() { + return new RegsMips(*this); +} + } // namespace unwindstack diff --git a/libunwindstack/RegsMips64.cpp b/libunwindstack/RegsMips64.cpp index 236a922..0b835a1 100644 --- a/libunwindstack/RegsMips64.cpp +++ b/libunwindstack/RegsMips64.cpp @@ -160,4 +160,8 @@ bool RegsMips64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_ return true; } +Regs* RegsMips64::Clone() { + return new RegsMips64(*this); +} + } // namespace unwindstack diff --git a/libunwindstack/RegsX86.cpp b/libunwindstack/RegsX86.cpp index f7e0614..9bb39d1 100644 --- a/libunwindstack/RegsX86.cpp +++ b/libunwindstack/RegsX86.cpp @@ -179,4 +179,8 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem return false; } +Regs* RegsX86::Clone() { + return new RegsX86(*this); +} + } // namespace unwindstack diff --git a/libunwindstack/RegsX86_64.cpp b/libunwindstack/RegsX86_64.cpp index 7d6ad86..ebad3f4 100644 --- a/libunwindstack/RegsX86_64.cpp +++ b/libunwindstack/RegsX86_64.cpp @@ -168,4 +168,8 @@ bool RegsX86_64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_ return true; } +Regs* RegsX86_64::Clone() { + return new RegsX86_64(*this); +} + } // namespace unwindstack diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h index 4bac473..878ced3 100644 --- a/libunwindstack/include/unwindstack/Regs.h +++ b/libunwindstack/include/unwindstack/Regs.h @@ -73,6 +73,8 @@ class Regs { uint16_t total_regs() { return total_regs_; } + virtual Regs* Clone() = 0; + static ArchEnum CurrentArch(); static Regs* RemoteGet(pid_t pid); static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext); diff --git a/libunwindstack/include/unwindstack/RegsArm.h b/libunwindstack/include/unwindstack/RegsArm.h index 31e6797..44f6744 100644 --- a/libunwindstack/include/unwindstack/RegsArm.h +++ b/libunwindstack/include/unwindstack/RegsArm.h @@ -50,6 +50,8 @@ class RegsArm : public RegsImpl<uint32_t> { void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; + Regs* Clone() override final; + static Regs* Read(void* data); static Regs* CreateFromUcontext(void* ucontext); diff --git a/libunwindstack/include/unwindstack/RegsArm64.h b/libunwindstack/include/unwindstack/RegsArm64.h index 0c45eba..a72f91f 100644 --- a/libunwindstack/include/unwindstack/RegsArm64.h +++ b/libunwindstack/include/unwindstack/RegsArm64.h @@ -50,6 +50,8 @@ class RegsArm64 : public RegsImpl<uint64_t> { void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; + Regs* Clone() override final; + static Regs* Read(void* data); static Regs* CreateFromUcontext(void* ucontext); diff --git a/libunwindstack/include/unwindstack/RegsMips.h b/libunwindstack/include/unwindstack/RegsMips.h index 709f9e2..c9dd202 100644 --- a/libunwindstack/include/unwindstack/RegsMips.h +++ b/libunwindstack/include/unwindstack/RegsMips.h @@ -50,6 +50,8 @@ class RegsMips : public RegsImpl<uint32_t> { void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; + Regs* Clone() override final; + static Regs* Read(void* data); static Regs* CreateFromUcontext(void* ucontext); diff --git a/libunwindstack/include/unwindstack/RegsMips64.h b/libunwindstack/include/unwindstack/RegsMips64.h index 1de83ea..7c42812 100644 --- a/libunwindstack/include/unwindstack/RegsMips64.h +++ b/libunwindstack/include/unwindstack/RegsMips64.h @@ -50,6 +50,8 @@ class RegsMips64 : public RegsImpl<uint64_t> { void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; + Regs* Clone() override final; + static Regs* Read(void* data); static Regs* CreateFromUcontext(void* ucontext); diff --git a/libunwindstack/include/unwindstack/RegsX86.h b/libunwindstack/include/unwindstack/RegsX86.h index 586c9d8..d19e449 100644 --- a/libunwindstack/include/unwindstack/RegsX86.h +++ b/libunwindstack/include/unwindstack/RegsX86.h @@ -53,6 +53,8 @@ class RegsX86 : public RegsImpl<uint32_t> { void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; + Regs* Clone() override final; + static Regs* Read(void* data); static Regs* CreateFromUcontext(void* ucontext); diff --git a/libunwindstack/include/unwindstack/RegsX86_64.h b/libunwindstack/include/unwindstack/RegsX86_64.h index 061f479..dc9a220 100644 --- a/libunwindstack/include/unwindstack/RegsX86_64.h +++ b/libunwindstack/include/unwindstack/RegsX86_64.h @@ -53,6 +53,8 @@ class RegsX86_64 : public RegsImpl<uint64_t> { void set_pc(uint64_t pc) override; void set_sp(uint64_t sp) override; + Regs* Clone() override final; + static Regs* Read(void* data); static Regs* CreateFromUcontext(void* ucontext); diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h index ede16b3..d6ca9b7 100644 --- a/libunwindstack/tests/RegsFake.h +++ b/libunwindstack/tests/RegsFake.h @@ -58,6 +58,8 @@ class RegsFake : public Regs { void FakeSetReturnAddress(uint64_t return_address) { fake_return_address_ = return_address; } void FakeSetReturnAddressValid(bool valid) { fake_return_address_valid_ = valid; } + Regs* Clone() override { return nullptr; } + private: ArchEnum fake_arch_ = ARCH_UNKNOWN; uint64_t fake_pc_ = 0; @@ -83,6 +85,8 @@ class RegsImplFake : public RegsImpl<TypeParam> { bool SetPcFromReturnAddress(Memory*) override { return false; } bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } + Regs* Clone() override { return nullptr; } + private: uint64_t fake_pc_ = 0; uint64_t fake_sp_ = 0; diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp index d15823e..90c3fe6 100644 --- a/libunwindstack/tests/RegsTest.cpp +++ b/libunwindstack/tests/RegsTest.cpp @@ -286,4 +286,39 @@ TEST_F(RegsTest, machine_type) { EXPECT_EQ(ARCH_MIPS64, mips64_regs.Arch()); } +template <typename RegisterType> +void clone_test(Regs* regs) { + RegisterType* register_values = reinterpret_cast<RegisterType*>(regs->RawData()); + int num_regs = regs->total_regs(); + for (int i = 0; i < num_regs; ++i) { + register_values[i] = i; + } + + std::unique_ptr<Regs> clone(regs->Clone()); + ASSERT_EQ(regs->total_regs(), clone->total_regs()); + RegisterType* clone_values = reinterpret_cast<RegisterType*>(clone->RawData()); + for (int i = 0; i < num_regs; ++i) { + EXPECT_EQ(register_values[i], clone_values[i]); + EXPECT_NE(®ister_values[i], &clone_values[i]); + } +} + +TEST_F(RegsTest, clone) { + std::vector<std::unique_ptr<Regs>> regs; + regs.emplace_back(new RegsArm()); + regs.emplace_back(new RegsArm64()); + regs.emplace_back(new RegsX86()); + regs.emplace_back(new RegsX86_64()); + regs.emplace_back(new RegsMips()); + regs.emplace_back(new RegsMips64()); + + for (auto& r : regs) { + if (r->Is32Bit()) { + clone_test<uint32_t>(r.get()); + } else { + clone_test<uint64_t>(r.get()); + } + } +} + } // namespace unwindstack |