I'm trying to understand exactly how the exception table (.arm.extab
) works.
I'm aware that this is compiler dependent, so I'll restrict myself to armcc (as I'm using Keil).
A typical entry in the table looks something like:
b0aa0380 2a002c00 01000000 00000000
To my understanding, the first word encodes instructions for the personality routine, while the third word is a R_ARM_PREL31
relocation to the start of the catch block.
What baffles me is the second word - it appears to be split into 2 shorts, the second of which measures some distance from the start of the throwing function, but I'm not sure exactly to what (nor what the first short does).
Is there any place where the structure of these entries is documented?
I've found 2 relevant documents, but as far as I can see they have no compiler-dependent information, so they're not sufficient:
If you happen to have the byte ordering missed up, the below applies. Some information is probably useful even if the byte-order is correct in your original example.
extab
and exidx
are sections added by the AAPCS which is a newer ARM ABI.
For the older APCS, the frame pointer or fp
is a root of a linked of the active routine back to the main routine (or _start
). With AAPCS records are created and placed in the exidx
and extab
sections. These are needed to unwind stacks (and resources) when the fp
is used as a generic register.
The exidx
is an ordered table of routine start addresses and an extab
index (or can't unwind). A PC
(program counter) can be examined and search via the table to find the corresponding extab
entry.
The ARM EHABI documentation has a section 7 on Exception-handling Table entries. These are extab
entries and you can at least start from there to learn more. There are two defined,
The compact model will be used for most 'C' code. There are no objects to be destroyed on the stack as with C++. The hex 8003aab0
gives,
1000
b for the leading nibble, so this is compact.0000
b for the index. Su16—Short03
h - pop 16 bytes, some locals or padding.aa
h - pop r4-r6b0
h - finishTable 4, ARM-defined frame-unwinding instructions gives the unwinding data of each byte.
The next is 0x002c002a
which is an offset to the generic personality routine. The next four values should be the 8.2 Data Structures, which are a size and should be zero... Next would be stride and then a four byte object type info. The offset 0x2c002a would be to call the objects destructor or some sort of wrapper to do this.
I think all C++ code is intended to use this Generic method. Other methods are for different languages and NOT compilers.
Related Q/A and links:
.cantunwind
, .vsave
, etc.