1 // Copyright (c) 2010, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
31 
32 // stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class.
33 
34 #include <string.h>
35 #include <string>
36 #include <vector>
37 
38 #include "breakpad_googletest_includes.h"
39 #include "common/test_assembler.h"
40 #include "common/using_std_string.h"
41 #include "google_breakpad/common/minidump_format.h"
42 #include "google_breakpad/processor/basic_source_line_resolver.h"
43 #include "google_breakpad/processor/call_stack.h"
44 #include "google_breakpad/processor/code_module.h"
45 #include "google_breakpad/processor/source_line_resolver_interface.h"
46 #include "google_breakpad/processor/stack_frame_cpu.h"
47 #include "processor/stackwalker_unittest_utils.h"
48 #include "processor/stackwalker_arm.h"
49 #include "processor/windows_frame_info.h"
50 
51 using google_breakpad::BasicSourceLineResolver;
52 using google_breakpad::CallStack;
53 using google_breakpad::CodeModule;
54 using google_breakpad::StackFrameSymbolizer;
55 using google_breakpad::StackFrame;
56 using google_breakpad::StackFrameARM;
57 using google_breakpad::Stackwalker;
58 using google_breakpad::StackwalkerARM;
59 using google_breakpad::SystemInfo;
60 using google_breakpad::WindowsFrameInfo;
61 using google_breakpad::test_assembler::kLittleEndian;
62 using google_breakpad::test_assembler::Label;
63 using google_breakpad::test_assembler::Section;
64 using std::vector;
65 using testing::_;
66 using testing::AnyNumber;
67 using testing::DoAll;
68 using testing::Return;
69 using testing::SetArgumentPointee;
70 using testing::Test;
71 
72 class StackwalkerARMFixture {
73  public:
StackwalkerARMFixture()74   StackwalkerARMFixture()
75     : stack_section(kLittleEndian),
76       // Give the two modules reasonable standard locations and names
77       // for tests to play with.
78       module1(0x40000000, 0x10000, "module1", "version1"),
79       module2(0x50000000, 0x10000, "module2", "version2") {
80     // Identify the system as a Linux system.
81     system_info.os = "Linux";
82     system_info.os_short = "linux";
83     system_info.os_version = "Lugubrious Labrador";
84     system_info.cpu = "arm";
85     system_info.cpu_info = "";
86 
87     // Put distinctive values in the raw CPU context.
88     BrandContext(&raw_context);
89 
90     // Create some modules with some stock debugging information.
91     modules.Add(&module1);
92     modules.Add(&module2);
93 
94     // By default, none of the modules have symbol info; call
95     // SetModuleSymbols to override this.
96     EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _))
97       .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
98 
99     // Avoid GMOCK WARNING "Uninteresting mock function call - returning
100     // directly" for FreeSymbolData().
101     EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber());
102 
103     // Reset max_frames_scanned since it's static.
104     Stackwalker::set_max_frames_scanned(1024);
105   }
106 
107   // Set the Breakpad symbol information that supplier should return for
108   // MODULE to INFO.
SetModuleSymbols(MockCodeModule * module,const string & info)109   void SetModuleSymbols(MockCodeModule *module, const string &info) {
110     size_t buffer_size;
111     char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size);
112     EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _))
113       .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
114                             SetArgumentPointee<4>(buffer_size),
115                             Return(MockSymbolSupplier::FOUND)));
116   }
117 
118   // Populate stack_region with the contents of stack_section. Use
119   // stack_section.start() as the region's starting address.
RegionFromSection()120   void RegionFromSection() {
121     string contents;
122     ASSERT_TRUE(stack_section.GetContents(&contents));
123     stack_region.Init(stack_section.start().Value(), contents);
124   }
125 
126   // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
BrandContext(MDRawContextARM * raw_context)127   void BrandContext(MDRawContextARM *raw_context) {
128     uint8_t x = 173;
129     for (size_t i = 0; i < sizeof(*raw_context); i++)
130       reinterpret_cast<uint8_t *>(raw_context)[i] = (x += 17);
131   }
132 
133   SystemInfo system_info;
134   MDRawContextARM raw_context;
135   Section stack_section;
136   MockMemoryRegion stack_region;
137   MockCodeModule module1;
138   MockCodeModule module2;
139   MockCodeModules modules;
140   MockSymbolSupplier supplier;
141   BasicSourceLineResolver resolver;
142   CallStack call_stack;
143   const vector<StackFrame *> *frames;
144 };
145 
146 class SanityCheck: public StackwalkerARMFixture, public Test { };
147 
TEST_F(SanityCheck,NoResolver)148 TEST_F(SanityCheck, NoResolver) {
149   // Since we have no call frame information, and all unwinding
150   // requires call frame information, the stack walk will end after
151   // the first frame.
152   StackFrameSymbolizer frame_symbolizer(NULL, NULL);
153   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
154                         &frame_symbolizer);
155   // This should succeed even without a resolver or supplier.
156   vector<const CodeModule*> modules_without_symbols;
157   vector<const CodeModule*> modules_with_corrupt_symbols;
158   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
159                           &modules_with_corrupt_symbols));
160   ASSERT_EQ(0U, modules_without_symbols.size());
161   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
162   frames = call_stack.frames();
163   ASSERT_EQ(1U, frames->size());
164   StackFrameARM *frame = static_cast<StackFrameARM *>(frames->at(0));
165   // Check that the values from the original raw context made it
166   // through to the context in the stack frame.
167   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
168 }
169 
170 class GetContextFrame: public StackwalkerARMFixture, public Test { };
171 
TEST_F(GetContextFrame,Simple)172 TEST_F(GetContextFrame, Simple) {
173   // Since we have no call frame information, and all unwinding
174   // requires call frame information, the stack walk will end after
175   // the first frame.
176   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
177   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &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   StackFrameARM *frame = static_cast<StackFrameARM *>(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 // The stackwalker should be able to produce the context frame even
194 // without stack memory present.
TEST_F(GetContextFrame,NoStackMemory)195 TEST_F(GetContextFrame, NoStackMemory) {
196   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
197   StackwalkerARM walker(&system_info, &raw_context, -1, NULL, &modules,
198                         &frame_symbolizer);
199   vector<const CodeModule*> modules_without_symbols;
200   vector<const CodeModule*> modules_with_corrupt_symbols;
201   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
202                           &modules_with_corrupt_symbols));
203   ASSERT_EQ(0U, modules_without_symbols.size());
204   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
205   frames = call_stack.frames();
206   ASSERT_EQ(1U, frames->size());
207   StackFrameARM *frame = static_cast<StackFrameARM *>(frames->at(0));
208   // Check that the values from the original raw context made it
209   // through to the context in the stack frame.
210   EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
211 }
212 
213 class GetCallerFrame: public StackwalkerARMFixture, public Test { };
214 
TEST_F(GetCallerFrame,ScanWithoutSymbols)215 TEST_F(GetCallerFrame, ScanWithoutSymbols) {
216   // When the stack walker resorts to scanning the stack,
217   // only addresses located within loaded modules are
218   // considered valid return addresses.
219   // Force scanning through three frames to ensure that the
220   // stack pointer is set properly in scan-recovered frames.
221   stack_section.start() = 0x80000000;
222   uint32_t return_address1 = 0x50000100;
223   uint32_t return_address2 = 0x50000900;
224   Label frame1_sp, frame2_sp;
225   stack_section
226     // frame 0
227     .Append(16, 0)                      // space
228 
229     .D32(0x40090000)                    // junk that's not
230     .D32(0x60000000)                    // a return address
231 
232     .D32(return_address1)               // actual return address
233     // frame 1
234     .Mark(&frame1_sp)
235     .Append(16, 0)                      // space
236 
237     .D32(0xF0000000)                    // more junk
238     .D32(0x0000000D)
239 
240     .D32(return_address2)               // actual return address
241     // frame 2
242     .Mark(&frame2_sp)
243     .Append(32, 0);                     // end of stack
244   RegionFromSection();
245 
246   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
247   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
248 
249   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
250   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
251                         &frame_symbolizer);
252   vector<const CodeModule*> modules_without_symbols;
253   vector<const CodeModule*> modules_with_corrupt_symbols;
254   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
255                           &modules_with_corrupt_symbols));
256   ASSERT_EQ(2U, modules_without_symbols.size());
257   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
258   ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
259   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
260   frames = call_stack.frames();
261   ASSERT_EQ(3U, frames->size());
262 
263   StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
264   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
265   ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
266   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
267 
268   StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
269   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
270   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
271              StackFrameARM::CONTEXT_VALID_SP),
272             frame1->context_validity);
273   EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
274   EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
275 
276   StackFrameARM *frame2 = static_cast<StackFrameARM *>(frames->at(2));
277   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust);
278   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
279              StackFrameARM::CONTEXT_VALID_SP),
280             frame2->context_validity);
281   EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
282   EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
283 }
284 
TEST_F(GetCallerFrame,ScanWithFunctionSymbols)285 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
286   // During stack scanning, if a potential return address
287   // is located within a loaded module that has symbols,
288   // it is only considered a valid return address if it
289   // lies within a function's bounds.
290   stack_section.start() = 0x80000000;
291   uint32_t return_address = 0x50000200;
292   Label frame1_sp;
293 
294   stack_section
295     // frame 0
296     .Append(16, 0)                      // space
297 
298     .D32(0x40090000)                    // junk that's not
299     .D32(0x60000000)                    // a return address
300 
301     .D32(0x40001000)                    // a couple of plausible addresses
302     .D32(0x5000F000)                    // that are not within functions
303 
304     .D32(return_address)                // actual return address
305     // frame 1
306     .Mark(&frame1_sp)
307     .Append(32, 0);                     // end of stack
308   RegionFromSection();
309 
310   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40000200;
311   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
312 
313   SetModuleSymbols(&module1,
314                    // The youngest frame's function.
315                    "FUNC 100 400 10 monotreme\n");
316   SetModuleSymbols(&module2,
317                    // The calling frame's function.
318                    "FUNC 100 400 10 marsupial\n");
319 
320   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
321   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
322                         &frame_symbolizer);
323   vector<const CodeModule*> modules_without_symbols;
324   vector<const CodeModule*> modules_with_corrupt_symbols;
325   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
326                           &modules_with_corrupt_symbols));
327   ASSERT_EQ(0U, modules_without_symbols.size());
328   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
329   frames = call_stack.frames();
330   ASSERT_EQ(2U, frames->size());
331 
332   StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
333   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
334   ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
335   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
336   EXPECT_EQ("monotreme", frame0->function_name);
337   EXPECT_EQ(0x40000100U, frame0->function_base);
338 
339   StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
340   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
341   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
342              StackFrameARM::CONTEXT_VALID_SP),
343             frame1->context_validity);
344   EXPECT_EQ(return_address, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
345   EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
346   EXPECT_EQ("marsupial", frame1->function_name);
347   EXPECT_EQ(0x50000100U, frame1->function_base);
348 }
349 
TEST_F(GetCallerFrame,ScanFirstFrame)350 TEST_F(GetCallerFrame, ScanFirstFrame) {
351   // If the stackwalker resorts to stack scanning, it will scan much
352   // farther to find the caller of the context frame.
353   stack_section.start() = 0x80000000;
354   uint32_t return_address1 = 0x50000100;
355   uint32_t return_address2 = 0x50000900;
356   Label frame1_sp, frame2_sp;
357   stack_section
358     // frame 0
359     .Append(32, 0)                      // space
360 
361     .D32(0x40090000)                    // junk that's not
362     .D32(0x60000000)                    // a return address
363 
364     .Append(96, 0)                      // more space
365 
366     .D32(return_address1)               // actual return address
367     // frame 1
368     .Mark(&frame1_sp)
369     .Append(32, 0)                      // space
370 
371     .D32(0xF0000000)                    // more junk
372     .D32(0x0000000D)
373 
374     .Append(136, 0)                     // more space
375 
376     .D32(return_address2)               // actual return address
377                                         // (won't be found)
378     // frame 2
379     .Mark(&frame2_sp)
380     .Append(32, 0);                     // end of stack
381   RegionFromSection();
382 
383   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
384   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
385 
386   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
387   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
388                         &frame_symbolizer);
389   vector<const CodeModule*> modules_without_symbols;
390   vector<const CodeModule*> modules_with_corrupt_symbols;
391   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
392                           &modules_with_corrupt_symbols));
393   ASSERT_EQ(2U, modules_without_symbols.size());
394   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
395   ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
396   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
397   frames = call_stack.frames();
398   ASSERT_EQ(2U, frames->size());
399 
400   StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
401   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
402   ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
403   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
404 
405   StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
406   EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
407   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
408              StackFrameARM::CONTEXT_VALID_SP),
409             frame1->context_validity);
410   EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
411   EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
412 }
413 
414 // Test that set_max_frames_scanned prevents using stack scanning
415 // to find caller frames.
TEST_F(GetCallerFrame,ScanningNotAllowed)416 TEST_F(GetCallerFrame, ScanningNotAllowed) {
417   // When the stack walker resorts to scanning the stack,
418   // only addresses located within loaded modules are
419   // considered valid return addresses.
420   stack_section.start() = 0x80000000;
421   uint32_t return_address1 = 0x50000100;
422   uint32_t return_address2 = 0x50000900;
423   Label frame1_sp, frame2_sp;
424   stack_section
425     // frame 0
426     .Append(16, 0)                      // space
427 
428     .D32(0x40090000)                    // junk that's not
429     .D32(0x60000000)                    // a return address
430 
431     .D32(return_address1)               // actual return address
432     // frame 1
433     .Mark(&frame1_sp)
434     .Append(16, 0)                      // space
435 
436     .D32(0xF0000000)                    // more junk
437     .D32(0x0000000D)
438 
439     .D32(return_address2)               // actual return address
440     // frame 2
441     .Mark(&frame2_sp)
442     .Append(32, 0);                     // end of stack
443   RegionFromSection();
444 
445   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
446   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
447 
448   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
449   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
450                         &frame_symbolizer);
451   Stackwalker::set_max_frames_scanned(0);
452 
453   vector<const CodeModule*> modules_without_symbols;
454   vector<const CodeModule*> modules_with_corrupt_symbols;
455   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
456                           &modules_with_corrupt_symbols));
457   ASSERT_EQ(1U, modules_without_symbols.size());
458   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
459   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
460   frames = call_stack.frames();
461   ASSERT_EQ(1U, frames->size());
462 
463   StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
464   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
465   ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
466   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
467 }
468 
469 struct CFIFixture: public StackwalkerARMFixture {
CFIFixtureCFIFixture470   CFIFixture() {
471     // Provide a bunch of STACK CFI records; we'll walk to the caller
472     // from every point in this series, expecting to find the same set
473     // of register values.
474     SetModuleSymbols(&module1,
475                      // The youngest frame's function.
476                      "FUNC 4000 1000 10 enchiridion\n"
477                      // Initially, nothing has been pushed on the stack,
478                      // and the return address is still in the link register.
479                      "STACK CFI INIT 4000 100 .cfa: sp .ra: lr\n"
480                      // Push r4, the frame pointer, and the link register.
481                      "STACK CFI 4001 .cfa: sp 12 + r4: .cfa 12 - ^"
482                      " r11: .cfa 8 - ^ .ra: .cfa 4 - ^\n"
483                      // Save r4..r7 in r0..r3: verify that we populate
484                      // the youngest frame with all the values we have.
485                      "STACK CFI 4002 r4: r0 r5: r1 r6: r2 r7: r3\n"
486                      // Restore r4..r7. Save the non-callee-saves register r1.
487                      "STACK CFI 4003 .cfa: sp 16 + r1: .cfa 16 - ^"
488                      " r4: r4 r5: r5 r6: r6 r7: r7\n"
489                      // Move the .cfa back four bytes, to point at the return
490                      // address, and restore the sp explicitly.
491                      "STACK CFI 4005 .cfa: sp 12 + r1: .cfa 12 - ^"
492                      " r11: .cfa 4 - ^ .ra: .cfa ^ sp: .cfa 4 +\n"
493                      // Recover the PC explicitly from a new stack slot;
494                      // provide garbage for the .ra.
495                      "STACK CFI 4006 .cfa: sp 16 + pc: .cfa 16 - ^\n"
496 
497                      // The calling function.
498                      "FUNC 5000 1000 10 epictetus\n"
499                      // Mark it as end of stack.
500                      "STACK CFI INIT 5000 1000 .cfa: 0 .ra: 0\n"
501 
502                      // A function whose CFI makes the stack pointer
503                      // go backwards.
504                      "FUNC 6000 1000 20 palinal\n"
505                      "STACK CFI INIT 6000 1000 .cfa: sp 4 - .ra: lr\n"
506 
507                      // A function with CFI expressions that can't be
508                      // evaluated.
509                      "FUNC 7000 1000 20 rhetorical\n"
510                      "STACK CFI INIT 7000 1000 .cfa: moot .ra: ambiguous\n");
511 
512     // Provide some distinctive values for the caller's registers.
513     expected.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
514     expected.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
515     expected.iregs[4] = 0xb5d55e68;
516     expected.iregs[5] = 0xebd134f3;
517     expected.iregs[6] = 0xa31e74bc;
518     expected.iregs[7] = 0x2dcb16b3;
519     expected.iregs[8] = 0x2ada2137;
520     expected.iregs[9] = 0xbbbb557d;
521     expected.iregs[10] = 0x48bf8ca7;
522     expected.iregs[MD_CONTEXT_ARM_REG_FP] = 0x8112e110;
523 
524     // Expect CFI to recover all callee-saves registers. Since CFI is the
525     // only stack frame construction technique we have, aside from the
526     // context frame itself, there's no way for us to have a set of valid
527     // registers smaller than this.
528     expected_validity = (StackFrameARM::CONTEXT_VALID_PC |
529                          StackFrameARM::CONTEXT_VALID_SP |
530                          StackFrameARM::CONTEXT_VALID_R4 |
531                          StackFrameARM::CONTEXT_VALID_R5 |
532                          StackFrameARM::CONTEXT_VALID_R6 |
533                          StackFrameARM::CONTEXT_VALID_R7 |
534                          StackFrameARM::CONTEXT_VALID_R8 |
535                          StackFrameARM::CONTEXT_VALID_R9 |
536                          StackFrameARM::CONTEXT_VALID_R10 |
537                          StackFrameARM::CONTEXT_VALID_FP);
538 
539     // By default, context frames provide all registers, as normal.
540     context_frame_validity = StackFrameARM::CONTEXT_VALID_ALL;
541 
542     // By default, registers are unchanged.
543     raw_context = expected;
544   }
545 
546   // Walk the stack, using stack_section as the contents of the stack
547   // and raw_context as the current register values. (Set the stack
548   // pointer to the stack's starting address.) Expect two stack
549   // frames; in the older frame, expect the callee-saves registers to
550   // have values matching those in 'expected'.
CheckWalkCFIFixture551   void CheckWalk() {
552     RegionFromSection();
553     raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
554 
555     StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
556     StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region,
557                           &modules, &frame_symbolizer);
558     walker.SetContextFrameValidity(context_frame_validity);
559     vector<const CodeModule*> modules_without_symbols;
560     vector<const CodeModule*> modules_with_corrupt_symbols;
561     ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
562                             &modules_with_corrupt_symbols));
563     ASSERT_EQ(0U, modules_without_symbols.size());
564     ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
565     frames = call_stack.frames();
566     ASSERT_EQ(2U, frames->size());
567 
568     StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
569     EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
570     ASSERT_EQ(context_frame_validity, frame0->context_validity);
571     EXPECT_EQ("enchiridion", frame0->function_name);
572     EXPECT_EQ(0x40004000U, frame0->function_base);
573 
574     StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
575     EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
576     ASSERT_EQ(expected_validity, frame1->context_validity);
577     if (expected_validity & StackFrameARM::CONTEXT_VALID_R1)
578       EXPECT_EQ(expected.iregs[1], frame1->context.iregs[1]);
579     if (expected_validity & StackFrameARM::CONTEXT_VALID_R4)
580       EXPECT_EQ(expected.iregs[4], frame1->context.iregs[4]);
581     if (expected_validity & StackFrameARM::CONTEXT_VALID_R5)
582       EXPECT_EQ(expected.iregs[5], frame1->context.iregs[5]);
583     if (expected_validity & StackFrameARM::CONTEXT_VALID_R6)
584       EXPECT_EQ(expected.iregs[6], frame1->context.iregs[6]);
585     if (expected_validity & StackFrameARM::CONTEXT_VALID_R7)
586       EXPECT_EQ(expected.iregs[7], frame1->context.iregs[7]);
587     if (expected_validity & StackFrameARM::CONTEXT_VALID_R8)
588       EXPECT_EQ(expected.iregs[8], frame1->context.iregs[8]);
589     if (expected_validity & StackFrameARM::CONTEXT_VALID_R9)
590       EXPECT_EQ(expected.iregs[9], frame1->context.iregs[9]);
591     if (expected_validity & StackFrameARM::CONTEXT_VALID_R10)
592       EXPECT_EQ(expected.iregs[10], frame1->context.iregs[10]);
593     if (expected_validity & StackFrameARM::CONTEXT_VALID_FP)
594       EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_FP],
595                 frame1->context.iregs[MD_CONTEXT_ARM_REG_FP]);
596 
597     // We would never have gotten a frame in the first place if the SP
598     // and PC weren't valid or ->instruction weren't set.
599     EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_SP],
600               frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
601     EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC],
602               frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
603     EXPECT_EQ(expected.iregs[MD_CONTEXT_ARM_REG_PC],
604               frame1->instruction + 2);
605     EXPECT_EQ("epictetus", frame1->function_name);
606   }
607 
608   // The values we expect to find for the caller's registers.
609   MDRawContextARM expected;
610 
611   // The validity mask for expected.
612   int expected_validity;
613 
614   // The validity mask to impose on the context frame.
615   int context_frame_validity;
616 };
617 
618 class CFI: public CFIFixture, public Test { };
619 
TEST_F(CFI,At4000)620 TEST_F(CFI, At4000) {
621   stack_section.start() = expected.iregs[MD_CONTEXT_ARM_REG_SP];
622   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004000;
623   raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510;
624   CheckWalk();
625 }
626 
TEST_F(CFI,At4001)627 TEST_F(CFI, At4001) {
628   Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
629   stack_section
630     .D32(0xb5d55e68)            // saved r4
631     .D32(0x8112e110)            // saved fp
632     .D32(0x40005510)            // return address
633     .Mark(&frame1_sp);          // This effectively sets stack_section.start().
634   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001;
635   raw_context.iregs[4] = 0x635adc9f;                     // distinct callee r4
636   raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
637   CheckWalk();
638 }
639 
640 // As above, but unwind from a context that has only the PC and SP.
TEST_F(CFI,At4001LimitedValidity)641 TEST_F(CFI, At4001LimitedValidity) {
642   context_frame_validity =
643     StackFrameARM::CONTEXT_VALID_PC | StackFrameARM::CONTEXT_VALID_SP;
644   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004001;
645   raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
646   Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
647   stack_section
648     .D32(0xb5d55e68)            // saved r4
649     .D32(0x8112e110)            // saved fp
650     .D32(0x40005510)            // return address
651     .Mark(&frame1_sp);          // This effectively sets stack_section.start().
652   expected_validity = (StackFrameARM::CONTEXT_VALID_PC
653                        | StackFrameARM::CONTEXT_VALID_SP
654                        | StackFrameARM::CONTEXT_VALID_FP
655                        | StackFrameARM::CONTEXT_VALID_R4);
656   CheckWalk();
657 }
658 
TEST_F(CFI,At4002)659 TEST_F(CFI, At4002) {
660   Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
661   stack_section
662     .D32(0xfb81ff3d)            // no longer saved r4
663     .D32(0x8112e110)            // saved fp
664     .D32(0x40005510)            // return address
665     .Mark(&frame1_sp);          // This effectively sets stack_section.start().
666   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004002;
667   raw_context.iregs[0] = 0xb5d55e68;  // saved r4
668   raw_context.iregs[1] = 0xebd134f3;  // saved r5
669   raw_context.iregs[2] = 0xa31e74bc;  // saved r6
670   raw_context.iregs[3] = 0x2dcb16b3;  // saved r7
671   raw_context.iregs[4] = 0xfdd35466;  // distinct callee r4
672   raw_context.iregs[5] = 0xf18c946c;  // distinct callee r5
673   raw_context.iregs[6] = 0xac2079e8;  // distinct callee r6
674   raw_context.iregs[7] = 0xa449829f;  // distinct callee r7
675   raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0xbe145fc4; // distinct callee fp
676   CheckWalk();
677 }
678 
TEST_F(CFI,At4003)679 TEST_F(CFI, At4003) {
680   Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
681   stack_section
682     .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
683     .D32(0xcb78040e)            // no longer saved r4
684     .D32(0x8112e110)            // saved fp
685     .D32(0x40005510)            // return address
686     .Mark(&frame1_sp);          // This effectively sets stack_section.start().
687   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004003;
688   raw_context.iregs[1] = 0xfb756319;                     // distinct callee r1
689   raw_context.iregs[MD_CONTEXT_ARM_REG_FP] = 0x0a2857ea; // distinct callee fp
690   expected.iregs[1] = 0x48c8dd5a;    // caller's r1
691   expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
692   CheckWalk();
693 }
694 
695 // We have no new rule at module offset 0x4004, so the results here should
696 // be the same as those at module offset 0x4003.
TEST_F(CFI,At4004)697 TEST_F(CFI, At4004) {
698   Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
699   stack_section
700     .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
701     .D32(0xcb78040e)            // no longer saved r4
702     .D32(0x8112e110)            // saved fp
703     .D32(0x40005510)            // return address
704     .Mark(&frame1_sp);          // This effectively sets stack_section.start().
705   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004004;
706   raw_context.iregs[1] = 0xfb756319; // distinct callee r1
707   expected.iregs[1] = 0x48c8dd5a; // caller's r1
708   expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
709   CheckWalk();
710 }
711 
712 // Here we move the .cfa, but provide an explicit rule to recover the SP,
713 // so again there should be no change in the registers recovered.
TEST_F(CFI,At4005)714 TEST_F(CFI, At4005) {
715   Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
716   stack_section
717     .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
718     .D32(0xf013f841)            // no longer saved r4
719     .D32(0x8112e110)            // saved fp
720     .D32(0x40005510)            // return address
721     .Mark(&frame1_sp);          // This effectively sets stack_section.start().
722   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004005;
723   raw_context.iregs[1] = 0xfb756319; // distinct callee r1
724   expected.iregs[1] = 0x48c8dd5a; // caller's r1
725   expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
726   CheckWalk();
727 }
728 
729 // Here we provide an explicit rule for the PC, and have the saved .ra be
730 // bogus.
TEST_F(CFI,At4006)731 TEST_F(CFI, At4006) {
732   Label frame1_sp = expected.iregs[MD_CONTEXT_ARM_REG_SP];
733   stack_section
734     .D32(0x40005510)            // saved pc
735     .D32(0x48c8dd5a)            // saved r1 (even though it's not callee-saves)
736     .D32(0xf013f841)            // no longer saved r4
737     .D32(0x8112e110)            // saved fp
738     .D32(0xf8d15783)            // .ra rule recovers this, which is garbage
739     .Mark(&frame1_sp);          // This effectively sets stack_section.start().
740   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40004006;
741   raw_context.iregs[1] = 0xfb756319; // callee's r1, different from caller's
742   expected.iregs[1] = 0x48c8dd5a; // caller's r1
743   expected_validity |= StackFrameARM::CONTEXT_VALID_R1;
744   CheckWalk();
745 }
746 
747 // Check that we reject rules that would cause the stack pointer to
748 // move in the wrong direction.
TEST_F(CFI,RejectBackwards)749 TEST_F(CFI, RejectBackwards) {
750   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40006000;
751   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
752   raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = 0x40005510;
753   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
754   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
755                         &frame_symbolizer);
756   vector<const CodeModule*> modules_without_symbols;
757   vector<const CodeModule*> modules_with_corrupt_symbols;
758   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
759                           &modules_with_corrupt_symbols));
760   ASSERT_EQ(0U, modules_without_symbols.size());
761   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
762   frames = call_stack.frames();
763   ASSERT_EQ(1U, frames->size());
764 }
765 
766 // Check that we reject rules whose expressions' evaluation fails.
TEST_F(CFI,RejectBadExpressions)767 TEST_F(CFI, RejectBadExpressions) {
768   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40007000;
769   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = 0x80000000;
770   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
771   StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules,
772                         &frame_symbolizer);
773   vector<const CodeModule*> modules_without_symbols;
774   vector<const CodeModule*> modules_with_corrupt_symbols;
775   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
776                           &modules_with_corrupt_symbols));
777   ASSERT_EQ(0U, modules_without_symbols.size());
778   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
779   frames = call_stack.frames();
780   ASSERT_EQ(1U, frames->size());
781 }
782 
783 class StackwalkerARMFixtureIOS : public StackwalkerARMFixture {
784  public:
StackwalkerARMFixtureIOS()785   StackwalkerARMFixtureIOS() {
786     // iOS_test is used instead of iOS because the stackwalker has a check to
787     // avoid using CFI for iOS dumps. This is a workaround for bad CFI being
788     // produced by dump_syms for iOS.
789     // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=764
790     system_info.os = "iOS_test";
791     system_info.os_short = "ios_test";
792   }
793 };
794 
795 class GetFramesByFramePointer: public StackwalkerARMFixtureIOS, public Test { };
796 
TEST_F(GetFramesByFramePointer,OnlyFramePointer)797 TEST_F(GetFramesByFramePointer, OnlyFramePointer) {
798   stack_section.start() = 0x80000000;
799   uint32_t return_address1 = 0x50000100;
800   uint32_t return_address2 = 0x50000900;
801   Label frame1_sp, frame2_sp;
802   Label frame1_fp, frame2_fp;
803   stack_section
804     // frame 0
805     .Append(32, 0)           // Whatever values on the stack.
806     .D32(0x0000000D)         // junk that's not
807     .D32(0xF0000000)         // a return address.
808 
809     .Mark(&frame1_fp)        // Next fp will point to the next value.
810     .D32(frame2_fp)          // Save current frame pointer.
811     .D32(return_address2)    // Save current link register.
812     .Mark(&frame1_sp)
813 
814     // frame 1
815     .Append(32, 0)           // Whatever values on the stack.
816     .D32(0x0000000D)         // junk that's not
817     .D32(0xF0000000)         // a return address.
818 
819     .Mark(&frame2_fp)
820     .D32(0)
821     .D32(0)
822     .Mark(&frame2_sp)
823 
824     // frame 2
825     .Append(32, 0)           // Whatever values on the stack.
826     .D32(0x0000000D)         // junk that's not
827     .D32(0xF0000000);        // a return address.
828   RegionFromSection();
829 
830 
831   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x40005510;
832   raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1;
833   raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
834   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
835 
836   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
837   StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
838                         &stack_region, &modules, &frame_symbolizer);
839 
840   vector<const CodeModule*> modules_without_symbols;
841   vector<const CodeModule*> modules_with_corrupt_symbols;
842   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
843                           &modules_with_corrupt_symbols));
844   ASSERT_EQ(2U, modules_without_symbols.size());
845   ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
846   ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
847   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
848   frames = call_stack.frames();
849   ASSERT_EQ(3U, frames->size());
850 
851   StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
852   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
853   ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
854   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
855 
856   StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
857   EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
858   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
859              StackFrameARM::CONTEXT_VALID_LR |
860              StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
861              StackFrameARM::CONTEXT_VALID_SP),
862             frame1->context_validity);
863   EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
864   EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]);
865   EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
866   EXPECT_EQ(frame2_fp.Value(),
867             frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
868 
869   StackFrameARM *frame2 = static_cast<StackFrameARM *>(frames->at(2));
870   EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame2->trust);
871   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
872              StackFrameARM::CONTEXT_VALID_LR |
873              StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
874              StackFrameARM::CONTEXT_VALID_SP),
875             frame2->context_validity);
876   EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
877   EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]);
878   EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
879   EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
880 }
881 
TEST_F(GetFramesByFramePointer,FramePointerAndCFI)882 TEST_F(GetFramesByFramePointer, FramePointerAndCFI) {
883   // Provide the standatd STACK CFI records that is obtained when exmining an
884   // executable produced by XCode.
885   SetModuleSymbols(&module1,
886                      // Adding a function in CFI.
887                      "FUNC 4000 1000 10 enchiridion\n"
888 
889                      "STACK CFI INIT 4000 100 .cfa: sp 0 + .ra: lr\n"
890                      "STACK CFI 4001 .cfa: sp 8 + .ra: .cfa -4 + ^"
891                      " r7: .cfa -8 + ^\n"
892                      "STACK CFI 4002 .cfa: r7 8 +\n"
893                   );
894 
895   stack_section.start() = 0x80000000;
896   uint32_t return_address1 = 0x40004010;
897   uint32_t return_address2 = 0x50000900;
898   Label frame1_sp, frame2_sp;
899   Label frame1_fp, frame2_fp;
900   stack_section
901     // frame 0
902     .Append(32, 0)           // Whatever values on the stack.
903     .D32(0x0000000D)         // junk that's not
904     .D32(0xF0000000)         // a return address.
905 
906     .Mark(&frame1_fp)        // Next fp will point to the next value.
907     .D32(frame2_fp)          // Save current frame pointer.
908     .D32(return_address2)    // Save current link register.
909     .Mark(&frame1_sp)
910 
911     // frame 1
912     .Append(32, 0)           // Whatever values on the stack.
913     .D32(0x0000000D)         // junk that's not
914     .D32(0xF0000000)         // a return address.
915 
916     .Mark(&frame2_fp)
917     .D32(0)
918     .D32(0)
919     .Mark(&frame2_sp)
920 
921     // frame 2
922     .Append(32, 0)           // Whatever values on the stack.
923     .D32(0x0000000D)         // junk that's not
924     .D32(0xF0000000);        // a return address.
925   RegionFromSection();
926 
927 
928   raw_context.iregs[MD_CONTEXT_ARM_REG_PC] = 0x50000400;
929   raw_context.iregs[MD_CONTEXT_ARM_REG_LR] = return_address1;
930   raw_context.iregs[MD_CONTEXT_ARM_REG_IOS_FP] = frame1_fp.Value();
931   raw_context.iregs[MD_CONTEXT_ARM_REG_SP] = stack_section.start().Value();
932 
933   StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
934   StackwalkerARM walker(&system_info, &raw_context, MD_CONTEXT_ARM_REG_IOS_FP,
935                         &stack_region, &modules, &frame_symbolizer);
936 
937   vector<const CodeModule*> modules_without_symbols;
938   vector<const CodeModule*> modules_with_corrupt_symbols;
939   ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
940                           &modules_with_corrupt_symbols));
941   ASSERT_EQ(1U, modules_without_symbols.size());
942   ASSERT_EQ("module2", modules_without_symbols[0]->debug_file());
943   ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
944   frames = call_stack.frames();
945   ASSERT_EQ(3U, frames->size());
946 
947   StackFrameARM *frame0 = static_cast<StackFrameARM *>(frames->at(0));
948   EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
949   ASSERT_EQ(StackFrameARM::CONTEXT_VALID_ALL, frame0->context_validity);
950   EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
951 
952   StackFrameARM *frame1 = static_cast<StackFrameARM *>(frames->at(1));
953   EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
954   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
955              StackFrameARM::CONTEXT_VALID_LR |
956              StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
957              StackFrameARM::CONTEXT_VALID_SP),
958             frame1->context_validity);
959   EXPECT_EQ(return_address1, frame1->context.iregs[MD_CONTEXT_ARM_REG_PC]);
960   EXPECT_EQ(return_address2, frame1->context.iregs[MD_CONTEXT_ARM_REG_LR]);
961   EXPECT_EQ(frame1_sp.Value(), frame1->context.iregs[MD_CONTEXT_ARM_REG_SP]);
962   EXPECT_EQ(frame2_fp.Value(),
963             frame1->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
964   EXPECT_EQ("enchiridion", frame1->function_name);
965   EXPECT_EQ(0x40004000U, frame1->function_base);
966 
967 
968   StackFrameARM *frame2 = static_cast<StackFrameARM *>(frames->at(2));
969   EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
970   ASSERT_EQ((StackFrameARM::CONTEXT_VALID_PC |
971              StackFrameARM::CONTEXT_VALID_LR |
972              StackFrameARM::RegisterValidFlag(MD_CONTEXT_ARM_REG_IOS_FP) |
973              StackFrameARM::CONTEXT_VALID_SP),
974             frame2->context_validity);
975   EXPECT_EQ(return_address2, frame2->context.iregs[MD_CONTEXT_ARM_REG_PC]);
976   EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_LR]);
977   EXPECT_EQ(frame2_sp.Value(), frame2->context.iregs[MD_CONTEXT_ARM_REG_SP]);
978   EXPECT_EQ(0U, frame2->context.iregs[MD_CONTEXT_ARM_REG_IOS_FP]);
979 }
980