Coding standards

This commit is contained in:
Scott Lahteine
2019-02-12 16:25:49 -06:00
parent 19af90face
commit 3a1b6fe8c1
43 changed files with 2033 additions and 2344 deletions

View File

@ -231,7 +231,7 @@ void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause
// Reset controller
NVIC_SystemReset();
while(1) { WDT_Restart(WDT); }
for (;;) WDT_Restart(WDT);
}
__attribute__((naked)) void NMI_Handler(void) {

View File

@ -95,7 +95,7 @@ void u8g_SetPILevel_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index, uint8_t level) {
}
uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch(msg) {
switch (msg) {
case U8G_COM_MSG_STOP:
break;

View File

@ -206,7 +206,7 @@ void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause
// Reset controller
NVIC_SystemReset();
while(1) { watchdog_init(); }
for (;;) watchdog_init();
}
extern "C" {

View File

@ -45,12 +45,11 @@
#define OUTPUT 1
#define INPUT_PULLUP 2
uint8_t LPC1768_PIN_PORT(const uint8_t pin);
uint8_t LPC1768_PIN_PIN(const uint8_t pin);
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
// I/O functions
@ -63,22 +62,21 @@ void pinMode_LCD(uint8_t pin, uint8_t mode) {
PINSEL_FUNC_0,
PINSEL_PINMODE_TRISTATE,
PINSEL_PINMODE_NORMAL };
switch(mode) {
case INPUT:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin));
PINSEL_ConfigPin(&config);
break;
case OUTPUT:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR |= LPC_PIN(LPC1768_PIN_PIN(pin));
PINSEL_ConfigPin(&config);
break;
case INPUT_PULLUP:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin));
config.Pinmode = PINSEL_PINMODE_PULLUP;
PINSEL_ConfigPin(&config);
break;
default:
break;
switch (mode) {
case INPUT:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin));
PINSEL_ConfigPin(&config);
break;
case OUTPUT:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR |= LPC_PIN(LPC1768_PIN_PIN(pin));
PINSEL_ConfigPin(&config);
break;
case INPUT_PULLUP:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin));
config.Pinmode = PINSEL_PINMODE_PULLUP;
PINSEL_ConfigPin(&config);
break;
default: break;
}
}
@ -105,7 +103,6 @@ uint8_t u8g_GetPinLevel(uint8_t pin) {
return (uint32_t)LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOPIN & LPC_PIN(LPC1768_PIN_PIN(pin)) ? 1 : 0;
}
#ifdef __cplusplus
}
#endif

View File

