arch: generalize frame pointer via CONFIG_FRAME_POINTER introduction

Enabling `CONFIG_FRAME_POINTER` allows the users to build the
kernel with frame-pointer.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
Yong Cong Sin 2024-05-13 13:12:12 +08:00 committed by Carles Cufí
commit c87dc641bc
13 changed files with 32 additions and 27 deletions

View file

@ -398,6 +398,13 @@ config NOCACHE_MEMORY
transfers when cache coherence issues are not optimal or can not
be solved using cache maintenance operations.
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
select OVERRIDE_FRAME_POINTER_DEFAULT
help
Select Y here to gain precise stack traces at the expense of slightly
increased size and decreased speed.
menu "Interrupt Configuration"
config ISR_TABLES_LOCAL_DECLARATION_SUPPORTED

View file

@ -43,7 +43,7 @@ if ((CONFIG_MP_MAX_NUM_CPUS GREATER 1) OR (CONFIG_SMP))
endif ()
zephyr_cc_option_ifdef(CONFIG_USERSPACE -mno-outline-atomics)
zephyr_cc_option_ifdef(CONFIG_ARM64_ENABLE_FRAME_POINTER -mno-omit-leaf-frame-pointer)
zephyr_cc_option_ifdef(CONFIG_FRAME_POINTER -mno-omit-leaf-frame-pointer)
# GCC may generate ldp/stp instructions with the Advanced SIMD Qn registers for
# consecutive 32-byte loads and stores. Saving and restoring the Advanced SIMD

View file

@ -145,9 +145,11 @@ config ARM64_SAFE_EXCEPTION_STACK
config ARM64_ENABLE_FRAME_POINTER
bool
default y
depends on OVERRIDE_FRAME_POINTER_DEFAULT && !OMIT_FRAME_POINTER
depends on !FRAME_POINTER
select DEPRECATED
help
Deprecated. Use CONFIG_FRAME_POINTER instead.
Hidden option to simplify access to OVERRIDE_FRAME_POINTER_DEFAULT
and OMIT_FRAME_POINTER. It is automatically enabled when the frame
pointer unwinding is enabled.

View file

@ -195,7 +195,7 @@ static void esf_dump(const z_arch_esf_t *esf)
LOG_ERR("x18: 0x%016llx lr: 0x%016llx", esf->x18, esf->lr);
}
#ifdef CONFIG_ARM64_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
static void esf_unwind(const z_arch_esf_t *esf)
{
/*
@ -363,9 +363,9 @@ void z_arm64_fatal_error(unsigned int reason, z_arch_esf_t *esf)
esf_dump(esf);
}
#ifdef CONFIG_ARM64_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
esf_unwind(esf);
#endif /* CONFIG_ARM64_ENABLE_FRAME_POINTER */
#endif /* CONFIG_FRAME_POINTER */
#endif /* CONFIG_EXCEPTION_DEBUG */
z_fatal_error(reason, esf);

View file

@ -40,7 +40,7 @@ GEN_NAMED_OFFSET_SYM(_callee_saved_t, x27, x27_x28);
GEN_NAMED_OFFSET_SYM(_callee_saved_t, x29, x29_sp_el0);
GEN_NAMED_OFFSET_SYM(_callee_saved_t, sp_elx, sp_elx_lr);
#ifdef CONFIG_ARM64_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
GEN_NAMED_OFFSET_SYM(_esf_t, fp, fp);
#endif

View file

@ -72,7 +72,7 @@ _ASM_FILE_PROLOGUE
.endif
#endif
#ifdef CONFIG_ARM64_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
str x29, [sp, ___esf_t_fp_OFFSET]
#endif
@ -339,7 +339,7 @@ SECTION_FUNC(TEXT, z_arm64_exit_exc)
ldp x16, x17, [sp, ___esf_t_x16_x17_OFFSET]
ldp x18, lr, [sp, ___esf_t_x18_lr_OFFSET]
#ifdef CONFIG_ARM64_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
ldr x29, [sp, ___esf_t_fp_OFFSET]
#endif

View file

@ -38,15 +38,6 @@ config RISCV_ALWAYS_SWITCH_THROUGH_ECALL
and most people should say n here to minimize context switching
overhead.
config RISCV_ENABLE_FRAME_POINTER
bool
default y
depends on OVERRIDE_FRAME_POINTER_DEFAULT && !OMIT_FRAME_POINTER
help
Hidden option to simplify access to OVERRIDE_FRAME_POINTER_DEFAULT
and OMIT_FRAME_POINTER. It is automatically enabled when the frame
pointer unwinding is enabled.
config RISCV_EXCEPTION_STACK_TRACE
bool
default y

View file

@ -27,7 +27,7 @@ struct stackframe {
uintptr_t ra;
};
#ifdef CONFIG_RISCV_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
#define SFP_FMT "fp: "
#else
#define SFP_FMT "sp: "
@ -85,7 +85,7 @@ static inline bool in_text_region(uintptr_t addr)
return (addr >= (uintptr_t)&__text_region_start) && (addr < (uintptr_t)&__text_region_end);
}
#ifdef CONFIG_RISCV_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
void z_riscv_unwind_stack(const z_arch_esf_t *esf)
{
uintptr_t fp = esf->s0;
@ -114,7 +114,7 @@ void z_riscv_unwind_stack(const z_arch_esf_t *esf)
LOG_ERR("");
}
#else /* !CONFIG_RISCV_ENABLE_FRAME_POINTER */
#else /* !CONFIG_FRAME_POINTER */
void z_riscv_unwind_stack(const z_arch_esf_t *esf)
{
uintptr_t sp = z_riscv_get_sp_before_exc(esf);
@ -143,4 +143,4 @@ void z_riscv_unwind_stack(const z_arch_esf_t *esf)
LOG_ERR("");
}
#endif /* CONFIG_RISCV_ENABLE_FRAME_POINTER */
#endif /* CONFIG_FRAME_POINTER */

