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