Skip to content

Commit f4b5576

Browse files
committed
Adding relations to non edged bytecode chunks that appear in the debug trace
1 parent b1e3873 commit f4b5576

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

src/main/java/net/nandgr/debugger/cfg/CFGCreatorDefault.java

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.nandgr.debugger.cfg.beans.BytecodeSection;
55
import net.nandgr.debugger.cfg.beans.ContractBytecode;
66
import net.nandgr.debugger.cfg.beans.OpcodeSource;
7+
import net.nandgr.debugger.node.response.json.DebugTraceTransactionLog;
78
import net.nandgr.eth.Opcode;
89
import net.nandgr.eth.Opcodes;
910
import java.math.BigInteger;
@@ -20,10 +21,11 @@ public class CFGCreatorDefault {
2021
Opcodes.JUMP,
2122
Opcodes.STOP,
2223
Opcodes.REVERT,
23-
Opcodes.RETURN
24+
Opcodes.RETURN,
25+
Opcodes.INVALID
2426
).collect(Collectors.toList());
2527

26-
public ContractBytecode createContractBytecode(List<OpcodeSource> contractOpcodes) {
28+
public ContractBytecode createContractBytecode(List<OpcodeSource> contractOpcodes, Map<Integer, DebugTraceTransactionLog> trace) {
2729
BigInteger codeOffset = BigInteger.valueOf(0);
2830
BytecodeSection constructorSection = null;
2931
boolean constructorFound = false;
@@ -52,11 +54,51 @@ public ContractBytecode createContractBytecode(List<OpcodeSource> contractOpcode
5254

5355
Map<Integer, BytecodeChunk> functionsChunks = splitInChunks(functionsOpcodes);
5456
createRelations(functionsChunks);
57+
checkChunksWithTrace(functionsChunks, trace);
5558
BytecodeSection functionsSection = new BytecodeSection(functionsChunks);
5659

5760
return new ContractBytecode(constructorSection, functionsSection);
5861
}
5962

63+
private void checkChunksWithTrace(Map<Integer, BytecodeChunk> functionsChunks, Map<Integer, DebugTraceTransactionLog> trace) {
64+
for (Map.Entry<Integer, BytecodeChunk> entry : functionsChunks.entrySet()) {
65+
BytecodeChunk chunk = entry.getValue();
66+
OpcodeSource lastOpcode = chunk.getOpcodes().get(chunk.getOpcodes().size() - 1);
67+
68+
if (trace.containsKey(lastOpcode.getOffset()) && chunk.hasEmptyRelations() && isJumpOpcode(lastOpcode)) {
69+
DebugTraceTransactionLog jumpTrace = trace.get(lastOpcode.getOffset());
70+
Integer jumpDestination = Integer.valueOf(jumpTrace.getStack().get(jumpTrace.getStack().size() - 1), 16);
71+
BytecodeChunk destChunk;
72+
if (functionsChunks.containsKey(jumpDestination)) {
73+
destChunk = functionsChunks.get(jumpDestination);
74+
} else {
75+
destChunk = searchDestinationChunk(functionsChunks, jumpDestination);
76+
}
77+
chunk.setBranchA(destChunk);
78+
}
79+
}
80+
}
81+
82+
private boolean isJumpOpcode(OpcodeSource lastOpcode) {
83+
return isJump(lastOpcode) || lastOpcode.getOpcode().equals(Opcodes.JUMPI);
84+
}
85+
86+
private boolean isJump(OpcodeSource lastOpcode) {
87+
return lastOpcode.getOpcode().equals(Opcodes.JUMP);
88+
}
89+
90+
private BytecodeChunk searchDestinationChunk(Map<Integer, BytecodeChunk> functionsChunks, Integer jumpDestination) {
91+
for (Map.Entry<Integer, BytecodeChunk> entry : functionsChunks.entrySet()) {
92+
BytecodeChunk chunk = entry.getValue();
93+
for (OpcodeSource opcodeSource : chunk.getOpcodes()) {
94+
if (opcodeSource.getOffset() == jumpDestination) {
95+
return chunk;
96+
}
97+
}
98+
}
99+
return null;
100+
}
101+
60102
private static void adjustOffsets(List<OpcodeSource> functionsOpcodes, int offset) {
61103
for (Opcode opcode : functionsOpcodes) {
62104
opcode.setOffset(opcode.getOffset() - offset);

src/main/java/net/nandgr/debugger/transformers/SolidityTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public List<ContractObject> loadContracts(String sourceCodeFile) throws Transfor
124124

125125
CFGCreatorDefault cfgCreatorDefault = new CFGCreatorDefault();
126126

127-
ContractBytecode contractBytecode = cfgCreatorDefault.createContractBytecode(opcodeSources);
127+
ContractBytecode contractBytecode = cfgCreatorDefault.createContractBytecode(opcodeSources, traceDataContract);
128128
Map<Integer, BytecodeChunk> runtimeChunks = contractBytecode.getRuntime().getChunks();
129129

130130
GraphVizCreator graphVizCreator = new GraphVizCreator(runtimeChunks, traceDataContract, cName);

0 commit comments

Comments
 (0)