diff options
Diffstat (limited to 'include/common')
-rw-r--r-- | include/common/aarch32/asm_macros.S | 22 | ||||
-rw-r--r-- | include/common/aarch32/el3_common_macros.S | 2 | ||||
-rw-r--r-- | include/common/aarch64/asm_macros.S | 22 |
3 files changed, 45 insertions, 1 deletions
diff --git a/include/common/aarch32/asm_macros.S b/include/common/aarch32/asm_macros.S index 5f044991..23122f34 100644 --- a/include/common/aarch32/asm_macros.S +++ b/include/common/aarch32/asm_macros.S @@ -102,4 +102,26 @@ ldr r0, =(\_name + \_size) .endm + /* + * Macro to mark instances where we're jumping to a function and don't + * expect a return. To provide the function being jumped to with + * additional information, we use 'bl' instruction to jump rather than + * 'b'. + * + * Debuggers infer the location of a call from where LR points to, which + * is usually the instruction after 'bl'. If this macro expansion + * happens to be the last location in a function, that'll cause the LR + * to point a location beyond the function, thereby misleading debugger + * back trace. We therefore insert a 'nop' after the function call for + * debug builds, unless 'skip_nop' parameter is non-zero. + */ + .macro no_ret _func:req, skip_nop=0 + bl \_func +#if DEBUG + .ifeq \skip_nop + nop + .endif +#endif + .endm + #endif /* __ASM_MACROS_S__ */ diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S index 0018ea4b..228d7216 100644 --- a/include/common/aarch32/el3_common_macros.S +++ b/include/common/aarch32/el3_common_macros.S @@ -212,7 +212,7 @@ /* This is a cold boot on a secondary CPU */ bl plat_secondary_cold_boot_setup /* plat_secondary_cold_boot_setup() is not supposed to return */ - bl plat_panic_handler + no_ret plat_panic_handler do_primary_cold_boot: .endif /* _secondary_cold_boot */ diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S index cc8f4243..88e8d9c6 100644 --- a/include/common/aarch64/asm_macros.S +++ b/include/common/aarch64/asm_macros.S @@ -178,4 +178,26 @@ .endif .endm + /* + * Macro to mark instances where we're jumping to a function and don't + * expect a return. To provide the function being jumped to with + * additional information, we use 'bl' instruction to jump rather than + * 'b'. + * + * Debuggers infer the location of a call from where LR points to, which + * is usually the instruction after 'bl'. If this macro expansion + * happens to be the last location in a function, that'll cause the LR + * to point a location beyond the function, thereby misleading debugger + * back trace. We therefore insert a 'nop' after the function call for + * debug builds, unless 'skip_nop' parameter is non-zero. + */ + .macro no_ret _func:req, skip_nop=0 + bl \_func +#if DEBUG + .ifeq \skip_nop + nop + .endif +#endif + .endm + #endif /* __ASM_MACROS_S__ */ |