Hello,
I’m working on a simple unwinder for Android that relies on common C++ exception handling tables (.ARM.exidx / .eh_frame) and recently I found out that for armeabi-v7a it is impossible to unwind stack for abort that happens when someone’s destructor throws (seems like it is the case for any nothrow function). In that case std::terminate() is called via shim function __clang_call_terminate() which is emitted by compiler and has EXIDX_CANTUNWIND associated entry that prevents unwinder to pass through this function:
$ readelf --unwind test.o | grep __clang_call_terminate
Unwind section ‘.ARM.exidx.text.__clang_call_terminate’ at offset 0x98 contains 1 entry:
0x0 <__clang_call_terminate>: 0x1 [cantunwind]
Here is mentioned shim generated with -funwind-tables -O3 (source code is trivial so I omitted it):
__clang_call_terminate:
.fnstart
.save {r7, lr}
push {r7, lr}
bl __cxa_begin_catch
bl _ZSt9terminatev
.Lfunc_end1:
.size __clang_call_terminate, .Lfunc_end1-__clang_call_terminate
.cantunwind
.fnend
At the same time unwinder passes through it on arm64-v8a. I failed to find any explanations of this difference. So asking here seems to be the last resort.
My question is: why for 32-bit ARM clang emits .cantunwind for __clang_call_terminate() instead of normal unwind instructions?
Thanks.