Fixture 07

packet parser

C · 2 functions · 4 lanes · 8 of 8 function-lanes behave identically

All 4 lanes recompile and return the same results as the original.

Structure-preservation fixture modeling a realistic bounded binary-message parser. It exercises packed and naturally-aligned structs, a nested struct, a union, and bitfields, plus portable (byte-shift) endian conversion and a length-checked variable-length payload read. The target bug class is a decompiler that loses the relationship between the input length, the header's declared length field, pointer/offset advancement, and the final bounded buffer access — the exact structure a security analyst relies on to reason about out-of-bounds reads.

Targets realistic security-analysis structure preservation. Each validation failure returns a DISTINCT negative code; a successful parse returns an int summarizing the parse. Differential-testable via a const uint8_t* buffer and int len; no libc, no bswap intrinsics.

tests/decompiler_fixtures/src/07_packet_parser.c source
/* 07_packet_parser.c
 *
 * Structure-preservation fixture modeling a realistic bounded binary-message
 * parser. It exercises packed and naturally-aligned structs, a nested struct,
 * a union, and bitfields, plus portable (byte-shift) endian conversion and a
 * length-checked variable-length payload read. The target bug class is a
 * decompiler that loses the relationship between the input length, the header's
 * declared length field, pointer/offset advancement, and the final bounded
 * buffer access — the exact structure a security analyst relies on to reason
 * about out-of-bounds reads.
 *
 * Targets realistic security-analysis structure preservation. Each validation
 * failure returns a DISTINCT negative code; a successful parse returns an int
 * summarizing the parse. Differential-testable via a const uint8_t* buffer and
 * int len; no libc, no bswap intrinsics.
 */
#include <stdint.h>

/* Wire header, 8 bytes, byte-for-byte as it appears on the wire:
 *   off 0: magic   (u16, big-endian)
 *   off 2: version:4, type:4        (one byte of bitfields)
 *   off 3: flags   (u8)
 *   off 4: length  (u16, big-endian)   -- declared payload length
 *   off 6: reserved(u16)
 * We do NOT rely on struct layout for parsing the wire bytes (that is done with
 * explicit shifts below); the packed struct exists so the decompiler must
 * preserve a packed aggregate and its bitfield byte.
 */
#pragma pack(push, 1)
struct wire_header {
    uint16_t magic;        /* stored big-endian on the wire */
    uint8_t  ver_type;     /* version:4 | type:4 */
    uint8_t  flags;
    uint16_t length;       /* big-endian */
    uint16_t reserved;
};
#pragma pack(pop)

/* Bitfield view of the ver_type byte. */
struct ver_type_bits {
    uint8_t version : 4;
    uint8_t type    : 4;
};

/* Naturally-aligned decoded header (host layout) with a nested struct. */
struct endpoint {
    uint16_t port;
    uint8_t  kind;
};

struct decoded_header {
    uint16_t magic;
    uint8_t  version;
    uint8_t  type;
    uint8_t  flags;
    uint16_t length;
    struct endpoint src;   /* nested struct */
};

/* A union: the same 4 payload bytes viewed either as one u32 or as an id/code
 * pair. Exercises union structure preservation. */
union payload_head {
    uint32_t raw;
    struct {
        uint16_t id;
        uint16_t code;
    } fields;
    uint8_t bytes[4];
};

#define WIRE_MAGIC   0xC0DEu
#define HEADER_SIZE  8

/* Portable big-endian 16-bit read (no bswap intrinsic). */
static uint16_t read_be16(const uint8_t *p) {
    return (uint16_t)(((uint16_t)p[0] << 8) | (uint16_t)p[1]);
}

/* Portable big-endian 32-bit read. */
static uint32_t read_be32(const uint8_t *p) {
    return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) |
           ((uint32_t)p[2] << 8)  | (uint32_t)p[3];
}

/* Validate the header alone. Distinct negative codes per failure mode so a
 * mis-structured bounds check surfaces immediately. Returns 0 on success. */
int validate_header(const uint8_t *buf, int len) {
    if (buf == 0)
        return -1;
    if (len < HEADER_SIZE)
        return -2;                       /* not enough bytes for a header */

    uint16_t magic = read_be16(buf + 0);
    if (magic != WIRE_MAGIC)
        return -3;                       /* bad magic */

    uint8_t ver_type = buf[2];
    uint8_t version = (uint8_t)(ver_type >> 4);       /* high nibble */
    uint8_t type    = (uint8_t)(ver_type & 0x0F);     /* low nibble */
    if (version != 1)
        return -4;                       /* unsupported version */
    if (type == 0 || type > 7)
        return -5;                       /* out-of-range type */

    uint16_t length = read_be16(buf + 4);
    /* The declared payload length must fit within the remaining buffer. This
     * is the critical relationship the decompiler must preserve. */
    if ((int)length > len - HEADER_SIZE)
        return -6;                       /* declared length overruns buffer */

    return 0;
}

