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