Skip to content

Commit b7fd40b

Browse files
Abstract semantics of RETURNDATASIZE
1 parent bdcf5fe commit b7fd40b

File tree

2 files changed

+65
-7
lines changed

2 files changed

+65
-7
lines changed

src/main/java/it/unipr/analysis/AbstractStack.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ public class AbstractStack implements ValueDomain<AbstractStack>, BaseLattice<Ab
5656
*/
5757
private int tail;
5858

59+
/**
60+
* Value of the output size of the last call (CALL, DELEGATECALL, CALLCODE,
61+
* STATICCALL).
62+
*/
63+
private StackElement outSize;
64+
5965
/**
6066
* Helper method to create and fill an array with a specific element.
6167
*/
@@ -72,17 +78,19 @@ public AbstractStack() {
7278
this(createFilledArray(STACK_LIMIT, StackElement.BOTTOM));
7379
this.head = 0;
7480
this.tail = 0;
81+
this.outSize = StackElement.BOTTOM;
7582
}
7683

7784
/**
7885
* Builds a symbolic stack starting from a given stack array.
7986
*
8087
* @param stack the stack of values
8188
*/
82-
public AbstractStack(StackElement[] stack) {
89+
private AbstractStack(StackElement[] stack) {
8390
this.circularArray = stack;
8491
this.head = 0;
8592
this.tail = 0;
93+
this.outSize = StackElement.BOTTOM;
8694
}
8795

8896
@Override
@@ -236,6 +244,7 @@ public AbstractStack clone() {
236244
AbstractStack clone = new AbstractStack(circularArray.clone());
237245
clone.head = this.head;
238246
clone.tail = this.tail;
247+
clone.outSize = this.outSize;
239248
return clone;
240249
}
241250

@@ -359,7 +368,6 @@ public static int getStackLimit() {
359368
* @return {@code true} if between 0 and x-positions of the stack an element
360369
* is bottom, {@code false} otherwise.
361370
*/
362-
363371
public boolean hasBottomUntil(int x) {
364372
for (int i = 0; i < x; i++) {
365373
int pos = (tail - 1 - i + STACK_LIMIT) % STACK_LIMIT;
@@ -422,4 +430,22 @@ private StackElement[] toLogicalArray() {
422430
logical[i] = circularArray[(head + i) % STACK_LIMIT];
423431
return logical;
424432
}
433+
434+
/**
435+
* Sets size of output data from the previous call.
436+
*
437+
* @param outSize the size of output data from the previous call.
438+
*/
439+
public void setOutSize(StackElement outSize) {
440+
this.outSize = outSize;
441+
}
442+
443+
/**
444+
* Gets size of output data from the previous call.
445+
*
446+
* @return the size of output data from the previous call
447+
*/
448+
public StackElement getOutSize() {
449+
return outSize;
450+
}
425451
}

src/main/java/it/unipr/analysis/EVMAbstractState.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ public EVMAbstractState smallStepSemantics(ValueExpression expression, ProgramPo
214214
case "GaslimitOperator": // GASLIMIT
215215
case "ChainidOperator": // CHAINID
216216
case "SelfbalanceOperator": // SELFBALANCE
217-
case "ReturndatasizeOperator": // RETURNDATASIZE
218217
case "GaspriceOperator": // GASPRICE
219218
case "CodesizeOperator": // CODESIZE
220219
case "OriginOperator": // ORIGIN
@@ -230,6 +229,23 @@ public EVMAbstractState smallStepSemantics(ValueExpression expression, ProgramPo
230229
return new EVMAbstractState(result, memory, storage);
231230
}
232231

232+
case "ReturndatasizeOperator": { // RETURNDATASIZE
233+
for (AbstractStack stack : stacks) {
234+
// stack corresponding to the case when
235+
// last call failed
236+
AbstractStack resultStackFailing = stack.clone();
237+
resultStackFailing.push(StackElement.ZERO);
238+
result.add(resultStackFailing);
239+
240+
// stack corresponding to the case when
241+
// last call was successful
242+
AbstractStack resultStackSuccess = stack.clone();
243+
resultStackSuccess.push(stack.getOutSize());
244+
result.add(resultStackSuccess);
245+
}
246+
247+
return new EVMAbstractState(result, memory, storage);
248+
}
233249
case "PcOperator": { // PC
234250
for (AbstractStack stack : stacks) {
235251
AbstractStack resultStack = stack.clone();
@@ -1755,7 +1771,11 @@ else if (indexOfByte.compareTo(new StackElement(Number.MAX_INT)) < 0) {
17551771
if (stack.hasBottomUntil(7))
17561772
continue;
17571773
AbstractStack resultStack = stack.clone();
1758-
resultStack.popX(7);
1774+
resultStack.popX(6);
1775+
1776+
// Setting outsize
1777+
StackElement outSize = resultStack.pop();
1778+
resultStack.setOutSize(outSize);
17591779

17601780
resultStack.push(StackElement.NOT_JUMPDEST_TOP);
17611781
result.add(resultStack);
@@ -1771,7 +1791,11 @@ else if (indexOfByte.compareTo(new StackElement(Number.MAX_INT)) < 0) {
17711791
if (stack.hasBottomUntil(7))
17721792
continue;
17731793
AbstractStack resultStack = stack.clone();
1774-
resultStack.popX(7);
1794+
resultStack.popX(6);
1795+
1796+
// Setting outsize
1797+
StackElement outSize = resultStack.pop();
1798+
resultStack.setOutSize(outSize);
17751799

17761800
resultStack.push(StackElement.NOT_JUMPDEST_TOP);
17771801
result.add(resultStack);
@@ -1803,7 +1827,11 @@ else if (indexOfByte.compareTo(new StackElement(Number.MAX_INT)) < 0) {
18031827
if (stack.hasBottomUntil(6))
18041828
continue;
18051829
AbstractStack resultStack = stack.clone();
1806-
resultStack.popX(6);
1830+
resultStack.popX(5);
1831+
1832+
// Setting outsize
1833+
StackElement outSize = resultStack.pop();
1834+
resultStack.setOutSize(outSize);
18071835

18081836
resultStack.push(StackElement.NOT_JUMPDEST_TOP);
18091837
result.add(resultStack);
@@ -1819,7 +1847,11 @@ else if (indexOfByte.compareTo(new StackElement(Number.MAX_INT)) < 0) {
18191847
if (stack.hasBottomUntil(6))
18201848
continue;
18211849
AbstractStack resultStack = stack.clone();
1822-
resultStack.popX(6);
1850+
resultStack.popX(5);
1851+
1852+
// Setting outsize
1853+
StackElement outSize = resultStack.pop();
1854+
resultStack.setOutSize(outSize);
18231855

18241856
resultStack.push(StackElement.NOT_JUMPDEST_TOP);
18251857
result.add(resultStack);

0 commit comments

Comments
 (0)