summaryrefslogtreecommitdiff
path: root/libunwindstack/tests/DwarfCfaTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/tests/DwarfCfaTest.cpp')
-rw-r--r--libunwindstack/tests/DwarfCfaTest.cpp61
1 files changed, 57 insertions, 4 deletions
diff --git a/libunwindstack/tests/DwarfCfaTest.cpp b/libunwindstack/tests/DwarfCfaTest.cpp
index 9c6ab05e63..ea7e70807e 100644
--- a/libunwindstack/tests/DwarfCfaTest.cpp
+++ b/libunwindstack/tests/DwarfCfaTest.cpp
@@ -25,7 +25,9 @@
#include <unwindstack/DwarfLocation.h>
#include <unwindstack/DwarfMemory.h>
#include <unwindstack/DwarfStructs.h>
+#include <unwindstack/Elf.h>
#include <unwindstack/Log.h>
+#include <unwindstack/MachineArm64.h>
#include "DwarfCfa.h"
@@ -55,7 +57,7 @@ class DwarfCfaTest : public ::testing::Test {
fde_.pc_start = 0x2000;
fde_.cie = &cie_;
- cfa_.reset(new DwarfCfa<TypeParam>(dmem_.get(), &fde_));
+ cfa_.reset(new DwarfCfa<TypeParam>(dmem_.get(), &fde_, ARCH_UNKNOWN));
}
MemoryFake memory_;
@@ -70,8 +72,8 @@ TYPED_TEST_SUITE_P(DwarfCfaTest);
TYPED_TEST_P(DwarfCfaTest, cfa_illegal) {
for (uint8_t i = 0x17; i < 0x3f; i++) {
- if (i == 0x2e || i == 0x2f) {
- // Skip gnu extension ops.
+ if (i == 0x2d || i == 0x2e || i == 0x2f) {
+ // Skip gnu extension ops and aarch64 specialized op.
continue;
}
this->memory_.SetMemory(0x2000, std::vector<uint8_t>{i});
@@ -952,6 +954,57 @@ TYPED_TEST_P(DwarfCfaTest, cfa_register_override) {
ASSERT_EQ("", GetFakeLogBuf());
}
+TYPED_TEST_P(DwarfCfaTest, cfa_aarch64_negate_ra_state) {
+ this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x2d});
+ dwarf_loc_regs_t loc_regs;
+
+ ASSERT_FALSE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2001, &loc_regs));
+ ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->cfa_->LastErrorCode());
+ ASSERT_EQ(0x2001U, this->dmem_->cur_offset());
+
+ ASSERT_EQ("", GetFakeLogPrint());
+ ASSERT_EQ("", GetFakeLogBuf());
+
+ ResetLogs();
+ this->cfa_.reset(new DwarfCfa<TypeParam>(this->dmem_.get(), &this->fde_, ARCH_ARM64));
+ ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2001, &loc_regs));
+ ASSERT_EQ(0x2001U, this->dmem_->cur_offset());
+
+ auto location = loc_regs.find(Arm64Reg::ARM64_PREG_RA_SIGN_STATE);
+ ASSERT_NE(loc_regs.end(), location);
+ ASSERT_EQ(DWARF_LOCATION_PSEUDO_REGISTER, location->second.type);
+ ASSERT_EQ(1U, location->second.values[0]);
+
+ ASSERT_EQ("", GetFakeLogPrint());
+ ASSERT_EQ("", GetFakeLogBuf());
+
+ // Verify that the value is set to 0 after another evaluation.
+ ResetLogs();
+ ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2001, &loc_regs));
+ ASSERT_EQ(0x2001U, this->dmem_->cur_offset());
+
+ location = loc_regs.find(Arm64Reg::ARM64_PREG_RA_SIGN_STATE);
+ ASSERT_NE(loc_regs.end(), location);
+ ASSERT_EQ(DWARF_LOCATION_PSEUDO_REGISTER, location->second.type);
+ ASSERT_EQ(0U, location->second.values[0]);
+
+ ASSERT_EQ("", GetFakeLogPrint());
+ ASSERT_EQ("", GetFakeLogBuf());
+
+ // Verify that the value is set to 1 again after a third op.
+ ResetLogs();
+ ASSERT_TRUE(this->cfa_->GetLocationInfo(this->fde_.pc_start, 0x2000, 0x2001, &loc_regs));
+ ASSERT_EQ(0x2001U, this->dmem_->cur_offset());
+
+ location = loc_regs.find(Arm64Reg::ARM64_PREG_RA_SIGN_STATE);
+ ASSERT_NE(loc_regs.end(), location);
+ ASSERT_EQ(DWARF_LOCATION_PSEUDO_REGISTER, location->second.type);
+ ASSERT_EQ(1U, location->second.values[0]);
+
+ ASSERT_EQ("", GetFakeLogPrint());
+ ASSERT_EQ("", GetFakeLogBuf());
+}
+
REGISTER_TYPED_TEST_SUITE_P(DwarfCfaTest, cfa_illegal, cfa_nop, cfa_offset, cfa_offset_extended,
cfa_offset_extended_sf, cfa_restore, cfa_restore_extended, cfa_set_loc,
cfa_advance_loc1, cfa_advance_loc2, cfa_advance_loc4, cfa_undefined,
@@ -960,7 +1013,7 @@ REGISTER_TYPED_TEST_SUITE_P(DwarfCfaTest, cfa_illegal, cfa_nop, cfa_offset, cfa_
cfa_def_cfa_offset_sf, cfa_def_cfa_expression, cfa_expression,
cfa_val_offset, cfa_val_offset_sf, cfa_val_expression,
cfa_gnu_args_size, cfa_gnu_negative_offset_extended,
- cfa_register_override);
+ cfa_register_override, cfa_aarch64_negate_ra_state);
typedef ::testing::Types<uint32_t, uint64_t> DwarfCfaTestTypes;
INSTANTIATE_TYPED_TEST_SUITE_P(Libunwindstack, DwarfCfaTest, DwarfCfaTestTypes);