blob: 967c2c25f2079eca446c85710e53f9084d5b3ffb [file] [log] [blame]
Christopher Ferris8642fcb2017-04-24 11:14:39 -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 <memory>
20#include <type_traits>
21#include <unordered_map>
22
23#include <android-base/stringprintf.h>
24#include <gtest/gtest.h>
25
26#include "DwarfCfa.h"
27#include "DwarfLocation.h"
28#include "DwarfMemory.h"
29#include "DwarfStructs.h"
30#include "Log.h"
31
32#include "LogFake.h"
33#include "MemoryFake.h"
34
35template <typename TypeParam>
36class DwarfCfaLogTest : public ::testing::Test {
37 protected:
38 void SetUp() override {
39 ResetLogs();
40 memory_.Clear();
41
42 dmem_.reset(new DwarfMemory(&memory_));
43
44 cie_.cfa_instructions_offset = 0x1000;
45 cie_.cfa_instructions_end = 0x1030;
46 // These two values should be different to distinguish between
47 // operations that deal with code versus data.
48 cie_.code_alignment_factor = 4;
49 cie_.data_alignment_factor = 8;
50
51 fde_.cfa_instructions_offset = 0x2000;
52 fde_.cfa_instructions_end = 0x2030;
53 fde_.pc_start = 0x2000;
54 fde_.pc_end = 0x2000;
55 fde_.pc_end = 0x10000;
56 fde_.cie = &cie_;
57 cfa_.reset(new DwarfCfa<TypeParam>(dmem_.get(), &fde_));
58 }
59
60 MemoryFake memory_;
61 std::unique_ptr<DwarfMemory> dmem_;
62 std::unique_ptr<DwarfCfa<TypeParam>> cfa_;
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070063 DwarfCie cie_;
64 DwarfFde fde_;
Christopher Ferris8642fcb2017-04-24 11:14:39 -070065};
66TYPED_TEST_CASE_P(DwarfCfaLogTest);
67
68// NOTE: All class variable references have to be prefaced with this->.
69
70TYPED_TEST_P(DwarfCfaLogTest, cfa_illegal) {
71 for (uint8_t i = 0x17; i < 0x3f; i++) {
72 if (i == 0x2e || i == 0x2f) {
73 // Skip gnu extension ops.
74 continue;
75 }
76 this->memory_.SetMemory(0x2000, std::vector<uint8_t>{i});
77
78 ResetLogs();
79 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2001));
80 std::string expected = "4 unwind Illegal\n";
81 expected += android::base::StringPrintf("4 unwind Raw Data: 0x%02x\n", i);
82 ASSERT_EQ(expected, GetFakeLogPrint());
83 ASSERT_EQ("", GetFakeLogBuf());
84 }
85}
86
87TYPED_TEST_P(DwarfCfaLogTest, cfa_nop) {
88 this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x00});
89
90 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2001));
91 std::string expected =
92 "4 unwind DW_CFA_nop\n"
93 "4 unwind Raw Data: 0x00\n";
94 ASSERT_EQ(expected, GetFakeLogPrint());
95 ASSERT_EQ("", GetFakeLogBuf());
96}
97
98TYPED_TEST_P(DwarfCfaLogTest, cfa_offset) {
99 this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x83, 0x04});
100
101 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2002));
102 std::string expected =
103 "4 unwind DW_CFA_offset register(3) 4\n"
104 "4 unwind Raw Data: 0x83 0x04\n";
105 ASSERT_EQ(expected, GetFakeLogPrint());
106 ASSERT_EQ("", GetFakeLogBuf());
107
108 ResetLogs();
109 this->memory_.SetMemory(0x2100, std::vector<uint8_t>{0x83, 0x84, 0x01});
110
111 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2100, 0x2103));
112 expected =
113 "4 unwind DW_CFA_offset register(3) 132\n"
114 "4 unwind Raw Data: 0x83 0x84 0x01\n";
115 ASSERT_EQ(expected, GetFakeLogPrint());
116 ASSERT_EQ("", GetFakeLogBuf());
117}
118
119TYPED_TEST_P(DwarfCfaLogTest, cfa_offset_extended) {
120 this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x05, 0x03, 0x02});
121
122 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x503));
123 std::string expected =
124 "4 unwind DW_CFA_offset_extended register(3) 2\n"
125 "4 unwind Raw Data: 0x05 0x03 0x02\n";
126 ASSERT_EQ(expected, GetFakeLogPrint());
127 ASSERT_EQ("", GetFakeLogBuf());
128
129 ResetLogs();
130 this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x05, 0x81, 0x01, 0x82, 0x12});
131
132 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1500, 0x1505));
133 expected =
134 "4 unwind DW_CFA_offset_extended register(129) 2306\n"
135 "4 unwind Raw Data: 0x05 0x81 0x01 0x82 0x12\n";
136 ASSERT_EQ(expected, GetFakeLogPrint());
137 ASSERT_EQ("", GetFakeLogBuf());
138}
139
140TYPED_TEST_P(DwarfCfaLogTest, cfa_offset_extended_sf) {
141 this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x11, 0x05, 0x10});
142
143 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x503));
144 std::string expected =
145 "4 unwind DW_CFA_offset_extended_sf register(5) 16\n"
146 "4 unwind Raw Data: 0x11 0x05 0x10\n";
147 ASSERT_EQ(expected, GetFakeLogPrint());
148 ASSERT_EQ("", GetFakeLogBuf());
149
150 // Check a negative value for the offset.
151 ResetLogs();
152 this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x11, 0x86, 0x01, 0xff, 0x7f});
153
154 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1500, 0x1505));
155 expected =
156 "4 unwind DW_CFA_offset_extended_sf register(134) -1\n"
157 "4 unwind Raw Data: 0x11 0x86 0x01 0xff 0x7f\n";
158 ASSERT_EQ(expected, GetFakeLogPrint());
159 ASSERT_EQ("", GetFakeLogBuf());
160}
161
162TYPED_TEST_P(DwarfCfaLogTest, cfa_restore) {
163 this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0xc2});
164
165 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2001));
166 std::string expected =
167 "4 unwind DW_CFA_restore register(2)\n"
168 "4 unwind Raw Data: 0xc2\n";
169 ASSERT_EQ(expected, GetFakeLogPrint());
170 ASSERT_EQ("", GetFakeLogBuf());
171
172 ResetLogs();
173 this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x82, 0x04, 0xc2});
174
175 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x3000, 0x3003));
176 expected =
177 "4 unwind DW_CFA_offset register(2) 4\n"
178 "4 unwind Raw Data: 0x82 0x04\n"
179 "4 unwind DW_CFA_restore register(2)\n"
180 "4 unwind Raw Data: 0xc2\n";
181 ASSERT_EQ(expected, GetFakeLogPrint());
182 ASSERT_EQ("", GetFakeLogBuf());
183}
184
185TYPED_TEST_P(DwarfCfaLogTest, cfa_restore_extended) {
186 this->memory_.SetMemory(0x4000, std::vector<uint8_t>{0x06, 0x08});
187
188 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x4000, 0x4002));
189 std::string expected =
190 "4 unwind DW_CFA_restore_extended register(8)\n"
191 "4 unwind Raw Data: 0x06 0x08\n";
192 ASSERT_EQ(expected, GetFakeLogPrint());
193 ASSERT_EQ("", GetFakeLogBuf());
194
195 ResetLogs();
196 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x05, 0x82, 0x02, 0x04, 0x06, 0x82, 0x02});
197
198 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x5000, 0x5007));
199 expected =
200 "4 unwind DW_CFA_offset_extended register(258) 4\n"
201 "4 unwind Raw Data: 0x05 0x82 0x02 0x04\n"
202 "4 unwind DW_CFA_restore_extended register(258)\n"
203 "4 unwind Raw Data: 0x06 0x82 0x02\n";
204 ASSERT_EQ(expected, GetFakeLogPrint());
205 ASSERT_EQ("", GetFakeLogBuf());
206}
207
208TYPED_TEST_P(DwarfCfaLogTest, cfa_set_loc) {
209 uint8_t buffer[1 + sizeof(TypeParam)];
210 buffer[0] = 0x1;
211 TypeParam address;
212 std::string raw_data("Raw Data: 0x01 ");
213 std::string address_str;
214 if (std::is_same<TypeParam, uint32_t>::value) {
215 address = 0x81234578U;
216 address_str = "0x81234578";
217 raw_data += "0x78 0x45 0x23 0x81";
218 } else {
219 address = 0x8123456712345678ULL;
220 address_str = "0x8123456712345678";
221 raw_data += "0x78 0x56 0x34 0x12 0x67 0x45 0x23 0x81";
222 }
223 memcpy(&buffer[1], &address, sizeof(address));
224
225 this->memory_.SetMemory(0x50, buffer, sizeof(buffer));
226 ResetLogs();
227
228 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x50, 0x51 + sizeof(TypeParam)));
229 std::string expected = "4 unwind DW_CFA_set_loc " + address_str + "\n";
230 expected += "4 unwind " + raw_data + "\n";
231 expected += "4 unwind \n";
232 expected += "4 unwind PC " + address_str + "\n";
233 ASSERT_EQ(expected, GetFakeLogPrint());
234 ASSERT_EQ("", GetFakeLogBuf());
235
236 // Check for a set going back.
237 ResetLogs();
238 this->fde_.pc_start = address + 0x10;
239
240 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x50, 0x51 + sizeof(TypeParam)));
241 expected = "4 unwind DW_CFA_set_loc " + address_str + "\n";
242 expected += "4 unwind " + raw_data + "\n";
243 expected += "4 unwind \n";
244 expected += "4 unwind PC " + address_str + "\n";
245 ASSERT_EQ(expected, GetFakeLogPrint());
246 ASSERT_EQ("", GetFakeLogBuf());
247}
248
249TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc) {
250 this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x44});
251
252 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x201));
253 std::string expected =
254 "4 unwind DW_CFA_advance_loc 4\n"
255 "4 unwind Raw Data: 0x44\n"
256 "4 unwind \n"
257 "4 unwind PC 0x2010\n";
258 ASSERT_EQ(expected, GetFakeLogPrint());
259 ASSERT_EQ("", GetFakeLogBuf());
260
261 ResetLogs();
262 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x100, 0x200, 0x201));
263 expected =
264 "4 unwind DW_CFA_advance_loc 4\n"
265 "4 unwind Raw Data: 0x44\n"
266 "4 unwind \n"
267 "4 unwind PC 0x2110\n";
268 ASSERT_EQ(expected, GetFakeLogPrint());
269 ASSERT_EQ("", GetFakeLogBuf());
270}
271
272TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc1) {
273 this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x02, 0x04});
274
275 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x202));
276 std::string expected =
277 "4 unwind DW_CFA_advance_loc1 4\n"
278 "4 unwind Raw Data: 0x02 0x04\n"
279 "4 unwind \n"
280 "4 unwind PC 0x2004\n";
281 ASSERT_EQ(expected, GetFakeLogPrint());
282 ASSERT_EQ("", GetFakeLogBuf());
283
284 ResetLogs();
285 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x10, 0x200, 0x202));
286 expected =
287 "4 unwind DW_CFA_advance_loc1 4\n"
288 "4 unwind Raw Data: 0x02 0x04\n"
289 "4 unwind \n"
290 "4 unwind PC 0x2014\n";
291 ASSERT_EQ(expected, GetFakeLogPrint());
292 ASSERT_EQ("", GetFakeLogBuf());
293}
294
295TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc2) {
296 this->memory_.SetMemory(0x600, std::vector<uint8_t>{0x03, 0x04, 0x03});
297
298 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x600, 0x603));
299 std::string expected =
300 "4 unwind DW_CFA_advance_loc2 772\n"
301 "4 unwind Raw Data: 0x03 0x04 0x03\n"
302 "4 unwind \n"
303 "4 unwind PC 0x2304\n";
304 ASSERT_EQ(expected, GetFakeLogPrint());
305 ASSERT_EQ("", GetFakeLogBuf());
306
307 ResetLogs();
308 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x1000, 0x600, 0x603));
309 expected =
310 "4 unwind DW_CFA_advance_loc2 772\n"
311 "4 unwind Raw Data: 0x03 0x04 0x03\n"
312 "4 unwind \n"
313 "4 unwind PC 0x3304\n";
314 ASSERT_EQ(expected, GetFakeLogPrint());
315 ASSERT_EQ("", GetFakeLogBuf());
316}
317
318TYPED_TEST_P(DwarfCfaLogTest, cfa_advance_loc4) {
319 this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x04, 0x04, 0x03, 0x02, 0x01});
320
321 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x505));
322 std::string expected =
323 "4 unwind DW_CFA_advance_loc4 16909060\n"
324 "4 unwind Raw Data: 0x04 0x04 0x03 0x02 0x01\n"
325 "4 unwind \n"
326 "4 unwind PC 0x1022304\n";
327 ASSERT_EQ(expected, GetFakeLogPrint());
328 ASSERT_EQ("", GetFakeLogBuf());
329
330 ResetLogs();
331 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0x2000, 0x500, 0x505));
332 expected =
333 "4 unwind DW_CFA_advance_loc4 16909060\n"
334 "4 unwind Raw Data: 0x04 0x04 0x03 0x02 0x01\n"
335 "4 unwind \n"
336 "4 unwind PC 0x1024304\n";
337 ASSERT_EQ(expected, GetFakeLogPrint());
338 ASSERT_EQ("", GetFakeLogBuf());
339}
340
341TYPED_TEST_P(DwarfCfaLogTest, cfa_undefined) {
342 this->memory_.SetMemory(0xa00, std::vector<uint8_t>{0x07, 0x09});
343
344 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0xa00, 0xa02));
345 std::string expected =
346 "4 unwind DW_CFA_undefined register(9)\n"
347 "4 unwind Raw Data: 0x07 0x09\n";
348 ASSERT_EQ(expected, GetFakeLogPrint());
349 ASSERT_EQ("", GetFakeLogBuf());
350
351 ResetLogs();
352 dwarf_loc_regs_t cie_loc_regs;
353 this->memory_.SetMemory(0x1a00, std::vector<uint8_t>{0x07, 0x81, 0x01});
354
355 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1a00, 0x1a03));
356 expected =
357 "4 unwind DW_CFA_undefined register(129)\n"
358 "4 unwind Raw Data: 0x07 0x81 0x01\n";
359 ASSERT_EQ(expected, GetFakeLogPrint());
360 ASSERT_EQ("", GetFakeLogBuf());
361}
362
363TYPED_TEST_P(DwarfCfaLogTest, cfa_same) {
364 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x08, 0x7f});
365
366 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
367 std::string expected =
368 "4 unwind DW_CFA_same_value register(127)\n"
369 "4 unwind Raw Data: 0x08 0x7f\n";
370 ASSERT_EQ(expected, GetFakeLogPrint());
371 ASSERT_EQ("", GetFakeLogBuf());
372
373 ResetLogs();
374 this->memory_.SetMemory(0x2100, std::vector<uint8_t>{0x08, 0xff, 0x01});
375
376 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2100, 0x2103));
377 expected =
378 "4 unwind DW_CFA_same_value register(255)\n"
379 "4 unwind Raw Data: 0x08 0xff 0x01\n";
380 ASSERT_EQ(expected, GetFakeLogPrint());
381 ASSERT_EQ("", GetFakeLogBuf());
382}
383
384TYPED_TEST_P(DwarfCfaLogTest, cfa_register) {
385 this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x09, 0x02, 0x01});
386
387 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x300, 0x303));
388 std::string expected =
389 "4 unwind DW_CFA_register register(2) register(1)\n"
390 "4 unwind Raw Data: 0x09 0x02 0x01\n";
391 ASSERT_EQ(expected, GetFakeLogPrint());
392 ASSERT_EQ("", GetFakeLogBuf());
393
394 ResetLogs();
395 this->memory_.SetMemory(0x4300, std::vector<uint8_t>{0x09, 0xff, 0x01, 0xff, 0x03});
396
397 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x4300, 0x4305));
398 expected =
399 "4 unwind DW_CFA_register register(255) register(511)\n"
400 "4 unwind Raw Data: 0x09 0xff 0x01 0xff 0x03\n";
401 ASSERT_EQ(expected, GetFakeLogPrint());
402 ASSERT_EQ("", GetFakeLogBuf());
403}
404
405TYPED_TEST_P(DwarfCfaLogTest, cfa_state) {
406 this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x0a});
407
408 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x300, 0x301));
409
410 std::string expected =
411 "4 unwind DW_CFA_remember_state\n"
412 "4 unwind Raw Data: 0x0a\n";
413 ASSERT_EQ(expected, GetFakeLogPrint());
414 ASSERT_EQ("", GetFakeLogBuf());
415
416 ResetLogs();
417 this->memory_.SetMemory(0x4300, std::vector<uint8_t>{0x0b});
418
419 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x4300, 0x4301));
420
421 expected =
422 "4 unwind DW_CFA_restore_state\n"
423 "4 unwind Raw Data: 0x0b\n";
424 ASSERT_EQ(expected, GetFakeLogPrint());
425 ASSERT_EQ("", GetFakeLogBuf());
426}
427
428TYPED_TEST_P(DwarfCfaLogTest, cfa_state_cfa_offset_restore) {
429 this->memory_.SetMemory(0x3000, std::vector<uint8_t>{0x0a, 0x0e, 0x40, 0x0b});
430
431 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x3000, 0x3004));
432
433 std::string expected =
434 "4 unwind DW_CFA_remember_state\n"
435 "4 unwind Raw Data: 0x0a\n"
436 "4 unwind DW_CFA_def_cfa_offset 64\n"
437 "4 unwind Raw Data: 0x0e 0x40\n"
438 "4 unwind DW_CFA_restore_state\n"
439 "4 unwind Raw Data: 0x0b\n";
440 ASSERT_EQ(expected, GetFakeLogPrint());
441 ASSERT_EQ("", GetFakeLogBuf());
442}
443
444TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa) {
445 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0c, 0x7f, 0x74});
446
447 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
448
449 std::string expected =
450 "4 unwind DW_CFA_def_cfa register(127) 116\n"
451 "4 unwind Raw Data: 0x0c 0x7f 0x74\n";
452 ASSERT_EQ(expected, GetFakeLogPrint());
453 ASSERT_EQ("", GetFakeLogBuf());
454
455 ResetLogs();
456 this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0c, 0xff, 0x02, 0xf4, 0x04});
457
458 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x205));
459
460 expected =
461 "4 unwind DW_CFA_def_cfa register(383) 628\n"
462 "4 unwind Raw Data: 0x0c 0xff 0x02 0xf4 0x04\n";
463 ASSERT_EQ(expected, GetFakeLogPrint());
464 ASSERT_EQ("", GetFakeLogBuf());
465}
466
467TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_sf) {
468 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x12, 0x30, 0x25});
469
470 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
471
472 std::string expected =
473 "4 unwind DW_CFA_def_cfa_sf register(48) 37\n"
474 "4 unwind Raw Data: 0x12 0x30 0x25\n";
475 ASSERT_EQ(expected, GetFakeLogPrint());
476 ASSERT_EQ("", GetFakeLogBuf());
477
478 // Test a negative value.
479 ResetLogs();
480 this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x12, 0xa3, 0x01, 0xfa, 0x7f});
481
482 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x205));
483
484 expected =
485 "4 unwind DW_CFA_def_cfa_sf register(163) -6\n"
486 "4 unwind Raw Data: 0x12 0xa3 0x01 0xfa 0x7f\n";
487 ASSERT_EQ(expected, GetFakeLogPrint());
488 ASSERT_EQ("", GetFakeLogBuf());
489}
490
491TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_register) {
492 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0d, 0x72});
493
494 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
495
496 std::string expected =
497 "4 unwind DW_CFA_def_cfa_register register(114)\n"
498 "4 unwind Raw Data: 0x0d 0x72\n";
499 ASSERT_EQ(expected, GetFakeLogPrint());
500 ASSERT_EQ("", GetFakeLogBuf());
501
502 ResetLogs();
503 this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0d, 0xf9, 0x20});
504
505 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x203));
506
507 expected =
508 "4 unwind DW_CFA_def_cfa_register register(4217)\n"
509 "4 unwind Raw Data: 0x0d 0xf9 0x20\n";
510 ASSERT_EQ(expected, GetFakeLogPrint());
511 ASSERT_EQ("", GetFakeLogBuf());
512}
513
514TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_offset) {
515 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0e, 0x59});
516
517 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
518
519 std::string expected =
520 "4 unwind DW_CFA_def_cfa_offset 89\n"
521 "4 unwind Raw Data: 0x0e 0x59\n";
522 ASSERT_EQ(expected, GetFakeLogPrint());
523 ASSERT_EQ("", GetFakeLogBuf());
524
525 ResetLogs();
526 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
527
528 expected =
529 "4 unwind DW_CFA_def_cfa_offset 89\n"
530 "4 unwind Raw Data: 0x0e 0x59\n";
531 ASSERT_EQ(expected, GetFakeLogPrint());
532 ASSERT_EQ("", GetFakeLogBuf());
533
534 ResetLogs();
535 this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x0e, 0xd4, 0x0a});
536
537 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x203));
538
539 expected =
540 "4 unwind DW_CFA_def_cfa_offset 1364\n"
541 "4 unwind Raw Data: 0x0e 0xd4 0x0a\n";
542 ASSERT_EQ(expected, GetFakeLogPrint());
543 ASSERT_EQ("", GetFakeLogBuf());
544}
545
546TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_offset_sf) {
547 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x13, 0x23});
548
549 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
550
551 std::string expected =
552 "4 unwind DW_CFA_def_cfa_offset_sf 35\n"
553 "4 unwind Raw Data: 0x13 0x23\n";
554 ASSERT_EQ(expected, GetFakeLogPrint());
555 ASSERT_EQ("", GetFakeLogBuf());
556
557 ResetLogs();
558 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x102));
559
560 expected =
561 "4 unwind DW_CFA_def_cfa_offset_sf 35\n"
562 "4 unwind Raw Data: 0x13 0x23\n";
563 ASSERT_EQ(expected, GetFakeLogPrint());
564 ASSERT_EQ("", GetFakeLogBuf());
565
566 // Negative offset.
567 ResetLogs();
568 this->memory_.SetMemory(0x200, std::vector<uint8_t>{0x13, 0xf6, 0x7f});
569
570 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x203));
571
572 expected =
573 "4 unwind DW_CFA_def_cfa_offset_sf -10\n"
574 "4 unwind Raw Data: 0x13 0xf6 0x7f\n";
575 ASSERT_EQ(expected, GetFakeLogPrint());
576 ASSERT_EQ("", GetFakeLogBuf());
577}
578
579TYPED_TEST_P(DwarfCfaLogTest, cfa_def_cfa_expression) {
580 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x0f, 0x04, 0x01, 0x02, 0x04, 0x05});
581
582 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x106));
583
584 std::string expected =
585 "4 unwind DW_CFA_def_cfa_expression 4\n"
586 "4 unwind Raw Data: 0x0f 0x04 0x01 0x02 0x04 0x05\n"
587 "4 unwind Illegal\n"
588 "4 unwind Raw Data: 0x01\n"
589 "4 unwind Illegal\n"
590 "4 unwind Raw Data: 0x02\n"
591 "4 unwind Illegal\n"
592 "4 unwind Raw Data: 0x04\n"
593 "4 unwind Illegal\n"
594 "4 unwind Raw Data: 0x05\n";
595 ASSERT_EQ(expected, GetFakeLogPrint());
596 ASSERT_EQ("", GetFakeLogBuf());
597
598 ResetLogs();
599 std::vector<uint8_t> ops{0x0f, 0x81, 0x01};
600 expected = "4 unwind Raw Data: 0x0f 0x81 0x01";
601 std::string op_string;
602 for (uint8_t i = 3; i < 132; i++) {
603 ops.push_back(0x05);
604 op_string +=
605 "4 unwind Illegal\n"
606 "4 unwind Raw Data: 0x05\n";
607 expected += " 0x05";
608 if (((i + 1) % 10) == 0) {
609 expected += "\n4 unwind Raw Data:";
610 }
611 }
612 expected += '\n';
613 this->memory_.SetMemory(0x200, ops);
614 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x284));
615
616 expected = "4 unwind DW_CFA_def_cfa_expression 129\n" + expected;
617 ASSERT_EQ(expected + op_string, GetFakeLogPrint());
618 ASSERT_EQ("", GetFakeLogBuf());
619}
620
621TYPED_TEST_P(DwarfCfaLogTest, cfa_expression) {
622 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x10, 0x04, 0x02, 0xc0, 0xc1});
623
624 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x105));
625
626 std::string expected =
627 "4 unwind DW_CFA_expression register(4) 2\n"
628 "4 unwind Raw Data: 0x10 0x04 0x02 0xc0 0xc1\n"
629 "4 unwind Illegal\n"
630 "4 unwind Raw Data: 0xc0\n"
631 "4 unwind Illegal\n"
632 "4 unwind Raw Data: 0xc1\n";
633 ASSERT_EQ(expected, GetFakeLogPrint());
634 ASSERT_EQ("", GetFakeLogBuf());
635
636 ResetLogs();
637 std::vector<uint8_t> ops{0x10, 0xff, 0x01, 0x82, 0x01};
638 expected = "4 unwind Raw Data: 0x10 0xff 0x01 0x82 0x01";
639 std::string op_string;
640 for (uint8_t i = 5; i < 135; i++) {
641 ops.push_back(0xa0 + (i - 5) % 96);
642 op_string += "4 unwind Illegal\n";
643 op_string += android::base::StringPrintf("4 unwind Raw Data: 0x%02x\n", ops.back());
644 expected += android::base::StringPrintf(" 0x%02x", ops.back());
645 if (((i + 1) % 10) == 0) {
646 expected += "\n4 unwind Raw Data:";
647 }
648 }
649 expected = "4 unwind DW_CFA_expression register(255) 130\n" + expected + "\n";
650
651 this->memory_.SetMemory(0x200, ops);
652 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x200, 0x287));
653
654 ASSERT_EQ(expected + op_string, GetFakeLogPrint());
655 ASSERT_EQ("", GetFakeLogBuf());
656}
657
658TYPED_TEST_P(DwarfCfaLogTest, cfa_val_offset) {
659 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x14, 0x45, 0x54});
660
661 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
662
663 std::string expected =
664 "4 unwind DW_CFA_val_offset register(69) 84\n"
665 "4 unwind Raw Data: 0x14 0x45 0x54\n";
666 ASSERT_EQ(expected, GetFakeLogPrint());
667 ASSERT_EQ("", GetFakeLogBuf());
668
669 ResetLogs();
670 this->memory_.SetMemory(0x400, std::vector<uint8_t>{0x14, 0xa2, 0x02, 0xb4, 0x05});
671
672 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x400, 0x405));
673
674 expected =
675 "4 unwind DW_CFA_val_offset register(290) 692\n"
676 "4 unwind Raw Data: 0x14 0xa2 0x02 0xb4 0x05\n";
677 ASSERT_EQ(expected, GetFakeLogPrint());
678 ASSERT_EQ("", GetFakeLogBuf());
679}
680
681TYPED_TEST_P(DwarfCfaLogTest, cfa_val_offset_sf) {
682 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x15, 0x56, 0x12});
683
684 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x103));
685
686 std::string expected =
687 "4 unwind DW_CFA_val_offset_sf register(86) 18\n"
688 "4 unwind Raw Data: 0x15 0x56 0x12\n";
689 ASSERT_EQ(expected, GetFakeLogPrint());
690 ASSERT_EQ("", GetFakeLogBuf());
691
692 // Negative value.
693 ResetLogs();
694 this->memory_.SetMemory(0xa00, std::vector<uint8_t>{0x15, 0xff, 0x01, 0xc0, 0x7f});
695
696 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0xa00, 0xa05));
697
698 expected =
699 "4 unwind DW_CFA_val_offset_sf register(255) -64\n"
700 "4 unwind Raw Data: 0x15 0xff 0x01 0xc0 0x7f\n";
701 ASSERT_EQ(expected, GetFakeLogPrint());
702 ASSERT_EQ("", GetFakeLogBuf());
703}
704
705TYPED_TEST_P(DwarfCfaLogTest, cfa_val_expression) {
706 this->memory_.SetMemory(0x100, std::vector<uint8_t>{0x16, 0x05, 0x02, 0xb0, 0xb1});
707
708 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x100, 0x105));
709
710 std::string expected =
711 "4 unwind DW_CFA_val_expression register(5) 2\n"
712 "4 unwind Raw Data: 0x16 0x05 0x02 0xb0 0xb1\n"
713 "4 unwind Illegal\n"
714 "4 unwind Raw Data: 0xb0\n"
715 "4 unwind Illegal\n"
716 "4 unwind Raw Data: 0xb1\n";
717 ASSERT_EQ(expected, GetFakeLogPrint());
718 ASSERT_EQ("", GetFakeLogBuf());
719
720 ResetLogs();
721 std::vector<uint8_t> ops{0x16, 0x83, 0x10, 0xa8, 0x01};
722 expected = "4 unwind Raw Data: 0x16 0x83 0x10 0xa8 0x01";
723 std::string op_string;
724 for (uint8_t i = 0; i < 168; i++) {
725 ops.push_back(0xa0 + (i % 96));
726 op_string += "4 unwind Illegal\n";
727 op_string += android::base::StringPrintf("4 unwind Raw Data: 0x%02x\n", ops.back());
728 expected += android::base::StringPrintf(" 0x%02x", ops.back());
729 if (((i + 6) % 10) == 0) {
730 expected += "\n4 unwind Raw Data:";
731 }
732 }
733 expected = "4 unwind DW_CFA_val_expression register(2051) 168\n" + expected + "\n";
734
735 this->memory_.SetMemory(0xa00, ops);
736
737 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0xa00, 0xaad));
738
739 ASSERT_EQ(expected + op_string, GetFakeLogPrint());
740 ASSERT_EQ("", GetFakeLogBuf());
741}
742
743TYPED_TEST_P(DwarfCfaLogTest, cfa_gnu_args_size) {
744 this->memory_.SetMemory(0x2000, std::vector<uint8_t>{0x2e, 0x04});
745
746 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x2000, 0x2002));
747
748 std::string expected =
749 "4 unwind DW_CFA_GNU_args_size 4\n"
750 "4 unwind Raw Data: 0x2e 0x04\n";
751 ASSERT_EQ(expected, GetFakeLogPrint());
752 ASSERT_EQ("", GetFakeLogBuf());
753
754 ResetLogs();
755 this->memory_.SetMemory(0x5000, std::vector<uint8_t>{0x2e, 0xa4, 0x80, 0x04});
756
757 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x5000, 0x5004));
758
759 expected =
760 "4 unwind DW_CFA_GNU_args_size 65572\n"
761 "4 unwind Raw Data: 0x2e 0xa4 0x80 0x04\n";
762 ASSERT_EQ(expected, GetFakeLogPrint());
763 ASSERT_EQ("", GetFakeLogBuf());
764}
765
766TYPED_TEST_P(DwarfCfaLogTest, cfa_gnu_negative_offset_extended) {
767 this->memory_.SetMemory(0x500, std::vector<uint8_t>{0x2f, 0x08, 0x10});
768
769 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x500, 0x503));
770
771 std::string expected =
772 "4 unwind DW_CFA_GNU_negative_offset_extended register(8) 16\n"
773 "4 unwind Raw Data: 0x2f 0x08 0x10\n";
774 ASSERT_EQ(expected, GetFakeLogPrint());
775 ASSERT_EQ("", GetFakeLogBuf());
776
777 ResetLogs();
778 this->memory_.SetMemory(0x1500, std::vector<uint8_t>{0x2f, 0x81, 0x02, 0xff, 0x01});
779
780 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x1500, 0x1505));
781
782 expected =
783 "4 unwind DW_CFA_GNU_negative_offset_extended register(257) 255\n"
784 "4 unwind Raw Data: 0x2f 0x81 0x02 0xff 0x01\n";
785 ASSERT_EQ(expected, GetFakeLogPrint());
786 ASSERT_EQ("", GetFakeLogBuf());
787}
788
789TYPED_TEST_P(DwarfCfaLogTest, cfa_register_override) {
790 this->memory_.SetMemory(0x300, std::vector<uint8_t>{0x09, 0x02, 0x01, 0x09, 0x02, 0x04});
791
792 ASSERT_TRUE(this->cfa_->Log(0, this->fde_.pc_start, 0, 0x300, 0x306));
793
794 std::string expected =
795 "4 unwind DW_CFA_register register(2) register(1)\n"
796 "4 unwind Raw Data: 0x09 0x02 0x01\n"
797 "4 unwind DW_CFA_register register(2) register(4)\n"
798 "4 unwind Raw Data: 0x09 0x02 0x04\n";
799 ASSERT_EQ(expected, GetFakeLogPrint());
800 ASSERT_EQ("", GetFakeLogBuf());
801}
802
803REGISTER_TYPED_TEST_CASE_P(DwarfCfaLogTest, cfa_illegal, cfa_nop, cfa_offset, cfa_offset_extended,
804 cfa_offset_extended_sf, cfa_restore, cfa_restore_extended, cfa_set_loc,
805 cfa_advance_loc, cfa_advance_loc1, cfa_advance_loc2, cfa_advance_loc4,
806 cfa_undefined, cfa_same, cfa_register, cfa_state,
807 cfa_state_cfa_offset_restore, cfa_def_cfa, cfa_def_cfa_sf,
808 cfa_def_cfa_register, cfa_def_cfa_offset, cfa_def_cfa_offset_sf,
809 cfa_def_cfa_expression, cfa_expression, cfa_val_offset,
810 cfa_val_offset_sf, cfa_val_expression, cfa_gnu_args_size,
811 cfa_gnu_negative_offset_extended, cfa_register_override);
812
813typedef ::testing::Types<uint32_t, uint64_t> DwarfCfaLogTestTypes;
814INSTANTIATE_TYPED_TEST_CASE_P(, DwarfCfaLogTest, DwarfCfaLogTestTypes);