* [PATCH v2 0/2] riscv: simplify longjmp
@ 2021-03-22 11:02 Heinrich Schuchardt
2021-03-22 11:02 ` [PATCH v2 1/2] " Heinrich Schuchardt
2021-03-22 11:02 ` [PATCH v2 2/2] test: unit test for longjmp Heinrich Schuchardt
0 siblings, 2 replies; 13+ messages in thread
From: Heinrich Schuchardt @ 2021-03-22 11:02 UTC (permalink / raw)
To: u-boot
The implementation of longjmp() is simplified.
A unit test for longjmp() is provided.
For testing use
CONFIG_UNIT_TEST=y
CONFIG_CMD_SETEXPR=n
and execute
ut lib
v2:
correct title of patch 1
Heinrich Schuchardt (2):
riscv: simplify longjmp
test: unit test for longjmp
arch/riscv/lib/setjmp.S | 8 ++------
test/lib/Makefile | 1 +
test/lib/longjmp.c | 44 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+), 6 deletions(-)
create mode 100644 test/lib/longjmp.c
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v2 1/2] riscv: simplify longjmp 2021-03-22 11:02 [PATCH v2 0/2] riscv: simplify longjmp Heinrich Schuchardt @ 2021-03-22 11:02 ` Heinrich Schuchardt 2021-03-22 12:53 ` Sean Anderson 2021-03-23 11:54 ` Leo Liang 2021-03-22 11:02 ` [PATCH v2 2/2] test: unit test for longjmp Heinrich Schuchardt 1 sibling, 2 replies; 13+ messages in thread From: Heinrich Schuchardt @ 2021-03-22 11:02 UTC (permalink / raw) To: u-boot The value returned by setjmp must be nonzero. If zero is passed as parameter it must be replaced by 1. This patch reduces the code size a bit. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Sean Anderson <seanga2@gmail.com> --- v2: fix typo in title --- arch/riscv/lib/setjmp.S | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S index 72bc9241f6..99d6195827 100644 --- a/arch/riscv/lib/setjmp.S +++ b/arch/riscv/lib/setjmp.S @@ -54,12 +54,8 @@ ENTRY(longjmp) LOAD_IDX(sp, 13) /* Move the return value in place, but return 1 if passed 0. */ - beq a1, zero, longjmp_1 - mv a0, a1 - ret - - longjmp_1: - li a0, 1 + seqz a0, a1 + add a0, a0, a1 ret ENDPROC(longjmp) .popsection -- 2.30.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 1/2] riscv: simplify longjmp 2021-03-22 11:02 ` [PATCH v2 1/2] " Heinrich Schuchardt @ 2021-03-22 12:53 ` Sean Anderson 2021-03-23 11:54 ` Leo Liang 1 sibling, 0 replies; 13+ messages in thread From: Sean Anderson @ 2021-03-22 12:53 UTC (permalink / raw) To: u-boot On 3/22/21 7:02 AM, Heinrich Schuchardt wrote: > The value returned by setjmp must be nonzero. If zero is passed as > parameter it must be replaced by 1. > > This patch reduces the code size a bit. > > Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> > Sean Anderson <seanga2@gmail.com> You are missing something here. > --- > v2: > fix typo in title > --- > arch/riscv/lib/setjmp.S | 8 ++------ > 1 file changed, 2 insertions(+), 6 deletions(-) > > diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S > index 72bc9241f6..99d6195827 100644 > --- a/arch/riscv/lib/setjmp.S > +++ b/arch/riscv/lib/setjmp.S > @@ -54,12 +54,8 @@ ENTRY(longjmp) > LOAD_IDX(sp, 13) > > /* Move the return value in place, but return 1 if passed 0. */ > - beq a1, zero, longjmp_1 > - mv a0, a1 > - ret > - > - longjmp_1: > - li a0, 1 > + seqz a0, a1 > + add a0, a0, a1 > ret > ENDPROC(longjmp) > .popsection > -- > 2.30.2 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/2] riscv: simplify longjmp 2021-03-22 11:02 ` [PATCH v2 1/2] " Heinrich Schuchardt 2021-03-22 12:53 ` Sean Anderson @ 2021-03-23 11:54 ` Leo Liang 1 sibling, 0 replies; 13+ messages in thread From: Leo Liang @ 2021-03-23 11:54 UTC (permalink / raw) To: u-boot Hi Heinrich, On Mon, Mar 22, 2021 at 12:02:48PM +0100, Heinrich Schuchardt wrote: > The value returned by setjmp must be nonzero. If zero is passed as > parameter it must be replaced by 1. > > This patch reduces the code size a bit. > > Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> > Sean Anderson <seanga2@gmail.com> I think Sean is refering to the "Reviewed-by" tag is missing. Otherwise than that, LGTM. > --- > v2: > fix typo in title > --- > arch/riscv/lib/setjmp.S | 8 ++------ > 1 file changed, 2 insertions(+), 6 deletions(-) > > diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S > index 72bc9241f6..99d6195827 100644 > --- a/arch/riscv/lib/setjmp.S > +++ b/arch/riscv/lib/setjmp.S > @@ -54,12 +54,8 @@ ENTRY(longjmp) > LOAD_IDX(sp, 13) > > /* Move the return value in place, but return 1 if passed 0. */ > - beq a1, zero, longjmp_1 > - mv a0, a1 > - ret > - > - longjmp_1: > - li a0, 1 > + seqz a0, a1 > + add a0, a0, a1 > ret > ENDPROC(longjmp) > .popsection > -- > 2.30.2 > Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com> Best regards, Leo ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-22 11:02 [PATCH v2 0/2] riscv: simplify longjmp Heinrich Schuchardt 2021-03-22 11:02 ` [PATCH v2 1/2] " Heinrich Schuchardt @ 2021-03-22 11:02 ` Heinrich Schuchardt 2021-03-22 13:23 ` Sean Anderson 1 sibling, 1 reply; 13+ messages in thread From: Heinrich Schuchardt @ 2021-03-22 11:02 UTC (permalink / raw) To: u-boot Provide a unit test for the longjmp() library function Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> --- v2: no change --- test/lib/Makefile | 1 + test/lib/longjmp.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 test/lib/longjmp.c diff --git a/test/lib/Makefile b/test/lib/Makefile index 97c11e35a8..a30f615aa9 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o obj-y += hexdump.o obj-y += lmb.o +obj-y += longjmp.o obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o obj-y += string.o diff --git a/test/lib/longjmp.c b/test/lib/longjmp.c new file mode 100644 index 0000000000..7571540ffc --- /dev/null +++ b/test/lib/longjmp.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test setjmp(), longjmp() + * + * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de> + */ + +#include <common.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> +#include <asm/setjmp.h> + +/** + * test_longjmp_ret() - get longjmp() return value + * + * @i: value passed to longjmp() + * Return: value returned by longjmp() + */ +int test_longjmp_ret(int i) +{ + jmp_buf env; + int ret; + + ret = setjmp(env); + if (ret) + return ret; + longjmp(env, i); + /* We should not arrive here */ + return 0x1000; +} + +static int lib_test_longjmp(struct unit_test_state *uts) +{ + int i; + + for (i = -3; i < 0; ++i) + ut_asserteq(i, test_longjmp_ret(i)); + ut_asserteq(1, test_longjmp_ret(0)); + for (i = 1; i < 4; ++i) + ut_asserteq(i, test_longjmp_ret(i)); + return 0; +} +LIB_TEST(lib_test_longjmp, 0); -- 2.30.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-22 11:02 ` [PATCH v2 2/2] test: unit test for longjmp Heinrich Schuchardt @ 2021-03-22 13:23 ` Sean Anderson 2021-03-22 13:30 ` Sean Anderson 0 siblings, 1 reply; 13+ messages in thread From: Sean Anderson @ 2021-03-22 13:23 UTC (permalink / raw) To: u-boot On 3/22/21 7:02 AM, Heinrich Schuchardt wrote: > Provide a unit test for the longjmp() library function > > Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> > --- > v2: > no change > --- > test/lib/Makefile | 1 + > test/lib/longjmp.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 45 insertions(+) > create mode 100644 test/lib/longjmp.c > > diff --git a/test/lib/Makefile b/test/lib/Makefile > index 97c11e35a8..a30f615aa9 100644 > --- a/test/lib/Makefile > +++ b/test/lib/Makefile > @@ -7,6 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o > obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o > obj-y += hexdump.o > obj-y += lmb.o > +obj-y += longjmp.o > obj-$(CONFIG_CONSOLE_RECORD) += test_print.o > obj-$(CONFIG_SSCANF) += sscanf.o > obj-y += string.o > diff --git a/test/lib/longjmp.c b/test/lib/longjmp.c > new file mode 100644 > index 0000000000..7571540ffc > --- /dev/null > +++ b/test/lib/longjmp.c > @@ -0,0 +1,44 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Test setjmp(), longjmp() > + * > + * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de> > + */ > + > +#include <common.h> > +#include <test/lib.h> > +#include <test/test.h> > +#include <test/ut.h> > +#include <asm/setjmp.h> > + > +/** > + * test_longjmp_ret() - get longjmp() return value > + * > + * @i: value passed to longjmp() > + * Return: value returned by longjmp() > + */ > +int test_longjmp_ret(int i) > +{ > + jmp_buf env; > + int ret; > + > + ret = setjmp(env); > + if (ret) > + return ret; > + longjmp(env, i); > + /* We should not arrive here */ > + return 0x1000; > +} > + > +static int lib_test_longjmp(struct unit_test_state *uts) > +{ > + int i; > + > + for (i = -3; i < 0; ++i) > + ut_asserteq(i, test_longjmp_ret(i)); > + ut_asserteq(1, test_longjmp_ret(0)); > + for (i = 1; i < 4; ++i) > + ut_asserteq(i, test_longjmp_ret(i)); > + return 0; > +} > +LIB_TEST(lib_test_longjmp, 0); > -- > 2.30.2 > Reviewed-by: Sean Anderson <seanga2@gmail.com> Tested-by: Sean Anderson <seanga2@gmail.com> Though I would like to test that variables are set correctly e.g. by doing int test_longjmp_ret(int i) { jmp_buf env; int ret; ret = setjmp(env); if (ret) return ret; ret = 0x1000; longjmp(env, i); /* We should not arrive here */ return ret; } --Sean ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-22 13:23 ` Sean Anderson @ 2021-03-22 13:30 ` Sean Anderson 2021-03-22 16:42 ` Heinrich Schuchardt 2021-03-24 9:18 ` Andreas Schwab 0 siblings, 2 replies; 13+ messages in thread From: Sean Anderson @ 2021-03-22 13:30 UTC (permalink / raw) To: u-boot On 3/22/21 9:23 AM, Sean Anderson wrote: > > On 3/22/21 7:02 AM, Heinrich Schuchardt wrote: >> Provide a unit test for the longjmp() library function >> >> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> >> --- >> v2: >> no change >> --- >> test/lib/Makefile | 1 + >> test/lib/longjmp.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 45 insertions(+) >> create mode 100644 test/lib/longjmp.c >> >> diff --git a/test/lib/Makefile b/test/lib/Makefile >> index 97c11e35a8..a30f615aa9 100644 >> --- a/test/lib/Makefile >> +++ b/test/lib/Makefile >> @@ -7,6 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o >> obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o >> obj-y += hexdump.o >> obj-y += lmb.o >> +obj-y += longjmp.o >> obj-$(CONFIG_CONSOLE_RECORD) += test_print.o >> obj-$(CONFIG_SSCANF) += sscanf.o >> obj-y += string.o >> diff --git a/test/lib/longjmp.c b/test/lib/longjmp.c >> new file mode 100644 >> index 0000000000..7571540ffc >> --- /dev/null >> +++ b/test/lib/longjmp.c >> @@ -0,0 +1,44 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * Test setjmp(), longjmp() >> + * >> + * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de> >> + */ >> + >> +#include <common.h> >> +#include <test/lib.h> >> +#include <test/test.h> >> +#include <test/ut.h> >> +#include <asm/setjmp.h> >> + >> +/** >> + * test_longjmp_ret() - get longjmp() return value >> + * >> + * @i: value passed to longjmp() >> + * Return: value returned by longjmp() >> + */ >> +int test_longjmp_ret(int i) >> +{ >> + jmp_buf env; >> + int ret; >> + >> + ret = setjmp(env); >> + if (ret) >> + return ret; >> + longjmp(env, i); >> + /* We should not arrive here */ >> + return 0x1000; >> +} >> + >> +static int lib_test_longjmp(struct unit_test_state *uts) >> +{ >> + int i; >> + >> + for (i = -3; i < 0; ++i) >> + ut_asserteq(i, test_longjmp_ret(i)); >> + ut_asserteq(1, test_longjmp_ret(0)); >> + for (i = 1; i < 4; ++i) >> + ut_asserteq(i, test_longjmp_ret(i)); >> + return 0; >> +} >> +LIB_TEST(lib_test_longjmp, 0); >> -- >> 2.30.2 >> > > Reviewed-by: Sean Anderson <seanga2@gmail.com> > Tested-by: Sean Anderson <seanga2@gmail.com> > > Though I would like to test that variables are set correctly e.g. by doing > > int test_longjmp_ret(int i) > { > jmp_buf env; > int ret; > > ret = setjmp(env); > if (ret) > return ret; > ret = 0x1000; > longjmp(env, i); > /* We should not arrive here */ > return ret; > } > > --Sean err, rather by doing int test_longjmp_ret(int i) { jmp_buf env; int ret; int foo = i; ret = setjmp(env); if (ret) return foo; foo = 0x1000; longjmp(env, i); /* We should not arrive here */ return foo; } or something else which demonstrates that variables get reset to their earlier values. --Sean ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-22 13:30 ` Sean Anderson @ 2021-03-22 16:42 ` Heinrich Schuchardt 2021-03-23 13:30 ` Sean Anderson 2021-03-24 9:18 ` Andreas Schwab 1 sibling, 1 reply; 13+ messages in thread From: Heinrich Schuchardt @ 2021-03-22 16:42 UTC (permalink / raw) To: u-boot On 22.03.21 14:30, Sean Anderson wrote: > > On 3/22/21 9:23 AM, Sean Anderson wrote: >> >> On 3/22/21 7:02 AM, Heinrich Schuchardt wrote: >>> Provide a unit test for the longjmp() library function >>> >>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> >>> --- >>> v2: >>> ??? no change >>> --- >>> ? test/lib/Makefile? |? 1 + >>> ? test/lib/longjmp.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ >>> ? 2 files changed, 45 insertions(+) >>> ? create mode 100644 test/lib/longjmp.c >>> >>> diff --git a/test/lib/Makefile b/test/lib/Makefile >>> index 97c11e35a8..a30f615aa9 100644 >>> --- a/test/lib/Makefile >>> +++ b/test/lib/Makefile >>> @@ -7,6 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o >>> ? obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o >>> ? obj-y += hexdump.o >>> ? obj-y += lmb.o >>> +obj-y += longjmp.o >>> ? obj-$(CONFIG_CONSOLE_RECORD) += test_print.o >>> ? obj-$(CONFIG_SSCANF) += sscanf.o >>> ? obj-y += string.o >>> diff --git a/test/lib/longjmp.c b/test/lib/longjmp.c >>> new file mode 100644 >>> index 0000000000..7571540ffc >>> --- /dev/null >>> +++ b/test/lib/longjmp.c >>> @@ -0,0 +1,44 @@ >>> +// SPDX-License-Identifier: GPL-2.0+ >>> +/* >>> + * Test setjmp(), longjmp() >>> + * >>> + * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de> >>> + */ >>> + >>> +#include <common.h> >>> +#include <test/lib.h> >>> +#include <test/test.h> >>> +#include <test/ut.h> >>> +#include <asm/setjmp.h> >>> + >>> +/** >>> + * test_longjmp_ret() - get longjmp() return value >>> + * >>> + * @i:??????? value passed to longjmp() >>> + * Return:??? value returned by longjmp() >>> + */ >>> +int test_longjmp_ret(int i) >>> +{ >>> +??? jmp_buf env; >>> +??? int ret; >>> + >>> +??? ret = setjmp(env); >>> +??? if (ret) >>> +??????? return ret; >>> +??? longjmp(env, i); >>> +??? /* We should not arrive here */ >>> +??? return 0x1000; >>> +} >>> + >>> +static int lib_test_longjmp(struct unit_test_state *uts) >>> +{ >>> +??? int i; >>> + >>> +??? for (i = -3; i < 0; ++i) >>> +??????? ut_asserteq(i, test_longjmp_ret(i)); >>> +??? ut_asserteq(1, test_longjmp_ret(0)); >>> +??? for (i = 1; i < 4; ++i) >>> +??????? ut_asserteq(i, test_longjmp_ret(i)); >>> +??? return 0; >>> +} >>> +LIB_TEST(lib_test_longjmp, 0); >>> --? >>> 2.30.2 >>> >> >> Reviewed-by: Sean Anderson <seanga2@gmail.com> >> Tested-by: Sean Anderson <seanga2@gmail.com> >> >> Though I would like to test that variables are set correctly e.g. by >> doing >> >> int test_longjmp_ret(int i) >> { >> ???? jmp_buf env; >> ???? int ret; >> >> ???? ret = setjmp(env); >> ???? if (ret) >> ???????? return ret; >> ???? ret = 0x1000; >> ???? longjmp(env, i); >> ???? /* We should not arrive here */ >> ???? return ret; >> } >> >> --Sean > > err, rather by doing > > int test_longjmp_ret(int i) > { > ???? jmp_buf env; > ???? int ret; > ???? int foo = i; > > ???? ret = setjmp(env); > ???? if (ret) > ???????? return foo; > ???? foo = 0x1000; > ???? longjmp(env, i); > ???? /* We should not arrive here */ > ???? return foo; > } > > or something else which demonstrates that variables get reset to their > earlier values. > > --Sean Hello Sean, thank you for reviewing. Would the following make sense to you to check that the stack pointer is correctly restored? struct test_jmp_buf { jmp_buf env; int val; }; /** * test_longjmp() - test longjmp function * * @i is passed to longjmp. * @i << 8 is set in the environment structure. * * @env: environment * @i: value passed to longjmp() */ static void noinline test_longjmp(struct test_jmp_buf *env, int i) { env->val = i << 8; longjmp(env->env, i); } /** * test_setjmp() - test setjmp function * * setjmp() will return the value @i passed to longjmp() if @i is non-zero. * For @i == 0 we expect return value 1. * * @i << 8 will be set by test_longjmp in the environment structure. * This value can be used to check that the stack frame is restored. * * We return the XORed values to allow simply check both@once. * * @i: value passed to longjmp() * Return: values return byby longjmp() */ static int test_setjmp(int i) { struct test_jmp_buf env; int ret; env.val = -1; ret = setjmp(env.env); if (ret) return ret ^ env.val; test_longjmp(&env, i); /* We should not arrive here */ return 0x1000; } Best regards Heinrich ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-22 16:42 ` Heinrich Schuchardt @ 2021-03-23 13:30 ` Sean Anderson 0 siblings, 0 replies; 13+ messages in thread From: Sean Anderson @ 2021-03-23 13:30 UTC (permalink / raw) To: u-boot On 3/22/21 12:42 PM, Heinrich Schuchardt wrote: > On 22.03.21 14:30, Sean Anderson wrote: >> >> On 3/22/21 9:23 AM, Sean Anderson wrote: >>> >>> On 3/22/21 7:02 AM, Heinrich Schuchardt wrote: >>>> Provide a unit test for the longjmp() library function >>>> >>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> >>>> --- >>>> v2: >>>> ??? no change >>>> --- >>>> ? test/lib/Makefile? |? 1 + >>>> ? test/lib/longjmp.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ >>>> ? 2 files changed, 45 insertions(+) >>>> ? create mode 100644 test/lib/longjmp.c >>>> >>>> diff --git a/test/lib/Makefile b/test/lib/Makefile >>>> index 97c11e35a8..a30f615aa9 100644 >>>> --- a/test/lib/Makefile >>>> +++ b/test/lib/Makefile >>>> @@ -7,6 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o >>>> ? obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o >>>> ? obj-y += hexdump.o >>>> ? obj-y += lmb.o >>>> +obj-y += longjmp.o >>>> ? obj-$(CONFIG_CONSOLE_RECORD) += test_print.o >>>> ? obj-$(CONFIG_SSCANF) += sscanf.o >>>> ? obj-y += string.o >>>> diff --git a/test/lib/longjmp.c b/test/lib/longjmp.c >>>> new file mode 100644 >>>> index 0000000000..7571540ffc >>>> --- /dev/null >>>> +++ b/test/lib/longjmp.c >>>> @@ -0,0 +1,44 @@ >>>> +// SPDX-License-Identifier: GPL-2.0+ >>>> +/* >>>> + * Test setjmp(), longjmp() >>>> + * >>>> + * Copyright (c) 2021, Heinrich Schuchardt <xypron.glpk@gmx.de> >>>> + */ >>>> + >>>> +#include <common.h> >>>> +#include <test/lib.h> >>>> +#include <test/test.h> >>>> +#include <test/ut.h> >>>> +#include <asm/setjmp.h> >>>> + >>>> +/** >>>> + * test_longjmp_ret() - get longjmp() return value >>>> + * >>>> + * @i:??????? value passed to longjmp() >>>> + * Return:??? value returned by longjmp() >>>> + */ >>>> +int test_longjmp_ret(int i) >>>> +{ >>>> +??? jmp_buf env; >>>> +??? int ret; >>>> + >>>> +??? ret = setjmp(env); >>>> +??? if (ret) >>>> +??????? return ret; >>>> +??? longjmp(env, i); >>>> +??? /* We should not arrive here */ >>>> +??? return 0x1000; >>>> +} >>>> + >>>> +static int lib_test_longjmp(struct unit_test_state *uts) >>>> +{ >>>> +??? int i; >>>> + >>>> +??? for (i = -3; i < 0; ++i) >>>> +??????? ut_asserteq(i, test_longjmp_ret(i)); >>>> +??? ut_asserteq(1, test_longjmp_ret(0)); >>>> +??? for (i = 1; i < 4; ++i) >>>> +??????? ut_asserteq(i, test_longjmp_ret(i)); >>>> +??? return 0; >>>> +} >>>> +LIB_TEST(lib_test_longjmp, 0); >>>> -- >>>> 2.30.2 >>>> >>> >>> Reviewed-by: Sean Anderson <seanga2@gmail.com> >>> Tested-by: Sean Anderson <seanga2@gmail.com> >>> >>> Though I would like to test that variables are set correctly e.g. by >>> doing >>> >>> int test_longjmp_ret(int i) >>> { >>> ???? jmp_buf env; >>> ???? int ret; >>> >>> ???? ret = setjmp(env); >>> ???? if (ret) >>> ???????? return ret; >>> ???? ret = 0x1000; >>> ???? longjmp(env, i); >>> ???? /* We should not arrive here */ >>> ???? return ret; >>> } >>> >>> --Sean >> >> err, rather by doing >> >> int test_longjmp_ret(int i) >> { >> ???? jmp_buf env; >> ???? int ret; >> ???? int foo = i; >> >> ???? ret = setjmp(env); >> ???? if (ret) >> ???????? return foo; >> ???? foo = 0x1000; >> ???? longjmp(env, i); >> ???? /* We should not arrive here */ >> ???? return foo; >> } >> >> or something else which demonstrates that variables get reset to their >> earlier values. >> >> --Sean > > Hello Sean, > > thank you for reviewing. > > Would the following make sense to you to check that the stack pointer is > correctly restored? > > > struct test_jmp_buf { > jmp_buf env; > int val; > }; > > /** > * test_longjmp() - test longjmp function > * > * @i is passed to longjmp. > * @i << 8 is set in the environment structure. > * > * @env: environment > * @i: value passed to longjmp() > */ > static void noinline test_longjmp(struct test_jmp_buf *env, int i) > { > env->val = i << 8; > longjmp(env->env, i); > } > > /** > * test_setjmp() - test setjmp function > * > * setjmp() will return the value @i passed to longjmp() if @i is non-zero. > * For @i == 0 we expect return value 1. > * > * @i << 8 will be set by test_longjmp in the environment structure. > * This value can be used to check that the stack frame is restored. > * > * We return the XORed values to allow simply check both at once. > * > * @i: value passed to longjmp() > * Return: values return byby longjmp() nit: by > */ > static int test_setjmp(int i) > { > struct test_jmp_buf env; > int ret; > > env.val = -1; > ret = setjmp(env.env); > if (ret) > return ret ^ env.val; > test_longjmp(&env, i); > /* We should not arrive here */ > return 0x1000; > } > > Best regards > > Heinrich > Yes, this looks good. --Sean ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-22 13:30 ` Sean Anderson 2021-03-22 16:42 ` Heinrich Schuchardt @ 2021-03-24 9:18 ` Andreas Schwab 2021-03-24 11:16 ` Heinrich Schuchardt 1 sibling, 1 reply; 13+ messages in thread From: Andreas Schwab @ 2021-03-24 9:18 UTC (permalink / raw) To: u-boot On M?r 22 2021, Sean Anderson wrote: > int test_longjmp_ret(int i) > { > jmp_buf env; > int ret; > int foo = i; > > ret = setjmp(env); > if (ret) > return foo; > foo = 0x1000; > longjmp(env, i); > /* We should not arrive here */ > return foo; This is undefined. When modifying a non-volatile auto variable between setjmp and longjmp, there is no requirement that the value is preserved. Andreas. -- Andreas Schwab, schwab at linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-24 9:18 ` Andreas Schwab @ 2021-03-24 11:16 ` Heinrich Schuchardt 2021-03-24 12:39 ` Andreas Schwab 0 siblings, 1 reply; 13+ messages in thread From: Heinrich Schuchardt @ 2021-03-24 11:16 UTC (permalink / raw) To: u-boot On 24.03.21 10:18, Andreas Schwab wrote: > On M?r 22 2021, Sean Anderson wrote: > >> int test_longjmp_ret(int i) >> { >> jmp_buf env; >> int ret; >> int foo = i; >> >> ret = setjmp(env); >> if (ret) >> return foo; >> foo = 0x1000; >> longjmp(env, i); >> /* We should not arrive here */ >> return foo; > > This is undefined. When modifying a non-volatile auto variable between > setjmp and longjmp, there is no requirement that the value is preserved. > > Andreas. > Hello Andreas, thank you for reviewing. Your comment relates to the following paragraph in the C99 specification: "All accessible objects have values, and all other components of the abstract machine have state, as of the time the longjmp function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate." And foo is obviously "changed between the setjmp invocation and longjmp call". The current version of the patch is: https://patchwork.ozlabs.org/project/uboot/patch/20210323181127.32411-3-xypron.glpk at gmx.de/ So I guess we have to declare env as volatile in setjmp() in this version of the patch because it is changed between the setjmp and longjmp invocations? Best regards Heinrich ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-24 11:16 ` Heinrich Schuchardt @ 2021-03-24 12:39 ` Andreas Schwab 2021-03-24 13:28 ` Heinrich Schuchardt 0 siblings, 1 reply; 13+ messages in thread From: Andreas Schwab @ 2021-03-24 12:39 UTC (permalink / raw) To: u-boot On M?r 24 2021, Heinrich Schuchardt wrote: > And foo is obviously "changed between the setjmp invocation and longjmp > call". > > The current version of the patch is: > https://patchwork.ozlabs.org/project/uboot/patch/20210323181127.32411-3-xypron.glpk at gmx.de/ > > So I guess we have to declare env as volatile in setjmp() in this > version of the patch because it is changed between the setjmp and > longjmp invocations? Yes, I think so, or make it static. Andreas. -- Andreas Schwab, schwab at linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] test: unit test for longjmp 2021-03-24 12:39 ` Andreas Schwab @ 2021-03-24 13:28 ` Heinrich Schuchardt 0 siblings, 0 replies; 13+ messages in thread From: Heinrich Schuchardt @ 2021-03-24 13:28 UTC (permalink / raw) To: u-boot On 24.03.21 13:39, Andreas Schwab wrote: > On M?r 24 2021, Heinrich Schuchardt wrote: > >> And foo is obviously "changed between the setjmp invocation and longjmp >> call". >> >> The current version of the patch is: >> https://patchwork.ozlabs.org/project/uboot/patch/20210323181127.32411-3-xypron.glpk at gmx.de/ >> >> So I guess we have to declare env as volatile in setjmp() in this >> version of the patch because it is changed between the setjmp and >> longjmp invocations? > > Yes, I think so, or make it static. The whole point of this variable during test is that it lives on the stack. So static is not what I am looking for. Actually adding volatile does not change the generated machine code because test_longjmp() is marked as noinline and therefore has its own stack frame separated from test_setjmp(). But adding volatile adds to the portability. So I will respin the series. Best regards Heinrich ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2021-03-24 13:28 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-03-22 11:02 [PATCH v2 0/2] riscv: simplify longjmp Heinrich Schuchardt 2021-03-22 11:02 ` [PATCH v2 1/2] " Heinrich Schuchardt 2021-03-22 12:53 ` Sean Anderson 2021-03-23 11:54 ` Leo Liang 2021-03-22 11:02 ` [PATCH v2 2/2] test: unit test for longjmp Heinrich Schuchardt 2021-03-22 13:23 ` Sean Anderson 2021-03-22 13:30 ` Sean Anderson 2021-03-22 16:42 ` Heinrich Schuchardt 2021-03-23 13:30 ` Sean Anderson 2021-03-24 9:18 ` Andreas Schwab 2021-03-24 11:16 ` Heinrich Schuchardt 2021-03-24 12:39 ` Andreas Schwab 2021-03-24 13:28 ` Heinrich Schuchardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox