2012-01-25 08:57:59 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* 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"
|
2012-04-02 13:20:02 +00:00
|
|
|
#include "safe_read.h"
|
2012-01-25 08:57:59 +00:00
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* 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;
|
|
|
|
|
|
|
|
|
2012-05-27 22:51:47 +00:00
|
|
|
lcd_putsf(0, (*line)++, " %c: %08x",
|
2012-01-25 08:57:59 +00:00
|
|
|
(address & 0x1) ? 'T' : 'A',
|
|
|
|
address & (~0x1));
|
|
|
|
lcd_update();
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Boolean CliReadW(const Int32 a, Int32 *v)
|
|
|
|
{
|
2012-04-02 13:20:02 +00:00
|
|
|
return safe_read32((uint32_t *)a, (uint32_t *)v);
|
2012-01-25 08:57:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Boolean CliReadH(const Int32 a, Int16 *v)
|
|
|
|
{
|
2012-04-02 13:20:02 +00:00
|
|
|
return safe_read16((void *)a, (uint16_t *)v);
|
2012-01-25 08:57:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Boolean CliReadB(const Int32 a, Int8 *v)
|
|
|
|
{
|
2012-04-02 13:20:02 +00:00
|
|
|
return safe_read8((void *)a, (uint8_t *)v);
|
2012-01-25 08:57:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Boolean CliInvalidateW(const Int32 a)
|
|
|
|
{
|
|
|
|
*(Int32 *)a = 0xdeadbeef;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void backtrace(int pcAddr, int spAddr, unsigned *line)
|
|
|
|
{
|
2012-09-05 06:52:39 +00:00
|
|
|
lcd_putsf(0, (*line)++, "pc:%08x sp:%08x", pcAddr, spAddr);
|
2012-01-25 08:57:59 +00:00
|
|
|
lcd_update();
|
|
|
|
|
2014-08-25 18:07:19 +00:00
|
|
|
UnwindStart(pcAddr, spAddr, &cliCallbacks, (void *)line);
|
2012-01-25 08:57:59 +00:00
|
|
|
|
|
|
|
lcd_puts(0, (*line)++, "bt end");
|
|
|
|
lcd_update();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* END OF FILE */
|