note: rust-lld: error: undefined symbol: setjmp
... (info on regions in code that refer to the undefined symbol)
note: rust-lld: error: undefined symbol: longjmp
... (info on regions in code that refer to the undefined symbol)
After this, I tried changing the linker I'm using (from rust-lld to the GNU linker (arm-none-eabi-ld)).
Now the program compiles without errors, but it doesn't load to my board..
Reading symbols from target/thumbv7em-none-eabihf/debug/stm32f407g_paranoia...done.
0x00000000 in ?? ()
Function "DefaultHandler" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
Function "HardFault" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
Function "rust_begin_unwind" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
Function "main" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
semihosting is enabled
Start address 0x8000, load size 0
Transfer rate: 0 bits in <1 sec.
openocd.gdb:35: Error in sourced command file:
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x8004
Has anyone successfully used LLVM intrinsics setjmp/longjmp on an embedded board before?
Out of curiosity, where do the setjmp and longjmp symbols come from? Could it be that they're available in your Ubuntu machine's copy of glibc, but because the stm32f407g-disc doesn't link to a libc, the symbols just don't exist?
I also wasn't able to see setjmp and longjmp on the docs for core::intrinsics. Are you adding your own declarations in an extern block and relying on the linker to find the symbols, or are these functions coming from a 3rd party dependency?
EDIT: it looks like you are using the undocumented llvm.setjmp intrinsic. Have you tried linking to the official llvm.eh.sjlj.setjmp instead?
So the program from the book does build successfully when the build target is x86_ubuntu.
Thank you for pointing this out..
I'm not sure whether the llvm-intrinsics setjmp/longjmp link to setjmp/longjmp defined in libc, or the intrinsics provide a separate implementation of setjmp/longjmp..
Switching to the official llvm.eh.sjlj.setjmp worked!
I've just successfully built and flashed the program to my board.
It runs successfully as expected!
Thank you so much for your help
You saved my day
LLVM supports two flavors of setjmp/longjmp intrinsics: llvm.{set|long}jmp
and llvm.eh.sjlj.{set|long}jmp
The latter is documented in Exception Handling in LLVM — LLVM 18.0.0git documentation and
has some tests for it. The former is not documented anywhere and has no
tests. The former is handled by lowering the intrinsic call to calling the
actual library function in SelectionDAGBuilder.cpp