• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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, &regs, &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