/* Decode the wire header into the host-layout struct. Returns 0 on success or
 * the validate_header error code. `out` is written only on success. */
static int decode_header(const uint8_t *buf, int len, struct decoded_header *out) {
    int rc = validate_header(buf, len);
    if (rc != 0)
        return rc;

    struct ver_type_bits vt;
    vt.version = (uint8_t)(buf[2] >> 4);
    vt.type    = (uint8_t)(buf[2] & 0x0F);

    out->magic   = read_be16(buf + 0);
    out->version = vt.version;
    out->type    = vt.type;
    out->flags   = buf[3];
    out->length  = read_be16(buf + 4);
    /* reserved (buf+6) folded into a nested endpoint for structure coverage */
    out->src.port = read_be16(buf + 6);
    out->src.kind = vt.type;
    return 0;
}

/* Full parse: validate, decode, advance past the header, then read the
 * variable-length payload with a bounds check BEFORE touching the bytes.
 * Returns a positive summary on success, or a distinct negative error.
 *
 * The summary deliberately combines the header fields and a checksum over
 * exactly `length` payload bytes, so if pointer advancement or the length
 * bound is mis-decompiled the summary (or an OOB access) diverges. */
int parse_packet(const uint8_t *buf, int len) {
    struct decoded_header hdr;
    int rc = decode_header(buf, len, &hdr);
    if (rc != 0)
        return rc;

    /* Advance the cursor past the fixed header. */
    const uint8_t *cursor = buf + HEADER_SIZE;
    int remaining = len - HEADER_SIZE;

    uint16_t declared = hdr.length;

    /* Redundant, explicit bound before the payload access — must be preserved
     * relative to `declared` and `remaining`. */
    if ((int)declared > remaining)
        return -7;                       /* should have been caught, defensive */

    /* Optional 4-byte payload head viewed through a union when present. */
    uint32_t head_word = 0;
    if (declared >= 4) {
        union payload_head ph;
        ph.raw = read_be32(cursor);
        head_word = (uint32_t)ph.fields.id + (uint32_t)ph.fields.code +
                    (uint32_t)ph.bytes[0];
    }

    /* Bounded checksum over exactly `declared` payload bytes. The loop index
     * must never exceed `declared`, and cursor[i] must stay within buf+len. */
    uint32_t sum = 0;
    for (int i = 0; i < (int)declared; i++) {
        sum += cursor[i];
        sum = (sum << 1) | (sum >> 31);  /* rotate to spread the bits */
    }

    /* Trailing flag: bit 0 of flags requests that the last payload byte equal
     * the low byte of the checksum. Distinct negative on mismatch. */
    if ((hdr.flags & 0x01) && declared > 0) {
        uint8_t last = cursor[declared - 1];
        if (last != (uint8_t)(sum & 0xFF))
            return -8;
    }

    /* Positive summary folding header + payload, kept in a modest range. */
    int summary = 100
                + (int)hdr.type * 7
                + (int)hdr.version
                + (int)(declared & 0xFF)
                + (int)(sum & 0x7F)
                + (int)(head_word & 0x3F);
    return summary;
}

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/2
parse_packet pass 107 lines
// glaurung: parse_packet @ 0x1240
__attribute__((no_stack_protector)) int parse_packet(const uint8_t * arg0, int arg1) {
    extern int decode_header(char *, int, char *);
    extern unsigned int read_be32(char *);
    int rc;
    char * cursor;
    int remaining;
    unsigned short declared;
    unsigned int head_word;
    unsigned int sum;
    int i;
    int summary;
    unsigned char last;
    unsigned char local_20[12];
    int local_4;
    unsigned char local_40[4];
    int var0;
    unsigned int var11;
    int var42;
    long var43;
    int var44;
    int var46;
    int var47;
    int var50;
    int var52;
    int var55;
    int var57;
    int var60;
    int var62;
    // x86-64 prologue: save rbp, frame 80 bytes
    var0 = decode_header((char *)(arg0), (unsigned long)((unsigned int)(arg1)), (char *)(&local_20[0]));
    rc = var0;
    if (((unsigned long)((unsigned int)(rc)) == 0)) {
        cursor = (char *)((arg0 + 8));
        remaining = ((unsigned int)(arg1) - 8);
        declared = *(short *)((&local_20[0] + 6));
        if ((((unsigned long)((unsigned long)(declared)) == (unsigned long)((unsigned int)(remaining))) | ((long)(declared) < (long)(remaining)))) {
            head_word = 0;
            if ((4 <= (long)(declared))) {
                var11 = read_be32(cursor);
                *(int *)(&local_40[0]) = var11;
                head_word = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)(&local_40[0]))) + (unsigned int)((unsigned short)(*(short *)((&local_40[0] + 2)))))) + (unsigned int)((unsigned char)(*(char *)(&local_40[0]))));
            }
            sum = 0;
            for (i = 0; ((long)(i) < (long)(declared)); i++) {
                sum = ((unsigned int)((unsigned char)(cursor[i])) + sum);
                sum = ((unsigned int)((sum << 1)) | (unsigned int)(((unsigned int)(sum) >> 31)));
            }
            if (((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)((&local_20[0] + 4)))) & 1))) == 0)) {
                var42 = (unsigned int)((unsigned char)(*(char *)((&local_20[0] + 3))));
                var43 = ((unsigned long)((unsigned int)(var42)) * 7);
                var44 = (var43 + 100);
                var46 = (unsigned int)((unsigned char)(*(char *)((&local_20[0] + 2))));
                var47 = ((unsigned int)(var44) + var46);
                var50 = ((unsigned int)(declared) & 255);
                var52 = ((unsigned int)(var47) + (unsigned int)(var50));
                var55 = (sum & 127);
                var57 = ((unsigned int)(var52) + (unsigned int)(var55));
                var60 = (head_word & 63);
                var62 = ((unsigned int)(var57) + (unsigned int)(var60));
                summary = var62;
                local_4 = summary;
                // x86-64 epilogue: restore rbp
                return (unsigned int)(local_4);
            }
            if ((((unsigned long)((unsigned long)(declared)) == 0) | ((long)(declared) < 0))) {
                var42 = (unsigned int)((unsigned char)(*(char *)((&local_20[0] + 3))));
                var43 = ((unsigned long)((unsigned int)(var42)) * 7);
                var44 = (var43 + 100);
                var46 = (unsigned int)((unsigned char)(*(char *)((&local_20[0] + 2))));
                var47 = ((unsigned int)(var44) + var46);
                var50 = ((unsigned int)(declared) & 255);
                var52 = ((unsigned int)(var47) + (unsigned int)(var50));
                var55 = (sum & 127);
                var57 = ((unsigned int)(var52) + (unsigned int)(var55));
                var60 = (head_word & 63);
                var62 = ((unsigned int)(var57) + (unsigned int)(var60));
                summary = var62;
                local_4 = summary;
                // x86-64 epilogue: restore rbp
                return (unsigned int)(local_4);
            }
            last = cursor[(long)((int)(((unsigned int)(declared) - 1)))];
            if (((unsigned long)((unsigned long)(last)) == (unsigned long)((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((sum & 255))) & 255)))))) {
                var42 = (unsigned int)((unsigned char)(*(char *)((&local_20[0] + 3))));
                var43 = ((unsigned long)((unsigned int)(var42)) * 7);
                var44 = (var43 + 100);
                var46 = (unsigned int)((unsigned char)(*(char *)((&local_20[0] + 2))));
                var47 = ((unsigned int)(var44) + var46);
                var50 = ((unsigned int)(declared) & 255);
                var52 = ((unsigned int)(var47) + (unsigned int)(var50));
                var55 = (sum & 127);
                var57 = ((unsigned int)(var52) + (unsigned int)(var55));
                var60 = (head_word & 63);
                var62 = ((unsigned int)(var57) + (unsigned int)(var60));
                summary = var62;
                return (unsigned int)(summary);
            } else {
                return (unsigned int)(-8);
            }
        } else {
            return (unsigned int)(-7);
        }
    } else {
        return (unsigned int)(rc);
    }
}
validate_header pass 53 lines
// glaurung: validate_header @ 0x1110
int validate_header(const uint8_t * arg0, int arg1) {
    extern unsigned short read_be16(char *);
    unsigned short magic;
    unsigned char ver_type;
    unsigned char version;
    unsigned char type;
    unsigned short length;
    int local_4;
    unsigned short var0;
    unsigned short var17;
    long var22;
    // x86-64 prologue: save rbp, frame 32 bytes
    if ((arg0 != 0)) {
        if ((8 <= (long)(arg1))) {
            var0 = read_be16((char *)(arg0));
            magic = var0;
            if (((unsigned long)((unsigned long)(magic)) == 0xc0de)) {
                ver_type = *(char *)(((long)arg0 + 0x2));
                version = ((int)(ver_type) >> 4);
                type = (ver_type & 15);
                if (((unsigned long)((unsigned long)(version)) == 1)) {
                    if (((unsigned long)((unsigned long)(type)) == 0)) {
                        local_4 = -5;
                        // x86-64 epilogue: restore rbp
                        return (unsigned int)(local_4);
                    }
                    if (((((unsigned long)((unsigned long)(type)) == 7) | ((long)(type) < 7)) == 0)) {
                        local_4 = -5;
                        // x86-64 epilogue: restore rbp
                        return (unsigned int)(local_4);
                    }
                    var17 = read_be16((char *)((arg0 + 4)));
                    length = var17;
                    var22 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) - 8)));
                    if ((((unsigned long)((unsigned long)(length)) == (unsigned long)((unsigned int)(var22))) | ((long)(length) < (long)((int)(var22))))) {
                        return 0;
                    } else {
                        return (unsigned int)(-6);
                    }
                } else {
                    return (unsigned int)(-4);
                }
            } else {
                return (unsigned int)(-3);
            }
        } else {
            return (unsigned int)(-2);
        }
    } else {
        return (unsigned int)(-1);
    }
}

