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