Hello all, I have been struggling for quite a few days to get exceptions working on a new board. Some back story, the project I am working on has cpp and exceptions support. We are using llvm for cpp library and are using libsupc++.a from the toolchain. We have an armv7r based board on which exceptions are working. So, I can confirm that the llvm code is working fine. When I am trying to compile the same code for armv8m based board, if throw is called then it's resulting in calling terminate. Below are the flags used for compilation,arm-none-eabi-g++ -c -fno-builtin -mcpu=cortex-m33 -mthumb -mcmse -mfloat-abi=soft -Wall -Wshadow -Wundef -g -Os -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer -pipe -fcheck-new -frtti -std=c++17 -pedantic -ffunction-sections -fdata-sections -fexceptions main.cxx -o main.oand below are the linker flags,
arm-none-eabi-ld --entry=__start -g --gc-sections -T script.ld -L"output/libraries" -L "/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/lib/thumb/v8-m.main/nofp" -o "main_final" --start-group mylibs.a "/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/lib/thumb/v8-m.main/nofp/libsupc++.a" "/bin/../lib/gcc/arm-none-eabi/10.2.1/thumb/v8-m.main/nofp/libgcc.a" --end-group -Map ./output.map
and I have also placed the sections required for exceptions properly in the linker script, /* Add This for C++ support */ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH .ARM.exidx : { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > FLASH
from the map file, it looks like the exidx start and end are placed properly. I have checked many forums regarding similar errors but none of them were helpful. (most of the resolutions were to modify the linker script, which is already correct in my case. Or to stop using lib nano. I am using libsupc++.a instead of libsupc++_nano.a)So currently I am stuck without knowing how to proceed. Sample code I am using for test,static void test_exception(void) { try { throw runtime_error("runtime error"); } catch (runtime_error &e) { cout << "Catch exception: " << e.what() << endl; } }
I have also thought that the toolchain might be an issue. I was using a pretty old version of the toolchain (6.3.1). So I have also checked it with 10.2.1 but the same issue persists.
As far as I understand this can happen if the code is unable to find a suitable exception handler from the ARM.exidx section. But I don't know how to proceed on this hunch.
Also, I had to modify the libsupc++.a file a bit. I have removed the vterminate.o file from the library as it was causing issues during the call to terminate and have added my custom verbose_terminate function.
Any suggestions would be very helpful.
Our project was using a custom bootloader and the final elf file generated was being modified so that the bootloader can do some checks. During this we missed copying the ARM.exidx and ARM.extab sections to the modified elf file. Hence, the issue.
before :arm-none-eabi-objcopy -j .text \-Obinary elfout.bin elfin.bin
after :arm-none-eabi-objcopy -j .text -j .ARM.extab -j .ARM.exidx \-Obinary elfout.bin elfin.bin
Thank you for coming back to share the solution you found with the community.