Fixture 05
cleanup and state machine
C · 2 functions · 4 lanes · 8 of 8 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Control-flow closure fixture: goto cleanup ladders, cold error blocks, retry loops (backward gotos), and a small protocol state machine. The target bug class is mis-structured cross-block flow — a decompiler that drops a cleanup edge, folds two error arms together, or mis-orders the state transitions produces a different return the moment an input exercises the affected path.
Targets review #3 / #5 (cleanup ladders + control-flow join structuring). Key property: every local goto resolves to an emitted label — no dangling gotos, every cold block is reachable via some input. Each failure path returns a DISTINCT negative code; success returns a positive value derived from the input. All functions are differential-testable: int / const uint8_t* arguments, int return, no libc.
/* 05_cleanup_and_state_machine.c
*
* Control-flow closure fixture: `goto cleanup` ladders, cold error blocks,
* retry loops (backward gotos), and a small protocol state machine. The target
* bug class is mis-structured cross-block flow — a decompiler that drops a
* cleanup edge, folds two error arms together, or mis-orders the state
* transitions produces a different return the moment an input exercises the
* affected path.
*
* Targets review #3 / #5 (cleanup ladders + control-flow join structuring).
* Key property: every local `goto` resolves to an emitted label — no dangling
* gotos, every cold block is reachable via some input. Each failure path
* returns a DISTINCT negative code; success returns a positive value derived
* from the input. All functions are differential-testable: int / const uint8_t*
* arguments, int return, no libc.
*/
#include <stdint.h>
/* Resource-acquisition-style validation ladder. Several conditions are checked
* in sequence; each failure jumps into a cleanup ladder that unwinds the
* "acquired" state (modeled by an accumulator that each stage adjusts) and
* returns a distinct negative error code. Success returns a positive value
* derived from the input bytes.
*
* A bounded retry loop sits in the middle: a transient condition on one byte
* jumps backward to `retry` up to a fixed number of attempts before giving up
* through the cleanup ladder. */
int process(const uint8_t *in, int n) {
int acc = 0;
int stage = 0; /* how far we "acquired"; cleanup unwinds by stage */
int attempts = 0;
if (in == 0)
goto fail_null; /* nothing acquired yet */
if (n < 4)
goto fail_short; /* nothing acquired yet */
/* Stage 1: header byte must be even. */
stage = 1;
if ((in[0] & 1) != 0)
goto fail_hdr;
acc += in[0];
retry:
/* Stage 2 with retry: in[1] must be non-zero. If it is zero we "retry"
* by folding in the next attempt's contribution; after 3 attempts we fail
* through the cleanup ladder. */
if (in[1] == 0) {
attempts++;
if (attempts < 3) {
acc += 1; /* transient backoff contribution */
goto retry;
}
goto fail_retry; /* exhausted retries: stage 1 acquired */
}
/* Stage 2 acquired. */
stage = 2;
acc += in[1] * 2;
/* Stage 3: in[2] bounds the payload nibble. */
stage = 3;
if (in[2] > 0x7F)
goto fail_range;
acc += in[2] * 3;
/* Stage 4: checksum-style consistency across the first four bytes. */
stage = 4;
{
int sum = in[0] + in[1] + in[2] + in[3];
if ((sum & 0xFF) == 0xEE)
goto fail_checksum;
acc += in[3] * 4;
}
/* Success: a positive value that folds in the stage reached and the
* accumulated contributions, kept in a modest positive range. */
return 1000 + (acc & 0x3FF) + stage;
/* --- cold cleanup ladder: unwinds by falling through, each entry point
* releases exactly the resources acquired up to its stage. --- */
fail_checksum:
acc -= in[3] * 4; /* release stage 4 */
/* fall through */
fail_range:
if (stage >= 3)
acc -= in[2] * 3; /* release stage 3 */
/* fall through */
fail_retry:
fail_hdr:
if (stage >= 1)
acc -= in[0]; /* release stage 1 */
/* distinct codes for the ladder entry points that share the tail */
if (stage == 4) return -40;
if (stage == 3) return -30;
if (attempts >= 3) return -25; /* fail_retry entry */
return -10; /* fail_hdr entry */
fail_short:
return -2;
fail_null:
return -1;
}
/* Protocol state machine: walk `input` advancing IDLE -> HDR -> BODY -> DONE.
* The byte sequence drives the transitions; the return code depends on which
* state the walk ends in and how much body was consumed. If a decompiler
* mis-structures the state dispatch (e.g. swaps two case arms or drops the
* fallthrough from HDR to BODY) the return diverges for crafted inputs. */
int fsm(const uint8_t *input, int len) {
enum { S_IDLE = 0, S_HDR = 1, S_BODY = 2, S_DONE = 3, S_ERR = 4 };
int state = S_IDLE;
int body_count = 0;
int checksum = 0;
int i = 0;
if (input == 0 || len <= 0)
return -100;
while (i < len) {
uint8_t b = input[i];
switch (state) {
case S_IDLE:
/* Start-of-message marker. */
if (b == 0xA5)
state = S_HDR;
else if (b == 0x00)
state = S_IDLE; /* idle padding, stay */
else
goto machine_error;
break;
case S_HDR:
/* Header carries the declared body length in the low nibble. */
if (b == 0xFF)
goto machine_error; /* reserved header */
body_count = (b & 0x0F);
if (body_count == 0)
state = S_DONE; /* empty body: jump straight to DONE */
else
state = S_BODY;
checksum = b;
break;
case S_BODY:
checksum += b;
body_count--;
if (body_count == 0)
state = S_DONE;
/* else remain in S_BODY consuming more bytes */
break;
case S_DONE:
/* Trailer byte must match the low byte of the checksum. */
if (b == (uint8_t)(checksum & 0xFF))
return 200 + (checksum & 0x3F); /* clean finish */
else
return -201; /* bad trailer */
default:
goto machine_error;
}
i++;
}
/* Ran out of input: distinct code per terminal state so a mis-structured
* transition surfaces. */
if (state == S_DONE) return 150; /* reached DONE, no trailer seen */
if (state == S_BODY) return -150; /* truncated body */
if (state == S_HDR) return -140; /* header without body */
return -130; /* still idle */
machine_error:
return -110 - state; /* distinct per originating state */
} Recovered C
Generated by glaurung decompile --style decbench at b47f6b43.
baseline.json records the result after recompiling the C and calling it beside the
original with seeded inputs.
clang -O0
2/2fsm pass 121 lines
// glaurung: fsm @ 0x1320
int fsm(const uint8_t * arg0, int arg1) {
int state;
int body_count;
int checksum;
int i;
unsigned char b;
long local_30;
int local_4;
// x86-64 prologue: save rbp
state = 0;
body_count = 0;
checksum = 0;
i = 0;
if ((arg0 == 0)) {
local_4 = -100;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0)) != 0)) {
local_4 = -100;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
L_136d: ;
while (1) {
if ((arg1 <= i)) {
goto L_14a9;
}
b = arg0[i];
local_30 = (unsigned int)(state);
if (((unsigned long)(3) < (unsigned long)((unsigned long)((unsigned int)(state))))) {
goto L_1496;
}
switch (local_30) {
case 0:
goto L_13ac;
case 1:
goto L_13ef;
case 2:
goto L_1436;
case 3:
goto L_145f;
}
L_13ac: ;
if (((unsigned long)((unsigned long)(b)) == 165)) {
state = 1;
goto L_13ea;
}
if (((unsigned long)((unsigned long)(b)) != 0)) {
goto L_13e0;
}
state = 0;
goto L_13e5;
L_13e5: ;
goto L_13ea;
L_13ea: ;
goto L_149b;
L_13ef: ;
if (((unsigned long)((unsigned long)(b)) == 255)) {
goto L_13fe;
}
body_count = ((unsigned int)(b) & 15);
if (((unsigned long)((unsigned int)(body_count)) == 0)) {
state = 3;
goto L_142a;
}
state = 2;
L_142a: ;
checksum = b;
goto L_149b;
L_1436: ;
checksum = ((unsigned int)(b) + checksum);
body_count = ((unsigned int)(body_count) - 1);
if (((unsigned long)((unsigned int)(body_count)) == 0)) {
state = 3;
}
goto L_149b;
L_149b: ;
i = ((unsigned int)(i) + 1);
goto L_136d;
}
L_13e0: ;
goto L_14f7;
L_13fe: ;
goto L_14f7;
L_145f: ;
if (((unsigned long)((unsigned long)(b)) == (unsigned long)((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(checksum)) & 255))) & 255)))))) {
local_4 = ((unsigned int)(((unsigned long)((unsigned int)(checksum)) & 63)) + 200);
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_4 = -201;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1496: ;
goto L_14f7;
L_14a9: ;
if (((unsigned long)((unsigned int)(state)) == 3)) {
local_4 = 150;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned long)((unsigned int)(state)) == 2)) {
local_4 = -150;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned long)((unsigned int)(state)) == 1)) {
local_4 = -140;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_4 = -130;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_14f7: ;
local_4 = (0xffffff92 - state);
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} process pass 84 lines
// glaurung: process @ 0x1100
int process(const uint8_t * arg0, int arg1) {
int acc;
int stage;
int attempts;
int sum;
int local_4;
int var23;
acc = 0;
stage = 0;
attempts = 0;
if ((arg0 == 0)) {
goto L_1305;
}
if (((long)(arg1) < 4)) {
goto L_12f9;
}
stage = 1;
if (((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)((long)arg0))) & 1))) != 0)) {
goto L_1292;
}
acc = ((unsigned int)((unsigned char)(*(char *)((long)arg0))) + acc);
L_116b: ;
if (((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x1))))) == 0)) {
attempts = ((unsigned int)(attempts) + 1);
if (((long)(attempts) < 3)) {
acc = ((unsigned int)(acc) + 1);
goto L_116b;
}
goto L_128d;
}
stage = 2;
acc = ((unsigned int)(((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x1)))) << 1)) + acc);
stage = 3;
var23 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x2))));
if (((((unsigned long)((unsigned int)(var23)) == 127) | ((long)((int)(var23)) < 127)) != 0)) {
acc = (((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x2)))) * 3) + acc);
stage = 4;
sum = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)((long)arg0))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x1))))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x2)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x3)))));
if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(sum)) & 255))) != 238)) {
acc = ((unsigned int)(((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x3)))) << 2)) + acc);
local_4 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(acc)) & 1023))) + 1000)) + stage);
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
acc = ((unsigned int)(acc) - (unsigned int)(((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x3)))) << 2)));
}
if ((3 <= (long)(stage))) {
acc = ((unsigned int)(acc) - ((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x2)))) * 3));
}
goto L_128d;
L_128d: ;
goto L_1292;
L_1292: ;
if ((1 <= (long)(stage))) {
acc = ((unsigned int)(acc) - (unsigned int)((unsigned char)(*(char *)((long)arg0))));
}
if (((unsigned long)((unsigned int)(stage)) == 4)) {
local_4 = -40;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((unsigned long)((unsigned int)(stage)) == 3)) {
local_4 = -30;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if ((3 <= (long)(attempts))) {
local_4 = -25;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
local_4 = -10;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_12f9: ;
local_4 = -2;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_1305: ;
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
2/2fsm pass 103 lines
// glaurung: fsm @ 0x1170
int fsm(const uint8_t * arg0, int arg1) {
int state;
int i;
int body_count;
int checksum;
long ret;
long var0;
long var10;
long var11;
long var12;
int var14;
int var19;
long var20;
int var34;
int var40;
long var41;
ret = 0xffffff9c;
if ((arg0 == 0)) {
return ret;
}
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return ret;
}
var0 = (unsigned long)((unsigned int)(arg1));
var10 = 0;
var11 = 0;
var12 = 0;
state = 0;
L_11b8: ;
while (1) {
if (((unsigned long)(3) < (unsigned long)((unsigned long)((unsigned int)(state))))) {
goto L_121c;
}
goto L_11bd;
L_11a0: ;
var19 = (var11 - 1);
var20 = (unsigned long)((unsigned int)(var19));
var10 = (unsigned long)((unsigned int)((var10 + var14)));
state = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(var19)) == 0) | 2)));
L_11af: ;
i = (var12 + 1);
var11 = var20;
var12 = (unsigned long)((unsigned int)(i));
if ((var0 == i)) {
goto L_1201;
}
goto L_11b8;
L_11bd: ;
var14 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + var12))));
switch ((unsigned long)((unsigned int)(state))) {
case 0:
goto L_11cc;
case 1:
goto L_11e0;
case 2:
goto L_11a0;
case 3:
goto L_1224;
}
L_11cc: ;
if (((unsigned long)((unsigned char)((var14 & 255))) == 165)) {
goto L_11fa;
}
if (((unsigned long)((unsigned char)((var14 & 255))) != 0)) {
goto L_121c;
}
var20 = var11;
state = 0;
goto L_11af;
L_11e0: ;
if (((unsigned long)((unsigned char)((var14 & 255))) == 255)) {
goto L_121c;
}
var34 = ((unsigned int)(var14) & 15);
state = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(var34)) == 0) | 2)));
var10 = (unsigned long)((unsigned int)(var14));
var20 = (unsigned long)((unsigned int)(var34));
goto L_11af;
L_11fa: ;
state = 1;
var20 = var11;
goto L_11af;
}
L_1201: ;
var40 = (state - 1);
var41 = (unsigned long)((unsigned int)(var40));
ret = 0xffffff7e;
if (((unsigned long)(3) <= (unsigned long)((unsigned long)((unsigned int)(var40))))) {
goto L_121b;
}
ret = (unsigned long)((unsigned int)(*(int *)((0x2010 + ((long)((int)(var41)) * 4)))));
L_121b: ;
return ret;
L_121c: ;
return (unsigned int)((0xffffff92 - state));
L_1224: ;
ret = 0xffffff37;
if (((unsigned char)((var14 & 255)) != (unsigned char)((var10 & 255)))) {
goto L_121b;
}
return (unsigned int)(((unsigned long)((unsigned int)((var10 & 63))) + 200));
} process pass 36 lines
// glaurung: process @ 0x1100
int process(const uint8_t * arg0, int arg1) {
int acc;
int stage;
int sum;
long ret;
int var0;
int var1;
int var2;
int var6;
if ((arg0 == 0)) {
return 0xffffffff;
}
ret = 0xfffffffe;
if ((4 <= (long)(arg1))) {
var0 = (unsigned int)((unsigned char)(*(char *)(((long)arg0))));
ret = 0xfffffff6;
if (((unsigned long)((unsigned char)((var0 & 1))) != 0)) {
return ret;
}
var1 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x1))));
if (((unsigned long)((unsigned int)(var1)) == 0)) {
return 0xffffffe7;
}
var2 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x2))));
if (((long)((signed char)((var2 & 255))) < 0)) {
return 0xffffffe2;
}
var6 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x3))));
ret = 0xffffffd8;
if (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var1 + var0))) + var2))) + var6))) & 255))) != 238)) {
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var2 + (var2 * 2)))) + (unsigned long)((unsigned int)((var0 + (var1 * 2))))))) + (var6 * 4)))) & 1023))) + 1004)));
}
}
return ret;
} gcc -O0
2/2fsm pass 86 lines
// glaurung: fsm @ 0x12dc
int fsm(const uint8_t * arg0, int arg1) {
int state;
int body_count;
int checksum;
int i;
unsigned char b;
state = 0;
body_count = 0;
checksum = 0;
i = 0;
if ((arg0 != 0)) {
if (((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0)) == 0)) {
goto L_13fa;
}
}
// x86-64 epilogue: restore rbp
return 0xffffff9c;
L_1322: ;
b = arg0[i];
switch (state) {
case 0:
if ((b == 165)) {
state = 1;
goto L_13f6;
}
if ((b != 0)) {
// x86-64 epilogue: restore rbp
return (unsigned int)((0xffffff92 - state));
}
state = 0;
goto L_13f6;
case 1:
if ((b == 255)) {
// x86-64 epilogue: restore rbp
return (unsigned int)((0xffffff92 - state));
}
body_count = ((unsigned int)(b) & 15);
if (((unsigned long)((unsigned int)(body_count)) == 0)) {
state = 3;
goto L_13b6;
}
state = 2;
L_13b6: ;
checksum = b;
goto L_13f6;
case 2:
checksum = (checksum + (unsigned int)(b));
body_count = (body_count - 1);
if (((unsigned long)((unsigned int)(body_count)) != 0)) {
goto L_13f5;
}
state = 3;
goto L_13f5;
case 3:
if ((b == (unsigned long)((unsigned char)(((unsigned long)((unsigned int)(checksum)) & 255))))) {
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(checksum)) & 63))) + 200));
}
// x86-64 epilogue: restore rbp
return 0xffffff37;
L_13f5: ;
L_13f6: ;
i = (i + 1);
L_13fa: ;
if ((i < arg1)) {
goto L_1322;
}
if (((unsigned long)((unsigned int)(state)) == 3)) {
// x86-64 epilogue: restore rbp
return 150;
}
if (((unsigned long)((unsigned int)(state)) == 2)) {
// x86-64 epilogue: restore rbp
return 0xffffff6a;
}
if (((unsigned long)((unsigned int)(state)) != 1)) {
// x86-64 epilogue: restore rbp
return 0xffffff7e;
}
// x86-64 epilogue: restore rbp
return 0xffffff74;
}
// x86-64 epilogue: restore rbp
return (unsigned int)((0xffffff92 - state));
} process pass 82 lines
// glaurung: process @ 0x10f9
int process(const uint8_t * arg0, int arg1) {
int acc;
int stage;
int attempts;
int sum;
int var14;
int var23;
int var73;
acc = 0;
stage = 0;
attempts = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if ((((unsigned long)((unsigned int)(arg1)) == 3) | ((long)(arg1) < 3))) {
// x86-64 epilogue: restore rbp
return 0xfffffffe;
}
stage = 1;
if (((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((long)arg0))) & 255))) & 1))) != 0)) {
goto L_1284;
}
acc = (acc + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((long)arg0))) & 255))));
L_115b: ;
if (((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(arg0[1])) & 255))) == 0)) {
attempts = (attempts + 1);
if (((((unsigned long)((unsigned int)(attempts)) == 2) | ((long)(attempts) < 2)) == 0)) {
goto L_1287;
}
acc = (acc + 1);
goto L_115b;
}
stage = 2;
var14 = (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[1])) & 255)));
acc = (acc + (unsigned int)((var14 + var14)));
stage = 3;
if ((0 <= (long)((signed char)(((unsigned int)((unsigned char)(arg0[2])) & 255))))) {
var23 = (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[2])) & 255)));
acc = (acc + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var23)) + (unsigned long)((unsigned int)(var23))))) + var23)));
stage = 4;
sum = ((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[3])) & 255))) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((long)arg0))) & 255))) + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[1])) & 255)))))) + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[2])) & 255))))));
if (((unsigned long)((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(sum)) & 255)))) != 238)) {
acc = (acc + (unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[3])) & 255))) << 2)));
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(stage)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(acc)) & 1023))) + 1000)))));
}
acc = (acc - (unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[3])) & 255))) << 2)));
goto L_125e;
}
L_125e: ;
if ((((unsigned long)((unsigned int)(stage)) == 2) | ((long)(stage) < 2))) {
goto L_128a;
}
var73 = (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(arg0[2])) & 255)));
acc = (acc + (unsigned int)(((unsigned long)((unsigned int)(var73)) - (unsigned long)((unsigned int)((var73 * 4))))));
goto L_128b;
L_1284: ;
goto L_128b;
L_1287: ;
goto L_128b;
L_128a: ;
L_128b: ;
if (((((unsigned long)((unsigned int)(stage)) == 0) | ((long)(stage) < 0)) == 0)) {
acc = (acc - (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((long)arg0))) & 255))));
}
if (((unsigned long)((unsigned int)(stage)) == 4)) {
// x86-64 epilogue: restore rbp
return 0xffffffd8;
}
if (((unsigned long)((unsigned int)(stage)) == 3)) {
// x86-64 epilogue: restore rbp
return 0xffffffe2;
}
if ((((unsigned long)((unsigned int)(attempts)) == 2) | ((long)(attempts) < 2))) {
// x86-64 epilogue: restore rbp
return 0xfffffff6;
}
// x86-64 epilogue: restore rbp
return 0xffffffe7;
} gcc -O2
2/2fsm pass 118 lines
// glaurung: fsm @ 0x1180
int fsm(const uint8_t * arg0, int arg1) {
unsigned char b;
int body_count;
int checksum;
int i;
int state;
int var0;
long var1;
long var10;
int var14;
long var15;
int var16;
long var17;
long var20;
long var21;
long var22;
long var3;
long var31;
long var32;
long var33;
long var37;
long var38;
int var4;
long var41;
int var42;
long var5;
long var6;
if ((arg0 == 0)) {
return 0xffffff9c;
}
if ((((unsigned long)((unsigned int)(arg1)) == 0) | ((long)(arg1) < 0))) {
return 0xffffff9c;
}
var0 = (unsigned int)((unsigned char)(*(char *)(((long)arg0))));
if (((unsigned long)((unsigned char)((var0 & 255))) != 165)) {
if (((unsigned long)((unsigned char)((var0 & 255))) != 0)) {
return 0xffffff92;
}
if (((unsigned long)((unsigned int)(arg1)) != 1)) {
var1 = (long)(arg1);
var3 = 1;
do {
var4 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + var3))));
var5 = (long)((int)(var3));
if (((unsigned long)((unsigned char)((var4 & 255))) == 165)) {
goto L_1298;
}
if (((unsigned long)((unsigned char)((var4 & 255))) != 0)) {
return 0xffffff92;
}
var6 = (var3 + 1);
var3 = var6;
} while ((var1 != var6));
}
return 0xffffff7e;
}
var5 = 0;
var10 = 1;
L_11e8: ;
if ((((unsigned int)(arg1) == (unsigned int)(var10)) | ((long)(arg1) < (long)((int)(var10))))) {
return 0xffffff74;
}
b = (unsigned int)((unsigned char)(arg0[(long)((int)(var10))]));
if (((unsigned long)((unsigned char)((b & 255))) == 255)) {
return 0xffffff91;
}
var14 = (unsigned int)((unsigned char)((b & 255)));
var15 = (unsigned long)((unsigned int)((var5 + 2)));
var16 = ((unsigned int)((unsigned int)(b)) & 15);
var17 = (unsigned long)((unsigned int)(var16));
if (((unsigned long)((unsigned int)(var16)) != 0)) {
goto L_1238;
}
if ((((unsigned int)(arg1) == (unsigned int)(var15)) | ((long)(arg1) < (long)((int)(var15))))) {
return 150;
}
var20 = (unsigned long)((unsigned int)(var14));
var21 = (unsigned long)(b);
var22 = (unsigned int)((unsigned char)(arg0[(long)((int)(var15))]));
L_121e: ;
return (((unsigned char)((var21 & 255)) != (unsigned char)((var22 & 255))) ? 0xffffff37 : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var20 & 63))) + 200))));
L_1238: ;
if (((((unsigned int)(arg1) == (unsigned int)(var15)) | ((long)(arg1) < (long)((int)(var15)))) == 0)) {
var31 = (unsigned long)((unsigned int)((var14 + (unsigned int)((unsigned char)(arg0[(long)((int)(var15))])))));
var32 = var15;
if (((unsigned long)((unsigned char)((var17 & 255))) == 1)) {
goto L_1280;
}
var33 = (unsigned long)((unsigned int)((var5 + 3)));
if (((((unsigned int)(arg1) == (unsigned int)(var33)) | ((long)(arg1) < (long)((int)(var33)))) == 0)) {
var37 = ((var5 + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)((var17 & 255))) - 2)))) + 3);
var38 = (long)((int)(var33));
do {
var32 = (unsigned long)((unsigned int)(var38));
var31 = (unsigned long)((unsigned int)((var31 + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + var38)))))));
if ((var37 == var38)) {
goto L_1280;
}
var41 = (var38 + 1);
var38 = var41;
} while (((((unsigned int)(arg1) == (unsigned int)(var41)) | ((long)(arg1) < (long)((int)(var41)))) == 0));
}
}
return 0xffffff6a;
L_1280: ;
var42 = (var32 + 1);
if ((((unsigned int)(arg1) == (unsigned int)(var42)) | (arg1 < var42))) {
return 150;
}
var20 = var31;
var21 = (unsigned long)((unsigned int)(var31));
var22 = (unsigned int)((unsigned char)(arg0[(long)((int)(var42))]));
goto L_121e;
L_1298: ;
var10 = (unsigned long)((unsigned int)((var5 + 1)));
goto L_11e8;
} process pass 41 lines
// glaurung: process @ 0x1100
int process(const uint8_t * arg0, int arg1) {
int acc;
int stage;
long ret;
int var0;
int var1;
int var2;
long var3;
int var5;
long var6;
if ((arg0 == 0)) {
return 0xffffffff;
}
if ((((unsigned long)((unsigned int)(arg1)) == 3) | ((long)(arg1) < 3))) {
return 0xfffffffe;
}
var0 = (unsigned int)((unsigned char)(*(char *)(((long)arg0))));
ret = 0xfffffff6;
if (((unsigned long)((unsigned char)((var0 & 1))) != 0)) {
return ret;
}
var1 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x1))));
ret = 0xffffffe7;
if (((unsigned long)((unsigned char)((var1 & 255))) == 0)) {
return ret;
}
var2 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x2))));
ret = 0xffffffe2;
if (((long)((signed char)((var2 & 255))) < 0)) {
return ret;
}
var3 = (unsigned long)((unsigned int)((var0 + (var1 * 2))));
var5 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x3))));
var6 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var2 + (var2 * 2)))) + var3)));
ret = 0xffffffd8;
if (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var3 - var1))) + var2))) + var5))) & 255))) != 238)) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var6 + (var5 * 4)))) & 1023))) + 1004));
}
return 0xffffffd8;
}