clang -O2

2/2
parse_packet pass 168 lines
// glaurung: parse_packet @ 0x1170
int parse_packet(const uint8_t * arg0, int arg1) {
    unsigned char ver_type;
    int remaining;
    unsigned short declared;
    int i;
    unsigned int head_word;
    unsigned short length;
    unsigned short magic;
    int rc;
    unsigned int sum;
    int summary;
    unsigned char type;
    long local_8;
    long ret;
    long t40;
    long t407;
    long var0;
    int var16;
    int var20;
    int var23;
    long var28;
    long var33;
    long var37;
    long var38;
    long var42;
    long var47;
    long var49;
    long var52;
    long var58;
    int var60;
    int var64;
    int var68;
    int var72;
    long var74;
    long var76;
    long var78;
    long var80;
    long var81;
    int var83;
    int var85;
    long var89;
    int var95;
    local_8 = var0;
    if ((arg0 != 0)) {
        ret = 0xfffffffe;
        if (((long)(arg1) < 8)) {
            // x86-64 epilogue: tear down frame
            return ret;
        }
        t40 = ((unsigned int)((unsigned short)(*(short *)(((long)arg0)))) & 0xffff);
        ret = 0xfffffffd;
        if (((unsigned long)((unsigned int)((unsigned short)((((t40 << 8) | ((unsigned long)(t40) >> 8)) & 0xffff)))) != 0xc0de)) {
            // x86-64 epilogue: tear down frame
            return ret;
        }
        ver_type = (*(char *)(((long)arg0 + 0x2)) & 255);
        ret = 0xfffffffc;
        if (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((unsigned int)(ver_type))) & 240))) != 16)) {
            // x86-64 epilogue: tear down frame
            return ret;
        }
        ret = 0xfffffffb;
        if (((unsigned long)((unsigned long)((unsigned char)(((((unsigned long)((unsigned int)((unsigned int)(ver_type))) & 15) - 8) & 255)))) < (unsigned long)(249))) {
            // x86-64 epilogue: tear down frame
            return ret;
        }
        var16 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x4))));
        var20 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x5))));
        var23 = (arg1 - 8);
        remaining = (unsigned long)((unsigned int)(var23));
        ret = 0xfffffffa;
        if (((unsigned long)((unsigned long)((unsigned int)(var23))) < (unsigned long)((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var16)) << 8))) | var20)))))) {
            // x86-64 epilogue: tear down frame
            return ret;
        }
        declared = ((var16 << 8) | var20);
        ret = 0xfffffff9;
        if (((unsigned long)((unsigned long)((unsigned int)(remaining))) < (unsigned long)((unsigned long)((unsigned int)((unsigned int)(declared)))))) {
            // x86-64 epilogue: tear down frame
            return ret;
        }
        var28 = (*(char *)(((long)arg0 + 0x3)) & 255);
        if (((unsigned long)((unsigned long)((unsigned short)((declared & 0xffff)))) < (unsigned long)(4))) {
            goto L_1229;
        }
        var33 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x9)))) + ((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xb)))) * 2)))) & 63)));
        goto L_123b;
    }
    // x86-64 epilogue: tear down frame
    return 0xffffffff;
    L_1229: ;
    var33 = 0;
    var37 = 0;
    var38 = 0;
    if (((unsigned long)((unsigned short)((declared & 0xffff))) == 0)) {
        t407 = ((unsigned long)(ver_type) & 255);
        var89 = (((t407 << 4) | ((unsigned long)(t407) >> 4)) & 255);
        var95 = (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((var89 & 255))) >> 4) & 255)));
        // x86-64 epilogue: tear down frame
        return (unsigned int)(((unsigned long)((unsigned int)((var38 & 127))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)((declared & 255))) + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(var89)) & 15))) + (unsigned int)((unsigned char)(((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var95 * 8))) - var95))) & 255) + 100) & 255))))))))) + var37)))));
    }
    L_123b: ;
    var42 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned int)(declared))) & 3)));
    if (((unsigned long)((declared - 1)) < (unsigned long)(3))) {
        var47 = 0;
        var49 = 0;
        goto L_1289;
    }
    var52 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned int)(declared))) & -4)));
    i = 0;
    var58 = 0;
    do {
        var60 = ((unsigned int)((unsigned char)(*(char *)(((long)arg0 + i + 0x8)))) + var58);
        var64 = ((unsigned int)((unsigned char)(*(char *)(((long)arg0 + i + 0x9)))) + (((unsigned long)((unsigned int)(var60)) << 1) | ((unsigned long)((unsigned int)(var60)) >> 31)));
        var68 = ((unsigned int)((unsigned char)(*(char *)(((long)arg0 + i + 0xa)))) + (((unsigned long)((unsigned int)(var64)) << 1) | ((unsigned long)((unsigned int)(var64)) >> 31)));
        var72 = ((unsigned int)((unsigned char)(*(char *)(((long)arg0 + i + 0xb)))) + (((unsigned long)((unsigned int)(var68)) << 1) | ((unsigned long)((unsigned int)(var68)) >> 31)));
        var74 = (((unsigned long)((unsigned int)(var72)) << 1) | ((unsigned long)((unsigned int)(var72)) >> 31));
        i = (i + 4);
        var58 = var74;
        var47 = (unsigned long)((unsigned int)(i));
        var49 = var74;
    } while ((var52 != i));
    L_1289: ;
    var76 = (unsigned long)((unsigned int)(var49));
    if ((var42 != 0)) {
        var78 = (long)(((var47 + (long)arg0) + 8));
        var80 = 0;
        var81 = var49;
        while ((var42 != var80)) {
            var83 = ((unsigned int)((unsigned char)(*(char *)((var78 + var80)))) + var81);
            var85 = (((unsigned long)((unsigned int)(var83)) << 1) | ((unsigned long)((unsigned int)(var83)) >> 31));
            var80 = (var80 + 1);
            var81 = (unsigned long)((unsigned int)(var85));
            var76 = (unsigned long)((unsigned int)(var85));
        }
    }
    var37 = var33;
    var38 = var76;
    if (((unsigned long)((unsigned char)((var28 & 1))) == 0)) {
        t407 = ((unsigned long)(ver_type) & 255);
        var89 = (((t407 << 4) | ((unsigned long)(t407) >> 4)) & 255);
        var95 = (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((var89 & 255))) >> 4) & 255)));
        // x86-64 epilogue: tear down frame
        return (unsigned int)(((unsigned long)((unsigned int)((var38 & 127))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)((declared & 255))) + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(var89)) & 15))) + (unsigned int)((unsigned char)(((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var95 * 8))) - var95))) & 255) + 100) & 255))))))))) + var37)))));
    }
    var37 = var33;
    var38 = var76;
    if (((unsigned long)((unsigned short)((declared & 0xffff))) == 0)) {
        t407 = ((unsigned long)(ver_type) & 255);
        var89 = (((t407 << 4) | ((unsigned long)(t407) >> 4)) & 255);
        var95 = (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((var89 & 255))) >> 4) & 255)));
        // x86-64 epilogue: tear down frame
        return (unsigned int)(((unsigned long)((unsigned int)((var38 & 127))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)((declared & 255))) + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(var89)) & 15))) + (unsigned int)((unsigned char)(((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var95 * 8))) - var95))) & 255) + 100) & 255))))))))) + var37)))));
    }
    ret = 0xfffffff8;
    var37 = var33;
    var38 = var76;
    if (((unsigned char)(*(char *)((((long)arg0 + (unsigned long)((unsigned int)(((unsigned int)(declared) - 1)))) + 8))) != (unsigned char)((var76 & 255)))) {
        // x86-64 epilogue: tear down frame
        return ret;
    }
    t407 = ((unsigned long)(ver_type) & 255);
    var89 = (((t407 << 4) | ((unsigned long)(t407) >> 4)) & 255);
    var95 = (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((var89 & 255))) >> 4) & 255)));
    // x86-64 epilogue: tear down frame
    return (unsigned int)(((unsigned long)((unsigned int)((var38 & 127))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)((declared & 255))) + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(var89)) & 15))) + (unsigned int)((unsigned char)(((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var95 * 8))) - var95))) & 255) + 100) & 255))))))))) + var37)))));
}
validate_header pass 34 lines
// glaurung: validate_header @ 0x1100
int validate_header(const uint8_t * arg0, int arg1) {
    unsigned char ver_type;
    unsigned short length;
    unsigned short magic;
    unsigned char type;
    long ret;
    long t40;
    long var16;
    int var3;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    ret = 0xfffffffe;
    if ((8 <= (long)(arg1))) {
        t40 = ((unsigned int)((unsigned short)(*(short *)(((long)arg0)))) & 0xffff);
        var3 = (unsigned int)((unsigned short)((((t40 << 8) | ((unsigned long)(t40) >> 8)) & 0xffff)));
        ret = 0xfffffffd;
        if (((unsigned long)((unsigned int)(var3)) != 0xc0de)) {
            return ret;
        }
        ver_type = ((var3 & -256) | (*(char *)(((long)arg0 + 0x2)) & 255));
        ret = 0xfffffffc;
        if (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)((unsigned int)(ver_type))) & 240))) != 16)) {
            return ret;
        }
        ret = 0xfffffffb;
        if (((unsigned long)(249) <= (unsigned long)((unsigned long)((unsigned char)((((ver_type & 15) - 8) & 255)))))) {
            var16 = (unsigned long)((unsigned int)(((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x4)))) << 16)));
            ret = (((unsigned long)((unsigned long)((unsigned int)(((((((unsigned int)(var16) & 255) << 24) | ((((unsigned int)(var16) >> 8) & 255) << 16)) | ((((unsigned int)(var16) >> 16) & 255) << 8)) | (((unsigned int)(var16) >> 24) & 255))))) <= (unsigned long)((unsigned long)((unsigned int)((arg1 - 8))))) ? 0 : 0xfffffffa);
        }
    }
    return ret;
}

