summaryrefslogtreecommitdiffstats
path: root/libunwindstack
diff options
context:
space:
mode:
authorDavid Srbecky <dsrbecky@google.com>2018-03-08 16:57:19 +0000
committerChristopher Ferris <cferris@google.com>2018-03-12 14:08:49 -0700
commitc4772ae94c847878594ab9dc855586a96adbf255 (patch)
tree416b7072f1826d2d9579f18c22fc1057174a9ebd /libunwindstack
parent23d45d1cc73ffb7a74bad4552c826fd497c83a97 (diff)
downloadcore-c4772ae94c847878594ab9dc855586a96adbf255.tar.gz
core-c4772ae94c847878594ab9dc855586a96adbf255.tar.bz2
core-c4772ae94c847878594ab9dc855586a96adbf255.zip
Don't implicitly dereference DW_CFA_def_cfa_expression.
The specification isn't entirely clear. Follow the gdb interpretation. Bug: 73954823 Test: libunwindstack_test Change-Id: If72717f54eed84e442f43af19e615143a9796b68 (cherry picked from commit 3692f251990ecb063bb9a3f8af1f820782be9973)
Diffstat (limited to 'libunwindstack')
-rw-r--r--libunwindstack/DwarfCfa.cpp5
-rw-r--r--libunwindstack/DwarfSection.cpp12
-rw-r--r--libunwindstack/tests/DwarfCfaTest.cpp2
-rw-r--r--libunwindstack/tests/DwarfSectionImplTest.cpp12
4 files changed, 13 insertions, 18 deletions
diff --git a/libunwindstack/DwarfCfa.cpp b/libunwindstack/DwarfCfa.cpp
index 4fc95c766..aa8cd3a6f 100644
--- a/libunwindstack/DwarfCfa.cpp
+++ b/libunwindstack/DwarfCfa.cpp
@@ -424,7 +424,10 @@ bool DwarfCfa<AddressType>::cfa_def_cfa_offset(dwarf_loc_regs_t* loc_regs) {
template <typename AddressType>
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()}};
return true;
}
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp
index 764979863..ddbc12ef4 100644
--- a/libunwindstack/DwarfSection.cpp
+++ b/libunwindstack/DwarfSection.cpp
@@ -214,21 +214,13 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
}
eval_info.cfa += loc->values[1];
break;
- case DWARF_LOCATION_EXPRESSION:
case DWARF_LOCATION_VAL_EXPRESSION: {
AddressType value;
if (!EvalExpression(*loc, regular_memory, &value, &eval_info.regs_info, nullptr)) {
return false;
}
- if (loc->type == DWARF_LOCATION_EXPRESSION) {
- 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;
- }
+ // There is only one type of valid expression for CFA evaluation.
+ eval_info.cfa = value;
break;
}
default:
diff --git a/libunwindstack/tests/DwarfCfaTest.cpp b/libunwindstack/tests/DwarfCfaTest.cpp
index 68dc30cd9..7395b04dd 100644
--- a/libunwindstack/tests/DwarfCfaTest.cpp
+++ b/libunwindstack/tests/DwarfCfaTest.cpp
@@ -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_EQ(0x284U, this->dmem_->cur_offset());
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("", GetFakeLogBuf());
diff --git a/libunwindstack/tests/DwarfSectionImplTest.cpp b/libunwindstack/tests/DwarfSectionImplTest.cpp
index 37305b26b..99f4d873f 100644
--- a/libunwindstack/tests/DwarfSectionImplTest.cpp
+++ b/libunwindstack/tests/DwarfSectionImplTest.cpp
@@ -99,7 +99,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) {
regs.set_sp(0x2000);
regs[5] = 0x20;
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;
ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
@@ -116,7 +116,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) {
regs[5] = 0x20;
regs[9] = 0x3000;
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;
ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode());
@@ -136,10 +136,8 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) {
this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}};
bool finished;
- ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
- EXPECT_FALSE(finished);
- EXPECT_EQ(0x12345U, regs.sp());
- EXPECT_EQ(0x20U, regs.pc());
+ ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
+ EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
}
TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) {
@@ -170,7 +168,7 @@ TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) {
regs[5] = 0x20;
regs[9] = 0x3000;
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;
ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode());