llvm.org GIT mirror llvm / dced3cd
Fix bug in exception table allocation (PR13678) Patch by Michael Muller. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172214 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Bendersky 7 years ago
2 changed file(s) with 68 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
968968 SavedBufferBegin = BufferBegin;
969969 SavedBufferEnd = BufferEnd;
970970 SavedCurBufferPtr = CurBufferPtr;
971
972 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
973 ActualSize);
974 BufferEnd = BufferBegin+ActualSize;
975 EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin;
976 uint8_t *EhStart;
977 uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd,
978 EhStart);
971 uint8_t *FrameRegister;
972
973 while (true) {
974 BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
975 ActualSize);
976 BufferEnd = BufferBegin+ActualSize;
977 EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin;
978 uint8_t *EhStart;
979 FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, EhStart);
980
981 // If the buffer was large enough to hold the table then we are done.
982 if (CurBufferPtr != BufferEnd)
983 break;
984
985 // Try again with twice as much space.
986 ActualSize = (CurBufferPtr - BufferBegin) * 2;
987 MemMgr->deallocateExceptionTable(BufferBegin);
988 }
979989 MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
980990 FrameRegister);
981991 BufferBegin = SavedBufferBegin;
160160 uintptr_t ActualSizeResult;
161161 };
162162 std::vector startExceptionTableCalls;
163 virtual uint8_t* startExceptionTable(const Function* F,
163 virtual uint8_t *startExceptionTable(const Function *F,
164164 uintptr_t &ActualSize) {
165165 uintptr_t InitialActualSize = ActualSize;
166166 uint8_t *Result = Base->startExceptionTable(F, ActualSize);
202202
203203 class JITTest : public testing::Test {
204204 protected:
205 virtual RecordingJITMemoryManager *createMemoryManager() {
206 return new RecordingJITMemoryManager;
207 }
208
205209 virtual void SetUp() {
206210 M = new Module("
", Context);
207 RJMM = new RecordingJITMemoryManager;
211 RJMM = createMemoryManager();
208212 RJMM->setPoisonMemory(true);
209213 std::string Error;
214 TargetOptions Options;
215 Options.JITExceptionHandling = true;
210216 TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
211217 .setJITMemoryManager(RJMM)
212 .setErrorStr(&Error).create());
218 .setErrorStr(&Error)
219 .setTargetOptions(Options).create());
213220 ASSERT_TRUE(TheJIT.get() != NULL) << Error;
214221 }
215222
295302 }
296303
297304 #endif // !defined(__arm__) && !defined(__powerpc__)
305
306 // Regression test for a bug. The JITEmitter wasn't checking to verify that
307 // it hadn't run out of space while generating the DWARF exception information
308 // for an emitted function.
309
310 class ExceptionMemoryManagerMock : public RecordingJITMemoryManager {
311 public:
312 virtual uint8_t *startExceptionTable(const Function *F,
313 uintptr_t &ActualSize) {
314 // force an insufficient size the first time through.
315 bool ChangeActualSize = false;
316 if (ActualSize == 0)
317 ChangeActualSize = true;;
318 uint8_t *result =
319 RecordingJITMemoryManager::startExceptionTable(F, ActualSize);
320 if (ChangeActualSize)
321 ActualSize = 1;
322 return result;
323 }
324 };
325
326 class JITExceptionMemoryTest : public JITTest {
327 protected:
328 virtual RecordingJITMemoryManager *createMemoryManager() {
329 return new ExceptionMemoryManagerMock;
330 }
331 };
332
333 TEST_F(JITExceptionMemoryTest, ExceptionTableOverflow) {
334 Function *F = Function::Create(TypeBuilder::get(Context),
335 Function::ExternalLinkage,
336 "func1", M);
337 BasicBlock *Block = BasicBlock::Create(Context, "block", F);
338 IRBuilder<> Builder(Block);
339 Builder.CreateRetVoid();
340 TheJIT->getPointerToFunction(F);
341 ASSERT_TRUE(RJMM->startExceptionTableCalls.size() == 2);
342 ASSERT_TRUE(RJMM->deallocateExceptionTableCalls.size() == 1);
343 ASSERT_TRUE(RJMM->endExceptionTableCalls.size() == 1);
344 }
298345
299346 int PlusOne(int arg) {
300347 return arg + 1;