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