[U-Boot] [PATCH 08/16] sandbox: Add a setjmp() implementation

Rob Clark robdclark at gmail.com
Mon Sep 18 19:10:29 UTC 2017


On Mon, Sep 18, 2017 at 2:01 AM, Heinrich Schuchardt <xypron.glpk at 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 <sjg at 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 <agraf at 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 at entry=<error reading variable: DWARF-2 expression error: Loop
detected (257).>, ret=1,
    ret at 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


More information about the U-Boot mailing list