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