Loading libunwindstack/DwarfCfa.cpp +4 −1 Original line number Original line Diff line number Diff line Loading @@ -424,7 +424,10 @@ bool DwarfCfa<AddressType>::cfa_def_cfa_offset(dwarf_loc_regs_t* loc_regs) { template <typename AddressType> template <typename AddressType> bool DwarfCfa<AddressType>::cfa_def_cfa_expression(dwarf_loc_regs_t* loc_regs) { bool DwarfCfa<AddressType>::cfa_def_cfa_expression(dwarf_loc_regs_t* loc_regs) { (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_EXPRESSION, // There is only one type of expression for CFA evaluation and the DWARF // specification is unclear whether it returns the address or the // dereferenced value. GDB expects the value, so will we. (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_VAL_EXPRESSION, .values = {operands_[0], memory_->cur_offset()}}; .values = {operands_[0], memory_->cur_offset()}}; return true; return true; } } Loading libunwindstack/DwarfSection.cpp +2 −10 Original line number Original line Diff line number Diff line Loading @@ -214,21 +214,13 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me } } eval_info.cfa += loc->values[1]; eval_info.cfa += loc->values[1]; break; break; case DWARF_LOCATION_EXPRESSION: case DWARF_LOCATION_VAL_EXPRESSION: { case DWARF_LOCATION_VAL_EXPRESSION: { AddressType value; AddressType value; if (!EvalExpression(*loc, regular_memory, &value, &eval_info.regs_info, nullptr)) { if (!EvalExpression(*loc, regular_memory, &value, &eval_info.regs_info, nullptr)) { return false; return false; } } if (loc->type == DWARF_LOCATION_EXPRESSION) { // There is only one type of valid expression for CFA evaluation. if (!regular_memory->ReadFully(value, &eval_info.cfa, sizeof(AddressType))) { last_error_.code = DWARF_ERROR_MEMORY_INVALID; last_error_.address = value; return false; } } else { eval_info.cfa = value; eval_info.cfa = value; } break; break; } } default: default: Loading libunwindstack/tests/DwarfCfaTest.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -737,6 +737,8 @@ TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa_expression) { ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x284, &loc_regs)); ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x284, &loc_regs)); ASSERT_EQ(0x284U, this->dmem_->cur_offset()); ASSERT_EQ(0x284U, this->dmem_->cur_offset()); ASSERT_EQ(1U, loc_regs.size()); ASSERT_EQ(1U, loc_regs.size()); ASSERT_EQ(DWARF_LOCATION_VAL_EXPRESSION, loc_regs[CFA_REG].type); ASSERT_EQ(0x81U, loc_regs[CFA_REG].values[0]); ASSERT_EQ("", GetFakeLogPrint()); ASSERT_EQ("", GetFakeLogPrint()); ASSERT_EQ("", GetFakeLogBuf()); ASSERT_EQ("", GetFakeLogBuf()); Loading libunwindstack/tests/DwarfSectionImplTest.cpp +5 −7 Original line number Original line Diff line number Diff line Loading @@ -99,7 +99,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { regs.set_sp(0x2000); regs.set_sp(0x2000); regs[5] = 0x20; regs[5] = 0x20; regs[9] = 0x3000; regs[9] = 0x3000; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5002}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; bool finished; bool finished; ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); Loading @@ -116,7 +116,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { regs[5] = 0x20; regs[5] = 0x20; regs[9] = 0x3000; regs[9] = 0x3000; this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96}); this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96}); loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5002}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; bool finished; bool finished; ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode()); EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode()); Loading @@ -136,10 +136,8 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; bool finished; bool finished; ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_FALSE(finished); EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); EXPECT_EQ(0x12345U, regs.sp()); EXPECT_EQ(0x20U, regs.pc()); } } TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { Loading Loading @@ -170,7 +168,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { regs[5] = 0x20; regs[5] = 0x20; regs[9] = 0x3000; regs[9] = 0x3000; this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96}); this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96}); loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5002}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; bool finished; bool finished; ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode()); EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode()); Loading Loading
libunwindstack/DwarfCfa.cpp +4 −1 Original line number Original line Diff line number Diff line Loading @@ -424,7 +424,10 @@ bool DwarfCfa<AddressType>::cfa_def_cfa_offset(dwarf_loc_regs_t* loc_regs) { template <typename AddressType> template <typename AddressType> bool DwarfCfa<AddressType>::cfa_def_cfa_expression(dwarf_loc_regs_t* loc_regs) { bool DwarfCfa<AddressType>::cfa_def_cfa_expression(dwarf_loc_regs_t* loc_regs) { (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_EXPRESSION, // There is only one type of expression for CFA evaluation and the DWARF // specification is unclear whether it returns the address or the // dereferenced value. GDB expects the value, so will we. (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_VAL_EXPRESSION, .values = {operands_[0], memory_->cur_offset()}}; .values = {operands_[0], memory_->cur_offset()}}; return true; return true; } } Loading
libunwindstack/DwarfSection.cpp +2 −10 Original line number Original line Diff line number Diff line Loading @@ -214,21 +214,13 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me } } eval_info.cfa += loc->values[1]; eval_info.cfa += loc->values[1]; break; break; case DWARF_LOCATION_EXPRESSION: case DWARF_LOCATION_VAL_EXPRESSION: { case DWARF_LOCATION_VAL_EXPRESSION: { AddressType value; AddressType value; if (!EvalExpression(*loc, regular_memory, &value, &eval_info.regs_info, nullptr)) { if (!EvalExpression(*loc, regular_memory, &value, &eval_info.regs_info, nullptr)) { return false; return false; } } if (loc->type == DWARF_LOCATION_EXPRESSION) { // There is only one type of valid expression for CFA evaluation. if (!regular_memory->ReadFully(value, &eval_info.cfa, sizeof(AddressType))) { last_error_.code = DWARF_ERROR_MEMORY_INVALID; last_error_.address = value; return false; } } else { eval_info.cfa = value; eval_info.cfa = value; } break; break; } } default: default: Loading
libunwindstack/tests/DwarfCfaTest.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -737,6 +737,8 @@ TYPED_TEST_P(DwarfCfaTest, cfa_def_cfa_expression) { ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x284, &loc_regs)); ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x200, 0x284, &loc_regs)); ASSERT_EQ(0x284U, this->dmem_->cur_offset()); ASSERT_EQ(0x284U, this->dmem_->cur_offset()); ASSERT_EQ(1U, loc_regs.size()); ASSERT_EQ(1U, loc_regs.size()); ASSERT_EQ(DWARF_LOCATION_VAL_EXPRESSION, loc_regs[CFA_REG].type); ASSERT_EQ(0x81U, loc_regs[CFA_REG].values[0]); ASSERT_EQ("", GetFakeLogPrint()); ASSERT_EQ("", GetFakeLogPrint()); ASSERT_EQ("", GetFakeLogBuf()); ASSERT_EQ("", GetFakeLogBuf()); Loading
libunwindstack/tests/DwarfSectionImplTest.cpp +5 −7 Original line number Original line Diff line number Diff line Loading @@ -99,7 +99,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { regs.set_sp(0x2000); regs.set_sp(0x2000); regs[5] = 0x20; regs[5] = 0x20; regs[9] = 0x3000; regs[9] = 0x3000; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5002}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; bool finished; bool finished; ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); Loading @@ -116,7 +116,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { regs[5] = 0x20; regs[5] = 0x20; regs[9] = 0x3000; regs[9] = 0x3000; this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96}); this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96}); loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5002}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; bool finished; bool finished; ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode()); EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode()); Loading @@ -136,10 +136,8 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; bool finished; bool finished; ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_FALSE(finished); EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); EXPECT_EQ(0x12345U, regs.sp()); EXPECT_EQ(0x20U, regs.pc()); } } TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { Loading Loading @@ -170,7 +168,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { regs[5] = 0x20; regs[5] = 0x20; regs[9] = 0x3000; regs[9] = 0x3000; this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96}); this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96}); loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5002}}; loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; bool finished; bool finished; ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode()); EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode()); Loading