blob: 5b9f3ee195b724679d8d99e3b46914d0abf180b7 [file] [log] [blame]
Christopher Ferris53a3c9b2017-05-10 18:34:15 -07001/*
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
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21
Christopher Ferrisd226a512017-07-14 10:37:19 -070022#include <unwindstack/DwarfSection.h>
23
24#include "DwarfEncoding.h"
25#include "DwarfError.h"
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070026
27#include "LogFake.h"
28#include "MemoryFake.h"
29#include "RegsFake.h"
30
Christopher Ferrisd226a512017-07-14 10:37:19 -070031namespace unwindstack {
32
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070033template <typename TypeParam>
34class MockDwarfSectionImpl : public DwarfSectionImpl<TypeParam> {
35 public:
36 MockDwarfSectionImpl(Memory* memory) : DwarfSectionImpl<TypeParam>(memory) {}
37 virtual ~MockDwarfSectionImpl() = default;
38
39 MOCK_METHOD2(Init, bool(uint64_t, uint64_t));
40
41 MOCK_METHOD2(GetFdeOffsetFromPc, bool(uint64_t, uint64_t*));
42
43 MOCK_METHOD1(GetFdeFromIndex, const DwarfFde*(size_t));
44
45 MOCK_METHOD1(IsCie32, bool(uint32_t));
46
47 MOCK_METHOD1(IsCie64, bool(uint64_t));
48
49 MOCK_METHOD1(GetCieOffsetFromFde32, uint64_t(uint32_t));
50
51 MOCK_METHOD1(GetCieOffsetFromFde64, uint64_t(uint64_t));
52
53 MOCK_METHOD1(AdjustPcFromFde, uint64_t(uint64_t));
54
55 void TestSetCachedCieEntry(uint64_t offset, const DwarfCie& cie) {
56 this->cie_entries_[offset] = cie;
57 }
58 void TestClearCachedCieEntry() { this->cie_entries_.clear(); }
59
60 void TestSetCachedFdeEntry(uint64_t offset, const DwarfFde& fde) {
61 this->fde_entries_[offset] = fde;
62 }
63 void TestClearCachedFdeEntry() { this->fde_entries_.clear(); }
64
65 void TestSetCachedCieLocRegs(uint64_t offset, const dwarf_loc_regs_t& loc_regs) {
66 this->cie_loc_regs_[offset] = loc_regs;
67 }
68 void TestClearCachedCieLocRegs() { this->cie_loc_regs_.clear(); }
69
70 void TestClearError() { this->last_error_ = DWARF_ERROR_NONE; }
71};
72
73template <typename TypeParam>
74class DwarfSectionImplTest : public ::testing::Test {
75 protected:
76 void SetUp() override {
77 memory_.Clear();
78 section_ = new MockDwarfSectionImpl<TypeParam>(&memory_);
79 ResetLogs();
80 }
81
82 void TearDown() override { delete section_; }
83
84 MemoryFake memory_;
85 MockDwarfSectionImpl<TypeParam>* section_ = nullptr;
86};
87TYPED_TEST_CASE_P(DwarfSectionImplTest);
88
89// NOTE: All test class variables need to be referenced as this->.
90
91TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) {
92 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070093 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070094 dwarf_loc_regs_t loc_regs;
95
96 regs.set_pc(0x100);
97 regs.set_sp(0x2000);
98 regs[5] = 0x20;
99 regs[9] = 0x3000;
100 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700101 bool finished;
102 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700103 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
104}
105
106TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) {
107 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700108 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700109 dwarf_loc_regs_t loc_regs;
110
111 regs.set_pc(0x100);
112 regs.set_sp(0x2000);
113 regs[5] = 0x20;
114 regs[9] = 0x3000;
115 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96});
116 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700117 bool finished;
118 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700119 EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->last_error());
120}
121
122TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) {
123 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700124 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700125 dwarf_loc_regs_t loc_regs;
126
127 regs.set_pc(0x100);
128 regs.set_sp(0x2000);
129 regs[5] = 0x20;
130 regs[9] = 0x3000;
131 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
132 TypeParam cfa_value = 0x12345;
133 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
134 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700135 bool finished;
136 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
137 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700138 EXPECT_EQ(0x12345U, regs.sp());
139 EXPECT_EQ(0x20U, regs.pc());
140}
141
142TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) {
143 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700144 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700145 dwarf_loc_regs_t loc_regs;
146
147 regs.set_pc(0x100);
148 regs.set_sp(0x2000);
149 regs[5] = 0x20;
150 regs[9] = 0x3000;
151 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
152 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700153 bool finished;
154 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
155 ASSERT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700156 EXPECT_EQ(0x80000000U, regs.sp());
157 EXPECT_EQ(0x20U, regs.pc());
158}
159
160TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) {
161 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700162 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700163 dwarf_loc_regs_t loc_regs;
164
165 regs.set_pc(0x100);
166 regs.set_sp(0x2000);
167 regs[5] = 0x20;
168 regs[9] = 0x3000;
169 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96});
170 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700171 bool finished;
172 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700173 EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->last_error());
174}
175
176TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) {
177 DwarfCie cie{.return_address_register = 60};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700178 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700179 dwarf_loc_regs_t loc_regs;
180
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700181 bool finished;
182 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700183 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
184}
185
186TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) {
187 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700188 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700189 dwarf_loc_regs_t loc_regs;
190
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700191 bool finished;
192 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700193 EXPECT_EQ(DWARF_ERROR_CFA_NOT_DEFINED, this->section_->last_error());
194}
195
196TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) {
197 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700198 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700199 dwarf_loc_regs_t loc_regs;
200
201 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700202 bool finished;
203 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700204 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
205
206 this->section_->TestClearError();
207 loc_regs.erase(CFA_REG);
208 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_INVALID, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700209 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700210 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
211
212 this->section_->TestClearError();
213 loc_regs.erase(CFA_REG);
214 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_OFFSET, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700215 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700216 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
217
218 this->section_->TestClearError();
219 loc_regs.erase(CFA_REG);
220 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700221 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700222 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
223}
224
225TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) {
226 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700227 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700228 dwarf_loc_regs_t loc_regs;
229
230 regs.set_pc(0x100);
231 regs.set_sp(0x2000);
232 regs[5] = 0x20;
233 regs[9] = 0x3000;
234 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {9, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700235 bool finished;
236 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
237 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700238 EXPECT_EQ(0x20U, regs.pc());
239 EXPECT_EQ(0x2000U, regs.sp());
240}
241
242TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) {
243 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700244 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700245 dwarf_loc_regs_t loc_regs;
246
247 regs.set_pc(0x100);
248 regs.set_sp(0x2000);
249 regs[5] = 0x20;
250 regs[6] = 0x4000;
251 regs[9] = 0x3000;
252 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {6, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700253 bool finished;
254 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
255 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700256 EXPECT_EQ(0x20U, regs.pc());
257 EXPECT_EQ(0x4000U, regs.sp());
258}
259
260TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) {
261 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700262 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700263 dwarf_loc_regs_t loc_regs;
264
265 regs.set_pc(0x100);
266 regs.set_sp(0x2000);
267 regs[8] = 0x10;
268 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
269 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 0}};
270 loc_regs[9] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700271 bool finished;
272 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700273 EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->last_error());
274}
275
276TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) {
277 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700278 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700279 dwarf_loc_regs_t loc_regs;
280
281 regs.set_pc(0x100);
282 regs.set_sp(0x2000);
283 regs[8] = 0x10;
284 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
285 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {10, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700286 bool finished;
287 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700288 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
289}
290
291TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) {
292 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700293 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700294 dwarf_loc_regs_t loc_regs;
295
296 if (sizeof(TypeParam) == sizeof(uint64_t)) {
297 this->memory_.SetData64(0x2150, 0x12345678abcdef00ULL);
298 } else {
299 this->memory_.SetData32(0x2150, 0x12345678);
300 }
301
302 regs.set_pc(0x100);
303 regs.set_sp(0x2000);
304 regs[3] = 0x234;
305 regs[5] = 0x10;
306 regs[8] = 0x2100;
307 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
308 loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0x100, 0}};
309 loc_regs[2] = DwarfLocation{DWARF_LOCATION_OFFSET, {0x50, 0}};
310 loc_regs[3] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700311 bool finished;
312 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
313 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700314 EXPECT_EQ(0x10U, regs.pc());
315 EXPECT_EQ(0x2100U, regs.sp());
316 EXPECT_EQ(0x2200U, regs[1]);
317 EXPECT_EQ(0x234U, regs[3]);
318 if (sizeof(TypeParam) == sizeof(uint64_t)) {
319 EXPECT_EQ(0x12345678abcdef00ULL, regs[2]);
320 } else {
321 EXPECT_EQ(0x12345678U, regs[2]);
322 }
323}
324
325TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) {
326 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700327 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700328 dwarf_loc_regs_t loc_regs;
329
330 regs.set_pc(0x100);
331 regs.set_sp(0x2000);
332 regs[5] = 0x20;
333 regs[8] = 0x10;
334 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
335 loc_regs[5] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700336 bool finished;
337 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
338 EXPECT_TRUE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700339 EXPECT_EQ(0U, regs.pc());
340 EXPECT_EQ(0x10U, regs.sp());
341}
342
Christopher Ferris2502a602017-10-23 13:51:54 -0700343TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) {
344 DwarfCie cie{.return_address_register = 5};
345 RegsImplFake<TypeParam> regs(10, 9);
346 dwarf_loc_regs_t loc_regs;
347
348 regs.set_pc(0x100);
349 regs.set_sp(0x2000);
350 regs[5] = 0;
351 regs[8] = 0x10;
352 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
353 bool finished;
354 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
355 EXPECT_TRUE(finished);
356 EXPECT_EQ(0U, regs.pc());
357 EXPECT_EQ(0x10U, regs.sp());
358}
359
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700360TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) {
361 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700362 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700363 dwarf_loc_regs_t loc_regs;
364
365 regs.set_pc(0x100);
366 regs.set_sp(0x2000);
367 regs[5] = 0x20;
368 regs[8] = 0x10;
369 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700370 bool finished;
371 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
372 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700373 EXPECT_EQ(0x20U, regs.pc());
374 EXPECT_EQ(0x10U, regs.sp());
375}
376
377TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) {
378 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700379 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700380 dwarf_loc_regs_t loc_regs;
381
382 regs.set_pc(0x100);
383 regs.set_sp(0x2000);
384 regs[5] = 0x20;
385 regs[8] = 0x10;
386 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
387 // This should not result in any errors.
388 loc_regs[20] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700389 bool finished;
390 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
391 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700392 EXPECT_EQ(0x20U, regs.pc());
393 EXPECT_EQ(0x10U, regs.sp());
394}
395
396TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) {
397 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700398 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700399 dwarf_loc_regs_t loc_regs;
400
401 regs.set_pc(0x100);
402 regs.set_sp(0x2000);
403 regs[8] = 0x3000;
404 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
405 TypeParam cfa_value = 0x12345;
406 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
407 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
408 loc_regs[5] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700409 bool finished;
410 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
411 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700412 EXPECT_EQ(0x3000U, regs.sp());
413 EXPECT_EQ(0x12345U, regs.pc());
414}
415
416TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) {
417 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700418 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700419 dwarf_loc_regs_t loc_regs;
420
421 regs.set_pc(0x100);
422 regs.set_sp(0x2000);
423 regs[8] = 0x3000;
424 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
425 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
426 loc_regs[5] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700427 bool finished;
428 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
429 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700430 EXPECT_EQ(0x3000U, regs.sp());
431 EXPECT_EQ(0x80000000U, regs.pc());
432}
433
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700434TYPED_TEST_P(DwarfSectionImplTest, GetCie_fail_should_not_cache) {
435 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
436 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
437 this->section_->TestClearError();
438 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
439 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
440}
441
442TYPED_TEST_P(DwarfSectionImplTest, GetCie_32_version_check) {
443 this->memory_.SetData32(0x5000, 0x100);
444 this->memory_.SetData32(0x5004, 0xffffffff);
445 this->memory_.SetData8(0x5008, 0x1);
446 this->memory_.SetData8(0x5009, '\0');
447 this->memory_.SetData8(0x500a, 4);
448 this->memory_.SetData8(0x500b, 8);
449 this->memory_.SetData8(0x500c, 0x20);
450
451 EXPECT_CALL(*this->section_, IsCie32(0xffffffff)).WillRepeatedly(::testing::Return(true));
452
453 const DwarfCie* cie = this->section_->GetCie(0x5000);
454 ASSERT_TRUE(cie != nullptr);
455 EXPECT_EQ(1U, cie->version);
456 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
457 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
458 EXPECT_EQ(0U, cie->segment_size);
459 EXPECT_EQ(1U, cie->augmentation_string.size());
460 EXPECT_EQ('\0', cie->augmentation_string[0]);
461 EXPECT_EQ(0U, cie->personality_handler);
462 EXPECT_EQ(0x500dU, cie->cfa_instructions_offset);
463 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
464 EXPECT_EQ(4U, cie->code_alignment_factor);
465 EXPECT_EQ(8, cie->data_alignment_factor);
466 EXPECT_EQ(0x20U, cie->return_address_register);
467 EXPECT_EQ(DWARF_ERROR_NONE, this->section_->last_error());
468
469 this->section_->TestClearCachedCieEntry();
470 // Set version to 0, 2, 5 and verify we fail.
471 this->memory_.SetData8(0x5008, 0x0);
472 this->section_->TestClearError();
473 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
474 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->last_error());
475
476 this->memory_.SetData8(0x5008, 0x2);
477 this->section_->TestClearError();
478 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
479 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->last_error());
480
481 this->memory_.SetData8(0x5008, 0x5);
482 this->section_->TestClearError();
483 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
484 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->last_error());
485}
486
487TYPED_TEST_P(DwarfSectionImplTest, GetCie_negative_data_alignment_factor) {
488 this->memory_.SetData32(0x5000, 0x100);
489 this->memory_.SetData32(0x5004, 0xffffffff);
490 this->memory_.SetData8(0x5008, 0x1);
491 this->memory_.SetData8(0x5009, '\0');
492 this->memory_.SetData8(0x500a, 4);
493 this->memory_.SetMemory(0x500b, std::vector<uint8_t>{0xfc, 0xff, 0xff, 0xff, 0x7f});
494 this->memory_.SetData8(0x5010, 0x20);
495
496 EXPECT_CALL(*this->section_, IsCie32(0xffffffff)).WillRepeatedly(::testing::Return(true));
497
498 const DwarfCie* cie = this->section_->GetCie(0x5000);
499 ASSERT_TRUE(cie != nullptr);
500 EXPECT_EQ(1U, cie->version);
501 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
502 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
503 EXPECT_EQ(0U, cie->segment_size);
504 EXPECT_EQ(1U, cie->augmentation_string.size());
505 EXPECT_EQ('\0', cie->augmentation_string[0]);
506 EXPECT_EQ(0U, cie->personality_handler);
507 EXPECT_EQ(0x5011U, cie->cfa_instructions_offset);
508 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
509 EXPECT_EQ(4U, cie->code_alignment_factor);
510 EXPECT_EQ(-4, cie->data_alignment_factor);
511 EXPECT_EQ(0x20U, cie->return_address_register);
512}
513
514TYPED_TEST_P(DwarfSectionImplTest, GetCie_64_no_augment) {
515 this->memory_.SetData32(0x8000, 0xffffffff);
516 this->memory_.SetData64(0x8004, 0x200);
517 this->memory_.SetData64(0x800c, 0xffffffff);
518 this->memory_.SetData8(0x8014, 0x1);
519 this->memory_.SetData8(0x8015, '\0');
520 this->memory_.SetData8(0x8016, 4);
521 this->memory_.SetData8(0x8017, 8);
522 this->memory_.SetData8(0x8018, 0x20);
523
524 EXPECT_CALL(*this->section_, IsCie64(0xffffffff)).WillRepeatedly(::testing::Return(true));
525
526 const DwarfCie* cie = this->section_->GetCie(0x8000);
527 ASSERT_TRUE(cie != nullptr);
528 EXPECT_EQ(1U, cie->version);
529 EXPECT_EQ(DW_EH_PE_sdata8, cie->fde_address_encoding);
530 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
531 EXPECT_EQ(0U, cie->segment_size);
532 EXPECT_EQ(1U, cie->augmentation_string.size());
533 EXPECT_EQ('\0', cie->augmentation_string[0]);
534 EXPECT_EQ(0U, cie->personality_handler);
535 EXPECT_EQ(0x8019U, cie->cfa_instructions_offset);
536 EXPECT_EQ(0x820cU, cie->cfa_instructions_end);
537 EXPECT_EQ(4U, cie->code_alignment_factor);
538 EXPECT_EQ(8, cie->data_alignment_factor);
539 EXPECT_EQ(0x20U, cie->return_address_register);
540}
541
542TYPED_TEST_P(DwarfSectionImplTest, GetCie_augment) {
543 this->memory_.SetData32(0x5000, 0x100);
544 this->memory_.SetData32(0x5004, 0xffffffff);
545 this->memory_.SetData8(0x5008, 0x1);
546 this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'});
547 this->memory_.SetData8(0x500e, 4);
548 this->memory_.SetData8(0x500f, 8);
549 this->memory_.SetData8(0x5010, 0x10);
550 // Augment length.
551 this->memory_.SetData8(0x5011, 0xf);
552 // L data.
553 this->memory_.SetData8(0x5012, DW_EH_PE_textrel | DW_EH_PE_udata2);
554 // P data.
555 this->memory_.SetData8(0x5013, DW_EH_PE_udata4);
556 this->memory_.SetData32(0x5014, 0x12345678);
557 // R data.
558 this->memory_.SetData8(0x5018, DW_EH_PE_udata2);
559
560 EXPECT_CALL(*this->section_, IsCie32(0xffffffff)).WillRepeatedly(::testing::Return(true));
561
562 const DwarfCie* cie = this->section_->GetCie(0x5000);
563 ASSERT_TRUE(cie != nullptr);
564 EXPECT_EQ(1U, cie->version);
565 EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding);
566 EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding);
567 EXPECT_EQ(0U, cie->segment_size);
568 EXPECT_EQ(5U, cie->augmentation_string.size());
569 EXPECT_EQ('z', cie->augmentation_string[0]);
570 EXPECT_EQ('L', cie->augmentation_string[1]);
571 EXPECT_EQ('P', cie->augmentation_string[2]);
572 EXPECT_EQ('R', cie->augmentation_string[3]);
573 EXPECT_EQ('\0', cie->augmentation_string[4]);
574 EXPECT_EQ(0x12345678U, cie->personality_handler);
575 EXPECT_EQ(0x5021U, cie->cfa_instructions_offset);
576 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
577 EXPECT_EQ(4U, cie->code_alignment_factor);
578 EXPECT_EQ(8, cie->data_alignment_factor);
579 EXPECT_EQ(0x10U, cie->return_address_register);
580}
581
582TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_3) {
583 this->memory_.SetData32(0x5000, 0x100);
584 this->memory_.SetData32(0x5004, 0xffffffff);
585 this->memory_.SetData8(0x5008, 0x3);
586 this->memory_.SetData8(0x5009, '\0');
587 this->memory_.SetData8(0x500a, 4);
588 this->memory_.SetData8(0x500b, 8);
589 this->memory_.SetMemory(0x500c, std::vector<uint8_t>{0x81, 0x03});
590
591 EXPECT_CALL(*this->section_, IsCie32(0xffffffff)).WillRepeatedly(::testing::Return(true));
592
593 const DwarfCie* cie = this->section_->GetCie(0x5000);
594 ASSERT_TRUE(cie != nullptr);
595 EXPECT_EQ(3U, cie->version);
596 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
597 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
598 EXPECT_EQ(0U, cie->segment_size);
599 EXPECT_EQ(1U, cie->augmentation_string.size());
600 EXPECT_EQ('\0', cie->augmentation_string[0]);
601 EXPECT_EQ(0U, cie->personality_handler);
602 EXPECT_EQ(0x500eU, cie->cfa_instructions_offset);
603 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
604 EXPECT_EQ(4U, cie->code_alignment_factor);
605 EXPECT_EQ(8, cie->data_alignment_factor);
606 EXPECT_EQ(0x181U, cie->return_address_register);
607}
608
609TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_4) {
610 this->memory_.SetData32(0x5000, 0x100);
611 this->memory_.SetData32(0x5004, 0xffffffff);
612 this->memory_.SetData8(0x5008, 0x4);
613 this->memory_.SetData8(0x5009, '\0');
614 this->memory_.SetData8(0x500a, 4);
615 this->memory_.SetData8(0x500b, 0x13);
616 this->memory_.SetData8(0x500c, 4);
617 this->memory_.SetData8(0x500d, 8);
618 this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x81, 0x03});
619
620 EXPECT_CALL(*this->section_, IsCie32(0xffffffff)).WillRepeatedly(::testing::Return(true));
621
622 const DwarfCie* cie = this->section_->GetCie(0x5000);
623 ASSERT_TRUE(cie != nullptr);
624 EXPECT_EQ(4U, cie->version);
625 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
626 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
627 EXPECT_EQ(0x13U, cie->segment_size);
628 EXPECT_EQ(1U, cie->augmentation_string.size());
629 EXPECT_EQ('\0', cie->augmentation_string[0]);
630 EXPECT_EQ(0U, cie->personality_handler);
631 EXPECT_EQ(0x5010U, cie->cfa_instructions_offset);
632 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
633 EXPECT_EQ(4U, cie->code_alignment_factor);
634 EXPECT_EQ(8, cie->data_alignment_factor);
635 EXPECT_EQ(0x181U, cie->return_address_register);
636}
637
638TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) {
639 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
640 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
641 this->section_->TestClearError();
642 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
643 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
644}
645
646TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment) {
647 this->memory_.SetData32(0x4000, 0x20);
648 this->memory_.SetData32(0x4004, 0x8000);
649 this->memory_.SetData32(0x4008, 0x5000);
650 this->memory_.SetData32(0x400c, 0x100);
651
652 EXPECT_CALL(*this->section_, IsCie32(0x8000)).WillOnce(::testing::Return(false));
653 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
654 DwarfCie cie{};
655 cie.fde_address_encoding = DW_EH_PE_udata4;
656 this->section_->TestSetCachedCieEntry(0x8000, cie);
657 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
658
659 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
660 ASSERT_TRUE(fde != nullptr);
661 ASSERT_TRUE(fde->cie != nullptr);
662 EXPECT_EQ(0x4010U, fde->cfa_instructions_offset);
663 EXPECT_EQ(0x4024U, fde->cfa_instructions_end);
664 EXPECT_EQ(0x5000U, fde->pc_start);
665 EXPECT_EQ(0x5100U, fde->pc_end);
666 EXPECT_EQ(0x8000U, fde->cie_offset);
667 EXPECT_EQ(0U, fde->lsda_address);
668}
669
670TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment_non_zero_segment_size) {
671 this->memory_.SetData32(0x4000, 0x30);
672 this->memory_.SetData32(0x4004, 0x8000);
673 this->memory_.SetData32(0x4018, 0x5000);
674 this->memory_.SetData32(0x401c, 0x100);
675
676 EXPECT_CALL(*this->section_, IsCie32(0x8000)).WillOnce(::testing::Return(false));
677 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
678 DwarfCie cie{};
679 cie.fde_address_encoding = DW_EH_PE_udata4;
680 cie.segment_size = 0x10;
681 this->section_->TestSetCachedCieEntry(0x8000, cie);
682 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
683
684 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
685 ASSERT_TRUE(fde != nullptr);
686 ASSERT_TRUE(fde->cie != nullptr);
687 EXPECT_EQ(0x4020U, fde->cfa_instructions_offset);
688 EXPECT_EQ(0x4034U, fde->cfa_instructions_end);
689 EXPECT_EQ(0x5000U, fde->pc_start);
690 EXPECT_EQ(0x5100U, fde->pc_end);
691 EXPECT_EQ(0x8000U, fde->cie_offset);
692 EXPECT_EQ(0U, fde->lsda_address);
693}
694
695TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_augment) {
696 this->memory_.SetData32(0x4000, 0x100);
697 this->memory_.SetData32(0x4004, 0x8000);
698 this->memory_.SetData32(0x4008, 0x5000);
699 this->memory_.SetData32(0x400c, 0x100);
700 this->memory_.SetMemory(0x4010, std::vector<uint8_t>{0x82, 0x01});
701 this->memory_.SetData16(0x4012, 0x1234);
702
703 EXPECT_CALL(*this->section_, IsCie32(0x8000)).WillOnce(::testing::Return(false));
704 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
705 DwarfCie cie{};
706 cie.fde_address_encoding = DW_EH_PE_udata4;
707 cie.augmentation_string.push_back('z');
708 cie.lsda_encoding = DW_EH_PE_udata2;
709 this->section_->TestSetCachedCieEntry(0x8000, cie);
710 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
711
712 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
713 ASSERT_TRUE(fde != nullptr);
714 ASSERT_TRUE(fde->cie != nullptr);
715 EXPECT_EQ(0x4094U, fde->cfa_instructions_offset);
716 EXPECT_EQ(0x4104U, fde->cfa_instructions_end);
717 EXPECT_EQ(0x5000U, fde->pc_start);
718 EXPECT_EQ(0x5100U, fde->pc_end);
719 EXPECT_EQ(0x8000U, fde->cie_offset);
720 EXPECT_EQ(0x1234U, fde->lsda_address);
721}
722
723TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_64_no_augment) {
724 this->memory_.SetData32(0x4000, 0xffffffff);
725 this->memory_.SetData64(0x4004, 0x100);
726 this->memory_.SetData64(0x400c, 0x12345678);
727 this->memory_.SetData32(0x4014, 0x5000);
728 this->memory_.SetData32(0x4018, 0x100);
729
730 EXPECT_CALL(*this->section_, IsCie64(0x12345678)).WillOnce(::testing::Return(false));
731 EXPECT_CALL(*this->section_, GetCieOffsetFromFde64(0x12345678))
732 .WillOnce(::testing::Return(0x12345678));
733 DwarfCie cie{};
734 cie.fde_address_encoding = DW_EH_PE_udata4;
735 this->section_->TestSetCachedCieEntry(0x12345678, cie);
736 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
737
738 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
739 ASSERT_TRUE(fde != nullptr);
740 ASSERT_TRUE(fde->cie != nullptr);
741 EXPECT_EQ(0x401cU, fde->cfa_instructions_offset);
742 EXPECT_EQ(0x410cU, fde->cfa_instructions_end);
743 EXPECT_EQ(0x5000U, fde->pc_start);
744 EXPECT_EQ(0x5100U, fde->pc_end);
745 EXPECT_EQ(0x12345678U, fde->cie_offset);
746 EXPECT_EQ(0U, fde->lsda_address);
747}
748
749TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_cached) {
750 DwarfCie cie{};
751 cie.fde_address_encoding = DW_EH_PE_udata4;
752 cie.augmentation_string.push_back('z');
753 cie.lsda_encoding = DW_EH_PE_udata2;
754
755 DwarfFde fde_cached{};
756 fde_cached.cfa_instructions_offset = 0x1000;
757 fde_cached.cfa_instructions_end = 0x1100;
758 fde_cached.pc_start = 0x9000;
759 fde_cached.pc_end = 0x9400;
760 fde_cached.cie_offset = 0x30000;
761 fde_cached.cie = &cie;
762 this->section_->TestSetCachedFdeEntry(0x6000, fde_cached);
763
764 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x6000);
765 ASSERT_TRUE(fde != nullptr);
766 ASSERT_EQ(&cie, fde->cie);
767 EXPECT_EQ(0x1000U, fde->cfa_instructions_offset);
768 EXPECT_EQ(0x1100U, fde->cfa_instructions_end);
769 EXPECT_EQ(0x9000U, fde->pc_start);
770 EXPECT_EQ(0x9400U, fde->pc_end);
771 EXPECT_EQ(0x30000U, fde->cie_offset);
772}
773
774TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_not_cached) {
775 DwarfCie cie{};
776 cie.cfa_instructions_offset = 0x3000;
777 cie.cfa_instructions_end = 0x3002;
778 DwarfFde fde{};
779 fde.cie = &cie;
780 fde.cie_offset = 0x8000;
781 fde.cfa_instructions_offset = 0x6000;
782 fde.cfa_instructions_end = 0x6002;
783
784 this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x09, 0x02, 0x01});
785 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
786
787 dwarf_loc_regs_t loc_regs;
788 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
789 ASSERT_EQ(2U, loc_regs.size());
790
791 auto entry = loc_regs.find(2);
792 ASSERT_NE(entry, loc_regs.end());
793 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
794 ASSERT_EQ(1U, entry->second.values[0]);
795
796 entry = loc_regs.find(4);
797 ASSERT_NE(entry, loc_regs.end());
798 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
799 ASSERT_EQ(3U, entry->second.values[0]);
800}
801
802TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) {
803 DwarfCie cie{};
804 cie.cfa_instructions_offset = 0x3000;
805 cie.cfa_instructions_end = 0x3002;
806 DwarfFde fde{};
807 fde.cie = &cie;
808 fde.cie_offset = 0x8000;
809 fde.cfa_instructions_offset = 0x6000;
810 fde.cfa_instructions_end = 0x6002;
811
812 dwarf_loc_regs_t cie_loc_regs{{6, {DWARF_LOCATION_REGISTER, {4, 0}}}};
813 this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs);
814 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
815
816 dwarf_loc_regs_t loc_regs;
817 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
818 ASSERT_EQ(2U, loc_regs.size());
819
820 auto entry = loc_regs.find(6);
821 ASSERT_NE(entry, loc_regs.end());
822 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
823 ASSERT_EQ(4U, entry->second.values[0]);
824
825 entry = loc_regs.find(4);
826 ASSERT_NE(entry, loc_regs.end());
827 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
828 ASSERT_EQ(3U, entry->second.values[0]);
829}
830
831TYPED_TEST_P(DwarfSectionImplTest, Log) {
832 DwarfCie cie{};
833 cie.cfa_instructions_offset = 0x5000;
834 cie.cfa_instructions_end = 0x5001;
835 DwarfFde fde{};
836 fde.cie = &cie;
837 fde.cfa_instructions_offset = 0x6000;
838 fde.cfa_instructions_end = 0x6001;
839
840 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x00});
841 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0xc2});
842 ASSERT_TRUE(this->section_->Log(2, 0x1000, 0x1000, &fde));
843
844 ASSERT_EQ(
845 "4 unwind DW_CFA_nop\n"
846 "4 unwind Raw Data: 0x00\n"
847 "4 unwind DW_CFA_restore register(2)\n"
848 "4 unwind Raw Data: 0xc2\n",
849 GetFakeLogPrint());
850 ASSERT_EQ("", GetFakeLogBuf());
851}
852
853REGISTER_TYPED_TEST_CASE_P(
854 DwarfSectionImplTest, Eval_cfa_expr_eval_fail, Eval_cfa_expr_no_stack,
855 Eval_cfa_expr_is_register, Eval_cfa_expr, Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa,
856 Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection,
857 Eval_invalid_register, Eval_different_reg_locations, Eval_return_address_undefined,
Christopher Ferris2502a602017-10-23 13:51:54 -0700858 Eval_pc_zero, Eval_return_address, Eval_ignore_large_reg_loc, Eval_reg_expr, Eval_reg_val_expr,
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700859 GetCie_fail_should_not_cache, GetCie_32_version_check, GetCie_negative_data_alignment_factor,
860 GetCie_64_no_augment, GetCie_augment, GetCie_version_3, GetCie_version_4,
861 GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700862 GetFdeFromOffset_32_no_augment_non_zero_segment_size, GetFdeFromOffset_32_augment,
863 GetFdeFromOffset_64_no_augment, GetFdeFromOffset_cached, GetCfaLocationInfo_cie_not_cached,
864 GetCfaLocationInfo_cie_cached, Log);
865
866typedef ::testing::Types<uint32_t, uint64_t> DwarfSectionImplTestTypes;
867INSTANTIATE_TYPED_TEST_CASE_P(, DwarfSectionImplTest, DwarfSectionImplTestTypes);
Christopher Ferrisd226a512017-07-14 10:37:19 -0700868
869} // namespace unwindstack