Yul grammar generator: Bound memory accesses.

This commit is contained in:
Bhargava Shastry
2023-02-02 08:10:53 +01:00
parent ddbef8f650
commit f8880cad82
10 changed files with 215 additions and 85 deletions
+78 -21
View File
@@ -351,9 +351,22 @@ void ProtoConverter::visit(BinaryOp const& _x)
break;
}
m_output << "(";
visit(_x.left());
m_output << ",";
visit(_x.right());
if (op == BinaryOp::KECCAK)
{
m_output << "mod(";
visit(_x.left());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ",";
m_output << "mod(";
visit(_x.right());
m_output << ", " << to_string(s_maxSize) << ")";
}
else
{
visit(_x.left());
m_output << ",";
visit(_x.right());
}
m_output << ")";
}
@@ -623,7 +636,14 @@ void ProtoConverter::visit(UnaryOp const& _x)
break;
}
m_output << "(";
visit(_x.operand());
if (op == UnaryOp::MLOAD)
{
m_output << "mod(";
visit(_x.operand());
m_output << ", " << to_string(s_maxMemory) << ")";
}
else
visit(_x.operand());
m_output << ")";
}
@@ -778,11 +798,15 @@ void ProtoConverter::visit(CopyFunc const& _x)
break;
}
m_output << "(";
m_output << "mod(";
visit(_x.target());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ", ";
visit(_x.source());
m_output << ", ";
m_output << "mod(";
visit(_x.size());
m_output << ", " << to_string(s_maxSize) << ")";
m_output << ")\n";
}
@@ -792,32 +816,42 @@ void ProtoConverter::visit(ExtCodeCopy const& _x)
m_output << "(";
visit(_x.addr());
m_output << ", ";
m_output << "mod(";
visit(_x.target());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ", ";
visit(_x.source());
m_output << ", ";
m_output << "mod(";
visit(_x.size());
m_output << ", " << to_string(s_maxSize) << ")";
m_output << ")\n";
}
void ProtoConverter::visit(LogFunc const& _x)
{
auto visitPosAndSize = [&](LogFunc const& _y) {
m_output << "mod(";
visit(_y.pos());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ", ";
m_output << "mod(";
visit(_y.size());
m_output << ", " << to_string(s_maxSize) << ")";
};
switch (_x.num_topics())
{
case LogFunc::ZERO:
m_output << "log0";
m_output << "(";
visit(_x.pos());
m_output << ", ";
visit(_x.size());
visitPosAndSize(_x);
m_output << ")\n";
break;
case LogFunc::ONE:
m_output << "log1";
m_output << "(";
visit(_x.pos());
m_output << ", ";
visit(_x.size());
visitPosAndSize(_x);
m_output << ", ";
visit(_x.t1());
m_output << ")\n";
@@ -825,9 +859,7 @@ void ProtoConverter::visit(LogFunc const& _x)
case LogFunc::TWO:
m_output << "log2";
m_output << "(";
visit(_x.pos());
m_output << ", ";
visit(_x.size());
visitPosAndSize(_x);
m_output << ", ";
visit(_x.t1());
m_output << ", ";
@@ -837,9 +869,7 @@ void ProtoConverter::visit(LogFunc const& _x)
case LogFunc::THREE:
m_output << "log3";
m_output << "(";
visit(_x.pos());
m_output << ", ";
visit(_x.size());
visitPosAndSize(_x);
m_output << ", ";
visit(_x.t1());
m_output << ", ";
@@ -851,9 +881,7 @@ void ProtoConverter::visit(LogFunc const& _x)
case LogFunc::FOUR:
m_output << "log4";
m_output << "(";
visit(_x.pos());
m_output << ", ";
visit(_x.size());
visitPosAndSize(_x);
m_output << ", ";
visit(_x.t1());
m_output << ", ";
@@ -1015,13 +1043,21 @@ void ProtoConverter::visit(LowLevelCall const& _x)
visit(_x.wei());
m_output << ", ";
}
m_output << "mod(";
visit(_x.in());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ", ";
m_output << "mod(";
visit(_x.insize());
m_output << ", " << to_string(s_maxSize) << ")";
m_output << ", ";
m_output << "mod(";
visit(_x.out());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ", ";
m_output << "mod(";
visit(_x.outsize());
m_output << ", " << to_string(s_maxSize) << ")";
m_output << ")";
}
@@ -1048,9 +1084,13 @@ void ProtoConverter::visit(Create const& _x)
}
visit(_x.wei());
m_output << ", ";
m_output << "mod(";
visit(_x.position());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ", ";
m_output << "mod(";
visit(_x.size());
m_output << ", " << to_string(s_maxSize) << ")";
if (type == Create::CREATE2)
{
m_output << ", ";
@@ -1069,7 +1109,8 @@ void ProtoConverter::visit(IfStmt const& _x)
void ProtoConverter::visit(StoreFunc const& _x)
{
switch (_x.st())
auto storeType = _x.st();
switch (storeType)
{
case StoreFunc::MSTORE:
m_output << "mstore(";
@@ -1081,7 +1122,15 @@ void ProtoConverter::visit(StoreFunc const& _x)
m_output << "mstore8(";
break;
}
visit(_x.loc());
// Write to memory within bounds, storage is unbounded
if (storeType == StoreFunc::SSTORE)
visit(_x.loc());
else
{
m_output << "mod(";
visit(_x.loc());
m_output << ", " << to_string(s_maxMemory) << ")";
}
m_output << ", ";
visit(_x.val());
m_output << ")\n";
@@ -1262,9 +1311,13 @@ void ProtoConverter::visit(RetRevStmt const& _x)
break;
}
m_output << "(";
m_output << "mod(";
visit(_x.pos());
m_output << ", " << to_string(s_maxMemory - s_maxSize) << ")";
m_output << ", ";
m_output << "mod(";
visit(_x.size());
m_output << ", " << to_string(s_maxSize) << ")";
m_output << ")\n";
}
@@ -1651,8 +1704,12 @@ void ProtoConverter::fillFunctionCallInput(unsigned _numInParams)
m_output << "calldataload(" << slot << ")";
break;
case 1:
{
// Access memory within stipulated bounds
slot = "mod(" + dictionaryToken() + ", " + to_string(s_maxMemory) + ")";
m_output << "mload(" << slot << ")";
break;
}
case 2:
m_output << "sload(" << slot << ")";
break;
+5
View File
@@ -344,6 +344,11 @@ private:
static unsigned constexpr s_modOutputParams = 5;
/// Hard-coded identifier for a Yul object's data block
static auto constexpr s_dataIdentifier = "datablock";
/// Upper bound on memory writes = 2**32 - 1
/// See: https://eips.ethereum.org/EIPS/eip-1985#memory-size
static unsigned constexpr s_maxMemory = 4294967295;
/// Upper bound on size for range copy functions
static unsigned constexpr s_maxSize = 65536;
/// Predicate to keep track of for body scope. If false, break/continue
/// statements can not be created.
bool m_inForBodyScope;