stackwalker_mips64_unittest.cc
1 // Copyright 2013 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 // Original author: Veljko Mihailovic <veljko.mihailovic@imgtec.com> 30 31 // stackwalker_mips64_unittest.cc: Unit tests for StackwalkerMIPS class for 32 // mips64 platforms. 33 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> // Must come first 36 #endif 37 38 #include <string.h> 39 #include <string> 40 #include <vector> 41 42 #include "breakpad_googletest_includes.h" 43 #include "common/test_assembler.h" 44 #include "common/using_std_string.h" 45 #include "google_breakpad/common/minidump_format.h" 46 #include "google_breakpad/processor/basic_source_line_resolver.h" 47 #include "google_breakpad/processor/call_stack.h" 48 #include "google_breakpad/processor/code_module.h" 49 #include "google_breakpad/processor/source_line_resolver_interface.h" 50 #include "google_breakpad/processor/stack_frame_cpu.h" 51 #include "processor/stackwalker_unittest_utils.h" 52 #include "processor/stackwalker_mips.h" 53 #include "processor/windows_frame_info.h" 54 55 using google_breakpad::BasicSourceLineResolver; 56 using google_breakpad::CallStack; 57 using google_breakpad::CodeModule; 58 using google_breakpad::StackFrameSymbolizer; 59 using google_breakpad::StackFrame; 60 using google_breakpad::StackFrameMIPS; 61 using google_breakpad::Stackwalker; 62 using google_breakpad::StackwalkerMIPS; 63 using google_breakpad::SystemInfo; 64 using google_breakpad::WindowsFrameInfo; 65 using google_breakpad::test_assembler::kLittleEndian; 66 using google_breakpad::test_assembler::Label; 67 using google_breakpad::test_assembler::Section; 68 using std::vector; 69 using testing::_; 70 using testing::AnyNumber; 71 using testing::DoAll; 72 using testing::Return; 73 using testing::SetArgumentPointee; 74 using testing::Test; 75 76 class StackwalkerMIPSFixture { 77 public: 78 StackwalkerMIPSFixture() 79 : stack_section(kLittleEndian), 80 // Give the two modules reasonable standard locations and names 81 // for tests to play with. 82 module1(0x00400000, 0x10000, "module1", "version1"), 83 module2(0x00500000, 0x10000, "module2", "version2") { 84 // Identify the system as a Linux system. 85 system_info.os = "Linux"; 86 system_info.os_short = "linux"; 87 system_info.os_version = "Observant Opossum"; // Jealous Jellyfish 88 system_info.cpu = "mips64"; 89 system_info.cpu_info = ""; 90 91 // Put distinctive values in the raw CPU context. 92 BrandContext(&raw_context); 93 94 // Create some modules with some stock debugging information. 95 modules.Add(&module1); 96 modules.Add(&module2); 97 98 // By default, none of the modules have symbol info; call 99 // SetModuleSymbols to override this. 100 EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _)) 101 .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND)); 102 103 // Avoid GMOCK WARNING "Uninteresting mock function call - returning 104 // directly" for FreeSymbolData(). 105 EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber()); 106 107 // Reset max_frames_scanned since it's static. 108 Stackwalker::set_max_frames_scanned(1024); 109 } 110 111 // Set the Breakpad symbol information that supplier should return for 112 // MODULE to INFO. 113 void SetModuleSymbols(MockCodeModule* module, const string& info) { 114 size_t buffer_size; 115 char* buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); 116 EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _)) 117 .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), 118 SetArgumentPointee<4>(buffer_size), 119 Return(MockSymbolSupplier::FOUND))); 120 } 121 122 // Populate stack_region with the contents of stack_section. Use 123 // stack_section.start() as the region's starting address. 124 void RegionFromSection() { 125 string contents; 126 ASSERT_TRUE(stack_section.GetContents(&contents)); 127 stack_region.Init(stack_section.start().Value(), contents); 128 } 129 130 // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking. 131 void BrandContext(MDRawContextMIPS* raw_context) { 132 uint8_t x = 173; 133 for (size_t i = 0; i < sizeof(*raw_context); ++i) 134 reinterpret_cast<uint8_t*>(raw_context)[i] = (x += 17); 135 } 136 137 SystemInfo system_info; 138 MDRawContextMIPS raw_context; 139 Section stack_section; 140 MockMemoryRegion stack_region; 141 MockCodeModule module1; 142 MockCodeModule module2; 143 MockCodeModules modules; 144 MockSymbolSupplier supplier; 145 BasicSourceLineResolver resolver; 146 CallStack call_stack; 147 const vector<StackFrame*>* frames; 148 }; 149 150 class SanityCheck: public StackwalkerMIPSFixture, public Test { }; 151 152 TEST_F(SanityCheck, NoResolver) { 153 raw_context.context_flags = 154 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 155 stack_section.start() = 0x80000000; 156 stack_section.D64(0).D64(0x0); 157 RegionFromSection(); 158 raw_context.epc = 0x00400020; 159 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; 160 161 StackFrameSymbolizer frame_symbolizer(NULL, NULL); 162 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 163 &frame_symbolizer); 164 // This should succeed, even without a resolver or supplier. 165 vector<const CodeModule*> modules_without_symbols; 166 vector<const CodeModule*> modules_with_corrupt_symbols; 167 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 168 &modules_with_corrupt_symbols)); 169 ASSERT_EQ(1U, modules_without_symbols.size()); 170 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 171 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 172 frames = call_stack.frames(); 173 ASSERT_EQ(1U, frames->size()); 174 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); 175 // Check that the values from the original raw context made it 176 // through to the context in the stack frame. 177 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 178 } 179 180 class GetContextFrame: public StackwalkerMIPSFixture, public Test { }; 181 182 TEST_F(GetContextFrame, Simple) { 183 raw_context.context_flags = 184 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 185 stack_section.start() = 0x80000000; 186 stack_section.D64(0).D64(0x0); 187 RegionFromSection(); 188 raw_context.epc = 0x00400020; 189 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; 190 191 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 192 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 193 &frame_symbolizer); 194 vector<const CodeModule*> modules_without_symbols; 195 vector<const CodeModule*> modules_with_corrupt_symbols; 196 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 197 &modules_with_corrupt_symbols)); 198 ASSERT_EQ(1U, modules_without_symbols.size()); 199 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 200 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 201 frames = call_stack.frames(); 202 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); 203 // Check that the values from the original raw context made it 204 // through to the context in the stack frame. 205 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 206 } 207 208 // The stackwalker should be able to produce the context frame even 209 // without stack memory present. 210 TEST_F(GetContextFrame, NoStackMemory) { 211 raw_context.context_flags = 212 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 213 raw_context.epc = 0x00400020; 214 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; 215 216 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 217 StackwalkerMIPS walker(&system_info, &raw_context, NULL, &modules, 218 &frame_symbolizer); 219 vector<const CodeModule*> modules_without_symbols; 220 vector<const CodeModule*> modules_with_corrupt_symbols; 221 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 222 &modules_with_corrupt_symbols)); 223 ASSERT_EQ(1U, modules_without_symbols.size()); 224 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 225 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 226 frames = call_stack.frames(); 227 StackFrameMIPS* frame = static_cast<StackFrameMIPS*>(frames->at(0)); 228 // Check that the values from the original raw context made it 229 // through to the context in the stack frame. 230 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 231 } 232 233 class GetCallerFrame: public StackwalkerMIPSFixture, public Test { }; 234 235 TEST_F(GetCallerFrame, ScanWithoutSymbols) { 236 raw_context.context_flags = 237 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 238 // When the stack walker resorts to scanning the stack, 239 // only addresses located within loaded modules are 240 // considered valid return addresses. 241 // Force scanning through three frames to ensure that the 242 // stack pointer is set properly in scan-recovered frames. 243 stack_section.start() = 0x80000000; 244 uint64_t return_address1 = 0x00400100; 245 uint64_t return_address2 = 0x00400900; 246 Label frame1_sp, frame2_sp; 247 stack_section 248 // frame 0 249 .Append(32, 0) // space 250 251 .D64(0x00490000) // junk that's not 252 .D64(0x00600000) // a return address 253 254 .D64(frame1_sp) // stack pointer 255 .D64(return_address1) // actual return address 256 // frame 1 257 .Mark(&frame1_sp) 258 .Append(32, 0) // space 259 260 .D64(0xF0000000) // more junk 261 .D64(0x0000000D) 262 263 .D64(frame2_sp) // stack pointer 264 .D64(return_address2) // actual return address 265 // frame 2 266 .Mark(&frame2_sp) 267 .Append(64, 0); // end of stack 268 RegionFromSection(); 269 270 raw_context.epc = 0x00405510; 271 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); 272 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; 273 274 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 275 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 276 &frame_symbolizer); 277 vector<const CodeModule*> modules_without_symbols; 278 vector<const CodeModule*> modules_with_corrupt_symbols; 279 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 280 &modules_with_corrupt_symbols)); 281 ASSERT_EQ(1U, modules_without_symbols.size()); 282 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 283 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 284 frames = call_stack.frames(); 285 ASSERT_EQ(3U, frames->size()); 286 287 StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0)); 288 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 289 ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); 290 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 291 292 StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1)); 293 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 294 ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | 295 StackFrameMIPS::CONTEXT_VALID_SP | 296 StackFrameMIPS::CONTEXT_VALID_FP | 297 StackFrameMIPS::CONTEXT_VALID_RA), 298 frame1->context_validity); 299 EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc); 300 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); 301 302 StackFrameMIPS* frame2 = static_cast<StackFrameMIPS*>(frames->at(2)); 303 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust); 304 ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | 305 StackFrameMIPS::CONTEXT_VALID_SP | 306 StackFrameMIPS::CONTEXT_VALID_FP | 307 StackFrameMIPS::CONTEXT_VALID_RA), 308 frame2->context_validity); 309 EXPECT_EQ(return_address2 - 2 * sizeof(return_address2), frame2->context.epc); 310 EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_MIPS_REG_SP]); 311 } 312 313 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { 314 raw_context.context_flags = 315 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 316 // During stack scanning, if a potential return address 317 // is located within a loaded module that has symbols, 318 // it is only considered a valid return address if it 319 // lies within a function's bounds. 320 stack_section.start() = 0x80000000; 321 uint64_t return_address = 0x00500200; 322 Label frame1_sp; 323 stack_section 324 // frame 0 325 .Append(16, 0) // space 326 327 .D64(0x00490000) // junk that's not 328 .D64(0x00600000) // a return address 329 330 .D64(0x00401000) // a couple of plausible addresses 331 .D64(0x0050F000) // that are not within functions 332 333 .D64(frame1_sp) // stack pointer 334 .D64(return_address) // actual return address 335 // frame 1 336 .Mark(&frame1_sp) 337 .Append(64, 0); // end of stack 338 RegionFromSection(); 339 340 raw_context.epc = 0x00400200; 341 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); 342 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address; 343 344 SetModuleSymbols(&module1, 345 // The youngest frame's function. 346 "FUNC 100 400 10 monotreme\n"); 347 SetModuleSymbols(&module2, 348 // The calling frame's function. 349 "FUNC 100 400 10 marsupial\n"); 350 351 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 352 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 353 &frame_symbolizer); 354 vector<const CodeModule*> modules_without_symbols; 355 vector<const CodeModule*> modules_with_corrupt_symbols; 356 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 357 &modules_with_corrupt_symbols)); 358 ASSERT_EQ(0U, modules_without_symbols.size()); 359 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 360 frames = call_stack.frames(); 361 ASSERT_EQ(2U, frames->size()); 362 363 StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0)); 364 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 365 ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); 366 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 367 EXPECT_EQ("monotreme", frame0->function_name); 368 EXPECT_EQ(0x00400100U, frame0->function_base); 369 370 StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1)); 371 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 372 ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | 373 StackFrameMIPS::CONTEXT_VALID_SP | 374 StackFrameMIPS::CONTEXT_VALID_FP | 375 StackFrameMIPS::CONTEXT_VALID_RA), 376 frame1->context_validity); 377 EXPECT_EQ(return_address - 2 * sizeof(return_address), frame1->context.epc); 378 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); 379 EXPECT_EQ("marsupial", frame1->function_name); 380 EXPECT_EQ(0x00500100U, frame1->function_base); 381 } 382 383 TEST_F(GetCallerFrame, CheckStackFrameSizeLimit) { 384 raw_context.context_flags = 385 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 386 // If the stackwalker resorts to stack scanning, it will scan only 387 // 1024 bytes of stack which correspondes to maximum size of stack frame. 388 stack_section.start() = 0x80000000; 389 uint64_t return_address1 = 0x00500100; 390 uint64_t return_address2 = 0x00500900; 391 Label frame1_sp, frame2_sp; 392 stack_section 393 // frame 0 394 .Append(32, 0) // space 395 396 .D64(0x00490000) // junk that's not 397 .D64(0x00600000) // a return address 398 399 .Append(96, 0) // more space 400 401 .D64(frame1_sp) // stack pointer 402 .D64(return_address1) // actual return address 403 // frame 1 404 .Mark(&frame1_sp) 405 .Append(128 * 4, 0) // space 406 407 .D64(0x00F00000) // more junk 408 .D64(0x0000000D) 409 410 .Append(128 * 4, 0) // more space 411 412 .D64(frame2_sp) // stack pointer 413 .D64(return_address2) // actual return address 414 // (won't be found) 415 // frame 2 416 .Mark(&frame2_sp) 417 .Append(64, 0); // end of stack 418 RegionFromSection(); 419 420 raw_context.epc = 0x00405510; 421 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); 422 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; 423 424 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 425 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 426 &frame_symbolizer); 427 vector<const CodeModule*> modules_without_symbols; 428 vector<const CodeModule*> modules_with_corrupt_symbols; 429 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 430 &modules_with_corrupt_symbols)); 431 ASSERT_EQ(2U, modules_without_symbols.size()); 432 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 433 ASSERT_EQ("module2", modules_without_symbols[1]->debug_file()); 434 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 435 frames = call_stack.frames(); 436 ASSERT_EQ(2U, frames->size()); 437 438 StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0)); 439 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 440 ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); 441 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 442 443 StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1)); 444 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 445 ASSERT_EQ((StackFrameMIPS::CONTEXT_VALID_PC | 446 StackFrameMIPS::CONTEXT_VALID_SP | 447 StackFrameMIPS::CONTEXT_VALID_FP | 448 StackFrameMIPS::CONTEXT_VALID_RA), 449 frame1->context_validity); 450 EXPECT_EQ(return_address1 - 2 * sizeof(return_address1), frame1->context.epc); 451 EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); 452 } 453 454 // Test that set_max_frames_scanned prevents using stack scanning 455 // to find caller frames. 456 TEST_F(GetCallerFrame, ScanningNotAllowed) { 457 raw_context.context_flags = 458 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 459 // When the stack walker resorts to scanning the stack, 460 // only fixed number of frames are allowed to be scanned out from stack 461 stack_section.start() = 0x80000000; 462 uint64_t return_address1 = 0x00500100; 463 uint64_t return_address2 = 0x00500900; 464 Label frame1_sp, frame2_sp; 465 stack_section 466 // frame 0 467 .Append(32, 0) // space 468 469 .D64(0x00490000) // junk that's not 470 .D64(0x00600000) // a return address 471 472 .Append(96, 0) // more space 473 474 .D64(frame1_sp) // stack pointer 475 .D64(return_address1) // actual return address 476 // frame 1 477 .Mark(&frame1_sp) 478 .Append(128 * 4, 0) // space 479 480 .D64(0x00F00000) // more junk 481 .D64(0x0000000D) 482 483 .Append(128 * 4, 0) // more space 484 485 .D64(frame2_sp) // stack pointer 486 .D64(return_address2) // actual return address 487 // (won't be found) 488 // frame 2 489 .Mark(&frame2_sp) 490 .Append(64, 0); // end of stack 491 RegionFromSection(); 492 493 raw_context.epc = 0x00405510; 494 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); 495 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = return_address1; 496 497 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 498 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 499 &frame_symbolizer); 500 Stackwalker::set_max_frames_scanned(0); 501 502 vector<const CodeModule*> modules_without_symbols; 503 vector<const CodeModule*> modules_with_corrupt_symbols; 504 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 505 &modules_with_corrupt_symbols)); 506 ASSERT_EQ(1U, modules_without_symbols.size()); 507 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 508 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 509 frames = call_stack.frames(); 510 ASSERT_EQ(1U, frames->size()); 511 512 StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0)); 513 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 514 ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); 515 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 516 } 517 518 struct CFIFixture: public StackwalkerMIPSFixture { 519 CFIFixture() { 520 // Provide some STACK CFI records; 521 SetModuleSymbols(&module1, 522 // The youngest frame's function. 523 "FUNC 4000 1000 0 enchiridion\n" 524 // Initially, nothing has been pushed on the stack, 525 // and the return address is still in the $ra register. 526 "STACK CFI INIT 4000 1000 .cfa: $sp 0 + .ra: $ra\n" 527 // Move stack pointer. 528 "STACK CFI 4004 .cfa: $sp 32 +\n" 529 // store $fp and ra 530 "STACK CFI 4008 $fp: .cfa -8 + ^ .ra: .cfa -4 + ^\n" 531 // restore $fp 532 "STACK CFI 400c .cfa: $fp 32 +\n" 533 // restore $sp 534 "STACK CFI 4018 .cfa: $sp 32 +\n" 535 536 "STACK CFI 4020 $fp: $fp .cfa: $sp 0 + .ra: .ra\n" 537 538 // The calling function. 539 "FUNC 5000 1000 0 epictetus\n" 540 // Mark it as end of stack. 541 "STACK CFI INIT 5000 8 .cfa: $sp 0 + .ra: $ra\n" 542 543 // A function whose CFI makes the stack pointer 544 // go backwards. 545 "FUNC 6000 1000 20 palinal\n" 546 "STACK CFI INIT 6000 1000 .cfa: $sp 4 - .ra: $ra\n" 547 548 // A function with CFI expressions that can't be 549 // evaluated. 550 "FUNC 7000 1000 20 rhetorical\n" 551 "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n" 552 ); 553 554 // Provide some distinctive values for the caller's registers. 555 expected.epc = 0x00405500; 556 expected.iregs[MD_CONTEXT_MIPS_REG_S0] = 0x0; 557 expected.iregs[MD_CONTEXT_MIPS_REG_S1] = 0x1; 558 expected.iregs[MD_CONTEXT_MIPS_REG_S2] = 0x2; 559 expected.iregs[MD_CONTEXT_MIPS_REG_S3] = 0x3; 560 expected.iregs[MD_CONTEXT_MIPS_REG_S4] = 0x4; 561 expected.iregs[MD_CONTEXT_MIPS_REG_S5] = 0x5; 562 expected.iregs[MD_CONTEXT_MIPS_REG_S6] = 0x6; 563 expected.iregs[MD_CONTEXT_MIPS_REG_S7] = 0x7; 564 expected.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; 565 expected.iregs[MD_CONTEXT_MIPS_REG_FP] = 0x80000000; 566 expected.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; 567 568 // Expect CFI to recover all callee-save registers. Since CFI is the 569 // only stack frame construction technique we have, aside from the 570 // context frame itself, there's no way for us to have a set of valid 571 // registers smaller than this. 572 expected_validity = (StackFrameMIPS::CONTEXT_VALID_PC | 573 StackFrameMIPS::CONTEXT_VALID_S0 | 574 StackFrameMIPS::CONTEXT_VALID_S1 | 575 StackFrameMIPS::CONTEXT_VALID_S2 | 576 StackFrameMIPS::CONTEXT_VALID_S3 | 577 StackFrameMIPS::CONTEXT_VALID_S4 | 578 StackFrameMIPS::CONTEXT_VALID_S5 | 579 StackFrameMIPS::CONTEXT_VALID_S6 | 580 StackFrameMIPS::CONTEXT_VALID_S7 | 581 StackFrameMIPS::CONTEXT_VALID_SP | 582 StackFrameMIPS::CONTEXT_VALID_FP | 583 StackFrameMIPS::CONTEXT_VALID_GP | 584 StackFrameMIPS::CONTEXT_VALID_RA); 585 586 // By default, context frames provide all registers, as normal. 587 context_frame_validity = StackFrameMIPS::CONTEXT_VALID_ALL; 588 589 // By default, registers are unchanged. 590 raw_context = expected; 591 } 592 593 // Walk the stack, using stack_section as the contents of the stack 594 // and raw_context as the current register values. (Set the stack 595 // pointer to the stack's starting address.) Expect two stack 596 // frames; in the older frame, expect the callee-saves registers to 597 // have values matching those in 'expected'. 598 void CheckWalk() { 599 RegionFromSection(); 600 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = stack_section.start().Value(); 601 602 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 603 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, 604 &modules, &frame_symbolizer); 605 vector<const CodeModule*> modules_without_symbols; 606 vector<const CodeModule*> modules_with_corrupt_symbols; 607 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 608 &modules_with_corrupt_symbols)); 609 ASSERT_EQ(0U, modules_without_symbols.size()); 610 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 611 frames = call_stack.frames(); 612 ASSERT_EQ(2U, frames->size()); 613 614 StackFrameMIPS* frame0 = static_cast<StackFrameMIPS*>(frames->at(0)); 615 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 616 ASSERT_EQ(StackFrameMIPS::CONTEXT_VALID_ALL, frame0->context_validity); 617 EXPECT_EQ("enchiridion", frame0->function_name); 618 EXPECT_EQ(0x00404000U, frame0->function_base); 619 620 StackFrameMIPS* frame1 = static_cast<StackFrameMIPS*>(frames->at(1)); 621 EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 622 ASSERT_EQ(expected_validity, frame1->context_validity); 623 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S0], 624 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S0]); 625 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S1], 626 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S1]); 627 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S2], 628 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S2]); 629 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S3], 630 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S3]); 631 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S4], 632 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S4]); 633 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S5], 634 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S5]); 635 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S6], 636 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S6]); 637 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_S7], 638 frame1->context.iregs[MD_CONTEXT_MIPS_REG_S7]); 639 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_FP], 640 frame1->context.iregs[MD_CONTEXT_MIPS_REG_FP]); 641 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_RA], 642 frame1->context.iregs[MD_CONTEXT_MIPS_REG_RA]); 643 EXPECT_EQ(expected.iregs[MD_CONTEXT_MIPS_REG_SP], 644 frame1->context.iregs[MD_CONTEXT_MIPS_REG_SP]); 645 EXPECT_EQ(expected.epc, frame1->context.epc); 646 EXPECT_EQ(expected.epc, frame1->instruction); 647 EXPECT_EQ("epictetus", frame1->function_name); 648 EXPECT_EQ(0x00405000U, frame1->function_base); 649 } 650 651 // The values we expect to find for the caller's registers. Forcibly 652 // default-init it, since it's POD and not all bits are always overwritten by 653 // the constructor. 654 MDRawContextMIPS expected{}; 655 656 // The validity mask for expected. 657 int expected_validity; 658 659 // The validity mask to impose on the context frame. 660 int context_frame_validity; 661 }; 662 663 class CFI: public CFIFixture, public Test { }; 664 665 // TODO(gordanac): add CFI tests 666 667 TEST_F(CFI, At4004) { 668 raw_context.context_flags = 669 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 670 Label frame1_sp = expected.iregs[MD_CONTEXT_MIPS_REG_SP]; 671 stack_section 672 // frame0 673 .Append(16, 0) // space 674 .D64(frame1_sp) // stack pointer 675 .D64(0x00405510) // return address 676 .Mark(&frame1_sp); // This effectively sets stack_section.start(). 677 raw_context.epc = 0x00404004; 678 CheckWalk(); 679 } 680 681 // Check that we reject rules that would cause the stack pointer to 682 // move in the wrong direction. 683 TEST_F(CFI, RejectBackwards) { 684 raw_context.context_flags = 685 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 686 raw_context.epc = 0x40005000; 687 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; 688 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; 689 690 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 691 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 692 &frame_symbolizer); 693 vector<const CodeModule*> modules_without_symbols; 694 vector<const CodeModule*> modules_with_corrupt_symbols; 695 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 696 &modules_with_corrupt_symbols)); 697 ASSERT_EQ(0U, modules_without_symbols.size()); 698 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 699 frames = call_stack.frames(); 700 ASSERT_EQ(1U, frames->size()); 701 } 702 703 // Check that we reject rules whose expressions' evaluation fails. 704 TEST_F(CFI, RejectBadExpressions) { 705 raw_context.context_flags = 706 raw_context.context_flags | MD_CONTEXT_MIPS64_FULL; 707 raw_context.epc = 0x00407000; 708 raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; 709 raw_context.iregs[MD_CONTEXT_MIPS_REG_RA] = 0x00405510; 710 711 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 712 StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, 713 &frame_symbolizer); 714 vector<const CodeModule*> modules_without_symbols; 715 vector<const CodeModule*> modules_with_corrupt_symbols; 716 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 717 &modules_with_corrupt_symbols)); 718 ASSERT_EQ(0U, modules_without_symbols.size()); 719 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 720 frames = call_stack.frames(); 721 ASSERT_EQ(1U, frames->size()); 722 }