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