Backtrace minor cleanup
This commit is contained in:
parent
53f0c7522a
commit
889fd5f71f
@ -75,9 +75,7 @@ static void TX(char c) {
|
|||||||
|
|
||||||
// Send String through UART
|
// Send String through UART
|
||||||
static void TX(const char* s) {
|
static void TX(const char* s) {
|
||||||
while (*s) {
|
while (*s) TX(*s++);
|
||||||
TX(*s++);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TXDigit(uint32_t d) {
|
static void TXDigit(uint32_t d) {
|
||||||
@ -89,9 +87,8 @@ static void TXDigit(uint32_t d) {
|
|||||||
// Send Hex number thru UART
|
// Send Hex number thru UART
|
||||||
static void TXHex(uint32_t v) {
|
static void TXHex(uint32_t v) {
|
||||||
TX("0x");
|
TX("0x");
|
||||||
for (int i=0; i<8; i++, v <<= 4) {
|
for (uint8_t i = 0; i < 8; i++, v <<= 4)
|
||||||
TXDigit((v >> 28) & 0xF);
|
TXDigit((v >> 28) & 0xF);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send Decimal number thru UART
|
// Send Decimal number thru UART
|
||||||
@ -125,15 +122,15 @@ static bool UnwReportOut(void* ctx, const UnwReport* bte) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(UNW_DEBUG)
|
#ifdef UNW_DEBUG
|
||||||
void UnwPrintf(const char* format, ...) {
|
void UnwPrintf(const char* format, ...) {
|
||||||
char dest[256];
|
char dest[256];
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, format);
|
va_start(argptr, format);
|
||||||
vsprintf(dest, format, argptr);
|
vsprintf(dest, format, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
TX(&dest[0]);
|
TX(&dest[0]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Table of function pointers for passing to the unwinder */
|
/* Table of function pointers for passing to the unwinder */
|
||||||
@ -142,9 +139,9 @@ static const UnwindCallbacks UnwCallbacks = {
|
|||||||
UnwReadW,
|
UnwReadW,
|
||||||
UnwReadH,
|
UnwReadH,
|
||||||
UnwReadB
|
UnwReadB
|
||||||
#if defined(UNW_DEBUG)
|
#if defined(UNW_DEBUG)
|
||||||
,UnwPrintf
|
,UnwPrintf
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,26 +30,26 @@
|
|||||||
|
|
||||||
// Dump a backtrace entry
|
// Dump a backtrace entry
|
||||||
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
|
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
|
||||||
int* p = (int*)ctx;
|
int *p = (int*)ctx;
|
||||||
|
|
||||||
(*p)++;
|
(*p)++;
|
||||||
|
|
||||||
SERIAL_CHAR('#'); SERIAL_PRINT(*p,DEC); SERIAL_ECHOPGM(" : ");
|
SERIAL_CHAR('#'); SERIAL_PRINT(*p,DEC); SERIAL_ECHOPGM(" : ");
|
||||||
SERIAL_ECHOPGM(bte->name?bte->name:"unknown"); SERIAL_ECHOPGM("@0x"); SERIAL_PRINT(bte->function,HEX);
|
SERIAL_ECHOPGM(bte->name ? bte->name : "unknown"); SERIAL_ECHOPGM("@0x"); SERIAL_PRINT(bte->function, HEX);
|
||||||
SERIAL_CHAR('+'); SERIAL_PRINT(bte->address - bte->function,DEC);
|
SERIAL_CHAR('+'); SERIAL_PRINT(bte->address - bte->function,DEC);
|
||||||
SERIAL_ECHOPGM(" PC:"); SERIAL_PRINT(bte->address,HEX); SERIAL_CHAR('\n');
|
SERIAL_ECHOPGM(" PC:"); SERIAL_PRINT(bte->address,HEX); SERIAL_CHAR('\n');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(UNW_DEBUG)
|
#ifdef UNW_DEBUG
|
||||||
void UnwPrintf(const char* format, ...) {
|
void UnwPrintf(const char* format, ...) {
|
||||||
char dest[256];
|
char dest[256];
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, format);
|
va_start(argptr, format);
|
||||||
vsprintf(dest, format, argptr);
|
vsprintf(dest, format, argptr);
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
TX(&dest[0]);
|
TX(&dest[0]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Table of function pointers for passing to the unwinder */
|
/* Table of function pointers for passing to the unwinder */
|
||||||
@ -58,9 +58,9 @@ static const UnwindCallbacks UnwCallbacks = {
|
|||||||
UnwReadW,
|
UnwReadW,
|
||||||
UnwReadH,
|
UnwReadH,
|
||||||
UnwReadB
|
UnwReadB
|
||||||
#if defined(UNW_DEBUG)
|
#ifdef UNW_DEBUG
|
||||||
,UnwPrintf
|
, UnwPrintf
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void backtrace(void) {
|
void backtrace(void) {
|
||||||
@ -92,11 +92,8 @@ void backtrace(void) {
|
|||||||
UnwindStart(&btf, &UnwCallbacks, &ctr);
|
UnwindStart(&btf, &UnwCallbacks, &ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else // !__arm__ && !__thumb__
|
||||||
|
|
||||||
void backtrace(void) {}
|
void backtrace(void) {}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
#if defined(UNW_DEBUG)
|
#if defined(UNW_DEBUG)
|
||||||
|
|
||||||
/** Printf wrapper.
|
/**
|
||||||
|
* Printf wrapper.
|
||||||
* This is used such that alternative outputs for any output can be selected
|
* This is used such that alternative outputs for any output can be selected
|
||||||
* by modification of this wrapper function.
|
* by modification of this wrapper function.
|
||||||
*/
|
*/
|
||||||
@ -37,10 +38,10 @@ void UnwPrintf(const char *format, ...) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Invalidate all general purpose registers.
|
/**
|
||||||
|
* Invalidate all general purpose registers.
|
||||||
*/
|
*/
|
||||||
void UnwInvalidateRegisterFile(RegData *regFile) {
|
void UnwInvalidateRegisterFile(RegData *regFile) {
|
||||||
|
|
||||||
uint8_t t = 0;
|
uint8_t t = 0;
|
||||||
do {
|
do {
|
||||||
regFile[t].o = REG_VAL_INVALID;
|
regFile[t].o = REG_VAL_INVALID;
|
||||||
@ -49,7 +50,8 @@ void UnwInvalidateRegisterFile(RegData *regFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Initialise the data used for unwinding.
|
/**
|
||||||
|
* Initialise the data used for unwinding.
|
||||||
*/
|
*/
|
||||||
void UnwInitState(UnwState * const state, /**< Pointer to structure to fill. */
|
void UnwInitState(UnwState * const state, /**< Pointer to structure to fill. */
|
||||||
const UnwindCallbacks *cb, /**< Callbacks. */
|
const UnwindCallbacks *cb, /**< Callbacks. */
|
||||||
@ -77,12 +79,12 @@ void UnwInitState(UnwState * const state, /**< Pointer to structure to fill.
|
|||||||
|
|
||||||
// Detect if function names are available
|
// Detect if function names are available
|
||||||
static int __attribute__ ((noinline)) has_function_names(void) {
|
static int __attribute__ ((noinline)) has_function_names(void) {
|
||||||
|
|
||||||
uint32_t flag_word = ((uint32_t*)(((uint32_t)(&has_function_names)) & (-4))) [-1];
|
uint32_t flag_word = ((uint32_t*)(((uint32_t)(&has_function_names)) & (-4))) [-1];
|
||||||
return ((flag_word & 0xff000000) == 0xff000000) ? 1 : 0;
|
return ((flag_word & 0xff000000) == 0xff000000) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Call the report function to indicate some return address.
|
/**
|
||||||
|
* Call the report function to indicate some return address.
|
||||||
* This returns the value of the report function, which if true
|
* This returns the value of the report function, which if true
|
||||||
* indicates that unwinding may continue.
|
* indicates that unwinding may continue.
|
||||||
*/
|
*/
|
||||||
@ -108,11 +110,9 @@ bool UnwReportRetAddr(UnwState * const state, uint32_t addr) {
|
|||||||
while(state->cb->readW(pf-4,&v)) {
|
while(state->cb->readW(pf-4,&v)) {
|
||||||
|
|
||||||
// Check if name descriptor is valid
|
// Check if name descriptor is valid
|
||||||
if ((v & 0xffffff00) == 0xff000000 &&
|
if ((v & 0xFFFFFF00) == 0xFF000000 && (v & 0xFF) > 1) {
|
||||||
(v & 0xff) > 1) {
|
|
||||||
|
|
||||||
// Assume the name was found!
|
// Assume the name was found!
|
||||||
entry.name = ((const char*)pf) - 4 - (v & 0xff);
|
entry.name = ((const char*)pf) - 4 - (v & 0xFF);
|
||||||
entry.function = pf;
|
entry.function = pf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -129,7 +129,8 @@ bool UnwReportRetAddr(UnwState * const state, uint32_t addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Write some register to memory.
|
/**
|
||||||
|
* Write some register to memory.
|
||||||
* This will store some register and meta data onto the virtual stack.
|
* This will store some register and meta data onto the virtual stack.
|
||||||
* The address for the write
|
* The address for the write
|
||||||
* \param state [in/out] The unwinding state.
|
* \param state [in/out] The unwinding state.
|
||||||
@ -141,7 +142,8 @@ bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegD
|
|||||||
return UnwMemHashWrite(&state->memData, addr, reg->v, M_IsOriginValid(reg->o));
|
return UnwMemHashWrite(&state->memData, addr, reg->v, M_IsOriginValid(reg->o));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read a register from memory.
|
/**
|
||||||
|
* Read a register from memory.
|
||||||
* This will read a register from memory, and setup the meta data.
|
* This will read a register from memory, and setup the meta data.
|
||||||
* If the register has been previously written to memory using
|
* If the register has been previously written to memory using
|
||||||
* UnwMemWriteRegister, the local hash will be used to return the
|
* UnwMemWriteRegister, the local hash will be used to return the
|
||||||
@ -156,23 +158,18 @@ bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegD
|
|||||||
* false is the data could not be read.
|
* false is the data could not be read.
|
||||||
*/
|
*/
|
||||||
bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg) {
|
bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg) {
|
||||||
|
|
||||||
bool tracked;
|
bool tracked;
|
||||||
|
|
||||||
/* Check if the value can be found in the hash */
|
// Check if the value can be found in the hash
|
||||||
if(UnwMemHashRead(&state->memData, addr, ®->v, &tracked)) {
|
if (UnwMemHashRead(&state->memData, addr, ®->v, &tracked)) {
|
||||||
reg->o = tracked ? REG_VAL_FROM_MEMORY : REG_VAL_INVALID;
|
reg->o = tracked ? REG_VAL_FROM_MEMORY : REG_VAL_INVALID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* Not in the hash, so read from real memory */
|
else if (state->cb->readW(addr, ®->v)) { // Not in the hash, so read from real memory
|
||||||
else if(state->cb->readW(addr, ®->v)) {
|
|
||||||
reg->o = REG_VAL_FROM_MEMORY;
|
reg->o = REG_VAL_FROM_MEMORY;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* Not in the hash, and failed to read from memory */
|
else return false; // Not in the hash, and failed to read from memory
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -146,10 +146,10 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
bool (*readB)(const uint32_t address, uint8_t *val);
|
bool (*readB)(const uint32_t address, uint8_t *val);
|
||||||
|
|
||||||
#if defined(UNW_DEBUG)
|
#ifdef UNW_DEBUG
|
||||||
/** Print a formatted line for debug. */
|
/** Print a formatted line for debug. */
|
||||||
void (*printf)(const char *format, ...);
|
void (*printf)(const char *format, ...);
|
||||||
#endif
|
#endif
|
||||||
} UnwindCallbacks;
|
} UnwindCallbacks;
|
||||||
|
|
||||||
/* A frame */
|
/* A frame */
|
||||||
|
Loading…
Reference in New Issue
Block a user