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