[rfc] exception handling in gimple

Olivier Hainque hainque@adacore.com
Wed Sep 9 08:07:00 GMT 2009


Richard Henderson wrote:
> Still writing the changelog, but here's the version that's
> current in my tree as of this afternoon.

 Very nice to see this area all refreshed :)

 Documentation-wise, FWIW, we have had a blurb about the runtime tables
 organization for while in ada/raise-gcc.c, quoted below. We found it
 very useful on several occasions to help understanding the personality
 routines implementations.

 The intent for this piece was to convey the general structure, which
 in principle belongs to a more common place. There are only tiny bits
 of Ada specific info there, easy to adjust if need be.

 This was written a long time ago, from our understanding of the
 organization at that time, so there might be a few inaccuracies.
 This would easier to maintain and by the most knowledgable
 people if it were in a more common place.

 Anyway, just to let you know that we'd be happy to see this info
 moved/updated to a more common place if you think it would be useful.
 Your current EH circuitry rewrite sounds like a nice possible
 opportunity for this.

 Olivier

--

/* There are three major runtime tables involved, generated by the
   GCC back-end. Contents slightly vary depending on the underlying
   implementation scheme (dwarf zero cost / sjlj).

   =======================================
   * Tables for the dwarf zero cost case *
   =======================================

   call_site []
   -------------------------------------------------------------------
   * region-start | region-length | landing-pad | first-action-index *
   -------------------------------------------------------------------

   Identify possible actions to be taken and where to resume control
   for that when an exception propagates through a pc inside the region
   delimited by start and length.

   A null landing-pad indicates that nothing is to be done.

   Otherwise, first-action-index provides an entry into the action[]
   table which heads a list of possible actions to be taken (see below).

   If it is determined that indeed an action should be taken, that
   is, if one action filter matches the exception being propagated,
   then control should be transfered to landing-pad.

   A null first-action-index indicates that there are only cleanups
   to run there.

   action []
   -------------------------------
   * action-filter | next-action *
   -------------------------------

   This table contains lists (called action chains) of possible actions
   associated with call-site entries described in the call-site [] table.
   There is at most one action list per call-site entry.

   A null action-filter indicates a cleanup.

   Non null action-filters provide an index into the ttypes [] table
   (see below), from which information may be retrieved to check if it
   matches the exception being propagated.

   action-filter > 0  means there is a regular handler to be run,

   action-filter < 0  means there is a some "exception_specification"
                      data to retrieve, which is only relevant for C++
                      and should never show up for Ada.

   next-action indexes the next entry in the list. 0 indicates there is
   no other entry.

   ttypes []
   ---------------
   * ttype-value *
   ---------------

   A null value indicates a catch-all handler in C++, and an "others"
   handler in Ada.

   Non null values are used to match the exception being propagated:
   In C++ this is a pointer to some rtti data, while in Ada this is an
   exception id.

   The special id value 1 indicates an "all_others" handler.

   For C++, this table is actually also used to store "exception
   specification" data. The differentiation between the two kinds
   of entries is made by the sign of the associated action filter,
   which translates into positive or negative offsets from the
   so called base of the table:

   Exception Specification data is stored at positive offsets from
   the ttypes table base, which Exception Type data is stored at
   negative offsets:

   ---------------------------------------------------------------------------

   Here is a quick summary of the tables organization:

          +-- Unwind_Context (pc, ...)
          |
          |(pc)
          |
          |   CALL-SITE[]
          |
          |   +=============================================================+
          |   | region-start + length |  landing-pad   | first-action-index |
          |   +=============================================================+
          +-> |       pc range          0 => no-action   0 => cleanups only |
              |                         !0 => jump @              N --+     |
              +====================================================== | ====+
                                                                      |
                                                                      |
       ACTION []                                                      |
                                                                      |
       +==========================================================+   |
       |              action-filter           |   next-action     |   |
       +==========================================================+   |
       |  0 => cleanup                                            |   |
       | >0 => ttype index for handler ------+  0 => end of chain | <-+
       | <0 => ttype index for spec data     |                    |
       +==================================== | ===================+
                                             |
                                             |
       TTYPES []                             |
                                             |  Offset negated from
                 +=====================+     |  the actual base.
                 |     ttype-value     |     |
    +============+=====================+     |
    |            |  0 => "others"      |     |
    |    ...     |  1 => "all others"  | <---+
    |            |  X => exception id  |
    |  handlers  +---------------------+
    |            |        ...          |
    |    ...     |        ...          |
    |            |        ...          |
    +============+=====================+ <<------ Table base
    |    ...     |        ...          |
    |   specs    |        ...          | (should not see negative filter
    |    ...     |        ...          |  values for Ada).
    +============+=====================+


   ============================
   * Tables for the sjlj case *
   ============================

   So called "function contexts" are pushed on a context stack by calls to
   _Unwind_SjLj_Register on function entry, and popped off at exit points by
   calls to _Unwind_SjLj_Unregister. The current call_site for a function is
   updated in the function context as the function's code runs along.

   The generic unwinding engine in _Unwind_RaiseException walks the function
   context stack and not the actual call chain.

   The ACTION and TTYPES tables remain unchanged, which allows to search them
   during the propagation phase to determine whether or not the propagated
   exception is handled somewhere. When it is, we only "jump" up once directly
   to the context where the handler will be found. Besides, this allows "break
   exception unhandled" to work also

   The CALL-SITE table is setup differently, though: the pc attached to the
   unwind context is a direct index into the table, so the entries in this
   table do not hold region bounds any more.

   A special index (-1) is used to indicate that no action is possibly
   connected with the context at hand, so null landing pads cannot appear
   in the table.

   Additionally, landing pad values in the table do not represent code address
   to jump at, but so called "dispatch" indices used by a common landing pad
   for the function to switch to the appropriate post-landing-pad.

   +-- Unwind_Context (pc, ...)
   |
   | pc = call-site index
   |  0 => terminate (should not see this for Ada)
   | -1 => no-action
   |
   |   CALL-SITE[]
   |
   |   +=====================================+
   |   |  landing-pad   | first-action-index |
   |   +=====================================+
   +-> |                  0 => cleanups only |
       | dispatch index             N        |
       +=====================================+



More information about the Gcc-patches mailing list