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