From 83a561584d28831a62da203cda532fe8da9cd295 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Wed, 24 Jan 2018 09:53:01 +0000 Subject: [Doc] Guideline on adding exception handling support for a target Summary: This is the first attempt to write down a guideline on adding exception handling support for a target. The content basically bases on the discussion on [1]. If you guys know who is exception handling expert, please add him as the reviewer. Thanks. [1] http://lists.llvm.org/pipermail/llvm-dev/2018-January/120405.html Reviewers: t.p.northover, theraven, nemanjai Reviewed By: theraven Subscribers: sdardis, llvm-commits Differential Revision: https://reviews.llvm.org/D42178 llvm-svn: 323311 --- llvm/docs/ExceptionHandling.rst | 63 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'llvm/docs/ExceptionHandling.rst') diff --git a/llvm/docs/ExceptionHandling.rst b/llvm/docs/ExceptionHandling.rst index ff8b6456c2b..e65c1bede04 100644 --- a/llvm/docs/ExceptionHandling.rst +++ b/llvm/docs/ExceptionHandling.rst @@ -839,3 +839,66 @@ or ``catchswitch`` to unwind. Finally, the funclet pads' unwind destinations cannot form a cycle. This ensures that EH lowering can construct "try regions" with a tree-like structure, which funclet-based personalities may require. + +Exception Handling support on the target +================================================= + +In order to support exception handling on particular target, there are a few +items need to be implemented. + +* CFI directives + + First, you have to assign each target register with a unique DWARF number. + Then in ``TargetFrameLowering``'s ``emitPrologue``, you have to emit `CFI + directives `_ + to specify how to calculate the CFA (Canonical Frame Address) and how register + is restored from the address pointed by the CFA with an offset. The assembler + is instructed by CFI directives to build ``.eh_frame`` section, which is used + by th unwinder to unwind stack during exception handling. + +* ``getExceptionPointerRegister`` and ``getExceptionSelectorRegister`` + + ``TargetLowering`` must implement both functions. The *personality function* + passes the *exception structure* (a pointer) and *selector value* (an integer) + to the landing pad through the registers specified by ``getExceptionPointerRegister`` + and ``getExceptionSelectorRegister`` respectively. On most platforms, they + will be GPRs and will be the same as the ones specified in the calling convention. + +* ``EH_RETURN`` + + The ISD node represents the undocumented GCC extension ``__builtin_eh_return (offset, handler)``, + which adjusts the stack by offset and then jumps to the handler. ``__builtin_eh_return`` + is used in GCC unwinder (`libgcc `_), + but not in LLVM unwinder (`libunwind `_). + If you are on the top of ``libgcc`` and have particular requirement on your target, + you have to handle ``EH_RETURN`` in ``TargetLowering``. + +If you don't leverage the existing runtime (``libstdc++`` and ``libgcc``), +you have to take a look on `libc++ `_ and +`libunwind `_ +to see what have to be done there. For ``libunwind``, you have to do the following + +* ``__libunwind_config.h`` + + Define macros for your target. + +* ``include/libunwind.h`` + + Define enum for the target registers. + +* ``src/Registers.hpp`` + + Define ``Registers`` class for your target, implement setter and getter functions. + +* ``src/UnwindCursor.hpp`` + + Define ``dwarfEncoding`` and ``stepWithCompactEncoding`` for your ``Registers`` + class. + +* ``src/UnwindRegistersRestore.S`` + + Write an assembly function to restore all your target registers from the memory. + +* ``src/UnwindRegistersSave.S`` + + Write an assembly function to save all your target registers on the memory. -- cgit v1.2.3