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