aboutsummaryrefslogtreecommitdiffstats
path: root/docs/ExceptionHandling.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/ExceptionHandling.html')
-rw-r--r--docs/ExceptionHandling.html296
1 files changed, 177 insertions, 119 deletions
diff --git a/docs/ExceptionHandling.html b/docs/ExceptionHandling.html
index d597ffb..247448d 100644
--- a/docs/ExceptionHandling.html
+++ b/docs/ExceptionHandling.html
@@ -11,7 +11,7 @@
<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">
@@ -35,6 +35,7 @@
<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>
@@ -58,10 +59,10 @@
<!-- *********************************************************************** -->
-<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
@@ -70,14 +71,12 @@
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
@@ -106,11 +105,11 @@
</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
@@ -138,11 +137,11 @@
</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>
@@ -185,12 +184,14 @@
</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>
@@ -200,14 +201,12 @@
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
@@ -225,11 +224,11 @@
</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
@@ -313,30 +312,43 @@
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="cleanups">Cleanups</a>
-</div>
+</h3>
+
+<div>
-<div class="doc_text">
+<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>
-<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>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>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
@@ -359,50 +371,57 @@
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<h3>
<a name="restrictions">Restrictions</a>
-</div>
+</h3>
+
+<div>
-<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>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>
+
+<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>()
@@ -413,11 +432,11 @@
</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</a>(i8*, i8*, ...)
@@ -426,30 +445,40 @@
<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</a>(i8*)
@@ -463,11 +492,38 @@
</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*)
@@ -492,11 +548,11 @@
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
+<h4>
<a name="llvm_eh_sjlj_longjmp">llvm.eh.sjlj.longjmp</a>
-</div>
+</h4>
-<div class="doc_text">
+<div>
<pre>
void %<a href="#llvm_eh_sjlj_longjmp">llvm.eh.sjlj.setjmp</a>(i8*)
@@ -507,16 +563,16 @@
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 transfered to the
+ are restored from the buffer, then control is transferred to the
destination address.</p>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
+<h4>
<a name="llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>
-</div>
+</h4>
-<div class="doc_text">
+<div>
<pre>
i8* %<a href="#llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>()
@@ -531,11 +587,11 @@
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
+<h4>
<a name="llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>
-</div>
+</h4>
-<div class="doc_text">
+<div>
<pre>
void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32)
@@ -549,11 +605,11 @@
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection">
+<h4>
<a name="llvm_eh_sjlj_dispatchsetup">llvm.eh.sjlj.dispatchsetup</a>
-</div>
+</h4>
-<div class="doc_text">
+<div>
<pre>
void %<a href="#llvm_eh_sjlj_dispatchsetup">llvm.eh.sjlj.dispatchsetup</a>(i32)
@@ -565,24 +621,24 @@
</div>
+</div>
+
<!-- ======================================================================= -->
-<div class="doc_section">
+<h2>
<a name="asm">Asm Table Formats</a>
-</div>
+</h2>
-<div class="doc_text">
+<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>
-</div>
-
<!-- ======================================================================= -->
-<div class="doc_subsection">
+<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
@@ -596,11 +652,11 @@
</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
@@ -611,12 +667,14 @@
</div>
+</div>
+
<!-- ======================================================================= -->
-<div class="doc_section">
+<h2>
<a name="todo">ToDo</a>
-</div>
+</h2>
-<div class="doc_text">
+<div>
<ol>
@@ -636,7 +694,7 @@
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>