diff options
Diffstat (limited to 'libunwindstack/tests/DwarfCfaTest.cpp')
-rw-r--r-- | libunwindstack/tests/DwarfCfaTest.cpp | 61 |
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); |