1 // Copyright (c) 2010, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // Original author: Jim Blandy <jimb (at) mozilla.com> <jimb (at) red-bean.com> 31 32 // stackwalker_arm64_unittest.cc: Unit tests for StackwalkerARM64 class. 33 34 #include <string.h> 35 #include <string> 36 #include <vector> 37 38 #include "breakpad_googletest_includes.h" 39 #include "common/test_assembler.h" 40 #include "common/using_std_string.h" 41 #include "google_breakpad/common/minidump_format.h" 42 #include "google_breakpad/processor/basic_source_line_resolver.h" 43 #include "google_breakpad/processor/call_stack.h" 44 #include "google_breakpad/processor/code_module.h" 45 #include "google_breakpad/processor/source_line_resolver_interface.h" 46 #include "google_breakpad/processor/stack_frame_cpu.h" 47 #include "processor/stackwalker_unittest_utils.h" 48 #include "processor/stackwalker_arm64.h" 49 #include "processor/windows_frame_info.h" 50 51 using google_breakpad::BasicSourceLineResolver; 52 using google_breakpad::CallStack; 53 using google_breakpad::CodeModule; 54 using google_breakpad::StackFrameSymbolizer; 55 using google_breakpad::StackFrame; 56 using google_breakpad::StackFrameARM64; 57 using google_breakpad::Stackwalker; 58 using google_breakpad::StackwalkerARM64; 59 using google_breakpad::SystemInfo; 60 using google_breakpad::WindowsFrameInfo; 61 using google_breakpad::test_assembler::kLittleEndian; 62 using google_breakpad::test_assembler::Label; 63 using google_breakpad::test_assembler::Section; 64 using std::vector; 65 using testing::_; 66 using testing::AnyNumber; 67 using testing::Return; 68 using testing::SetArgumentPointee; 69 using testing::Test; 70 71 class StackwalkerARM64Fixture { 72 public: 73 StackwalkerARM64Fixture() 74 : stack_section(kLittleEndian), 75 // Give the two modules reasonable standard locations and names 76 // for tests to play with. 77 module1(0x40000000, 0x10000, "module1", "version1"), 78 module2(0x50000000, 0x10000, "module2", "version2") { 79 // Identify the system as an iOS system. 80 system_info.os = "iOS"; 81 system_info.os_short = "ios"; 82 system_info.cpu = "arm64"; 83 system_info.cpu_info = ""; 84 85 // Put distinctive values in the raw CPU context. 86 BrandContext(&raw_context); 87 88 // Create some modules with some stock debugging information. 89 modules.Add(&module1); 90 modules.Add(&module2); 91 92 // By default, none of the modules have symbol info; call 93 // SetModuleSymbols to override this. 94 EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) 95 .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); 96 97 // Avoid GMOCK WARNING "Uninteresting mock function call - returning 98 // directly" for FreeSymbolData(). 99 EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); 100 101 // Reset max_frames_scanned since it's static. 102 Stackwalker::set_max_frames_scanned(1024); 103 } 104 105 // Set the Breakpad symbol information that supplier should return for 106 // MODULE to INFO. 107 void SetModuleSymbols(MockCodeModule *module, const string &info) { 108 size_t buffer_size; 109 char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); 110 EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) 111 .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), 112 SetArgumentPointee<4>(buffer_size), 113 Return(MockSymbolSupplier::FOUND))); 114 } 115 116 // Populate stack_region with the contents of stack_section. Use 117 // stack_section.start() as the region's starting address. 118 void RegionFromSection() { 119 string contents; 120 ASSERT_TRUE(stack_section.GetContents(&contents)); 121 stack_region.Init(stack_section.start().Value(), contents); 122 } 123 124 // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. 125 void BrandContext(MDRawContextARM64 *raw_context) { 126 uint8_t x = 173; 127 for (size_t i = 0; i < sizeof(*raw_context); i++) 128 reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17); 129 } 130 131 SystemInfo system_info; 132 MDRawContextARM64 raw_context; 133 Section stack_section; 134 MockMemoryRegion stack_region; 135 MockCodeModule module1; 136 MockCodeModule module2; 137 MockCodeModules modules; 138 MockSymbolSupplier supplier; 139 BasicSourceLineResolver resolver; 140 CallStack call_stack; 141 const vector<StackFrame *> *frames; 142 }; 143 144 class SanityCheck: public StackwalkerARM64Fixture, public Test { }; 145 146 TEST_F(SanityCheck, NoResolver) { 147 // Since the context's frame pointer is garbage, the stack walk will end after 148 // the first frame. 149 StackFrameSymbolizer frame_symbolizer(NULL, NULL); 150 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, 151 &frame_symbolizer); 152 // This should succeed even without a resolver or supplier. 153 vector<const CodeModule*> modules_without_symbols; 154 vector<const CodeModule*> modules_with_corrupt_symbols; 155 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 156 &modules_with_corrupt_symbols)); 157 ASSERT_EQ(0U, modules_without_symbols.size()); 158 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 159 frames = call_stack.frames(); 160 ASSERT_EQ(1U, frames->size()); 161 StackFrameARM64 *frame = static_cast<StackFrameARM64 *>(frames->at(0)); 162 // Check that the values from the original raw context made it 163 // through to the context in the stack frame. 164 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 165 } 166 167 class GetContextFrame: public StackwalkerARM64Fixture, public Test { }; 168 169 // The stackwalker should be able to produce the context frame even 170 // without stack memory present. 171 TEST_F(GetContextFrame, NoStackMemory) { 172 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 173 StackwalkerARM64 walker(&system_info, &raw_context, NULL, &modules, 174 &frame_symbolizer); 175 vector<const CodeModule*> modules_without_symbols; 176 vector<const CodeModule*> modules_with_corrupt_symbols; 177 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 178 &modules_with_corrupt_symbols)); 179 ASSERT_EQ(0U, modules_without_symbols.size()); 180 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 181 frames = call_stack.frames(); 182 ASSERT_EQ(1U, frames->size()); 183 StackFrameARM64 *frame = static_cast<StackFrameARM64 *>(frames->at(0)); 184 // Check that the values from the original raw context made it 185 // through to the context in the stack frame. 186 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 187 } 188 189 class GetCallerFrame: public StackwalkerARM64Fixture, public Test { }; 190 191 TEST_F(GetCallerFrame, ScanWithoutSymbols) { 192 // When the stack walker resorts to scanning the stack, 193 // only addresses located within loaded modules are 194 // considered valid return addresses. 195 // Force scanning through three frames to ensure that the 196 // stack pointer is set properly in scan-recovered frames. 197 stack_section.start() = 0x80000000; 198 uint64_t return_address1 = 0x50000100; 199 uint64_t return_address2 = 0x50000900; 200 Label frame1_sp, frame2_sp; 201 stack_section 202 // frame 0 203 .Append(16, 0) // space 204 205 .D64(0x40090000) // junk that's not 206 .D64(0x60000000) // a return address 207 208 .D64(return_address1) // actual return address 209 // frame 1 210 .Mark(&frame1_sp) 211 .Append(16, 0) // space 212 213 .D64(0xF0000000) // more junk 214 .D64(0x0000000D) 215 216 .D64(return_address2) // actual return address 217 // frame 2 218 .Mark(&frame2_sp) 219 .Append(64, 0); // end of stack 220 RegionFromSection(); 221 222 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; 223 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); 224 225 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 226 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, 227 &frame_symbolizer); 228 vector<const CodeModule*> modules_without_symbols; 229 vector<const CodeModule*> modules_with_corrupt_symbols; 230 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 231 &modules_with_corrupt_symbols)); 232 ASSERT_EQ(2U, modules_without_symbols.size()); 233 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 234 ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); 235 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 236 frames = call_stack.frames(); 237 ASSERT_EQ(3U, frames->size()); 238 239 StackFrameARM64 *frame0 = static_cast<StackFrameARM64 *>(frames->at(0)); 240 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 241 ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, 242 frame0->context_validity); 243 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 244 245 StackFrameARM64 *frame1 = static_cast<StackFrameARM64 *>(frames->at(1)); 246 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 247 ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | 248 StackFrameARM64::CONTEXT_VALID_SP), 249 frame1->context_validity); 250 EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); 251 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); 252 253 StackFrameARM64 *frame2 = static_cast<StackFrameARM64 *>(frames->at(2)); 254 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust); 255 ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | 256 StackFrameARM64::CONTEXT_VALID_SP), 257 frame2->context_validity); 258 EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM64_REG_PC]); 259 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM64_REG_SP]); 260 } 261 262 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { 263 // During stack scanning, if a potential return address 264 // is located within a loaded module that has symbols, 265 // it is only considered a valid return address if it 266 // lies within a function's bounds. 267 stack_section.start() = 0x80000000; 268 uint64_t return_address = 0x50000200; 269 Label frame1_sp; 270 271 stack_section 272 // frame 0 273 .Append(16, 0) // space 274 275 .D64(0x40090000) // junk that's not 276 .D64(0x60000000) // a return address 277 278 .D64(0x40001000) // a couple of plausible addresses 279 .D64(0x5000F000) // that are not within functions 280 281 .D64(return_address) // actual return address 282 // frame 1 283 .Mark(&frame1_sp) 284 .Append(64, 0); // end of stack 285 RegionFromSection(); 286 287 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40000200; 288 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); 289 290 SetModuleSymbols(&module1, 291 // The youngest frame's function. 292 "FUNC 100 400 10 monotreme\n"); 293 SetModuleSymbols(&module2, 294 // The calling frame's function. 295 "FUNC 100 400 10 marsupial\n"); 296 297 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 298 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, 299 &frame_symbolizer); 300 vector<const CodeModule*> modules_without_symbols; 301 vector<const CodeModule*> modules_with_corrupt_symbols; 302 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 303 &modules_with_corrupt_symbols)); 304 ASSERT_EQ(0U, modules_without_symbols.size()); 305 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 306 frames = call_stack.frames(); 307 ASSERT_EQ(2U, frames->size()); 308 309 StackFrameARM64 *frame0 = static_cast<StackFrameARM64 *>(frames->at(0)); 310 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 311 ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, 312 frame0->context_validity); 313 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 314 EXPECT_EQ("monotreme", frame0->function_name); 315 EXPECT_EQ(0x40000100ULL, frame0->function_base); 316 317 StackFrameARM64 *frame1 = static_cast<StackFrameARM64 *>(frames->at(1)); 318 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 319 ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | 320 StackFrameARM64::CONTEXT_VALID_SP), 321 frame1->context_validity); 322 EXPECT_EQ(return_address, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); 323 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); 324 EXPECT_EQ("marsupial", frame1->function_name); 325 EXPECT_EQ(0x50000100ULL, frame1->function_base); 326 } 327 328 TEST_F(GetCallerFrame, ScanFirstFrame) { 329 // If the stackwalker resorts to stack scanning, it will scan much 330 // farther to find the caller of the context frame. 331 stack_section.start() = 0x80000000; 332 uint64_t return_address1 = 0x50000100; 333 uint64_t return_address2 = 0x50000900; 334 Label frame1_sp, frame2_sp; 335 stack_section 336 // frame 0 337 .Append(32, 0) // space 338 339 .D64(0x40090000) // junk that's not 340 .D64(0x60000000) // a return address 341 342 .Append(96, 0) // more space 343 344 .D64(return_address1) // actual return address 345 // frame 1 346 .Mark(&frame1_sp) 347 .Append(32, 0) // space 348 349 .D64(0xF0000000) // more junk 350 .D64(0x0000000D) 351 352 .Append(256, 0) // more space 353 354 .D64(return_address2) // actual return address 355 // (won't be found) 356 // frame 2 357 .Mark(&frame2_sp) 358 .Append(64, 0); // end of stack 359 RegionFromSection(); 360 361 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; 362 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); 363 364 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 365 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, 366 &frame_symbolizer); 367 vector<const CodeModule*> modules_without_symbols; 368 vector<const CodeModule*> modules_with_corrupt_symbols; 369 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 370 &modules_with_corrupt_symbols)); 371 ASSERT_EQ(2U, modules_without_symbols.size()); 372 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 373 ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); 374 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 375 frames = call_stack.frames(); 376 ASSERT_EQ(2U, frames->size()); 377 378 StackFrameARM64 *frame0 = static_cast<StackFrameARM64 *>(frames->at(0)); 379 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 380 ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, 381 frame0->context_validity); 382 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 383 384 StackFrameARM64 *frame1 = static_cast<StackFrameARM64 *>(frames->at(1)); 385 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 386 ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | 387 StackFrameARM64::CONTEXT_VALID_SP), 388 frame1->context_validity); 389 EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); 390 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); 391 } 392 393 // Test that set_max_frames_scanned prevents using stack scanning 394 // to find caller frames. 395 TEST_F(GetCallerFrame, ScanningNotAllowed) { 396 // When the stack walker resorts to scanning the stack, 397 // only addresses located within loaded modules are 398 // considered valid return addresses. 399 stack_section.start() = 0x80000000; 400 uint64_t return_address1 = 0x50000100; 401 uint64_t return_address2 = 0x50000900; 402 Label frame1_sp, frame2_sp; 403 stack_section 404 // frame 0 405 .Append(16, 0) // space 406 407 .D64(0x40090000) // junk that's not 408 .D64(0x60000000) // a return address 409 410 .D64(return_address1) // actual return address 411 // frame 1 412 .Mark(&frame1_sp) 413 .Append(16, 0) // space 414 415 .D64(0xF0000000) // more junk 416 .D64(0x0000000D) 417 418 .D64(return_address2) // actual return address 419 // frame 2 420 .Mark(&frame2_sp) 421 .Append(64, 0); // end of stack 422 RegionFromSection(); 423 424 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; 425 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); 426 427 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 428 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, 429 &frame_symbolizer); 430 Stackwalker::set_max_frames_scanned(0); 431 432 vector<const CodeModule*> modules_without_symbols; 433 vector<const CodeModule*> modules_with_corrupt_symbols; 434 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 435 &modules_with_corrupt_symbols)); 436 ASSERT_EQ(1U, modules_without_symbols.size()); 437 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 438 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 439 frames = call_stack.frames(); 440 ASSERT_EQ(1U, frames->size()); 441 442 StackFrameARM64 *frame0 = static_cast<StackFrameARM64 *>(frames->at(0)); 443 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 444 ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, 445 frame0->context_validity); 446 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 447 } 448 449 class GetFramesByFramePointer: public StackwalkerARM64Fixture, public Test { }; 450 451 TEST_F(GetFramesByFramePointer, OnlyFramePointer) { 452 stack_section.start() = 0x80000000; 453 uint64_t return_address1 = 0x50000100; 454 uint64_t return_address2 = 0x50000900; 455 Label frame1_sp, frame2_sp; 456 Label frame1_fp, frame2_fp; 457 stack_section 458 // frame 0 459 .Append(64, 0) // Whatever values on the stack. 460 .D64(0x0000000D) // junk that's not 461 .D64(0xF0000000) // a return address. 462 463 .Mark(&frame1_fp) // Next fp will point to the next value. 464 .D64(frame2_fp) // Save current frame pointer. 465 .D64(return_address2) // Save current link register. 466 .Mark(&frame1_sp) 467 468 // frame 1 469 .Append(64, 0) // Whatever values on the stack. 470 .D64(0x0000000D) // junk that's not 471 .D64(0xF0000000) // a return address. 472 473 .Mark(&frame2_fp) 474 .D64(0) 475 .D64(0) 476 .Mark(&frame2_sp) 477 478 // frame 2 479 .Append(64, 0) // Whatever values on the stack. 480 .D64(0x0000000D) // junk that's not 481 .D64(0xF0000000); // a return address. 482 RegionFromSection(); 483 484 485 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x40005510; 486 raw_context.iregs[MD_CONTEXT_ARM64_REG_LR] = return_address1; 487 raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = frame1_fp.Value(); 488 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); 489 490 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 491 StackwalkerARM64 walker(&system_info, &raw_context, 492 &stack_region, &modules, &frame_symbolizer); 493 494 vector<const CodeModule*> modules_without_symbols; 495 vector<const CodeModule*> modules_with_corrupt_symbols; 496 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 497 &modules_with_corrupt_symbols)); 498 ASSERT_EQ(2U, modules_without_symbols.size()); 499 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 500 ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); 501 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 502 frames = call_stack.frames(); 503 ASSERT_EQ(3U, frames->size()); 504 505 StackFrameARM64 *frame0 = static_cast<StackFrameARM64 *>(frames->at(0)); 506 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 507 ASSERT_EQ(StackFrameARM64::CONTEXT_VALID_ALL, 508 frame0->context_validity); 509 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 510 511 StackFrameARM64 *frame1 = static_cast<StackFrameARM64 *>(frames->at(1)); 512 EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); 513 ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | 514 StackFrameARM64::CONTEXT_VALID_LR | 515 StackFrameARM64::CONTEXT_VALID_FP | 516 StackFrameARM64::CONTEXT_VALID_SP), 517 frame1->context_validity); 518 EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); 519 EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM64_REG_LR]); 520 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); 521 EXPECT_EQ(frame2_fp.Value(), 522 frame1->context.iregs[MD_CONTEXT_ARM64_REG_FP]); 523 524 StackFrameARM64 *frame2 = static_cast<StackFrameARM64 *>(frames->at(2)); 525 EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust); 526 ASSERT_EQ((StackFrameARM64::CONTEXT_VALID_PC | 527 StackFrameARM64::CONTEXT_VALID_LR | 528 StackFrameARM64::CONTEXT_VALID_FP | 529 StackFrameARM64::CONTEXT_VALID_SP), 530 frame2->context_validity); 531 EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM64_REG_PC]); 532 EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM64_REG_LR]); 533 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM64_REG_SP]); 534 EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM64_REG_FP]); 535 } 536 537 struct CFIFixture: public StackwalkerARM64Fixture { 538 CFIFixture() { 539 // Provide a bunch of STACK CFI records; we'll walk to the caller 540 // from every point in this series, expecting to find the same set 541 // of register values. 542 SetModuleSymbols(&module1, 543 // The youngest frame's function. 544 "FUNC 4000 1000 10 enchiridion\n" 545 // Initially, nothing has been pushed on the stack, 546 // and the return address is still in the link 547 // register (x30). 548 "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: x30\n" 549 // Push x19, x20, the frame pointer and the link register. 550 "STACK CFI 4001 .cfa: sp 32 + .ra: .cfa -8 + ^" 551 " x19: .cfa -32 + ^ x20: .cfa -24 + ^ " 552 " x29: .cfa -16 + ^\n" 553 // Save x19..x22 in x0..x3: verify that we populate 554 // the youngest frame with all the values we have. 555 "STACK CFI 4002 x19: x0 x20: x1 x21: x2 x22: x3\n" 556 // Restore x19..x22. Save the non-callee-saves register x1. 557 "STACK CFI 4003 .cfa: sp 40 + x1: .cfa 40 - ^" 558 " x19: x19 x20: x20 x21: x21 x22: x22\n" 559 // Move the .cfa back eight bytes, to point at the return 560 // address, and restore the sp explicitly. 561 "STACK CFI 4005 .cfa: sp 32 + x1: .cfa 32 - ^" 562 " x29: .cfa 8 - ^ .ra: .cfa ^ sp: .cfa 8 +\n" 563 // Recover the PC explicitly from a new stack slot; 564 // provide garbage for the .ra. 565 "STACK CFI 4006 .cfa: sp 40 + pc: .cfa 40 - ^\n" 566 567 // The calling function. 568 "FUNC 5000 1000 10 epictetus\n" 569 // Mark it as end of stack. 570 "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n" 571 572 // A function whose CFI makes the stack pointer 573 // go backwards. 574 "FUNC 6000 1000 20 palinal\n" 575 "STACK CFI INIT 6000 1000 .cfa: sp 8 - .ra: x30\n" 576 577 // A function with CFI expressions that can't be 578 // evaluated. 579 "FUNC 7000 1000 20 rhetorical\n" 580 "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n"); 581 582 // Provide some distinctive values for the caller's registers. 583 expected.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040005510L; 584 expected.iregs[MD_CONTEXT_ARM64_REG_SP] = 0x0000000080000000L; 585 expected.iregs[19] = 0x5e68b5d5b5d55e68L; 586 expected.iregs[20] = 0x34f3ebd1ebd134f3L; 587 expected.iregs[21] = 0x74bca31ea31e74bcL; 588 expected.iregs[22] = 0x16b32dcb2dcb16b3L; 589 expected.iregs[23] = 0x21372ada2ada2137L; 590 expected.iregs[24] = 0x557dbbbbbbbb557dL; 591 expected.iregs[25] = 0x8ca748bf48bf8ca7L; 592 expected.iregs[26] = 0x21f0ab46ab4621f0L; 593 expected.iregs[27] = 0x146732b732b71467L; 594 expected.iregs[28] = 0xa673645fa673645fL; 595 expected.iregs[MD_CONTEXT_ARM64_REG_FP] = 0xe11081128112e110L; 596 597 // Expect CFI to recover all callee-saves registers. Since CFI is the 598 // only stack frame construction technique we have, aside from the 599 // context frame itself, there's no way for us to have a set of valid 600 // registers smaller than this. 601 expected_validity = (StackFrameARM64::CONTEXT_VALID_PC | 602 StackFrameARM64::CONTEXT_VALID_SP | 603 StackFrameARM64::CONTEXT_VALID_X19 | 604 StackFrameARM64::CONTEXT_VALID_X20 | 605 StackFrameARM64::CONTEXT_VALID_X21 | 606 StackFrameARM64::CONTEXT_VALID_X22 | 607 StackFrameARM64::CONTEXT_VALID_X23 | 608 StackFrameARM64::CONTEXT_VALID_X24 | 609 StackFrameARM64::CONTEXT_VALID_X25 | 610 StackFrameARM64::CONTEXT_VALID_X26 | 611 StackFrameARM64::CONTEXT_VALID_X27 | 612 StackFrameARM64::CONTEXT_VALID_X28 | 613 StackFrameARM64::CONTEXT_VALID_FP); 614 615 // By default, context frames provide all registers, as normal. 616 context_frame_validity = StackFrameARM64::CONTEXT_VALID_ALL; 617 618 // By default, registers are unchanged. 619 raw_context = expected; 620 } 621 622 // Walk the stack, using stack_section as the contents of the stack 623 // and raw_context as the current register values. (Set the stack 624 // pointer to the stack's starting address.) Expect two stack 625 // frames; in the older frame, expect the callee-saves registers to 626 // have values matching those in 'expected'. 627 void CheckWalk() { 628 RegionFromSection(); 629 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = stack_section.start().Value(); 630 631 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 632 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, 633 &modules, &frame_symbolizer); 634 walker.SetContextFrameValidity(context_frame_validity); 635 vector<const CodeModule*> modules_without_symbols; 636 vector<const CodeModule*> modules_with_corrupt_symbols; 637 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 638 &modules_with_corrupt_symbols)); 639 ASSERT_EQ(0U, modules_without_symbols.size()); 640 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 641 frames = call_stack.frames(); 642 ASSERT_EQ(2U, frames->size()); 643 644 StackFrameARM64 *frame0 = static_cast<StackFrameARM64 *>(frames->at(0)); 645 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 646 ASSERT_EQ(context_frame_validity, frame0->context_validity); 647 EXPECT_EQ("enchiridion", frame0->function_name); 648 EXPECT_EQ(0x0000000040004000UL, frame0->function_base); 649 650 StackFrameARM64 *frame1 = static_cast<StackFrameARM64 *>(frames->at(1)); 651 EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 652 ASSERT_EQ(expected_validity, frame1->context_validity); 653 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X1) 654 EXPECT_EQ(expected.iregs[1], frame1->context.iregs[1]); 655 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X19) 656 EXPECT_EQ(expected.iregs[19], frame1->context.iregs[19]); 657 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X20) 658 EXPECT_EQ(expected.iregs[20], frame1->context.iregs[20]); 659 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X21) 660 EXPECT_EQ(expected.iregs[21], frame1->context.iregs[21]); 661 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X22) 662 EXPECT_EQ(expected.iregs[22], frame1->context.iregs[22]); 663 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X23) 664 EXPECT_EQ(expected.iregs[23], frame1->context.iregs[23]); 665 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X24) 666 EXPECT_EQ(expected.iregs[24], frame1->context.iregs[24]); 667 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X25) 668 EXPECT_EQ(expected.iregs[25], frame1->context.iregs[25]); 669 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X26) 670 EXPECT_EQ(expected.iregs[26], frame1->context.iregs[26]); 671 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X27) 672 EXPECT_EQ(expected.iregs[27], frame1->context.iregs[27]); 673 if (expected_validity & StackFrameARM64::CONTEXT_VALID_X28) 674 EXPECT_EQ(expected.iregs[28], frame1->context.iregs[28]); 675 if (expected_validity & StackFrameARM64::CONTEXT_VALID_FP) 676 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_FP], 677 frame1->context.iregs[MD_CONTEXT_ARM64_REG_FP]); 678 679 // We would never have gotten a frame in the first place if the SP 680 // and PC weren't valid or ->instruction weren't set. 681 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_SP], 682 frame1->context.iregs[MD_CONTEXT_ARM64_REG_SP]); 683 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_PC], 684 frame1->context.iregs[MD_CONTEXT_ARM64_REG_PC]); 685 EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM64_REG_PC], 686 frame1->instruction + 4); 687 EXPECT_EQ("epictetus", frame1->function_name); 688 } 689 690 // The values we expect to find for the caller's registers. 691 MDRawContextARM64 expected; 692 693 // The validity mask for expected. 694 uint64_t expected_validity; 695 696 // The validity mask to impose on the context frame. 697 uint64_t context_frame_validity; 698 }; 699 700 class CFI: public CFIFixture, public Test { }; 701 702 TEST_F(CFI, At4000) { 703 stack_section.start() = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 704 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004000L; 705 raw_context.iregs[MD_CONTEXT_ARM64_REG_LR] = 0x0000000040005510L; 706 CheckWalk(); 707 } 708 709 TEST_F(CFI, At4001) { 710 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 711 stack_section 712 .D64(0x5e68b5d5b5d55e68L) // saved x19 713 .D64(0x34f3ebd1ebd134f3L) // saved x20 714 .D64(0xe11081128112e110L) // saved fp 715 .D64(0x0000000040005510L) // return address 716 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 717 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004001L; 718 // distinct callee x19, x20 and fp 719 raw_context.iregs[19] = 0xadc9f635a635adc9L; 720 raw_context.iregs[20] = 0x623135ac35ac6231L; 721 raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; 722 CheckWalk(); 723 } 724 725 // As above, but unwind from a context that has only the PC and SP. 726 TEST_F(CFI, At4001LimitedValidity) { 727 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 728 stack_section 729 .D64(0x5e68b5d5b5d55e68L) // saved x19 730 .D64(0x34f3ebd1ebd134f3L) // saved x20 731 .D64(0xe11081128112e110L) // saved fp 732 .D64(0x0000000040005510L) // return address 733 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 734 context_frame_validity = 735 StackFrameARM64::CONTEXT_VALID_PC | StackFrameARM64::CONTEXT_VALID_SP; 736 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004001L; 737 raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; 738 739 expected_validity = (StackFrameARM64::CONTEXT_VALID_PC 740 | StackFrameARM64::CONTEXT_VALID_SP 741 | StackFrameARM64::CONTEXT_VALID_FP 742 | StackFrameARM64::CONTEXT_VALID_X19 743 | StackFrameARM64::CONTEXT_VALID_X20); 744 CheckWalk(); 745 } 746 747 TEST_F(CFI, At4002) { 748 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 749 stack_section 750 .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 751 .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 752 .D64(0xe11081128112e110L) // saved fp 753 .D64(0x0000000040005510L) // return address 754 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 755 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004002L; 756 raw_context.iregs[0] = 0x5e68b5d5b5d55e68L; // saved x19 757 raw_context.iregs[1] = 0x34f3ebd1ebd134f3L; // saved x20 758 raw_context.iregs[2] = 0x74bca31ea31e74bcL; // saved x21 759 raw_context.iregs[3] = 0x16b32dcb2dcb16b3L; // saved x22 760 raw_context.iregs[19] = 0xadc9f635a635adc9L; // distinct callee x19 761 raw_context.iregs[20] = 0x623135ac35ac6231L; // distinct callee x20 762 raw_context.iregs[21] = 0xac4543564356ac45L; // distinct callee x21 763 raw_context.iregs[22] = 0x2561562f562f2561L; // distinct callee x22 764 // distinct callee fp 765 raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; 766 CheckWalk(); 767 } 768 769 TEST_F(CFI, At4003) { 770 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 771 stack_section 772 .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) 773 .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 774 .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 775 .D64(0xe11081128112e110L) // saved fp 776 .D64(0x0000000040005510L) // return address 777 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 778 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004003L; 779 // distinct callee x1 and fp 780 raw_context.iregs[1] = 0xfb756319fb756319L; 781 raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; 782 // caller's x1 783 expected.iregs[1] = 0xdd5a48c848c8dd5aL; 784 expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; 785 CheckWalk(); 786 } 787 788 // We have no new rule at module offset 0x4004, so the results here should 789 // be the same as those at module offset 0x4003. 790 TEST_F(CFI, At4004) { 791 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 792 stack_section 793 .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) 794 .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 795 .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 796 .D64(0xe11081128112e110L) // saved fp 797 .D64(0x0000000040005510L) // return address 798 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 799 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004004L; 800 // distinct callee x1 and fp 801 raw_context.iregs[1] = 0xfb756319fb756319L; 802 raw_context.iregs[MD_CONTEXT_ARM64_REG_FP] = 0x5fc4be14be145fc4L; 803 // caller's x1 804 expected.iregs[1] = 0xdd5a48c848c8dd5aL; 805 expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; 806 CheckWalk(); 807 } 808 809 // Here we move the .cfa, but provide an explicit rule to recover the SP, 810 // so again there should be no change in the registers recovered. 811 TEST_F(CFI, At4005) { 812 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 813 stack_section 814 .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) 815 .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 816 .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 817 .D64(0xe11081128112e110L) // saved fp 818 .D64(0x0000000040005510L) // return address 819 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 820 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004005L; 821 raw_context.iregs[1] = 0xfb756319fb756319L; // distinct callee x1 822 expected.iregs[1] = 0xdd5a48c848c8dd5aL; // caller's x1 823 expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; 824 CheckWalk(); 825 } 826 827 // Here we provide an explicit rule for the PC, and have the saved .ra be 828 // bogus. 829 TEST_F(CFI, At4006) { 830 Label frame1_sp = expected.iregs[MD_CONTEXT_ARM64_REG_SP]; 831 stack_section 832 .D64(0x0000000040005510L) // saved pc 833 .D64(0xdd5a48c848c8dd5aL) // saved x1 (even though it's not callee-saves) 834 .D64(0xff3dfb81fb81ff3dL) // no longer saved x19 835 .D64(0x34f3ebd1ebd134f3L) // no longer saved x20 836 .D64(0xe11081128112e110L) // saved fp 837 .D64(0xf8d157835783f8d1L) // .ra rule recovers this, which is garbage 838 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 839 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040004006L; 840 raw_context.iregs[1] = 0xfb756319fb756319L; // distinct callee x1 841 expected.iregs[1] = 0xdd5a48c848c8dd5aL; // caller's x1 842 expected_validity |= StackFrameARM64::CONTEXT_VALID_X1; 843 CheckWalk(); 844 } 845 846 // Check that we reject rules that would cause the stack pointer to 847 // move in the wrong direction. 848 TEST_F(CFI, RejectBackwards) { 849 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040006000L; 850 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = 0x0000000080000000L; 851 raw_context.iregs[MD_CONTEXT_ARM64_REG_LR] = 0x0000000040005510L; 852 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 853 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, 854 &frame_symbolizer); 855 vector<const CodeModule*> modules_without_symbols; 856 vector<const CodeModule*> modules_with_corrupt_symbols; 857 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 858 &modules_with_corrupt_symbols)); 859 ASSERT_EQ(0U, modules_without_symbols.size()); 860 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 861 frames = call_stack.frames(); 862 ASSERT_EQ(1U, frames->size()); 863 } 864 865 // Check that we reject rules whose expressions' evaluation fails. 866 TEST_F(CFI, RejectBadExpressions) { 867 raw_context.iregs[MD_CONTEXT_ARM64_REG_PC] = 0x0000000040007000L; 868 raw_context.iregs[MD_CONTEXT_ARM64_REG_SP] = 0x0000000080000000L; 869 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 870 StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, 871 &frame_symbolizer); 872 vector<const CodeModule*> modules_without_symbols; 873 vector<const CodeModule*> modules_with_corrupt_symbols; 874 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 875 &modules_with_corrupt_symbols)); 876 ASSERT_EQ(0U, modules_without_symbols.size()); 877 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 878 frames = call_stack.frames(); 879 ASSERT_EQ(1U, frames->size()); 880 } 881