Fixture 145
control flow flattening
C · 4 functions · 4 lanes · 14 of 16 function-lanes behave identically
One lane has a function that returns a different result after decompilation: clang-O0 (2/4).
Control-flow flattening: the shape produced by every commodity obfuscator (OLLVM's -fla, VMProtect's dispatcher, most packers' unpack stubs).
Every structured region — the loop, the if/else ladder, the early exit — is dissolved into basic blocks that no longer dominate each other. What remains is a single while around a switch on a state variable, plus assignments to that variable at the end of each block. The original edges live only in the DATA the dispatcher reads, not in the CFG.
Why this breaks decompilers: interval/structural analysis sees one loop with N successors and no natural nesting, so it emits while (1) { switch (state) { ... } } verbatim — syntactically valid, semantically faithful, and completely useless to an analyst. Worse, a structurer that tries to be clever often *invents* nesting that isn't there, producing confident nonsense: a for loop whose body is only reachable on one of the three state edges. The differential catches exactly that class of over-eager restructuring, because a wrong edge changes the answer even though the text looks plausible.
Everything here is fully defined: all arithmetic that can overflow runs through uint32_t, every buffer index is bounded by a validated count, and the dispatcher carries a step budget so the loop terminates for any input.
#include <stdint.h>
/* Control-flow flattening: the shape produced by every commodity obfuscator
* (OLLVM's `-fla`, VMProtect's dispatcher, most packers' unpack stubs).
*
* Every structured region — the loop, the if/else ladder, the early exit — is
* dissolved into basic blocks that no longer dominate each other. What remains
* is a single `while` around a `switch` on a state variable, plus assignments
* to that variable at the end of each block. The original edges live only in
* the DATA the dispatcher reads, not in the CFG.
*
* Why this breaks decompilers: interval/structural analysis sees one loop with
* N successors and no natural nesting, so it emits `while (1) { switch (state)
* { ... } }` verbatim — syntactically valid, semantically faithful, and
* completely useless to an analyst. Worse, a structurer that tries to be clever
* often *invents* nesting that isn't there, producing confident nonsense: a
* `for` loop whose body is only reachable on one of the three state edges.
* The differential catches exactly that class of over-eager restructuring,
* because a wrong edge changes the answer even though the text looks plausible.
*
* Everything here is fully defined: all arithmetic that can overflow runs
* through uint32_t, every buffer index is bounded by a validated count, and
* the dispatcher carries a step budget so the loop terminates for any input.
*/
#define FLAT145_S_ENTRY 0
#define FLAT145_S_TEST 1
#define FLAT145_S_BODY 2
#define FLAT145_S_ARM_A 3
#define FLAT145_S_ARM_B 4
#define FLAT145_S_NEXT 5
#define FLAT145_S_DONE 6
#define FLAT145_MAX_ELEMS 16
#define FLAT145_MAX_STEPS 256
/* A flattened `for (i = 0; i < count; ++i)` whose body is a flattened
* `if (odd) ... else ...`. Six states replace two structured constructs. */
__attribute__((noinline)) int32_t
flattened_accumulate(int32_t *values, int32_t count, int32_t seed) {
int32_t state = FLAT145_S_ENTRY;
int32_t index = 0;
int32_t steps;
uint32_t acc = 0u;
if (values == 0 || count < 0 || count > FLAT145_MAX_ELEMS) {
return -1;
}
for (steps = 0; steps < FLAT145_MAX_STEPS && state != FLAT145_S_DONE; ++steps) {
switch (state) {
case FLAT145_S_ENTRY:
acc = (uint32_t)seed;
index = 0;
state = FLAT145_S_TEST;
break;
case FLAT145_S_TEST:
state = (index < count) ? FLAT145_S_BODY : FLAT145_S_DONE;
break;
case FLAT145_S_BODY:
state = (values[index] & 1) ? FLAT145_S_ARM_A : FLAT145_S_ARM_B;
break;
case FLAT145_S_ARM_A:
acc = acc * 3u + (uint32_t)values[index];
state = FLAT145_S_NEXT;
break;
case FLAT145_S_ARM_B:
acc ^= (uint32_t)values[index] << 1;
state = FLAT145_S_NEXT;
break;
case FLAT145_S_NEXT:
index += 1;
state = FLAT145_S_TEST;
break;
default:
state = FLAT145_S_DONE;
break;
}
}
return (int32_t)(acc ^ (uint32_t)index);
}
/* A flattened loop with an early exit: the `found` edge jumps straight to the
* terminal state, so the dispatcher has two distinct predecessors of DONE. A
* structurer that folds both into one tail loses the break. */
__attribute__((noinline)) int32_t
flattened_search(int32_t *haystack, int32_t count, int32_t needle) {
int32_t state = FLAT145_S_ENTRY;
int32_t index = 0;
int32_t found = -1;
int32_t steps;
if (haystack == 0 || count < 0 || count > FLAT145_MAX_ELEMS) {
return -2;
}
for (steps = 0; steps < FLAT145_MAX_STEPS && state != FLAT145_S_DONE; ++steps) {
switch (state) {
case FLAT145_S_ENTRY:
index = 0;
found = -1;
state = FLAT145_S_TEST;
break;
case FLAT145_S_TEST:
state = (index < count) ? FLAT145_S_BODY : FLAT145_S_DONE;
break;
case FLAT145_S_BODY:
state = (haystack[index] == needle) ? FLAT145_S_ARM_A : FLAT145_S_NEXT;
break;
case FLAT145_S_ARM_A:
found = index;
state = FLAT145_S_DONE;
break;
case FLAT145_S_NEXT:
index += 1;
state = FLAT145_S_TEST;
break;
default:
state = FLAT145_S_DONE;
break;
}
}
return found;
}
/* Euclid's algorithm flattened. The natural loop is a three-state cycle; the
* guard that keeps `%` defined lives in a different state from the `%` itself,
* so a decompiler that reorders the states introduces a division by zero that
* the original never performs. */
__attribute__((noinline)) uint32_t
flattened_gcd(uint32_t left, uint32_t right) {
uint32_t a = left;
uint32_t b = right;
uint32_t rem = 0u;
int32_t state = FLAT145_S_TEST;
int32_t steps;
for (steps = 0; steps < FLAT145_MAX_STEPS && state != FLAT145_S_DONE; ++steps) {
switch (state) {
case FLAT145_S_TEST:
state = (b == 0u) ? FLAT145_S_DONE : FLAT145_S_BODY;
break;
case FLAT145_S_BODY:
rem = a % b;
state = FLAT145_S_NEXT;
break;
case FLAT145_S_NEXT:
a = b;
b = rem;
state = FLAT145_S_TEST;
break;
default:
state = FLAT145_S_DONE;
break;
}
}
return a;
}
/* A flattened if/else-if/else ladder with no loop at all in the source: the
* dispatcher is pure control-flow noise. The case labels are deliberately not
* in execution order, which is what a real obfuscator's randomised state
* numbering produces. */
__attribute__((noinline)) int32_t
flattened_classify(int32_t x, int32_t y) {
int32_t state = FLAT145_S_ENTRY;
int32_t result = 0;
int32_t steps;
for (steps = 0; steps < 32 && state != FLAT145_S_DONE; ++steps) {
switch (state) {
case FLAT145_S_ENTRY:
state = (x < y) ? FLAT145_S_ARM_A : FLAT145_S_TEST;
break;
case FLAT145_S_NEXT:
result = (y < 0) ? 2 : 1;
state = FLAT145_S_DONE;
break;
case FLAT145_S_ARM_A:
result = (x < 0) ? -2 : -1;
state = FLAT145_S_DONE;
break;
case FLAT145_S_TEST:
state = (x == y) ? FLAT145_S_ARM_B : FLAT145_S_NEXT;
break;
case FLAT145_S_ARM_B:
result = 0;
state = FLAT145_S_DONE;
break;
default:
state = FLAT145_S_DONE;
break;
}
}
return result * 10 + steps;
} 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/4flattened_accumulate fail 46 lines
// glaurung: flattened_accumulate @ 0x1100
int32_t flattened_accumulate(int32_t * arg0, int32_t arg1, int32_t arg2) {
int state;
int index;
unsigned int acc;
int steps;
signed char local_29;
long local_38;
int local_4;
state = 0;
index = 0;
acc = 0;
if ((arg0 != 0)) {
if ((0 <= (long)(arg1))) {
if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
goto L_114e;
}
}
}
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_114e: ;
steps = 0;
L_1155: ;
local_29 = 0;
if (((long)(steps) < 256)) {
local_29 = ((unsigned long)((unsigned int)(state)) != 6);
}
if (((unsigned long)((unsigned char)((local_29 & 1))) == 0)) {
goto L_126f;
}
local_38 = (unsigned int)(state);
if (((unsigned long)((unsigned long)((unsigned int)(state))) <= (unsigned long)(5))) {
/* unrecovered indirect jump through ((long)((int)(*(int *)((0x2000 + (local_38 * 4))))) + 0x2000) */
}
state = 6;
goto L_1261;
L_1261: ;
steps = ((unsigned int)(steps) + 1);
goto L_1155;
L_126f: ;
local_4 = (acc ^ index);
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} flattened_classify fail 29 lines
// glaurung: flattened_classify @ 0x14d0
int32_t flattened_classify(int32_t arg0, int32_t arg1) {
int state;
int result;
int steps;
signed char local_15;
long local_20;
state = 0;
result = 0;
steps = 0;
L_14ef: ;
local_15 = 0;
if (((long)(steps) < 32)) {
local_15 = ((unsigned long)((unsigned int)(state)) != 6);
}
if (((unsigned long)((unsigned char)((local_15 & 1))) == 0)) {
// x86-64 epilogue: restore rbp
return (unsigned int)(((result * 10) + steps));
}
local_20 = (unsigned int)(state);
if (((unsigned long)((unsigned long)((unsigned int)(state))) <= (unsigned long)(5))) {
/* unrecovered indirect jump through ((long)((int)(*(int *)((0x2030 + (local_20 * 4))))) + 0x2030) */
}
state = 6;
goto L_15da;
L_15da: ;
steps = ((unsigned int)(steps) + 1);
goto L_14ef;
} flattened_gcd pass 58 lines
// glaurung: flattened_gcd @ 0x13d0
uint32_t flattened_gcd(uint32_t arg0, uint32_t arg1) {
unsigned int a;
unsigned int b;
unsigned int rem;
int state;
int steps;
signed char local_1d;
int local_24;
a = arg0;
b = arg1;
rem = 0;
state = 1;
steps = 0;
L_13fb: ;
local_1d = 0;
if (((long)(steps) < 256)) {
local_1d = ((unsigned long)((unsigned int)(state)) != 6);
}
if (((unsigned long)((unsigned char)((local_1d & 1))) == 0)) {
// x86-64 epilogue: restore rbp
return a;
}
local_24 = state;
if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(state)) - 1))) == 0)) {
goto L_145d;
}
goto L_143b;
L_143b: ;
if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(local_24)) - 2))) == 0)) {
goto L_1478;
}
goto L_144c;
L_144c: ;
if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(local_24)) - 5))) == 0)) {
goto L_148f;
}
goto L_14a7;
L_145d: ;
state = ((b == 0) ? 6 : 2);
goto L_14ae;
L_1478: ;
rem = ((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(a)) % (unsigned int)(b))));
state = 5;
goto L_14ae;
L_148f: ;
a = b;
b = rem;
state = 1;
goto L_14ae;
L_14a7: ;
state = 6;
L_14ae: ;
goto L_14b3;
L_14b3: ;
steps = ((unsigned int)(steps) + 1);
goto L_13fb;
} flattened_search pass 46 lines
// glaurung: flattened_search @ 0x1280
int32_t flattened_search(int32_t * arg0, int32_t arg1, int32_t arg2) {
int state;
int index;
int found;
int steps;
signed char local_29;
long local_38;
int local_4;
state = 0;
index = 0;
found = -1;
if ((arg0 != 0)) {
if ((0 <= (long)(arg1))) {
if ((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16))) {
goto L_12ce;
}
}
}
local_4 = -2;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
L_12ce: ;
steps = 0;
L_12d5: ;
local_29 = 0;
if (((long)(steps) < 256)) {
local_29 = ((unsigned long)((unsigned int)(state)) != 6);
}
if (((unsigned long)((unsigned char)((local_29 & 1))) == 0)) {
goto L_13c3;
}
local_38 = (unsigned int)(state);
if (((unsigned long)((unsigned long)((unsigned int)(state))) <= (unsigned long)(5))) {
/* unrecovered indirect jump through ((long)((int)(*(int *)((0x2018 + (local_38 * 4))))) + 0x2018) */
}
state = 6;
goto L_13b5;
L_13b5: ;
steps = ((unsigned int)(steps) + 1);
goto L_12d5;
L_13c3: ;
local_4 = found;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
4/4flattened_accumulate pass 103 lines
// glaurung: flattened_accumulate @ 0x1100
int32_t flattened_accumulate(int32_t * arg0, int32_t arg1, int32_t arg2) {
unsigned int acc;
int index;
int state;
int steps;
long local_10;
long ret;
long var0;
long var1;
long var13;
long var15;
long var20;
long var21;
long var26;
long var37;
long var47;
long var8;
local_10 = var0;
var1 = 0xffffffff;
ret = 0xffffffff;
if ((arg0 == 0)) {
// x86-64 epilogue: tear down frame
return ret;
}
ret = var1;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
// x86-64 epilogue: tear down frame
return ret;
}
acc = 0;
var8 = 0;
index = 0;
var13 = 0;
L_1130: ;
while (1) {
if (((unsigned long)(5) < (unsigned long)((unsigned long)((unsigned int)(var13))))) {
var20 = (unsigned long)(acc);
var47 = (unsigned long)((unsigned int)(index));
// x86-64 epilogue: tear down frame
return (unsigned int)((acc ^ (unsigned long)((unsigned int)(index))));
}
var15 = 1;
var20 = (unsigned long)((unsigned int)(arg2));
var21 = (unsigned long)((unsigned int)(var13));
switch ((unsigned long)((unsigned int)(var13))) {
case 0:
goto L_1197;
case 1:
goto L_1149;
case 2:
goto L_115a;
case 3:
goto L_116c;
case 4:
goto L_1178;
case 5:
goto L_118d;
}
L_1149: ;
var15 = (unsigned long)((unsigned int)((((arg1 <= index) * 4) + 2)));
var26 = (unsigned long)((unsigned int)(index));
goto L_1191;
L_115a: ;
var15 = (unsigned long)((unsigned int)((4 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) & 1))))));
var26 = (unsigned long)((unsigned int)(index));
goto L_1191;
L_116c: ;
var20 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((acc + (acc * 2)))) + arg0[(long)(index)])));
goto L_1183;
L_1178: ;
var37 = (unsigned long)((unsigned int)(arg0[(long)(index)]));
var20 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var37 + var37))) ^ acc)));
L_1183: ;
var15 = 5;
var21 = (unsigned long)((unsigned int)(index));
goto L_1197;
L_118d: ;
var26 = (unsigned long)((unsigned int)((index + 1)));
L_1191: ;
var20 = (unsigned long)(acc);
var21 = (unsigned long)((unsigned int)(var26));
L_1197: ;
var47 = var21;
if (((unsigned long)(254) < (unsigned long)((unsigned long)((unsigned int)(var8))))) {
// x86-64 epilogue: tear down frame
return (unsigned int)((var20 ^ var47));
}
var8 = (unsigned long)((unsigned int)((var8 + 1)));
acc = (unsigned long)((unsigned int)(var20));
index = (unsigned long)((unsigned int)(var21));
var13 = var15;
if (((unsigned long)((unsigned int)(var15)) != 6)) {
goto L_1130;
}
var47 = var21;
// x86-64 epilogue: tear down frame
return (unsigned int)((var20 ^ var21));
}
var47 = var21;
// x86-64 epilogue: tear down frame
return (unsigned int)((var20 ^ var21));
} flattened_classify pass 21 lines
// glaurung: flattened_classify @ 0x12f0
int32_t flattened_classify(int32_t arg0, int32_t arg1) {
int state;
int steps;
long var1;
long var21;
long var22;
long var3;
long var7;
var1 = 0;
var3 = ((unsigned int)(arg0) == (unsigned int)(arg1));
var7 = (0 <= (long)(arg0));
if ((arg1 <= arg0)) {
var21 = (((unsigned long)((unsigned int)((((var1 & -256) | (var3 & 255)) ^ 5))) == 5) ? (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) >> 31))) + 1))) : 0);
var22 = 2;
} else {
var21 = (unsigned long)((unsigned int)(((var7 & 255) | -2)));
var22 = 1;
}
return (unsigned int)(((unsigned long)((unsigned int)((var22 + ((unsigned long)((unsigned int)((var21 + (var21 * 4)))) * 2)))) + 1));
} flattened_gcd pass 62 lines
// glaurung: flattened_gcd @ 0x1270
uint32_t flattened_gcd(uint32_t arg0, uint32_t arg1) {
int state;
unsigned int a;
unsigned int b;
unsigned int rem;
int steps;
long var15;
long var16;
long var2;
long var7;
long var9;
var2 = 0;
state = 1;
a = arg0;
var7 = 0;
b = arg1;
L_1280: ;
if (((unsigned long)((unsigned int)(state)) != 5)) {
if (((unsigned long)((unsigned int)(state)) == 2)) {
goto L_12d0;
}
var9 = (unsigned long)(a);
if (((unsigned long)((unsigned int)(state)) != 1)) {
return (unsigned int)(var9);
}
state = (unsigned long)((unsigned int)((((b == 0) * 4) + 2)));
var15 = var7;
var16 = (unsigned long)(b);
if (((unsigned long)((unsigned long)((unsigned int)(var2))) <= (unsigned long)(254))) {
goto L_12e3;
}
var9 = (unsigned long)(a);
return a;
}
a = b;
var16 = (unsigned long)((unsigned int)(var7));
state = 1;
var15 = var7;
if (((unsigned long)((unsigned long)((unsigned int)(var2))) <= (unsigned long)(254))) {
goto L_12e3;
}
var9 = (unsigned long)(a);
return a;
L_12d0: ;
state = 5;
var15 = ((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(a)) % (unsigned int)(b))));
var16 = (unsigned long)(b);
var9 = (unsigned long)(a);
if (((unsigned long)(254) < (unsigned long)((unsigned long)((unsigned int)(var2))))) {
return (unsigned int)(var9);
}
L_12e3: ;
var2 = (unsigned long)((unsigned int)((var2 + 1)));
var7 = var15;
b = var16;
var9 = (unsigned long)(a);
if (((unsigned long)((unsigned int)(state)) != 6)) {
goto L_1280;
}
return (unsigned int)(var9);
} flattened_search pass 41 lines
// glaurung: flattened_search @ 0x11c0
int32_t flattened_search(int32_t * arg0, int32_t arg1, int32_t arg2) {
int index;
int state;
int steps;
long var13;
long var19;
long var2;
long var3;
long var8;
index = 0xfffffffe;
if ((arg0 == 0)) {
return index;
}
index = 0xfffffffe;
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return index;
}
var2 = 0;
var3 = 0x2018;
state = 0;
var8 = 0;
L_11f0: ;
if (((unsigned long)(5) < (unsigned long)((unsigned long)((unsigned int)(state))))) {
return 0xffffffff;
}
index = (unsigned long)((unsigned int)(var8));
/* unrecovered indirect jump through ((long)((int)(*(int *)((var3 + ((unsigned long)((unsigned int)(state)) * 4))))) + var3) */
index = 0xffffffff;
if (((unsigned long)(254) < (unsigned long)((unsigned long)((unsigned int)(var2))))) {
return index;
}
var2 = (unsigned long)((unsigned int)((var2 + 1)));
state = (unsigned long)((unsigned int)(var13));
var8 = (unsigned long)((unsigned int)(var19));
index = 0xffffffff;
if (((unsigned long)((unsigned int)(var13)) != 6)) {
goto L_11f0;
}
return index;
} gcc -O0
4/4flattened_accumulate pass 62 lines
// glaurung: flattened_accumulate @ 0x10f9
int32_t flattened_accumulate(int32_t * arg0, int32_t arg1, int32_t arg2) {
int state;
int index;
unsigned int acc;
int steps;
long var38;
// x86-64 prologue: save rbp
state = 0;
index = 0;
acc = 0;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
steps = 0;
while (((((unsigned long)((unsigned int)(steps)) == 255) | ((long)(steps) < 255)) != 0)) {
if (((unsigned long)((unsigned int)(state)) == 6)) {
break;
}
switch ((unsigned long)((unsigned int)(state))) {
case 0:
acc = arg2;
index = 0;
state = 1;
break;
case 1:
state = ((arg1 <= index) ? 6 : 2);
break;
case 2:
state = (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0[(long)(index)])) & 1))) == 0) ? 4 : 3);
break;
case 3:
acc = ((unsigned int)(arg0[(long)(index)]) + (unsigned int)((acc + (unsigned long)((unsigned int)((acc + acc))))));
state = 5;
break;
case 4:
var38 = (unsigned long)((unsigned int)(arg0[(long)(index)]));
acc = (acc ^ (unsigned int)((var38 + var38)));
state = 5;
break;
case 5:
index = (index + 1);
state = 1;
break;
default:
state = 6;
break;
}
steps = (steps + 1);
}
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(index)) ^ acc));
} flattened_classify pass 43 lines
// glaurung: flattened_classify @ 0x1427
int32_t flattened_classify(int32_t arg0, int32_t arg1) {
int state;
int result;
int steps;
int var17;
// x86-64 prologue: save rbp
state = 0;
result = 0;
steps = 0;
while (((((unsigned long)((unsigned int)(steps)) == 31) | ((long)(steps) < 31)) != 0)) {
if (((unsigned long)((unsigned int)(state)) == 6)) {
break;
}
switch ((unsigned long)((unsigned int)(state))) {
case 0:
state = ((arg1 <= arg0) ? 1 : 3);
break;
case 1:
state = (((unsigned int)(arg0) != (unsigned int)(arg1)) ? 5 : 4);
break;
case 3:
result = ((0 <= (long)(arg0)) ? 0xffffffff : 0xfffffffe);
state = 6;
break;
case 4:
result = 0;
state = 6;
break;
case 5:
result = ((0 <= (long)(arg1)) ? 1 : 2);
state = 6;
break;
default:
state = 6;
break;
}
steps = (steps + 1);
}
var17 = ((unsigned int)(((unsigned long)((unsigned int)(result)) << 2)) + (unsigned int)(result));
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(steps)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) + (unsigned long)((unsigned int)(var17)))))));
} flattened_gcd pass 43 lines
// glaurung: flattened_gcd @ 0x1379
uint32_t flattened_gcd(uint32_t arg0, uint32_t arg1) {
unsigned int a;
unsigned int b;
unsigned int rem;
int state;
int steps;
// x86-64 prologue: save rbp
a = arg0;
b = arg1;
rem = 0;
state = 1;
steps = 0;
while (((((unsigned long)((unsigned int)(steps)) == 255) | ((long)(steps) < 255)) != 0)) {
if (((unsigned long)((unsigned int)(state)) == 6)) {
break;
}
if (((unsigned long)((unsigned int)(state)) == 5)) {
a = b;
b = rem;
state = 1;
} else {
if (((((unsigned long)((unsigned int)(state)) == 5) | ((long)(state) < 5)) == 0)) {
L_1407: ;
state = 6;
} else {
if (((unsigned long)((unsigned int)(state)) == 1)) {
state = ((b != 0) ? 2 : 6);
} else {
if (((unsigned long)((unsigned int)(state)) == 2)) {
rem = ((unsigned int)(((((unsigned long long)(unsigned int)(0) << 32) | (unsigned int)(a)) % (unsigned int)(b))));
state = 5;
} else {
goto L_1407;
}
}
}
}
steps = (steps + 1);
}
// x86-64 epilogue: restore rbp
return a;
} flattened_search pass 56 lines
// glaurung: flattened_search @ 0x125f
int32_t flattened_search(int32_t * arg0, int32_t arg1, int32_t arg2) {
int state;
int index;
int found;
int steps;
// x86-64 prologue: save rbp
state = 0;
index = 0;
found = -1;
if ((arg0 == 0)) {
// x86-64 epilogue: restore rbp
return 0xfffffffe;
}
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0xfffffffe;
}
if (((((unsigned long)((unsigned int)(arg1)) == 16) | ((long)(arg1) < 16)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xfffffffe;
}
steps = 0;
while (((((unsigned long)((unsigned int)(steps)) == 255) | ((long)(steps) < 255)) != 0)) {
if (((unsigned long)((unsigned int)(state)) == 6)) {
break;
}
switch ((unsigned long)((unsigned int)(state))) {
case 0:
index = 0;
found = -1;
state = 1;
break;
case 1:
state = ((arg1 <= index) ? 6 : 2);
break;
case 2:
state = (((unsigned int)(arg2) != (unsigned int)(arg0[(long)(index)])) ? 5 : 3);
break;
case 3:
found = index;
state = 6;
break;
case 5:
index = (index + 1);
state = 1;
break;
default:
state = 6;
break;
}
steps = (steps + 1);
}
// x86-64 epilogue: restore rbp
return (unsigned int)(found);
} gcc -O2
4/4flattened_accumulate pass 27 lines
// glaurung: flattened_accumulate @ 0x1100
int32_t flattened_accumulate(int32_t * arg0, int32_t arg1, int32_t arg2) {
unsigned int acc;
int index;
int state;
int steps;
long var3;
long var4;
long var5;
long var6;
if ((arg0 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
var3 = (unsigned long)((unsigned int)(arg2));
var4 = 0;
var5 = (long)arg0;
while (((((unsigned int)(arg1) == (unsigned int)(var4)) | ((long)(arg1) < (long)((int)(var4)))) == 0)) {
var6 = (unsigned long)((unsigned int)(*(int *)((var5))));
var3 = (((unsigned long)((unsigned char)((var6 & 1))) == 0) ? (unsigned long)((unsigned int)((var3 ^ (unsigned long)((unsigned int)((var6 + var6)))))) : (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var3 + (var3 * 2)))) + var6))));
var5 = (var5 + 4);
var4 = (unsigned long)((unsigned int)((var4 + 1)));
}
return (unsigned int)((var3 ^ var4));
} flattened_classify pass 16 lines
// glaurung: flattened_classify @ 0x11c0
int32_t flattened_classify(int32_t arg0, int32_t arg1) {
int state;
int steps;
long ret;
long var0;
var0 = (unsigned long)((unsigned int)(arg0));
if (((((unsigned int)(arg1) == (unsigned int)(arg0)) | (arg1 < arg0)) == 0)) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((int)(var0) >> 31))) & -10))) - 8));
}
ret = 3;
if (((unsigned int)(arg1) != (unsigned int)(arg0))) {
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((int)(arg1) >> 31))) & 10))) + 13)));
}
return ret;
} flattened_gcd pass 28 lines
// glaurung: flattened_gcd @ 0x1190
uint32_t flattened_gcd(uint32_t arg0, uint32_t arg1) {
unsigned int a;
unsigned int b;
unsigned int rem;
int state;
int steps;
long ret;
long var0;
long var1;
long var4;
long var9;
ret = (unsigned long)(arg0);
var0 = 86;
var1 = (unsigned long)(arg0);
var4 = (unsigned long)(arg1);
while (((unsigned long)((unsigned int)(var4)) != 0)) {
if (((unsigned long)((unsigned int)(var0)) == 1)) {
break;
}
var0 = (unsigned long)((unsigned int)((var0 - 1)));
ret = (unsigned long)((unsigned int)(var4));
var9 = (unsigned long)((unsigned int)(((unsigned int)(((((unsigned long long)(unsigned int)((unsigned long)((unsigned int)(0))) << 32) | (unsigned int)(var1)) % (unsigned int)(var4))))));
var1 = (unsigned long)((unsigned int)(var4));
var4 = var9;
}
return ret;
} flattened_search pass 25 lines
// glaurung: flattened_search @ 0x1150
int32_t flattened_search(int32_t * arg0, int32_t arg1, int32_t arg2) {
int index;
int found;
int state;
long var4;
if ((arg0 == 0)) {
return 0xfffffffe;
}
if (((unsigned long)(16) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xfffffffe;
}
index = 0;
while (1) {
var4 = (unsigned long)((unsigned int)(index));
if (((((unsigned int)(arg1) == (unsigned int)(index)) | (arg1 < index)) != 0)) {
break;
}
index = (index + 1);
if (((unsigned int)(*(int *)(((long)arg0 + index * 4 - 0x4))) == (unsigned int)(arg2))) {
return (unsigned int)(var4);
}
}
return 0xffffffff;
}