toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm_unittest.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial