Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09123383 authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "If the pc is set to zero, the unwind is done."

parents b128c78a 2502a60e
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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();
+3 −1
Original line number Diff line number Diff line
@@ -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) {
+18 −1
Original line number Diff line number Diff line
@@ -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, &regs, &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,
+36 −0
Original line number Diff line number Diff line
@@ -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, &regs, &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, &regs, &process_memory_, &finished));
  ASSERT_TRUE(finished);
  ASSERT_EQ(0U, regs.pc());
}

}  // namespace unwindstack