If the pc is set to zero, the unwind is done.
Bug: 68047085 Test: Ran new unit tests, verified new unwinder does not show an Test: extra pc zero frame for arm 32 bit processes. Change-Id: Ic6532e56fbb786a8b7d41638abae777c2d0f1d59
This commit is contained in:
parent
26b614ddf6
commit
2502a60ea1
|
@ -225,11 +225,13 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
|
|||
// Find the return address location.
|
||||
if (return_address_undefined) {
|
||||
cur_regs->set_pc(0);
|
||||
*finished = true;
|
||||
} else {
|
||||
cur_regs->set_pc((*cur_regs)[cie->return_address_register]);
|
||||
*finished = false;
|
||||
}
|
||||
|
||||
// If the pc was set to zero, consider this the final frame.
|
||||
*finished = (cur_regs->pc() == 0) ? true : false;
|
||||
|
||||
cur_regs->set_sp(cfa);
|
||||
// Return false if the unwind is not finished or the cfa and pc didn't change.
|
||||
return *finished || prev_cfa != cfa || prev_pc != cur_regs->pc();
|
||||
|
|
|
@ -121,8 +121,10 @@ bool ElfInterfaceArm::StepExidx(uint64_t pc, Regs* regs, Memory* process_memory,
|
|||
}
|
||||
regs_arm->set_sp(arm.cfa());
|
||||
(*regs_arm)[ARM_REG_SP] = regs_arm->sp();
|
||||
*finished = false;
|
||||
return_value = true;
|
||||
|
||||
// If the pc was set to zero, consider this the final frame.
|
||||
*finished = (regs_arm->pc() == 0) ? true : false;
|
||||
}
|
||||
|
||||
if (arm.status() == ARM_STATUS_NO_UNWIND) {
|
||||
|
|
|
@ -340,6 +340,23 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) {
|
|||
EXPECT_EQ(0x10U, regs.sp());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) {
|
||||
DwarfCie cie{.return_address_register = 5};
|
||||
RegsImplFake<TypeParam> regs(10, 9);
|
||||
dwarf_loc_regs_t loc_regs;
|
||||
|
||||
regs.set_pc(0x100);
|
||||
regs.set_sp(0x2000);
|
||||
regs[5] = 0;
|
||||
regs[8] = 0x10;
|
||||
loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
|
||||
bool finished;
|
||||
ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
|
||||
EXPECT_TRUE(finished);
|
||||
EXPECT_EQ(0U, regs.pc());
|
||||
EXPECT_EQ(0x10U, regs.sp());
|
||||
}
|
||||
|
||||
TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) {
|
||||
DwarfCie cie{.return_address_register = 5};
|
||||
RegsImplFake<TypeParam> regs(10, 9);
|
||||
|
@ -854,7 +871,7 @@ REGISTER_TYPED_TEST_CASE_P(
|
|||
Eval_cfa_expr_is_register, Eval_cfa_expr, Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa,
|
||||
Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection,
|
||||
Eval_invalid_register, Eval_different_reg_locations, Eval_return_address_undefined,
|
||||
Eval_return_address, Eval_ignore_large_reg_loc, Eval_reg_expr, Eval_reg_val_expr,
|
||||
Eval_pc_zero, Eval_return_address, Eval_ignore_large_reg_loc, Eval_reg_expr, Eval_reg_val_expr,
|
||||
Eval_same_cfa_same_pc, GetCie_fail_should_not_cache, GetCie_32_version_check,
|
||||
GetCie_negative_data_alignment_factor, GetCie_64_no_augment, GetCie_augment, GetCie_version_3,
|
||||
GetCie_version_4, GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
|
||||
|
|
|
@ -401,4 +401,40 @@ TEST_F(ElfInterfaceArmTest, StepExidx_refuse_unwind) {
|
|||
ASSERT_EQ(0x1234U, regs.pc());
|
||||
}
|
||||
|
||||
TEST_F(ElfInterfaceArmTest, StepExidx_pc_zero) {
|
||||
ElfInterfaceArmFake interface(&memory_);
|
||||
|
||||
interface.FakeSetStartOffset(0x1000);
|
||||
interface.FakeSetTotalEntries(1);
|
||||
memory_.SetData32(0x1000, 0x6000);
|
||||
// Set the pc using a pop r15 command.
|
||||
memory_.SetData32(0x1004, 0x808800b0);
|
||||
|
||||
// pc value of zero.
|
||||
process_memory_.SetData32(0x10000, 0);
|
||||
|
||||
RegsArm regs;
|
||||
regs[ARM_REG_SP] = 0x10000;
|
||||
regs[ARM_REG_LR] = 0x20000;
|
||||
regs.set_sp(regs[ARM_REG_SP]);
|
||||
regs.set_pc(0x1234);
|
||||
|
||||
bool finished;
|
||||
ASSERT_TRUE(interface.StepExidx(0x7000, ®s, &process_memory_, &finished));
|
||||
ASSERT_TRUE(finished);
|
||||
ASSERT_EQ(0U, regs.pc());
|
||||
|
||||
// Now set the pc from the lr register (pop r14).
|
||||
memory_.SetData32(0x1004, 0x808400b0);
|
||||
|
||||
regs[ARM_REG_SP] = 0x10000;
|
||||
regs[ARM_REG_LR] = 0x20000;
|
||||
regs.set_sp(regs[ARM_REG_SP]);
|
||||
regs.set_pc(0x1234);
|
||||
|
||||
ASSERT_TRUE(interface.StepExidx(0x7000, ®s, &process_memory_, &finished));
|
||||
ASSERT_TRUE(finished);
|
||||
ASSERT_EQ(0U, regs.pc());
|
||||
}
|
||||
|
||||
} // namespace unwindstack
|
||||
|
|
Loading…
Reference in New Issue