@ -95,9 +95,8 @@ uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) {
if (u8g->pin_list[U8G_PI_SET_A0] == 0) return 1;
/* setup bus, might be a repeated start */
if (u8g_i2c_start(I2C_SLA) == 0)
return 0;
if (u8g->pin_list[U8G_PI_A0_STATE] == 0 ) {
if (u8g_i2c_start(I2C_SLA) == 0) return 0;
if (u8g->pin_list[U8G_PI_A0_STATE] == 0) {
if (u8g_i2c_send_byte(I2C_CMD_MODE) == 0) return 0;
}
else if (u8g_i2c_send_byte(I2C_DATA_MODE) == 0)
@ -108,7 +107,7 @@ uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) {
}
uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch(msg) {
switch (msg) {
case U8G_COM_MSG_INIT:
//u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH);
//u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH);

View File

@ -91,7 +91,7 @@ static void u8g_com_LPC1768_st7920_write_byte_hw_spi(uint8_t rs, uint8_t val) {
}
uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch(msg) {
switch (msg) {
case U8G_COM_MSG_INIT:
u8g_SetPILevel(u8g, U8G_PI_CS, 0);
u8g_SetPIOutput(u8g, U8G_PI_CS);

View File

@ -89,10 +89,8 @@ static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) {
swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
}
uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
switch(msg)
{
uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch (msg) {
case U8G_COM_MSG_INIT:
SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK];
MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI];

View File

@ -72,7 +72,7 @@ static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin,
}
uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch(msg) {
switch (msg) {
case U8G_COM_MSG_INIT:
u8g_SetPIOutput(u8g, U8G_PI_SCK);
u8g_SetPIOutput(u8g, U8G_PI_MOSI);

View File

@ -58,7 +58,7 @@ uint8_t u8g_com_stm32duino_fsmc_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, voi
static uint8_t isCommand;
switch(msg) {
switch (msg) {
case U8G_COM_MSG_STOP:
break;
case U8G_COM_MSG_INIT:
@ -154,7 +154,7 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) {
if (fsmcInit) return;
fsmcInit = 1;
switch(cs) {
switch (cs) {
case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; break;
case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; break;
case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; break;
@ -164,7 +164,7 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) {
#define _ORADDR(N) controllerAddress |= (_BV32(N) - 2)
switch(rs) {
switch (rs) {
case FSMC_RS_A0: _ORADDR( 1); break;
case FSMC_RS_A1: _ORADDR( 2); break;
case FSMC_RS_A2: _ORADDR( 3); break;

View File

@ -71,7 +71,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch(timer_num) {
switch (timer_num) {
case 0: NVIC_ENABLE_IRQ(IRQ_FTM0); break;
case 1: NVIC_ENABLE_IRQ(IRQ_FTM1); break;
}
@ -98,7 +98,7 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
}
void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch(timer_num) {
switch (timer_num) {
case 0:
FTM0_CNT = 0x0000;
FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag

View File

@ -72,7 +72,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch(timer_num) {
switch (timer_num) {
case 0: NVIC_ENABLE_IRQ(IRQ_FTM0); break;
case 1: NVIC_ENABLE_IRQ(IRQ_FTM1); break;
}
@ -99,7 +99,7 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
}
void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch(timer_num) {
switch (timer_num) {
case 0:
FTM0_CNT = 0x0000;
FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag

View File

@ -76,7 +76,7 @@ void HAL_analog_pin_state(char buffer[], int8_t pin) {
*/
bool HAL_pwm_status(int8_t pin) {
char buffer[20]; // for the sprintf statements
switch(pin) {
switch (pin) {
FTM_CASE(0,0);
FTM_CASE(0,1);
FTM_CASE(0,2);

View File

@ -103,7 +103,7 @@ typedef struct {
* Macros
**************************************************************************/
#define M_IsOriginValid(v) (((v) & 0x7F) ? true : false)
#define M_IsOriginValid(v) !!((v) & 0x7F)
#define M_Origin2Str(v) ((v) ? "VALID" : "INVALID")
#ifdef UNW_DEBUG

View File

@ -32,23 +32,17 @@
* \retval false This is not a data-processing instruction,
*/
static bool isDataProc(uint32_t instr) {
uint8_t opcode = (instr & 0x01E00000) >> 21;
bool S = (instr & 0x00100000) ? true : false;
if ((instr & 0xFC000000) != 0xE0000000) return false;
if ((instr & 0xFC000000) != 0xE0000000) {
return false;
}
else if (!S && opcode >= 8 && opcode <= 11) {
/* TST, TEQ, CMP and CMN all require S to be set */
return false;
}
else
return true;
/* TST, TEQ, CMP and CMN all require S to be set */
bool S = !!(instr & 0x00100000);
if (!S && opcode >= 8 && opcode <= 11) return false;
return true;
}
UnwResult UnwStartArm(UnwState * const state) {
bool found = false;
uint16_t t = UNW_MAX_INSTR_COUNT;
@ -56,9 +50,8 @@ UnwResult UnwStartArm(UnwState * const state) {
uint32_t instr;
/* Attempt to read the instruction */
if (!state->cb->readW(state->regData[15].v, &instr)) {
if (!state->cb->readW(state->regData[15].v, &instr))
return UNWIND_IREAD_W_FAIL;
}
UnwPrintd4("A %x %x %08x:", state->regData[13].v, state->regData[15].v, instr);
@ -103,31 +96,20 @@ UnwResult UnwStartArm(UnwState * const state) {
}
/* Determine the return mode */
if (state->regData[rn].v & 0x1) {
/* Branching to THUMB */
if (state->regData[rn].v & 0x1) /* Branching to THUMB */
return UnwStartThumb(state);
}
else {
/* Branch to ARM */
/* Account for the auto-increment which isn't needed */
state->regData[15].v -= 4;
}
/* Branch to ARM */
/* Account for the auto-increment which isn't needed */
state->regData[15].v -= 4;
}
/* Branch */
else if ((instr & 0xFF000000) == 0xEA000000) {
int32_t offset = (instr & 0x00FFFFFF);
/* Shift value */
offset = offset << 2;
int32_t offset = (instr & 0x00FFFFFF) << 2;
/* Sign extend if needed */
if (offset & 0x02000000) {
offset |= 0xFC000000;
}
if (offset & 0x02000000) offset |= 0xFC000000;
UnwPrintd2("B %d\n", offset);
@ -142,11 +124,12 @@ UnwResult UnwStartArm(UnwState * const state) {
/* MRS */
else if ((instr & 0xFFBF0FFF) == 0xE10F0000) {
#ifdef UNW_DEBUG
bool R = (instr & 0x00400000) ? true : false;
#endif
#ifdef UNW_DEBUG
const bool R = !!(instr & 0x00400000);
#else
constexpr bool R = false;
#endif
uint8_t rd = (instr & 0x0000F000) >> 12;
UnwPrintd4("MRS r%d,%s\t; r%d invalidated", rd, R ? "SPSR" : "CPSR", rd);
/* Status registers untracked */
@ -154,11 +137,10 @@ UnwResult UnwStartArm(UnwState * const state) {
}
/* MSR */
else if ((instr & 0xFFB0F000) == 0xE120F000) {
#ifdef UNW_DEBUG
bool R = (instr & 0x00400000) ? true : false;
#ifdef UNW_DEBUG
UnwPrintd2("MSR %s_?, ???", (instr & 0x00400000) ? "SPSR" : "CPSR");
#endif
UnwPrintd2("MSR %s_?, ???", R ? "SPSR" : "CPSR");
#endif
/* Status registers untracked.
* Potentially this could change processor mode and switch
* banked registers r8-r14. Most likely is that r13 (sp) will
@ -170,18 +152,18 @@ UnwResult UnwStartArm(UnwState * const state) {
}
/* Data processing */
else if (isDataProc(instr)) {
bool I = (instr & 0x02000000) ? true : false;
bool I = !!(instr & 0x02000000);
uint8_t opcode = (instr & 0x01E00000) >> 21;
#ifdef UNW_DEBUG
bool S = (instr & 0x00100000) ? true : false;
#endif
#ifdef UNW_DEBUG
bool S = !!(instr & 0x00100000);
#endif
uint8_t rn = (instr & 0x000F0000) >> 16;
uint8_t rd = (instr & 0x0000F000) >> 12;
uint16_t operand2 = (instr & 0x00000FFF);
uint32_t op2val;
int op2origin;
switch(opcode) {
switch (opcode) {
case 0: UnwPrintd4("AND%s r%d,r%d,", S ? "S" : "", rd, rn); break;
case 1: UnwPrintd4("EOR%s r%d,r%d,", S ? "S" : "", rd, rn); break;
case 2: UnwPrintd4("SUB%s r%d,r%d,", S ? "S" : "", rd, rn); break;
@ -217,26 +199,23 @@ UnwResult UnwStartArm(UnwState * const state) {
/* Register and shift */
uint8_t rm = (operand2 & 0x000F);
uint8_t regShift = (operand2 & 0x0010) ? true : false;
uint8_t regShift = !!(operand2 & 0x0010);
uint8_t shiftType = (operand2 & 0x0060) >> 5;
uint32_t shiftDist;
#ifdef UNW_DEBUG
const char * const shiftMnu[4] = { "LSL", "LSR", "ASR", "ROR" };
#endif
#ifdef UNW_DEBUG
const char * const shiftMnu[4] = { "LSL", "LSR", "ASR", "ROR" };
#endif
UnwPrintd2("r%d ", rm);
/* Get the shift distance */
if (regShift) {
uint8_t rs = (operand2 & 0x0F00) >> 8;
if (operand2 & 0x00800) {
UnwPrintd1("\nError: Bit should be zero\n");
return UNWIND_ILLEGAL_INSTR;
}
else if (rs == 15) {
UnwPrintd1("\nError: Cannot use R15 with register shift\n");
return UNWIND_ILLEGAL_INSTR;
}
@ -250,46 +229,33 @@ UnwResult UnwStartArm(UnwState * const state) {
else {
shiftDist = (operand2 & 0x0F80) >> 7;
op2origin = REG_VAL_FROM_CONST;
if (shiftDist) {
UnwPrintd3("%s #%d", shiftMnu[shiftType], shiftDist);
}
if (shiftDist) UnwPrintd3("%s #%d", shiftMnu[shiftType], shiftDist);
UnwPrintd3("\t; r%d %s", rm, M_Origin2Str(state->regData[rm].o));
}
/* Apply the shift type to the source register */
switch(shiftType) {
switch (shiftType) {
case 0: /* logical left */
op2val = state->regData[rm].v << shiftDist;
break;
case 1: /* logical right */
if (!regShift && shiftDist == 0) {
shiftDist = 32;
}
if (!regShift && shiftDist == 0) shiftDist = 32;
op2val = state->regData[rm].v >> shiftDist;
break;
case 2: /* arithmetic right */
if (!regShift && shiftDist == 0) {
shiftDist = 32;
}
if (!regShift && shiftDist == 0) shiftDist = 32;
if (state->regData[rm].v & 0x80000000) {
/* Register shifts maybe greater than 32 */
if (shiftDist >= 32) {
if (shiftDist >= 32)
op2val = 0xFFFFFFFF;
}
else {
op2val = state->regData[rm].v >> shiftDist;
op2val |= 0xFFFFFFFF << (32 - shiftDist);
}
else
op2val = (state->regData[rm].v >> shiftDist) | (0xFFFFFFFF << (32 - shiftDist));
}
else {
else
op2val = state->regData[rm].v >> shiftDist;
}
break;
case 3: /* rotate right */
@ -317,19 +283,14 @@ UnwResult UnwStartArm(UnwState * const state) {
}
/* Decide the data origin */
if (M_IsOriginValid(op2origin) &&
M_IsOriginValid(state->regData[rm].o)) {
op2origin = state->regData[rm].o;
op2origin |= REG_VAL_ARITHMETIC;
}
else {
if (M_IsOriginValid(op2origin) && M_IsOriginValid(state->regData[rm].o))
op2origin = REG_VAL_ARITHMETIC | state->regData[rm].o;
else
op2origin = REG_VAL_INVALID;
}
}
/* Propagate register validity */
switch(opcode) {
switch (opcode) {
case 0: /* AND: Rd := Op1 AND Op2 */
case 1: /* EOR: Rd := Op1 EOR Op2 */
case 2: /* SUB: Rd:= Op1 - Op2 */
@ -374,14 +335,11 @@ UnwResult UnwStartArm(UnwState * const state) {
* to specify the shift amount the PC will be 12 bytes
* ahead.
*/
if (!I && (operand2 & 0x0010))
state->regData[rn].v += 12;
else
state->regData[rn].v += 8;
state->regData[rn].v += ((!I && (operand2 & 0x0010)) ? 12 : 8);
}
/* Compute values */
switch(opcode) {
switch (opcode) {
case 0: /* AND: Rd := Op1 AND Op2 */
state->regData[rd].v = state->regData[rn].v & op2val;
break;
@ -429,12 +387,8 @@ UnwResult UnwStartArm(UnwState * const state) {
}
/* Remove the prefetch offset from the PC */
if (rd != 15 && rn == 15) {
if (!I && (operand2 & 0x0010))
state->regData[rn].v -= 12;
else
state->regData[rn].v -= 8;
}
if (rd != 15 && rn == 15)
state->regData[rn].v -= ((!I && (operand2 & 0x0010)) ? 12 : 8);
}
/* Block Data Transfer
@ -442,26 +396,25 @@ UnwResult UnwStartArm(UnwState * const state) {
*/
else if ((instr & 0xFE000000) == 0xE8000000) {
bool P = (instr & 0x01000000) ? true : false;
bool U = (instr & 0x00800000) ? true : false;
bool S = (instr & 0x00400000) ? true : false;
bool W = (instr & 0x00200000) ? true : false;
bool L = (instr & 0x00100000) ? true : false;
bool P = !!(instr & 0x01000000),
U = !!(instr & 0x00800000),
S = !!(instr & 0x00400000),
W = !!(instr & 0x00200000),
L = !!(instr & 0x00100000);
uint16_t baseReg = (instr & 0x000F0000) >> 16;
uint16_t regList = (instr & 0x0000FFFF);
uint32_t addr = state->regData[baseReg].v;
bool addrValid = M_IsOriginValid(state->regData[baseReg].o);
int8_t r;
#ifdef UNW_DEBUG
/* Display the instruction */
if (L) {
UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : "");
}
else {
UnwPrintd6("STM%c%c r%d%s, {reglist}%s\n", !P ? 'E' : 'F', !U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : "");
}
#endif
#ifdef UNW_DEBUG
/* Display the instruction */
if (L)
UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : "");
else
UnwPrintd6("STM%c%c r%d%s, {reglist}%s\n", !P ? 'E' : 'F', !U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : "");
#endif
/* S indicates that banked registers (untracked) are used, unless
* this is a load including the PC when the S-bit indicates that
* that CPSR is loaded from SPSR (also untracked, but ignored).
@ -489,44 +442,35 @@ UnwResult UnwStartArm(UnwState * const state) {
/* Check if the register is to be transferred */
if (regList & (0x01 << r)) {
if (P)
addr += U ? 4 : -4;
if (P) addr += U ? 4 : -4;
if (L) {
if (addrValid) {
if (!UnwMemReadRegister(state, addr, &state->regData[r])) {
if (!UnwMemReadRegister(state, addr, &state->regData[r]))
return UNWIND_DREAD_W_FAIL;
}
/* Update the origin if read via the stack pointer */
if (M_IsOriginValid(state->regData[r].o) && baseReg == 13) {
if (M_IsOriginValid(state->regData[r].o) && baseReg == 13)
state->regData[r].o = REG_VAL_FROM_STACK;
}
UnwPrintd5(" R%d = 0x%08x\t; r%d %s\n",r,state->regData[r].v,r, M_Origin2Str(state->regData[r].o));
}
else {
/* Invalidate the register as the base reg was invalid */
state->regData[r].o = REG_VAL_INVALID;
UnwPrintd2(" R%d = ???\n", r);
}
}
else {
if (addrValid) {
if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) {
return UNWIND_DWRITE_W_FAIL;
}
}
if (addrValid && !UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r]))
return UNWIND_DWRITE_W_FAIL;
UnwPrintd2(" R%d = 0x%08x\n", r);
}
if (!P)
addr += U ? 4 : -4;
if (!P) addr += U ? 4 : -4;
}
/* Check the next register */
@ -535,8 +479,7 @@ UnwResult UnwStartArm(UnwState * const state) {
} while (r >= 0 && r <= 15);
/* Check the writeback bit */
if (W)
state->regData[baseReg].v = addr;
if (W) state->regData[baseReg].v = addr;
/* Check if the PC was loaded */
if (L && (regList & (0x01 << 15))) {
@ -547,9 +490,8 @@ UnwResult UnwStartArm(UnwState * const state) {
}
else {
/* Store the return address */
if (!UnwReportRetAddr(state, state->regData[15].v)) {
if (!UnwReportRetAddr(state, state->regData[15].v))
return UNWIND_TRUNCATED;
}
UnwPrintd2(" Return PC=0x%x", state->regData[15].v);
@ -585,9 +527,7 @@ UnwResult UnwStartArm(UnwState * const state) {
/* Garbage collect the memory hash (used only for the stack) */
UnwMemHashGC(state);
t--;
if (t == 0)
return UNWIND_EXHAUSTED;
if (--t == 0) return UNWIND_EXHAUSTED;
} while (!found);

View File

@ -25,17 +25,11 @@
* \param value The value to sign extend.
* \return The signed-11 bit value stored in a 16bit data type.
*/
static int32_t signExtend11(uint16_t value) {
if(value & 0x400) {
value |= 0xFFFFF800;
}
return value;
static int32_t signExtend11(const uint16_t value) {
return (value & 0x400) ? value | 0xFFFFF800 : value;
}
UnwResult UnwStartThumb(UnwState * const state) {
bool found = false;
uint16_t t = UNW_MAX_INSTR_COUNT;
uint32_t lastJumpAddr = 0; // Last JUMP address, to try to detect infinite loops
@ -45,20 +39,19 @@ UnwResult UnwStartThumb(UnwState * const state) {
uint16_t instr;
/* Attempt to read the instruction */
if(!state->cb->readH(state->regData[15].v & (~0x1), &instr)) {
if (!state->cb->readH(state->regData[15].v & (~0x1), &instr))
return UNWIND_IREAD_H_FAIL;
}
UnwPrintd4("T %x %x %04x:", state->regData[13].v, state->regData[15].v, instr);
/* Check that the PC is still on Thumb alignment */
if(!(state->regData[15].v & 0x1)) {
if (!(state->regData[15].v & 0x1)) {
UnwPrintd1("\nError: PC misalignment\n");
return UNWIND_INCONSISTENT;
}
/* Check that the SP and PC have not been invalidated */
if(!M_IsOriginValid(state->regData[13].o) || !M_IsOriginValid(state->regData[15].o)) {
if (!M_IsOriginValid(state->regData[13].o) || !M_IsOriginValid(state->regData[15].o)) {
UnwPrintd1("\nError: PC or SP invalidated\n");
return UNWIND_INCONSISTENT;
}
@ -73,9 +66,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
state->regData[15].v += 2;
/* Attempt to read the 2nd part of the instruction */
if(!state->cb->readH(state->regData[15].v & (~0x1), &instr2)) {
if (!state->cb->readH(state->regData[15].v & (~0x1), &instr2))
return UNWIND_IREAD_H_FAIL;
}
UnwPrintd3(" %x %04x:", state->regData[15].v, instr2);
@ -84,26 +76,25 @@ UnwResult UnwStartThumb(UnwState * const state) {
* PUSH and POP
*/
if ((instr & 0xFE6F) == 0xE82D) {
bool L = (instr & 0x10) ? true : false;
bool L = !!(instr & 0x10);
uint16_t rList = instr2;
if(L) {
if (L) {
uint8_t r;
/* Load from memory: POP */
UnwPrintd1("POP {Rlist}\n");
/* Load registers from stack */
for(r = 0; r < 16; r++) {
if(rList & (0x1 << r)) {
for (r = 0; r < 16; r++) {
if (rList & (0x1 << r)) {
/* Read the word */
if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) {
if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r]))
return UNWIND_DREAD_W_FAIL;
}
/* Alter the origin to be from the stack if it was valid */
if(M_IsOriginValid(state->regData[r].o)) {
if (M_IsOriginValid(state->regData[r].o)) {
state->regData[r].o = REG_VAL_FROM_STACK;
@ -114,7 +105,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
* the caller was from Thumb. This would allow return
* by BX for interworking APCS.
*/
if((state->regData[15].v & 0x1) == 0) {
if ((state->regData[15].v & 0x1) == 0) {
UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v);
/* Pop into the PC will not switch mode */
@ -122,9 +113,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
}
/* Store the return address */
if(!UnwReportRetAddr(state, state->regData[15].v)) {
if (!UnwReportRetAddr(state, state->regData[15].v))
return UNWIND_TRUNCATED;
}
/* Now have the return address */
UnwPrintd2(" Return PC=%x\n", state->regData[15].v);
@ -155,15 +145,14 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* Store to memory: PUSH */
UnwPrintd1("PUSH {Rlist}");
for(r = 15; r >= 0; r--) {
if(rList & (0x1 << r)) {
for (r = 15; r >= 0; r--) {
if (rList & (0x1 << r)) {
UnwPrintd4("\n r%d = 0x%08x\t; %s", r, state->regData[r].v, M_Origin2Str(state->regData[r].o));
state->regData[13].v -= 4;
if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) {
if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r]))
return UNWIND_DWRITE_W_FAIL;
}
}
}
}
@ -180,9 +169,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
state->regData[13].v -= 4;
if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) {
if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r]))
return UNWIND_DWRITE_W_FAIL;
}
}
/*
* POP register
@ -194,12 +182,11 @@ UnwResult UnwStartThumb(UnwState * const state) {
UnwPrintd2("POP {R%d}\n", r);
/* Read the word */
if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) {
if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r]))
return UNWIND_DREAD_W_FAIL;
}
/* Alter the origin to be from the stack if it was valid */
if(M_IsOriginValid(state->regData[r].o)) {
if (M_IsOriginValid(state->regData[r].o)) {
state->regData[r].o = REG_VAL_FROM_STACK;
@ -210,7 +197,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
* the caller was from Thumb. This would allow return
* by BX for interworking APCS.
*/
if((state->regData[15].v & 0x1) == 0) {
if ((state->regData[15].v & 0x1) == 0) {
UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v);
/* Pop into the PC will not switch mode */
@ -218,9 +205,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
}
/* Store the return address */
if(!UnwReportRetAddr(state, state->regData[15].v)) {
if (!UnwReportRetAddr(state, state->regData[15].v))
return UNWIND_TRUNCATED;
}
/* Now have the return address */
UnwPrintd2(" Return PC=%x\n", state->regData[15].v);
@ -255,7 +241,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
* the switch clauses
*/
uint8_t rn = instr & 0xF;
bool H = (instr2 & 0x10) ? true : false;
bool H = !!(instr2 & 0x10);
UnwPrintd5("TB%c [r%d,r%d%s]\n", H ? 'H' : 'B', rn, (instr2 & 0xF), H ? ",LSL #1" : "");
@ -263,15 +249,14 @@ UnwResult UnwStartThumb(UnwState * const state) {
if (rn == 15) {
if (H) {
uint16_t rv;
if(!state->cb->readH((state->regData[15].v & (~1)) + 2, &rv)) {
if (!state->cb->readH((state->regData[15].v & (~1)) + 2, &rv))
return UNWIND_DREAD_H_FAIL;
}
state->regData[15].v += rv * 2;
} else {
}
else {
uint8_t rv;
if(!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv)) {
if (!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv))
return UNWIND_DREAD_B_FAIL;
}
state->regData[15].v += rv * 2;
}
}
@ -355,12 +340,11 @@ UnwResult UnwStartThumb(UnwState * const state) {
UnwPrintd2(" Return PC=%x", state->regData[15].v);
/* Report the return address, including mode bit */
if(!UnwReportRetAddr(state, state->regData[15].v)) {
if (!UnwReportRetAddr(state, state->regData[15].v))
return UNWIND_TRUNCATED;
}
/* Determine the new mode */
if(state->regData[15].v & 0x1) {
if (state->regData[15].v & 0x1) {
/* Branching to THUMB */
/* Account for the auto-increment which isn't needed */
@ -411,10 +395,10 @@ UnwResult UnwStartThumb(UnwState * const state) {
* PC-relative load
* LDR Rd,[PC, #+/-imm]
*/
else if((instr & 0xFF7F) == 0xF85F) {
else if ((instr & 0xFF7F) == 0xF85F) {
uint8_t rt = (instr2 & 0xF000) >> 12;
uint8_t imm12 = (instr2 & 0x0FFF);
bool A = (instr & 0x80) ? true : false;
bool A = !!(instr & 0x80);
uint32_t address;
/* Compute load address, adding a word to account for prefetch */
@ -424,9 +408,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
UnwPrintd4("LDR r%d,[PC #%c0x%08x]", rt, A?'+':'-', address);
if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
if (!UnwMemReadRegister(state, address, &state->regData[rt]))
return UNWIND_DREAD_W_FAIL;
}
}
/*
* LDR immediate.
@ -441,11 +424,11 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* If destination is PC and we don't know the source value, then fail */
if (!M_IsOriginValid(state->regData[rn].o)) {
state->regData[rt].o = state->regData[rn].o;
} else {
}
else {
uint32_t address = state->regData[rn].v + imm12;
if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
if (!UnwMemReadRegister(state, address, &state->regData[rt]))
return UNWIND_DREAD_W_FAIL;
}
}
}
/*
@ -459,31 +442,20 @@ UnwResult UnwStartThumb(UnwState * const state) {
uint8_t rn = (instr & 0xF);
uint8_t rt = (instr2 & 0xF000) >> 12;
uint16_t imm8 = (instr2 & 0xFF);
bool P = (instr2 & 0x400) ? true : false;
bool U = (instr2 & 0x200) ? true : false;
bool W = (instr2 & 0x100) ? true : false;
bool P = !!(instr2 & 0x400);
bool U = !!(instr2 & 0x200);
bool W = !!(instr2 & 0x100);
if (!M_IsOriginValid(state->regData[rn].o)) {
if (!M_IsOriginValid(state->regData[rn].o))
state->regData[rt].o = state->regData[rn].o;
} else {
uint32_t offaddress = state->regData[rn].v + imm8;
if (U) offaddress += imm8;
else offaddress -= imm8;
else {
uint32_t offaddress = state->regData[rn].v + (U ? imm8 + imm8 : 0),
address = P ? offaddress : state->regData[rn].v;
uint32_t address;
if (P) {
address = offaddress;
} else {
address = state->regData[rn].v;
}
if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
if (!UnwMemReadRegister(state, address, &state->regData[rt]))
return UNWIND_DREAD_W_FAIL;
}
if (W) {
state->regData[rn].v = offaddress;
}
if (W) state->regData[rn].v = offaddress;
}
}
/*
@ -493,30 +465,28 @@ UnwResult UnwStartThumb(UnwState * const state) {
* Where Rt is PC, Rn value is known, Rm is not known or unknown
*/
else if ((instr & 0xFFF0) == 0xF850 && (instr2 & 0x0FC0) == 0x0000) {
uint8_t rn = (instr & 0xF);
uint8_t rt = (instr2 & 0xF000) >> 12;
uint8_t rm = (instr2 & 0xF);
uint8_t imm2 = (instr2 & 0x30) >> 4;
const uint8_t rn = (instr & 0xF),
rt = (instr2 & 0xF000) >> 12,
rm = (instr2 & 0xF),
imm2 = (instr2 & 0x30) >> 4;
if (!M_IsOriginValid(state->regData[rn].o) ||
!M_IsOriginValid(state->regData[rm].o)) {
if (!M_IsOriginValid(state->regData[rn].o) || !M_IsOriginValid(state->regData[rm].o)) {
/* If Rt is PC, and Rn is known, then do an exception and assume
Rm equals 0 => This takes the first case in a switch() */
if (rt == 15 && M_IsOriginValid(state->regData[rn].o)) {
uint32_t address = state->regData[rn].v;
if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
if (!UnwMemReadRegister(state, address, &state->regData[rt]))
return UNWIND_DREAD_W_FAIL;
}
} else {
/* Propagate unknown value */
}
else /* Propagate unknown value */
state->regData[rt].o = state->regData[rn].o;
}
} else {
}
else {
uint32_t address = state->regData[rn].v + (state->regData[rm].v << imm2);
if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
if (!UnwMemReadRegister(state, address, &state->regData[rt]))
return UNWIND_DREAD_W_FAIL;
}
}
}
else {
@ -533,14 +503,14 @@ UnwResult UnwStartThumb(UnwState * const state) {
* LSR Rd, Rs, #Offset5
* ASR Rd, Rs, #Offset5
*/
else if((instr & 0xE000) == 0x0000 && (instr & 0x1800) != 0x1800) {
else if ((instr & 0xE000) == 0x0000 && (instr & 0x1800) != 0x1800) {
bool signExtend;
uint8_t op = (instr & 0x1800) >> 11;
uint8_t offset5 = (instr & 0x07C0) >> 6;
uint8_t rs = (instr & 0x0038) >> 3;
uint8_t rd = (instr & 0x0007);
const uint8_t op = (instr & 0x1800) >> 11,
offset5 = (instr & 0x07C0) >> 6,
rs = (instr & 0x0038) >> 3,
rd = (instr & 0x0007);
switch(op) {
switch (op) {
case 0: /* LSL */
UnwPrintd6("LSL r%d, r%d, #%d\t; r%d %s", rd, rs, offset5, rs, M_Origin2Str(state->regData[rs].o));
state->regData[rd].v = state->regData[rs].v << offset5;
@ -558,11 +528,9 @@ UnwResult UnwStartThumb(UnwState * const state) {
case 2: /* ASR */
UnwPrintd6("ASL r%d, r%d, #%d\t; r%d %s", rd, rs, offset5, rs, M_Origin2Str(state->regData[rs].o));
signExtend = (state->regData[rs].v & 0x8000) ? true : false;
signExtend = !!(state->regData[rs].v & 0x8000);
state->regData[rd].v = state->regData[rs].v >> offset5;
if(signExtend) {
state->regData[rd].v |= 0xFFFFFFFF << (32 - offset5);
}
if (signExtend) state->regData[rd].v |= 0xFFFFFFFF << (32 - offset5);
state->regData[rd].o = state->regData[rs].o;
state->regData[rd].o |= REG_VAL_ARITHMETIC;
break;
@ -574,9 +542,9 @@ UnwResult UnwStartThumb(UnwState * const state) {
* SUB Rd, Rs, Rn
* SUB Rd, Rs, #Offset3
*/
else if((instr & 0xF800) == 0x1800) {
bool I = (instr & 0x0400) ? true : false;
bool op = (instr & 0x0200) ? true : false;
else if ((instr & 0xF800) == 0x1800) {
bool I = !!(instr & 0x0400);
bool op = !!(instr & 0x0200);
uint8_t rn = (instr & 0x01C0) >> 6;
uint8_t rs = (instr & 0x0038) >> 3;
uint8_t rd = (instr & 0x0007);
@ -584,36 +552,24 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* Print decoding */
UnwPrintd6("%s r%d, r%d, %c%d\t;",op ? "SUB" : "ADD",rd, rs,I ? '#' : 'r',rn);
UnwPrintd5("r%d %s, r%d %s",rd, M_Origin2Str(state->regData[rd].o),rs, M_Origin2Str(state->regData[rs].o));
if(!I) {
if (!I) {
UnwPrintd3(", r%d %s", rn, M_Origin2Str(state->regData[rn].o));
/* Perform calculation */
if(op) {
state->regData[rd].v = state->regData[rs].v - state->regData[rn].v;
}
else {
state->regData[rd].v = state->regData[rs].v + state->regData[rn].v;
}
state->regData[rd].v = state->regData[rs].v + (op ? -state->regData[rn].v : state->regData[rn].v);
/* Propagate the origin */
if(M_IsOriginValid(state->regData[rs].o) &&
M_IsOriginValid(state->regData[rn].o)) {
if (M_IsOriginValid(state->regData[rs].o) && M_IsOriginValid(state->regData[rn].o)) {
state->regData[rd].o = state->regData[rs].o;
state->regData[rd].o |= REG_VAL_ARITHMETIC;
}
else {
else
state->regData[rd].o = REG_VAL_INVALID;
}
}
else {
/* Perform calculation */
if(op) {
state->regData[rd].v = state->regData[rs].v - rn;
}
else {
state->regData[rd].v = state->regData[rs].v + rn;
}
state->regData[rd].v = state->regData[rs].v + (op ? -rn : rn);
/* Propagate the origin */
state->regData[rd].o = state->regData[rs].o;
@ -626,13 +582,13 @@ UnwResult UnwStartThumb(UnwState * const state) {
* ADD Rd, #Offset8
* SUB Rd, #Offset8
*/
else if((instr & 0xE000) == 0x2000) {
else if ((instr & 0xE000) == 0x2000) {
uint8_t op = (instr & 0x1800) >> 11;
uint8_t rd = (instr & 0x0700) >> 8;
uint8_t offset8 = (instr & 0x00FF);
switch(op) {
switch (op) {
case 0: /* MOV */
UnwPrintd3("MOV r%d, #0x%x", rd, offset8);
state->regData[rd].v = offset8;
@ -675,7 +631,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
* BIC Rd, Rs
* MVN Rd, Rs
*/
else if((instr & 0xFC00) == 0x4000) {
else if ((instr & 0xFC00) == 0x4000) {
uint8_t op = (instr & 0x03C0) >> 6;
uint8_t rs = (instr & 0x0038) >> 3;
uint8_t rd = (instr & 0x0007);
@ -688,7 +644,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
"ORR", "MUL", "BIC", "MVN" };
#endif
/* Print the mnemonic and registers */
switch(op) {
switch (op) {
case 0: /* AND */
case 1: /* EOR */
case 2: /* LSL */
@ -720,7 +676,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
}
/* Perform operation */
switch(op) {
switch (op) {
case 0: /* AND */
state->regData[rd].v &= state->regData[rs].v;
break;
@ -738,7 +694,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
break;
case 4: /* ASR */
if(state->regData[rd].v & 0x80000000) {
if (state->regData[rd].v & 0x80000000) {
state->regData[rd].v >>= state->regData[rs].v;
state->regData[rd].v |= 0xFFFFFFFF << (32 - state->regData[rs].v);
}
@ -782,7 +738,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
}
/* Propagate data origins */
switch(op) {
switch (op) {
case 0: /* AND */
case 1: /* EOR */
case 2: /* LSL */
@ -792,13 +748,12 @@ UnwResult UnwStartThumb(UnwState * const state) {
case 12: /* ORR */
case 13: /* MUL */
case 14: /* BIC */
if(M_IsOriginValid(state->regData[rd].o) && M_IsOriginValid(state->regData[rs].o)) {
if (M_IsOriginValid(state->regData[rd].o) && M_IsOriginValid(state->regData[rs].o)) {
state->regData[rd].o = state->regData[rs].o;
state->regData[rd].o |= REG_VAL_ARITHMETIC;
}
else {
else
state->regData[rd].o = REG_VAL_INVALID;
}
break;
case 5: /* ADC */
@ -825,7 +780,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
* CMP Hd, Rs
* MOV Hd, Hs
*/
else if((instr & 0xFC00) == 0x4400) {
else if ((instr & 0xFC00) == 0x4400) {
uint8_t op = (instr & 0x0300) >> 8;
bool h1 = (instr & 0x0080) ? true: false;
bool h2 = (instr & 0x0040) ? true: false;
@ -833,12 +788,10 @@ UnwResult UnwStartThumb(UnwState * const state) {
uint8_t rhd = (instr & 0x0007);
/* Adjust the register numbers */
if(h2)
rhs += 8;
if(h1)
rhd += 8;
if (h2) rhs += 8;
if (h1) rhd += 8;
switch(op) {
switch (op) {
case 0: /* ADD */
UnwPrintd5("ADD r%d, r%d\t; r%d %s", rhd, rhs, rhs, M_Origin2Str(state->regData[rhs].o));
state->regData[rhd].v += state->regData[rhs].v;
@ -861,28 +814,25 @@ UnwResult UnwStartThumb(UnwState * const state) {
UnwPrintd4("BX r%d\t; r%d %s\n", rhs, rhs, M_Origin2Str(state->regData[rhs].o));
/* Only follow BX if the data was from the stack or BX LR */
if(rhs == 14 || state->regData[rhs].o == REG_VAL_FROM_STACK) {
if (rhs == 14 || state->regData[rhs].o == REG_VAL_FROM_STACK) {
UnwPrintd2(" Return PC=0x%x\n", state->regData[rhs].v & (~0x1));
/* Report the return address, including mode bit */
if(!UnwReportRetAddr(state, state->regData[rhs].v)) {
if (!UnwReportRetAddr(state, state->regData[rhs].v))
return UNWIND_TRUNCATED;
}
/* Update the PC */
state->regData[15].v = state->regData[rhs].v;
/* Determine the new mode */
if(state->regData[rhs].v & 0x1) {
if (state->regData[rhs].v & 0x1) {
/* Branching to THUMB */
/* Account for the auto-increment which isn't needed */
state->regData[15].v -= 2;
}
else {
/* Branch to ARM */
else /* Branch to ARM */
return UnwStartArm(state);
}
}
else {
UnwPrintd4("\nError: BX to invalid register: r%d = 0x%x (%s)\n", rhs, state->regData[rhs].o, M_Origin2Str(state->regData[rhs].o));
@ -893,7 +843,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* Format 9: PC-relative load
* LDR Rd,[PC, #imm]
*/
else if((instr & 0xF800) == 0x4800) {
else if ((instr & 0xF800) == 0x4800) {
uint8_t rd = (instr & 0x0700) >> 8;
uint8_t word8 = (instr & 0x00FF);
uint32_t address;
@ -903,19 +853,18 @@ UnwResult UnwStartThumb(UnwState * const state) {
UnwPrintd3("LDR r%d, 0x%08x", rd, address);
if(!UnwMemReadRegister(state, address, &state->regData[rd])) {
if (!UnwMemReadRegister(state, address, &state->regData[rd]))
return UNWIND_DREAD_W_FAIL;
}
}
/* Format 13: add offset to Stack Pointer
* ADD sp,#+imm
* ADD sp,#-imm
*/
else if((instr & 0xFF00) == 0xB000) {
else if ((instr & 0xFF00) == 0xB000) {
uint8_t value = (instr & 0x7F) * 4;
/* Check the negative bit */
if((instr & 0x80) != 0) {
if ((instr & 0x80) != 0) {
UnwPrintd2("SUB sp,#0x%x", value);
state->regData[13].v -= value;
}
@ -930,29 +879,27 @@ UnwResult UnwStartThumb(UnwState * const state) {
* POP {Rlist}
* POP {Rlist, PC}
*/
else if((instr & 0xF600) == 0xB400) {
bool L = (instr & 0x0800) ? true : false;
bool R = (instr & 0x0100) ? true : false;
else if ((instr & 0xF600) == 0xB400) {
bool L = !!(instr & 0x0800);
bool R = !!(instr & 0x0100);
uint8_t rList = (instr & 0x00FF);
if(L) {
if (L) {
uint8_t r;
/* Load from memory: POP */
UnwPrintd2("POP {Rlist%s}\n", R ? ", PC" : "");
for(r = 0; r < 8; r++) {
if(rList & (0x1 << r)) {
for (r = 0; r < 8; r++) {
if (rList & (0x1 << r)) {
/* Read the word */
if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) {
if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r]))
return UNWIND_DREAD_W_FAIL;
}
/* Alter the origin to be from the stack if it was valid */
if(M_IsOriginValid(state->regData[r].o)) {
if (M_IsOriginValid(state->regData[r].o))
state->regData[r].o = REG_VAL_FROM_STACK;
}
state->regData[13].v += 4;
@ -961,14 +908,13 @@ UnwResult UnwStartThumb(UnwState * const state) {
}
/* Check if the PC is to be popped */
if(R) {
if (R) {
/* Get the return address */
if(!UnwMemReadRegister(state, state->regData[13].v, &state->regData[15])) {
if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[15]))
return UNWIND_DREAD_W_FAIL;
}
/* Alter the origin to be from the stack if it was valid */
if(!M_IsOriginValid(state->regData[15].o)) {
if (!M_IsOriginValid(state->regData[15].o)) {
/* Return address is not valid */
UnwPrintd1("PC popped with invalid address\n");
return UNWIND_FAILURE;
@ -978,7 +924,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
* the caller was from Thumb. This would allow return
* by BX for interworking APCS.
*/
if((state->regData[15].v & 0x1) == 0) {
if ((state->regData[15].v & 0x1) == 0) {
UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v);
/* Pop into the PC will not switch mode */
@ -986,9 +932,8 @@ UnwResult UnwStartThumb(UnwState * const state) {
}
/* Store the return address */
if(!UnwReportRetAddr(state, state->regData[15].v)) {
if (!UnwReportRetAddr(state, state->regData[15].v))
return UNWIND_TRUNCATED;
}
/* Now have the return address */
UnwPrintd2(" Return PC=%x\n", state->regData[15].v);
@ -1008,26 +953,24 @@ UnwResult UnwStartThumb(UnwState * const state) {
UnwPrintd2("PUSH {Rlist%s}", R ? ", LR" : "");
/* Check if the LR is to be pushed */
if(R) {
if (R) {
UnwPrintd3("\n lr = 0x%08x\t; %s", state->regData[14].v, M_Origin2Str(state->regData[14].o));
state->regData[13].v -= 4;
/* Write the register value to memory */
if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[14])) {
if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[14]))
return UNWIND_DWRITE_W_FAIL;
}
}
for(r = 7; r >= 0; r--) {
if(rList & (0x1 << r)) {
for (r = 7; r >= 0; r--) {
if (rList & (0x1 << r)) {
UnwPrintd4("\n r%d = 0x%08x\t; %s", r, state->regData[r].v, M_Origin2Str(state->regData[r].o));
state->regData[13].v -= 4;
if(!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) {
if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r]))
return UNWIND_DWRITE_W_FAIL;
}
}
}
}
@ -1037,7 +980,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
* Conditional branches
* Bcond
*/
else if((instr & 0xF000) == 0xD000) {
else if ((instr & 0xF000) == 0xD000) {
int32_t branchValue = (instr & 0xFF);
if (branchValue & 0x80) branchValue |= 0xFFFFFF00;
@ -1066,7 +1009,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* Format 18: unconditional branch
* B label
*/
else if((instr & 0xF800) == 0xE000) {
else if ((instr & 0xF800) == 0xE000) {
uint32_t v;
int32_t branchValue = signExtend11(instr & 0x07FF);
@ -1106,8 +1049,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
UnwPrintd1("\n");
/* Should never hit the reset vector */
if(state->regData[15].v == 0)
return UNWIND_RESET;
if (state->regData[15].v == 0) return UNWIND_RESET;
/* Check next address */
state->regData[15].v += 2;
@ -1115,11 +1057,9 @@ UnwResult UnwStartThumb(UnwState * const state) {
/* Garbage collect the memory hash (used only for the stack) */
UnwMemHashGC(state);
t--;
if(t == 0)
return UNWIND_EXHAUSTED;
if (--t == 0) return UNWIND_EXHAUSTED;
} while(!found);
} while (!found);
return UNWIND_SUCCESS;
}

View File

@ -19,7 +19,7 @@
#include "unwarmmem.h"
#include "unwarm.h"
#define M_IsIdxUsed(a, v) (((a)[v >> 3] & (1 << (v & 0x7))) ? true : false)
#define M_IsIdxUsed(a, v) !!((a)[v >> 3] & (1 << (v & 0x7)))
#define M_SetIdxUsed(a, v) ((a)[v >> 3] |= (1 << (v & 0x7)))
#define M_ClrIdxUsed(a, v) ((a)[v >> 3] &= ~(1 << (v & 0x7)))
@ -34,11 +34,9 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) {
do {
/* Check if the element is occupied */
if(M_IsIdxUsed(memData->used, s)) {
if (M_IsIdxUsed(memData->used, s)) {
/* Check if it is occupied with the sought data */
if(memData->a[s] == addr) {
return s;
}
if (memData->a[s] == addr) return s;
}
else {
/* Item is free, this is where the item should be stored */
@ -47,10 +45,8 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) {
/* Search the next entry */
s++;
if(s > MEM_HASH_SIZE) {
s = 0;
}
} while(s != v);
if (s > MEM_HASH_SIZE) s = 0;
} while (s != v);
/* Search failed, hash is full and the address not stored */
return -1;
@ -58,9 +54,9 @@ static int16_t memHashIndex(MemData * const memData, const uint32_t addr) {
bool UnwMemHashRead(MemData * const memData, uint32_t addr,uint32_t * const data, bool * const tracked) {
int16_t i = memHashIndex(memData, addr);
const int16_t i = memHashIndex(memData, addr);
if(i >= 0 && M_IsIdxUsed(memData->used, i) && memData->a[i] == addr) {
if (i >= 0 && M_IsIdxUsed(memData->used, i) && memData->a[i] == addr) {
*data = memData->v[i];
*tracked = M_IsIdxUsed(memData->tracked, i);
return true;
@ -72,44 +68,36 @@ bool UnwMemHashRead(MemData * const memData, uint32_t addr,uint32_t * const data
}
bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool valValid) {
const int16_t i = memHashIndex(memData, addr);
if (i < 0) return false; /* Hash full */
int16_t i = memHashIndex(memData, addr);
/* Store the item */
memData->a[i] = addr;
M_SetIdxUsed(memData->used, i);
if(i < 0){
/* Hash full */
return false;
if (valValid) {
memData->v[i] = val;
M_SetIdxUsed(memData->tracked, i);
}
else {
/* Store the item */
memData->a[i] = addr;
M_SetIdxUsed(memData->used, i);
if(valValid)
{
memData->v[i] = val;
M_SetIdxUsed(memData->tracked, i);
}
else {
#ifdef UNW_DEBUG
memData->v[i] = 0xDEADBEEF;
#endif
M_ClrIdxUsed(memData->tracked, i);
}
return true;
#ifdef UNW_DEBUG
memData->v[i] = 0xDEADBEEF;
#endif
M_ClrIdxUsed(memData->tracked, i);
}
return true;
}
void UnwMemHashGC(UnwState * const state) {
const uint32_t minValidAddr = state->regData[13].v;
MemData * const memData = &state->memData;
uint16_t t;
uint16_t t;
for(t = 0; t < MEM_HASH_SIZE; t++) {
if(M_IsIdxUsed(memData->used, t) && (memData->a[t] < minValidAddr)) {
for (t = 0; t < MEM_HASH_SIZE; t++) {
if (M_IsIdxUsed(memData->used, t) && (memData->a[t] < minValidAddr)) {
UnwPrintd3("MemHashGC: Free elem %d, addr 0x%08x\n", t, memData->a[t]);
M_ClrIdxUsed(memData->used, t);
}
}

View File

@ -33,13 +33,11 @@ static int HasUnwindTableInfo(void) {
}
UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data) {
if (HasUnwindTableInfo()) {
/* We have unwind information tables */
return UnwindByTableStart(frame, cb, data);
} else {
}
else {
/* We don't have unwind information tables */
UnwState state;
@ -48,12 +46,7 @@ UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data)
UnwInitState(&state, cb, data, frame->pc, frame->sp);
/* Check the Thumb bit */
if(frame->pc & 0x1) {
return UnwStartThumb(&state);
}
else {
return UnwStartArm(&state);
}
return (frame->pc & 0x1) ? UnwStartThumb(&state) : UnwStartArm(&state);
}
}
#endif