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