Home | History | Annotate | Download | only in processor
      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 (at) mozilla.com> <jimb (at) red-bean.com>
     31 
     32 // stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class.
     33 
     34 #include <string.h>
     35 #include <string>
     36 #include <vector>
     37 
     38 #include "breakpad_googletest_includes.h"
     39 #include "common/test_assembler.h"
     40 #include "common/using_std_string.h"
     41 #include "google_breakpad/common/minidump_format.h"
     42 #include "google_breakpad/processor/basic_source_line_resolver.h"
     43 #include "google_breakpad/processor/call_stack.h"
     44 #include "google_breakpad/processor/code_module.h"
     45 #include "google_breakpad/processor/source_line_resolver_interface.h"
     46 #include "google_breakpad/processor/stack_frame_cpu.h"
     47 #include "processor/stackwalker_unittest_utils.h"
     48 #include "processor/stackwalker_arm.h"
     49 #include "processor/windows_frame_info.h"
     50 
     51 using google_breakpad::BasicSourceLineResolver;
     52 using google_breakpad::CallStack;
     53 using google_breakpad::CodeModule;
     54 using google_breakpad::StackFrameSymbolizer;
     55 using google_breakpad::StackFrame;
     56 using google_breakpad::StackFrameARM;
     57 using google_breakpad::Stackwalker;
     58 using google_breakpad::StackwalkerARM;
     59 using google_breakpad::SystemInfo;
     60 using google_breakpad::WindowsFrameInfo;
     61 using google_breakpad::test_assembler::kLittleEndian;
     62 using google_breakpad::test_assembler::Label;
     63 using google_breakpad::test_assembler::Section;
     64 using std::vector;
     65 using testing::_;
     66 using testing::AnyNumber;
     67 using testing::Return;
     68 using testing::SetArgumentPointee;
     69 using testing::Test;
     70 
     71 class 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 
    145 class SanityCheck: public StackwalkerARMFixture, public Test { };
    146 
    147 TEST_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 
    169 class GetContextFrame: public StackwalkerARMFixture, public Test { };
    170 
    171 TEST_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.
    194 TEST_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 
    212 class GetCallerFrame: public StackwalkerARMFixture, public Test { };
    213 
    214 TEST_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 
    284 TEST_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 
    349 TEST_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.
    415 TEST_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 
    468 struct 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 
    617 class CFI: public CFIFixture, public Test { };
    618 
    619 TEST_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 
    626 TEST_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.
    640 TEST_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 
    658 TEST_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 
    678 TEST_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.
    696 TEST_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.
    713 TEST_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.
    730 TEST_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.
    748 TEST_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.
    766 TEST_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 
    782 class StackwalkerARMFixtureIOS : public StackwalkerARMFixture {
    783  public:
    784   StackwalkerARMFixtureIOS() {
    785     system_info.os = "iOS";
    786     system_info.os_short = "ios";
    787   }
    788 };
    789 
    790 class GetFramesByFramePointer: public StackwalkerARMFixtureIOS, public Test { };
    791 
    792 TEST_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 
    877 TEST_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