Make GetPcAdjustment a free function.
We're now using it in contexts that don't have all of the registers available, such as GWP-ASan and soon MTE, so it doesn't make sense to have it be a member function of Regs. Bug: 135772972 Change-Id: I18b104ea0adb78588d7e475d0624cefc701ba52c
This commit is contained in:
parent
3ab681c9a8
commit
5ac3927878
|
@ -172,15 +172,12 @@ static unwindstack::FrameData BuildFrame(unwindstack::Unwinder* unwinder, uintpt
|
|||
return frame;
|
||||
}
|
||||
|
||||
unwindstack::Elf* elf =
|
||||
map_info->GetElf(unwinder->GetProcessMemory(), unwindstack::Regs::CurrentArch());
|
||||
unwindstack::ArchEnum arch = unwindstack::Regs::CurrentArch();
|
||||
unwindstack::Elf* elf = map_info->GetElf(unwinder->GetProcessMemory(), arch);
|
||||
|
||||
uint64_t relative_pc = elf->GetRelPc(pc, map_info);
|
||||
|
||||
// Create registers just to get PC adjustment. Doesn't matter what they point
|
||||
// to.
|
||||
unwindstack::Regs* regs = unwindstack::Regs::CreateFromLocal();
|
||||
uint64_t pc_adjustment = regs->GetPcAdjustment(relative_pc, elf);
|
||||
uint64_t pc_adjustment = unwindstack::GetPcAdjustment(relative_pc, elf, arch);
|
||||
relative_pc -= pc_adjustment;
|
||||
// The debug PC may be different if the PC comes from the JIT.
|
||||
uint64_t debug_pc = relative_pc;
|
||||
|
|
|
@ -106,7 +106,7 @@ bool LocalUnwinder::Unwind(std::vector<LocalFrameData>* frame_info, size_t max_f
|
|||
uint64_t step_pc = rel_pc;
|
||||
uint64_t pc_adjustment;
|
||||
if (adjust_pc) {
|
||||
pc_adjustment = regs->GetPcAdjustment(rel_pc, elf);
|
||||
pc_adjustment = GetPcAdjustment(rel_pc, elf, arch);
|
||||
} else {
|
||||
pc_adjustment = 0;
|
||||
}
|
||||
|
|
|
@ -121,4 +121,62 @@ Regs* Regs::CreateFromLocal() {
|
|||
return regs;
|
||||
}
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch) {
|
||||
switch (arch) {
|
||||
case ARCH_ARM: {
|
||||
if (!elf->valid()) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint64_t load_bias = elf->GetLoadBias();
|
||||
if (rel_pc < load_bias) {
|
||||
if (rel_pc < 2) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
uint64_t adjusted_rel_pc = rel_pc - load_bias;
|
||||
if (adjusted_rel_pc < 5) {
|
||||
if (adjusted_rel_pc < 2) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (adjusted_rel_pc & 1) {
|
||||
// This is a thumb instruction, it could be 2 or 4 bytes.
|
||||
uint32_t value;
|
||||
if (!elf->memory()->ReadFully(adjusted_rel_pc - 5, &value, sizeof(value)) ||
|
||||
(value & 0xe000f000) != 0xe000f000) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
case ARCH_ARM64: {
|
||||
if (rel_pc < 4) {
|
||||
return 0;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
case ARCH_MIPS:
|
||||
case ARCH_MIPS64: {
|
||||
if (rel_pc < 8) {
|
||||
return 0;
|
||||
}
|
||||
// For now, just assume no compact branches
|
||||
return 8;
|
||||
}
|
||||
case ARCH_X86:
|
||||
case ARCH_X86_64: {
|
||||
if (rel_pc == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case ARCH_UNKNOWN:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace unwindstack
|
||||
|
|
|
@ -51,37 +51,6 @@ void RegsArm::set_sp(uint64_t sp) {
|
|||
regs_[ARM_REG_SP] = sp;
|
||||
}
|
||||
|
||||
uint64_t RegsArm::GetPcAdjustment(uint64_t rel_pc, Elf* elf) {
|
||||
if (!elf->valid()) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint64_t load_bias = elf->GetLoadBias();
|
||||
if (rel_pc < load_bias) {
|
||||
if (rel_pc < 2) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
uint64_t adjusted_rel_pc = rel_pc - load_bias;
|
||||
if (adjusted_rel_pc < 5) {
|
||||
if (adjusted_rel_pc < 2) {
|
||||
return 0;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (adjusted_rel_pc & 1) {
|
||||
// This is a thumb instruction, it could be 2 or 4 bytes.
|
||||
uint32_t value;
|
||||
if (!elf->memory()->ReadFully(adjusted_rel_pc - 5, &value, sizeof(value)) ||
|
||||
(value & 0xe000f000) != 0xe000f000) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool RegsArm::SetPcFromReturnAddress(Memory*) {
|
||||
uint32_t lr = regs_[ARM_REG_LR];
|
||||
if (regs_[ARM_REG_PC] == lr) {
|
||||
|
|
|
@ -52,13 +52,6 @@ void RegsArm64::set_sp(uint64_t sp) {
|
|||
regs_[ARM64_REG_SP] = sp;
|
||||
}
|
||||
|
||||
uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf*) {
|
||||
if (rel_pc < 4) {
|
||||
return 0;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool RegsArm64::SetPcFromReturnAddress(Memory*) {
|
||||
uint64_t lr = regs_[ARM64_REG_LR];
|
||||
if (regs_[ARM64_REG_PC] == lr) {
|
||||
|
|
|
@ -52,14 +52,6 @@ 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*) {
|
||||
if (rel_pc < 8) {
|
||||
return 0;
|
||||
}
|
||||
// For now, just assume no compact branches
|
||||
return 8;
|
||||
}
|
||||
|
||||
bool RegsMips::SetPcFromReturnAddress(Memory*) {
|
||||
uint32_t ra = regs_[MIPS_REG_RA];
|
||||
if (regs_[MIPS_REG_PC] == ra) {
|
||||
|
|
|
@ -52,14 +52,6 @@ void RegsMips64::set_sp(uint64_t sp) {
|
|||
regs_[MIPS64_REG_SP] = sp;
|
||||
}
|
||||
|
||||
uint64_t RegsMips64::GetPcAdjustment(uint64_t rel_pc, Elf*) {
|
||||
if (rel_pc < 8) {
|
||||
return 0;
|
||||
}
|
||||
// For now, just assume no compact branches
|
||||
return 8;
|
||||
}
|
||||
|
||||
bool RegsMips64::SetPcFromReturnAddress(Memory*) {
|
||||
uint64_t ra = regs_[MIPS64_REG_RA];
|
||||
if (regs_[MIPS64_REG_PC] == ra) {
|
||||
|
|
|
@ -50,13 +50,6 @@ 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*) {
|
||||
if (rel_pc == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool RegsX86::SetPcFromReturnAddress(Memory* process_memory) {
|
||||
// Attempt to get the return address from the top of the stack.
|
||||
uint32_t new_pc;
|
||||
|
|
|
@ -51,13 +51,6 @@ void RegsX86_64::set_sp(uint64_t sp) {
|
|||
regs_[X86_64_REG_SP] = sp;
|
||||
}
|
||||
|
||||
uint64_t RegsX86_64::GetPcAdjustment(uint64_t rel_pc, Elf*) {
|
||||
if (rel_pc == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool RegsX86_64::SetPcFromReturnAddress(Memory* process_memory) {
|
||||
// Attempt to get the return address from the top of the stack.
|
||||
uint64_t new_pc;
|
||||
|
|
|
@ -181,7 +181,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
|
|||
step_pc = rel_pc;
|
||||
}
|
||||
if (adjust_pc) {
|
||||
pc_adjustment = regs_->GetPcAdjustment(rel_pc, elf);
|
||||
pc_adjustment = GetPcAdjustment(rel_pc, elf, arch);
|
||||
} else {
|
||||
pc_adjustment = 0;
|
||||
}
|
||||
|
|
|
@ -64,8 +64,6 @@ class Regs {
|
|||
uint64_t dex_pc() { return dex_pc_; }
|
||||
void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; }
|
||||
|
||||
virtual uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) = 0;
|
||||
|
||||
virtual bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) = 0;
|
||||
|
||||
virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0;
|
||||
|
@ -110,6 +108,8 @@ class RegsImpl : public Regs {
|
|||
std::vector<AddressType> regs_;
|
||||
};
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch);
|
||||
|
||||
} // namespace unwindstack
|
||||
|
||||
#endif // _LIBUNWINDSTACK_REGS_H
|
||||
|
|
|
@ -36,8 +36,6 @@ class RegsArm : public RegsImpl<uint32_t> {
|
|||
|
||||
ArchEnum Arch() override final;
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override;
|
||||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
|
|
@ -36,8 +36,6 @@ class RegsArm64 : public RegsImpl<uint64_t> {
|
|||
|
||||
ArchEnum Arch() override final;
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override;
|
||||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
|
|
@ -36,8 +36,6 @@ class RegsMips : public RegsImpl<uint32_t> {
|
|||
|
||||
ArchEnum Arch() override final;
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override;
|
||||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
|
|
@ -36,8 +36,6 @@ class RegsMips64 : public RegsImpl<uint64_t> {
|
|||
|
||||
ArchEnum Arch() override final;
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override;
|
||||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
|
|
@ -37,8 +37,6 @@ class RegsX86 : public RegsImpl<uint32_t> {
|
|||
|
||||
ArchEnum Arch() override final;
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override;
|
||||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
|
|
@ -37,8 +37,6 @@ class RegsX86_64 : public RegsImpl<uint64_t> {
|
|||
|
||||
ArchEnum Arch() override final;
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) override;
|
||||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
|
|
@ -54,8 +54,6 @@ class RegsFake : public Regs {
|
|||
return fake_arch_ == ARCH_ARM || fake_arch_ == ARCH_X86 || fake_arch_ == ARCH_MIPS;
|
||||
}
|
||||
|
||||
uint64_t GetPcAdjustment(uint64_t, Elf*) override { return 2; }
|
||||
|
||||
bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
|
||||
|
||||
void FakeSetArch(ArchEnum arch) { fake_arch_ = arch; }
|
||||
|
@ -86,7 +84,6 @@ class RegsImplFake : public RegsImpl<TypeParam> {
|
|||
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; }
|
||||
bool SetPcFromReturnAddress(Memory*) override { return false; }
|
||||
bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
|
||||
|
||||
|
|
|
@ -93,123 +93,104 @@ TEST_F(RegsTest, regs64) {
|
|||
}
|
||||
|
||||
TEST_F(RegsTest, rel_pc) {
|
||||
RegsArm64 arm64;
|
||||
EXPECT_EQ(4U, arm64.GetPcAdjustment(0x10, elf_.get()));
|
||||
EXPECT_EQ(4U, arm64.GetPcAdjustment(0x4, elf_.get()));
|
||||
EXPECT_EQ(0U, arm64.GetPcAdjustment(0x3, elf_.get()));
|
||||
EXPECT_EQ(0U, arm64.GetPcAdjustment(0x2, elf_.get()));
|
||||
EXPECT_EQ(0U, arm64.GetPcAdjustment(0x1, elf_.get()));
|
||||
EXPECT_EQ(0U, arm64.GetPcAdjustment(0x0, elf_.get()));
|
||||
EXPECT_EQ(4U, GetPcAdjustment(0x10, elf_.get(), ARCH_ARM64));
|
||||
EXPECT_EQ(4U, GetPcAdjustment(0x4, elf_.get(), ARCH_ARM64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x3, elf_.get(), ARCH_ARM64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x2, elf_.get(), ARCH_ARM64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x1, elf_.get(), ARCH_ARM64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x0, elf_.get(), ARCH_ARM64));
|
||||
|
||||
RegsX86 x86;
|
||||
EXPECT_EQ(1U, x86.GetPcAdjustment(0x100, elf_.get()));
|
||||
EXPECT_EQ(1U, x86.GetPcAdjustment(0x2, elf_.get()));
|
||||
EXPECT_EQ(1U, x86.GetPcAdjustment(0x1, elf_.get()));
|
||||
EXPECT_EQ(0U, x86.GetPcAdjustment(0x0, elf_.get()));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x100, elf_.get(), ARCH_X86));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x2, elf_.get(), ARCH_X86));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x1, elf_.get(), ARCH_X86));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x0, elf_.get(), ARCH_X86));
|
||||
|
||||
RegsX86_64 x86_64;
|
||||
EXPECT_EQ(1U, x86_64.GetPcAdjustment(0x100, elf_.get()));
|
||||
EXPECT_EQ(1U, x86_64.GetPcAdjustment(0x2, elf_.get()));
|
||||
EXPECT_EQ(1U, x86_64.GetPcAdjustment(0x1, elf_.get()));
|
||||
EXPECT_EQ(0U, x86_64.GetPcAdjustment(0x0, elf_.get()));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x100, elf_.get(), ARCH_X86_64));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x2, elf_.get(), ARCH_X86_64));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x1, elf_.get(), ARCH_X86_64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x0, elf_.get(), ARCH_X86_64));
|
||||
|
||||
RegsMips mips;
|
||||
EXPECT_EQ(8U, mips.GetPcAdjustment(0x10, elf_.get()));
|
||||
EXPECT_EQ(8U, mips.GetPcAdjustment(0x8, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x7, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x6, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x5, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x4, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x3, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x2, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x1, elf_.get()));
|
||||
EXPECT_EQ(0U, mips.GetPcAdjustment(0x0, elf_.get()));
|
||||
EXPECT_EQ(8U, GetPcAdjustment(0x10, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(8U, GetPcAdjustment(0x8, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x7, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x6, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x5, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x4, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x3, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x2, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x1, elf_.get(), ARCH_MIPS));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x0, elf_.get(), ARCH_MIPS));
|
||||
|
||||
RegsMips64 mips64;
|
||||
EXPECT_EQ(8U, mips64.GetPcAdjustment(0x10, elf_.get()));
|
||||
EXPECT_EQ(8U, mips64.GetPcAdjustment(0x8, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x7, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x6, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x5, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x4, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x3, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x2, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x1, elf_.get()));
|
||||
EXPECT_EQ(0U, mips64.GetPcAdjustment(0x0, elf_.get()));
|
||||
EXPECT_EQ(8U, GetPcAdjustment(0x10, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(8U, GetPcAdjustment(0x8, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x7, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x6, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x5, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x4, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x3, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x2, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x1, elf_.get(), ARCH_MIPS64));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x0, elf_.get(), ARCH_MIPS64));
|
||||
}
|
||||
|
||||
TEST_F(RegsTest, rel_pc_arm) {
|
||||
RegsArm arm;
|
||||
|
||||
// Check fence posts.
|
||||
elf_->FakeSetLoadBias(0);
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x5, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x4, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x3, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x2, elf_.get()));
|
||||
EXPECT_EQ(0U, arm.GetPcAdjustment(0x1, elf_.get()));
|
||||
EXPECT_EQ(0U, arm.GetPcAdjustment(0x0, elf_.get()));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x5, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x4, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x3, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x2, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x1, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x0, elf_.get(), ARCH_ARM));
|
||||
|
||||
elf_->FakeSetLoadBias(0x100);
|
||||
EXPECT_EQ(0U, arm.GetPcAdjustment(0x1, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x2, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0xff, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x105, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x104, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x103, elf_.get()));
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x102, elf_.get()));
|
||||
EXPECT_EQ(0U, arm.GetPcAdjustment(0x101, elf_.get()));
|
||||
EXPECT_EQ(0U, arm.GetPcAdjustment(0x100, elf_.get()));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x1, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x2, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0xff, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x105, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x104, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x103, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x102, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x101, elf_.get(), ARCH_ARM));
|
||||
EXPECT_EQ(0U, GetPcAdjustment(0x100, elf_.get(), ARCH_ARM));
|
||||
|
||||
// Check thumb instructions handling.
|
||||
elf_->FakeSetLoadBias(0);
|
||||
memory_->SetData32(0x2000, 0);
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x2005, elf_.get()));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x2005, elf_.get(), ARCH_ARM));
|
||||
memory_->SetData32(0x2000, 0xe000f000);
|
||||
EXPECT_EQ(4U, arm.GetPcAdjustment(0x2005, elf_.get()));
|
||||
EXPECT_EQ(4U, GetPcAdjustment(0x2005, elf_.get(), ARCH_ARM));
|
||||
|
||||
elf_->FakeSetLoadBias(0x400);
|
||||
memory_->SetData32(0x2100, 0);
|
||||
EXPECT_EQ(2U, arm.GetPcAdjustment(0x2505, elf_.get()));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x2505, elf_.get(), ARCH_ARM));
|
||||
memory_->SetData32(0x2100, 0xf111f111);
|
||||
EXPECT_EQ(4U, arm.GetPcAdjustment(0x2505, elf_.get()));
|
||||
EXPECT_EQ(4U, GetPcAdjustment(0x2505, elf_.get(), ARCH_ARM));
|
||||
}
|
||||
|
||||
TEST_F(RegsTest, elf_invalid) {
|
||||
RegsArm regs_arm;
|
||||
RegsArm64 regs_arm64;
|
||||
RegsX86 regs_x86;
|
||||
RegsX86_64 regs_x86_64;
|
||||
RegsMips regs_mips;
|
||||
RegsMips64 regs_mips64;
|
||||
MapInfo map_info(nullptr, nullptr, 0x1000, 0x2000, 0, 0, "");
|
||||
Elf* invalid_elf = new Elf(nullptr);
|
||||
map_info.elf.reset(invalid_elf);
|
||||
|
||||
regs_arm.set_pc(0x1500);
|
||||
EXPECT_EQ(0x500U, invalid_elf->GetRelPc(regs_arm.pc(), &map_info));
|
||||
EXPECT_EQ(2U, regs_arm.GetPcAdjustment(0x500U, invalid_elf));
|
||||
EXPECT_EQ(2U, regs_arm.GetPcAdjustment(0x511U, invalid_elf));
|
||||
EXPECT_EQ(0x500U, invalid_elf->GetRelPc(0x1500, &map_info));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x500U, invalid_elf, ARCH_ARM));
|
||||
EXPECT_EQ(2U, GetPcAdjustment(0x511U, invalid_elf, ARCH_ARM));
|
||||
|
||||
regs_arm64.set_pc(0x1600);
|
||||
EXPECT_EQ(0x600U, invalid_elf->GetRelPc(regs_arm64.pc(), &map_info));
|
||||
EXPECT_EQ(4U, regs_arm64.GetPcAdjustment(0x600U, invalid_elf));
|
||||
EXPECT_EQ(0x600U, invalid_elf->GetRelPc(0x1600, &map_info));
|
||||
EXPECT_EQ(4U, GetPcAdjustment(0x600U, invalid_elf, ARCH_ARM64));
|
||||
|
||||
regs_x86.set_pc(0x1700);
|
||||
EXPECT_EQ(0x700U, invalid_elf->GetRelPc(regs_x86.pc(), &map_info));
|
||||
EXPECT_EQ(1U, regs_x86.GetPcAdjustment(0x700U, invalid_elf));
|
||||
EXPECT_EQ(0x700U, invalid_elf->GetRelPc(0x1700, &map_info));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x700U, invalid_elf, ARCH_X86));
|
||||
|
||||
regs_x86_64.set_pc(0x1800);
|
||||
EXPECT_EQ(0x800U, invalid_elf->GetRelPc(regs_x86_64.pc(), &map_info));
|
||||
EXPECT_EQ(1U, regs_x86_64.GetPcAdjustment(0x800U, invalid_elf));
|
||||
EXPECT_EQ(0x800U, invalid_elf->GetRelPc(0x1800, &map_info));
|
||||
EXPECT_EQ(1U, GetPcAdjustment(0x800U, invalid_elf, ARCH_X86_64));
|
||||
|
||||
regs_mips.set_pc(0x1900);
|
||||
EXPECT_EQ(0x900U, invalid_elf->GetRelPc(regs_mips.pc(), &map_info));
|
||||
EXPECT_EQ(8U, regs_mips.GetPcAdjustment(0x900U, invalid_elf));
|
||||
EXPECT_EQ(0x900U, invalid_elf->GetRelPc(0x1900, &map_info));
|
||||
EXPECT_EQ(8U, GetPcAdjustment(0x900U, invalid_elf, ARCH_MIPS));
|
||||
|
||||
regs_mips64.set_pc(0x1a00);
|
||||
EXPECT_EQ(0xa00U, invalid_elf->GetRelPc(regs_mips64.pc(), &map_info));
|
||||
EXPECT_EQ(8U, regs_mips64.GetPcAdjustment(0xa00U, invalid_elf));
|
||||
EXPECT_EQ(0xa00U, invalid_elf->GetRelPc(0x1a00, &map_info));
|
||||
EXPECT_EQ(8U, GetPcAdjustment(0xa00U, invalid_elf, ARCH_MIPS64));
|
||||
}
|
||||
|
||||
TEST_F(RegsTest, arm_verify_sp_pc) {
|
||||
|
|
|
@ -161,8 +161,8 @@ TEST_F(UnwinderTest, multiple_frames) {
|
|||
|
||||
regs_.set_pc(0x1000);
|
||||
regs_.set_sp(0x10000);
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
@ -225,8 +225,8 @@ TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
|
|||
|
||||
regs_.set_pc(0x1000);
|
||||
regs_.set_sp(0x10000);
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
@ -445,7 +445,7 @@ TEST_F(UnwinderTest, no_frames_after_finished) {
|
|||
TEST_F(UnwinderTest, max_frames) {
|
||||
for (size_t i = 0; i < 30; i++) {
|
||||
ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1104 + i * 0x100, 0x10010 + i * 0x10, false));
|
||||
}
|
||||
|
||||
regs_.set_pc(0x1000);
|
||||
|
@ -484,12 +484,12 @@ TEST_F(UnwinderTest, verify_frames_skipped) {
|
|||
|
||||
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));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x23004, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x20004, 0x10030, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10040, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10060, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
|
@ -553,7 +553,7 @@ TEST_F(UnwinderTest, sp_not_in_map) {
|
|||
|
||||
regs_.set_pc(0x1000);
|
||||
regs_.set_sp(0x63000);
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x50020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
@ -670,10 +670,10 @@ TEST_F(UnwinderTest, speculative_frame) {
|
|||
// Fake as if code called a nullptr function.
|
||||
regs_.set_pc(0);
|
||||
regs_.set_sp(0x10000);
|
||||
regs_.FakeSetReturnAddress(0x1202);
|
||||
regs_.FakeSetReturnAddress(0x1204);
|
||||
regs_.FakeSetReturnAddressValid(true);
|
||||
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
@ -789,7 +789,7 @@ TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
|
|||
// Fake as if code called a nullptr function.
|
||||
regs_.set_pc(0);
|
||||
regs_.set_sp(0x10000);
|
||||
regs_.FakeSetReturnAddress(0x1202);
|
||||
regs_.FakeSetReturnAddress(0x1204);
|
||||
regs_.FakeSetReturnAddressValid(true);
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
@ -858,8 +858,8 @@ TEST_F(UnwinderTest, map_ignore_suffixes) {
|
|||
// Fake as if code called a nullptr function.
|
||||
regs_.set_pc(0x1000);
|
||||
regs_.set_sp(0x10000);
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x43404, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x53504, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
@ -915,11 +915,11 @@ TEST_F(UnwinderTest, sp_pc_do_not_change) {
|
|||
|
||||
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));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
@ -1113,7 +1113,7 @@ TEST_F(UnwinderTest, dex_pc_multiple_frames) {
|
|||
regs_.set_pc(0x1000);
|
||||
regs_.set_sp(0x10000);
|
||||
regs_.FakeSetDexPc(0xa3400);
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
|
||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||
|
||||
Unwinder unwinder(64, maps_.get(), ®s_, process_memory_);
|
||||
|
|
Loading…
Reference in New Issue