forked from len0rd/rockbox
Arm stack unwinder
Simplified stack unwinder for ARM. This is port of http://www.mcternan.me.uk/ArmStackUnwinding/ backtrace() is called from UIE() on native targets and from panicf() on both native and ARM RaaA. Change-Id: I8e4b3c02490dd60b30aa372fe842d193b8929ce0
This commit is contained in:
parent
680c6fcde1
commit
b4eab59951
23 changed files with 2630 additions and 18 deletions
124
lib/unwarminder/backtrace.c
Normal file
124
lib/unwarminder/backtrace.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/***************************************************************************
|
||||
* ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
|
||||
*
|
||||
* This program is PUBLIC DOMAIN.
|
||||
* This means that there is no copyright and anyone is able to take a copy
|
||||
* for free and use it as they wish, with or without modifications, and in
|
||||
* any context, commercially or otherwise. The only limitation is that I
|
||||
* don't guarantee that the software is fit for any purpose or accept any
|
||||
* liability for it's use or misuse - this software is without warranty.
|
||||
***************************************************************************
|
||||
* File Description: Unwinder client that reads local memory.
|
||||
* This client reads from local memory and is designed to run on target
|
||||
* along with the unwinder. Memory read requests are implemented by
|
||||
* casting a point to read the memory directly, although checks for
|
||||
* alignment should probably also be made if this is to be used in
|
||||
* production code, as otherwise the ARM may return the memory in a
|
||||
* rotated/rolled format, or the MMU may generate an alignment exception
|
||||
* if present and so configured.
|
||||
**************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* Includes
|
||||
***************************************************************************/
|
||||
|
||||
#include "backtrace.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Prototypes
|
||||
***************************************************************************/
|
||||
|
||||
static Boolean CliReport(void *data, Int32 address);
|
||||
static Boolean CliReadW(Int32 a, Int32 *v);
|
||||
static Boolean CliReadH(Int32 a, Int16 *v);
|
||||
static Boolean CliReadB(Int32 a, Int8 *v);
|
||||
|
||||
/***************************************************************************
|
||||
* Variables
|
||||
***************************************************************************/
|
||||
|
||||
/* Table of function pointers for passing to the unwinder */
|
||||
const UnwindCallbacks cliCallbacks =
|
||||
{
|
||||
CliReport,
|
||||
CliReadW,
|
||||
CliReadH,
|
||||
CliReadB
|
||||
#if defined(UNW_DEBUG)
|
||||
,printf
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Callbacks
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Function: CliReport
|
||||
*
|
||||
* Parameters: data - Pointer to data passed to UnwindStart()
|
||||
* address - The return address of a stack frame.
|
||||
*
|
||||
* Returns: TRUE if unwinding should continue, otherwise FALSE to
|
||||
* indicate that unwinding should stop.
|
||||
*
|
||||
* Description: This function is called from the unwinder each time a stack
|
||||
* frame has been unwound. The LSB of address indicates if
|
||||
* the processor is in ARM mode (LSB clear) or Thumb (LSB
|
||||
* set).
|
||||
*
|
||||
***************************************************************************/
|
||||
static Boolean CliReport(void *data, Int32 address)
|
||||
{
|
||||
/* CliStack *s = (CliStack *)data; */
|
||||
unsigned *line = (unsigned *)data;
|
||||
|
||||
|
||||
lcd_putsf(0, (*line)++, " %c: 0x%08x",
|
||||
(address & 0x1) ? 'T' : 'A',
|
||||
address & (~0x1));
|
||||
lcd_update();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Boolean CliReadW(const Int32 a, Int32 *v)
|
||||
{
|
||||
*v = *(Int32 *)a;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Boolean CliReadH(const Int32 a, Int16 *v)
|
||||
{
|
||||
*v = *(Int16 *)a;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Boolean CliReadB(const Int32 a, Int8 *v)
|
||||
{
|
||||
*v = *(Int8 *)a;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Boolean CliInvalidateW(const Int32 a)
|
||||
{
|
||||
*(Int32 *)a = 0xdeadbeef;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void backtrace(int pcAddr, int spAddr, unsigned *line)
|
||||
{
|
||||
UnwResult r;
|
||||
|
||||
lcd_putsf(0, (*line)++, "bt pc: 0x%08x, sp: 0x%08x", pcAddr, spAddr);
|
||||
lcd_update();
|
||||
|
||||
r = UnwindStart(pcAddr, spAddr, &cliCallbacks, (void *)line);
|
||||
|
||||
lcd_puts(0, (*line)++, "bt end");
|
||||
lcd_update();
|
||||
}
|
||||
|
||||
/* END OF FILE */
|
||||
Loading…
Add table
Add a link
Reference in a new issue