183e085b7a331c96237cf8e814f97b3ef4c36a70fjimblandy// Copyright (c) 2010 Google Inc.
28eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// All rights reserved.
38eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//
48eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// Redistribution and use in source and binary forms, with or without
58eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// modification, are permitted provided that the following conditions are
68eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// met:
78eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//
88eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//     * Redistributions of source code must retain the above copyright
98eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// notice, this list of conditions and the following disclaimer.
108eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//     * Redistributions in binary form must reproduce the above
118eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// copyright notice, this list of conditions and the following disclaimer
128eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// in the documentation and/or other materials provided with the
138eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// distribution.
148eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//     * Neither the name of Google Inc. nor the names of its
158eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// contributors may be used to endorse or promote products derived from
168eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// this software without specific prior written permission.
178eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//
188eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
198eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
208eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
218eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
228eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
238eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
248eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
258eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
268eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
278eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
288eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
298eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
308eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// stackwalker_amd64.h: amd64-specific stackwalker.
318eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//
328eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// Provides stack frames given amd64 register context and a memory region
338eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// corresponding to a amd64 stack.
348eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek//
358eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek// Author: Mark Mentovai, Ted Mielczarek
368eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
378eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
388eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek#ifndef PROCESSOR_STACKWALKER_AMD64_H__
398eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek#define PROCESSOR_STACKWALKER_AMD64_H__
408eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
419753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com#include <vector>
428eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
438eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek#include "google_breakpad/common/breakpad_types.h"
448eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek#include "google_breakpad/common/minidump_format.h"
458eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek#include "google_breakpad/processor/stackwalker.h"
46e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy#include "google_breakpad/processor/stack_frame_cpu.h"
47e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy#include "processor/cfi_frame_info.h"
488eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
498eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczareknamespace google_breakpad {
508eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
518eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarekclass CodeModules;
528eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
538eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarekclass StackwalkerAMD64 : public Stackwalker {
548eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek public:
558eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // context is a amd64 context object that gives access to amd64-specific
568eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // register state corresponding to the innermost called frame to be
578eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // included in the stack.  The other arguments are passed directly through
588eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // to the base Stackwalker constructor.
599753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com  StackwalkerAMD64(const SystemInfo* system_info,
609753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com                   const MDRawContextAMD64* context,
619753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com                   MemoryRegion* memory,
629753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com                   const CodeModules* modules,
639753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com                   StackFrameSymbolizer* frame_symbolizer);
648eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
658eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek private:
66e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  // A STACK CFI-driven frame walker for the AMD64
676162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  typedef SimpleCFIWalker<uint64_t, MDRawContextAMD64> CFIWalker;
68e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy
698eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // Implementation of Stackwalker, using amd64 context (stack pointer in %rsp,
708eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // stack base in %rbp) and stack conventions (saved stack pointer at 0(%rbp))
718eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  virtual StackFrame* GetContextFrame();
7242b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com  virtual StackFrame* GetCallerFrame(const CallStack* stack,
7342b91fbbf30f8a6d900d1fb97e96394dbb363890ted.mielczarek@gmail.com                                     bool stack_scan_allowed);
748eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
75e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  // Use cfi_frame_info (derived from STACK CFI records) to construct
76e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  // the frame that called frames.back(). The caller takes ownership
77e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  // of the returned frame. Return NULL on failure.
789753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com  StackFrameAMD64* GetCallerByCFIFrameInfo(const vector<StackFrame*> &frames,
799753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com                                           CFIFrameInfo* cfi_frame_info);
80e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy
810f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org  // Assumes a traditional frame layout where the frame pointer has not been
820f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org  // omitted. The expectation is that caller's %rbp is pushed to the stack
830f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org  // after the return address of the callee, and that the callee's %rsp can
840f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org  // be used to find the pushed %rbp.
850f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org  // Caller owns the returned frame object. Returns NULL on failure.
860f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org  StackFrameAMD64* GetCallerByFramePointerRecovery(
870f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org      const vector<StackFrame*>& frames);
880f416c9df36db2506a66788b3064779b053fcb3brsesek@chromium.org
89c653618a9175d3252cc6d1aa8c3393f9558646e8ted.mielczarek  // Scan the stack for plausible return addresses. The caller takes ownership
909753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com  // of the returned frame. Return NULL on failure.
919753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com  StackFrameAMD64* GetCallerByStackScan(const vector<StackFrame*> &frames);
92c653618a9175d3252cc6d1aa8c3393f9558646e8ted.mielczarek
938eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // Stores the CPU context corresponding to the innermost stack frame to
948eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek  // be returned by GetContextFrame.
959753aff85a9a20dbe294529b4184d9686ec42cddSiyangXie@gmail.com  const MDRawContextAMD64* context_;
96e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy
97e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  // Our register map, for cfi_walker_.
98e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  static const CFIWalker::RegisterSet cfi_register_map_[];
99e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy
100e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  // Our CFI frame walker.
101e7e1e1ebf58a306af1e3199f6e493106e463cf91jimblandy  const CFIWalker cfi_walker_;
1028eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek};
1038eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
1048eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
1058eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek}  // namespace google_breakpad
1068eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
1078eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek
1088eb7111814953cb64ec0569b91ea99804b2d5b85ted.mielczarek#endif  // PROCESSOR_STACKWALKER_AMD64_H__
109