gcc -O0

2/2
parse_packet pass 70 lines
// glaurung: parse_packet @ 0x1384
int parse_packet(const uint8_t * arg0, int arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    extern int decode_header(char *, int, char *);
    extern unsigned int read_be32(char *);
    int rc;
    char * cursor;
    int remaining;
    unsigned short declared;
    unsigned int head_word;
    unsigned int sum;
    int i;
    int summary;
    unsigned char last;
    unsigned char local_18[12];
    long local_8;
    unsigned char local_c[4];
    long ret;
    unsigned int var15;
    int var39;
    int var5;
    // x86-64 prologue: save rbp, frame 80 bytes
    local_8 = (long)(0x28);
    var5 = decode_header((char *)(arg0), (unsigned long)((unsigned int)(arg1)), (char *)(&local_18[0]));
    rc = var5;
    if (((unsigned long)((unsigned int)(rc)) == 0)) {
        cursor = (char *)((arg0 + 8));
        remaining = ((unsigned int)(arg1) - 8);
        declared = *(short *)((&local_18[0] + 6));
        if (((long)(declared) <= (long)(remaining))) {
            head_word = 0;
            if (((unsigned long)(3) < (unsigned long)(declared))) {
                var15 = read_be32(cursor);
                *(int *)(&local_c[0]) = var15;
                head_word = ((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_c[0]))) & 255))) + (unsigned int)(((unsigned int)((unsigned short)(((unsigned int)((unsigned short)(*(short *)(&local_c[0]))) & 0xffff))) + (unsigned int)((unsigned short)(((unsigned int)((unsigned short)(*(short *)((&local_c[0] + 2)))) & 0xffff))))));
            }
            sum = 0;
            for (i = 0; ((long)(i) < (long)(declared)); i++) {
                sum = (sum + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(cursor[i])) & 255))));
                sum = ((sum << 1) | ((unsigned int)(sum) >> 31));
            }
            if (((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_18[0] + 4)))) & 255))) & 1))) == 0)) {
                L_14a4: ;
                var39 = (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_18[0] + 3)))) & 255)));
                summary = ((unsigned int)((head_word & 63)) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var39)) << 3))) - var39))) + 100))) + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_18[0] + 2)))) & 255)))))) + (unsigned int)((unsigned char)((declared & 255)))))) + (unsigned long)((unsigned int)((sum & 127))))));
                ret = (unsigned long)((unsigned int)(summary));
            } else {
                if ((declared == 0)) {
                    goto L_14a4;
                } else {
                    last = cursor[(declared - 1)];
                    if ((last == (unsigned long)((unsigned char)((sum & 255))))) {
                        goto L_14a4;
                    } else {
                        ret = 0xfffffff8;
                    }
                }
            }
        } else {
            ret = 0xfffffff9;
        }
    } else {
        ret = (unsigned long)((unsigned int)(rc));
    }
    if ((local_8 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}
validate_header pass 50 lines
// glaurung: validate_header @ 0x11b9
int validate_header(const uint8_t * arg0, int arg1) {
    extern unsigned short read_be16(char *);
    unsigned short magic;
    unsigned char ver_type;
    unsigned char version;
    unsigned char type;
    unsigned short length;
    unsigned short var1;
    unsigned short var14;
    long var17;
    // x86-64 prologue: save rbp, frame 32 bytes
    if ((arg0 != 0)) {
        if (((((unsigned long)((unsigned int)(arg1)) == 7) | ((long)(arg1) < 7)) == 0)) {
            var1 = read_be16((char *)(arg0));
            magic = var1;
            if ((magic == 0xc0de)) {
                ver_type = arg0[2];
                version = ((unsigned long)((unsigned char)((ver_type & 255))) >> 4);
                type = (ver_type & 15);
                if ((version == 1)) {
                    if ((type == 0)) {
                        // x86-64 epilogue: restore rbp
                        return 0xfffffffb;
                    }
                    if (((unsigned long)(7) < (unsigned long)(type))) {
                        // x86-64 epilogue: restore rbp
                        return 0xfffffffb;
                    }
                    var14 = read_be16((char *)((arg0 + 4)));
                    length = var14;
                    var17 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) - 7)));
                    if (((((unsigned long)((unsigned int)(var17)) == (unsigned long)((unsigned long)(length))) | ((long)((int)(var17)) < (long)(length))) == 0)) {
                        return 0;
                    } else {
                        return 0xfffffffa;
                    }
                } else {
                    return 0xfffffffc;
                }
            } else {
                return 0xfffffffd;
            }
        } else {
            return 0xfffffffe;
        }
    } else {
        return 0xffffffff;
    }
}

