[LLVMdev] [PATCH] Fix for bug in JIT exception table allocation (no test yet)

Michael Muller mmuller at enduden.com
Tue Aug 21 14:12:49 PDT 2012


Hi, I found a bug in the code that generates exception tables, I've attached
what I think is the correct fix.

When you run out of space writing to a buffer, the buffer management code
simply stops writing at the end of the buffer.  It is the responsibility of
the caller to verify that it has stayed in bounds and perform a retry with
a larger memory estimate if not.  The function writing code does this, but
the exception table code following it does not.  The end result is that
exception table pointers can get registered pointing to invalid data, causing
seg-faults when an exception is thrown.

I haven't implemented a test case that reproduces the problem, but I will do
so.  (I've verified the problem and the fix in the scope of a much larger
system) I'm open to suggestions as to how best to test it, I'm currently
thinking of trying to create a highly contrived situation to force exception
tables to be written at the end of a buffer that won't be long enough.

=============================================================================
michaelMuller = mmuller at enduden.com | http://www.mindhog.net/~mmuller
-----------------------------------------------------------------------------
In this book it is spoken of the Sephiroth, and the Paths, of Spirits and
Conjurations; of Gods, Spheres, Planes and many other things which may or
may not exist.  It is immaterial whether they exist or not.  By doing
certain things certain results follow. - Aleister Crowley
=============================================================================
-------------- next part --------------
Index: lib/ExecutionEngine/JIT/JITEmitter.cpp
===================================================================
--- lib/ExecutionEngine/JIT/JITEmitter.cpp	(revision 162311)
+++ lib/ExecutionEngine/JIT/JITEmitter.cpp	(working copy)
@@ -974,14 +974,24 @@
     SavedBufferBegin = BufferBegin;
     SavedBufferEnd = BufferEnd;
     SavedCurBufferPtr = CurBufferPtr;
+    uint8_t *FrameRegister;
 
-    BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
-                                                             ActualSize);
-    BufferEnd = BufferBegin+ActualSize;
-    EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin;
-    uint8_t *EhStart;
-    uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd,
-                                                EhStart);
+    while (true) {
+      BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
+                                                              ActualSize);
+      BufferEnd = BufferBegin+ActualSize;
+      EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin;
+      uint8_t *EhStart;
+      FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, EhStart);
+
+      // If we've run out of memory, try again with twice as much space.
+      if (CurBufferPtr == BufferEnd) {
+        ActualSize = (CurBufferPtr-BufferBegin)*2;
+        MemMgr->deallocateExceptionTable(BufferBegin);
+      } else {
+        break;
+      }
+    }
     MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
                               FrameRegister);
     BufferBegin = SavedBufferBegin;


More information about the llvm-dev mailing list