Home | History | Annotate | Download | only in processor
      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