gcc -O2

2/2
parse_packet pass 135 lines
// glaurung: parse_packet @ 0x11b0
int parse_packet(const uint8_t * arg0, int arg1) {
    extern int validate_header(char *, int);
    int rc;
    char * cursor;
    unsigned short declared;
    unsigned int head_word;
    int i;
    unsigned int sum;
    long local_18;
    long local_8;
    long t40;
    long var0;
    long var1;
    long var10;
    int var12;
    int var18;
    long var2;
    long var20;
    long var21;
    long var25;
    long var28;
    int var29;
    long var3;
    long var40;
    long var43;
    long var46;
    long var47;
    int var48;
    int var49;
    long var52;
    int var53;
    int var54;
    int var55;
    int var56;
    long var58;
    int var61;
    long var63;
    int var64;
    int var66;
    int var68;
    int var8;
    local_8 = var0;
    var1 = (unsigned long)((unsigned int)(arg1));
    local_18 = var2;
    var3 = (long)arg0;
    rc = validate_header((char *)(arg0), arg1);
    if (((unsigned long)((unsigned int)(rc)) != 0)) {
        // x86-64 epilogue: tear down frame
        return rc;
    }
    var8 = (unsigned int)((unsigned char)(*(char *)((var3 + 0x2))));
    var10 = (unsigned long)((unsigned int)((var1 - 8)));
    cursor = (char *)((var3 + 8));
    var12 = (unsigned int)((unsigned char)(*(char *)((var3 + 0x3))));
    t40 = ((unsigned int)((unsigned short)(*(short *)((var3 + 0x4)))) & 0xffff);
    declared = (((t40 << 8) | ((unsigned long)(t40) >> 8)) & 0xffff);
    var18 = (unsigned int)((unsigned short)((declared & 0xffff)));
    var20 = (((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(var8)) & 255))) >> 4) & 255);
    var21 = (unsigned long)((unsigned int)((var8 & 15)));
    if (((((unsigned int)(var18) == (unsigned int)(var10)) | ((long)((int)(var18)) < (long)((int)(var10)))) == 0)) {
        return 0xfffffff9;
    } else {
        var25 = 0;
        if (((unsigned long)(3) < (unsigned long)((unsigned long)((unsigned short)((declared & 0xffff)))))) {
            var28 = (unsigned long)((unsigned int)(*(int *)((var3 + 0x8))));
            var29 = (unsigned int)(((((((unsigned int)(var28) & 255) << 24) | ((((unsigned int)(var28) >> 8) & 255) << 16)) | ((((unsigned int)(var28) >> 16) & 255) << 8)) | (((unsigned int)(var28) >> 24) & 255)));
            var25 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned short)((var29 & 0xffff))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var29)) >> 16)))))) + (unsigned int)((unsigned char)((var29 & 255))))));
        }
        if (((unsigned long)((unsigned int)(var18)) == 0)) {
            var40 = 0;
        } else {
            var43 = (long)cursor;
            var46 = ((var3 + (unsigned long)((unsigned int)((var18 - 1)))) + 9);
            var47 = 0;
            do {
                var48 = (unsigned int)((unsigned char)(*(char *)((var43))));
                var43 = (var43 + 1);
                var49 = (var48 + var47);
                var52 = (((unsigned long)((unsigned int)(var49)) << 1) | ((unsigned long)((unsigned int)(var49)) >> 31));
                var47 = var52;
                var40 = var52;
            } while ((var43 != var46));
        }
        if (((unsigned long)((unsigned short)((declared & 0xffff))) == 0)) {
            var53 = (unsigned int)((unsigned char)((var21 & 255)));
            var54 = (unsigned int)((unsigned char)((var20 & 255)));
            var55 = (unsigned int)((unsigned char)((declared & 255)));
            var56 = (var40 & 127);
            var58 = (unsigned long)((unsigned int)((var53 * 8)));
            head_word = (var25 & 63);
            var61 = (var58 - var53);
            var63 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(var61)) + var54) + 100)));
            var64 = (var63 + var55);
            var66 = ((unsigned int)(var64) + (unsigned int)(var56));
            var68 = ((unsigned int)(var66) + head_word);
            rc = (unsigned long)((unsigned int)(var68));
            // x86-64 epilogue: tear down frame
            return (unsigned int)(var68);
        }
        if (((unsigned long)((unsigned int)((var12 & 1))) == 0)) {
            var53 = (unsigned int)((unsigned char)((var21 & 255)));
            var54 = (unsigned int)((unsigned char)((var20 & 255)));
            var55 = (unsigned int)((unsigned char)((declared & 255)));
            var56 = (var40 & 127);
            var58 = (unsigned long)((unsigned int)((var53 * 8)));
            head_word = (var25 & 63);
            var61 = (var58 - var53);
            var63 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(var61)) + var54) + 100)));
            var64 = (var63 + var55);
            var66 = ((unsigned int)(var64) + (unsigned int)(var56));
            var68 = ((unsigned int)(var66) + head_word);
            rc = (unsigned long)((unsigned int)(var68));
            // x86-64 epilogue: tear down frame
            return (unsigned int)(var68);
        }
        if (((unsigned char)(*(char *)((((long)cursor + (unsigned int)((unsigned short)((declared & 0xffff)))) - 1))) == (unsigned char)((var40 & 255)))) {
            var53 = (unsigned int)((unsigned char)((var21 & 255)));
            var54 = (unsigned int)((unsigned char)((var20 & 255)));
            var55 = (unsigned int)((unsigned char)((declared & 255)));
            var56 = (var40 & 127);
            var58 = (unsigned long)((unsigned int)((var53 * 8)));
            head_word = (var25 & 63);
            var61 = (var58 - var53);
            var63 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(var61)) + var54) + 100)));
            var64 = (var63 + var55);
            var66 = ((unsigned int)(var64) + (unsigned int)(var56));
            var68 = ((unsigned int)(var66) + head_word);
            rc = (unsigned long)((unsigned int)(var68));
            // x86-64 epilogue: tear down frame
            return (unsigned int)(var68);
        }
        return 0xfffffff8;
    }
}
validate_header pass 30 lines
// glaurung: validate_header @ 0x1120
int validate_header(const uint8_t * arg0, int arg1) {
    unsigned short length;
    unsigned char type;
    unsigned char ver_type;
    unsigned char version;
    long t40;
    int var0;
    long var10;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    if ((((unsigned long)((unsigned int)(arg1)) == 7) | ((long)(arg1) < 7))) {
        return 0xfffffffe;
    }
    if (((unsigned long)((unsigned short)(*(short *)(((long)arg0)))) != 0xdec0)) {
        return 0xfffffffd;
    }
    var0 = (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x2))));
    if (((unsigned long)((unsigned char)((((unsigned long)((unsigned char)((var0 & 255))) >> 4) & 255))) != 1)) {
        return 0xfffffffc;
    }
    if (((unsigned long)(6) < (unsigned long)((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var0)) & 15))) - 1))) & 255)))))) {
        return 0xfffffffb;
    }
    var10 = (unsigned long)((unsigned int)((arg1 - 7)));
    t40 = ((unsigned int)((unsigned short)(*(short *)(((long)arg0 + 0x4)))) & 0xffff);
    length = (unsigned int)((unsigned short)((((t40 << 8) | ((unsigned long)(t40) >> 8)) & 0xffff)));
    return ((((unsigned int)(var10) == (unsigned int)((unsigned int)(length))) | ((long)((int)(var10)) < (long)((int)((unsigned int)(length))))) ? 0xfffffffa : 0);
}

← 213 fixtures