Browse Source

Report error if static-analysed stack is too small

cl-refactor
Paweł Bylica 10 years ago
parent
commit
b56a815d2c
  1. 26
      evmcc/Compiler.cpp
  2. 2
      evmcc/GasMeter.cpp
  3. 2
      evmcc/test/jump/loop1.evm
  4. 12
      evmcc/test/jump/loop1.lll
  5. 2
      evmcc/test/jump/loop2.evm
  6. 16
      evmcc/test/jump/loop2.lll

26
evmcc/Compiler.cpp

@ -882,17 +882,22 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
void Compiler::linkBasicBlocks() void Compiler::linkBasicBlocks()
{ {
/// Helper function that finds basic block given LLVM basic block pointer /// Helper function that finds basic block given LLVM basic block pointer
auto findBasicBlock = [this](llvm::BasicBlock* _llbb) -> BasicBlock& auto findBasicBlock = [this](llvm::BasicBlock* _llbb) -> BasicBlock*
{ {
// TODO: Fix for finding jumpTableBlock // TODO: Fix for finding jumpTableBlock
if (_llbb == this->m_jumpTableBlock->llvm()) if (_llbb == this->m_jumpTableBlock->llvm())
return *this->m_jumpTableBlock; return this->m_jumpTableBlock.get();
for (auto&& bb : this->basicBlocks)
if (_llbb == bb.second.llvm())
return &bb.second;
return nullptr;
// Name is used to get basic block index (index of first instruction) // Name is used to get basic block index (index of first instruction)
// TODO: If basicBlocs are still a map - multikey map can be used // TODO: If basicBlocs are still a map - multikey map can be used
auto&& idxStr = _llbb->getName().substr(sizeof(BasicBlock::NamePrefix) - 2); //auto&& idxStr = _llbb->getName().substr(sizeof(BasicBlock::NamePrefix) - 2);
auto idx = std::stoul(idxStr); //auto idx = std::stoul(idxStr);
return basicBlocks.find(idx)->second; //return basicBlocks.find(idx)->second;
}; };
auto completePhiNodes = [findBasicBlock](llvm::BasicBlock* _llbb) -> void auto completePhiNodes = [findBasicBlock](llvm::BasicBlock* _llbb) -> void
@ -905,9 +910,14 @@ void Compiler::linkBasicBlocks()
for (auto predIt = llvm::pred_begin(_llbb); predIt != llvm::pred_end(_llbb); ++predIt) for (auto predIt = llvm::pred_begin(_llbb); predIt != llvm::pred_end(_llbb); ++predIt)
{ {
// TODO: In case entry block is reached - report error // TODO: In case entry block is reached - report error
auto& predBB = findBasicBlock(*predIt); auto predBB = findBasicBlock(*predIt);
auto value = predBB.getStack().get(valueIdx); if (!predBB)
phi->addIncoming(value, predBB); {
std::cerr << "Stack too small in " << _llbb->getName().str() << std::endl;
std::exit(1);
}
auto value = predBB->getStack().get(valueIdx);
phi->addIncoming(value, predBB->llvm());
} }
} }
}; };

2
evmcc/GasMeter.cpp

@ -45,7 +45,7 @@ uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to F
return static_cast<uint64_t>(c_createGas); return static_cast<uint64_t>(c_createGas);
default: // Assumes instruction code is valid default: // Assumes instruction code is valid
return static_cast<uint64_t>(c_stepGas);; return static_cast<uint64_t>(c_stepGas);
} }
} }

2
evmcc/test/jump/loop1.evm

@ -1 +1 @@
600a600181038060025900 600a600181038060025960005460015460025400

12
evmcc/test/jump/loop1.lll

@ -12,12 +12,12 @@ DUP1
JUMPI JUMPI
;; stack = 1 2 3 4 5 6 7 8 9 10 ;; stack = 1 2 3 4 5 6 7 8 9 10
;;0 0
;;MSTORE MSTORE
;;1 1
;;MSTORE MSTORE
;;2 2
;;MSTORE MSTORE
;;3 ;;3
;;MSTORE ;;MSTORE

2
evmcc/test/jump/loop2.evm

@ -1 +1 @@
600a80600160800360a060025900 600a80600190038060025960005460015460025400

16
evmcc/test/jump/loop2.lll

@ -6,19 +6,19 @@
;; 2 ;; 2
DUP1 DUP1
1 1
SWAP SWAP1
SUB SUB
DUP DUP1
2 2
JUMPI JUMPI
;; stack = 1 2 3 4 5 6 7 8 9 10 ;; stack = 1 2 3 4 5 6 7 8 9 10
;;0 0
;;MSTORE MSTORE
;;1 1
;;MSTORE MSTORE
;;2 2
;;MSTORE MSTORE
;;3 ;;3
;;MSTORE ;;MSTORE

Loading…
Cancel
Save