blob: 143cd89f120babdc0fcb3eb0ad689b51ae915497 [file] [log] [blame]
/* **********************************************************
* 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_ */