extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; uint32_t sp_limit = __current_sp(); zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned struct __initial_stackheap r; r.heap_base = zi_limit; r.heap_limit = sp_limit; return r; }
static void fetch_stack(ble_error_log_data_t * error_log) { uint32_t * p_stack; uint32_t * initial_sp; uint32_t length; initial_sp = (uint32_t *) __Vectors; p_stack = (uint32_t *) __current_sp(); length = ((uint32_t) initial_sp) - ((uint32_t) p_stack); memcpy(error_log->stack_info, p_stack, (length > STACK_DUMP_LENGTH) ? STACK_DUMP_LENGTH : length); }
static void cmd_info(Stream * chp, int argc, char *argv[]) { (void)argv; if (argc > 0) { shellUsage(chp, "info"); return; } long sp = __current_sp(); long pc = __current_pc(); heapinfo(chp); }
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; uint32_t sp_limit = __current_sp(); zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned //push down stack pointer to recycle some of the stack space that are not use in future __asm volatile ( "MRS IP, MSP \n" "ADD IP, #64 \n" "BIC IP, IP, #7 \n" "MSR MSP, IP \n" ); struct __initial_stackheap r; r.heap_base = zi_limit; r.heap_limit = sp_limit; return r; }
EAP_FUNC_EXPORT void stack_trace::trace(const void * const memory_address) { #if defined(__SYMBIAN32__) && (defined(USE_EAP_STACK_TRACE) || defined(USE_EAP_ASSERT_STACK_TRACE)) u32_t current_sp = 0; #if 0 // Thumb does not support inline assembler. __asm { MOV current_sp, __current_sp() } #else current_sp = reinterpret_cast<u32_t>(¤t_sp); #endif if (current_sp == 0) { EAP_TRACE_ERROR( m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Cannot obtain current stack pointer.\n"))); } TThreadStackInfo aInfo; RThread current_thread; if (current_thread.StackInfo(aInfo) != KErrNone) { EAP_TRACE_ERROR( m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Cannot obtain stack information.\n"))); } if (aInfo.iBase < current_sp) { EAP_TRACE_ERROR( m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack start %d < current stack pointer %d.\n"), aInfo.iBase, current_sp)); } u32_t *start_address = reinterpret_cast<u32_t *>(current_sp); u32_t *address = start_address; EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("address 0x%08x, accessed from:.\n"), memory_address)); while (reinterpret_cast<TLinAddr>(address) >= aInfo.iLimit) { EAP_TRACE_ALWAYS( m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("stack address 0x%08x: 0x%08x\n"), address, *address)); --address; } EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n"))); EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("address 0x%08x, accessed from:.\n"), memory_address)); address = start_address; while (reinterpret_cast<TLinAddr>(address) < aInfo.iBase) { EAP_TRACE_ALWAYS( m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("stack address 0x%08x: 0x%08x\n"), address, *address)); ++address; } #elif (defined(unix) || defined(WIN32)) && (defined(USE_EAP_STACK_TRACE) || defined(USE_EAP_ASSERT_STACK_TRACE)) jmp_buf tmp_buf; #if defined(linux) _setjmp( tmp_buf ); #else setjmp( tmp_buf ); #endif EAP_TRACE_ALWAYS(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("address 0x%08x, accessed from:.\n"), memory_address)); trace_frames( #if defined(linux) reinterpret_cast<unsigned long *>(tmp_buf->__jmpbuf[JB_BP]) #elif defined(WIN32) reinterpret_cast<unsigned long *>(((_JUMP_BUFFER *)tmp_buf)->Ebp) #elif defined(cygwin) reinterpret_cast<unsigned long *>(tmp_buf[0].ebp) #else reinterpret_cast<unsigned long *>(tmp_buf->__ebp) #endif ); #else EAP_UNREFERENCED_PARAMETER(memory_address); #endif //#if defined(unix) || defined(WIN32) }
/** * @brief Return the Main Stack Pointer (return current ARM7 stack) * * @param none * @return uint32_t Main Stack Pointer * * Return the current value of the MSP (main stack pointer) * Cortex processor register */ uint32_t __get_MSP(void) { return __current_sp(); }