[PATCH 0/2] x86: fix longjmp() implementation

longjmp() must be defined as
void longjmp(jmp_buf env, int val)
Add the missing jmp_buf type and fix the definition. This fixes building the longjmp unit test on qemu-x86_defconfig.
If longjmp(jmp_buf env, int val) is invoked with val == 0, the setjmp() macro must return 1.
We could have easily discovered this problem and others if unit tests (CONFIG_UNIT_TEST) were enabled for qemu-x86_defconfig. We should try to get there in the 2023.01 cycle.
Heinrich Schuchardt (2): x86: fix longjmp() implementation x86: provide typedef jmp_buf
arch/x86/cpu/i386/setjmp.S | 5 +++++ arch/x86/include/asm/setjmp.h | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-)

If longjmp(jmp_buf env, int val) is called with val = 0, the setjmp() macro must return 1.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- arch/x86/cpu/i386/setjmp.S | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/x86/cpu/i386/setjmp.S b/arch/x86/cpu/i386/setjmp.S index 40b10dc8df..eceeafa7c8 100644 --- a/arch/x86/cpu/i386/setjmp.S +++ b/arch/x86/cpu/i386/setjmp.S @@ -49,12 +49,17 @@ longjmp: xchgl %eax, %edx #else movl 4(%esp), %edx /* jmp_ptr address */ + movl 8(%esp), %eax /* Return value */ #endif movl (%edx), %ebx movl 4(%edx), %esp movl 8(%edx), %ebp movl 12(%edx), %esi movl 16(%edx), %edi + test %eax, %eax + jnz nz + inc %eax +nz: jmp *20(%edx)
.size longjmp, .-longjmp

On Sat, 1 Oct 2022 at 07:05, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
If longjmp(jmp_buf env, int val) is called with val = 0, the setjmp() macro must return 1.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
arch/x86/cpu/i386/setjmp.S | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/x86/cpu/i386/setjmp.S b/arch/x86/cpu/i386/setjmp.S index 40b10dc8df..eceeafa7c8 100644 --- a/arch/x86/cpu/i386/setjmp.S +++ b/arch/x86/cpu/i386/setjmp.S @@ -49,12 +49,17 @@ longjmp: xchgl %eax, %edx #else movl 4(%esp), %edx /* jmp_ptr address */
movl 8(%esp), %eax /* Return value */
#endif movl (%edx), %ebx movl 4(%edx), %esp movl 8(%edx), %ebp movl 12(%edx), %esi movl 16(%edx), %edi
test %eax, %eax
jnz nz
inc %eax
+nz: jmp *20(%edx)
.size longjmp, .-longjmp
-- 2.37.2
Reviewed-by: Simon Glass sjg@chromium.org

On Sat, 1 Oct 2022 at 07:05, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
If longjmp(jmp_buf env, int val) is called with val = 0, the setjmp() macro must return 1.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
arch/x86/cpu/i386/setjmp.S | 5 +++++ 1 file changed, 5 insertions(+)
Applied to u-boot-dm, thanks!

The jmp_buf type is required by the C99 specification. Defining it for x86 fixes building the longjmp unit test.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- arch/x86/include/asm/setjmp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h index 49c36c1cc8..788d59e231 100644 --- a/arch/x86/include/asm/setjmp.h +++ b/arch/x86/include/asm/setjmp.h @@ -34,7 +34,9 @@ struct jmp_buf_data {
#endif
-int setjmp(struct jmp_buf_data *jmp_buf); -void longjmp(struct jmp_buf_data *jmp_buf, int val); +typedef struct jmp_buf_data jmp_buf[1]; + +int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val);
#endif

Hi Heinrich,
On Sat, 1 Oct 2022 at 07:05, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
The jmp_buf type is required by the C99 specification. Defining it for x86 fixes building the longjmp unit test.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
arch/x86/include/asm/setjmp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h index 49c36c1cc8..788d59e231 100644 --- a/arch/x86/include/asm/setjmp.h +++ b/arch/x86/include/asm/setjmp.h @@ -34,7 +34,9 @@ struct jmp_buf_data {
#endif
-int setjmp(struct jmp_buf_data *jmp_buf); -void longjmp(struct jmp_buf_data *jmp_buf, int val); +typedef struct jmp_buf_data jmp_buf[1];
+int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val);
#endif
2.37.2
This is an odd test. Where is the failure?
Regards, Simon

On 10/3/22 03:10, Simon Glass wrote:
Hi Heinrich,
On Sat, 1 Oct 2022 at 07:05, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
The jmp_buf type is required by the C99 specification. Defining it for x86 fixes building the longjmp unit test.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
arch/x86/include/asm/setjmp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h index 49c36c1cc8..788d59e231 100644 --- a/arch/x86/include/asm/setjmp.h +++ b/arch/x86/include/asm/setjmp.h @@ -34,7 +34,9 @@ struct jmp_buf_data {
#endif
-int setjmp(struct jmp_buf_data *jmp_buf); -void longjmp(struct jmp_buf_data *jmp_buf, int val); +typedef struct jmp_buf_data jmp_buf[1];
+int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val);
#endif
2.37.2
This is an odd test. Where is the failure?
qemu-x86_defconfig with CONFIG_UNIT_TEST=y does not build without this patch:
test/lib/longjmp.c:15:9: error: unknown type name ‘jmp_buf’ 15 | jmp_buf env;
Best regards
Heinrich

On 10/3/22 03:10, Simon Glass wrote:
Hi Heinrich,
On Sat, 1 Oct 2022 at 07:05, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
The jmp_buf type is required by the C99 specification. Defining it for x86 fixes building the longjmp unit test.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
arch/x86/include/asm/setjmp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!
participants (2)
-
Heinrich Schuchardt
-
Simon Glass