On 12/04/2017 10:28 PM, Simon Glass wrote: > Add an implementation of setjmp() and longjmp() which rely on the > underlying host C library. Since we cannot know how large the jump buffer > needs to be, pick something that should be suitable and check it at > runtime. At present we need access to the underlying struct as well. > > Signed-off-by: Simon Glass <s...@chromium.org> > --- > > Changes in v2: None > > arch/sandbox/cpu/cpu.c | 13 +++++++++++++ > arch/sandbox/cpu/os.c | 17 +++++++++++++++++ > arch/sandbox/include/asm/setjmp.h | 21 +++++++++++++++++++++ > include/os.h | 21 +++++++++++++++++++++ > 4 files changed, 72 insertions(+) > create mode 100644 arch/sandbox/include/asm/setjmp.h > > diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c > index 66c3a6a88a..8b397c7168 100644 > --- a/arch/sandbox/cpu/cpu.c > +++ b/arch/sandbox/cpu/cpu.c > @@ -9,6 +9,7 @@ > #include <libfdt.h> > #include <os.h> > #include <asm/io.h> > +#include <asm/setjmp.h> > #include <asm/state.h> > #include <dm/root.h> > > @@ -164,3 +165,15 @@ ulong timer_get_boot_us(void) > > return (count - base_count) / 1000; > } > + > +int setjmp(jmp_buf jmp) > +{ > + return os_setjmp((ulong *)jmp, sizeof(jmp));
This produces a warning: ‘sizeof’ on array function parameter ‘jmp’ will return size of ‘struct jmp_buf_data *’ [-Wsizeof-array-argument] Did you mean sizeof(struct jmp_buf_data)? > +} > + > +void longjmp(jmp_buf jmp, int ret) > +{ > + os_longjmp((ulong *)jmp, ret); > + while (1) > + ; > +} > diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c > index c524957b6c..e9200192c6 100644 > --- a/arch/sandbox/cpu/os.c > +++ b/arch/sandbox/cpu/os.c > @@ -7,6 +7,7 @@ > #include <errno.h> > #include <fcntl.h> > #include <getopt.h> > +#include <setjmp.h> > #include <stdio.h> > #include <stdint.h> > #include <stdlib.h> > @@ -617,3 +618,19 @@ void os_localtime(struct rtc_time *rt) > rt->tm_yday = tm->tm_yday; > rt->tm_isdst = tm->tm_isdst; > } > + > +int os_setjmp(ulong *jmp, int size) > +{ > + if (size < sizeof(jmp_buf)) { > + printf("setjmp: jmpbuf is too small (%d bytes, need %d)\n", > + size, sizeof(struct jmp_buf_data)); Shouldn't this be sizeof(*jmp_buf)? > + return -ENOSPC; > + } > + > + return setjmp((struct __jmp_buf_tag *)jmp); > +} > + > +void os_longjmp(ulong *jmp, int ret) > +{ > + longjmp((struct __jmp_buf_tag *)jmp, ret); > +} > diff --git a/arch/sandbox/include/asm/setjmp.h > b/arch/sandbox/include/asm/setjmp.h > new file mode 100644 > index 0000000000..e25f50107c > --- /dev/null > +++ b/arch/sandbox/include/asm/setjmp.h > @@ -0,0 +1,21 @@ > +/* > + * (C) Copyright 2016 > + * Alexander Graf <ag...@suse.de> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef _SETJMP_H_ > +#define _SETJMP_H_ 1 > + > +struct jmp_buf_data { > + /* We're not sure how long this should be */ > + ulong data[32]; Isn't this buffer is too short? sizeof(jmp_buf) =============== amd64: 200 bytes arm64: 392 bytes armhf: 392 bytes Please, check the alignment. On Windows amd64 a jump buffer must be 16 byte aligned. Best regards Heinrich > +}; > + > +typedef struct jmp_buf_data jmp_buf[1]; > + > +int setjmp(jmp_buf jmp); > +__noreturn void longjmp(jmp_buf jmp, int ret); > + > +#endif /* _SETJMP_H_ */ > diff --git a/include/os.h b/include/os.h > index 2bf4bdb1b8..ad1836ac9f 100644 > --- a/include/os.h > +++ b/include/os.h > @@ -310,4 +310,25 @@ int os_spl_to_uboot(const char *fname); > */ > void os_localtime(struct rtc_time *rt); > > +/** > + * os_setjmp() - Call setjmp() > + * > + * Call the host system's setjmp() function. > + * > + * @jmp: Buffer to store current execution state > + * @size: Size of buffer > + * @return normal setjmp() value if OK, -ENOSPC if @size is too small > + */ > +int os_setjmp(ulong *jmp, int size); > + > +/** > + * os_longjmp() - Call longjmp() > + * > + * Call the host system's longjmp() function. > + * > + * @jmp: Buffer where previous execution state was stored > + * @ret: Value to pass to longjmp() > + */ > +void os_longjmp(ulong *jmp, int ret); > + > #endif > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot