xref: /aosp_15_r20/external/google-breakpad/src/processor/stackwalker_arm_unittest.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
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 <[email protected]> <[email protected]>
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:
StackwalkerARMFixture()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.
SetModuleSymbols(MockCodeModule * module,const string & info)112   void SetModuleSymbols(MockCodeModule* module, const string& info) {
113     size_t buffer_size;
114     char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size);
115     EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _))
116       .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
117                             SetArgumentPointee<4>(buffer_size),
118                             Return(MockSymbolSupplier::FOUND)));
119   }
120 
121   // Populate stack_region with the contents of stack_section. Use
122   // stack_section.start() as the region's starting address.
RegionFromSection()123   void RegionFromSection() {
124     string contents;
125     ASSERT_TRUE(stack_section.GetContents(&contents));
126     stack_region.Init(stack_section.start().Value(), contents);
127   }
128 
129   // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
BrandContext(MDRawContextARM * raw_context)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 
TEST_F(SanityCheck,NoResolver)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 
TEST_F(GetContextFrame,Simple)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.
TEST_F(GetContextFrame,NoStackMemory)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 
TEST_F(GetCallerFrame,ScanWithoutSymbols)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 
TEST_F(GetCallerFrame,ScanWithFunctionSymbols)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 
TEST_F(GetCallerFrame,ScanFirstFrame)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.
TEST_F(GetCallerFrame,ScanningNotAllowed)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 {
CFIFixtureCFIFixture473   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'.
CheckWalkCFIFixture554   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 
TEST_F(CFI,At4000)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 
TEST_F(CFI,At4001)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.
TEST_F(CFI,At4001LimitedValidity)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 
TEST_F(CFI,At4002)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 
TEST_F(CFI,At4003)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.
TEST_F(CFI,At4004)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.
TEST_F(CFI,At4005)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.
TEST_F(CFI,At4006)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.
TEST_F(CFI,RejectBackwards)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.
TEST_F(CFI,RejectBadExpressions)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:
StackwalkerARMFixtureIOS()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 
TEST_F(GetFramesByFramePointer,OnlyFramePointer)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 
TEST_F(GetFramesByFramePointer,FramePointerAndCFI)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 }
983