xref: /aosp_15_r20/external/google-breakpad/src/processor/stackwalker_riscv64_unittest.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
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 /* stackwalker_riscv64_unittest.cc: Unit tests for StackwalkerRISCV64 class.
30  *
31  * Author: Iacopo Colonnelli
32  */
33 
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>  // Must come first
36 #endif
37 
38 #include <string.h>
39 #include <string>
40 #include <vector>
41 
42 #include "breakpad_googletest_includes.h"
43 #include "common/test_assembler.h"
44 #include "common/using_std_string.h"
45 #include "google_breakpad/common/minidump_format.h"
46 #include "google_breakpad/processor/basic_source_line_resolver.h"
47 #include "google_breakpad/processor/call_stack.h"
48 #include "google_breakpad/processor/code_module.h"
49 #include "google_breakpad/processor/source_line_resolver_interface.h"
50 #include "google_breakpad/processor/stack_frame_cpu.h"
51 #include "processor/stackwalker_unittest_utils.h"
52 #include "processor/stackwalker_riscv64.h"
53 #include "processor/windows_frame_info.h"
54 
55 using google_breakpad::BasicSourceLineResolver;
56 using google_breakpad::CallStack;
57 using google_breakpad::CodeModule;
58 using google_breakpad::StackFrameSymbolizer;
59 using google_breakpad::StackFrame;
60 using google_breakpad::StackFrameRISCV64;
61 using google_breakpad::Stackwalker;
62 using google_breakpad::StackwalkerRISCV64;
63 using google_breakpad::SystemInfo;
64 using google_breakpad::WindowsFrameInfo;
65 using google_breakpad::test_assembler::kLittleEndian;
66 using google_breakpad::test_assembler::Label;
67 using google_breakpad::test_assembler::Section;
68 using std::vector;
69 using testing::_;
70 using testing::AnyNumber;
71 using testing::DoAll;
72 using testing::Return;
73 using testing::SetArgumentPointee;
74 using testing::Test;
75 
76 class StackwalkerRISCV64Fixture {
77 public:
StackwalkerRISCV64Fixture()78   StackwalkerRISCV64Fixture()
79       : stack_section(kLittleEndian),
80       // Give the two modules reasonable standard locations and names
81       // for tests to play with.
82         module1(0x40000000, 0x10000, "module1", "version1"),
83         module2(0x50000000, 0x10000, "module2", "version2") {
84     // Identify the system as an iOS system.
85     system_info.os = "iOS";
86     system_info.os_short = "ios";
87     system_info.cpu = "riscv64";
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(MDRawContextRISCV64 * raw_context)130   void BrandContext(MDRawContextRISCV64 *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   MDRawContextRISCV64 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 StackwalkerRISCV64Fixture, public Test { };
150 
TEST_F(SanityCheck,NoResolver)151 TEST_F(SanityCheck, NoResolver) {
152   // Since the context's frame pointer is garbage, the stack walk will end after
153   // the first frame.
154   StackFrameSymbolizer frame_symbolizer(NULL, NULL);
155   StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region, &modules,
156                             &frame_symbolizer);
157   // This should succeed even without a resolver or supplier.
158   vector<const CodeModule*> modules_without_symbols;
159   vector<const CodeModule*> modules_with_corrupt_symbols;
160   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
161               &modules_with_corrupt_symbols));
162   ASSERT_EQ(0U, modules_without_symbols.size());
163   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
164             frames = call_stack.frames();
165   ASSERT_EQ(1U, frames->size());
166   StackFrameRISCV64 *frame = static_cast<StackFrameRISCV64*>(frames->at(0));
167   // Check that the values from the original raw context made it
168   // through to the context in the stack frame.
169   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
170 }
171 
172 class GetContextFrame: public StackwalkerRISCV64Fixture, public Test { };
173 
174 // The stackwalker should be able to produce the context frame even
175 // without stack memory present.
TEST_F(GetContextFrame,NoStackMemory)176 TEST_F(GetContextFrame, NoStackMemory) {
177   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
178   StackwalkerRISCV64 walker(&system_info, &raw_context, NULL, &modules,
179                             &frame_symbolizer);
180   vector<const CodeModule*> modules_without_symbols;
181   vector<const CodeModule*> modules_with_corrupt_symbols;
182   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
183               &modules_with_corrupt_symbols));
184   ASSERT_EQ(0U, modules_without_symbols.size());
185   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
186             frames = call_stack.frames();
187   ASSERT_EQ(1U, frames->size());
188   StackFrameRISCV64 *frame = static_cast<StackFrameRISCV64*>(frames->at(0));
189   // Check that the values from the original raw context made it
190   // through to the context in the stack frame.
191   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
192 }
193 
194 class GetCallerFrame: public StackwalkerRISCV64Fixture, public Test { };
195 
TEST_F(GetCallerFrame,ScanWithoutSymbols)196 TEST_F(GetCallerFrame, ScanWithoutSymbols) {
197   // When the stack walker resorts to scanning the stack,
198   // only addresses located within loaded modules are
199   // considered valid return addresses.
200   // Force scanning through three frames to ensure that the
201   // stack pointer is set properly in scan-recovered frames.
202   stack_section.start() = 0x80000000;
203   uint64_t return_address1 = 0x50000100;
204   uint64_t return_address2 = 0x50000900;
205   Label frame1_sp, frame2_sp;
206   stack_section
207       // frame 0
208       .Append(16, 0)                      // space
209 
210       .D64(0x40090000)                    // junk that's not
211       .D64(0x60000000)                    // a return address
212 
213       .D64(return_address1)               // actual return address
214       // frame 1
215       .Mark(&frame1_sp)
216       .Append(16, 0)                      // space
217 
218       .D64(0xF0000000)                    // more junk
219       .D64(0x0000000D)
220 
221       .D64(return_address2)               // actual return address
222       // frame 2
223       .Mark(&frame2_sp)
224       .Append(64, 0);                     // end of stack
225   RegionFromSection();
226 
227   raw_context.pc = 0x40005510;
228   raw_context.sp = stack_section.start().Value();
229 
230   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
231   StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region, &modules,
232                             &frame_symbolizer);
233   vector<const CodeModule*> modules_without_symbols;
234   vector<const CodeModule*> modules_with_corrupt_symbols;
235   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
236               &modules_with_corrupt_symbols));
237   ASSERT_EQ(2U, modules_without_symbols.size());
238   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
239   ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
240   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
241             frames = call_stack.frames();
242   ASSERT_EQ(3U, frames->size());
243 
244   StackFrameRISCV64 *frame0 = static_cast<StackFrameRISCV64*>(frames->at(0));
245   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
246   ASSERT_EQ(StackFrameRISCV64::CONTEXT_VALID_ALL,
247             frame0->context_validity);
248   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
249 
250   StackFrameRISCV64 *frame1 = static_cast<StackFrameRISCV64*>(frames->at(1));
251   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
252   ASSERT_EQ((StackFrameRISCV64::CONTEXT_VALID_PC |
253              StackFrameRISCV64::CONTEXT_VALID_SP),
254              frame1->context_validity);
255   EXPECT_EQ(return_address1, frame1->context.pc);
256   EXPECT_EQ(frame1_sp.Value(), frame1->context.sp);
257 
258   StackFrameRISCV64 *frame2 = static_cast<StackFrameRISCV64*>(frames->at(2));
259   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust);
260   ASSERT_EQ((StackFrameRISCV64::CONTEXT_VALID_PC |
261              StackFrameRISCV64::CONTEXT_VALID_SP),
262              frame2->context_validity);
263   EXPECT_EQ(return_address2, frame2->context.pc);
264   EXPECT_EQ(frame2_sp.Value(), frame2->context.sp);
265 }
266 
TEST_F(GetCallerFrame,ScanWithFunctionSymbols)267 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
268   // During stack scanning, if a potential return address
269   // is located within a loaded module that has symbols,
270   // it is only considered a valid return address if it
271   // lies within a function's bounds.
272   stack_section.start() = 0x80000000;
273   uint64_t return_address = 0x50000200;
274   Label frame1_sp;
275 
276   stack_section
277       // frame 0
278       .Append(16, 0)                      // space
279 
280       .D64(0x40090000)                    // junk that's not
281       .D64(0x60000000)                    // a return address
282 
283       .D64(0x40001000)                    // a couple of plausible addresses
284       .D64(0x5000F000)                    // that are not within functions
285 
286       .D64(return_address)                // actual return address
287       // frame 1
288       .Mark(&frame1_sp)
289       .Append(64, 0);                     // end of stack
290   RegionFromSection();
291 
292   raw_context.pc = 0x40000200;
293   raw_context.sp = stack_section.start().Value();
294 
295   SetModuleSymbols(&module1,
296       // The youngest frame's function.
297       "FUNC 100 400 10 monotreme\n");
298   SetModuleSymbols(&module2,
299       // The calling frame's function.
300       "FUNC 100 400 10 marsupial\n");
301 
302   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
303   StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region,
304                             &modules, &frame_symbolizer);
305   vector<const CodeModule*> modules_without_symbols;
306   vector<const CodeModule*> modules_with_corrupt_symbols;
307   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
308               &modules_with_corrupt_symbols));
309   ASSERT_EQ(0U, modules_without_symbols.size());
310   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
311             frames = call_stack.frames();
312   ASSERT_EQ(2U, frames->size());
313 
314   StackFrameRISCV64 *frame0 = static_cast<StackFrameRISCV64*>(frames->at(0));
315   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
316   ASSERT_EQ(StackFrameRISCV64::CONTEXT_VALID_ALL,
317             frame0->context_validity);
318   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
319   EXPECT_EQ("monotreme", frame0->function_name);
320   EXPECT_EQ(0x40000100ULL, frame0->function_base);
321 
322   StackFrameRISCV64 *frame1 = static_cast<StackFrameRISCV64*>(frames->at(1));
323   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
324   ASSERT_EQ((StackFrameRISCV64::CONTEXT_VALID_PC |
325              StackFrameRISCV64::CONTEXT_VALID_SP),
326              frame1->context_validity);
327   EXPECT_EQ(return_address, frame1->context.pc);
328   EXPECT_EQ(frame1_sp.Value(), frame1->context.sp);
329   EXPECT_EQ("marsupial", frame1->function_name);
330   EXPECT_EQ(0x50000100ULL, frame1->function_base);
331 }
332 
TEST_F(GetCallerFrame,ScanFirstFrame)333 TEST_F(GetCallerFrame, ScanFirstFrame) {
334   // If the stackwalker resorts to stack scanning, it will scan much
335   // farther to find the caller of the context frame.
336   stack_section.start() = 0x80000000;
337   uint64_t return_address1 = 0x50000100;
338   uint64_t return_address2 = 0x50000900;
339   Label frame1_sp, frame2_sp;
340   stack_section
341       // frame 0
342       .Append(32, 0)                      // space
343 
344       .D64(0x40090000)                    // junk that's not
345       .D64(0x60000000)                    // a return address
346 
347       .Append(96, 0)                      // more space
348 
349       .D64(return_address1)               // actual return address
350       // frame 1
351       .Mark(&frame1_sp)
352       .Append(32, 0)                      // space
353 
354       .D64(0xF0000000)                    // more junk
355       .D64(0x0000000D)
356 
357       .Append(336, 0)                     // more space
358 
359       .D64(return_address2)               // actual return address
360       // (won't be found)
361       // frame 2
362       .Mark(&frame2_sp)
363       .Append(64, 0);                     // end of stack
364   RegionFromSection();
365 
366   raw_context.pc = 0x40005510;
367   raw_context.sp = stack_section.start().Value();
368 
369   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
370   StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region,
371                             &modules, &frame_symbolizer);
372   vector<const CodeModule*> modules_without_symbols;
373   vector<const CodeModule*> modules_with_corrupt_symbols;
374   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
375               &modules_with_corrupt_symbols));
376   ASSERT_EQ(2U, modules_without_symbols.size());
377   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
378   ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
379   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
380             frames = call_stack.frames();
381   ASSERT_EQ(2U, frames->size());
382 
383   StackFrameRISCV64 *frame0 = static_cast<StackFrameRISCV64*>(frames->at(0));
384   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
385   ASSERT_EQ(StackFrameRISCV64::CONTEXT_VALID_ALL,
386             frame0->context_validity);
387   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
388 
389   StackFrameRISCV64 *frame1 = static_cast<StackFrameRISCV64*>(frames->at(1));
390   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
391   ASSERT_EQ((StackFrameRISCV64::CONTEXT_VALID_PC |
392              StackFrameRISCV64::CONTEXT_VALID_SP),
393              frame1->context_validity);
394   EXPECT_EQ(return_address1, frame1->context.pc);
395   EXPECT_EQ(frame1_sp.Value(), frame1->context.sp);
396 }
397 
398 // Test that set_max_frames_scanned prevents using stack scanning
399 // to find caller frames.
TEST_F(GetCallerFrame,ScanningNotAllowed)400 TEST_F(GetCallerFrame, ScanningNotAllowed) {
401   // When the stack walker resorts to scanning the stack,
402   // only addresses located within loaded modules are
403   // considered valid return addresses.
404   stack_section.start() = 0x80000000;
405   uint64_t return_address1 = 0x50000100;
406   uint64_t return_address2 = 0x50000900;
407   Label frame1_sp, frame2_sp;
408   stack_section
409       // frame 0
410       .Append(16, 0)                      // space
411 
412       .D64(0x40090000)                    // junk that's not
413       .D64(0x60000000)                    // a return address
414 
415       .D64(return_address1)               // actual return address
416       // frame 1
417       .Mark(&frame1_sp)
418       .Append(16, 0)                      // space
419 
420       .D64(0xF0000000)                    // more junk
421       .D64(0x0000000D)
422 
423       .D64(return_address2)               // actual return address
424       // frame 2
425       .Mark(&frame2_sp)
426       .Append(64, 0);                     // end of stack
427   RegionFromSection();
428 
429   raw_context.pc = 0x40005510;
430   raw_context.sp = stack_section.start().Value();
431 
432   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
433   StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region,
434                             &modules, &frame_symbolizer);
435   Stackwalker::set_max_frames_scanned(0);
436 
437   vector<const CodeModule*> modules_without_symbols;
438   vector<const CodeModule*> modules_with_corrupt_symbols;
439   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
440               &modules_with_corrupt_symbols));
441   ASSERT_EQ(1U, modules_without_symbols.size());
442   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
443   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
444             frames = call_stack.frames();
445   ASSERT_EQ(1U, frames->size());
446 
447   StackFrameRISCV64 *frame0 = static_cast<StackFrameRISCV64*>(frames->at(0));
448   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
449   ASSERT_EQ(StackFrameRISCV64::CONTEXT_VALID_ALL,
450             frame0->context_validity);
451   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
452 }
453 
454 class GetFramesByFramePointer:
455     public StackwalkerRISCV64Fixture,
456     public Test { };
457 
TEST_F(GetFramesByFramePointer,OnlyFramePointer)458 TEST_F(GetFramesByFramePointer, OnlyFramePointer) {
459   stack_section.start() = 0x80000000;
460   uint64_t return_address1 = 0x50000100;
461   uint64_t return_address2 = 0x50000900;
462   Label frame1_sp, frame2_sp;
463   Label frame1_fp, frame2_fp;
464   stack_section
465       // frame 0
466       .Append(64, 0)           // Whatever values on the stack.
467       .D64(0x0000000D)         // junk that's not
468       .D64(0xF0000000)         // a return address.
469 
470       .Mark(&frame1_fp)        // Next fp will point to the next value.
471       .D64(frame2_fp)          // Save current frame pointer.
472       .D64(return_address2)    // Save current link register.
473       .Mark(&frame1_sp)
474 
475       // frame 1
476       .Append(64, 0)           // Whatever values on the stack.
477       .D64(0x0000000D)         // junk that's not
478       .D64(0xF0000000)         // a return address.
479 
480       .Mark(&frame2_fp)
481       .D64(0)
482       .D64(0)
483       .Mark(&frame2_sp)
484 
485       // frame 2
486       .Append(64, 0)           // Whatever values on the stack.
487       .D64(0x0000000D)         // junk that's not
488       .D64(0xF0000000);        // a return address.
489   RegionFromSection();
490 
491 
492   raw_context.pc = 0x40005510;
493   raw_context.ra = return_address1;
494   raw_context.s0 = frame1_fp.Value();
495   raw_context.sp = stack_section.start().Value();
496 
497   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
498   StackwalkerRISCV64 walker(&system_info, &raw_context,
499                             &stack_region, &modules, &frame_symbolizer);
500 
501   vector<const CodeModule*> modules_without_symbols;
502   vector<const CodeModule*> modules_with_corrupt_symbols;
503   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
504               &modules_with_corrupt_symbols));
505   ASSERT_EQ(2U, modules_without_symbols.size());
506   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
507   ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
508   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
509             frames = call_stack.frames();
510   ASSERT_EQ(3U, frames->size());
511 
512   StackFrameRISCV64 *frame0 = static_cast<StackFrameRISCV64*>(frames->at(0));
513   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
514   ASSERT_EQ(StackFrameRISCV64::CONTEXT_VALID_ALL,
515             frame0->context_validity);
516   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
517 
518   StackFrameRISCV64 *frame1 = static_cast<StackFrameRISCV64*>(frames->at(1));
519   EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
520   ASSERT_EQ((StackFrameRISCV64::CONTEXT_VALID_PC |
521              StackFrameRISCV64::CONTEXT_VALID_RA |
522              StackFrameRISCV64::CONTEXT_VALID_S0 |
523              StackFrameRISCV64::CONTEXT_VALID_SP),
524              frame1->context_validity);
525   EXPECT_EQ(return_address1, frame1->context.pc);
526   EXPECT_EQ(return_address2, frame1->context.ra);
527   EXPECT_EQ(frame1_sp.Value(), frame1->context.sp);
528   EXPECT_EQ(frame2_fp.Value(), frame1->context.s0);
529 
530   StackFrameRISCV64 *frame2 = static_cast<StackFrameRISCV64*>(frames->at(2));
531   EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust);
532   ASSERT_EQ((StackFrameRISCV64::CONTEXT_VALID_PC |
533              StackFrameRISCV64::CONTEXT_VALID_RA |
534              StackFrameRISCV64::CONTEXT_VALID_S0 |
535              StackFrameRISCV64::CONTEXT_VALID_SP),
536              frame2->context_validity);
537   EXPECT_EQ(return_address2, frame2->context.pc);
538   EXPECT_EQ(0U, frame2->context.ra);
539   EXPECT_EQ(frame2_sp.Value(), frame2->context.sp);
540   EXPECT_EQ(0U, frame2->context.s0);
541 }
542 
543 struct CFIFixture: public StackwalkerRISCV64Fixture {
CFIFixtureCFIFixture544   CFIFixture() {
545     // Provide a bunch of STACK CFI records; we'll walk to the caller
546     // from every point in this series, expecting to find the same set
547     // of register values.
548     SetModuleSymbols(&module1,
549         // The youngest frame's function.
550                      "FUNC 4000 1000 10 enchiridion\n"
551                      // Initially, nothing has been pushed on the stack,
552                      // and the return address is still in the return
553                      // address register (ra).
554                      "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: ra\n"
555                      // Push s1, s2, the frame pointer (s0) and the
556                      // return address register.
557                      "STACK CFI 4001 .cfa: sp 32 + .ra: .cfa -8 + ^"
558                      " s1: .cfa -32 + ^ s2: .cfa -24 + ^ "
559                      " s0: .cfa -16 + ^\n"
560                      // Save s1..s4 in a1..a4: verify that we populate
561                      // the youngest frame with all the values we have.
562                      "STACK CFI 4002 s1: a1 s2: a2 s3: a3 s4: a4\n"
563                      // Restore s1..s4. Save the non-callee-saves register a2.
564                      "STACK CFI 4003 .cfa: sp 40 + a2: .cfa 40 - ^"
565                      " s1: s1 s2: s2 s3: s3 s4: s4\n"
566                      // Move the .cfa back eight bytes, to point at the return
567                      // address, and restore the sp explicitly.
568                      "STACK CFI 4005 .cfa: sp 32 + a2: .cfa 32 - ^"
569                      " s0: .cfa 8 - ^ .ra: .cfa ^ sp: .cfa 8 +\n"
570                      // Recover the PC explicitly from a new stack slot;
571                      // provide garbage for the .ra.
572                      "STACK CFI 4006 .cfa: sp 40 + pc: .cfa 40 - ^\n"
573 
574                      // The calling function.
575                      "FUNC 5000 1000 10 epictetus\n"
576                      // Mark it as end of stack.
577                      "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n"
578 
579                      // A function whose CFI makes the stack pointer
580                      // go backwards.
581                      "FUNC 6000 1000 20 palinal\n"
582                      "STACK CFI INIT 6000 1000 .cfa: sp 8 - .ra: ra\n"
583 
584                      // A function with CFI expressions that can't be
585                      // evaluated.
586                      "FUNC 7000 1000 20 rhetorical\n"
587                      "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n");
588 
589     // Provide some distinctive values for the caller's registers.
590     expected.pc  = 0x0000000040005510L;
591     expected.sp  = 0x0000000080000000L;
592     expected.s1  = 0x5e68b5d5b5d55e68L;
593     expected.s2  = 0x34f3ebd1ebd134f3L;
594     expected.s3  = 0x74bca31ea31e74bcL;
595     expected.s4  = 0x16b32dcb2dcb16b3L;
596     expected.s5  = 0x21372ada2ada2137L;
597     expected.s6  = 0x557dbbbbbbbb557dL;
598     expected.s7  = 0x8ca748bf48bf8ca7L;
599     expected.s8  = 0x21f0ab46ab4621f0L;
600     expected.s9  = 0x146732b732b71467L;
601     expected.s10 = 0xa673645fa673645fL;
602     expected.s11 = 0xa673645fa673645fL;
603     expected.s0  = 0xe11081128112e110L;
604 
605     // Expect CFI to recover all callee-saves registers. Since CFI is the
606     // only stack frame construction technique we have, aside from the
607     // context frame itself, there's no way for us to have a set of valid
608     // registers smaller than this.
609     expected_validity = (StackFrameRISCV64::CONTEXT_VALID_PC  |
610                          StackFrameRISCV64::CONTEXT_VALID_SP  |
611                          StackFrameRISCV64::CONTEXT_VALID_S1  |
612                          StackFrameRISCV64::CONTEXT_VALID_S2  |
613                          StackFrameRISCV64::CONTEXT_VALID_S3  |
614                          StackFrameRISCV64::CONTEXT_VALID_S4  |
615                          StackFrameRISCV64::CONTEXT_VALID_S5  |
616                          StackFrameRISCV64::CONTEXT_VALID_S6  |
617                          StackFrameRISCV64::CONTEXT_VALID_S7  |
618                          StackFrameRISCV64::CONTEXT_VALID_S8  |
619                          StackFrameRISCV64::CONTEXT_VALID_S9  |
620                          StackFrameRISCV64::CONTEXT_VALID_S10 |
621                          StackFrameRISCV64::CONTEXT_VALID_S11 |
622                          StackFrameRISCV64::CONTEXT_VALID_S0);
623 
624     // By default, context frames provide all registers, as normal.
625     context_frame_validity = StackFrameRISCV64::CONTEXT_VALID_ALL;
626 
627     // By default, registers are unchanged.
628     raw_context = expected;
629   }
630 
631   // Walk the stack, using stack_section as the contents of the stack
632   // and raw_context as the current register values. (Set the stack
633   // pointer to the stack's starting address.) Expect two stack
634   // frames; in the older frame, expect the callee-saves registers to
635   // have values matching those in 'expected'.
CheckWalkCFIFixture636   void CheckWalk() {
637     RegionFromSection();
638     raw_context.sp = stack_section.start().Value();
639 
640     StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
641     StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region,
642                               &modules, &frame_symbolizer);
643     walker.SetContextFrameValidity(context_frame_validity);
644     vector<const CodeModule*> modules_without_symbols;
645     vector<const CodeModule*> modules_with_corrupt_symbols;
646     ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
647                             &modules_with_corrupt_symbols));
648     ASSERT_EQ(0U, modules_without_symbols.size());
649     ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
650     frames = call_stack.frames();
651     ASSERT_EQ(2U, frames->size());
652 
653     StackFrameRISCV64 *frame0 = static_cast<StackFrameRISCV64*>(frames->at(0));
654     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
655     ASSERT_EQ(context_frame_validity, frame0->context_validity);
656     EXPECT_EQ("enchiridion", frame0->function_name);
657     EXPECT_EQ(0x0000000040004000UL, frame0->function_base);
658 
659     StackFrameRISCV64 *frame1 = static_cast<StackFrameRISCV64*>(frames->at(1));
660     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
661     ASSERT_EQ(expected_validity, frame1->context_validity);
662     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_A2)
663       EXPECT_EQ(expected.a2, frame1->context.a2);
664     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S1)
665       EXPECT_EQ(expected.s1, frame1->context.s1);
666     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S2)
667       EXPECT_EQ(expected.s2, frame1->context.s2);
668     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S3)
669       EXPECT_EQ(expected.s3, frame1->context.s3);
670     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S4)
671       EXPECT_EQ(expected.s4, frame1->context.s4);
672     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S5)
673       EXPECT_EQ(expected.s5, frame1->context.s5);
674     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S6)
675       EXPECT_EQ(expected.s6, frame1->context.s6);
676     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S7)
677       EXPECT_EQ(expected.s7, frame1->context.s7);
678     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S8)
679       EXPECT_EQ(expected.s8, frame1->context.s8);
680     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S9)
681       EXPECT_EQ(expected.s9, frame1->context.s9);
682     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S10)
683       EXPECT_EQ(expected.s10, frame1->context.s10);
684     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S11)
685       EXPECT_EQ(expected.s11, frame1->context.s11);
686     if (expected_validity & StackFrameRISCV64::CONTEXT_VALID_S0)
687       EXPECT_EQ(expected.s0, frame1->context.s0);
688 
689     // We would never have gotten a frame in the first place if the SP
690     // and PC weren't valid or ->instruction weren't set.
691     EXPECT_EQ(expected.sp, frame1->context.sp);
692     EXPECT_EQ(expected.pc, frame1->context.pc);
693     EXPECT_EQ(expected.pc, frame1->instruction + 4);
694     EXPECT_EQ("epictetus", frame1->function_name);
695   }
696 
697   // The values we expect to find for the caller's registers.
698   MDRawContextRISCV64 expected;
699 
700   // The validity mask for expected.
701   int expected_validity;
702 
703   // The validity mask to impose on the context frame.
704   int context_frame_validity;
705 };
706 
707 class CFI: public CFIFixture, public Test { };
708 
TEST_F(CFI,At4000)709 TEST_F(CFI, At4000) {
710   stack_section.start() = expected.sp;
711   raw_context.pc = 0x0000000040004000L;
712   raw_context.ra = 0x0000000040005510L;
713   CheckWalk();
714 }
715 
TEST_F(CFI,At4001)716 TEST_F(CFI, At4001) {
717   Label frame1_sp = expected.sp;
718   stack_section
719       .D64(0x5e68b5d5b5d55e68L) // saved s1
720       .D64(0x34f3ebd1ebd134f3L) // saved s2
721       .D64(0xe11081128112e110L) // saved s0
722       .D64(0x0000000040005510L) // return address
723       .Mark(&frame1_sp);        // This effectively sets stack_section.start().
724   raw_context.pc = 0x0000000040004001L;
725   // distinct callee s1, s2 and s0
726   raw_context.s1 = 0xadc9f635a635adc9L;
727   raw_context.s2 = 0x623135ac35ac6231L;
728   raw_context.s0 = 0x5fc4be14be145fc4L;
729   CheckWalk();
730 }
731 
732 // As above, but unwind from a context that has only the PC and SP.
TEST_F(CFI,At4001LimitedValidity)733 TEST_F(CFI, At4001LimitedValidity) {
734   Label frame1_sp = expected.sp;
735   stack_section
736       .D64(0x5e68b5d5b5d55e68L) // saved s1
737       .D64(0x34f3ebd1ebd134f3L) // saved s2
738       .D64(0xe11081128112e110L) // saved s0
739       .D64(0x0000000040005510L) // return address
740       .Mark(&frame1_sp);        // This effectively sets stack_section.start().
741   context_frame_validity = StackFrameRISCV64::CONTEXT_VALID_PC |
742                            StackFrameRISCV64::CONTEXT_VALID_SP;
743   raw_context.pc = 0x0000000040004001L;
744   raw_context.s0 = 0x5fc4be14be145fc4L;
745 
746   expected_validity = (StackFrameRISCV64::CONTEXT_VALID_PC |
747                        StackFrameRISCV64::CONTEXT_VALID_SP |
748                        StackFrameRISCV64::CONTEXT_VALID_S0 |
749                        StackFrameRISCV64::CONTEXT_VALID_S1 |
750                        StackFrameRISCV64::CONTEXT_VALID_S2);
751   CheckWalk();
752 }
753 
TEST_F(CFI,At4002)754 TEST_F(CFI, At4002) {
755   Label frame1_sp = expected.sp;
756   stack_section
757       .D64(0xff3dfb81fb81ff3dL) // no longer saved s1
758       .D64(0x34f3ebd1ebd134f3L) // no longer saved s2
759       .D64(0xe11081128112e110L) // saved s0
760       .D64(0x0000000040005510L) // return address
761       .Mark(&frame1_sp);        // This effectively sets stack_section.start().
762   raw_context.pc = 0x0000000040004002L;
763   raw_context.a1 = 0x5e68b5d5b5d55e68L;  // saved s1
764   raw_context.a2 = 0x34f3ebd1ebd134f3L;  // saved s2
765   raw_context.a3 = 0x74bca31ea31e74bcL;  // saved s3
766   raw_context.a4 = 0x16b32dcb2dcb16b3L;  // saved s4
767   raw_context.s1 = 0xadc9f635a635adc9L;  // distinct callee s1
768   raw_context.s2 = 0x623135ac35ac6231L;  // distinct callee s2
769   raw_context.s3 = 0xac4543564356ac45L;  // distinct callee s3
770   raw_context.s4 = 0x2561562f562f2561L;  // distinct callee s4
771   // distinct callee s0
772   raw_context.s0 = 0x5fc4be14be145fc4L;
773   CheckWalk();
774 }
775 
TEST_F(CFI,At4003)776 TEST_F(CFI, At4003) {
777   Label frame1_sp = expected.sp;
778   stack_section
779       .D64(0xdd5a48c848c8dd5aL) // saved a2 (even though it's not callee-saves)
780       .D64(0xff3dfb81fb81ff3dL) // no longer saved s1
781       .D64(0x34f3ebd1ebd134f3L) // no longer saved s2
782       .D64(0xe11081128112e110L) // saved s0
783       .D64(0x0000000040005510L) // return address
784       .Mark(&frame1_sp);        // This effectively sets stack_section.start().
785   raw_context.pc = 0x0000000040004003L;
786   // distinct callee a2 and fp
787   raw_context.a2 = 0xfb756319fb756319L;
788   raw_context.s0 = 0x5fc4be14be145fc4L;
789   // caller's a2
790   expected.a2 = 0xdd5a48c848c8dd5aL;
791   expected_validity |= StackFrameRISCV64::CONTEXT_VALID_A2;
792   CheckWalk();
793 }
794 
795 // We have no new rule at module offset 0x4004, so the results here should
796 // be the same as those at module offset 0x4003.
TEST_F(CFI,At4004)797 TEST_F(CFI, At4004) {
798   Label frame1_sp = expected.sp;
799   stack_section
800       .D64(0xdd5a48c848c8dd5aL) // saved a2 (even though it's not callee-saves)
801       .D64(0xff3dfb81fb81ff3dL) // no longer saved s1
802       .D64(0x34f3ebd1ebd134f3L) // no longer saved s2
803       .D64(0xe11081128112e110L) // saved s0
804       .D64(0x0000000040005510L) // return address
805       .Mark(&frame1_sp);        // This effectively sets stack_section.start().
806   raw_context.pc = 0x0000000040004004L;
807   // distinct callee a2 and s0
808   raw_context.a2 = 0xfb756319fb756319L;
809   raw_context.s0 = 0x5fc4be14be145fc4L;
810   // caller's a2
811   expected.a2 = 0xdd5a48c848c8dd5aL;
812   expected_validity |= StackFrameRISCV64::CONTEXT_VALID_A2;
813   CheckWalk();
814 }
815 
816 // Here we move the .cfa, but provide an explicit rule to recover the SP,
817 // so again there should be no change in the registers recovered.
TEST_F(CFI,At4005)818 TEST_F(CFI, At4005) {
819   Label frame1_sp = expected.sp;
820   stack_section
821       .D64(0xdd5a48c848c8dd5aL) // saved a2 (even though it's not callee-saves)
822       .D64(0xff3dfb81fb81ff3dL) // no longer saved s1
823       .D64(0x34f3ebd1ebd134f3L) // no longer saved s2
824       .D64(0xe11081128112e110L) // saved s0
825       .D64(0x0000000040005510L) // return address
826       .Mark(&frame1_sp);        // This effectively sets stack_section.start().
827   raw_context.pc = 0x0000000040004005L;
828   raw_context.a2 = 0xfb756319fb756319L;  // distinct callee a2
829   expected.a2 = 0xdd5a48c848c8dd5aL;     // caller's a2
830   expected_validity |= StackFrameRISCV64::CONTEXT_VALID_A2;
831   CheckWalk();
832 }
833 
834 // Here we provide an explicit rule for the PC, and have the saved .ra be
835 // bogus.
TEST_F(CFI,At4006)836 TEST_F(CFI, At4006) {
837   Label frame1_sp = expected.sp;
838   stack_section
839       .D64(0x0000000040005510L) // saved pc
840       .D64(0xdd5a48c848c8dd5aL) // saved a2 (even though it's not callee-saves)
841       .D64(0xff3dfb81fb81ff3dL) // no longer saved s1
842       .D64(0x34f3ebd1ebd134f3L) // no longer saved s2
843       .D64(0xe11081128112e110L) // saved s0
844       .D64(0xf8d157835783f8d1L) // .ra rule recovers this, which is garbage
845       .Mark(&frame1_sp);        // This effectively sets stack_section.start().
846   raw_context.pc = 0x0000000040004006L;
847   raw_context.a2 = 0xfb756319fb756319L;  // distinct callee a2
848   expected.a2 = 0xdd5a48c848c8dd5aL;     // caller's a2
849   expected_validity |= StackFrameRISCV64::CONTEXT_VALID_A2;
850   CheckWalk();
851 }
852 
853 // Check that we reject rules that would cause the stack pointer to
854 // move in the wrong direction.
TEST_F(CFI,RejectBackwards)855 TEST_F(CFI, RejectBackwards) {
856   raw_context.pc = 0x0000000040006000L;
857   raw_context.sp = 0x0000000080000000L;
858   raw_context.ra = 0x0000000040005510L;
859   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
860   StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region,
861                             &modules, &frame_symbolizer);
862   vector<const CodeModule*> modules_without_symbols;
863   vector<const CodeModule*> modules_with_corrupt_symbols;
864   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
865               &modules_with_corrupt_symbols));
866   ASSERT_EQ(0U, modules_without_symbols.size());
867   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
868             frames = call_stack.frames();
869   ASSERT_EQ(1U, frames->size());
870 }
871 
872 // Check that we reject rules whose expressions' evaluation fails.
TEST_F(CFI,RejectBadExpressions)873 TEST_F(CFI, RejectBadExpressions) {
874   raw_context.pc = 0x0000000040007000L;
875   raw_context.sp = 0x0000000080000000L;
876   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
877   StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region,
878                             &modules, &frame_symbolizer);
879   vector<const CodeModule*> modules_without_symbols;
880   vector<const CodeModule*> modules_with_corrupt_symbols;
881   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
882               &modules_with_corrupt_symbols));
883   ASSERT_EQ(0U, modules_without_symbols.size());
884   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
885             frames = call_stack.frames();
886   ASSERT_EQ(1U, frames->size());
887 }
888