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