1 // Copyright (c) 2010, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
31
32 // stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class.
33
34 #include <string.h>
35 #include <string>
36 #include <vector>
37
38 #include "breakpad_googletest_includes.h"
39 #include "common/test_assembler.h"
40 #include "common/using_std_string.h"
41 #include "google_breakpad/common/minidump_format.h"
42 #include "google_breakpad/processor/basic_source_line_resolver.h"
43 #include "google_breakpad/processor/call_stack.h"
44 #include "google_breakpad/processor/code_module.h"
45 #include "google_breakpad/processor/source_line_resolver_interface.h"
46 #include "google_breakpad/processor/stack_frame_cpu.h"
47 #include "processor/stackwalker_unittest_utils.h"
48 #include "processor/stackwalker_arm.h"
49 #include "processor/windows_frame_info.h"
50
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:
StackwalkerARMFixture()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.
SetModuleSymbols(MockCodeModule * module,const string & 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.
RegionFromSection()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.
BrandContext(MDRawContextARM * raw_context)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
TEST_F(SanityCheck,NoResolver)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
TEST_F(GetContextFrame,Simple)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.
TEST_F(GetContextFrame,NoStackMemory)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
TEST_F(GetCallerFrame,ScanWithoutSymbols)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
TEST_F(GetCallerFrame,ScanWithFunctionSymbols)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
TEST_F(GetCallerFrame,ScanFirstFrame)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.
TEST_F(GetCallerFrame,ScanningNotAllowed)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 {
CFIFixtureCFIFixture469 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'.
CheckWalkCFIFixture550 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
TEST_F(CFI,At4000)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
TEST_F(CFI,At4001)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.
TEST_F(CFI,At4001LimitedValidity)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
TEST_F(CFI,At4002)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
TEST_F(CFI,At4003)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.
TEST_F(CFI,At4004)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.
TEST_F(CFI,At4005)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.
TEST_F(CFI,At4006)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.
TEST_F(CFI,RejectBackwards)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.
TEST_F(CFI,RejectBadExpressions)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:
StackwalkerARMFixtureIOS()784 StackwalkerARMFixtureIOS() {
785 system_info.os = "iOS";
786 system_info.os_short = "ios";
787 }
788 };
789
790 class GetFramesByFramePointer: public StackwalkerARMFixtureIOS, public Test { };
791
TEST_F(GetFramesByFramePointer,OnlyFramePointer)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
TEST_F(GetFramesByFramePointer,FramePointerAndCFI)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