mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 12:46:44 +00:00
Create bad jump block on demand
This commit is contained in:
parent
c21237f7b0
commit
024639bef6
2 changed files with 24 additions and 14 deletions
|
|
@ -94,13 +94,12 @@ void Compiler::createBasicBlocks(bytes const& _bytecode)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);
|
m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);
|
||||||
m_badJumpBlock = std::unique_ptr<BasicBlock>(new BasicBlock("BadJumpBlock", m_mainFunc, m_builder));
|
|
||||||
|
|
||||||
for (auto it = indirectJumpTargets.cbegin(); it != indirectJumpTargets.cend(); ++it)
|
for (auto it = indirectJumpTargets.cbegin(); it != indirectJumpTargets.cend(); ++it)
|
||||||
basicBlocks.find(*it)->second.markAsJumpDest();
|
basicBlocks.find(*it)->second.markAsJumpDest();
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBlock& Compiler::getJumpTableBlock()
|
llvm::BasicBlock* Compiler::getJumpTableBlock()
|
||||||
{
|
{
|
||||||
if (!m_jumpTableBlock)
|
if (!m_jumpTableBlock)
|
||||||
{
|
{
|
||||||
|
|
@ -108,14 +107,26 @@ BasicBlock& Compiler::getJumpTableBlock()
|
||||||
InsertPointGuard g{m_builder};
|
InsertPointGuard g{m_builder};
|
||||||
m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
|
m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
|
||||||
auto dest = m_jumpTableBlock->localStack().pop();
|
auto dest = m_jumpTableBlock->localStack().pop();
|
||||||
auto switchInstr = m_builder.CreateSwitch(dest, m_badJumpBlock->llvm());
|
auto switchInstr = m_builder.CreateSwitch(dest, getBadJumpBlock());
|
||||||
for (auto&& p : basicBlocks)
|
for (auto&& p : basicBlocks)
|
||||||
{
|
{
|
||||||
if (p.second.isJumpDest())
|
if (p.second.isJumpDest())
|
||||||
switchInstr->addCase(Constant::get(p.first), p.second.llvm());
|
switchInstr->addCase(Constant::get(p.first), p.second.llvm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *m_jumpTableBlock;
|
return m_jumpTableBlock->llvm();
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::BasicBlock* Compiler::getBadJumpBlock()
|
||||||
|
{
|
||||||
|
if (!m_badJumpBlock)
|
||||||
|
{
|
||||||
|
m_badJumpBlock.reset(new BasicBlock("BadJump", m_mainFunc, m_builder));
|
||||||
|
InsertPointGuard g{m_builder};
|
||||||
|
m_builder.SetInsertPoint(m_badJumpBlock->llvm());
|
||||||
|
m_builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
|
||||||
|
}
|
||||||
|
return m_badJumpBlock->llvm();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::string const& _id)
|
std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::string const& _id)
|
||||||
|
|
@ -158,9 +169,6 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::str
|
||||||
m_builder.SetInsertPoint(m_stopBB);
|
m_builder.SetInsertPoint(m_stopBB);
|
||||||
m_builder.CreateRet(Constant::get(ReturnCode::Stop));
|
m_builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||||
|
|
||||||
m_builder.SetInsertPoint(m_badJumpBlock->llvm());
|
|
||||||
m_builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
|
|
||||||
|
|
||||||
removeDeadBlocks();
|
removeDeadBlocks();
|
||||||
|
|
||||||
dumpCFGifRequired("blocks-init.dot");
|
dumpCFGifRequired("blocks-init.dot");
|
||||||
|
|
@ -560,7 +568,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetBlock)
|
if (!targetBlock)
|
||||||
targetBlock = m_badJumpBlock->llvm();
|
targetBlock = getBadJumpBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst == Instruction::JUMP)
|
if (inst == Instruction::JUMP)
|
||||||
|
|
@ -574,7 +582,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stack.push(target);
|
stack.push(target);
|
||||||
m_builder.CreateBr(getJumpTableBlock().llvm());
|
m_builder.CreateBr(getJumpTableBlock());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // JUMPI
|
else // JUMPI
|
||||||
|
|
@ -591,7 +599,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
|
||||||
{
|
{
|
||||||
UNTESTED;
|
UNTESTED;
|
||||||
stack.push(target);
|
stack.push(target);
|
||||||
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), _nextBasicBlock);
|
m_builder.CreateCondBr(cond, getJumpTableBlock(), _nextBasicBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,9 @@ private:
|
||||||
|
|
||||||
void compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock);
|
void compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock);
|
||||||
|
|
||||||
BasicBlock& getJumpTableBlock();
|
llvm::BasicBlock* getJumpTableBlock();
|
||||||
|
|
||||||
|
llvm::BasicBlock* getBadJumpBlock();
|
||||||
|
|
||||||
void removeDeadBlocks();
|
void removeDeadBlocks();
|
||||||
|
|
||||||
|
|
@ -73,10 +75,10 @@ private:
|
||||||
llvm::BasicBlock* m_stopBB = nullptr;
|
llvm::BasicBlock* m_stopBB = nullptr;
|
||||||
|
|
||||||
/// Block with a jump table.
|
/// Block with a jump table.
|
||||||
std::unique_ptr<BasicBlock> m_jumpTableBlock = nullptr;
|
std::unique_ptr<BasicBlock> m_jumpTableBlock;
|
||||||
|
|
||||||
/// Default destination for indirect jumps.
|
/// Destination for invalid jumps
|
||||||
std::unique_ptr<BasicBlock> m_badJumpBlock = nullptr;
|
std::unique_ptr<BasicBlock> m_badJumpBlock;
|
||||||
|
|
||||||
/// Main program function
|
/// Main program function
|
||||||
llvm::Function* m_mainFunc = nullptr;
|
llvm::Function* m_mainFunc = nullptr;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue