Add stack limit evader.

This commit is contained in:
Daniel Kirchner
2020-09-17 22:13:27 +02:00
parent b571fd05b0
commit f4b42d1c72
54 changed files with 2323 additions and 66 deletions
@@ -142,6 +142,9 @@ public:
std::set<ContractDefinition const*, ASTNode::CompareByID>& subObjectsCreated() { return m_subObjects; }
bool inlineAssemblySeen() const { return m_inlineAssemblySeen; }
void setInlineAssemblySeen() { m_inlineAssemblySeen = true; }
private:
langutil::EVMVersion m_evmVersion;
RevertStrings m_revertStrings;
@@ -159,6 +162,9 @@ private:
MultiUseYulFunctionCollector m_functions;
size_t m_varCounter = 0;
/// Flag indicating whether any inline assembly block was seen.
bool m_inlineAssemblySeen = false;
/// Function definitions queued for code generation. They're the Solidity functions whose calls
/// were discovered by the IR generator during AST traversal.
/// Note that the queue gets filled in a lazy way - new definitions can be added while the
+14 -7
View File
@@ -92,7 +92,7 @@ string IRGenerator::generate(
Whiskers t(R"(
object "<CreationObject>" {
code {
<memoryInit>
<memoryInitCreation>
<callValueCheck>
<?notLibrary>
<?constructorHasParams> let <constructorParams> := <copyConstructorArguments>() </constructorHasParams>
@@ -103,7 +103,7 @@ string IRGenerator::generate(
}
object "<RuntimeObject>" {
code {
<memoryInit>
<memoryInitRuntime>
<dispatch>
<runtimeFunctions>
}
@@ -118,7 +118,6 @@ string IRGenerator::generate(
m_context.registerImmutableVariable(*var);
t("CreationObject", IRNames::creationObject(_contract));
t("memoryInit", memoryInit());
t("notLibrary", !_contract.isLibrary());
FunctionDefinition const* constructor = _contract.constructor();
@@ -143,6 +142,7 @@ string IRGenerator::generate(
InternalDispatchMap internalDispatchMap = generateInternalDispatchFunctions();
t("functions", m_context.functionCollector().requestedFunctions());
t("subObjects", subObjectSources(m_context.subObjectsCreated()));
t("memoryInitCreation", memoryInit(!m_context.inlineAssemblySeen()));
resetContext(_contract);
@@ -158,6 +158,7 @@ string IRGenerator::generate(
generateInternalDispatchFunctions();
t("runtimeFunctions", m_context.functionCollector().requestedFunctions());
t("runtimeSubObjects", subObjectSources(m_context.subObjectsCreated()));
t("memoryInitRuntime", memoryInit(!m_context.inlineAssemblySeen()));
return t.render();
}
@@ -651,16 +652,22 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
return t.render();
}
string IRGenerator::memoryInit()
string IRGenerator::memoryInit(bool _useMemoryGuard)
{
// This function should be called at the beginning of the EVM call frame
// and thus can assume all memory to be zero, including the contents of
// the "zero memory area" (the position CompilerUtils::zeroPointer points to).
return
Whiskers{"mstore(<memPtr>, <freeMemoryStart>)"}
Whiskers{
_useMemoryGuard ?
"mstore(<memPtr>, memoryguard(<freeMemoryStart>))" :
"mstore(<memPtr>, <freeMemoryStart>)"
}
("memPtr", to_string(CompilerUtils::freeMemoryPointer))
("freeMemoryStart", to_string(CompilerUtils::generalPurposeMemoryStart + m_context.reservedMemory()))
.render();
(
"freeMemoryStart",
to_string(CompilerUtils::generalPurposeMemoryStart + m_context.reservedMemory())
).render();
}
void IRGenerator::resetContext(ContractDefinition const& _contract)
+3 -1
View File
@@ -100,7 +100,9 @@ private:
std::string dispatchRoutine(ContractDefinition const& _contract);
std::string memoryInit();
/// @a _useMemoryGuard If true, use a memory guard, allowing the optimiser
/// to perform memory optimizations.
std::string memoryInit(bool _useMemoryGuard);
void resetContext(ContractDefinition const& _contract);
@@ -1858,6 +1858,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
{
setLocation(_inlineAsm);
m_context.setInlineAssemblySeen();
CopyTranslate bodyCopier{_inlineAsm.dialect(), m_context, _inlineAsm.annotation().externalReferences};
yul::Statement modified = bodyCopier(_inlineAsm.operations());