Browse Source

Check also stack underflow in evm.stack.require() function.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
5507cc870a
  1. 2
      evmjit/libevmjit/Compiler.cpp
  2. 19
      evmjit/libevmjit/RuntimeManager.cpp
  3. 2
      evmjit/libevmjit/RuntimeManager.h

2
evmjit/libevmjit/Compiler.cpp

@ -797,7 +797,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti
stack.finalize(m_builder, *_basicBlock.llvm()); // TODO: Use references stack.finalize(m_builder, *_basicBlock.llvm()); // TODO: Use references
m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI()); // TODO: Move to LocalStack::finalize m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI()); // TODO: Move to LocalStack::finalize
_runtimeManager.checkStackLimit(stack.maxSize(), stack.size()); _runtimeManager.checkStackLimit(stack.minSize(), stack.maxSize(), stack.size());
} }

19
evmjit/libevmjit/RuntimeManager.cpp

@ -110,8 +110,8 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
m_gasPtr = m_builder.CreateAlloca(Type::Gas, nullptr, "gas.ptr"); m_gasPtr = m_builder.CreateAlloca(Type::Gas, nullptr, "gas.ptr");
m_builder.CreateStore(m_dataElts[RuntimeData::Index::Gas], m_gasPtr); m_builder.CreateStore(m_dataElts[RuntimeData::Index::Gas], m_gasPtr);
llvm::Type* checkStackLimitArgs[] = {Type::Size->getPointerTo(), Type::Size, Type::Size, Type::BytePtr}; llvm::Type* checkStackLimitArgs[] = {Type::Size->getPointerTo(), Type::Size, Type::Size, Type::Size, Type::BytePtr};
m_checkStackLimit = llvm::Function::Create(llvm::FunctionType::get(Type::Void, checkStackLimitArgs, false), llvm::Function::PrivateLinkage, "stack.checkSize", getModule()); m_checkStackLimit = llvm::Function::Create(llvm::FunctionType::get(Type::Void, checkStackLimitArgs, false), llvm::Function::PrivateLinkage, "evm.stack.require", getModule());
m_checkStackLimit->setDoesNotThrow(); m_checkStackLimit->setDoesNotThrow();
m_checkStackLimit->setDoesNotCapture(1); m_checkStackLimit->setDoesNotCapture(1);
@ -121,7 +121,9 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
auto currSizePtr = &m_checkStackLimit->getArgumentList().front(); auto currSizePtr = &m_checkStackLimit->getArgumentList().front();
currSizePtr->setName("currSize"); currSizePtr->setName("currSize");
auto max = currSizePtr->getNextNode(); auto min = currSizePtr->getNextNode();
min->setName("min");
auto max = min->getNextNode();
max->setName("max"); max->setName("max");
auto diff = max->getNextNode(); auto diff = max->getNextNode();
diff->setName("diff"); diff->setName("diff");
@ -131,8 +133,11 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
InsertPointGuard guard{m_builder}; InsertPointGuard guard{m_builder};
m_builder.SetInsertPoint(checkBB); m_builder.SetInsertPoint(checkBB);
auto currSize = m_builder.CreateLoad(currSizePtr, "cur"); auto currSize = m_builder.CreateLoad(currSizePtr, "cur");
auto maxSize = m_builder.CreateNUWAdd(currSize, max, "maxSize"); auto minSize = m_builder.CreateAdd(currSize, min, "minSize", false, true);
auto ok = m_builder.CreateICmpULE(maxSize, m_builder.getInt64(1024), "ok"); auto maxSize = m_builder.CreateAdd(currSize, max, "maxSize", true, true);
auto minOk = m_builder.CreateICmpSGE(minSize, m_builder.getInt64(0), "min.ok");
auto maxOk = m_builder.CreateICmpULE(maxSize, m_builder.getInt64(1024), "max.ok");
auto ok = m_builder.CreateAnd(minOk, maxOk, "ok");
m_builder.CreateCondBr(ok, updateBB, outOfStackBB, Type::expectTrue); m_builder.CreateCondBr(ok, updateBB, outOfStackBB, Type::expectTrue);
m_builder.SetInsertPoint(updateBB); m_builder.SetInsertPoint(updateBB);
@ -145,9 +150,9 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
m_builder.CreateUnreachable(); m_builder.CreateUnreachable();
} }
void RuntimeManager::checkStackLimit(size_t _max, ssize_t _diff) void RuntimeManager::checkStackLimit(ssize_t _min, ssize_t _max, ssize_t _diff)
{ {
createCall(m_checkStackLimit, {m_stackSize, m_builder.getInt64(_max), m_builder.getInt64(_diff), getJmpBuf()}); createCall(m_checkStackLimit, {m_stackSize, m_builder.getInt64(_min), m_builder.getInt64(_max), m_builder.getInt64(_diff), getJmpBuf()});
} }
llvm::Value* RuntimeManager::getRuntimePtr() llvm::Value* RuntimeManager::getRuntimePtr()

2
evmjit/libevmjit/RuntimeManager.h

@ -50,7 +50,7 @@ public:
static llvm::StructType* getRuntimeType(); static llvm::StructType* getRuntimeType();
static llvm::StructType* getRuntimeDataType(); static llvm::StructType* getRuntimeDataType();
void checkStackLimit(size_t _max, ssize_t _diff); void checkStackLimit(ssize_t _min, ssize_t _max, ssize_t _diff);
private: private:
llvm::Value* getPtr(RuntimeData::Index _index); llvm::Value* getPtr(RuntimeData::Index _index);

Loading…
Cancel
Save