blob: d54b0bf59ed329127addf4927368d21fc480b3c2 [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
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070045 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
Christopher Ferrisc9dee842017-11-03 14:50:27 -070051 void TestSetCie32Value(uint32_t value32) { this->cie32_value_ = value32; }
52
53 void TestSetCie64Value(uint64_t value64) { this->cie64_value_ = value64; }
54
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070055 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();
Christopher Ferrisc9dee842017-11-03 14:50:27 -070080 section_->TestSetCie32Value(static_cast<uint32_t>(-1));
81 section_->TestSetCie64Value(static_cast<uint64_t>(-1));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070082 }
83
84 void TearDown() override { delete section_; }
85
86 MemoryFake memory_;
87 MockDwarfSectionImpl<TypeParam>* section_ = nullptr;
88};
89TYPED_TEST_CASE_P(DwarfSectionImplTest);
90
91// NOTE: All test class variables need to be referenced as this->.
92
93TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) {
94 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070095 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070096 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_EXPRESSION, {0x2, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700103 bool finished;
104 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700105 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
106}
107
108TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_no_stack) {
109 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700110 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700111 dwarf_loc_regs_t loc_regs;
112
113 regs.set_pc(0x100);
114 regs.set_sp(0x2000);
115 regs[5] = 0x20;
116 regs[9] = 0x3000;
117 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x96, 0x96, 0x96});
118 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700119 bool finished;
120 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700121 EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->last_error());
122}
123
124TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr) {
125 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700126 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700127 dwarf_loc_regs_t loc_regs;
128
129 regs.set_pc(0x100);
130 regs.set_sp(0x2000);
131 regs[5] = 0x20;
132 regs[9] = 0x3000;
133 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
134 TypeParam cfa_value = 0x12345;
135 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
136 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700137 bool finished;
138 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
139 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700140 EXPECT_EQ(0x12345U, regs.sp());
141 EXPECT_EQ(0x20U, regs.pc());
142}
143
144TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_val_expr) {
145 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700146 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700147 dwarf_loc_regs_t loc_regs;
148
149 regs.set_pc(0x100);
150 regs.set_sp(0x2000);
151 regs[5] = 0x20;
152 regs[9] = 0x3000;
153 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
154 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700155 bool finished;
156 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
157 ASSERT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700158 EXPECT_EQ(0x80000000U, regs.sp());
159 EXPECT_EQ(0x20U, regs.pc());
160}
161
162TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_is_register) {
163 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700164 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700165 dwarf_loc_regs_t loc_regs;
166
167 regs.set_pc(0x100);
168 regs.set_sp(0x2000);
169 regs[5] = 0x20;
170 regs[9] = 0x3000;
171 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x50, 0x96, 0x96});
172 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x2, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700173 bool finished;
174 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700175 EXPECT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->section_->last_error());
176}
177
178TYPED_TEST_P(DwarfSectionImplTest, Eval_bad_regs) {
179 DwarfCie cie{.return_address_register = 60};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700180 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700181 dwarf_loc_regs_t loc_regs;
182
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700183 bool finished;
184 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700185 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
186}
187
188TYPED_TEST_P(DwarfSectionImplTest, Eval_no_cfa) {
189 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700190 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700191 dwarf_loc_regs_t loc_regs;
192
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700193 bool finished;
194 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700195 EXPECT_EQ(DWARF_ERROR_CFA_NOT_DEFINED, this->section_->last_error());
196}
197
198TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_bad) {
199 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700200 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700201 dwarf_loc_regs_t loc_regs;
202
203 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {20, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700204 bool finished;
205 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700206 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
207
208 this->section_->TestClearError();
209 loc_regs.erase(CFA_REG);
210 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_INVALID, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700211 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700212 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
213
214 this->section_->TestClearError();
215 loc_regs.erase(CFA_REG);
216 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_OFFSET, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700217 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700218 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
219
220 this->section_->TestClearError();
221 loc_regs.erase(CFA_REG);
222 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700223 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700224 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
225}
226
227TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_prev) {
228 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700229 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700230 dwarf_loc_regs_t loc_regs;
231
232 regs.set_pc(0x100);
233 regs.set_sp(0x2000);
234 regs[5] = 0x20;
235 regs[9] = 0x3000;
236 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {9, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700237 bool finished;
238 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
239 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700240 EXPECT_EQ(0x20U, regs.pc());
241 EXPECT_EQ(0x2000U, regs.sp());
242}
243
244TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_register_from_value) {
245 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700246 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700247 dwarf_loc_regs_t loc_regs;
248
249 regs.set_pc(0x100);
250 regs.set_sp(0x2000);
251 regs[5] = 0x20;
252 regs[6] = 0x4000;
253 regs[9] = 0x3000;
254 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {6, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700255 bool finished;
256 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
257 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700258 EXPECT_EQ(0x20U, regs.pc());
259 EXPECT_EQ(0x4000U, regs.sp());
260}
261
262TYPED_TEST_P(DwarfSectionImplTest, Eval_double_indirection) {
263 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700264 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700265 dwarf_loc_regs_t loc_regs;
266
267 regs.set_pc(0x100);
268 regs.set_sp(0x2000);
269 regs[8] = 0x10;
270 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
271 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {3, 0}};
272 loc_regs[9] = DwarfLocation{DWARF_LOCATION_REGISTER, {1, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700273 bool finished;
274 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700275 EXPECT_EQ(DWARF_ERROR_ILLEGAL_STATE, this->section_->last_error());
276}
277
278TYPED_TEST_P(DwarfSectionImplTest, Eval_invalid_register) {
279 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700280 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700281 dwarf_loc_regs_t loc_regs;
282
283 regs.set_pc(0x100);
284 regs.set_sp(0x2000);
285 regs[8] = 0x10;
286 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
287 loc_regs[1] = DwarfLocation{DWARF_LOCATION_REGISTER, {10, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700288 bool finished;
289 ASSERT_FALSE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700290 EXPECT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->section_->last_error());
291}
292
293TYPED_TEST_P(DwarfSectionImplTest, Eval_different_reg_locations) {
294 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700295 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700296 dwarf_loc_regs_t loc_regs;
297
298 if (sizeof(TypeParam) == sizeof(uint64_t)) {
299 this->memory_.SetData64(0x2150, 0x12345678abcdef00ULL);
300 } else {
301 this->memory_.SetData32(0x2150, 0x12345678);
302 }
303
304 regs.set_pc(0x100);
305 regs.set_sp(0x2000);
306 regs[3] = 0x234;
307 regs[5] = 0x10;
308 regs[8] = 0x2100;
309 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
310 loc_regs[1] = DwarfLocation{DWARF_LOCATION_VAL_OFFSET, {0x100, 0}};
311 loc_regs[2] = DwarfLocation{DWARF_LOCATION_OFFSET, {0x50, 0}};
312 loc_regs[3] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700313 bool finished;
314 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
315 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700316 EXPECT_EQ(0x10U, regs.pc());
317 EXPECT_EQ(0x2100U, regs.sp());
318 EXPECT_EQ(0x2200U, regs[1]);
319 EXPECT_EQ(0x234U, regs[3]);
320 if (sizeof(TypeParam) == sizeof(uint64_t)) {
321 EXPECT_EQ(0x12345678abcdef00ULL, regs[2]);
322 } else {
323 EXPECT_EQ(0x12345678U, regs[2]);
324 }
325}
326
327TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address_undefined) {
328 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700329 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700330 dwarf_loc_regs_t loc_regs;
331
332 regs.set_pc(0x100);
333 regs.set_sp(0x2000);
334 regs[5] = 0x20;
335 regs[8] = 0x10;
336 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
337 loc_regs[5] = DwarfLocation{DWARF_LOCATION_UNDEFINED, {0, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700338 bool finished;
339 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
340 EXPECT_TRUE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700341 EXPECT_EQ(0U, regs.pc());
342 EXPECT_EQ(0x10U, regs.sp());
343}
344
Christopher Ferris2502a602017-10-23 13:51:54 -0700345TYPED_TEST_P(DwarfSectionImplTest, Eval_pc_zero) {
346 DwarfCie cie{.return_address_register = 5};
347 RegsImplFake<TypeParam> regs(10, 9);
348 dwarf_loc_regs_t loc_regs;
349
350 regs.set_pc(0x100);
351 regs.set_sp(0x2000);
352 regs[5] = 0;
353 regs[8] = 0x10;
354 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
355 bool finished;
356 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
357 EXPECT_TRUE(finished);
358 EXPECT_EQ(0U, regs.pc());
359 EXPECT_EQ(0x10U, regs.sp());
360}
361
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700362TYPED_TEST_P(DwarfSectionImplTest, Eval_return_address) {
363 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700364 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700365 dwarf_loc_regs_t loc_regs;
366
367 regs.set_pc(0x100);
368 regs.set_sp(0x2000);
369 regs[5] = 0x20;
370 regs[8] = 0x10;
371 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700372 bool finished;
373 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
374 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700375 EXPECT_EQ(0x20U, regs.pc());
376 EXPECT_EQ(0x10U, regs.sp());
377}
378
379TYPED_TEST_P(DwarfSectionImplTest, Eval_ignore_large_reg_loc) {
380 DwarfCie cie{.return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700381 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700382 dwarf_loc_regs_t loc_regs;
383
384 regs.set_pc(0x100);
385 regs.set_sp(0x2000);
386 regs[5] = 0x20;
387 regs[8] = 0x10;
388 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
389 // This should not result in any errors.
390 loc_regs[20] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700391 bool finished;
392 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
393 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700394 EXPECT_EQ(0x20U, regs.pc());
395 EXPECT_EQ(0x10U, regs.sp());
396}
397
398TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_expr) {
399 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700400 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700401 dwarf_loc_regs_t loc_regs;
402
403 regs.set_pc(0x100);
404 regs.set_sp(0x2000);
405 regs[8] = 0x3000;
406 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
407 TypeParam cfa_value = 0x12345;
408 this->memory_.SetMemory(0x80000000, &cfa_value, sizeof(cfa_value));
409 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
410 loc_regs[5] = DwarfLocation{DWARF_LOCATION_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700411 bool finished;
412 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
413 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700414 EXPECT_EQ(0x3000U, regs.sp());
415 EXPECT_EQ(0x12345U, regs.pc());
416}
417
418TYPED_TEST_P(DwarfSectionImplTest, Eval_reg_val_expr) {
419 DwarfCie cie{.version = 3, .return_address_register = 5};
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700420 RegsImplFake<TypeParam> regs(10, 9);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700421 dwarf_loc_regs_t loc_regs;
422
423 regs.set_pc(0x100);
424 regs.set_sp(0x2000);
425 regs[8] = 0x3000;
426 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x0c, 0x00, 0x00, 0x00, 0x80});
427 loc_regs[CFA_REG] = DwarfLocation{DWARF_LOCATION_REGISTER, {8, 0}};
428 loc_regs[5] = DwarfLocation{DWARF_LOCATION_VAL_EXPRESSION, {0x4, 0x5000}};
Christopher Ferrisb9de87f2017-09-20 13:37:24 -0700429 bool finished;
430 ASSERT_TRUE(this->section_->Eval(&cie, &this->memory_, loc_regs, &regs, &finished));
431 EXPECT_FALSE(finished);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700432 EXPECT_EQ(0x3000U, regs.sp());
433 EXPECT_EQ(0x80000000U, regs.pc());
434}
435
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700436TYPED_TEST_P(DwarfSectionImplTest, GetCie_fail_should_not_cache) {
437 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
438 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
439 this->section_->TestClearError();
440 ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
441 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
442}
443
444TYPED_TEST_P(DwarfSectionImplTest, GetCie_32_version_check) {
445 this->memory_.SetData32(0x5000, 0x100);
446 this->memory_.SetData32(0x5004, 0xffffffff);
447 this->memory_.SetData8(0x5008, 0x1);
448 this->memory_.SetData8(0x5009, '\0');
449 this->memory_.SetData8(0x500a, 4);
450 this->memory_.SetData8(0x500b, 8);
451 this->memory_.SetData8(0x500c, 0x20);
452
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700453 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
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700496 const DwarfCie* cie = this->section_->GetCie(0x5000);
497 ASSERT_TRUE(cie != nullptr);
498 EXPECT_EQ(1U, cie->version);
499 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
500 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
501 EXPECT_EQ(0U, cie->segment_size);
502 EXPECT_EQ(1U, cie->augmentation_string.size());
503 EXPECT_EQ('\0', cie->augmentation_string[0]);
504 EXPECT_EQ(0U, cie->personality_handler);
505 EXPECT_EQ(0x5011U, cie->cfa_instructions_offset);
506 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
507 EXPECT_EQ(4U, cie->code_alignment_factor);
508 EXPECT_EQ(-4, cie->data_alignment_factor);
509 EXPECT_EQ(0x20U, cie->return_address_register);
510}
511
512TYPED_TEST_P(DwarfSectionImplTest, GetCie_64_no_augment) {
513 this->memory_.SetData32(0x8000, 0xffffffff);
514 this->memory_.SetData64(0x8004, 0x200);
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700515 this->memory_.SetData64(0x800c, 0xffffffffffffffffULL);
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700516 this->memory_.SetData8(0x8014, 0x1);
517 this->memory_.SetData8(0x8015, '\0');
518 this->memory_.SetData8(0x8016, 4);
519 this->memory_.SetData8(0x8017, 8);
520 this->memory_.SetData8(0x8018, 0x20);
521
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700522 const DwarfCie* cie = this->section_->GetCie(0x8000);
523 ASSERT_TRUE(cie != nullptr);
524 EXPECT_EQ(1U, cie->version);
525 EXPECT_EQ(DW_EH_PE_sdata8, cie->fde_address_encoding);
526 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
527 EXPECT_EQ(0U, cie->segment_size);
528 EXPECT_EQ(1U, cie->augmentation_string.size());
529 EXPECT_EQ('\0', cie->augmentation_string[0]);
530 EXPECT_EQ(0U, cie->personality_handler);
531 EXPECT_EQ(0x8019U, cie->cfa_instructions_offset);
532 EXPECT_EQ(0x820cU, cie->cfa_instructions_end);
533 EXPECT_EQ(4U, cie->code_alignment_factor);
534 EXPECT_EQ(8, cie->data_alignment_factor);
535 EXPECT_EQ(0x20U, cie->return_address_register);
536}
537
538TYPED_TEST_P(DwarfSectionImplTest, GetCie_augment) {
539 this->memory_.SetData32(0x5000, 0x100);
540 this->memory_.SetData32(0x5004, 0xffffffff);
541 this->memory_.SetData8(0x5008, 0x1);
542 this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'});
543 this->memory_.SetData8(0x500e, 4);
544 this->memory_.SetData8(0x500f, 8);
545 this->memory_.SetData8(0x5010, 0x10);
546 // Augment length.
547 this->memory_.SetData8(0x5011, 0xf);
548 // L data.
549 this->memory_.SetData8(0x5012, DW_EH_PE_textrel | DW_EH_PE_udata2);
550 // P data.
551 this->memory_.SetData8(0x5013, DW_EH_PE_udata4);
552 this->memory_.SetData32(0x5014, 0x12345678);
553 // R data.
554 this->memory_.SetData8(0x5018, DW_EH_PE_udata2);
555
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700556 const DwarfCie* cie = this->section_->GetCie(0x5000);
557 ASSERT_TRUE(cie != nullptr);
558 EXPECT_EQ(1U, cie->version);
559 EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding);
560 EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding);
561 EXPECT_EQ(0U, cie->segment_size);
562 EXPECT_EQ(5U, cie->augmentation_string.size());
563 EXPECT_EQ('z', cie->augmentation_string[0]);
564 EXPECT_EQ('L', cie->augmentation_string[1]);
565 EXPECT_EQ('P', cie->augmentation_string[2]);
566 EXPECT_EQ('R', cie->augmentation_string[3]);
567 EXPECT_EQ('\0', cie->augmentation_string[4]);
568 EXPECT_EQ(0x12345678U, cie->personality_handler);
569 EXPECT_EQ(0x5021U, cie->cfa_instructions_offset);
570 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
571 EXPECT_EQ(4U, cie->code_alignment_factor);
572 EXPECT_EQ(8, cie->data_alignment_factor);
573 EXPECT_EQ(0x10U, cie->return_address_register);
574}
575
576TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_3) {
577 this->memory_.SetData32(0x5000, 0x100);
578 this->memory_.SetData32(0x5004, 0xffffffff);
579 this->memory_.SetData8(0x5008, 0x3);
580 this->memory_.SetData8(0x5009, '\0');
581 this->memory_.SetData8(0x500a, 4);
582 this->memory_.SetData8(0x500b, 8);
583 this->memory_.SetMemory(0x500c, std::vector<uint8_t>{0x81, 0x03});
584
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700585 const DwarfCie* cie = this->section_->GetCie(0x5000);
586 ASSERT_TRUE(cie != nullptr);
587 EXPECT_EQ(3U, cie->version);
588 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
589 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
590 EXPECT_EQ(0U, cie->segment_size);
591 EXPECT_EQ(1U, cie->augmentation_string.size());
592 EXPECT_EQ('\0', cie->augmentation_string[0]);
593 EXPECT_EQ(0U, cie->personality_handler);
594 EXPECT_EQ(0x500eU, cie->cfa_instructions_offset);
595 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
596 EXPECT_EQ(4U, cie->code_alignment_factor);
597 EXPECT_EQ(8, cie->data_alignment_factor);
598 EXPECT_EQ(0x181U, cie->return_address_register);
599}
600
601TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_4) {
602 this->memory_.SetData32(0x5000, 0x100);
603 this->memory_.SetData32(0x5004, 0xffffffff);
604 this->memory_.SetData8(0x5008, 0x4);
605 this->memory_.SetData8(0x5009, '\0');
606 this->memory_.SetData8(0x500a, 4);
607 this->memory_.SetData8(0x500b, 0x13);
608 this->memory_.SetData8(0x500c, 4);
609 this->memory_.SetData8(0x500d, 8);
610 this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x81, 0x03});
611
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700612 const DwarfCie* cie = this->section_->GetCie(0x5000);
613 ASSERT_TRUE(cie != nullptr);
614 EXPECT_EQ(4U, cie->version);
615 EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
616 EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
617 EXPECT_EQ(0x13U, cie->segment_size);
618 EXPECT_EQ(1U, cie->augmentation_string.size());
619 EXPECT_EQ('\0', cie->augmentation_string[0]);
620 EXPECT_EQ(0U, cie->personality_handler);
621 EXPECT_EQ(0x5010U, cie->cfa_instructions_offset);
622 EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
623 EXPECT_EQ(4U, cie->code_alignment_factor);
624 EXPECT_EQ(8, cie->data_alignment_factor);
625 EXPECT_EQ(0x181U, cie->return_address_register);
626}
627
628TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) {
629 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
630 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
631 this->section_->TestClearError();
632 ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
633 EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->last_error());
634}
635
636TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment) {
637 this->memory_.SetData32(0x4000, 0x20);
638 this->memory_.SetData32(0x4004, 0x8000);
639 this->memory_.SetData32(0x4008, 0x5000);
640 this->memory_.SetData32(0x400c, 0x100);
641
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700642 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
643 DwarfCie cie{};
644 cie.fde_address_encoding = DW_EH_PE_udata4;
645 this->section_->TestSetCachedCieEntry(0x8000, cie);
646 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
647
648 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
649 ASSERT_TRUE(fde != nullptr);
650 ASSERT_TRUE(fde->cie != nullptr);
651 EXPECT_EQ(0x4010U, fde->cfa_instructions_offset);
652 EXPECT_EQ(0x4024U, fde->cfa_instructions_end);
653 EXPECT_EQ(0x5000U, fde->pc_start);
654 EXPECT_EQ(0x5100U, fde->pc_end);
655 EXPECT_EQ(0x8000U, fde->cie_offset);
656 EXPECT_EQ(0U, fde->lsda_address);
657}
658
659TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment_non_zero_segment_size) {
660 this->memory_.SetData32(0x4000, 0x30);
661 this->memory_.SetData32(0x4004, 0x8000);
662 this->memory_.SetData32(0x4018, 0x5000);
663 this->memory_.SetData32(0x401c, 0x100);
664
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700665 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
666 DwarfCie cie{};
667 cie.fde_address_encoding = DW_EH_PE_udata4;
668 cie.segment_size = 0x10;
669 this->section_->TestSetCachedCieEntry(0x8000, cie);
670 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
671
672 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
673 ASSERT_TRUE(fde != nullptr);
674 ASSERT_TRUE(fde->cie != nullptr);
675 EXPECT_EQ(0x4020U, fde->cfa_instructions_offset);
676 EXPECT_EQ(0x4034U, fde->cfa_instructions_end);
677 EXPECT_EQ(0x5000U, fde->pc_start);
678 EXPECT_EQ(0x5100U, fde->pc_end);
679 EXPECT_EQ(0x8000U, fde->cie_offset);
680 EXPECT_EQ(0U, fde->lsda_address);
681}
682
683TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_augment) {
684 this->memory_.SetData32(0x4000, 0x100);
685 this->memory_.SetData32(0x4004, 0x8000);
686 this->memory_.SetData32(0x4008, 0x5000);
687 this->memory_.SetData32(0x400c, 0x100);
688 this->memory_.SetMemory(0x4010, std::vector<uint8_t>{0x82, 0x01});
689 this->memory_.SetData16(0x4012, 0x1234);
690
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700691 EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
692 DwarfCie cie{};
693 cie.fde_address_encoding = DW_EH_PE_udata4;
694 cie.augmentation_string.push_back('z');
695 cie.lsda_encoding = DW_EH_PE_udata2;
696 this->section_->TestSetCachedCieEntry(0x8000, cie);
697 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
698
699 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
700 ASSERT_TRUE(fde != nullptr);
701 ASSERT_TRUE(fde->cie != nullptr);
702 EXPECT_EQ(0x4094U, fde->cfa_instructions_offset);
703 EXPECT_EQ(0x4104U, fde->cfa_instructions_end);
704 EXPECT_EQ(0x5000U, fde->pc_start);
705 EXPECT_EQ(0x5100U, fde->pc_end);
706 EXPECT_EQ(0x8000U, fde->cie_offset);
707 EXPECT_EQ(0x1234U, fde->lsda_address);
708}
709
710TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_64_no_augment) {
711 this->memory_.SetData32(0x4000, 0xffffffff);
712 this->memory_.SetData64(0x4004, 0x100);
713 this->memory_.SetData64(0x400c, 0x12345678);
714 this->memory_.SetData32(0x4014, 0x5000);
715 this->memory_.SetData32(0x4018, 0x100);
716
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700717 EXPECT_CALL(*this->section_, GetCieOffsetFromFde64(0x12345678))
718 .WillOnce(::testing::Return(0x12345678));
719 DwarfCie cie{};
720 cie.fde_address_encoding = DW_EH_PE_udata4;
721 this->section_->TestSetCachedCieEntry(0x12345678, cie);
722 EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
723
724 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
725 ASSERT_TRUE(fde != nullptr);
726 ASSERT_TRUE(fde->cie != nullptr);
727 EXPECT_EQ(0x401cU, fde->cfa_instructions_offset);
728 EXPECT_EQ(0x410cU, fde->cfa_instructions_end);
729 EXPECT_EQ(0x5000U, fde->pc_start);
730 EXPECT_EQ(0x5100U, fde->pc_end);
731 EXPECT_EQ(0x12345678U, fde->cie_offset);
732 EXPECT_EQ(0U, fde->lsda_address);
733}
734
735TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_cached) {
736 DwarfCie cie{};
737 cie.fde_address_encoding = DW_EH_PE_udata4;
738 cie.augmentation_string.push_back('z');
739 cie.lsda_encoding = DW_EH_PE_udata2;
740
741 DwarfFde fde_cached{};
742 fde_cached.cfa_instructions_offset = 0x1000;
743 fde_cached.cfa_instructions_end = 0x1100;
744 fde_cached.pc_start = 0x9000;
745 fde_cached.pc_end = 0x9400;
746 fde_cached.cie_offset = 0x30000;
747 fde_cached.cie = &cie;
748 this->section_->TestSetCachedFdeEntry(0x6000, fde_cached);
749
750 const DwarfFde* fde = this->section_->GetFdeFromOffset(0x6000);
751 ASSERT_TRUE(fde != nullptr);
752 ASSERT_EQ(&cie, fde->cie);
753 EXPECT_EQ(0x1000U, fde->cfa_instructions_offset);
754 EXPECT_EQ(0x1100U, fde->cfa_instructions_end);
755 EXPECT_EQ(0x9000U, fde->pc_start);
756 EXPECT_EQ(0x9400U, fde->pc_end);
757 EXPECT_EQ(0x30000U, fde->cie_offset);
758}
759
760TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_not_cached) {
761 DwarfCie cie{};
762 cie.cfa_instructions_offset = 0x3000;
763 cie.cfa_instructions_end = 0x3002;
764 DwarfFde fde{};
765 fde.cie = &cie;
766 fde.cie_offset = 0x8000;
767 fde.cfa_instructions_offset = 0x6000;
768 fde.cfa_instructions_end = 0x6002;
769
770 this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x09, 0x02, 0x01});
771 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
772
773 dwarf_loc_regs_t loc_regs;
774 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
775 ASSERT_EQ(2U, loc_regs.size());
776
777 auto entry = loc_regs.find(2);
778 ASSERT_NE(entry, loc_regs.end());
779 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
780 ASSERT_EQ(1U, entry->second.values[0]);
781
782 entry = loc_regs.find(4);
783 ASSERT_NE(entry, loc_regs.end());
784 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
785 ASSERT_EQ(3U, entry->second.values[0]);
786}
787
788TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) {
789 DwarfCie cie{};
790 cie.cfa_instructions_offset = 0x3000;
791 cie.cfa_instructions_end = 0x3002;
792 DwarfFde fde{};
793 fde.cie = &cie;
794 fde.cie_offset = 0x8000;
795 fde.cfa_instructions_offset = 0x6000;
796 fde.cfa_instructions_end = 0x6002;
797
798 dwarf_loc_regs_t cie_loc_regs{{6, {DWARF_LOCATION_REGISTER, {4, 0}}}};
799 this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs);
800 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
801
802 dwarf_loc_regs_t loc_regs;
803 ASSERT_TRUE(this->section_->GetCfaLocationInfo(0x100, &fde, &loc_regs));
804 ASSERT_EQ(2U, loc_regs.size());
805
806 auto entry = loc_regs.find(6);
807 ASSERT_NE(entry, loc_regs.end());
808 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
809 ASSERT_EQ(4U, entry->second.values[0]);
810
811 entry = loc_regs.find(4);
812 ASSERT_NE(entry, loc_regs.end());
813 ASSERT_EQ(DWARF_LOCATION_REGISTER, entry->second.type);
814 ASSERT_EQ(3U, entry->second.values[0]);
815}
816
817TYPED_TEST_P(DwarfSectionImplTest, Log) {
818 DwarfCie cie{};
819 cie.cfa_instructions_offset = 0x5000;
820 cie.cfa_instructions_end = 0x5001;
821 DwarfFde fde{};
822 fde.cie = &cie;
823 fde.cfa_instructions_offset = 0x6000;
824 fde.cfa_instructions_end = 0x6001;
825
826 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x00});
827 this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0xc2});
828 ASSERT_TRUE(this->section_->Log(2, 0x1000, 0x1000, &fde));
829
830 ASSERT_EQ(
831 "4 unwind DW_CFA_nop\n"
832 "4 unwind Raw Data: 0x00\n"
833 "4 unwind DW_CFA_restore register(2)\n"
834 "4 unwind Raw Data: 0xc2\n",
835 GetFakeLogPrint());
836 ASSERT_EQ("", GetFakeLogBuf());
837}
838
839REGISTER_TYPED_TEST_CASE_P(
840 DwarfSectionImplTest, Eval_cfa_expr_eval_fail, Eval_cfa_expr_no_stack,
841 Eval_cfa_expr_is_register, Eval_cfa_expr, Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa,
842 Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection,
843 Eval_invalid_register, Eval_different_reg_locations, Eval_return_address_undefined,
Christopher Ferris2502a602017-10-23 13:51:54 -0700844 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 -0700845 GetCie_fail_should_not_cache, GetCie_32_version_check, GetCie_negative_data_alignment_factor,
846 GetCie_64_no_augment, GetCie_augment, GetCie_version_3, GetCie_version_4,
847 GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
Christopher Ferris53a3c9b2017-05-10 18:34:15 -0700848 GetFdeFromOffset_32_no_augment_non_zero_segment_size, GetFdeFromOffset_32_augment,
849 GetFdeFromOffset_64_no_augment, GetFdeFromOffset_cached, GetCfaLocationInfo_cie_not_cached,
850 GetCfaLocationInfo_cie_cached, Log);
851
852typedef ::testing::Types<uint32_t, uint64_t> DwarfSectionImplTestTypes;
853INSTANTIATE_TYPED_TEST_CASE_P(, DwarfSectionImplTest, DwarfSectionImplTestTypes);
Christopher Ferrisd226a512017-07-14 10:37:19 -0700854
855} // namespace unwindstack