Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix stack pointer in core dumps #76221

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions arch/arm/core/cortex_a_r/swap_helper.S
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,14 @@ _context_switch:

_oops:
/*
* Pass the exception frame to z_do_kernel_oops. r0 contains the
* exception reason.
* Pass the exception frame to z_do_kernel_oops.
*/
cps #MODE_SYS
mov r0, sp
cps #MODE_SVC
/* zero callee_regs and EXC_RETURN (only used on Cortex-M) */
mov r1, #0
mov r2, #0
bl z_do_kernel_oops
b z_arm_int_exit

Expand Down
6 changes: 4 additions & 2 deletions arch/arm/core/cortex_a_r/switch.S
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,12 @@ offload:

_oops:
/*
* Pass the exception frame to z_do_kernel_oops. r0 contains the
* exception reason.
* Pass the exception frame to z_do_kernel_oops.
*/
mov r0, sp
/* zero callee_regs and EXC_RETURN (only used on Cortex-M) */
mov r1, #0
mov r2, #0
bl z_do_kernel_oops

inv:
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/core/cortex_m/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@ void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return,
"ESF could not be retrieved successfully. Shall never occur.");

#ifdef CONFIG_DEBUG_COREDUMP
z_arm_coredump_fault_sp = POINTER_TO_UINT(esf);
ithinuel marked this conversation as resolved.
Show resolved Hide resolved
z_arm_coredump_fault_sp = POINTER_TO_UINT(esf) + z_arm_get_hw_esf_size(exc_return);
#endif

reason = fault_handle(esf, fault, &recoverable);
Expand Down
1 change: 1 addition & 0 deletions arch/arm/core/cortex_m/swap_helper.S
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ _oops:
push {r1, r2}
push {r4-r11}
mov r1, sp /* pointer to _callee_saved_t */
mov r2, lr /* EXC_RETURN */
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */
bl z_do_kernel_oops
Expand Down
5 changes: 0 additions & 5 deletions arch/arm/core/cortex_m/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@
#define FP_GUARD_EXTRA_SIZE 0
#endif

#ifndef EXC_RETURN_FTYPE
/* bit [4] allocate stack for floating-point context: 0=done 1=skipped */
#define EXC_RETURN_FTYPE (0x00000010UL)
#endif

/* Default last octet of EXC_RETURN, for threads that have not run yet.
* The full EXC_RETURN value will be e.g. 0xFFFFFFBC.
*/
Expand Down
8 changes: 7 additions & 1 deletion arch/arm/core/fatal.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,13 @@ void z_arm_fatal_error(unsigned int reason, const struct arch_esf *esf)
*
* @param esf exception frame
* @param callee_regs Callee-saved registers (R4-R11)
* @param exc_return EXC_RETURN value stored in lr on exception entry
*/
void z_do_kernel_oops(const struct arch_esf *esf, _callee_saved_t *callee_regs)
void z_do_kernel_oops(const struct arch_esf *esf, _callee_saved_t *callee_regs, uint32_t exc_return)
{
#if !(defined(CONFIG_EXTRA_EXCEPTION_INFO) && defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE))
ARG_UNUSED(callee_regs);
ARG_UNUSED(exc_return);
#endif
/* Stacked R0 holds the exception reason. */
unsigned int reason = esf->basic.r0;
Expand All @@ -127,6 +129,10 @@ void z_do_kernel_oops(const struct arch_esf *esf, _callee_saved_t *callee_regs)

#endif /* CONFIG_USERSPACE */

#ifdef CONFIG_DEBUG_COREDUMP
z_arm_coredump_fault_sp = POINTER_TO_UINT(esf) + z_arm_get_hw_esf_size(exc_return);
#endif

#if !defined(CONFIG_EXTRA_EXCEPTION_INFO)
z_arm_fatal_error(reason, esf);
#else
Expand Down
21 changes: 21 additions & 0 deletions include/zephyr/arch/arm/cortex_m/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
#define _EXC_PENDSV_PRIO 0xff
#define _EXC_PENDSV_PRIO_MASK Z_EXC_PRIO(_EXC_PENDSV_PRIO)

#ifndef EXC_RETURN_FTYPE
/* bit [4] allocate stack for floating-point context: 0=done 1=skipped */
#define EXC_RETURN_FTYPE (0x00000010UL)
#endif

#ifdef _ASMLANGUAGE
GTEXT(z_arm_exc_exit);
#else
Expand Down Expand Up @@ -119,6 +124,22 @@ struct arch_esf {

extern uint32_t z_arm_coredump_fault_sp;

/* Returns the size of the exception frame pushed by hardware, in bytes. */
static inline int z_arm_get_hw_esf_size(uint32_t exc_return)
{
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
if ((exc_return & EXC_RETURN_FTYPE) == 0) {
/* Thread had used FPU instructions and Extended stack frame was pushed */
return sizeof(struct __basic_sf) + sizeof(struct __fpu_sf);
}
#else
ARG_UNUSED(exc_return);
#endif

/* Only Basic stack frame was pushed */
return sizeof(struct __basic_sf);
}

extern void z_arm_exc_exit(void);

#ifdef __cplusplus
Expand Down
Loading