<head>
<title>Exception Handling in LLVM</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="description"
+ <meta name="description"
content="Exception Handling in LLVM.">
<link rel="stylesheet" href="llvm.css" type="text/css">
</head>
<body>
-<div class="doc_title">Exception Handling in LLVM</div>
+<h1>Exception Handling in LLVM</h1>
<table class="layout" style="width:100%">
<tr class="layout">
<ol>
<li><a href="#llvm_eh_exception"><tt>llvm.eh.exception</tt></a></li>
<li><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a></li>
+ <li><a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a></li>
<li><a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a></li>
<li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li>
<li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li>
<li><a href="#llvm_eh_sjlj_lsda"><tt>llvm.eh.sjlj.lsda</tt></a></li>
+ <li><a href="#llvm_eh_sjlj_callsite"><tt>llvm.eh.sjlj.callsite</tt></a></li>
+ <li><a href="#llvm_eh_sjlj_dispatchsetup"><tt>llvm.eh.sjlj.dispatchsetup</tt></a></li>
</ol></li>
<li><a href="#asm">Asm Table Formats</a>
<ol>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="introduction">Introduction</a></div>
+<h2><a name="introduction">Introduction</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<p>This document is the central repository for all information pertaining to
exception handling in LLVM. It describes the format that LLVM exception
provides specific examples of what exception handling information is used for
in C/C++.</p>
-</div>
-
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="itanium">Itanium ABI Zero-cost Exception Handling</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>Exception handling for most programming languages is designed to recover from
conditions that rarely occur during general use of an application. To that
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="sjlj">Setjmp/Longjmp Exception Handling</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>Setjmp/Longjmp (SJLJ) based exception handling uses LLVM intrinsics
<a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a> and
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="overview">Overview</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>When an exception is thrown in LLVM code, the runtime does its best to find a
handler suited to processing the circumstance.</p>
</div>
+</div>
+
<!-- ======================================================================= -->
-<div class="doc_section">
+<h2>
<a name="codegen">LLVM Code Generation</a>
-</div>
+</h2>
-<div class="doc_text">
+<div>
<p>At the time of this writing, only C++ exception handling support is available
in LLVM. So the remainder of this document will be somewhat C++-centric.</p>
we will describe the implementation of LLVM exception handling in terms of
C++ examples.</p>
-</div>
-
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="throw">Throw</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>Languages that support exception handling typically provide a <tt>throw</tt>
operation to initiate the exception process. Internally, a throw operation
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="try_catch">Try/Catch</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>A call within the scope of a <i>try</i> statement can potentially raise an
exception. In those circumstances, the LLVM C++ front-end replaces the call
<li><tt>__cxa_begin_catch</tt> takes a exception structure reference as an
argument and returns the value of the exception object.</li>
- <li><tt>__cxa_end_catch</tt> takes a exception structure reference as an
- argument. This function clears the exception from the exception space.
- Note: a rethrow from within the catch may replace this call with
- a <tt>__cxa_rethrow</tt>.</li>
+ <li><tt>__cxa_end_catch</tt> takes no arguments. This function:<br><br>
+ <ol>
+ <li>Locates the most recently caught exception and decrements its handler
+ count,</li>
+ <li>Removes the exception from the "caught" stack if the handler count
+ goes to zero, and</li>
+ <li>Destroys the exception if the handler count goes to zero, and the
+ exception was not re-thrown by throw.</li>
+ </ol>
+ <p>Note: a rethrow from within the catch may replace this call with
+ a <tt>__cxa_rethrow</tt>.</p></li>
</ul>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="cleanups">Cleanups</a>
-</div>
+</h3>
+
+<div>
+
+<p>A cleanup is extra code which needs to be run as part of unwinding
+ a scope. C++ destructors are a prominent example, but other
+ languages and language extensions provide a variety of different
+ kinds of cleanup. In general, a landing pad may need to run
+ arbitrary amounts of cleanup code before actually entering a catch
+ block. To indicate the presence of cleanups, a landing pad's call
+ to <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> should
+ end with the argument <tt>i32 0</tt>; otherwise, the unwinder will
+ not stop at the landing pad if there are no catches or filters that
+ require it to.</p>
-<div class="doc_text">
+<p>Do not allow a new exception to propagate out of the execution of a
+ cleanup. This can corrupt the internal state of the unwinder.
+ Different languages describe different high-level semantics for
+ these situations: for example, C++ requires that the process be
+ terminated, whereas Ada cancels both exceptions and throws a third.</p>
-<p>To handle destructors and cleanups in <tt>try</tt> code, control may not run
- directly from a landing pad to the first catch. Control may actually flow
- from the landing pad to clean up code and then to the first catch. Since the
- required clean up for each <tt>invoke</tt> in a <tt>try</tt> may be different
- (e.g. intervening constructor), there may be several landing pads for a given
- try. If cleanups need to be run, an <tt>i32 0</tt> should be passed as the
- last <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> argument.
- However, when using DWARF exception handling with C++, a <tt>i8* null</tt>
- <a href="#restrictions">must</a> be passed instead.</p>
+<p>When all cleanups have completed, if the exception is not handled
+ by the current function, resume unwinding by calling the
+ <a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a> intrinsic,
+ passing in the results of <tt>llvm.eh.exception</tt> and
+ <tt>llvm.eh.selector</tt> for the original landing pad.</p>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="throw_filters">Throw Filters</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>C++ allows the specification of which exception types can be thrown from a
function. To represent this a top level landing pad may exist to filter out
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="restrictions">Restrictions</a>
-</div>
+</h3>
+
+<div>
+
+<p>The unwinder delegates the decision of whether to stop in a call
+ frame to that call frame's language-specific personality function.
+ Not all personalities functions guarantee that they will stop to
+ perform cleanups: for example, the GNU C++ personality doesn't do
+ so unless the exception is actually caught somewhere further up the
+ stack. When using this personality to implement EH for a language
+ that guarantees that cleanups will always be run, be sure to
+ indicate a catch-all in the
+ <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> call
+ rather than just cleanups.</p>
-<div class="doc_text">
-
-<p>The semantics of the invoke instruction require that any exception that
- unwinds through an invoke call should result in a branch to the invoke's
- unwind label. However such a branch will only happen if the
- <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> matches. Thus in
- order to ensure correct operation, the front-end must only generate
- <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> calls that are
- guaranteed to always match whatever exception unwinds through the invoke.
- For most languages it is enough to pass zero, indicating the presence of
- a <a href="#cleanups">cleanup</a>, as the
- last <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> argument.
- However for C++ this is not sufficient, because the C++ personality function
- will terminate the program if it detects that unwinding the exception only
- results in matches with cleanups. For C++ a <tt>null i8*</tt> should be
- passed as the last <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a>
- argument instead. This is interpreted as a catch-all by the C++ personality
- function, and will always match.</p>
+<p>In order for inlining to behave correctly, landing pads must be
+ prepared to handle selector results that they did not originally
+ advertise. Suppose that a function catches exceptions of
+ type <tt>A</tt>, and it's inlined into a function that catches
+ exceptions of type <tt>B</tt>. The inliner will update the
+ selector for the inlined landing pad to include the fact
+ that <tt>B</tt> is caught. If that landing pad assumes that it
+ will only be entered to catch an <tt>A</tt>, it's in for a rude
+ surprise. Consequently, landing pads must test for the selector
+ results they understand and then resume exception propagation
+ with the <a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a>
+ intrinsic if none of the conditions match.</p>
+
+</div>
</div>
<!-- ======================================================================= -->
-<div class="doc_section">
+<h2>
<a name="format_common_intrinsics">Exception Handling Intrinsics</a>
-</div>
+</h2>
-<div class="doc_text">
+<div>
<p>LLVM uses several intrinsic functions (name prefixed with "llvm.eh") to
provide exception handling information at various points in generated
code.</p>
-</div>
-
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
+<h4>
<a name="llvm_eh_exception">llvm.eh.exception</a>
-</div>
+</h4>
-<div class="doc_text">
+<div>
<pre>
- i8* %<a href="#llvm_eh_exception">llvm.eh.exception</a>( )
+ i8* %<a href="#llvm_eh_exception">llvm.eh.exception</a>()
</pre>
<p>This intrinsic returns a pointer to the exception structure.</p>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
+<h4>
<a name="llvm_eh_selector">llvm.eh.selector</a>
-</div>
+</h4>
-<div class="doc_text">
+<div>
<pre>
- i32 %<a href="#llvm_eh_selector">llvm.eh.selector.i32</a>(i8*, i8*, i8*, ...)
- i64 %<a href="#llvm_eh_selector">llvm.eh.selector.i64</a>(i8*, i8*, i8*, ...)
+ i32 %<a href="#llvm_eh_selector">llvm.eh.selector</a>(i8*, i8*, ...)
</pre>
<p>This intrinsic is used to compare the exception with the given type infos,
filters and cleanups.</p>
-<p><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a minimum of
- three arguments. The first argument is the reference to the exception
- structure. The second argument is a reference to the personality function to
- be used for this try catch sequence. Each of the remaining arguments is
- either a reference to the type info for a catch statement,
- a <a href="#throw_filters">filter</a> expression, or the number zero
- representing a <a href="#cleanups">cleanup</a>. The exception is tested
- against the arguments sequentially from first to last. The result of
- the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a positive
- number if the exception matched a type info, a negative number if it matched
- a filter, and zero if it matched a cleanup. If nothing is matched, the
- behaviour of the program is <a href="#restrictions">undefined</a>. If a type
- info matched then the selector value is the index of the type info in the
- exception table, which can be obtained using the
+<p><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a
+ minimum of three arguments. The first argument is the reference to
+ the exception structure. The second argument is a reference to the
+ personality function to be used for this try catch sequence. Each
+ of the remaining arguments is either a reference to the type info
+ for a catch statement, a <a href="#throw_filters">filter</a>
+ expression, or the number zero representing
+ a <a href="#cleanups">cleanup</a>. The exception is tested against
+ the arguments sequentially from first to last. The result of
+ the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a
+ positive number if the exception matched a type info, a negative
+ number if it matched a filter, and zero if it matched a cleanup.
+ If nothing is matched, or if only a cleanup is matched, different
+ personality functions may or may not cause control to stop at the
+ landing pad; see <a href="#restrictions">the restrictions</a> for
+ more information. If a type info matched then the selector value
+ is the index of the type info in the exception table, which can be
+ obtained using the
<a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a> intrinsic.</p>
+<p>If a landing pad containing a call to <tt>llvm.eh.selector</tt> is
+ inlined into an <tt>invoke</tt> instruction, the selector arguments
+ for the outer landing pad are appended to those of the inlined
+ landing pad. Consequently, landing pads must be written to ignore
+ selector values that they did not originally advertise.</p>
+
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
+<h4>
<a name="llvm_eh_typeid_for">llvm.eh.typeid.for</a>
-</div>
+</h4>
-<div class="doc_text">
+<div>
<pre>
- i32 %<a href="#llvm_eh_typeid_for">llvm.eh.typeid.for.i32</a>(i8*)
- i64 %<a href="#llvm_eh_typeid_for">llvm.eh.typeid.for.i64</a>(i8*)
+ i32 %<a href="#llvm_eh_typeid_for">llvm.eh.typeid.for</a>(i8*)
</pre>
<p>This intrinsic returns the type info index in the exception table of the
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
- <a name="llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a>
+<h4>
+ <a name="llvm_eh_resume">llvm.eh.resume</a>
+</h4>
+
+<div>
+
+<pre>
+ void %<a href="#llvm_eh_resume">llvm.eh.resume</a>(i8*, i32) noreturn
+</pre>
+
+<p>This intrinsic is used to resume propagation of an exception after
+ landing at a landing pad. The first argument should be the result
+ of <a href="#llvm_eh_exception">llvm.eh.exception</a> for that
+ landing pad, and the second argument should be the result of
+ <a href="#llvm_eh_selector">llvm.eh.selector</a>. When a call to
+ this intrinsic is inlined into an invoke, the call is transformed
+ into a branch to the invoke's unwind destination, using its
+ arguments in place of the calls
+ to <a href="#llvm_eh_exception">llvm.eh.exception</a> and
+ <a href="#llvm_eh_selector">llvm.eh.selector</a> there.</p>
+
+<p>This intrinsic is not implicitly <tt>nounwind</tt>; calls to it
+ will always throw. It may not be invoked.</p>
+
</div>
-<div class="doc_text">
+<!-- ======================================================================= -->
+<h4>
+ <a name="llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a>
+</h4>
+
+<div>
<pre>
i32 %<a href="#llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a>(i8*)
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
- <a name="llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>
+<h4>
+ <a name="llvm_eh_sjlj_longjmp">llvm.eh.sjlj.longjmp</a>
+</h4>
+
+<div>
+
+<pre>
+ void %<a href="#llvm_eh_sjlj_longjmp">llvm.eh.sjlj.setjmp</a>(i8*)
+</pre>
+
+<p>The <a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a>
+ intrinsic is used to implement <tt>__builtin_longjmp()</tt> for SJLJ
+ style exception handling. The single parameter is a pointer to a
+ buffer populated by <a href="#llvm_eh_sjlj_setjmp">
+ <tt>llvm.eh.sjlj.setjmp</tt></a>. The frame pointer and stack pointer
+ are restored from the buffer, then control is transferred to the
+ destination address.</p>
+
</div>
+<!-- ======================================================================= -->
+<h4>
+ <a name="llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>
+</h4>
-<div class="doc_text">
+<div>
<pre>
- i8* %<a href="#llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>( )
+ i8* %<a href="#llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>()
</pre>
<p>Used for SJLJ based exception handling, the <a href="#llvm_eh_sjlj_lsda">
</div>
<!-- ======================================================================= -->
-<div class="doc_section">
- <a name="asm">Asm Table Formats</a>
+<h4>
+ <a name="llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>
+</h4>
+
+<div>
+
+<pre>
+ void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32)
+</pre>
+
+<p>For SJLJ based exception handling, the <a href="#llvm_eh_sjlj_callsite">
+ <tt>llvm.eh.sjlj.callsite</tt></a> intrinsic identifies the callsite value
+ associated with the following invoke instruction. This is used to ensure
+ that landing pad entries in the LSDA are generated in the matching order.</p>
+
</div>
-<div class="doc_text">
+<!-- ======================================================================= -->
+<h4>
+ <a name="llvm_eh_sjlj_dispatchsetup">llvm.eh.sjlj.dispatchsetup</a>
+</h4>
-<p>There are two tables that are used by the exception handling runtime to
- determine which actions should take place when an exception is thrown.</p>
+<div>
+
+<pre>
+ void %<a href="#llvm_eh_sjlj_dispatchsetup">llvm.eh.sjlj.dispatchsetup</a>(i32)
+</pre>
+
+<p>For SJLJ based exception handling, the <a href="#llvm_eh_sjlj_dispatchsetup">
+ <tt>llvm.eh.sjlj.dispatchsetup</tt></a> intrinsic is used by targets to do
+ any unwind-edge setup they need. By default, no action is taken. </p>
+
+</div>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h2>
+ <a name="asm">Asm Table Formats</a>
+</h2>
+
+<div>
+
+<p>There are two tables that are used by the exception handling runtime to
+ determine which actions should take place when an exception is thrown.</p>
+
+<!-- ======================================================================= -->
+<h3>
<a name="unwind_tables">Exception Handling Frame</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>An exception handling frame <tt>eh_frame</tt> is very similar to the unwind
frame used by dwarf debug info. The frame contains all the information
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="exception_tables">Exception Tables</a>
-</div>
+</h3>
-<div class="doc_text">
+<div>
<p>An exception table contains information about what actions to take when an
exception is thrown in a particular part of a function's code. There is one
</div>
+</div>
+
<!-- ======================================================================= -->
-<div class="doc_section">
+<h2>
<a name="todo">ToDo</a>
-</div>
+</h2>
-<div class="doc_text">
+<div>
<ol>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
- <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
+ <a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date$
</address>