/* simple.c -- The backtrace_simple function.1Copyright (C) 2012-2021 Free Software Foundation, Inc.2Written by Ian Lance Taylor, Google.34Redistribution and use in source and binary forms, with or without5modification, are permitted provided that the following conditions are6met:78(1) Redistributions of source code must retain the above copyright9notice, this list of conditions and the following disclaimer.1011(2) Redistributions in binary form must reproduce the above copyright12notice, this list of conditions and the following disclaimer in13the documentation and/or other materials provided with the14distribution.1516(3) The name of the author may not be used to17endorse or promote products derived from this software without18specific prior written permission.1920THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR21IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED22WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,24INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES25(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR26SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,28STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING29IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE30POSSIBILITY OF SUCH DAMAGE. */3132#include "config.h"3334#include "unwind.h"35#include "backtrace.h"3637/* The simple_backtrace routine. */3839/* Data passed through _Unwind_Backtrace. */4041struct backtrace_simple_data42{43/* Number of frames to skip. */44int skip;45/* Library state. */46struct backtrace_state *state;47/* Callback routine. */48backtrace_simple_callback callback;49/* Error callback routine. */50backtrace_error_callback error_callback;51/* Data to pass to callback routine. */52void *data;53/* Value to return from backtrace. */54int ret;55};5657/* Unwind library callback routine. This is passed to58_Unwind_Backtrace. */5960static _Unwind_Reason_Code61simple_unwind (struct _Unwind_Context *context, void *vdata)62{63struct backtrace_simple_data *bdata = (struct backtrace_simple_data *) vdata;64uintptr_t pc;65int ip_before_insn = 0;6667#ifdef HAVE_GETIPINFO68pc = _Unwind_GetIPInfo (context, &ip_before_insn);69#else70pc = _Unwind_GetIP (context);71#endif7273if (bdata->skip > 0)74{75--bdata->skip;76return _URC_NO_REASON;77}7879if (!ip_before_insn)80--pc;8182bdata->ret = bdata->callback (bdata->data, pc);8384if (bdata->ret != 0)85return _URC_END_OF_STACK;8687return _URC_NO_REASON;88}8990/* Get a simple stack backtrace. */9192int __attribute__((noinline))93backtrace_simple (struct backtrace_state *state, int skip,94backtrace_simple_callback callback,95backtrace_error_callback error_callback, void *data)96{97struct backtrace_simple_data bdata;9899bdata.skip = skip + 1;100bdata.state = state;101bdata.callback = callback;102bdata.error_callback = error_callback;103bdata.data = data;104bdata.ret = 0;105_Unwind_Backtrace (simple_unwind, &bdata);106return bdata.ret;107}108109110