Skip to content

Commit 375cdf5

Browse files
authored
fix: handle undefined for unsupported opcode (#244)
1 parent 0b17248 commit 375cdf5

File tree

6 files changed

+33
-7
lines changed

6 files changed

+33
-7
lines changed

src/action/evm_bytecode_visitor.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,9 @@ template <typename IRBuilder> class EVMByteCodeVisitor {
545545

546546
case OP_SELFDESTRUCT: {
547547
Operand Beneficiary = pop();
548+
handleEndBlock();
548549
Builder.handleSelfDestruct(Beneficiary);
550+
InDeadCode = true;
549551
break;
550552
}
551553

@@ -616,8 +618,10 @@ template <typename IRBuilder> class EVMByteCodeVisitor {
616618
}
617619

618620
default:
619-
throw getErrorWithExtraMessage(ErrorCode::UnsupportedOpcode,
620-
std::to_string(Opcode));
621+
// Treat as undefined
622+
handleEndBlock();
623+
Builder.handleUndefined();
624+
InDeadCode = true;
621625
}
622626
PC++; // offset 1 byte for opcode
623627
}

src/compiler/evm_frontend/evm_analyzer.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class EVMAnalyzer {
9999
case OP_TLOAD:
100100
case OP_BALANCE:
101101
case OP_SLOAD:
102+
case OP_BLOBHASH:
102103
PopCount = 1;
103104
PushCount = 1;
104105
break;
@@ -273,8 +274,11 @@ class EVMAnalyzer {
273274
case OP_EXTCODECOPY:
274275
PopCount = 4;
275276
break;
277+
case OP_JUMPDEST:
278+
break;
276279
default:
277-
// For unhandled opcodes, assume no stack change
280+
// For unhandled opcodes, treat as invalid
281+
Opcode = OP_INVALID;
278282
break;
279283
}
280284

@@ -291,9 +295,9 @@ class EVMAnalyzer {
291295
// Check if this is a block starting opcode
292296
bool IsBlockStart = (Opcode == OP_JUMPDEST || Opcode == OP_JUMPI);
293297
// Check if this is a block ending opcode
294-
bool IsBlockEnd =
295-
(Opcode == OP_JUMP || Opcode == OP_RETURN || Opcode == OP_STOP ||
296-
Opcode == OP_INVALID || Opcode == OP_REVERT);
298+
bool IsBlockEnd = (Opcode == OP_JUMP || Opcode == OP_RETURN ||
299+
Opcode == OP_STOP || Opcode == OP_INVALID ||
300+
Opcode == OP_REVERT || Opcode == OP_SELFDESTRUCT);
297301

298302
if (IsBlockStart) {
299303
if (PC != CurInfo.EntryPC) {

src/compiler/evm_frontend/evm_imported.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const RuntimeFunctions &getRuntimeFunctionTable() {
111111
.HandleStaticCall = &evmHandleStaticCall,
112112
.SetRevert = &evmSetRevert,
113113
.HandleInvalid = &evmHandleInvalid,
114+
.HandleUndefined = &evmHandleUndefined,
114115
.HandleSelfDestruct = &evmHandleSelfDestruct,
115116
.GetKeccak256 = &evmGetKeccak256};
116117
return Table;
@@ -997,14 +998,23 @@ uint64_t evmHandleCallCode(zen::runtime::EVMInstance *Instance, uint64_t Gas,
997998
}
998999

9991000
void evmHandleInvalid(zen::runtime::EVMInstance *Instance) {
1000-
// Immediately terminate the execution and return the revert code (2)
1001+
// Immediately terminate the execution and return the invalid code (4)
10011002
evmc::Result ExeResult(
10021003
EVMC_INVALID_INSTRUCTION, 0, Instance ? Instance->getGasRefund() : 0,
10031004
Instance->getReturnData().data(), Instance->getReturnData().size());
10041005
Instance->setExeResult(std::move(ExeResult));
10051006
Instance->exit(4);
10061007
}
10071008

1009+
void evmHandleUndefined(zen::runtime::EVMInstance *Instance) {
1010+
// Immediately terminate the execution and return the undefined code
1011+
evmc::Result ExeResult(
1012+
EVMC_UNDEFINED_INSTRUCTION, 0, Instance ? Instance->getGasRefund() : 0,
1013+
Instance->getReturnData().data(), Instance->getReturnData().size());
1014+
Instance->setExeResult(std::move(ExeResult));
1015+
Instance->exit(5);
1016+
}
1017+
10081018
uint64_t evmHandleDelegateCall(zen::runtime::EVMInstance *Instance,
10091019
uint64_t Gas, const uint8_t *ToAddr,
10101020
uint64_t ArgsOffset, uint64_t ArgsSize,

src/compiler/evm_frontend/evm_imported.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ struct RuntimeFunctions {
136136
DelegateCallFn HandleStaticCall;
137137
VoidWithUInt64UInt64Fn SetRevert;
138138
VoidFn HandleInvalid;
139+
VoidFn HandleUndefined;
139140
VoidWithBytes32Fn HandleSelfDestruct;
140141
Bytes32WithUInt64UInt64Fn GetKeccak256;
141142
};
@@ -258,6 +259,7 @@ uint64_t evmHandleStaticCall(zen::runtime::EVMInstance *Instance, uint64_t Gas,
258259
void evmSetRevert(zen::runtime::EVMInstance *Instance, uint64_t Offset,
259260
uint64_t Size);
260261
void evmHandleInvalid(zen::runtime::EVMInstance *Instance);
262+
void evmHandleUndefined(zen::runtime::EVMInstance *Instance);
261263
const uint8_t *evmGetKeccak256(zen::runtime::EVMInstance *Instance,
262264
uint64_t Offset, uint64_t Length);
263265
const intx::uint256 *evmGetSLoad(zen::runtime::EVMInstance *Instance,

src/compiler/evm_frontend/evm_mir_compiler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,11 @@ void EVMMirBuilder::handleInvalid() {
19471947
const auto &RuntimeFunctions = getRuntimeFunctionTable();
19481948
callRuntimeFor(RuntimeFunctions.HandleInvalid);
19491949
}
1950+
1951+
void EVMMirBuilder::handleUndefined() {
1952+
const auto &RuntimeFunctions = getRuntimeFunctionTable();
1953+
callRuntimeFor(RuntimeFunctions.HandleUndefined);
1954+
}
19501955
typename EVMMirBuilder::Operand
19511956
EVMMirBuilder::handleSLoad(Operand KeyComponents) {
19521957
const auto &RuntimeFunctions = getRuntimeFunctionTable();

src/compiler/evm_frontend/evm_mir_compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ class EVMMirBuilder final {
397397
Operand RetOffsetOp, Operand RetSizeOp);
398398
void handleRevert(Operand OffsetOp, Operand SizeOp);
399399
void handleInvalid();
400+
void handleUndefined();
400401
void handleTrap(ErrorCode ErrCode);
401402
Operand handleKeccak256(Operand OffsetComponents, Operand LengthComponents);
402403
Operand handleSLoad(Operand KeyComponents);

0 commit comments

Comments
 (0)