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