summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2018-04-20 11:51:14 -0700
committerJosh Gao <jmgao@google.com>2018-04-20 13:23:20 -0700
commit2f37a15472945194fed528cb8d3104aa4865fc4c (patch)
tree01fde5f19a6c4c2833fc2bc39bd0ad268fc4811f
parent22dc27b9fa46b20aca4f5982979681a858a97284 (diff)
downloadsystem_core-2f37a15472945194fed528cb8d3104aa4865fc4c.tar.gz
system_core-2f37a15472945194fed528cb8d3104aa4865fc4c.tar.bz2
system_core-2f37a15472945194fed528cb8d3104aa4865fc4c.zip
libunwindstack: add Regs::Clone.
Add a way to copy a Regs object. Bug: http://b/77296294 Test: libunwindstack_test Change-Id: I28aff510aa3e1b677d5ae46dc3bfe7652817ce52
-rw-r--r--libunwindstack/RegsArm.cpp4
-rw-r--r--libunwindstack/RegsArm64.cpp4
-rw-r--r--libunwindstack/RegsMips.cpp4
-rw-r--r--libunwindstack/RegsMips64.cpp4
-rw-r--r--libunwindstack/RegsX86.cpp4
-rw-r--r--libunwindstack/RegsX86_64.cpp4
-rw-r--r--libunwindstack/include/unwindstack/Regs.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsArm.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsArm64.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsMips.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsMips64.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsX86.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsX86_64.h2
-rw-r--r--libunwindstack/tests/RegsFake.h4
-rw-r--r--libunwindstack/tests/RegsTest.cpp35
15 files changed, 77 insertions, 0 deletions
diff --git a/libunwindstack/RegsArm.cpp b/libunwindstack/RegsArm.cpp
index 27cab4384..de22bdea9 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 4a2a6c4db..a68f6e04a 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 c87e69b90..2e6908c26 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 236a9223b..0b835a152 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 f7e06145e..9bb39d10e 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 7d6ad86cf..ebad3f421 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 4bac47313..878ced30c 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 31e6797fa..44f67443f 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 0c45ebab8..a72f91ff2 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 709f9e2c7..c9dd202aa 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 1de83ea9d..7c42812b7 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 586c9d85c..d19e4499b 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 061f479a0..dc9a220c3 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 ede16b32b..d6ca9b7b5 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 d15823e1c..90c3fe619 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(&register_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