On Mon, Sep 18, 2017 at 2:01 AM, Heinrich Schuchardt <xypron.g...@gmx.de> wrote: > On 09/18/2017 12:59 AM, 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> >> --- >> >> 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 01991049cc..de5862a53b 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> >> >> @@ -154,3 +155,15 @@ ulong timer_get_boot_us(void) >> >> return (count - base_count) / 1000; >> } >> + >> +int setjmp(jmp_buf jmp) >> +{ >> + return os_setjmp((ulong *)jmp, sizeof(jmp)); >> +} >> + >> +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 22d6aab534..909034fa4b 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> >> @@ -609,3 +610,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(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]; >> +}; >> + >> +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 >> > > Please, fix this warning: > > arch/sandbox/cpu/cpu.c: In function ‘setjmp’: > arch/sandbox/cpu/cpu.c:161:39: warning: ‘sizeof’ on array function > parameter ‘jmp’ will return size of ‘struct jmp_buf_data *’ > [-Wsizeof-array-argument] > return os_setjmp((ulong *)jmp, sizeof(jmp)); > ^ > arch/sandbox/cpu/cpu.c:159:20: note: declared here > int setjmp(jmp_buf jmp) >
with the sizeof changed to sizeof(jmp_buf), I'm getting: ... EFI: Entry efi_exit(00007fffffffc198, 2147483662, 0, 0000000000000000) Program received signal SIGSEGV, Segmentation fault. os_longjmp (jmp=0x7fffffffc200, jmp@entry=<error reading variable: DWARF-2 expression error: Loop detected (257).>, ret=1, ret@entry=<error reading variable: DWARF-2 expression error: Loop detected (257).>) at ../arch/sandbox/cpu/os.c:627 627 longjmp((struct __jmp_buf_tag *)jmp, ret); So it seems like something not quite right still.. BR, -R _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot