Merge pull request #1810 from antonio-nino-diaz-arm/an/setjmp

Make setjmp/longjmp compliant with the C standard and move them to libc
This commit is contained in:
Antonio Niño Díaz 2019-02-11 09:58:53 +00:00 committed by GitHub
commit 873e394b3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 94 additions and 83 deletions

View File

@ -31,7 +31,6 @@ BL31_SOURCES += bl31/bl31_main.c \
bl31/aarch64/runtime_exceptions.S \
bl31/bl31_context_mgmt.c \
common/runtime_svc.c \
lib/aarch64/setjmp.S \
lib/cpus/aarch64/dsu_helpers.S \
plat/common/aarch64/platform_mp_stack.S \
services/arm_arch_svc/arm_arch_svc_setup.c \

View File

@ -1,59 +0,0 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SETJMP_H
#define SETJMP_H
#define JMP_CTX_X19 0x0
#define JMP_CTX_X21 0x10
#define JMP_CTX_X23 0x20
#define JMP_CTX_X25 0x30
#define JMP_CTX_X27 0x40
#define JMP_CTX_X29 0x50
#define JMP_CTX_SP 0x60
#define JMP_CTX_END 0x70
#define JMP_SIZE (JMP_CTX_END >> 3)
#ifndef __ASSEMBLY__
#include <stdint.h>
/* Jump buffer hosting x18 - x30 and sp_el0 registers */
struct jmpbuf {
uint64_t buf[JMP_SIZE];
} __aligned(16);
/*
* Set a jump point, and populate the jump buffer with context information so
* that longjmp() can jump later. The caller must adhere to the following
* conditions:
*
* - After calling this function, the stack must not be shrunk. The contents of
* the stack must not be changed either.
*
* - If the caller were to 'return', the buffer must be considered invalid, and
* must not be used with longjmp().
*
* The caller will observe this function returning at two distinct
* circumstances, each with different return values:
*
* - Zero, when the buffer is setup;
*
* - Non-zero, when a call to longjmp() is made (presumably by one of the
* callee functions) with the same jump buffer.
*/
int setjmp(struct jmpbuf *buf);
/*
* Reset execution to a jump point, and restore context information according to
* the jump buffer populated by setjmp().
*/
void longjmp(struct jmpbuf *buf);
#endif /* __ASSEMBLY__ */
#endif /* SETJMP_H */

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SETJMP__H
#define SETJMP__H
#define JMP_CTX_X19 0x0
#define JMP_CTX_X21 0x10
#define JMP_CTX_X23 0x20
#define JMP_CTX_X25 0x30
#define JMP_CTX_X27 0x40
#define JMP_CTX_X29 0x50
#define JMP_CTX_SP 0x60
#define JMP_CTX_END 0x70 /* Aligned to 16 bytes */
#define JMP_SIZE (JMP_CTX_END >> 3)
#ifndef __ASSEMBLY__
#include <cdefs.h>
/* Jump buffer hosting x18 - x30 and sp_el0 registers */
typedef uint64_t jmp_buf[JMP_SIZE] __aligned(16);
#endif /* __ASSEMBLY__ */
#endif /* SETJMP__H */

