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.
/* 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/2parse_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/2parse_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/2parse_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/2parse_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);
}