| /* ********************************************************** |
| * Copyright (c) 2021 Google, Inc. All rights reserved. |
| * **********************************************************/ |
| |
| /* |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * * Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * * Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * * Neither the name of Google, Inc. nor the names of its contributors may be |
| * used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGE. |
| */ |
| |
| /* DynamoRIO Callstack Walker. */ |
| |
| #ifndef _DRCALLSTACK_H_ |
| #define _DRCALLSTACK_H_ 1 |
| |
| /** |
| * @file drcallstack.h |
| * @brief Header for DynamoRIO Callstack Walker |
| */ |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * \addtogroup drcallstack Callstack Walker |
| */ |
| /**@{*/ /* begin doxygen group */ |
| |
| /** Success code for each drcallstack operation. */ |
| typedef enum { |
| DRCALLSTACK_SUCCESS, /**< Operation succeeded. */ |
| DRCALLSTACK_NO_MORE_FRAMES, /**< No further frames found. */ |
| DRCALLSTACK_ERROR, /**< Operation failed. */ |
| DRCALLSTACK_ERROR_INVALID_PARAMETER, /**< Operation failed: invalid parameter */ |
| DRCALLSTACK_ERROR_FEATURE_NOT_AVAILABLE, /**< Operation failed: not available */ |
| } drcallstack_status_t; |
| |
| /*************************************************************************** |
| * INIT |
| */ |
| |
| /** Specifies the options when initializing drcallstack. */ |
| typedef struct _drcallstack_options_t { |
| /** Set this to the size of this structure. */ |
| size_t struct_size; |
| /* We expect to add more options in the future. */ |
| } drcallstack_options_t; |
| |
| /** Describes one callstack frame. */ |
| typedef struct _drcallstack_frame_t { |
| /** Set this to the size of this structure. */ |
| size_t struct_size; |
| /** The program counter. */ |
| app_pc pc; |
| /** The stack address for the start of the frame. */ |
| reg_t sp; |
| } drcallstack_frame_t; |
| |
| /** Opaque type. */ |
| struct _drcallstack_walk_t; |
| /** Opaque type. */ |
| typedef struct _drcallstack_walk_t drcallstack_walk_t; |
| |
| DR_EXPORT |
| /** |
| * Initializes the drcallstack extension. Must be called prior to any of the other |
| * routines. Can be called multiple times (by separate components, normally) |
| * but each call must be paired with a corresponding call to drcallstack_exit(). |
| * |
| * @param[in] ops Specifies the optional parameters that control how |
| * drcallstack operates. |
| * |
| * @return whether successful or an error code on failure. |
| */ |
| drcallstack_status_t |
| drcallstack_init(drcallstack_options_t *ops); |
| |
| DR_EXPORT |
| /** |
| * Cleans up the drcallstack extension. |
| * @return whether successful or an error code on failure. |
| */ |
| drcallstack_status_t |
| drcallstack_exit(void); |
| |
| DR_EXPORT |
| /** |
| * Initializes a new callstack walk with the passed-in context 'mc', which |
| * must have #DR_MC_CONTROL and #DR_MC_INTEGER filled in. |
| * The 'walk' pointer should then be passed to repeated calls to |
| * drcallstack_next_frame() until it returns #DRCALLSTACK_NO_MORE_FRAMES. |
| * drcallstack_cleanup_walk() should then be called to free up resources. |
| * |
| * \note Currently callstack walking is only available for Linux. |
| */ |
| drcallstack_status_t |
| drcallstack_init_walk(dr_mcontext_t *mc, DR_PARAM_OUT drcallstack_walk_t **walk); |
| |
| DR_EXPORT |
| /** |
| * Called when the 'walk' pointer is no longer needed. |
| */ |
| drcallstack_status_t |
| drcallstack_cleanup_walk(drcallstack_walk_t *walk); |
| |
| DR_EXPORT |
| /** |
| * First, call drcallstack_init_walk() to initialize 'walk'. |
| * The 'walk' pointer should then be passed to repeated calls to |
| * drcallstack_next_frame() until it returns #DRCALLSTACK_NO_MORE_FRAMES |
| * or an error code. |
| * drcallstack_cleanup_walk() should then be called to free up resources. |
| * |
| * \note Currently callstack walking is only available for Linux. |
| */ |
| drcallstack_status_t |
| drcallstack_next_frame(drcallstack_walk_t *walk, DR_PARAM_OUT drcallstack_frame_t *frame); |
| |
| /**@}*/ /* end doxygen group */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _DRCALLSTACK_H_ */ |