Backtrace minor cleanup

This commit is contained in:
Scott Lahteine 2018-03-31 18:48:51 -05:00
parent 53f0c7522a
commit 889fd5f71f
4 changed files with 51 additions and 60 deletions

View File

@ -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
}; };
/** /**

View File

@ -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

View File

@ -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, &reg->v, &tracked)) { if (UnwMemHashRead(&state->memData, addr, &reg->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, &reg->v)) { // Not in the hash, so read from real memory
else if(state->cb->readW(addr, &reg->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

View File

@ -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 */