/ src / processor / stackwalker_riscv64_unittest.cc
stackwalker_riscv64_unittest.cc
  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:
 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.
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.
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.
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  
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.
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  
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  
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  
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.
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  
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 {
544    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'.
636    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  
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  
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.
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  
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  
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.
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.
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.
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.
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.
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  }