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:
Peter Collingbourne 2020-03-19 17:27:58 -07:00
parent 3ab681c9a8
commit 5ac3927878
20 changed files with 153 additions and 200 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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; }

View File

@ -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) {

View File

@ -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(), &regs_, 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(), &regs_, 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(), &regs_, 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(), &regs_, 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(), &regs_, 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(), &regs_, 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(), &regs_, 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(), &regs_, process_memory_);