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
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include <unwindstack/DwarfError.h>
23 #include <unwindstack/DwarfSection.h>
24
25 #include "DwarfEncoding.h"
26
27 #include "LogFake.h"
28 #include "MemoryFake.h"
29 #include "RegsFake.h"
30
31 namespace unwindstack {
32
33 template <typename TypeParam>
34 class MockDwarfSectionImpl : public DwarfSectionImpl<TypeParam> {
35 public:
MockDwarfSectionImpl(Memory * memory)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(GetCieOffsetFromFde32, uint64_t(uint32_t));
46
47 MOCK_METHOD1(GetCieOffsetFromFde64, uint64_t(uint64_t));
48
49 MOCK_METHOD1(AdjustPcFromFde, uint64_t(uint64_t));
50
TestSetCie32Value(uint32_t value32)51 void TestSetCie32Value(uint32_t value32) { this->cie32_value_ = value32; }
52
TestSetCie64Value(uint64_t value64)53 void TestSetCie64Value(uint64_t value64) { this->cie64_value_ = value64; }
54
TestSetCachedCieEntry(uint64_t offset,const DwarfCie & cie)55 void TestSetCachedCieEntry(uint64_t offset, const DwarfCie& cie) {
56 this->cie_entries_[offset] = cie;
57 }
TestClearCachedCieEntry()58 void TestClearCachedCieEntry() { this->cie_entries_.clear(); }
59
TestSetCachedFdeEntry(uint64_t offset,const DwarfFde & fde)60 void TestSetCachedFdeEntry(uint64_t offset, const DwarfFde& fde) {
61 this->fde_entries_[offset] = fde;
62 }
TestClearCachedFdeEntry()63 void TestClearCachedFdeEntry() { this->fde_entries_.clear(); }
64
TestSetCachedCieLocRegs(uint64_t offset,const dwarf_loc_regs_t & loc_regs)65 void TestSetCachedCieLocRegs(uint64_t offset, const dwarf_loc_regs_t& loc_regs) {
66 this->cie_loc_regs_[offset] = loc_regs;
67 }
TestClearCachedCieLocRegs()68 void TestClearCachedCieLocRegs() { this->cie_loc_regs_.clear(); }
69
TestClearError()70 void TestClearError() { this->last_error_.code = DWARF_ERROR_NONE; }
71 };
72
73 template <typename TypeParam>
74 class DwarfSectionImplTest : public ::testing::Test {
75 protected:
SetUp()76 void SetUp() override {
77 memory_.Clear();
78 section_ = new MockDwarfSectionImpl<TypeParam>(&memory_);
79 ResetLogs();
80 section_->TestSetCie32Value(static_cast<uint32_t>(-1));
81 section_->TestSetCie64Value(static_cast<uint64_t>(-1));
82 }
83
TearDown()84 void TearDown() override { delete section_; }
85
86 MemoryFake memory_;
87 MockDwarfSectionImpl<TypeParam>* section_ = nullptr;
88 };
89 TYPED_TEST_CASE_P(DwarfSectionImplTest);
90
91 // NOTE: All test class variables need to be referenced as this->.
92
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_expr_eval_fail)93 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) {
94 DwarfCie cie{.version = 3, .return_address_register = 5};
95 RegsImplFake<TypeParam> regs(10);
96 dwarf_loc_regs_t loc_regs;
97
98 regs.set_pc(0x100);
99 regs.set_sp(0x2000);
100 regs[5] = 0x20;
101 regs[9] = 0x3000;
102 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}};
103 bool finished;
104 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
105 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
106 EXPECT_EQ(0x5000U, this->section_->LastErrorAddress());
107 }
108
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_expr_no_stack)109 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) {
110 DwarfCie cie{.version = 3, .return_address_register = 5};
111 RegsImplFake<TypeParam> regs(10);
112 dwarf_loc_regs_t loc_regs;
113
114 regs.set_pc(0x100);
115 regs.set_sp(0x2000);
116 regs[5] = 0x20;
117 regs[9] = 0x3000;
118 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96});
119 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}};
120 bool finished;
121 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
122 EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->LastErrorCode());
123 }
124
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_expr)125 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) {
126 DwarfCie cie{.version = 3, .return_address_register = 5};
127 RegsImplFake<TypeParam> regs(10);
128 dwarf_loc_regs_t loc_regs;
129
130 regs.set_pc(0x100);
131 regs.set_sp(0x2000);
132 regs[5] = 0x20;
133 regs[9] = 0x3000;
134 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
135 TypeParam cfa_value = 0x12345;
136 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
137 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}};
138 bool finished;
139 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
140 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
141 }
142
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_val_expr)143 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) {
144 DwarfCie cie{.version = 3, .return_address_register = 5};
145 RegsImplFake<TypeParam> regs(10);
146 dwarf_loc_regs_t loc_regs;
147
148 regs.set_pc(0x100);
149 regs.set_sp(0x2000);
150 regs[5] = 0x20;
151 regs[9] = 0x3000;
152 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
153 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}};
154 bool finished;
155 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
156 ASSERT_FALSE(finished);
157 EXPECT_EQ(0x80000000U, regs.sp());
158 EXPECT_EQ(0x20U, regs.pc());
159 }
160
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_expr_is_register)161 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) {
162 DwarfCie cie{.version = 3, .return_address_register = 5};
163 RegsImplFake<TypeParam> regs(10);
164 dwarf_loc_regs_t loc_regs;
165
166 regs.set_pc(0x100);
167 regs.set_sp(0x2000);
168 regs[5] = 0x20;
169 regs[9] = 0x3000;
170 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96});
171 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x2, 0x5002}};
172 bool finished;
173 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
174 EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->LastErrorCode());
175 }
176
TYPED_TEST_P(DwarfSectionImplTest,Eval_bad_regs)177 TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) {
178 DwarfCie cie{.return_address_register = 60};
179 RegsImplFake<TypeParam> regs(10);
180 dwarf_loc_regs_t loc_regs;
181
182 bool finished;
183 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
184 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
185 }
186
TYPED_TEST_P(DwarfSectionImplTest,Eval_no_cfa)187 TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) {
188 DwarfCie cie{.return_address_register = 5};
189 RegsImplFake<TypeParam> regs(10);
190 dwarf_loc_regs_t loc_regs;
191
192 bool finished;
193 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
194 EXPECT_EQ(DWARF_ERROR_CFA_NOT_DEFINED, this->section_->LastErrorCode());
195 }
196
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_bad)197 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) {
198 DwarfCie cie{.return_address_register = 5};
199 RegsImplFake<TypeParam> regs(10);
200 dwarf_loc_regs_t loc_regs;
201
202 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}};
203 bool finished;
204 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
205 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
206
207 this->section_->TestClearError();
208 loc_regs.erase(CFA_REG);
209 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_INVALID, {0, 0}};
210 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
211 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
212
213 this->section_->TestClearError();
214 loc_regs.erase(CFA_REG);
215 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_OFFSET, {0, 0}};
216 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
217 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
218
219 this->section_->TestClearError();
220 loc_regs.erase(CFA_REG);
221 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0, 0}};
222 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
223 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
224 }
225
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_register_prev)226 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) {
227 DwarfCie cie{.return_address_register = 5};
228 RegsImplFake<TypeParam> regs(10);
229 dwarf_loc_regs_t loc_regs;
230
231 regs.set_pc(0x100);
232 regs.set_sp(0x2000);
233 regs[5] = 0x20;
234 regs[9] = 0x3000;
235 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {9, 0}};
236 bool finished;
237 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
238 EXPECT_FALSE(finished);
239 EXPECT_EQ(0x20U, regs.pc());
240 EXPECT_EQ(0x3000U, regs.sp());
241 }
242
TYPED_TEST_P(DwarfSectionImplTest,Eval_cfa_register_from_value)243 TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) {
244 DwarfCie cie{.return_address_register = 5};
245 RegsImplFake<TypeParam> regs(10);
246 dwarf_loc_regs_t loc_regs;
247
248 regs.set_pc(0x100);
249 regs.set_sp(0x2000);
250 regs[5] = 0x20;
251 regs[6] = 0x4000;
252 regs[9] = 0x3000;
253 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {6, 0}};
254 bool finished;
255 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
256 EXPECT_FALSE(finished);
257 EXPECT_EQ(0x20U, regs.pc());
258 EXPECT_EQ(0x4000U, regs.sp());
259 }
260
TYPED_TEST_P(DwarfSectionImplTest,Eval_double_indirection)261 TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) {
262 DwarfCie cie{.return_address_register = 5};
263 RegsImplFake<TypeParam> regs(10);
264 dwarf_loc_regs_t loc_regs;
265
266 regs.set_pc(0x100);
267 regs.set_sp(0x2000);
268 regs[1] = 0x100;
269 regs[3] = 0x300;
270 regs[8] = 0x10;
271 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
272 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 1}};
273 loc_regs[9] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}};
274 bool finished;
275 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
276 EXPECT_EQ(0x301U, regs[1]);
277 EXPECT_EQ(0x300U, regs[3]);
278 EXPECT_EQ(0x10U, regs[8]);
279 EXPECT_EQ(0x102U, regs[9]);
280 }
281
TYPED_TEST_P(DwarfSectionImplTest,Eval_register_reference_chain)282 TYPED_TEST_P(DwarfSectionImplTest, Eval_register_reference_chain) {
283 DwarfCie cie{.return_address_register = 5};
284 RegsImplFake<TypeParam> regs(10);
285 dwarf_loc_regs_t loc_regs;
286
287 regs.set_pc(0x100);
288 regs.set_sp(0x2000);
289 regs[0] = 0x10;
290 regs[1] = 0x20;
291 regs[2] = 0x30;
292 regs[3] = 0x40;
293 regs[4] = 0x50;
294 regs[5] = 0x60;
295 regs[8] = 0x20;
296 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
297 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {0, 1}};
298 loc_regs[2] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 2}};
299 loc_regs[3] = DwarfLocation{DWARF_LOCATION_REGISTER, {2, 3}};
300 loc_regs[4] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 4}};
301 loc_regs[5] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 5}};
302 bool finished;
303 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
304 EXPECT_EQ(0x10U, regs[0]);
305 EXPECT_EQ(0x11U, regs[1]);
306 EXPECT_EQ(0x22U, regs[2]);
307 EXPECT_EQ(0x33U, regs[3]);
308 EXPECT_EQ(0x44U, regs[4]);
309 EXPECT_EQ(0x55U, regs[5]);
310 EXPECT_EQ(0x20U, regs[8]);
311 }
312
TYPED_TEST_P(DwarfSectionImplTest,Eval_dex_pc)313 TYPED_TEST_P(DwarfSectionImplTest, Eval_dex_pc) {
314 DwarfCie cie{.return_address_register = 5};
315 RegsImplFake<TypeParam> regs(10);
316 dwarf_loc_regs_t loc_regs;
317
318 regs.set_pc(0x100);
319 regs.set_sp(0x2000);
320 regs[0] = 0x10;
321 regs[8] = 0x20;
322 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
323 loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x8, 0x5008}};
324 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '1', 0x13, 0x08, 0x11});
325 bool finished;
326 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
327 EXPECT_EQ(0x10U, regs[0]);
328 EXPECT_EQ(0x20U, regs[8]);
329 EXPECT_EQ(0x11U, regs.dex_pc());
330 }
331
TYPED_TEST_P(DwarfSectionImplTest,Eval_invalid_register)332 TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) {
333 DwarfCie cie{.return_address_register = 5};
334 RegsImplFake<TypeParam> regs(10);
335 dwarf_loc_regs_t loc_regs;
336
337 regs.set_pc(0x100);
338 regs.set_sp(0x2000);
339 regs[8] = 0x10;
340 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
341 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {10, 0}};
342 bool finished;
343 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
344 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->LastErrorCode());
345 }
346
TYPED_TEST_P(DwarfSectionImplTest,Eval_different_reg_locations)347 TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) {
348 DwarfCie cie{.return_address_register = 5};
349 RegsImplFake<TypeParam> regs(10);
350 dwarf_loc_regs_t loc_regs;
351
352 if (sizeof(TypeParam) == sizeof(uint64_t)) {
353 this->memory_.SetData64(0x2150, 0x12345678abcdef00ULL);
354 } else {
355 this->memory_.SetData32(0x2150, 0x12345678);
356 }
357
358 regs.set_pc(0x100);
359 regs.set_sp(0x2000);
360 regs[3] = 0x234;
361 regs[5] = 0x10;
362 regs[8] = 0x2100;
363 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
364 loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0x100, 0}};
365 loc_regs[2] = DwarfLocation{DWARF_LOCATION_OFFSET, {0x50, 0}};
366 loc_regs[3] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
367 bool finished;
368 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
369 EXPECT_FALSE(finished);
370 EXPECT_EQ(0x10U, regs.pc());
371 EXPECT_EQ(0x2100U, regs.sp());
372 EXPECT_EQ(0x2200U, regs[1]);
373 EXPECT_EQ(0x234U, regs[3]);
374 if (sizeof(TypeParam) == sizeof(uint64_t)) {
375 EXPECT_EQ(0x12345678abcdef00ULL, regs[2]);
376 } else {
377 EXPECT_EQ(0x12345678U, regs[2]);
378 }
379 }
380
TYPED_TEST_P(DwarfSectionImplTest,Eval_return_address_undefined)381 TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) {
382 DwarfCie cie{.return_address_register = 5};
383 RegsImplFake<TypeParam> regs(10);
384 dwarf_loc_regs_t loc_regs;
385
386 regs.set_pc(0x100);
387 regs.set_sp(0x2000);
388 regs[5] = 0x20;
389 regs[8] = 0x10;
390 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
391 loc_regs[5] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
392 bool finished;
393 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
394 EXPECT_TRUE(finished);
395 EXPECT_EQ(0U, regs.pc());
396 EXPECT_EQ(0x10U, regs.sp());
397 }
398
TYPED_TEST_P(DwarfSectionImplTest,Eval_pc_zero)399 TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) {
400 DwarfCie cie{.return_address_register = 5};
401 RegsImplFake<TypeParam> regs(10);
402 dwarf_loc_regs_t loc_regs;
403
404 regs.set_pc(0x100);
405 regs.set_sp(0x2000);
406 regs[5] = 0;
407 regs[8] = 0x10;
408 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
409 bool finished;
410 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
411 EXPECT_TRUE(finished);
412 EXPECT_EQ(0U, regs.pc());
413 EXPECT_EQ(0x10U, regs.sp());
414 }
415
TYPED_TEST_P(DwarfSectionImplTest,Eval_return_address)416 TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) {
417 DwarfCie cie{.return_address_register = 5};
418 RegsImplFake<TypeParam> regs(10);
419 dwarf_loc_regs_t loc_regs;
420
421 regs.set_pc(0x100);
422 regs.set_sp(0x2000);
423 regs[5] = 0x20;
424 regs[8] = 0x10;
425 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
426 bool finished;
427 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
428 EXPECT_FALSE(finished);
429 EXPECT_EQ(0x20U, regs.pc());
430 EXPECT_EQ(0x10U, regs.sp());
431 }
432
TYPED_TEST_P(DwarfSectionImplTest,Eval_ignore_large_reg_loc)433 TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) {
434 DwarfCie cie{.return_address_register = 5};
435 RegsImplFake<TypeParam> regs(10);
436 dwarf_loc_regs_t loc_regs;
437
438 regs.set_pc(0x100);
439 regs.set_sp(0x2000);
440 regs[5] = 0x20;
441 regs[8] = 0x10;
442 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
443 // This should not result in any errors.
444 loc_regs[20] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
445 bool finished;
446 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
447 EXPECT_FALSE(finished);
448 EXPECT_EQ(0x20U, regs.pc());
449 EXPECT_EQ(0x10U, regs.sp());
450 }
451
TYPED_TEST_P(DwarfSectionImplTest,Eval_reg_expr)452 TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) {
453 DwarfCie cie{.version = 3, .return_address_register = 5};
454 RegsImplFake<TypeParam> regs(10);
455 dwarf_loc_regs_t loc_regs;
456
457 regs.set_pc(0x100);
458 regs.set_sp(0x2000);
459 regs[8] = 0x3000;
460 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
461 TypeParam cfa_value = 0x12345;
462 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
463 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
464 loc_regs[5] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5004}};
465 bool finished;
466 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
467 EXPECT_FALSE(finished);
468 EXPECT_EQ(0x3000U, regs.sp());
469 EXPECT_EQ(0x12345U, regs.pc());
470 }
471
TYPED_TEST_P(DwarfSectionImplTest,Eval_reg_val_expr)472 TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) {
473 DwarfCie cie{.version = 3, .return_address_register = 5};
474 RegsImplFake<TypeParam> regs(10);
475 dwarf_loc_regs_t loc_regs;
476
477 regs.set_pc(0x100);
478 regs.set_sp(0x2000);
479 regs[8] = 0x3000;
480 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
481 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
482 loc_regs[5] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5004}};
483 bool finished;
484 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, ®s, &finished));
485 EXPECT_FALSE(finished);
486 EXPECT_EQ(0x3000U, regs.sp());
487 EXPECT_EQ(0x80000000U, regs.pc());
488 }
489
TYPED_TEST_P(DwarfSectionImplTest,GetCie_fail_should_not_cache)490 TYPED_TEST_P(DwarfSectionImplTest, GetCie_fail_should_not_cache) {
491 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
492 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
493 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
494 this->section_->TestClearError();
495 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
496 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
497 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
498 }
499
TYPED_TEST_P(DwarfSectionImplTest,GetCie_32_version_check)500 TYPED_TEST_P(DwarfSectionImplTest, GetCie_32_version_check) {
501 this->memory_.SetData32(0x5000, 0x100);
502 this->memory_.SetData32(0x5004, 0xffffffff);
503 this->memory_.SetData8(0x5008, 0x1);
504 this->memory_.SetData8(0x5009, '\0');
505 this->memory_.SetData8(0x500a, 4);
506 this->memory_.SetData8(0x500b, 8);
507 this->memory_.SetData8(0x500c, 0x20);
508
509 const DwarfCie* cie = this->section_->GetCie(0x5000);
510 ASSERT_TRUE(cie != nullptr);
511 EXPECT_EQ(1U, cie->version);
512 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
513 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
514 EXPECT_EQ(0U, cie->segment_size);
515 EXPECT_EQ(1U, cie->augmentation_string.size());
516 EXPECT_EQ('\0', cie->augmentation_string[0]);
517 EXPECT_EQ(0U, cie->personality_handler);
518 EXPECT_EQ(0x500dU, cie->cfa_instructions_offset);
519 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
520 EXPECT_EQ(4U, cie->code_alignment_factor);
521 EXPECT_EQ(8, cie->data_alignment_factor);
522 EXPECT_EQ(0x20U, cie->return_address_register);
523 EXPECT_EQ(DWARF_ERROR_NONE, this->section_->LastErrorCode());
524
525 this->section_->TestClearCachedCieEntry();
526 // Set version to 0, 2, 5 and verify we fail.
527 this->memory_.SetData8(0x5008, 0x0);
528 this->section_->TestClearError();
529 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
530 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
531
532 this->memory_.SetData8(0x5008, 0x2);
533 this->section_->TestClearError();
534 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
535 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
536
537 this->memory_.SetData8(0x5008, 0x5);
538 this->section_->TestClearError();
539 ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
540 EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
541 }
542
TYPED_TEST_P(DwarfSectionImplTest,GetCie_negative_data_alignment_factor)543 TYPED_TEST_P(DwarfSectionImplTest, GetCie_negative_data_alignment_factor) {
544 this->memory_.SetData32(0x5000, 0x100);
545 this->memory_.SetData32(0x5004, 0xffffffff);
546 this->memory_.SetData8(0x5008, 0x1);
547 this->memory_.SetData8(0x5009, '\0');
548 this->memory_.SetData8(0x500a, 4);
549 this->memory_.SetMemory(0x500b, std::vector<uint8_t>{0xfc, 0xff, 0xff, 0xff, 0x7f});
550 this->memory_.SetData8(0x5010, 0x20);
551
552 const DwarfCie* cie = this->section_->GetCie(0x5000);
553 ASSERT_TRUE(cie != nullptr);
554 EXPECT_EQ(1U, cie->version);
555 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
556 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
557 EXPECT_EQ(0U, cie->segment_size);
558 EXPECT_EQ(1U, cie->augmentation_string.size());
559 EXPECT_EQ('\0', cie->augmentation_string[0]);
560 EXPECT_EQ(0U, cie->personality_handler);
561 EXPECT_EQ(0x5011U, cie->cfa_instructions_offset);
562 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
563 EXPECT_EQ(4U, cie->code_alignment_factor);
564 EXPECT_EQ(-4, cie->data_alignment_factor);
565 EXPECT_EQ(0x20U, cie->return_address_register);
566 }
567
TYPED_TEST_P(DwarfSectionImplTest,GetCie_64_no_augment)568 TYPED_TEST_P(DwarfSectionImplTest, GetCie_64_no_augment) {
569 this->memory_.SetData32(0x8000, 0xffffffff);
570 this->memory_.SetData64(0x8004, 0x200);
571 this->memory_.SetData64(0x800c, 0xffffffffffffffffULL);
572 this->memory_.SetData8(0x8014, 0x1);
573 this->memory_.SetData8(0x8015, '\0');
574 this->memory_.SetData8(0x8016, 4);
575 this->memory_.SetData8(0x8017, 8);
576 this->memory_.SetData8(0x8018, 0x20);
577
578 const DwarfCie* cie = this->section_->GetCie(0x8000);
579 ASSERT_TRUE(cie != nullptr);
580 EXPECT_EQ(1U, cie->version);
581 EXPECT_EQ(DW_EH_PE_sdata8, cie->fde_address_encoding);
582 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
583 EXPECT_EQ(0U, cie->segment_size);
584 EXPECT_EQ(1U, cie->augmentation_string.size());
585 EXPECT_EQ('\0', cie->augmentation_string[0]);
586 EXPECT_EQ(0U, cie->personality_handler);
587 EXPECT_EQ(0x8019U, cie->cfa_instructions_offset);
588 EXPECT_EQ(0x820cU, cie->cfa_instructions_end);
589 EXPECT_EQ(4U, cie->code_alignment_factor);
590 EXPECT_EQ(8, cie->data_alignment_factor);
591 EXPECT_EQ(0x20U, cie->return_address_register);
592 }
593
TYPED_TEST_P(DwarfSectionImplTest,GetCie_augment)594 TYPED_TEST_P(DwarfSectionImplTest, GetCie_augment) {
595 this->memory_.SetData32(0x5000, 0x100);
596 this->memory_.SetData32(0x5004, 0xffffffff);
597 this->memory_.SetData8(0x5008, 0x1);
598 this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'});
599 this->memory_.SetData8(0x500e, 4);
600 this->memory_.SetData8(0x500f, 8);
601 this->memory_.SetData8(0x5010, 0x10);
602 // Augment length.
603 this->memory_.SetData8(0x5011, 0xf);
604 // L data.
605 this->memory_.SetData8(0x5012, DW_EH_PE_textrel | DW_EH_PE_udata2);
606 // P data.
607 this->memory_.SetData8(0x5013, DW_EH_PE_udata4);
608 this->memory_.SetData32(0x5014, 0x12345678);
609 // R data.
610 this->memory_.SetData8(0x5018, DW_EH_PE_udata2);
611
612 const DwarfCie* cie = this->section_->GetCie(0x5000);
613 ASSERT_TRUE(cie != nullptr);
614 EXPECT_EQ(1U, cie->version);
615 EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding);
616 EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding);
617 EXPECT_EQ(0U, cie->segment_size);
618 EXPECT_EQ(5U, cie->augmentation_string.size());
619 EXPECT_EQ('z', cie->augmentation_string[0]);
620 EXPECT_EQ('L', cie->augmentation_string[1]);
621 EXPECT_EQ('P', cie->augmentation_string[2]);
622 EXPECT_EQ('R', cie->augmentation_string[3]);
623 EXPECT_EQ('\0', cie->augmentation_string[4]);
624 EXPECT_EQ(0x12345678U, cie->personality_handler);
625 EXPECT_EQ(0x5021U, cie->cfa_instructions_offset);
626 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
627 EXPECT_EQ(4U, cie->code_alignment_factor);
628 EXPECT_EQ(8, cie->data_alignment_factor);
629 EXPECT_EQ(0x10U, cie->return_address_register);
630 }
631
TYPED_TEST_P(DwarfSectionImplTest,GetCie_version_3)632 TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_3) {
633 this->memory_.SetData32(0x5000, 0x100);
634 this->memory_.SetData32(0x5004, 0xffffffff);
635 this->memory_.SetData8(0x5008, 0x3);
636 this->memory_.SetData8(0x5009, '\0');
637 this->memory_.SetData8(0x500a, 4);
638 this->memory_.SetData8(0x500b, 8);
639 this->memory_.SetMemory(0x500c, std::vector<uint8_t>{0x81, 0x03});
640
641 const DwarfCie* cie = this->section_->GetCie(0x5000);
642 ASSERT_TRUE(cie != nullptr);
643 EXPECT_EQ(3U, cie->version);
644 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
645 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
646 EXPECT_EQ(0U, cie->segment_size);
647 EXPECT_EQ(1U, cie->augmentation_string.size());
648 EXPECT_EQ('\0', cie->augmentation_string[0]);
649 EXPECT_EQ(0U, cie->personality_handler);
650 EXPECT_EQ(0x500eU, cie->cfa_instructions_offset);
651 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
652 EXPECT_EQ(4U, cie->code_alignment_factor);
653 EXPECT_EQ(8, cie->data_alignment_factor);
654 EXPECT_EQ(0x181U, cie->return_address_register);
655 }
656
TYPED_TEST_P(DwarfSectionImplTest,GetCie_version_4)657 TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_4) {
658 this->memory_.SetData32(0x5000, 0x100);
659 this->memory_.SetData32(0x5004, 0xffffffff);
660 this->memory_.SetData8(0x5008, 0x4);
661 this->memory_.SetData8(0x5009, '\0');
662 this->memory_.SetData8(0x500a, 4);
663 this->memory_.SetData8(0x500b, 0x13);
664 this->memory_.SetData8(0x500c, 4);
665 this->memory_.SetData8(0x500d, 8);
666 this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x81, 0x03});
667
668 const DwarfCie* cie = this->section_->GetCie(0x5000);
669 ASSERT_TRUE(cie != nullptr);
670 EXPECT_EQ(4U, cie->version);
671 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
672 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
673 EXPECT_EQ(0x13U, cie->segment_size);
674 EXPECT_EQ(1U, cie->augmentation_string.size());
675 EXPECT_EQ('\0', cie->augmentation_string[0]);
676 EXPECT_EQ(0U, cie->personality_handler);
677 EXPECT_EQ(0x5010U, cie->cfa_instructions_offset);
678 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
679 EXPECT_EQ(4U, cie->code_alignment_factor);
680 EXPECT_EQ(8, cie->data_alignment_factor);
681 EXPECT_EQ(0x181U, cie->return_address_register);
682 }
683
TYPED_TEST_P(DwarfSectionImplTest,GetFdeFromOffset_fail_should_not_cache)684 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) {
685 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
686 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
687 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
688 this->section_->TestClearError();
689 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
690 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
691 EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
692 }
693
TYPED_TEST_P(DwarfSectionImplTest,GetFdeFromOffset_32_no_augment)694 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment) {
695 this->memory_.SetData32(0x4000, 0x20);
696 this->memory_.SetData32(0x4004, 0x8000);
697 this->memory_.SetData32(0x4008, 0x5000);
698 this->memory_.SetData32(0x400c, 0x100);
699
700 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
701 DwarfCie cie{};
702 cie.fde_address_encoding = DW_EH_PE_udata4;
703 this->section_->TestSetCachedCieEntry(0x8000, cie);
704 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
705
706 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
707 ASSERT_TRUE(fde != nullptr);
708 ASSERT_TRUE(fde->cie != nullptr);
709 EXPECT_EQ(0x4010U, fde->cfa_instructions_offset);
710 EXPECT_EQ(0x4024U, fde->cfa_instructions_end);
711 EXPECT_EQ(0x5000U, fde->pc_start);
712 EXPECT_EQ(0x5100U, fde->pc_end);
713 EXPECT_EQ(0x8000U, fde->cie_offset);
714 EXPECT_EQ(0U, fde->lsda_address);
715 }
716
TYPED_TEST_P(DwarfSectionImplTest,GetFdeFromOffset_32_no_augment_non_zero_segment_size)717 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment_non_zero_segment_size) {
718 this->memory_.SetData32(0x4000, 0x30);
719 this->memory_.SetData32(0x4004, 0x8000);
720 this->memory_.SetData32(0x4018, 0x5000);
721 this->memory_.SetData32(0x401c, 0x100);
722
723 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
724 DwarfCie cie{};
725 cie.fde_address_encoding = DW_EH_PE_udata4;
726 cie.segment_size = 0x10;
727 this->section_->TestSetCachedCieEntry(0x8000, cie);
728 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
729
730 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
731 ASSERT_TRUE(fde != nullptr);
732 ASSERT_TRUE(fde->cie != nullptr);
733 EXPECT_EQ(0x4020U, fde->cfa_instructions_offset);
734 EXPECT_EQ(0x4034U, fde->cfa_instructions_end);
735 EXPECT_EQ(0x5000U, fde->pc_start);
736 EXPECT_EQ(0x5100U, fde->pc_end);
737 EXPECT_EQ(0x8000U, fde->cie_offset);
738 EXPECT_EQ(0U, fde->lsda_address);
739 }
740
TYPED_TEST_P(DwarfSectionImplTest,GetFdeFromOffset_32_augment)741 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_augment) {
742 this->memory_.SetData32(0x4000, 0x100);
743 this->memory_.SetData32(0x4004, 0x8000);
744 this->memory_.SetData32(0x4008, 0x5000);
745 this->memory_.SetData32(0x400c, 0x100);
746 this->memory_.SetMemory(0x4010, std::vector<uint8_t>{0x82, 0x01});
747 this->memory_.SetData16(0x4012, 0x1234);
748
749 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
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 this->section_->TestSetCachedCieEntry(0x8000, cie);
755 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
756
757 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
758 ASSERT_TRUE(fde != nullptr);
759 ASSERT_TRUE(fde->cie != nullptr);
760 EXPECT_EQ(0x4094U, fde->cfa_instructions_offset);
761 EXPECT_EQ(0x4104U, fde->cfa_instructions_end);
762 EXPECT_EQ(0x5000U, fde->pc_start);
763 EXPECT_EQ(0x5100U, fde->pc_end);
764 EXPECT_EQ(0x8000U, fde->cie_offset);
765 EXPECT_EQ(0x1234U, fde->lsda_address);
766 }
767
TYPED_TEST_P(DwarfSectionImplTest,GetFdeFromOffset_64_no_augment)768 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_64_no_augment) {
769 this->memory_.SetData32(0x4000, 0xffffffff);
770 this->memory_.SetData64(0x4004, 0x100);
771 this->memory_.SetData64(0x400c, 0x12345678);
772 this->memory_.SetData32(0x4014, 0x5000);
773 this->memory_.SetData32(0x4018, 0x100);
774
775 EXPECT_CALL(*this->section_, GetCieOffsetFromFde64(0x12345678))
776 .WillOnce(::testing::Return(0x12345678));
777 DwarfCie cie{};
778 cie.fde_address_encoding = DW_EH_PE_udata4;
779 this->section_->TestSetCachedCieEntry(0x12345678, cie);
780 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
781
782 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
783 ASSERT_TRUE(fde != nullptr);
784 ASSERT_TRUE(fde->cie != nullptr);
785 EXPECT_EQ(0x401cU, fde->cfa_instructions_offset);
786 EXPECT_EQ(0x410cU, fde->cfa_instructions_end);
787 EXPECT_EQ(0x5000U, fde->pc_start);
788 EXPECT_EQ(0x5100U, fde->pc_end);
789 EXPECT_EQ(0x12345678U, fde->cie_offset);
790 EXPECT_EQ(0U, fde->lsda_address);
791 }
792
TYPED_TEST_P(DwarfSectionImplTest,GetFdeFromOffset_cached)793 TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_cached) {
794 DwarfCie cie{};
795 cie.fde_address_encoding = DW_EH_PE_udata4;
796 cie.augmentation_string.push_back('z');
797 cie.lsda_encoding = DW_EH_PE_udata2;
798
799 DwarfFde fde_cached{};
800 fde_cached.cfa_instructions_offset = 0x1000;
801 fde_cached.cfa_instructions_end = 0x1100;
802 fde_cached.pc_start = 0x9000;
803 fde_cached.pc_end = 0x9400;
804 fde_cached.cie_offset = 0x30000;
805 fde_cached.cie = &cie;
806 this->section_->TestSetCachedFdeEntry(0x6000, fde_cached);
807
808 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x6000);
809 ASSERT_TRUE(fde != nullptr);
810 ASSERT_EQ(&cie, fde->cie);
811 EXPECT_EQ(0x1000U, fde->cfa_instructions_offset);
812 EXPECT_EQ(0x1100U, fde->cfa_instructions_end);
813 EXPECT_EQ(0x9000U, fde->pc_start);
814 EXPECT_EQ(0x9400U, fde->pc_end);
815 EXPECT_EQ(0x30000U, fde->cie_offset);
816 }
817
TYPED_TEST_P(DwarfSectionImplTest,GetCfaLocationInfo_cie_not_cached)818 TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_not_cached) {
819 DwarfCie cie{};
820 cie.cfa_instructions_offset = 0x3000;
821 cie.cfa_instructions_end = 0x3002;
822 DwarfFde fde{};
823 fde.cie = &cie;
824 fde.cie_offset = 0x8000;
825 fde.cfa_instructions_offset = 0x6000;
826 fde.cfa_instructions_end = 0x6002;
827
828 this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x09, 0x02, 0x01});
829 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
830
831 dwarf_loc_regs_t loc_regs;
832 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
833 ASSERT_EQ(2U, loc_regs.size());
834
835 auto entry = loc_regs.find(2);
836 ASSERT_NE(entry, loc_regs.end());
837 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
838 ASSERT_EQ(1U, entry->second.values[0]);
839
840 entry = loc_regs.find(4);
841 ASSERT_NE(entry, loc_regs.end());
842 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
843 ASSERT_EQ(3U, entry->second.values[0]);
844 }
845
TYPED_TEST_P(DwarfSectionImplTest,GetCfaLocationInfo_cie_cached)846 TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) {
847 DwarfCie cie{};
848 cie.cfa_instructions_offset = 0x3000;
849 cie.cfa_instructions_end = 0x3002;
850 DwarfFde fde{};
851 fde.cie = &cie;
852 fde.cie_offset = 0x8000;
853 fde.cfa_instructions_offset = 0x6000;
854 fde.cfa_instructions_end = 0x6002;
855
856 dwarf_loc_regs_t cie_loc_regs;
857 cie_loc_regs[6] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 0}};
858 this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs);
859 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
860
861 dwarf_loc_regs_t loc_regs;
862 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
863 ASSERT_EQ(2U, loc_regs.size());
864
865 auto entry = loc_regs.find(6);
866 ASSERT_NE(entry, loc_regs.end());
867 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
868 ASSERT_EQ(4U, entry->second.values[0]);
869
870 entry = loc_regs.find(4);
871 ASSERT_NE(entry, loc_regs.end());
872 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
873 ASSERT_EQ(3U, entry->second.values[0]);
874 }
875
TYPED_TEST_P(DwarfSectionImplTest,Log)876 TYPED_TEST_P(DwarfSectionImplTest, Log) {
877 DwarfCie cie{};
878 cie.cfa_instructions_offset = 0x5000;
879 cie.cfa_instructions_end = 0x5001;
880 DwarfFde fde{};
881 fde.cie = &cie;
882 fde.cfa_instructions_offset = 0x6000;
883 fde.cfa_instructions_end = 0x6001;
884
885 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x00});
886 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0xc2});
887 ASSERT_TRUE(this->section_->Log(2, 0x1000, 0x1000, &fde));
888
889 ASSERT_EQ(
890 "4 unwind DW_CFA_nop\n"
891 "4 unwind Raw Data: 0x00\n"
892 "4 unwind DW_CFA_restore register(2)\n"
893 "4 unwind Raw Data: 0xc2\n",
894 GetFakeLogPrint());
895 ASSERT_EQ("", GetFakeLogBuf());
896 }
897
898 REGISTER_TYPED_TEST_CASE_P(
899 DwarfSectionImplTest, Eval_cfa_expr_eval_fail, Eval_cfa_expr_no_stack,
900 Eval_cfa_expr_is_register, Eval_cfa_expr, Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa,
901 Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection,
902 Eval_register_reference_chain, Eval_dex_pc, Eval_invalid_register, Eval_different_reg_locations,
903 Eval_return_address_undefined, Eval_pc_zero, Eval_return_address, Eval_ignore_large_reg_loc,
904 Eval_reg_expr, Eval_reg_val_expr, GetCie_fail_should_not_cache, GetCie_32_version_check,
905 GetCie_negative_data_alignment_factor, GetCie_64_no_augment, GetCie_augment, GetCie_version_3,
906 GetCie_version_4, GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
907 GetFdeFromOffset_32_no_augment_non_zero_segment_size, GetFdeFromOffset_32_augment,
908 GetFdeFromOffset_64_no_augment, GetFdeFromOffset_cached, GetCfaLocationInfo_cie_not_cached,
909 GetCfaLocationInfo_cie_cached, Log);
910
911 typedef ::testing::Types<uint32_t, uint64_t> DwarfSectionImplTestTypes;
912 INSTANTIATE_TYPED_TEST_CASE_P(, DwarfSectionImplTest, DwarfSectionImplTestTypes);
913
914 } // namespace unwindstack
915