stackwalker_x86_unittest.cc revision 3108b9dd7bbac28dd01d78f9264fe494ee9c95a0
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_x86_unittest.cc: Unit tests for StackwalkerX86 class.
33
34#include <string>
35#include <vector>
36
37#include "breakpad_googletest_includes.h"
38#include "common/test_assembler.h"
39#include "common/using_std_string.h"
40#include "google_breakpad/common/minidump_format.h"
41#include "google_breakpad/processor/basic_source_line_resolver.h"
42#include "google_breakpad/processor/call_stack.h"
43#include "google_breakpad/processor/source_line_resolver_interface.h"
44#include "google_breakpad/processor/stack_frame_cpu.h"
45#include "processor/stackwalker_unittest_utils.h"
46#include "processor/stackwalker_x86.h"
47#include "processor/windows_frame_info.h"
48
49using google_breakpad::BasicSourceLineResolver;
50using google_breakpad::CallStack;
51using google_breakpad::StackFrameSymbolizer;
52using google_breakpad::StackFrame;
53using google_breakpad::StackFrameX86;
54using google_breakpad::StackwalkerX86;
55using google_breakpad::SystemInfo;
56using google_breakpad::WindowsFrameInfo;
57using google_breakpad::test_assembler::kLittleEndian;
58using google_breakpad::test_assembler::Label;
59using google_breakpad::test_assembler::Section;
60using std::vector;
61using testing::_;
62using testing::Return;
63using testing::SetArgumentPointee;
64using testing::Test;
65
66class StackwalkerX86Fixture {
67 public:
68  StackwalkerX86Fixture()
69    : stack_section(kLittleEndian),
70      // Give the two modules reasonable standard locations and names
71      // for tests to play with.
72      module1(0x40000000, 0x10000, "module1", "version1"),
73      module2(0x50000000, 0x10000, "module2", "version2"),
74      module3(0x771d0000, 0x180000, "module3", "version3"),
75      module4(0x75f90000, 0x46000, "module4", "version4"),
76      module5(0x75730000, 0x110000, "module5", "version5"),
77      module6(0x647f0000, 0x1ba8000, "module6", "version6") {
78    // Identify the system as a Linux system.
79    system_info.os = "Linux";
80    system_info.os_short = "linux";
81    system_info.os_version = "Salacious Skink";
82    system_info.cpu = "x86";
83    system_info.cpu_info = "";
84
85    // Put distinctive values in the raw CPU context.
86    BrandContext(&raw_context);
87
88    // Create some modules with some stock debugging information.
89    modules.Add(&module1);
90    modules.Add(&module2);
91    modules.Add(&module3);
92    modules.Add(&module4);
93    modules.Add(&module5);
94    modules.Add(&module6);
95
96    // By default, none of the modules have symbol info; call
97    // SetModuleSymbols to override this.
98    EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _))
99      .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
100  }
101
102  // Set the Breakpad symbol information that supplier should return for
103  // MODULE to INFO.
104  void SetModuleSymbols(MockCodeModule *module, const string &info) {
105    char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info);
106    EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _))
107      .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
108                            Return(MockSymbolSupplier::FOUND)));
109  }
110
111  // Populate stack_region with the contents of stack_section. Use
112  // stack_section.start() as the region's starting address.
113  void RegionFromSection() {
114    string contents;
115    ASSERT_TRUE(stack_section.GetContents(&contents));
116    stack_region.Init(stack_section.start().Value(), contents);
117  }
118
119  // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
120  void BrandContext(MDRawContextX86 *raw_context) {
121    u_int8_t x = 173;
122    for (size_t i = 0; i < sizeof(*raw_context); i++)
123      reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
124  }
125
126  SystemInfo system_info;
127  MDRawContextX86 raw_context;
128  Section stack_section;
129  MockMemoryRegion stack_region;
130  MockCodeModule module1;
131  MockCodeModule module2;
132  MockCodeModule module3;
133  MockCodeModule module4;
134  MockCodeModule module5;
135  MockCodeModule module6;
136  MockCodeModules modules;
137  MockSymbolSupplier supplier;
138  BasicSourceLineResolver resolver;
139  CallStack call_stack;
140  const vector<StackFrame *> *frames;
141};
142
143class SanityCheck: public StackwalkerX86Fixture, public Test { };
144
145TEST_F(SanityCheck, NoResolver) {
146  stack_section.start() = 0x80000000;
147  stack_section.D32(0).D32(0); // end-of-stack marker
148  RegionFromSection();
149  raw_context.eip = 0x40000200;
150  raw_context.ebp = 0x80000000;
151
152  StackFrameSymbolizer frame_symbolizer(NULL, NULL);
153  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
154                        &frame_symbolizer);
155  // This should succeed, even without a resolver or supplier.
156  ASSERT_TRUE(walker.Walk(&call_stack));
157  frames = call_stack.frames();
158  StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
159  // Check that the values from the original raw context made it
160  // through to the context in the stack frame.
161  EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
162}
163
164class GetContextFrame: public StackwalkerX86Fixture, public Test { };
165
166TEST_F(GetContextFrame, Simple) {
167  stack_section.start() = 0x80000000;
168  stack_section.D32(0).D32(0); // end-of-stack marker
169  RegionFromSection();
170  raw_context.eip = 0x40000200;
171  raw_context.ebp = 0x80000000;
172
173  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
174  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
175                        &frame_symbolizer);
176  ASSERT_TRUE(walker.Walk(&call_stack));
177  frames = call_stack.frames();
178  StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
179  // Check that the values from the original raw context made it
180  // through to the context in the stack frame.
181  EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
182}
183
184class GetCallerFrame: public StackwalkerX86Fixture, public Test { };
185
186// Walk a traditional frame. A traditional frame saves the caller's
187// %ebp just below the return address, and has its own %ebp pointing
188// at the saved %ebp.
189TEST_F(GetCallerFrame, Traditional) {
190  stack_section.start() = 0x80000000;
191  Label frame0_ebp, frame1_ebp;
192  stack_section
193    .Append(12, 0)                      // frame 0: space
194    .Mark(&frame0_ebp)                  // frame 0 %ebp points here
195    .D32(frame1_ebp)                    // frame 0: saved %ebp
196    .D32(0x40008679)                    // frame 0: return address
197    .Append(8, 0)                       // frame 1: space
198    .Mark(&frame1_ebp)                  // frame 1 %ebp points here
199    .D32(0)                             // frame 1: saved %ebp (stack end)
200    .D32(0);                            // frame 1: return address (stack end)
201  RegionFromSection();
202  raw_context.eip = 0x4000c7a5;
203  raw_context.esp = stack_section.start().Value();
204  raw_context.ebp = frame0_ebp.Value();
205
206  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
207  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
208                        &frame_symbolizer);
209  ASSERT_TRUE(walker.Walk(&call_stack));
210  frames = call_stack.frames();
211  ASSERT_EQ(2U, frames->size());
212
213  {  // To avoid reusing locals by mistake
214    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
215    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
216    EXPECT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
217    EXPECT_EQ(0x4000c7a5U, frame0->instruction);
218    EXPECT_EQ(0x4000c7a5U, frame0->context.eip);
219    EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
220    EXPECT_EQ(NULL, frame0->windows_frame_info);
221  }
222
223  {  // To avoid reusing locals by mistake
224    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
225    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
226    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
227               | StackFrameX86::CONTEXT_VALID_ESP
228               | StackFrameX86::CONTEXT_VALID_EBP),
229              frame1->context_validity);
230    EXPECT_EQ(0x40008679U, frame1->instruction + 1);
231    EXPECT_EQ(0x40008679U, frame1->context.eip);
232    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
233    EXPECT_EQ(NULL, frame1->windows_frame_info);
234  }
235}
236
237// Walk a traditional frame, but use a bogus %ebp value, forcing a scan
238// of the stack for something that looks like a return address.
239TEST_F(GetCallerFrame, TraditionalScan) {
240  stack_section.start() = 0x80000000;
241  Label frame1_ebp;
242  stack_section
243    // frame 0
244    .D32(0xf065dc76)    // locals area:
245    .D32(0x46ee2167)    // garbage that doesn't look like
246    .D32(0xbab023ec)    // a return address
247    .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
248    .D32(0x4000129d)    // return address
249    // frame 1
250    .Append(8, 0)       // space
251    .Mark(&frame1_ebp)  // %ebp points here
252    .D32(0)             // saved %ebp (stack end)
253    .D32(0);            // return address (stack end)
254
255  RegionFromSection();
256  raw_context.eip = 0x4000f49d;
257  raw_context.esp = stack_section.start().Value();
258  // Make the frame pointer bogus, to make the stackwalker scan the stack
259  // for something that looks like a return address.
260  raw_context.ebp = 0xd43eed6e;
261
262  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
263  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
264                        &frame_symbolizer);
265  ASSERT_TRUE(walker.Walk(&call_stack));
266  frames = call_stack.frames();
267  ASSERT_EQ(2U, frames->size());
268
269  {  // To avoid reusing locals by mistake
270    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
271    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
272    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
273    EXPECT_EQ(0x4000f49dU, frame0->instruction);
274    EXPECT_EQ(0x4000f49dU, frame0->context.eip);
275    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
276    EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
277    EXPECT_EQ(NULL, frame0->windows_frame_info);
278  }
279
280  {  // To avoid reusing locals by mistake
281    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
282    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
283    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
284    // walker does not actually fetch the EBP after a scan (forcing the
285    // next frame to be scanned as well). But let's grandfather the existing
286    // behavior in for now.
287    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
288               | StackFrameX86::CONTEXT_VALID_ESP
289               | StackFrameX86::CONTEXT_VALID_EBP),
290              frame1->context_validity);
291    EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
292    EXPECT_EQ(0x4000129dU, frame1->context.eip);
293    EXPECT_EQ(0x80000014U, frame1->context.esp);
294    EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
295    EXPECT_EQ(NULL, frame1->windows_frame_info);
296  }
297}
298
299// Force scanning for a return address a long way down the stack
300TEST_F(GetCallerFrame, TraditionalScanLongWay) {
301  stack_section.start() = 0x80000000;
302  Label frame1_ebp;
303  stack_section
304    // frame 0
305    .D32(0xf065dc76)    // locals area:
306    .D32(0x46ee2167)    // garbage that doesn't look like
307    .D32(0xbab023ec)    // a return address
308    .Append(20 * 4, 0)  // a bunch of space
309    .D32(frame1_ebp)    // saved %ebp (%ebp fails to point here, forcing scan)
310    .D32(0x4000129d)    // return address
311    // frame 1
312    .Append(8, 0)       // space
313    .Mark(&frame1_ebp)  // %ebp points here
314    .D32(0)             // saved %ebp (stack end)
315    .D32(0);            // return address (stack end)
316
317  RegionFromSection();
318  raw_context.eip = 0x4000f49d;
319  raw_context.esp = stack_section.start().Value();
320  // Make the frame pointer bogus, to make the stackwalker scan the stack
321  // for something that looks like a return address.
322  raw_context.ebp = 0xd43eed6e;
323
324  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
325  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
326                        &frame_symbolizer);
327  ASSERT_TRUE(walker.Walk(&call_stack));
328  frames = call_stack.frames();
329  ASSERT_EQ(2U, frames->size());
330
331  {  // To avoid reusing locals by mistake
332    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
333    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
334    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
335    EXPECT_EQ(0x4000f49dU, frame0->instruction);
336    EXPECT_EQ(0x4000f49dU, frame0->context.eip);
337    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
338    EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
339    EXPECT_EQ(NULL, frame0->windows_frame_info);
340  }
341
342  {  // To avoid reusing locals by mistake
343    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
344    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
345    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
346    // walker does not actually fetch the EBP after a scan (forcing the
347    // next frame to be scanned as well). But let's grandfather the existing
348    // behavior in for now.
349    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
350               | StackFrameX86::CONTEXT_VALID_ESP
351               | StackFrameX86::CONTEXT_VALID_EBP),
352              frame1->context_validity);
353    EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
354    EXPECT_EQ(0x4000129dU, frame1->context.eip);
355    EXPECT_EQ(0x80000064U, frame1->context.esp);
356    EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
357    EXPECT_EQ(NULL, frame1->windows_frame_info);
358  }
359}
360
361// Use Windows frame data (a "STACK WIN 4" record, from a
362// FrameTypeFrameData DIA record) to walk a stack frame.
363TEST_F(GetCallerFrame, WindowsFrameData) {
364  SetModuleSymbols(&module1,
365                   "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
366                   " $T2 $esp .cbSavedRegs + ="
367                   " $T0 .raSearchStart ="
368                   " $eip $T0 ^ ="
369                   " $esp $T0 4 + ="
370                   " $ebx $T2 4  - ^ ="
371                   " $edi $T2 8  - ^ ="
372                   " $esi $T2 12 - ^ ="
373                   " $ebp $T2 16 - ^ =\n");
374  Label frame1_esp, frame1_ebp;
375  stack_section.start() = 0x80000000;
376  stack_section
377    // frame 0
378    .D32(frame1_ebp)                    // saved regs: %ebp
379    .D32(0xa7120d1a)                    //             %esi
380    .D32(0x630891be)                    //             %edi
381    .D32(0x9068a878)                    //             %ebx
382    .D32(0xa08ea45f)                    // locals: unused
383    .D32(0x40001350)                    // return address
384    // frame 1
385    .Mark(&frame1_esp)
386    .Append(12, 0)                      // empty space
387    .Mark(&frame1_ebp)
388    .D32(0)                             // saved %ebp (stack end)
389    .D32(0);                            // saved %eip (stack end)
390
391  RegionFromSection();
392  raw_context.eip = 0x4000aa85;
393  raw_context.esp = stack_section.start().Value();
394  raw_context.ebp = 0xf052c1de;         // should not be needed to walk frame
395
396  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
397  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
398                        &frame_symbolizer);
399  ASSERT_TRUE(walker.Walk(&call_stack));
400  frames = call_stack.frames();
401  ASSERT_EQ(2U, frames->size());
402
403  {  // To avoid reusing locals by mistake
404    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
405    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
406    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
407    EXPECT_EQ(0x4000aa85U, frame0->instruction);
408    EXPECT_EQ(0x4000aa85U, frame0->context.eip);
409    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
410    EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
411    EXPECT_TRUE(frame0->windows_frame_info != NULL);
412  }
413
414  {  // To avoid reusing locals by mistake
415    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
416    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
417    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
418               | StackFrameX86::CONTEXT_VALID_ESP
419               | StackFrameX86::CONTEXT_VALID_EBP
420               | StackFrameX86::CONTEXT_VALID_EBX
421               | StackFrameX86::CONTEXT_VALID_ESI
422               | StackFrameX86::CONTEXT_VALID_EDI),
423              frame1->context_validity);
424    EXPECT_EQ(0x40001350U, frame1->instruction + 1);
425    EXPECT_EQ(0x40001350U, frame1->context.eip);
426    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
427    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
428    EXPECT_EQ(0x9068a878U, frame1->context.ebx);
429    EXPECT_EQ(0xa7120d1aU, frame1->context.esi);
430    EXPECT_EQ(0x630891beU, frame1->context.edi);
431    EXPECT_EQ(NULL, frame1->windows_frame_info);
432  }
433}
434
435// Use Windows frame data (a "STACK WIN 4" record, from a
436// FrameTypeFrameData DIA record) to walk a stack frame where the stack
437// is aligned and we must search
438TEST_F(GetCallerFrame, WindowsFrameDataAligned) {
439  SetModuleSymbols(&module1,
440                   "STACK WIN 4 aa85 176 0 0 4 4 8 0 1"
441		   " $T1 .raSearch ="
442		   " $T0 $T1 4 - 8 @ ="
443		   " $ebp $T1 4 - ^ ="
444		   " $eip $T1 ^ ="
445		   " $esp $T1 4 + =");
446  Label frame1_esp, frame1_ebp;
447  stack_section.start() = 0x80000000;
448  stack_section
449    // frame 0
450    .D32(0x0ffa0ffa)                    // unused saved register
451    .D32(0xdeaddead)                    // locals
452    .D32(0xbeefbeef)
453    .D32(0)                             // 8-byte alignment
454    .D32(frame1_ebp)
455    .D32(0x5000129d)                    // return address
456    // frame 1
457    .Mark(&frame1_esp)
458    .D32(0x1)                           // parameter
459    .Mark(&frame1_ebp)
460    .D32(0)                             // saved %ebp (stack end)
461    .D32(0);                            // saved %eip (stack end)
462
463  RegionFromSection();
464  raw_context.eip = 0x4000aa85;
465  raw_context.esp = stack_section.start().Value();
466  raw_context.ebp = 0xf052c1de;         // should not be needed to walk frame
467
468  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
469  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
470                        &frame_symbolizer);
471  ASSERT_TRUE(walker.Walk(&call_stack));
472  frames = call_stack.frames();
473  ASSERT_EQ(2U, frames->size());
474
475  {  // To avoid reusing locals by mistake
476    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
477    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
478    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
479    EXPECT_EQ(0x4000aa85U, frame0->instruction);
480    EXPECT_EQ(0x4000aa85U, frame0->context.eip);
481    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
482    EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
483    EXPECT_TRUE(frame0->windows_frame_info != NULL);
484  }
485
486  {  // To avoid reusing locals by mistake
487    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
488    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
489    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
490               | StackFrameX86::CONTEXT_VALID_ESP
491               | StackFrameX86::CONTEXT_VALID_EBP),
492              frame1->context_validity);
493    EXPECT_EQ(0x5000129dU, frame1->instruction + 1);
494    EXPECT_EQ(0x5000129dU, frame1->context.eip);
495    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
496    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
497    EXPECT_EQ(NULL, frame1->windows_frame_info);
498  }
499}
500
501// Use Windows frame data (a "STACK WIN 4" record, from a
502// FrameTypeFrameData DIA record) to walk a frame, and depend on the
503// parameter size from the callee as well.
504TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) {
505  SetModuleSymbols(&module1, "FUNC 1000 100 c module1::wheedle\n");
506  SetModuleSymbols(&module2,
507                   // Note bogus parameter size in FUNC record; the stack walker
508                   // should prefer the STACK WIN record, and see '4' below.
509                   "FUNC aa85 176 beef module2::whine\n"
510                   "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
511                   " $T2 $esp .cbLocals + .cbSavedRegs + ="
512                   " $T0 .raSearchStart ="
513                   " $eip $T0 ^ ="
514                   " $esp $T0 4 + ="
515                   " $ebp $T0 20 - ^ ="
516                   " $ebx $T0 8 - ^ =\n");
517  Label frame0_esp, frame0_ebp;
518  Label frame1_esp;
519  Label frame2_esp, frame2_ebp;
520  stack_section.start() = 0x80000000;
521  stack_section
522    // frame 0, in module1::wheedle.  Traditional frame.
523    .Mark(&frame0_esp)
524    .Append(16, 0)      // frame space
525    .Mark(&frame0_ebp)
526    .D32(0x6fa902e0)    // saved %ebp.  Not a frame pointer.
527    .D32(0x5000aa95)    // return address, in module2::whine
528    // frame 1, in module2::whine.  FrameData frame.
529    .Mark(&frame1_esp)
530    .D32(0xbaa0cb7a)    // argument 3 passed to module1::wheedle
531    .D32(0xbdc92f9f)    // argument 2
532    .D32(0x0b1d8442)    // argument 1
533    .D32(frame2_ebp)    // saved %ebp
534    .D32(0xb1b90a15)    // unused
535    .D32(0xf18e072d)    // unused
536    .D32(0x2558c7f3)    // saved %ebx
537    .D32(0x0365e25e)    // unused
538    .D32(0x2a179e38)    // return address; $T0 points here
539    // frame 2, in no module
540    .Mark(&frame2_esp)
541    .Append(12, 0)      // empty space
542    .Mark(&frame2_ebp)
543    .D32(0)             // saved %ebp (stack end)
544    .D32(0);            // saved %eip (stack end)
545
546  RegionFromSection();
547  raw_context.eip = 0x40001004; // in module1::wheedle
548  raw_context.esp = stack_section.start().Value();
549  raw_context.ebp = frame0_ebp.Value();
550
551  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
552  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
553                        &frame_symbolizer);
554  ASSERT_TRUE(walker.Walk(&call_stack));
555  frames = call_stack.frames();
556  ASSERT_EQ(3U, frames->size());
557
558  {  // To avoid reusing locals by mistake
559    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
560    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
561    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
562    EXPECT_EQ(0x40001004U, frame0->instruction);
563    EXPECT_EQ(0x40001004U, frame0->context.eip);
564    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
565    EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
566    EXPECT_EQ(&module1, frame0->module);
567    EXPECT_EQ("module1::wheedle", frame0->function_name);
568    EXPECT_EQ(0x40001000U, frame0->function_base);
569    // The FUNC record for module1::wheedle should have produced a
570    // WindowsFrameInfo structure with only the parameter size valid.
571    ASSERT_TRUE(frame0->windows_frame_info != NULL);
572    EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
573              frame0->windows_frame_info->valid);
574    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN,
575              frame0->windows_frame_info->type_);
576    EXPECT_EQ(12U, frame0->windows_frame_info->parameter_size);
577  }
578
579  {  // To avoid reusing locals by mistake
580    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
581    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
582    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
583               | StackFrameX86::CONTEXT_VALID_ESP
584               | StackFrameX86::CONTEXT_VALID_EBP),
585              frame1->context_validity);
586    EXPECT_EQ(0x5000aa95U, frame1->instruction + 1);
587    EXPECT_EQ(0x5000aa95U, frame1->context.eip);
588    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
589    EXPECT_EQ(0x6fa902e0U, frame1->context.ebp);
590    EXPECT_EQ(&module2, frame1->module);
591    EXPECT_EQ("module2::whine", frame1->function_name);
592    EXPECT_EQ(0x5000aa85U, frame1->function_base);
593    ASSERT_TRUE(frame1->windows_frame_info != NULL);
594    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
595    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
596              frame1->windows_frame_info->type_);
597    // This should not see the 0xbeef parameter size from the FUNC
598    // record, but should instead see the STACK WIN record.
599    EXPECT_EQ(4U, frame1->windows_frame_info->parameter_size);
600  }
601
602  {  // To avoid reusing locals by mistake
603    StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
604    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
605    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
606               | StackFrameX86::CONTEXT_VALID_ESP
607               | StackFrameX86::CONTEXT_VALID_EBP
608               | StackFrameX86::CONTEXT_VALID_EBX),
609              frame2->context_validity);
610    EXPECT_EQ(0x2a179e38U, frame2->instruction + 1);
611    EXPECT_EQ(0x2a179e38U, frame2->context.eip);
612    EXPECT_EQ(frame2_esp.Value(), frame2->context.esp);
613    EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp);
614    EXPECT_EQ(0x2558c7f3U, frame2->context.ebx);
615    EXPECT_EQ(NULL, frame2->module);
616    EXPECT_EQ(NULL, frame2->windows_frame_info);
617  }
618}
619
620// Use Windows frame data (a "STACK WIN 4" record, from a
621// FrameTypeFrameData DIA record) to walk a stack frame, where the
622// expression fails to yield both an $eip and an $ebp value, and the stack
623// walker must scan.
624TEST_F(GetCallerFrame, WindowsFrameDataScan) {
625  SetModuleSymbols(&module1,
626                   "STACK WIN 4 c8c 111 0 0 4 10 4 0 1 bad program string\n");
627  // Mark frame 1's PC as the end of the stack.
628  SetModuleSymbols(&module2,
629                   "FUNC 7c38 accf 0 module2::function\n"
630                   "STACK WIN 4 7c38 accf 0 0 4 10 4 0 1 $eip 0 = $ebp 0 =\n");
631  Label frame1_esp;
632  stack_section.start() = 0x80000000;
633  stack_section
634    // frame 0
635    .Append(16, 0x2a)                   // unused, garbage
636    .D32(0x50007ce9)                    // return address
637    // frame 1
638    .Mark(&frame1_esp)
639    .Append(8, 0);                      // empty space
640
641  RegionFromSection();
642  raw_context.eip = 0x40000c9c;
643  raw_context.esp = stack_section.start().Value();
644  raw_context.ebp = 0x2ae314cd;         // should not be needed to walk frame
645
646  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
647  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
648                        &frame_symbolizer);
649  ASSERT_TRUE(walker.Walk(&call_stack));
650  frames = call_stack.frames();
651  ASSERT_EQ(2U, frames->size());
652
653  {  // To avoid reusing locals by mistake
654    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
655    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
656    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
657    EXPECT_EQ(0x40000c9cU, frame0->instruction);
658    EXPECT_EQ(0x40000c9cU, frame0->context.eip);
659    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
660    EXPECT_EQ(0x2ae314cdU, frame0->context.ebp);
661    EXPECT_TRUE(frame0->windows_frame_info != NULL);
662  }
663
664  {  // To avoid reusing locals by mistake
665    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
666    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
667    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the walker
668    // does not actually fetch the EBP after a scan (forcing the next frame
669    // to be scanned as well). But let's grandfather the existing behavior in
670    // for now.
671    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
672               | StackFrameX86::CONTEXT_VALID_ESP
673               | StackFrameX86::CONTEXT_VALID_EBP),
674              frame1->context_validity);
675    EXPECT_EQ(0x50007ce9U, frame1->instruction + 1);
676    EXPECT_EQ(0x50007ce9U, frame1->context.eip);
677    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
678    EXPECT_TRUE(frame1->windows_frame_info != NULL);
679  }
680}
681
682// Use Windows frame data (a "STACK WIN 4" record, from a
683// FrameTypeFrameData DIA record) to walk a stack frame, where the
684// expression yields an $eip that falls outside of any module, and the
685// stack walker must scan.
686TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) {
687  SetModuleSymbols(&module1,
688                   "STACK WIN 4 6e6 e7 0 0 0 8 4 0 1"
689                   // A traditional frame, actually.
690                   " $eip $ebp 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =\n");
691  // Mark frame 1's PC as the end of the stack.
692  SetModuleSymbols(&module2,
693                   "FUNC cfdb 8406 0 module2::function\n"
694                   "STACK WIN 4 cfdb 8406 0 0 0 0 0 0 1 $eip 0 = $ebp 0 =\n");
695  stack_section.start() = 0x80000000;
696
697  // In this stack, the context's %ebp is pointing at the wrong place, so
698  // the stack walker needs to scan to find the return address, and then
699  // scan again to find the caller's saved %ebp.
700  Label frame0_ebp, frame1_ebp, frame1_esp;
701  stack_section
702    // frame 0
703    .Append(8, 0x2a)            // garbage
704    .Mark(&frame0_ebp)          // frame 0 %ebp points here, but should point
705                                // at *** below
706    // The STACK WIN record says that the following two values are
707    // frame 1's saved %ebp and return address, but the %ebp is wrong;
708    // they're garbage. The stack walker will scan for the right values.
709    .D32(0x3d937b2b)            // alleged to be frame 1's saved %ebp
710    .D32(0x17847f5b)            // alleged to be frame 1's return address
711    .D32(frame1_ebp)            // frame 1's real saved %ebp; scan will find
712    .D32(0x2b2b2b2b)            // first word of realigned register save area
713    // *** frame 0 %ebp ought to be pointing here
714    .D32(0x2c2c2c2c)            // realigned locals area
715    .D32(0x5000d000)            // frame 1's real saved %eip; scan will find
716    // Frame 1, in module2::function. The STACK WIN record describes
717    // this as the oldest frame, without referring to its contents, so
718    // we needn't to provide any actual data here.
719    .Mark(&frame1_esp)
720    .Mark(&frame1_ebp)          // frame 1 %ebp points here
721    // A dummy value for frame 1's %ebp to point at. The scan recognizes the
722    // saved %ebp because it points to a valid word in the stack memory region.
723    .D32(0x2d2d2d2d);
724
725  RegionFromSection();
726  raw_context.eip = 0x40000700;
727  raw_context.esp = stack_section.start().Value();
728  raw_context.ebp = frame0_ebp.Value();
729
730  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
731  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
732                        &frame_symbolizer);
733  ASSERT_TRUE(walker.Walk(&call_stack));
734  frames = call_stack.frames();
735  ASSERT_EQ(2U, frames->size());
736
737  {  // To avoid reusing locals by mistake
738    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
739    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
740    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
741    EXPECT_EQ(0x40000700U, frame0->instruction);
742    EXPECT_EQ(0x40000700U, frame0->context.eip);
743    EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
744    EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
745    EXPECT_TRUE(frame0->windows_frame_info != NULL);
746  }
747
748  {  // To avoid reusing locals by mistake
749    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
750    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
751    // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
752    // walker does not actually fetch the EBP after a scan (forcing the
753    // next frame to be scanned as well). But let's grandfather the existing
754    // behavior in for now.
755    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
756               | StackFrameX86::CONTEXT_VALID_ESP
757               | StackFrameX86::CONTEXT_VALID_EBP),
758              frame1->context_validity);
759    EXPECT_EQ(0x5000d000U, frame1->instruction + 1);
760    EXPECT_EQ(0x5000d000U, frame1->context.eip);
761    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
762    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
763    EXPECT_TRUE(frame1->windows_frame_info != NULL);
764  }
765}
766
767// Use Windows FrameTypeFPO data to walk a stack frame for a function that
768// does not modify %ebp from the value it had in the caller.
769TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) {
770  SetModuleSymbols(&module1,
771                   // Note bogus parameter size in FUNC record; the walker
772                   // should prefer the STACK WIN record, and see the '8' below.
773                   "FUNC e8a8 100 feeb module1::discombobulated\n"
774                   "STACK WIN 0 e8a8 100 0 0 8 4 10 0 0 0\n");
775  Label frame0_esp;
776  Label frame1_esp, frame1_ebp;
777  stack_section.start() = 0x80000000;
778  stack_section
779    // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
780    .Mark(&frame0_esp)
781    // no outgoing parameters; this is the youngest frame.
782    .D32(0x7c521352)    // four bytes of saved registers
783    .Append(0x10, 0x42) // local area
784    .D32(0x40009b5b)    // return address, in module1, no function
785    // frame 1, in module1, no function.
786    .Mark(&frame1_esp)
787    .D32(0xf60ea7fc)    // junk
788    .Mark(&frame1_ebp)
789    .D32(0)             // saved %ebp (stack end)
790    .D32(0);            // saved %eip (stack end)
791
792  RegionFromSection();
793  raw_context.eip = 0x4000e8b8; // in module1::whine
794  raw_context.esp = stack_section.start().Value();
795  // Frame pointer unchanged from caller.
796  raw_context.ebp = frame1_ebp.Value();
797
798  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
799  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
800                        &frame_symbolizer);
801  ASSERT_TRUE(walker.Walk(&call_stack));
802  frames = call_stack.frames();
803  ASSERT_EQ(2U, frames->size());
804
805  {  // To avoid reusing locals by mistake
806    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
807    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
808    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
809    EXPECT_EQ(0x4000e8b8U, frame0->instruction);
810    EXPECT_EQ(0x4000e8b8U, frame0->context.eip);
811    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
812    EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); // unchanged from caller
813    EXPECT_EQ(&module1, frame0->module);
814    EXPECT_EQ("module1::discombobulated", frame0->function_name);
815    EXPECT_EQ(0x4000e8a8U, frame0->function_base);
816    // The STACK WIN record for module1::discombobulated should have
817    // produced a fully populated WindowsFrameInfo structure.
818    ASSERT_TRUE(frame0->windows_frame_info != NULL);
819    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
820    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
821              frame0->windows_frame_info->type_);
822    EXPECT_EQ(0x10U, frame0->windows_frame_info->local_size);
823  }
824
825  {  // To avoid reusing locals by mistake
826    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
827    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
828    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
829               | StackFrameX86::CONTEXT_VALID_ESP
830               | StackFrameX86::CONTEXT_VALID_EBP),
831              frame1->context_validity);
832    EXPECT_EQ(0x40009b5bU, frame1->instruction + 1);
833    EXPECT_EQ(0x40009b5bU, frame1->context.eip);
834    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
835    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
836    EXPECT_EQ(&module1, frame1->module);
837    EXPECT_EQ("", frame1->function_name);
838    EXPECT_EQ(NULL, frame1->windows_frame_info);
839  }
840}
841
842// Use Windows FrameTypeFPO data to walk a stack frame for a function
843// that uses %ebp for its own purposes, saving the value it had in the
844// caller in the standard place in the saved register area.
845TEST_F(GetCallerFrame, WindowsFPOUsedEBP) {
846  SetModuleSymbols(&module1,
847                   // Note bogus parameter size in FUNC record; the walker
848                   // should prefer the STACK WIN record, and see the '8' below.
849                   "FUNC 9aa8 e6 abbe module1::RaisedByTheAliens\n"
850                   "STACK WIN 0 9aa8 e6 a 0 10 8 4 0 0 1\n");
851  Label frame0_esp;
852  Label frame1_esp, frame1_ebp;
853  stack_section.start() = 0x80000000;
854  stack_section
855    // frame 0, in module1::wheedle.  FrameTypeFPO (STACK WIN 0) frame.
856    .Mark(&frame0_esp)
857    // no outgoing parameters; this is the youngest frame.
858    .D32(frame1_ebp)    // saved register area: saved %ebp
859    .D32(0xb68bd5f9)    // saved register area: something else
860    .D32(0xd25d05fc)    // local area
861    .D32(0x4000debe)    // return address, in module1, no function
862    // frame 1, in module1, no function.
863    .Mark(&frame1_esp)
864    .D32(0xf0c9a974)    // junk
865    .Mark(&frame1_ebp)
866    .D32(0)             // saved %ebp (stack end)
867    .D32(0);            // saved %eip (stack end)
868
869  RegionFromSection();
870  raw_context.eip = 0x40009ab8; // in module1::RaisedByTheAliens
871  raw_context.esp = stack_section.start().Value();
872  // RaisedByTheAliens uses %ebp for its own mysterious purposes.
873  raw_context.ebp = 0xecbdd1a5;
874
875  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
876  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
877                        &frame_symbolizer);
878  ASSERT_TRUE(walker.Walk(&call_stack));
879  frames = call_stack.frames();
880  ASSERT_EQ(2U, frames->size());
881
882  {  // To avoid reusing locals by mistake
883    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
884    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
885    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
886    EXPECT_EQ(0x40009ab8U, frame0->instruction);
887    EXPECT_EQ(0x40009ab8U, frame0->context.eip);
888    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
889    EXPECT_EQ(0xecbdd1a5, frame0->context.ebp);
890    EXPECT_EQ(&module1, frame0->module);
891    EXPECT_EQ("module1::RaisedByTheAliens", frame0->function_name);
892    EXPECT_EQ(0x40009aa8U, frame0->function_base);
893    // The STACK WIN record for module1::RaisedByTheAliens should have
894    // produced a fully populated WindowsFrameInfo structure.
895    ASSERT_TRUE(frame0->windows_frame_info != NULL);
896    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
897    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
898              frame0->windows_frame_info->type_);
899    EXPECT_EQ("", frame0->windows_frame_info->program_string);
900    EXPECT_TRUE(frame0->windows_frame_info->allocates_base_pointer);
901  }
902
903  {  // To avoid reusing locals by mistake
904    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
905    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
906    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
907               | StackFrameX86::CONTEXT_VALID_ESP
908               | StackFrameX86::CONTEXT_VALID_EBP),
909              frame1->context_validity);
910    EXPECT_EQ(0x4000debeU, frame1->instruction + 1);
911    EXPECT_EQ(0x4000debeU, frame1->context.eip);
912    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
913    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
914    EXPECT_EQ(&module1, frame1->module);
915    EXPECT_EQ("", frame1->function_name);
916    EXPECT_EQ(NULL, frame1->windows_frame_info);
917  }
918}
919
920// This is a regression unit test which covers a bug which has to do with
921// FPO-optimized Windows system call stubs in the context frame.  There is
922// a more recent Windows system call dispatch mechanism which differs from
923// the one which is being tested here.  The newer system call dispatch
924// mechanism creates an extra context frame (KiFastSystemCallRet).
925TEST_F(GetCallerFrame, WindowsFPOSystemCall) {
926  SetModuleSymbols(&module3,  // ntdll.dll
927                   "PUBLIC 1f8ac c ZwWaitForSingleObject\n"
928                   "STACK WIN 0 1f8ac 1b 0 0 c 0 0 0 0 0\n");
929  SetModuleSymbols(&module4,  // kernelbase.dll
930                   "PUBLIC 109f9 c WaitForSingleObjectEx\n"
931                   "PUBLIC 36590 0 _except_handler4\n"
932                   "STACK WIN 4 109f9 df c 0 c c 48 0 1 $T0 $ebp = $eip "
933                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
934                   "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
935                   "STACK WIN 4 36590 154 17 0 10 0 14 0 1 $T0 $ebp = $eip "
936                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 "
937                   ".cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
938  SetModuleSymbols(&module5,  // kernel32.dll
939                   "PUBLIC 11136 8 WaitForSingleObject\n"
940                   "PUBLIC 11151 c WaitForSingleObjectExImplementation\n"
941                   "STACK WIN 4 11136 16 5 0 8 0 0 0 1 $T0 $ebp = $eip "
942                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
943                   "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
944                   "STACK WIN 4 11151 7a 5 0 c 0 0 0 1 $T0 $ebp = $eip "
945                   "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
946                   "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
947  SetModuleSymbols(&module6,  // chrome.dll
948                   "FILE 7038 some_file_name.h\n"
949                   "FILE 839776 some_file_name.cc\n"
950                   "FUNC 217fda 17 4 function_217fda\n"
951                   "217fda 4 102 839776\n"
952                   "FUNC 217ff1 a 4 function_217ff1\n"
953                   "217ff1 0 594 7038\n"
954                   "217ff1 a 596 7038\n"
955                   "STACK WIN 0 217ff1 a 0 0 4 0 0 0 0 0\n");
956
957  Label frame0_esp, frame1_esp;
958  Label frame1_ebp, frame2_ebp, frame3_ebp;
959  stack_section.start() = 0x002ff290;
960  stack_section
961    .Mark(&frame0_esp)
962    .D32(0x771ef8c1)    // EIP in frame 0 (system call)
963    .D32(0x75fa0a91)    // return address of frame 0
964    .Mark(&frame1_esp)
965    .D32(0x000017b0)    // args to child
966    .D32(0x00000000)
967    .D32(0x002ff2d8)
968    .D32(0x88014a2e)
969    .D32(0x002ff364)
970    .D32(0x000017b0)
971    .D32(0x00000000)
972    .D32(0x00000024)
973    .D32(0x00000001)
974    .D32(0x00000000)
975    .D32(0x00000000)
976    .D32(0x00000000)
977    .D32(0x00000000)
978    .D32(0x00000000)
979    .D32(0x00000000)
980    .D32(0x00000000)
981    .D32(0x9e3b9800)
982    .D32(0xfffffff7)
983    .D32(0x00000000)
984    .D32(0x002ff2a4)
985    .D32(0x64a07ff1)    // random value to be confused with a return address
986    .D32(0x002ff8dc)
987    .D32(0x75fc6590)    // random value to be confused with a return address
988    .D32(0xfdd2c6ea)
989    .D32(0x00000000)
990    .Mark(&frame1_ebp)
991    .D32(frame2_ebp)    // Child EBP
992    .D32(0x75741194)    // return address of frame 1
993    .D32(0x000017b0)    // args to child
994    .D32(0x0036ee80)
995    .D32(0x00000000)
996    .D32(0x65bc7d14)
997    .Mark(&frame2_ebp)
998    .D32(frame3_ebp)    // Child EBP
999    .D32(0x75741148)    // return address of frame 2
1000    .D32(0x000017b0)    // args to child
1001    .D32(0x0036ee80)
1002    .D32(0x00000000)
1003    .Mark(&frame3_ebp)
1004    .D32(0)             // saved %ebp (stack end)
1005    .D32(0);            // saved %eip (stack end)
1006
1007  RegionFromSection();
1008  raw_context.eip = 0x771ef8c1;  // in ntdll::ZwWaitForSingleObject
1009  raw_context.esp = stack_section.start().Value();
1010  ASSERT_TRUE(raw_context.esp == frame0_esp.Value());
1011  raw_context.ebp = frame1_ebp.Value();
1012
1013  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1014  StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
1015                        &frame_symbolizer);
1016  ASSERT_TRUE(walker.Walk(&call_stack));
1017  frames = call_stack.frames();
1018
1019  ASSERT_EQ(4U, frames->size());
1020
1021  {  // To avoid reusing locals by mistake
1022    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1023    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1024    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1025    EXPECT_EQ(0x771ef8c1U, frame0->instruction);
1026    EXPECT_EQ(0x771ef8c1U, frame0->context.eip);
1027    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
1028    EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp);
1029    EXPECT_EQ(&module3, frame0->module);
1030    EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name);
1031    // The STACK WIN record for module3!ZwWaitForSingleObject should have
1032    // produced a fully populated WindowsFrameInfo structure.
1033    ASSERT_TRUE(frame0->windows_frame_info != NULL);
1034    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
1035    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
1036              frame0->windows_frame_info->type_);
1037    EXPECT_EQ("", frame0->windows_frame_info->program_string);
1038    EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
1039  }
1040
1041  {  // To avoid reusing locals by mistake
1042    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1043    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
1044    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
1045               | StackFrameX86::CONTEXT_VALID_ESP
1046               | StackFrameX86::CONTEXT_VALID_EBP),
1047              frame1->context_validity);
1048    EXPECT_EQ(0x75fa0a91U, frame1->instruction + 1);
1049    EXPECT_EQ(0x75fa0a91U, frame1->context.eip);
1050    EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
1051    EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
1052    EXPECT_EQ(&module4, frame1->module);
1053    EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name);
1054    // The STACK WIN record for module4!WaitForSingleObjectEx should have
1055    // produced a fully populated WindowsFrameInfo structure.
1056    ASSERT_TRUE(frame1->windows_frame_info != NULL);
1057    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
1058    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1059              frame1->windows_frame_info->type_);
1060    EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
1061              "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =",
1062              frame1->windows_frame_info->program_string);
1063    EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
1064  }
1065}
1066
1067// Scan the stack for a better return address and potentially skip frames
1068// when the calculated return address is not in a known module.
1069// Note, that the span of this scan is somewhat arbitrarily limited to 30
1070// search words (pointers):
1071//     const int kRASearchWords = 30;
1072// This means that frames can be skipped only when their size is relatively
1073// small: smaller than kRASearchWords * sizeof(InstructionType)
1074TEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) {
1075  MockCodeModule msvcrt_dll(0x77be0000, 0x58000, "msvcrt.dll", "version1");
1076  SetModuleSymbols(&msvcrt_dll,  // msvcrt.dll
1077                   "PUBLIC 38180 0 wcsstr\n"
1078                   "STACK WIN 4 38180 61 10 0 8 0 0 0 1 $T0 $ebp = $eip $T0 "
1079                   "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1080                   "- = $P $T0 4 + .cbParams + =\n");
1081
1082  MockCodeModule kernel32_dll(0x7c800000, 0x103000, "kernel32.dll", "version1");
1083  SetModuleSymbols(&kernel32_dll,  // kernel32.dll
1084                   "PUBLIC efda 8 FindNextFileW\n"
1085                   "STACK WIN 4 efda 1bb c 0 8 8 3c 0 1 $T0 $ebp = $eip $T0 "
1086                   "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1087                   "- = $P $T0 4 + .cbParams + =\n");
1088
1089  MockCodeModule chrome_dll(0x1c30000, 0x28C8000, "chrome.dll", "version1");
1090  SetModuleSymbols(&chrome_dll,  // chrome.dll
1091                   "FUNC e3cff 4af 0 file_util::FileEnumerator::Next()\n"
1092                   "e3cff 1a 711 2505\n"
1093                   "STACK WIN 4 e3cff 4af 20 0 4 c 94 0 1 $T1 .raSearch = "
1094                   "$T0  $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp "
1095                   "$T1 4 + = $20 $T0 152 - ^ =  $23 $T0 156 - ^ =  $24 "
1096                   "$T0 160 - ^ =\n");
1097
1098  // Create some modules with some stock debugging information.
1099  MockCodeModules local_modules;
1100  local_modules.Add(&msvcrt_dll);
1101  local_modules.Add(&kernel32_dll);
1102  local_modules.Add(&chrome_dll);
1103
1104  Label frame0_esp;
1105  Label frame0_ebp;
1106  Label frame1_ebp;
1107  Label frame2_ebp;
1108  Label frame3_ebp;
1109
1110  stack_section.start() = 0x0932f2d0;
1111  stack_section
1112    .Mark(&frame0_esp)
1113    .D32(0x0764e000)
1114    .D32(0x0764e068)
1115    .Mark(&frame0_ebp)
1116    .D32(frame1_ebp)    // Child EBP
1117    .D32(0x001767a0)    // return address of frame 0
1118                        // Not in known module
1119    .D32(0x0764e0c6)
1120    .D32(0x001bb1b8)
1121    .D32(0x0764e068)
1122    .D32(0x00000003)
1123    .D32(0x0764e068)
1124    .D32(0x00000003)
1125    .D32(0x07578828)
1126    .D32(0x0764e000)
1127    .D32(0x00000000)
1128    .D32(0x001c0010)
1129    .D32(0x0764e0c6)
1130    .Mark(&frame1_ebp)
1131    .D32(frame2_ebp)    // Child EBP
1132    .D32(0x7c80f10f)    // return address of frame 1
1133                        // inside kernel32!FindNextFileW
1134    .D32(0x000008f8)
1135    .D32(0x00000000)
1136    .D32(0x00000000)
1137    .D32(0x00000000)
1138    .D32(0x0932f34c)
1139    .D32(0x0764e000)
1140    .D32(0x00001000)
1141    .D32(0x00000000)
1142    .D32(0x00000001)
1143    .D32(0x00000000)
1144    .D32(0x00000000)
1145    .D32(0x0932f6a8)
1146    .D32(0x00000000)
1147    .D32(0x0932f6d8)
1148    .D32(0x00000000)
1149    .D32(0x000000d6)
1150    .D32(0x0764e000)
1151    .D32(0x7ff9a000)
1152    .D32(0x0932f3fc)
1153    .D32(0x00000001)
1154    .D32(0x00000001)
1155    .D32(0x07578828)
1156    .D32(0x0000002e)
1157    .D32(0x0932f340)
1158    .D32(0x0932eef4)
1159    .D32(0x0932ffdc)
1160    .D32(0x7c839ad8)
1161    .D32(0x7c80f0d8)
1162    .D32(0x00000000)
1163    .Mark(&frame2_ebp)
1164    .D32(frame3_ebp)    // Child EBP
1165    .D32(0x01d13f91)    // return address of frame 2
1166                        // inside chrome_dll!file_util::FileEnumerator::Next
1167    .D32(0x07578828)
1168    .D32(0x0932f6ac)
1169    .D32(0x0932f9c4)
1170    .D32(0x0932f9b4)
1171    .D32(0x00000000)
1172    .D32(0x00000003)
1173    .D32(0x0932f978)
1174    .D32(0x01094330)
1175    .D32(0x00000000)
1176    .D32(0x00000001)
1177    .D32(0x01094330)
1178    .D32(0x00000000)
1179    .D32(0x00000000)
1180    .D32(0x07f30000)
1181    .D32(0x01c3ba17)
1182    .D32(0x08bab840)
1183    .D32(0x07f31580)
1184    .D32(0x00000000)
1185    .D32(0x00000007)
1186    .D32(0x0932f940)
1187    .D32(0x0000002e)
1188    .D32(0x0932f40c)
1189    .D32(0x01d13b53)
1190    .D32(0x0932f958)
1191    .D32(0x00000001)
1192    .D32(0x00000007)
1193    .D32(0x0932f940)
1194    .D32(0x0000002e)
1195    .D32(0x00000000)
1196    .D32(0x0932f6ac)
1197    .D32(0x01e13ef0)
1198    .D32(0x00000001)
1199    .D32(0x00000007)
1200    .D32(0x0932f958)
1201    .D32(0x08bab840)
1202    .D32(0x0932f9b4)
1203    .D32(0x00000000)
1204    .D32(0x0932f9b4)
1205    .D32(0x000000a7)
1206    .D32(0x000000a7)
1207    .D32(0x0932f998)
1208    .D32(0x579627a2)
1209    .Mark(&frame3_ebp)
1210    .D32(0)             // saved %ebp (stack end)
1211    .D32(0);            // saved %eip (stack end)
1212
1213  RegionFromSection();
1214  raw_context.eip = 0x77c181cd;  // inside msvcrt!wcsstr
1215  raw_context.esp = frame0_esp.Value();
1216  raw_context.ebp = frame0_ebp.Value();
1217  // sanity
1218  ASSERT_TRUE(raw_context.esp == stack_section.start().Value());
1219  ASSERT_TRUE(raw_context.ebp == stack_section.start().Value() + 8);
1220
1221  StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1222  StackwalkerX86 walker(&system_info, &raw_context, &stack_region,
1223                        &local_modules, &frame_symbolizer);
1224  ASSERT_TRUE(walker.Walk(&call_stack));
1225  frames = call_stack.frames();
1226
1227  ASSERT_EQ(3U, frames->size());
1228
1229  {  // To avoid reusing locals by mistake
1230    StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1231    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1232    ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1233    EXPECT_EQ(0x77c181cdU, frame0->instruction);
1234    EXPECT_EQ(0x77c181cdU, frame0->context.eip);
1235    EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
1236    EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
1237    EXPECT_EQ(&msvcrt_dll, frame0->module);
1238    EXPECT_EQ("wcsstr", frame0->function_name);
1239    ASSERT_TRUE(frame0->windows_frame_info != NULL);
1240    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
1241    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1242              frame0->windows_frame_info->type_);
1243    EXPECT_EQ("$T0 $ebp = $eip $T0 "
1244              "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1245              "- = $P $T0 4 + .cbParams + =",
1246              frame0->windows_frame_info->program_string);
1247    // It has program string, so allocates_base_pointer is not expected
1248    EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
1249  }
1250
1251  {  // To avoid reusing locals by mistake
1252    StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1253    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
1254    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1255               StackFrameX86::CONTEXT_VALID_ESP |
1256               StackFrameX86::CONTEXT_VALID_EBP),
1257              frame1->context_validity);
1258    EXPECT_EQ(0x7c80f10fU, frame1->instruction + 1);
1259    EXPECT_EQ(0x7c80f10fU, frame1->context.eip);
1260    // frame 1 was skipped, so intead of frame1_ebp compare with frame2_ebp.
1261    EXPECT_EQ(frame2_ebp.Value(), frame1->context.ebp);
1262    EXPECT_EQ(&kernel32_dll, frame1->module);
1263    EXPECT_EQ("FindNextFileW", frame1->function_name);
1264    ASSERT_TRUE(frame1->windows_frame_info != NULL);
1265    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
1266    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1267              frame1->windows_frame_info->type_);
1268    EXPECT_EQ("$T0 $ebp = $eip $T0 "
1269              "4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 .cbSavedRegs "
1270              "- = $P $T0 4 + .cbParams + =",
1271              frame1->windows_frame_info->program_string);
1272    EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
1273  }
1274
1275  {  // To avoid reusing locals by mistake
1276    StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
1277    EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
1278    ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1279               StackFrameX86::CONTEXT_VALID_ESP |
1280               StackFrameX86::CONTEXT_VALID_EBP),
1281              frame2->context_validity);
1282    EXPECT_EQ(0x01d13f91U, frame2->instruction + 1);
1283    EXPECT_EQ(0x01d13f91U, frame2->context.eip);
1284    // frame 1 was skipped, so intead of frame2_ebp compare with frame3_ebp.
1285    EXPECT_EQ(frame3_ebp.Value(), frame2->context.ebp);
1286    EXPECT_EQ(&chrome_dll, frame2->module);
1287    EXPECT_EQ("file_util::FileEnumerator::Next()", frame2->function_name);
1288    ASSERT_TRUE(frame2->windows_frame_info != NULL);
1289    EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid);
1290    EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
1291              frame2->windows_frame_info->type_);
1292    EXPECT_EQ("$T1 .raSearch = "
1293              "$T0  $T1 4 - 8 @ = $ebp $T1 4 - ^ = $eip $T1 ^ = $esp "
1294              "$T1 4 + = $20 $T0 152 - ^ =  $23 $T0 156 - ^ =  $24 "
1295              "$T0 160 - ^ =",
1296              frame2->windows_frame_info->program_string);
1297    EXPECT_FALSE(frame2->windows_frame_info->allocates_base_pointer);
1298  }
1299}
1300
1301struct CFIFixture: public StackwalkerX86Fixture {
1302  CFIFixture() {
1303    // Provide a bunch of STACK CFI records; individual tests walk to the
1304    // caller from every point in this series, expecting to find the same
1305    // set of register values.
1306    SetModuleSymbols(&module1,
1307                     // The youngest frame's function.
1308                     "FUNC 4000 1000 10 enchiridion\n"
1309                     // Initially, just a return address.
1310                     "STACK CFI INIT 4000 100 .cfa: $esp 4 + .ra: .cfa 4 - ^\n"
1311                     // Push %ebx.
1312                     "STACK CFI 4001 .cfa: $esp 8 + $ebx: .cfa 8 - ^\n"
1313                     // Move %esi into %ebx.  Weird, but permitted.
1314                     "STACK CFI 4002 $esi: $ebx\n"
1315                     // Allocate frame space, and save %edi.
1316                     "STACK CFI 4003 .cfa: $esp 20 + $edi: .cfa 16 - ^\n"
1317                     // Put the return address in %edi.
1318                     "STACK CFI 4005 .ra: $edi\n"
1319                     // Save %ebp, and use it as a frame pointer.
1320                     "STACK CFI 4006 .cfa: $ebp 8 + $ebp: .cfa 12 - ^\n"
1321
1322                     // The calling function.
1323                     "FUNC 5000 1000 10 epictetus\n"
1324                     // Mark it as end of stack.
1325                     "STACK CFI INIT 5000 1000 .cfa: $esp .ra 0\n");
1326
1327    // Provide some distinctive values for the caller's registers.
1328    expected.esp = 0x80000000;
1329    expected.eip = 0x40005510;
1330    expected.ebp = 0xc0d4aab9;
1331    expected.ebx = 0x60f20ce6;
1332    expected.esi = 0x53d1379d;
1333    expected.edi = 0xafbae234;
1334
1335    // By default, registers are unchanged.
1336    raw_context = expected;
1337  }
1338
1339  // Walk the stack, using stack_section as the contents of the stack
1340  // and raw_context as the current register values. (Set
1341  // raw_context.esp to the stack's starting address.) Expect two
1342  // stack frames; in the older frame, expect the callee-saves
1343  // registers to have values matching those in 'expected'.
1344  void CheckWalk() {
1345    RegionFromSection();
1346    raw_context.esp = stack_section.start().Value();
1347
1348    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
1349    StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
1350                          &frame_symbolizer);
1351    ASSERT_TRUE(walker.Walk(&call_stack));
1352    frames = call_stack.frames();
1353    ASSERT_EQ(2U, frames->size());
1354
1355    {  // To avoid reusing locals by mistake
1356      StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
1357      EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
1358      ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
1359      EXPECT_EQ("enchiridion", frame0->function_name);
1360      EXPECT_EQ(0x40004000U, frame0->function_base);
1361      ASSERT_TRUE(frame0->windows_frame_info != NULL);
1362      ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
1363                frame0->windows_frame_info->valid);
1364      ASSERT_TRUE(frame0->cfi_frame_info != NULL);
1365    }
1366
1367    {  // To avoid reusing locals by mistake
1368      StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
1369      EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
1370      ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
1371                 StackFrameX86::CONTEXT_VALID_ESP |
1372                 StackFrameX86::CONTEXT_VALID_EBP |
1373                 StackFrameX86::CONTEXT_VALID_EBX |
1374                 StackFrameX86::CONTEXT_VALID_ESI |
1375                 StackFrameX86::CONTEXT_VALID_EDI),
1376                 frame1->context_validity);
1377      EXPECT_EQ(expected.eip, frame1->context.eip);
1378      EXPECT_EQ(expected.esp, frame1->context.esp);
1379      EXPECT_EQ(expected.ebp, frame1->context.ebp);
1380      EXPECT_EQ(expected.ebx, frame1->context.ebx);
1381      EXPECT_EQ(expected.esi, frame1->context.esi);
1382      EXPECT_EQ(expected.edi, frame1->context.edi);
1383      EXPECT_EQ("epictetus", frame1->function_name);
1384    }
1385  }
1386
1387  // The values the stack walker should find for the caller's registers.
1388  MDRawContextX86 expected;
1389};
1390
1391class CFI: public CFIFixture, public Test { };
1392
1393TEST_F(CFI, At4000) {
1394  Label frame1_esp = expected.esp;
1395  stack_section
1396    .D32(0x40005510)            // return address
1397    .Mark(&frame1_esp);         // This effectively sets stack_section.start().
1398  raw_context.eip = 0x40004000;
1399  CheckWalk();
1400}
1401
1402TEST_F(CFI, At4001) {
1403  Label frame1_esp = expected.esp;
1404  stack_section
1405    .D32(0x60f20ce6)            // saved %ebx
1406    .D32(0x40005510)            // return address
1407    .Mark(&frame1_esp);         // This effectively sets stack_section.start().
1408  raw_context.eip = 0x40004001;
1409  raw_context.ebx = 0x91aa9a8b; // callee's %ebx value
1410  CheckWalk();
1411}
1412
1413TEST_F(CFI, At4002) {
1414  Label frame1_esp = expected.esp;
1415  stack_section
1416    .D32(0x60f20ce6)            // saved %ebx
1417    .D32(0x40005510)            // return address
1418    .Mark(&frame1_esp);         // This effectively sets stack_section.start().
1419  raw_context.eip = 0x40004002;
1420  raw_context.ebx = 0x53d1379d; // saved %esi
1421  raw_context.esi = 0xa5c790ed; // callee's %esi value
1422  CheckWalk();
1423}
1424
1425TEST_F(CFI, At4003) {
1426  Label frame1_esp = expected.esp;
1427  stack_section
1428    .D32(0x56ec3db7)            // garbage
1429    .D32(0xafbae234)            // saved %edi
1430    .D32(0x53d67131)            // garbage
1431    .D32(0x60f20ce6)            // saved %ebx
1432    .D32(0x40005510)            // return address
1433    .Mark(&frame1_esp);         // This effectively sets stack_section.start().
1434  raw_context.eip = 0x40004003;
1435  raw_context.ebx = 0x53d1379d; // saved %esi
1436  raw_context.esi = 0xa97f229d; // callee's %esi
1437  raw_context.edi = 0xb05cc997; // callee's %edi
1438  CheckWalk();
1439}
1440
1441// The results here should be the same as those at module offset
1442// 0x4003.
1443TEST_F(CFI, At4004) {
1444  Label frame1_esp = expected.esp;
1445  stack_section
1446    .D32(0xe29782c2)            // garbage
1447    .D32(0xafbae234)            // saved %edi
1448    .D32(0x5ba29ce9)            // garbage
1449    .D32(0x60f20ce6)            // saved %ebx
1450    .D32(0x40005510)            // return address
1451    .Mark(&frame1_esp);         // This effectively sets stack_section.start().
1452  raw_context.eip = 0x40004004;
1453  raw_context.ebx = 0x53d1379d; // saved %esi
1454  raw_context.esi = 0x0fb7dc4e; // callee's %esi
1455  raw_context.edi = 0x993b4280; // callee's %edi
1456  CheckWalk();
1457}
1458
1459TEST_F(CFI, At4005) {
1460  Label frame1_esp = expected.esp;
1461  stack_section
1462    .D32(0xe29782c2)            // garbage
1463    .D32(0xafbae234)            // saved %edi
1464    .D32(0x5ba29ce9)            // garbage
1465    .D32(0x60f20ce6)            // saved %ebx
1466    .D32(0x8036cc02)            // garbage
1467    .Mark(&frame1_esp);         // This effectively sets stack_section.start().
1468  raw_context.eip = 0x40004005;
1469  raw_context.ebx = 0x53d1379d; // saved %esi
1470  raw_context.esi = 0x0fb7dc4e; // callee's %esi
1471  raw_context.edi = 0x40005510; // return address
1472  CheckWalk();
1473}
1474
1475TEST_F(CFI, At4006) {
1476  Label frame0_ebp;
1477  Label frame1_esp = expected.esp;
1478  stack_section
1479    .D32(0xdcdd25cd)            // garbage
1480    .D32(0xafbae234)            // saved %edi
1481    .D32(0xc0d4aab9)            // saved %ebp
1482    .Mark(&frame0_ebp)          // frame pointer points here
1483    .D32(0x60f20ce6)            // saved %ebx
1484    .D32(0x8036cc02)            // garbage
1485    .Mark(&frame1_esp);         // This effectively sets stack_section.start().
1486  raw_context.eip = 0x40004006;
1487  raw_context.ebp = frame0_ebp.Value();
1488  raw_context.ebx = 0x53d1379d; // saved %esi
1489  raw_context.esi = 0x743833c9; // callee's %esi
1490  raw_context.edi = 0x40005510; // return address
1491  CheckWalk();
1492}
1493
1494