Long jump API
The long jump API allows to perform nonlocal gotos, that is jump from one function to another typically further down in the stack, while properly restoring the stack’s state (unwinding). The two functions needed to do this are setjmp() and longjmp().
In addition to these two standard POSIX.1-2001/C89 functions, a third one is present in U-Boot: initjmp(). It is an extension which allows to implement user-mode threads.
-
typejmp_buf
information needed to restore a calling environment
Parameters
jmp_buf envjump buffer used to store register values
Description
Registers, the stack pointer, and the return address are saved in the jump bufffer. The function returns zero afterwards. When longjmp() is executed the function returns a second time with a non-zero value.
Return
0 after setting up jump buffer, non-zero after longjmp()
Parameters
jmp_buf envjump buffer
int valvalue to be returned by setjmp(), 0 is replaced by 1
Description
Jump back to the address and the register state saved by setjmp().
-
intinitjmp(jmp_buf env, void__noreturn(*func)(void), void*stack_base, size_tstack_sz)
prepare for a long jump to a given function with a given stack
Parameters
jmp_buf envjump buffer
void __noreturn (*func)(void)function to be called on longjmp(), MUST NOT RETURN
void *stack_basethe stack to be used by func (lower address)
size_t stack_szthe stack size in bytes
Description
This function sets up a jump buffer for later use with longjmp(). It allows to branch to a specific function with a specific stack. Please note that func MUST NOT return. It shall typically restore the main stack and resume execution by doing a long jump to a jump buffer initialized by setjmp() before the long jump. initjmp() allows to implement multithreading.
Example
Here is an example showing how to use the a long jump functions and initjmp() in particular:
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright 2025 Linaro Limited 4 * 5 * Unit test for initjmp() 6 */ 7 8#include<compiler.h> 9#include<setjmp.h> 10#include<stdbool.h> 11#include<test/lib.h> 12#include<test/ut.h> 13#include<vsprintf.h> 14 15staticboolep_entered; 16staticjmp_bufreturn_buf; 17 18staticvoid__noreturnentrypoint(void) 19{ 20ep_entered=true; 21 22/* Jump back to the main routine */ 23longjmp(return_buf,1); 24 25/* Not reached */ 26panic("longjmp failed\n"); 27} 28 29staticintlib_initjmp(structunit_test_state*uts) 30{ 31intret; 32void*stack; 33jmp_bufbuf; 34/* Arbitrary but smaller values (< page size?) fail on SANDBOX */ 35size_tstack_sz=8192; 36 37(void)entrypoint; 38 39ep_entered=false; 40 41stack=malloc(stack_sz); 42ut_assertnonnull(stack); 43 44/* 45 * Prepare return_buf so that entrypoint may jump back just after the 46 * if() 47 */ 48if(!setjmp(return_buf)){ 49/* return_buf initialized, entrypoint not yet called */ 50 51/* 52 * Prepare another jump buffer to jump into entrypoint with the 53 * given stack 54 */ 55ret=initjmp(buf,entrypoint,stack,stack_sz); 56ut_assertok(ret); 57 58/* Jump into entrypoint */ 59longjmp(buf,1); 60/* 61 * Not reached since entrypoint is expected to branch after 62 * the if() 63 */ 64ut_assert(false); 65} 66 67ut_assert(ep_entered); 68 69free(stack); 70 71return0; 72} 73LIB_TEST(lib_initjmp,0);