/ src / processor / stackwalker_arm_unittest.cc
stackwalker_arm_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_arm_unittest.cc: Unit tests for StackwalkerARM 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_arm.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::StackFrameARM;
 60  using google_breakpad::Stackwalker;
 61  using google_breakpad::StackwalkerARM;
 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 StackwalkerARMFixture {
 76   public:
 77    StackwalkerARMFixture()
 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 a Linux system.
 84      system_info.os = "Linux";
 85      system_info.os_short = "linux";
 86      system_info.os_version = "Lugubrious Labrador";
 87      system_info.cpu = "arm";
 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(MDRawContextARM *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    MDRawContextARM 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 StackwalkerARMFixture, public Test { };
150  
151  TEST_F(SanityCheck, NoResolver) {
152    // Since we have no call frame information, and all unwinding
153    // requires call frame information, the stack walk will end after
154    // the first frame.
155    StackFrameSymbolizer frame_symbolizer(NULL, NULL);
156    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
157                          &frame_symbolizer);
158    // This should succeed even without a resolver or supplier.
159    vector<const CodeModule*> modules_without_symbols;
160    vector<const CodeModule*> modules_with_corrupt_symbols;
161    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
162                            &modules_with_corrupt_symbols));
163    ASSERT_EQ(0U, modules_without_symbols.size());
164    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
165    frames = call_stack.frames();
166    ASSERT_EQ(1U, frames->size());
167    StackFrameARM *frame = static_cast<StackFrameARM*>(frames->at(0));
168    // Check that the values from the original raw context made it
169    // through to the context in the stack frame.
170    EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
171  }
172  
173  class GetContextFrame: public StackwalkerARMFixture, public Test { };
174  
175  TEST_F(GetContextFrame, Simple) {
176    // Since we have no call frame information, and all unwinding
177    // requires call frame information, the stack walk will end after
178    // the first frame.
179    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
180    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
181                          &frame_symbolizer);
182    vector<const CodeModule*> modules_without_symbols;
183    vector<const CodeModule*> modules_with_corrupt_symbols;
184    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
185                            &modules_with_corrupt_symbols));
186    ASSERT_EQ(0U, modules_without_symbols.size());
187    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
188    frames = call_stack.frames();
189    ASSERT_EQ(1U, frames->size());
190    StackFrameARM *frame = static_cast<StackFrameARM*>(frames->at(0));
191    // Check that the values from the original raw context made it
192    // through to the context in the stack frame.
193    EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
194  }
195  
196  // The stackwalker should be able to produce the context frame even
197  // without stack memory present.
198  TEST_F(GetContextFrame, NoStackMemory) {
199    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
200    StackwalkerARM walker(&system_info, &raw_context, -1, NULL, &modules,
201                          &frame_symbolizer);
202    vector<const CodeModule*> modules_without_symbols;
203    vector<const CodeModule*> modules_with_corrupt_symbols;
204    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
205                            &modules_with_corrupt_symbols));
206    ASSERT_EQ(0U, modules_without_symbols.size());
207    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
208    frames = call_stack.frames();
209    ASSERT_EQ(1U, frames->size());
210    StackFrameARM *frame = static_cast<StackFrameARM*>(frames->at(0));
211    // Check that the values from the original raw context made it
212    // through to the context in the stack frame.
213    EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
214  }
215  
216  class GetCallerFrame: public StackwalkerARMFixture, public Test { };
217  
218  TEST_F(GetCallerFrame, ScanWithoutSymbols) {
219    // When the stack walker resorts to scanning the stack,
220    // only addresses located within loaded modules are
221    // considered valid return addresses.
222    // Force scanning through three frames to ensure that the
223    // stack pointer is set properly in scan-recovered frames.
224    stack_section.start() = 0x80000000;
225    uint32_t return_address1 = 0x50000100;
226    uint32_t return_address2 = 0x50000900;
227    Label frame1_sp, frame2_sp;
228    stack_section
229      // frame 0
230      .Append(16, 0)                      // space
231  
232      .D32(0x40090000)                    // junk that's not
233      .D32(0x60000000)                    // a return address
234  
235      .D32(return_address1)               // actual return address
236      // frame 1
237      .Mark(&frame1_sp)
238      .Append(16, 0)                      // space
239  
240      .D32(0xF0000000)                    // more junk
241      .D32(0x0000000D)
242  
243      .D32(return_address2)               // actual return address
244      // frame 2
245      .Mark(&frame2_sp)
246      .Append(32, 0);                     // end of stack
247    RegionFromSection();
248  
249    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
250    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
251  
252    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
253    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
254                          &frame_symbolizer);
255    vector<const CodeModule*> modules_without_symbols;
256    vector<const CodeModule*> modules_with_corrupt_symbols;
257    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
258                            &modules_with_corrupt_symbols));
259    ASSERT_EQ(2U, modules_without_symbols.size());
260    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
261    ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
262    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
263    frames = call_stack.frames();
264    ASSERT_EQ(3U, frames->size());
265  
266    StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0));
267    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
268    ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
269    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
270  
271    StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1));
272    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
273    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
274               StackFrameARM::CONTEXT_VALID_SP),
275              frame1->context_validity);
276    EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
277    EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
278  
279    StackFrameARM *frame2 = static_cast<StackFrameARM*>(frames->at(2));
280    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust);
281    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
282               StackFrameARM::CONTEXT_VALID_SP),
283              frame2->context_validity);
284    EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
285    EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
286  }
287  
288  TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
289    // During stack scanning, if a potential return address
290    // is located within a loaded module that has symbols,
291    // it is only considered a valid return address if it
292    // lies within a function's bounds.
293    stack_section.start() = 0x80000000;
294    uint32_t return_address = 0x50000200;
295    Label frame1_sp;
296  
297    stack_section
298      // frame 0
299      .Append(16, 0)                      // space
300  
301      .D32(0x40090000)                    // junk that's not
302      .D32(0x60000000)                    // a return address
303  
304      .D32(0x40001000)                    // a couple of plausible addresses
305      .D32(0x5000F000)                    // that are not within functions
306  
307      .D32(return_address)                // actual return address
308      // frame 1
309      .Mark(&frame1_sp)
310      .Append(32, 0);                     // end of stack
311    RegionFromSection();
312  
313    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40000200;
314    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
315  
316    SetModuleSymbols(&module1,
317                     // The youngest frame's function.
318                     "FUNC 100 400 10 monotreme\n");
319    SetModuleSymbols(&module2,
320                     // The calling frame's function.
321                     "FUNC 100 400 10 marsupial\n");
322  
323    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
324    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
325                          &frame_symbolizer);
326    vector<const CodeModule*> modules_without_symbols;
327    vector<const CodeModule*> modules_with_corrupt_symbols;
328    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
329                            &modules_with_corrupt_symbols));
330    ASSERT_EQ(0U, modules_without_symbols.size());
331    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
332    frames = call_stack.frames();
333    ASSERT_EQ(2U, frames->size());
334  
335    StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0));
336    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
337    ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
338    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
339    EXPECT_EQ("monotreme", frame0->function_name);
340    EXPECT_EQ(0x40000100U, frame0->function_base);
341  
342    StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1));
343    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
344    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
345               StackFrameARM::CONTEXT_VALID_SP),
346              frame1->context_validity);
347    EXPECT_EQ(return_address, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
348    EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
349    EXPECT_EQ("marsupial", frame1->function_name);
350    EXPECT_EQ(0x50000100U, frame1->function_base);
351  }
352  
353  TEST_F(GetCallerFrame, ScanFirstFrame) {
354    // If the stackwalker resorts to stack scanning, it will scan much
355    // farther to find the caller of the context frame.
356    stack_section.start() = 0x80000000;
357    uint32_t return_address1 = 0x50000100;
358    uint32_t return_address2 = 0x50000900;
359    Label frame1_sp, frame2_sp;
360    stack_section
361      // frame 0
362      .Append(32, 0)                      // space
363  
364      .D32(0x40090000)                    // junk that's not
365      .D32(0x60000000)                    // a return address
366  
367      .Append(96, 0)                      // more space
368  
369      .D32(return_address1)               // actual return address
370      // frame 1
371      .Mark(&frame1_sp)
372      .Append(32, 0)                      // space
373  
374      .D32(0xF0000000)                    // more junk
375      .D32(0x0000000D)
376  
377      .Append(136, 0)                     // more space
378  
379      .D32(return_address2)               // actual return address
380                                          // (won't be found)
381      // frame 2
382      .Mark(&frame2_sp)
383      .Append(32, 0);                     // end of stack
384    RegionFromSection();
385  
386    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
387    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
388  
389    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
390    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
391                          &frame_symbolizer);
392    vector<const CodeModule*> modules_without_symbols;
393    vector<const CodeModule*> modules_with_corrupt_symbols;
394    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
395                            &modules_with_corrupt_symbols));
396    ASSERT_EQ(2U, modules_without_symbols.size());
397    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
398    ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
399    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
400    frames = call_stack.frames();
401    ASSERT_EQ(2U, frames->size());
402  
403    StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0));
404    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
405    ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
406    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
407  
408    StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1));
409    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
410    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
411               StackFrameARM::CONTEXT_VALID_SP),
412              frame1->context_validity);
413    EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
414    EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
415  }
416  
417  // Test that set_max_frames_scanned prevents using stack scanning
418  // to find caller frames.
419  TEST_F(GetCallerFrame, ScanningNotAllowed) {
420    // When the stack walker resorts to scanning the stack,
421    // only addresses located within loaded modules are
422    // considered valid return addresses.
423    stack_section.start() = 0x80000000;
424    uint32_t return_address1 = 0x50000100;
425    uint32_t return_address2 = 0x50000900;
426    Label frame1_sp, frame2_sp;
427    stack_section
428      // frame 0
429      .Append(16, 0)                      // space
430  
431      .D32(0x40090000)                    // junk that's not
432      .D32(0x60000000)                    // a return address
433  
434      .D32(return_address1)               // actual return address
435      // frame 1
436      .Mark(&frame1_sp)
437      .Append(16, 0)                      // space
438  
439      .D32(0xF0000000)                    // more junk
440      .D32(0x0000000D)
441  
442      .D32(return_address2)               // actual return address
443      // frame 2
444      .Mark(&frame2_sp)
445      .Append(32, 0);                     // end of stack
446    RegionFromSection();
447  
448    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
449    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
450  
451    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
452    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
453                          &frame_symbolizer);
454    Stackwalker::set_max_frames_scanned(0);
455  
456    vector<const CodeModule*> modules_without_symbols;
457    vector<const CodeModule*> modules_with_corrupt_symbols;
458    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
459                            &modules_with_corrupt_symbols));
460    ASSERT_EQ(1U, modules_without_symbols.size());
461    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
462    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
463    frames = call_stack.frames();
464    ASSERT_EQ(1U, frames->size());
465  
466    StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0));
467    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
468    ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
469    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
470  }
471  
472  struct CFIFixture: public StackwalkerARMFixture {
473    CFIFixture() {
474      // Provide a bunch of STACK CFI records; we'll walk to the caller
475      // from every point in this series, expecting to find the same set
476      // of register values.
477      SetModuleSymbols(&module1,
478                       // The youngest frame's function.
479                       "FUNC 4000 1000 10 enchiridion\n"
480                       // Initially, nothing has been pushed on the stack,
481                       // and the return address is still in the link register.
482                       "STACK CFI INIT 4000 100 .cfa: sp .ra: lr\n"
483                       // Push r4, the frame pointer, and the link register.
484                       "STACK CFI 4001 .cfa: sp 12 + r4: .cfa 12 - ^"
485                       " r11: .cfa 8 - ^ .ra: .cfa 4 - ^\n"
486                       // Save r4..r7 in r0..r3: verify that we populate
487                       // the youngest frame with all the values we have.
488                       "STACK CFI 4002 r4: r0 r5: r1 r6: r2 r7: r3\n"
489                       // Restore r4..r7. Save the non-callee-saves register r1.
490                       "STACK CFI 4003 .cfa: sp 16 + r1: .cfa 16 - ^"
491                       " r4: r4 r5: r5 r6: r6 r7: r7\n"
492                       // Move the .cfa back four bytes, to point at the return
493                       // address, and restore the sp explicitly.
494                       "STACK CFI 4005 .cfa: sp 12 + r1: .cfa 12 - ^"
495                       " r11: .cfa 4 - ^ .ra: .cfa ^ sp: .cfa 4 +\n"
496                       // Recover the PC explicitly from a new stack slot;
497                       // provide garbage for the .ra.
498                       "STACK CFI 4006 .cfa: sp 16 + pc: .cfa 16 - ^\n"
499  
500                       // The calling function.
501                       "FUNC 5000 1000 10 epictetus\n"
502                       // Mark it as end of stack.
503                       "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n"
504  
505                       // A function whose CFI makes the stack pointer
506                       // go backwards.
507                       "FUNC 6000 1000 20 palinal\n"
508                       "STACK CFI INIT 6000 1000 .cfa: sp 4 - .ra: lr\n"
509  
510                       // A function with CFI expressions that can't be
511                       // evaluated.
512                       "FUNC 7000 1000 20 rhetorical\n"
513                       "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n");
514  
515      // Provide some distinctive values for the caller's registers.
516      expected.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
517      expected.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
518      expected.iregs[4] = 0xb5d55e68;
519      expected.iregs[5] = 0xebd134f3;
520      expected.iregs[6] = 0xa31e74bc;
521      expected.iregs[7] = 0x2dcb16b3;
522      expected.iregs[8] = 0x2ada2137;
523      expected.iregs[9] = 0xbbbb557d;
524      expected.iregs[10] = 0x48bf8ca7;
525      expected.iregs[MD_CONTEXT_ARM_REG_FP] = 0x8112e110;
526  
527      // Expect CFI to recover all callee-saves registers. Since CFI is the
528      // only stack frame construction technique we have, aside from the
529      // context frame itself, there's no way for us to have a set of valid
530      // registers smaller than this.
531      expected_validity = (StackFrameARM::CONTEXT_VALID_PC |
532                           StackFrameARM::CONTEXT_VALID_SP |
533                           StackFrameARM::CONTEXT_VALID_R4 |
534                           StackFrameARM::CONTEXT_VALID_R5 |
535                           StackFrameARM::CONTEXT_VALID_R6 |
536                           StackFrameARM::CONTEXT_VALID_R7 |
537                           StackFrameARM::CONTEXT_VALID_R8 |
538                           StackFrameARM::CONTEXT_VALID_R9 |
539                           StackFrameARM::CONTEXT_VALID_R10 |
540                           StackFrameARM::CONTEXT_VALID_FP);
541  
542      // By default, context frames provide all registers, as normal.
543      context_frame_validity = StackFrameARM::CONTEXT_VALID_ALL;
544  
545      // By default, registers are unchanged.
546      raw_context = expected;
547    }
548  
549    // Walk the stack, using stack_section as the contents of the stack
550    // and raw_context as the current register values. (Set the stack
551    // pointer to the stack's starting address.) Expect two stack
552    // frames; in the older frame, expect the callee-saves registers to
553    // have values matching those in 'expected'.
554    void CheckWalk() {
555      RegionFromSection();
556      raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
557  
558      StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
559      StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region,
560                            &modules, &frame_symbolizer);
561      walker.SetContextFrameValidity(context_frame_validity);
562      vector<const CodeModule*> modules_without_symbols;
563      vector<const CodeModule*> modules_with_corrupt_symbols;
564      ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
565                              &modules_with_corrupt_symbols));
566      ASSERT_EQ(0U, modules_without_symbols.size());
567      ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
568      frames = call_stack.frames();
569      ASSERT_EQ(2U, frames->size());
570  
571      StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0));
572      EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
573      ASSERT_EQ(context_frame_validity, frame0->context_validity);
574      EXPECT_EQ("enchiridion", frame0->function_name);
575      EXPECT_EQ(0x40004000U, frame0->function_base);
576  
577      StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1));
578      EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
579      ASSERT_EQ(expected_validity, frame1->context_validity);
580      if (expected_validity & StackFrameARM::CONTEXT_VALID_R1)
581        EXPECT_EQ(expected.iregs[1], frame1->context.iregs[1]);
582      if (expected_validity & StackFrameARM::CONTEXT_VALID_R4)
583        EXPECT_EQ(expected.iregs[4], frame1->context.iregs[4]);
584      if (expected_validity & StackFrameARM::CONTEXT_VALID_R5)
585        EXPECT_EQ(expected.iregs[5], frame1->context.iregs[5]);
586      if (expected_validity & StackFrameARM::CONTEXT_VALID_R6)
587        EXPECT_EQ(expected.iregs[6], frame1->context.iregs[6]);
588      if (expected_validity & StackFrameARM::CONTEXT_VALID_R7)
589        EXPECT_EQ(expected.iregs[7], frame1->context.iregs[7]);
590      if (expected_validity & StackFrameARM::CONTEXT_VALID_R8)
591        EXPECT_EQ(expected.iregs[8], frame1->context.iregs[8]);
592      if (expected_validity & StackFrameARM::CONTEXT_VALID_R9)
593        EXPECT_EQ(expected.iregs[9], frame1->context.iregs[9]);
594      if (expected_validity & StackFrameARM::CONTEXT_VALID_R10)
595        EXPECT_EQ(expected.iregs[10], frame1->context.iregs[10]);
596      if (expected_validity & StackFrameARM::CONTEXT_VALID_FP)
597        EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_FP],
598                  frame1->context.iregs[MD_CONTEXT_ARM_REG_FP]);
599  
600      // We would never have gotten a frame in the first place if the SP
601      // and PC weren't valid or ->instruction weren't set.
602      EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_SP],
603                frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
604      EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC],
605                frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
606      EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC],
607                frame1->instruction + 2);
608      EXPECT_EQ("epictetus", frame1->function_name);
609    }
610  
611    // The values we expect to find for the caller's registers.
612    MDRawContextARM expected;
613  
614    // The validity mask for expected.
615    int expected_validity;
616  
617    // The validity mask to impose on the context frame.
618    int context_frame_validity;
619  };
620  
621  class CFI: public CFIFixture, public Test { };
622  
623  TEST_F(CFI, At4000) {
624    stack_section.start() = expected.iregs[MD_CONTEXT_ARM_REG_SP];
625    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004000;
626    raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510;
627    CheckWalk();
628  }
629  
630  TEST_F(CFI, At4001) {
631    Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
632    stack_section
633      .D32(0xb5d55e68)            // saved r4
634      .D32(0x8112e110)            // saved fp
635      .D32(0x40005510)            // return address
636      .Mark(&frame1_sp);          // This effectively sets stack_section.start().
637    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001;
638    raw_context.iregs[4] = 0x635adc9f;                     // distinct callee r4
639    raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
640    CheckWalk();
641  }
642  
643  // As above, but unwind from a context that has only the PC and SP.
644  TEST_F(CFI, At4001LimitedValidity) {
645    context_frame_validity =
646      StackFrameARM::CONTEXT_VALID_PC | StackFrameARM::CONTEXT_VALID_SP;
647    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001;
648    raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
649    Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
650    stack_section
651      .D32(0xb5d55e68)            // saved r4
652      .D32(0x8112e110)            // saved fp
653      .D32(0x40005510)            // return address
654      .Mark(&frame1_sp);          // This effectively sets stack_section.start().
655    expected_validity = (StackFrameARM::CONTEXT_VALID_PC
656                         | StackFrameARM::CONTEXT_VALID_SP
657                         | StackFrameARM::CONTEXT_VALID_FP
658                         | StackFrameARM::CONTEXT_VALID_R4);
659    CheckWalk();
660  }
661  
662  TEST_F(CFI, At4002) {
663    Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
664    stack_section
665      .D32(0xfb81ff3d)            // no longer saved r4
666      .D32(0x8112e110)            // saved fp
667      .D32(0x40005510)            // return address
668      .Mark(&frame1_sp);          // This effectively sets stack_section.start().
669    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004002;
670    raw_context.iregs[0] = 0xb5d55e68;  // saved r4
671    raw_context.iregs[1] = 0xebd134f3;  // saved r5
672    raw_context.iregs[2] = 0xa31e74bc;  // saved r6
673    raw_context.iregs[3] = 0x2dcb16b3;  // saved r7
674    raw_context.iregs[4] = 0xfdd35466;  // distinct callee r4
675    raw_context.iregs[5] = 0xf18c946c;  // distinct callee r5
676    raw_context.iregs[6] = 0xac2079e8;  // distinct callee r6
677    raw_context.iregs[7] = 0xa449829f;  // distinct callee r7
678    raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
679    CheckWalk();
680  }
681  
682  TEST_F(CFI, At4003) {
683    Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
684    stack_section
685      .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
686      .D32(0xcb78040e)            // no longer saved r4
687      .D32(0x8112e110)            // saved fp
688      .D32(0x40005510)            // return address
689      .Mark(&frame1_sp);          // This effectively sets stack_section.start().
690    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004003;
691    raw_context.iregs[1] = 0xfb756319;                     // distinct callee r1
692    raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0x0a2857ea; // distinct callee fp
693    expected.iregs[1] = 0x48c8dd5a;    // caller's r1
694    expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
695    CheckWalk();
696  }
697  
698  // We have no new rule at module offset 0x4004, so the results here should
699  // be the same as those at module offset 0x4003.
700  TEST_F(CFI, At4004) {
701    Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
702    stack_section
703      .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
704      .D32(0xcb78040e)            // no longer saved r4
705      .D32(0x8112e110)            // saved fp
706      .D32(0x40005510)            // return address
707      .Mark(&frame1_sp);          // This effectively sets stack_section.start().
708    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004004;
709    raw_context.iregs[1] = 0xfb756319; // distinct callee r1
710    expected.iregs[1] = 0x48c8dd5a; // caller's r1
711    expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
712    CheckWalk();
713  }
714  
715  // Here we move the .cfa, but provide an explicit rule to recover the SP,
716  // so again there should be no change in the registers recovered.
717  TEST_F(CFI, At4005) {
718    Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
719    stack_section
720      .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
721      .D32(0xf013f841)            // no longer saved r4
722      .D32(0x8112e110)            // saved fp
723      .D32(0x40005510)            // return address
724      .Mark(&frame1_sp);          // This effectively sets stack_section.start().
725    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004005;
726    raw_context.iregs[1] = 0xfb756319; // distinct callee r1
727    expected.iregs[1] = 0x48c8dd5a; // caller's r1
728    expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
729    CheckWalk();
730  }
731  
732  // Here we provide an explicit rule for the PC, and have the saved .ra be
733  // bogus.
734  TEST_F(CFI, At4006) {
735    Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
736    stack_section
737      .D32(0x40005510)            // saved pc
738      .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
739      .D32(0xf013f841)            // no longer saved r4
740      .D32(0x8112e110)            // saved fp
741      .D32(0xf8d15783)            // .ra rule recovers this, which is garbage
742      .Mark(&frame1_sp);          // This effectively sets stack_section.start().
743    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004006;
744    raw_context.iregs[1] = 0xfb756319; // callee's r1, different from caller's
745    expected.iregs[1] = 0x48c8dd5a; // caller's r1
746    expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
747    CheckWalk();
748  }
749  
750  // Check that we reject rules that would cause the stack pointer to
751  // move in the wrong direction.
752  TEST_F(CFI, RejectBackwards) {
753    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40006000;
754    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
755    raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510;
756    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
757    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
758                          &frame_symbolizer);
759    vector<const CodeModule*> modules_without_symbols;
760    vector<const CodeModule*> modules_with_corrupt_symbols;
761    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
762                            &modules_with_corrupt_symbols));
763    ASSERT_EQ(0U, modules_without_symbols.size());
764    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
765    frames = call_stack.frames();
766    ASSERT_EQ(1U, frames->size());
767  }
768  
769  // Check that we reject rules whose expressions' evaluation fails.
770  TEST_F(CFI, RejectBadExpressions) {
771    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40007000;
772    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
773    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
774    StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
775                          &frame_symbolizer);
776    vector<const CodeModule*> modules_without_symbols;
777    vector<const CodeModule*> modules_with_corrupt_symbols;
778    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
779                            &modules_with_corrupt_symbols));
780    ASSERT_EQ(0U, modules_without_symbols.size());
781    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
782    frames = call_stack.frames();
783    ASSERT_EQ(1U, frames->size());
784  }
785  
786  class StackwalkerARMFixtureIOS : public StackwalkerARMFixture {
787   public:
788    StackwalkerARMFixtureIOS() {
789      // iOS_test is used instead of iOS because the stackwalker has a check to
790      // avoid using CFI for iOS dumps. This is a workaround for bad CFI being
791      // produced by dump_syms for iOS.
792      // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=764
793      system_info.os = "iOS_test";
794      system_info.os_short = "ios_test";
795    }
796  };
797  
798  class GetFramesByFramePointer: public StackwalkerARMFixtureIOS, public Test { };
799  
800  TEST_F(GetFramesByFramePointer, OnlyFramePointer) {
801    stack_section.start() = 0x80000000;
802    uint32_t return_address1 = 0x50000100;
803    uint32_t return_address2 = 0x50000900;
804    Label frame1_sp, frame2_sp;
805    Label frame1_fp, frame2_fp;
806    stack_section
807      // frame 0
808      .Append(32, 0)           // Whatever values on the stack.
809      .D32(0x0000000D)         // junk that's not
810      .D32(0xF0000000)         // a return address.
811  
812      .Mark(&frame1_fp)        // Next fp will point to the next value.
813      .D32(frame2_fp)          // Save current frame pointer.
814      .D32(return_address2)    // Save current link register.
815      .Mark(&frame1_sp)
816  
817      // frame 1
818      .Append(32, 0)           // Whatever values on the stack.
819      .D32(0x0000000D)         // junk that's not
820      .D32(0xF0000000)         // a return address.
821  
822      .Mark(&frame2_fp)
823      .D32(0)
824      .D32(0)
825      .Mark(&frame2_sp)
826  
827      // frame 2
828      .Append(32, 0)           // Whatever values on the stack.
829      .D32(0x0000000D)         // junk that's not
830      .D32(0xF0000000);        // a return address.
831    RegionFromSection();
832  
833  
834    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
835    raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1;
836    raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
837    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
838  
839    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
840    StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
841                          &stack_region, &modules, &frame_symbolizer);
842  
843    vector<const CodeModule*> modules_without_symbols;
844    vector<const CodeModule*> modules_with_corrupt_symbols;
845    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
846                            &modules_with_corrupt_symbols));
847    ASSERT_EQ(2U, modules_without_symbols.size());
848    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
849    ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
850    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
851    frames = call_stack.frames();
852    ASSERT_EQ(3U, frames->size());
853  
854    StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0));
855    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
856    ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
857    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
858  
859    StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1));
860    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
861    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
862               StackFrameARM::CONTEXT_VALID_LR |
863               StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
864               StackFrameARM::CONTEXT_VALID_SP),
865              frame1->context_validity);
866    EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
867    EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]);
868    EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
869    EXPECT_EQ(frame2_fp.Value(),
870              frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
871  
872    StackFrameARM *frame2 = static_cast<StackFrameARM*>(frames->at(2));
873    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust);
874    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
875               StackFrameARM::CONTEXT_VALID_LR |
876               StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
877               StackFrameARM::CONTEXT_VALID_SP),
878              frame2->context_validity);
879    EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
880    EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]);
881    EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
882    EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
883  }
884  
885  TEST_F(GetFramesByFramePointer, FramePointerAndCFI) {
886    // Provide the standatd STACK CFI records that is obtained when exmining an
887    // executable produced by XCode.
888    SetModuleSymbols(&module1,
889                       // Adding a function in CFI.
890                       "FUNC 4000 1000 10 enchiridion\n"
891  
892                       "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: lr\n"
893                       "STACK CFI 4001 .cfa: sp 8 + .ra: .cfa -4 + ^"
894                       " r7: .cfa -8 + ^\n"
895                       "STACK CFI 4002 .cfa: r7 8 +\n"
896                    );
897  
898    stack_section.start() = 0x80000000;
899    uint32_t return_address1 = 0x40004010;
900    uint32_t return_address2 = 0x50000900;
901    Label frame1_sp, frame2_sp;
902    Label frame1_fp, frame2_fp;
903    stack_section
904      // frame 0
905      .Append(32, 0)           // Whatever values on the stack.
906      .D32(0x0000000D)         // junk that's not
907      .D32(0xF0000000)         // a return address.
908  
909      .Mark(&frame1_fp)        // Next fp will point to the next value.
910      .D32(frame2_fp)          // Save current frame pointer.
911      .D32(return_address2)    // Save current link register.
912      .Mark(&frame1_sp)
913  
914      // frame 1
915      .Append(32, 0)           // Whatever values on the stack.
916      .D32(0x0000000D)         // junk that's not
917      .D32(0xF0000000)         // a return address.
918  
919      .Mark(&frame2_fp)
920      .D32(0)
921      .D32(0)
922      .Mark(&frame2_sp)
923  
924      // frame 2
925      .Append(32, 0)           // Whatever values on the stack.
926      .D32(0x0000000D)         // junk that's not
927      .D32(0xF0000000);        // a return address.
928    RegionFromSection();
929  
930  
931    raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x50000400;
932    raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1;
933    raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
934    raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
935  
936    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
937    StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
938                          &stack_region, &modules, &frame_symbolizer);
939  
940    vector<const CodeModule*> modules_without_symbols;
941    vector<const CodeModule*> modules_with_corrupt_symbols;
942    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
943                            &modules_with_corrupt_symbols));
944    ASSERT_EQ(1U, modules_without_symbols.size());
945    ASSERT_EQ("module2", modules_without_symbols[0]->debug_file());
946    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
947    frames = call_stack.frames();
948    ASSERT_EQ(3U, frames->size());
949  
950    StackFrameARM *frame0 = static_cast<StackFrameARM*>(frames->at(0));
951    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
952    ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
953    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
954  
955    StackFrameARM *frame1 = static_cast<StackFrameARM*>(frames->at(1));
956    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
957    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
958               StackFrameARM::CONTEXT_VALID_LR |
959               StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
960               StackFrameARM::CONTEXT_VALID_SP),
961              frame1->context_validity);
962    EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
963    EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]);
964    EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
965    EXPECT_EQ(frame2_fp.Value(),
966              frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
967    EXPECT_EQ("enchiridion", frame1->function_name);
968    EXPECT_EQ(0x40004000U, frame1->function_base);
969  
970  
971    StackFrameARM *frame2 = static_cast<StackFrameARM*>(frames->at(2));
972    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
973    ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
974               StackFrameARM::CONTEXT_VALID_LR |
975               StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
976               StackFrameARM::CONTEXT_VALID_SP),
977              frame2->context_validity);
978    EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
979    EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]);
980    EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
981    EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
982  }