| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2016 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <stdint.h> | 
|  | 18 |  | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 19 | #include <gtest/gtest.h> | 
|  | 20 |  | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 21 | #include <unwindstack/DwarfError.h> | 
| Christopher Ferris | d226a51 | 2017-07-14 10:37:19 -0700 | [diff] [blame] | 22 | #include <unwindstack/DwarfSection.h> | 
|  | 23 |  | 
|  | 24 | #include "DwarfEncoding.h" | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 25 |  | 
|  | 26 | #include "LogFake.h" | 
|  | 27 | #include "MemoryFake.h" | 
|  | 28 | #include "RegsFake.h" | 
|  | 29 |  | 
| Christopher Ferris | d226a51 | 2017-07-14 10:37:19 -0700 | [diff] [blame] | 30 | namespace unwindstack { | 
|  | 31 |  | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 32 | template <typename TypeParam> | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 33 | class TestDwarfSectionImpl : public DwarfSectionImpl<TypeParam> { | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 34 | public: | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 35 | TestDwarfSectionImpl(Memory* memory) : DwarfSectionImpl<TypeParam>(memory) {} | 
|  | 36 | virtual ~TestDwarfSectionImpl() = default; | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 37 |  | 
| Christopher Ferris | 819f131 | 2019-10-03 13:35:48 -0700 | [diff] [blame] | 38 | bool Init(uint64_t, uint64_t, int64_t) override { return false; } | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 39 |  | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 40 | void GetFdes(std::vector<const DwarfFde*>*) override {} | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 41 |  | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 42 | const DwarfFde* GetFdeFromPc(uint64_t) override { return nullptr; } | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 43 |  | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 44 | uint64_t GetCieOffsetFromFde32(uint32_t) { return 0; } | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 45 |  | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 46 | uint64_t GetCieOffsetFromFde64(uint64_t) { return 0; } | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 47 |  | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 48 | uint64_t AdjustPcFromFde(uint64_t) override { return 0; } | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 49 |  | 
|  | 50 | void TestSetCachedCieLocRegs(uint64_t offset, const dwarf_loc_regs_t& loc_regs) { | 
|  | 51 | this->cie_loc_regs_[offset] = loc_regs; | 
|  | 52 | } | 
|  | 53 | void TestClearCachedCieLocRegs() { this->cie_loc_regs_.clear(); } | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 54 | void TestClearError() { this->last_error_.code = DWARF_ERROR_NONE; } | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 55 | }; | 
|  | 56 |  | 
|  | 57 | template <typename TypeParam> | 
|  | 58 | class DwarfSectionImplTest : public ::testing::Test { | 
|  | 59 | protected: | 
|  | 60 | void SetUp() override { | 
|  | 61 | memory_.Clear(); | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 62 | section_ = new TestDwarfSectionImpl<TypeParam>(&memory_); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 63 | ResetLogs(); | 
|  | 64 | } | 
|  | 65 |  | 
|  | 66 | void TearDown() override { delete section_; } | 
|  | 67 |  | 
|  | 68 | MemoryFake memory_; | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 69 | TestDwarfSectionImpl<TypeParam>* section_ = nullptr; | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 70 | }; | 
| Christopher Ferris | 7e21eba | 2019-06-20 16:16:42 -0700 | [diff] [blame] | 71 | TYPED_TEST_SUITE_P(DwarfSectionImplTest); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 72 |  | 
|  | 73 | // NOTE: All test class variables need to be referenced as this->. | 
|  | 74 |  | 
| Christopher Ferris | 92acaac | 2018-06-21 10:44:02 -0700 | [diff] [blame] | 75 | TYPED_TEST_P(DwarfSectionImplTest, GetCieFromOffset_fail_should_not_cache) { | 
|  | 76 | ASSERT_TRUE(this->section_->GetCieFromOffset(0x4000) == nullptr); | 
|  | 77 | EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); | 
|  | 78 | EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); | 
|  | 79 |  | 
|  | 80 | this->section_->TestClearError(); | 
|  | 81 | ASSERT_TRUE(this->section_->GetCieFromOffset(0x4000) == nullptr); | 
|  | 82 | EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); | 
|  | 83 | EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); | 
|  | 84 | } | 
|  | 85 |  | 
|  | 86 | TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) { | 
|  | 87 | ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr); | 
|  | 88 | EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); | 
|  | 89 | EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); | 
|  | 90 |  | 
|  | 91 | this->section_->TestClearError(); | 
|  | 92 | ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr); | 
|  | 93 | EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); | 
|  | 94 | EXPECT_EQ(0x4000U, this->section_->LastErrorAddress()); | 
|  | 95 | } | 
|  | 96 |  | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 97 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) { | 
|  | 98 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 99 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 100 | dwarf_loc_regs_t loc_regs; | 
|  | 101 |  | 
|  | 102 | regs.set_pc(0x100); | 
|  | 103 | regs.set_sp(0x2000); | 
|  | 104 | regs[5] = 0x20; | 
|  | 105 | regs[9] = 0x3000; | 
| David Srbecky | 3692f25 | 2018-03-08 16:57:19 +0000 | [diff] [blame] | 106 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 107 | bool finished; | 
|  | 108 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 109 | EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode()); | 
|  | 110 | EXPECT_EQ(0x5000U, this->section_->LastErrorAddress()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 111 | } | 
|  | 112 |  | 
|  | 113 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) { | 
|  | 114 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 115 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 116 | dwarf_loc_regs_t loc_regs; | 
|  | 117 |  | 
|  | 118 | regs.set_pc(0x100); | 
|  | 119 | regs.set_sp(0x2000); | 
|  | 120 | regs[5] = 0x20; | 
|  | 121 | regs[9] = 0x3000; | 
|  | 122 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96}); | 
| David Srbecky | 3692f25 | 2018-03-08 16:57:19 +0000 | [diff] [blame] | 123 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 124 | bool finished; | 
|  | 125 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 126 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 127 | } | 
|  | 128 |  | 
|  | 129 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) { | 
|  | 130 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 131 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 132 | dwarf_loc_regs_t loc_regs; | 
|  | 133 |  | 
|  | 134 | regs.set_pc(0x100); | 
|  | 135 | regs.set_sp(0x2000); | 
|  | 136 | regs[5] = 0x20; | 
|  | 137 | regs[9] = 0x3000; | 
|  | 138 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); | 
|  | 139 | TypeParam cfa_value = 0x12345; | 
|  | 140 | this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 141 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 142 | bool finished; | 
| David Srbecky | 3692f25 | 2018-03-08 16:57:19 +0000 | [diff] [blame] | 143 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 144 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 145 | } | 
|  | 146 |  | 
|  | 147 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) { | 
|  | 148 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 149 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 150 | dwarf_loc_regs_t loc_regs; | 
|  | 151 |  | 
|  | 152 | regs.set_pc(0x100); | 
|  | 153 | regs.set_sp(0x2000); | 
|  | 154 | regs[5] = 0x20; | 
|  | 155 | regs[9] = 0x3000; | 
|  | 156 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 157 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 158 | bool finished; | 
|  | 159 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 160 | ASSERT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 161 | EXPECT_EQ(0x80000000U, regs.sp()); | 
|  | 162 | EXPECT_EQ(0x20U, regs.pc()); | 
|  | 163 | } | 
|  | 164 |  | 
|  | 165 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) { | 
|  | 166 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 167 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 168 | dwarf_loc_regs_t loc_regs; | 
|  | 169 |  | 
|  | 170 | regs.set_pc(0x100); | 
|  | 171 | regs.set_sp(0x2000); | 
|  | 172 | regs[5] = 0x20; | 
|  | 173 | regs[9] = 0x3000; | 
|  | 174 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96}); | 
| David Srbecky | 3692f25 | 2018-03-08 16:57:19 +0000 | [diff] [blame] | 175 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 176 | bool finished; | 
|  | 177 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 178 | EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 179 | } | 
|  | 180 |  | 
|  | 181 | TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) { | 
|  | 182 | DwarfCie cie{.return_address_register = 60}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 183 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 184 | dwarf_loc_regs_t loc_regs; | 
|  | 185 |  | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 186 | bool finished; | 
|  | 187 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 188 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 189 | } | 
|  | 190 |  | 
|  | 191 | TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) { | 
|  | 192 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 193 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 194 | dwarf_loc_regs_t loc_regs; | 
|  | 195 |  | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 196 | bool finished; | 
|  | 197 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 198 | EXPECT_EQ(DWARF_ERROR_CFA_NOT_DEFINED, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 199 | } | 
|  | 200 |  | 
|  | 201 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) { | 
|  | 202 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 203 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 204 | dwarf_loc_regs_t loc_regs; | 
|  | 205 |  | 
|  | 206 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 207 | bool finished; | 
|  | 208 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 209 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 210 |  | 
|  | 211 | this->section_->TestClearError(); | 
|  | 212 | loc_regs.erase(CFA_REG); | 
|  | 213 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_INVALID, {0, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 214 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 215 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 216 |  | 
|  | 217 | this->section_->TestClearError(); | 
|  | 218 | loc_regs.erase(CFA_REG); | 
|  | 219 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_OFFSET, {0, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 220 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 221 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 222 |  | 
|  | 223 | this->section_->TestClearError(); | 
|  | 224 | loc_regs.erase(CFA_REG); | 
|  | 225 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 226 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 227 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 228 | } | 
|  | 229 |  | 
|  | 230 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) { | 
|  | 231 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 232 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 233 | dwarf_loc_regs_t loc_regs; | 
|  | 234 |  | 
|  | 235 | regs.set_pc(0x100); | 
|  | 236 | regs.set_sp(0x2000); | 
|  | 237 | regs[5] = 0x20; | 
|  | 238 | regs[9] = 0x3000; | 
|  | 239 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {9, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 240 | bool finished; | 
|  | 241 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 242 | EXPECT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 243 | EXPECT_EQ(0x20U, regs.pc()); | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 244 | EXPECT_EQ(0x3000U, regs.sp()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 245 | } | 
|  | 246 |  | 
|  | 247 | TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) { | 
|  | 248 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 249 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 250 | dwarf_loc_regs_t loc_regs; | 
|  | 251 |  | 
|  | 252 | regs.set_pc(0x100); | 
|  | 253 | regs.set_sp(0x2000); | 
|  | 254 | regs[5] = 0x20; | 
|  | 255 | regs[6] = 0x4000; | 
|  | 256 | regs[9] = 0x3000; | 
|  | 257 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {6, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 258 | bool finished; | 
|  | 259 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 260 | EXPECT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 261 | EXPECT_EQ(0x20U, regs.pc()); | 
|  | 262 | EXPECT_EQ(0x4000U, regs.sp()); | 
|  | 263 | } | 
|  | 264 |  | 
|  | 265 | TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) { | 
|  | 266 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 267 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 268 | dwarf_loc_regs_t loc_regs; | 
|  | 269 |  | 
|  | 270 | regs.set_pc(0x100); | 
|  | 271 | regs.set_sp(0x2000); | 
| Christopher Ferris | 98984b4 | 2018-01-17 12:59:45 -0800 | [diff] [blame] | 272 | regs[1] = 0x100; | 
|  | 273 | regs[3] = 0x300; | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 274 | regs[8] = 0x10; | 
|  | 275 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
| Christopher Ferris | 98984b4 | 2018-01-17 12:59:45 -0800 | [diff] [blame] | 276 | loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 1}}; | 
|  | 277 | loc_regs[9] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 278 | bool finished; | 
| Christopher Ferris | 98984b4 | 2018-01-17 12:59:45 -0800 | [diff] [blame] | 279 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 280 | EXPECT_EQ(0x301U, regs[1]); | 
|  | 281 | EXPECT_EQ(0x300U, regs[3]); | 
|  | 282 | EXPECT_EQ(0x10U, regs[8]); | 
|  | 283 | EXPECT_EQ(0x102U, regs[9]); | 
|  | 284 | } | 
|  | 285 |  | 
|  | 286 | TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) { | 
|  | 287 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 288 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 98984b4 | 2018-01-17 12:59:45 -0800 | [diff] [blame] | 289 | dwarf_loc_regs_t loc_regs; | 
|  | 290 |  | 
|  | 291 | regs.set_pc(0x100); | 
|  | 292 | regs.set_sp(0x2000); | 
|  | 293 | regs[0] = 0x10; | 
|  | 294 | regs[1] = 0x20; | 
|  | 295 | regs[2] = 0x30; | 
|  | 296 | regs[3] = 0x40; | 
|  | 297 | regs[4] = 0x50; | 
|  | 298 | regs[5] = 0x60; | 
|  | 299 | regs[8] = 0x20; | 
|  | 300 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
|  | 301 | loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {0, 1}}; | 
|  | 302 | loc_regs[2] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}}; | 
|  | 303 | loc_regs[3] = DwarfLocation{DWARF_LOCATION_REGISTER, {2, 3}}; | 
|  | 304 | loc_regs[4] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 4}}; | 
|  | 305 | loc_regs[5] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 5}}; | 
|  | 306 | bool finished; | 
|  | 307 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 308 | EXPECT_EQ(0x10U, regs[0]); | 
|  | 309 | EXPECT_EQ(0x11U, regs[1]); | 
|  | 310 | EXPECT_EQ(0x22U, regs[2]); | 
|  | 311 | EXPECT_EQ(0x33U, regs[3]); | 
|  | 312 | EXPECT_EQ(0x44U, regs[4]); | 
|  | 313 | EXPECT_EQ(0x55U, regs[5]); | 
|  | 314 | EXPECT_EQ(0x20U, regs[8]); | 
|  | 315 | } | 
|  | 316 |  | 
|  | 317 | TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) { | 
|  | 318 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 319 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 98984b4 | 2018-01-17 12:59:45 -0800 | [diff] [blame] | 320 | dwarf_loc_regs_t loc_regs; | 
|  | 321 |  | 
|  | 322 | regs.set_pc(0x100); | 
|  | 323 | regs.set_sp(0x2000); | 
|  | 324 | regs[0] = 0x10; | 
|  | 325 | regs[8] = 0x20; | 
|  | 326 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 327 | loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x8, 0x5008}}; | 
|  | 328 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '1', 0x13, 0x08, 0x11}); | 
| Christopher Ferris | 98984b4 | 2018-01-17 12:59:45 -0800 | [diff] [blame] | 329 | bool finished; | 
|  | 330 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 331 | EXPECT_EQ(0x10U, regs[0]); | 
|  | 332 | EXPECT_EQ(0x20U, regs[8]); | 
|  | 333 | EXPECT_EQ(0x11U, regs.dex_pc()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 334 | } | 
|  | 335 |  | 
|  | 336 | TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) { | 
|  | 337 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 338 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 339 | dwarf_loc_regs_t loc_regs; | 
|  | 340 |  | 
|  | 341 | regs.set_pc(0x100); | 
|  | 342 | regs.set_sp(0x2000); | 
|  | 343 | regs[8] = 0x10; | 
|  | 344 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
|  | 345 | loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {10, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 346 | bool finished; | 
|  | 347 | ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 348 | EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode()); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 349 | } | 
|  | 350 |  | 
|  | 351 | TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) { | 
|  | 352 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 353 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 354 | dwarf_loc_regs_t loc_regs; | 
|  | 355 |  | 
|  | 356 | if (sizeof(TypeParam) == sizeof(uint64_t)) { | 
|  | 357 | this->memory_.SetData64(0x2150, 0x12345678abcdef00ULL); | 
|  | 358 | } else { | 
|  | 359 | this->memory_.SetData32(0x2150, 0x12345678); | 
|  | 360 | } | 
|  | 361 |  | 
|  | 362 | regs.set_pc(0x100); | 
|  | 363 | regs.set_sp(0x2000); | 
|  | 364 | regs[3] = 0x234; | 
|  | 365 | regs[5] = 0x10; | 
|  | 366 | regs[8] = 0x2100; | 
|  | 367 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
|  | 368 | loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0x100, 0}}; | 
|  | 369 | loc_regs[2] = DwarfLocation{DWARF_LOCATION_OFFSET, {0x50, 0}}; | 
|  | 370 | loc_regs[3] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 371 | bool finished; | 
|  | 372 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 373 | EXPECT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 374 | EXPECT_EQ(0x10U, regs.pc()); | 
|  | 375 | EXPECT_EQ(0x2100U, regs.sp()); | 
|  | 376 | EXPECT_EQ(0x2200U, regs[1]); | 
|  | 377 | EXPECT_EQ(0x234U, regs[3]); | 
|  | 378 | if (sizeof(TypeParam) == sizeof(uint64_t)) { | 
|  | 379 | EXPECT_EQ(0x12345678abcdef00ULL, regs[2]); | 
|  | 380 | } else { | 
|  | 381 | EXPECT_EQ(0x12345678U, regs[2]); | 
|  | 382 | } | 
|  | 383 | } | 
|  | 384 |  | 
|  | 385 | TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) { | 
|  | 386 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 387 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 388 | dwarf_loc_regs_t loc_regs; | 
|  | 389 |  | 
|  | 390 | regs.set_pc(0x100); | 
|  | 391 | regs.set_sp(0x2000); | 
|  | 392 | regs[5] = 0x20; | 
|  | 393 | regs[8] = 0x10; | 
|  | 394 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
|  | 395 | loc_regs[5] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 396 | bool finished; | 
|  | 397 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 398 | EXPECT_TRUE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 399 | EXPECT_EQ(0U, regs.pc()); | 
|  | 400 | EXPECT_EQ(0x10U, regs.sp()); | 
|  | 401 | } | 
|  | 402 |  | 
| Christopher Ferris | 2502a60 | 2017-10-23 13:51:54 -0700 | [diff] [blame] | 403 | TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) { | 
|  | 404 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 405 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 2502a60 | 2017-10-23 13:51:54 -0700 | [diff] [blame] | 406 | dwarf_loc_regs_t loc_regs; | 
|  | 407 |  | 
|  | 408 | regs.set_pc(0x100); | 
|  | 409 | regs.set_sp(0x2000); | 
|  | 410 | regs[5] = 0; | 
|  | 411 | regs[8] = 0x10; | 
|  | 412 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
|  | 413 | bool finished; | 
|  | 414 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 415 | EXPECT_TRUE(finished); | 
|  | 416 | EXPECT_EQ(0U, regs.pc()); | 
|  | 417 | EXPECT_EQ(0x10U, regs.sp()); | 
|  | 418 | } | 
|  | 419 |  | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 420 | TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) { | 
|  | 421 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 422 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 423 | dwarf_loc_regs_t loc_regs; | 
|  | 424 |  | 
|  | 425 | regs.set_pc(0x100); | 
|  | 426 | regs.set_sp(0x2000); | 
|  | 427 | regs[5] = 0x20; | 
|  | 428 | regs[8] = 0x10; | 
|  | 429 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 430 | bool finished; | 
|  | 431 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 432 | EXPECT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 433 | EXPECT_EQ(0x20U, regs.pc()); | 
|  | 434 | EXPECT_EQ(0x10U, regs.sp()); | 
|  | 435 | } | 
|  | 436 |  | 
|  | 437 | TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) { | 
|  | 438 | DwarfCie cie{.return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 439 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 440 | dwarf_loc_regs_t loc_regs; | 
|  | 441 |  | 
|  | 442 | regs.set_pc(0x100); | 
|  | 443 | regs.set_sp(0x2000); | 
|  | 444 | regs[5] = 0x20; | 
|  | 445 | regs[8] = 0x10; | 
|  | 446 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
|  | 447 | // This should not result in any errors. | 
|  | 448 | loc_regs[20] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 449 | bool finished; | 
|  | 450 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 451 | EXPECT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 452 | EXPECT_EQ(0x20U, regs.pc()); | 
|  | 453 | EXPECT_EQ(0x10U, regs.sp()); | 
|  | 454 | } | 
|  | 455 |  | 
|  | 456 | TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) { | 
|  | 457 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 458 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 459 | dwarf_loc_regs_t loc_regs; | 
|  | 460 |  | 
|  | 461 | regs.set_pc(0x100); | 
|  | 462 | regs.set_sp(0x2000); | 
|  | 463 | regs[8] = 0x3000; | 
|  | 464 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); | 
|  | 465 | TypeParam cfa_value = 0x12345; | 
|  | 466 | this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value)); | 
|  | 467 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 468 | loc_regs[5] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 469 | bool finished; | 
|  | 470 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 471 | EXPECT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 472 | EXPECT_EQ(0x3000U, regs.sp()); | 
|  | 473 | EXPECT_EQ(0x12345U, regs.pc()); | 
|  | 474 | } | 
|  | 475 |  | 
|  | 476 | TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) { | 
|  | 477 | DwarfCie cie{.version = 3, .return_address_register = 5}; | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 478 | RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 479 | dwarf_loc_regs_t loc_regs; | 
|  | 480 |  | 
|  | 481 | regs.set_pc(0x100); | 
|  | 482 | regs.set_sp(0x2000); | 
|  | 483 | regs[8] = 0x3000; | 
|  | 484 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80}); | 
|  | 485 | loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}}; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 486 | loc_regs[5] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}}; | 
| Christopher Ferris | b9de87f | 2017-09-20 13:37:24 -0700 | [diff] [blame] | 487 | bool finished; | 
|  | 488 | ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished)); | 
|  | 489 | EXPECT_FALSE(finished); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 490 | EXPECT_EQ(0x3000U, regs.sp()); | 
|  | 491 | EXPECT_EQ(0x80000000U, regs.pc()); | 
|  | 492 | } | 
|  | 493 |  | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 494 | TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_not_cached) { | 
|  | 495 | DwarfCie cie{}; | 
|  | 496 | cie.cfa_instructions_offset = 0x3000; | 
|  | 497 | cie.cfa_instructions_end = 0x3002; | 
|  | 498 | DwarfFde fde{}; | 
|  | 499 | fde.cie = &cie; | 
|  | 500 | fde.cie_offset = 0x8000; | 
|  | 501 | fde.cfa_instructions_offset = 0x6000; | 
|  | 502 | fde.cfa_instructions_end = 0x6002; | 
|  | 503 |  | 
|  | 504 | this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x09, 0x02, 0x01}); | 
|  | 505 | this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03}); | 
|  | 506 |  | 
|  | 507 | dwarf_loc_regs_t loc_regs; | 
|  | 508 | ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs)); | 
|  | 509 | ASSERT_EQ(2U, loc_regs.size()); | 
|  | 510 |  | 
|  | 511 | auto entry = loc_regs.find(2); | 
|  | 512 | ASSERT_NE(entry, loc_regs.end()); | 
|  | 513 | ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); | 
|  | 514 | ASSERT_EQ(1U, entry->second.values[0]); | 
|  | 515 |  | 
|  | 516 | entry = loc_regs.find(4); | 
|  | 517 | ASSERT_NE(entry, loc_regs.end()); | 
|  | 518 | ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); | 
|  | 519 | ASSERT_EQ(3U, entry->second.values[0]); | 
|  | 520 | } | 
|  | 521 |  | 
|  | 522 | TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) { | 
|  | 523 | DwarfCie cie{}; | 
|  | 524 | cie.cfa_instructions_offset = 0x3000; | 
|  | 525 | cie.cfa_instructions_end = 0x3002; | 
|  | 526 | DwarfFde fde{}; | 
|  | 527 | fde.cie = &cie; | 
|  | 528 | fde.cie_offset = 0x8000; | 
|  | 529 | fde.cfa_instructions_offset = 0x6000; | 
|  | 530 | fde.cfa_instructions_end = 0x6002; | 
|  | 531 |  | 
| David Srbecky | 3386eba | 2018-03-14 21:30:25 +0000 | [diff] [blame] | 532 | dwarf_loc_regs_t cie_loc_regs; | 
|  | 533 | cie_loc_regs[6] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 0}}; | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 534 | this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs); | 
|  | 535 | this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03}); | 
|  | 536 |  | 
|  | 537 | dwarf_loc_regs_t loc_regs; | 
|  | 538 | ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs)); | 
|  | 539 | ASSERT_EQ(2U, loc_regs.size()); | 
|  | 540 |  | 
|  | 541 | auto entry = loc_regs.find(6); | 
|  | 542 | ASSERT_NE(entry, loc_regs.end()); | 
|  | 543 | ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); | 
|  | 544 | ASSERT_EQ(4U, entry->second.values[0]); | 
|  | 545 |  | 
|  | 546 | entry = loc_regs.find(4); | 
|  | 547 | ASSERT_NE(entry, loc_regs.end()); | 
|  | 548 | ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type); | 
|  | 549 | ASSERT_EQ(3U, entry->second.values[0]); | 
|  | 550 | } | 
|  | 551 |  | 
|  | 552 | TYPED_TEST_P(DwarfSectionImplTest, Log) { | 
|  | 553 | DwarfCie cie{}; | 
|  | 554 | cie.cfa_instructions_offset = 0x5000; | 
|  | 555 | cie.cfa_instructions_end = 0x5001; | 
|  | 556 | DwarfFde fde{}; | 
|  | 557 | fde.cie = &cie; | 
|  | 558 | fde.cfa_instructions_offset = 0x6000; | 
|  | 559 | fde.cfa_instructions_end = 0x6001; | 
|  | 560 |  | 
|  | 561 | this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x00}); | 
|  | 562 | this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0xc2}); | 
| Christopher Ferris | 4cc36d2 | 2018-06-06 14:47:31 -0700 | [diff] [blame] | 563 | ASSERT_TRUE(this->section_->Log(2, 0x1000, &fde)); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 564 |  | 
|  | 565 | ASSERT_EQ( | 
|  | 566 | "4 unwind     DW_CFA_nop\n" | 
|  | 567 | "4 unwind     Raw Data: 0x00\n" | 
|  | 568 | "4 unwind     DW_CFA_restore register(2)\n" | 
|  | 569 | "4 unwind     Raw Data: 0xc2\n", | 
|  | 570 | GetFakeLogPrint()); | 
|  | 571 | ASSERT_EQ("", GetFakeLogBuf()); | 
|  | 572 | } | 
|  | 573 |  | 
| Christopher Ferris | 7e21eba | 2019-06-20 16:16:42 -0700 | [diff] [blame] | 574 | REGISTER_TYPED_TEST_SUITE_P(DwarfSectionImplTest, GetCieFromOffset_fail_should_not_cache, | 
|  | 575 | GetFdeFromOffset_fail_should_not_cache, Eval_cfa_expr_eval_fail, | 
|  | 576 | Eval_cfa_expr_no_stack, Eval_cfa_expr_is_register, Eval_cfa_expr, | 
|  | 577 | Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa, Eval_cfa_bad, | 
|  | 578 | Eval_cfa_register_prev, Eval_cfa_register_from_value, | 
|  | 579 | Eval_double_indirection, Eval_register_reference_chain, Eval_dex_pc, | 
|  | 580 | Eval_invalid_register, Eval_different_reg_locations, | 
|  | 581 | Eval_return_address_undefined, Eval_pc_zero, Eval_return_address, | 
|  | 582 | Eval_ignore_large_reg_loc, Eval_reg_expr, Eval_reg_val_expr, | 
|  | 583 | GetCfaLocationInfo_cie_not_cached, GetCfaLocationInfo_cie_cached, Log); | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 584 |  | 
|  | 585 | typedef ::testing::Types<uint32_t, uint64_t> DwarfSectionImplTestTypes; | 
| Christopher Ferris | 7e21eba | 2019-06-20 16:16:42 -0700 | [diff] [blame] | 586 | INSTANTIATE_TYPED_TEST_SUITE_P(, DwarfSectionImplTest, DwarfSectionImplTestTypes); | 
| Christopher Ferris | d226a51 | 2017-07-14 10:37:19 -0700 | [diff] [blame] | 587 |  | 
|  | 588 | }  // namespace unwindstack |