20
include/lib/libc/setjmp.h Normal file
View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SETJMP_H
#define SETJMP_H
#include <setjmp_.h>
#ifndef __ASSEMBLY__
#include <cdefs.h>
int setjmp(jmp_buf env);
__dead2 void longjmp(jmp_buf env, int val);
#endif /* __ASSEMBLY__ */
#endif /* SETJMP_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -12,10 +12,7 @@
.globl longjmp
/*
* int setjmp(struct jmpbuf *buf);
*
* Sets a jump point in the buffer specified in x0. Returns 0 to the caller when
* when setting up the jump, and 1 when returning from the jump.
* int setjmp(jmp_buf env);
*/
func setjmp
mov x7, sp
@ -34,9 +31,7 @@ endfunc setjmp
/*
* void longjmp(struct jmpbuf *buf);
*
* Return to a jump point setup by setjmp()
* void longjmp(jmp_buf env, int val);
*/
func longjmp
ldp x7, xzr, [x0, #JMP_CTX_SP]
@ -60,6 +55,7 @@ func longjmp
mov sp, x7
mov x0, #1
ands x0, x1, x1 /* Move val to x0 and set flags */
cinc x0, x0, eq /* If val is 0, return 1 */
ret
endfunc longjmp

View File

@ -1,10 +1,10 @@
#
# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
LIBC_SRCS := $(addprefix lib/libc/, \
LIBC_SRCS := $(addprefix lib/libc/, \
abort.c \
assert.c \
exit.c \
@ -25,5 +25,10 @@ LIBC_SRCS := $(addprefix lib/libc/, \
strnlen.c \
strrchr.c)
ifeq (${ARCH},aarch64)
LIBC_SRCS += $(addprefix lib/libc/aarch64/, \
setjmp.S)
endif
INCLUDES += -Iinclude/lib/libc \
-Iinclude/lib/libc/$(ARCH) \

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -206,6 +206,22 @@ $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
endef
# MAKE_S_LIB builds an assembly source file and generates the dependency file
# $(1) = output directory
# $(2) = source file (%.S)
# $(3) = library name
define MAKE_S_LIB
$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
$$(ECHO) " AS $$<"
$$(Q)$$(AS) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
-include $(DEP)
endef
# MAKE_C builds a C source file and generates the dependency file
# $(1) = output directory
@ -263,7 +279,7 @@ $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
endef
# MAKE_LIB_OBJS builds both C source files
# MAKE_LIB_OBJS builds both C and assembly source files
# $(1) = output directory
# $(2) = list of source files
# $(3) = name of the library
@ -272,6 +288,10 @@ define MAKE_LIB_OBJS
$(eval REMAIN := $(filter-out %.c,$(2)))
$(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3))))
$(eval S_OBJS := $(filter %.S,$(REMAIN)))
$(eval REMAIN := $(filter-out %.S,$(REMAIN)))
$(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3))))
$(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
endef

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -9,7 +9,7 @@
.globl begin_sdei_synchronous_dispatch
/*
* void begin_sdei_synchronous_dispatch(struct jmpbuf *buffer);
* void begin_sdei_synchronous_dispatch(jmp_buf *buffer);
*
* Begin SDEI dispatch synchronously by setting up a jump point, and exiting
* EL3. This jump point is jumped to by the dispatcher after the event is

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -31,7 +31,7 @@
typedef struct sdei_dispatch_context {
sdei_ev_map_t *map;
uint64_t x[SDEI_SAVED_GPREGS];
struct jmpbuf *dispatch_jmp;
jmp_buf *dispatch_jmp;
/* Exception state registers */
uint64_t elr_el3;
@ -236,7 +236,7 @@ static cpu_context_t *restore_and_resume_ns_context(void)
* SDEI client.
*/
static void setup_ns_dispatch(sdei_ev_map_t *map, sdei_entry_t *se,
cpu_context_t *ctx, struct jmpbuf *dispatch_jmp)
cpu_context_t *ctx, jmp_buf *dispatch_jmp)
{
sdei_dispatch_context_t *disp_ctx;
@ -347,7 +347,7 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
unsigned int sec_state;
sdei_cpu_state_t *state;
uint32_t intr;
struct jmpbuf dispatch_jmp;
jmp_buf dispatch_jmp;
const uint64_t mpidr = read_mpidr_el1();
/*
@ -529,7 +529,7 @@ int sdei_dispatch_event(int ev_num)
cpu_context_t *ns_ctx;
sdei_dispatch_context_t *disp_ctx;
sdei_cpu_state_t *state;
struct jmpbuf dispatch_jmp;
jmp_buf dispatch_jmp;
/* Can't dispatch if events are masked on this PE */
state = sdei_get_this_pe_state();
@ -595,9 +595,9 @@ int sdei_dispatch_event(int ev_num)
return 0;
}
static void end_sdei_synchronous_dispatch(struct jmpbuf *buffer)
static void end_sdei_synchronous_dispatch(jmp_buf *buffer)
{
longjmp(buffer);
longjmp(*buffer, 1);
}
int sdei_event_complete(bool resume, uint64_t pc)

View File

@ -243,6 +243,6 @@ int64_t sdei_pe_mask(void);
int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
void *cookie);
bool can_sdei_state_trans(sdei_entry_t *se, sdei_action_t act);
void begin_sdei_synchronous_dispatch(struct jmpbuf *buffer);
void begin_sdei_synchronous_dispatch(jmp_buf *buffer);
#endif /* SDEI_PRIVATE_H */