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

Simon Glass sjg at chromium.org
Mon Sep 25 02:12:58 UTC 2017


Hi,

On 18 September 2017 at 13:10, Rob Clark <robdclark at gmail.com> wrote:
> 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..

Hmm I'm not sure what, yet.

Regards,
Simon


More information about the U-Boot mailing list