View file

@ -598,6 +598,9 @@ Architectures
* Function :c:func:`arch_start_cpu` has been renamed to :c:func:`arch_cpu_start`. (:github:`64987`)
* ``CONFIG_ARM64_ENABLE_FRAME_POINTER`` is deprecated. Use :kconfig:option:`CONFIG_FRAME_POINTER`
instead. (:github:`72646`)
* x86
* Kconfigs ``CONFIG_DISABLE_SSBD`` and ``CONFIG_ENABLE_EXTENDED_IBRS``

View file

@ -47,7 +47,7 @@ struct __esf {
uint64_t lr;
uint64_t spsr;
uint64_t elr;
#ifdef CONFIG_ARM64_ENABLE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
uint64_t fp;
#endif
#ifdef CONFIG_ARM64_SAFE_EXCEPTION_STACK

View file

@ -345,6 +345,7 @@ config OVERRIDE_FRAME_POINTER_DEFAULT
config OMIT_FRAME_POINTER
bool "Omit frame pointer"
depends on !FRAME_POINTER
depends on OVERRIDE_FRAME_POINTER_DEFAULT
help
Choose Y for best performance. On some architectures (including x86)

View file

@ -1,2 +0,0 @@
CONFIG_OVERRIDE_FRAME_POINTER_DEFAULT=y
CONFIG_OMIT_FRAME_POINTER=n

View file

@ -9,7 +9,8 @@ tests:
integration_platforms:
- qemu_riscv32
- qemu_riscv64
extra_args: OVERLAY_CONFIG="enable_fp.conf"
extra_configs:
- CONFIG_FRAME_POINTER=y
harness_config:
type: multi_line
regex:
@ -44,7 +45,8 @@ tests:
- arm64
integration_platforms:
- qemu_cortex_a53
extra_args: OVERLAY_CONFIG="enable_fp.conf"
extra_configs:
- CONFIG_FRAME_POINTER=y
harness_config:
type: multi_line
regex:
@ -58,7 +60,8 @@ tests:
- qemu_riscv32
- qemu_riscv64
- qemu_cortex_a53
extra_args: OVERLAY_CONFIG="enable_fp.conf"
extra_configs:
- CONFIG_FRAME_POINTER=y
harness_config:
type: multi_line
regex: