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