Upstreaming ARM Unwinder and EHABI personality routines for libc++abi

Antoine Labour piman at
Mon Jun 2 10:26:12 PDT 2014

On Fri, May 30, 2014 at 9:11 PM, Albert Wong (王重傑) <ajwong at>

> Hello cfe-commits (and Nick),
> Last year, there were some small attempts to upstream our EHABI exception
> handling implementation but they fizzled out. We've picked up work again
> and would like to resume upstreaming.  Here is a link to the diff (newly
> rebased on top of Tip-of-tree Libc++abi and libc++):
> To see the relevant diffs, click on "Files changed" and search for
> "libc++abi."
> Unlike last time, this implementation now passes all the libc++abi and
> almost all libc++ tests in debug mode for Android. There are still a few
> pieces missing (Floating point register support should be complete next
> week and force unwind is not implemented) however what's there should be
> enough to provide exception handling support without libgcc.
> Our current plan is to try and upstream in the following chunks:
>  (1) Changes to AddressSpace.hpp needed to find the exidx section.
>  (2) Implementations for _Unwind_VRS_Get/Set, unw_getcontext, and then
>       stubs for the other _Unwind_VRS_* functions (basically get the
> non-floating-point
>       virtual register set working).
>  (3) Implementations of __aeabi_unwind_cpp_pr{0,1,2} including the ARM
> unwinder
>       bytecode interpreter. (most EHABI exception support done here)
>  (4) Changes to the DWARF personality routine  needed to support ARM.
> Does that sound like a good plan? Would it be easier if we merged some of
> these chunks?
> Thanks,
> Albert

Hi all,

Regarding this topic, we had a question regarding the use of the libunwind
integrated inside libcxxabi/src/Unwind/

While this is a good match for x86, it is a pretty poor match for ARM
because of the way the ARM EHABI is specified. There are 3 main problems:

A- The loop in unwind_phase1/2 is based around unw_step, which is
responsible for unwinding the stack frame, then extracting the personality
routine to call it to figure out catch/cleanup/specification handlers. On
ARM, the personality routine is not only responsible for the handlers, but
also for the stack unwinding itself. What it means is that we either:
 - make unw_step do less on ARM (not the actual stack unwinding, just
update internal data structures), which means it drifts away from what it's
meant to be (and, among others, it can't be directly used to implement
backtrace, etc.). This is what we have done in our current patchset.
 - skip unw_step in the ARM implementation of unwind_phase1/2 and instead
use directly the underlying structures, maybe through a new API that would
only update the internal structures.

B- The libunwind API is not expressive enough to implement certain aspects
of the ARM spec. Among others #7.5 mentions the multiple floating point
representations that don't fit into a singe unw_set_fpreg/unw_get_fpreg.
Even with adding an extra API to specify that (what we've done), the API &
implementation are still fairly inefficient to update several registers at
a time, unless we add more ARM-specific extensions.

C- Because of how the the PR is responsible for stack unwinding, it will
never be possible to fully implement unwinding in a remote address space.

The question becomes, really, should we still use libunwind in the longer
term on ARM. It feels like the value it provides is limited (since it can't
do the actual unwinding for exception handling) and adds significant
constraints. On the other hand, using it makes the ARM unwind_phase1/2 code
much closer to x86.

We would like to upstream what we have, but we are wondering what to do in
the long term.
Would you have any guidance to provide?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the cfe-commits mailing list