Fixture 216
packed union wire record
C · 5 functions · 4 lanes · 20 of 20 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
Bitfields inside a PACKED UNION, read back through a byte view — the shape every binary protocol header actually has, and one no fixture composes.
WHAT THE COMPOSITION COSTS. Three recovery problems interact here and none of them is visible alone:
* a bitfield read is a load, a shift and a mask, and the field's WIDTH is encoded only in the mask constant; * a union means the same storage is read at two different types, so an object model keyed by access width sees conflicting evidence for one address rather than two disjoint objects; * packed removes the padding that would otherwise separate the fields, so a byte view straddles bitfield boundaries and the shift amounts stop being multiples of eight.
A decompiler that recovers each in isolation can still produce wrong C for the combination: the classic failure is folding the union's two views into one field of the wider type, which compiles, runs, and silently reinterprets every read.
90_bitfields covers bitfield layout on its own. 91_union_type_punning covers a union on its own. 161_packed_struct_layout covers packed on its own. 163_wire_header_parser parses a wire header but does it with explicit shifts and masks rather than bitfields, which is a different recovery problem. This fixture is the intersection, which is what real headers look like.
Bit-field layout within a unit is implementation-defined, so every function here is written to be layout-AGNOSTIC: values are written through the bitfield view and read back through the same view, and the byte view is only ever used to observe that SOMETHING changed in a specific byte, never to assert which bit. That keeps the differential valid across every target while still forcing the recovery to model the storage overlap.
#include <stdint.h>
/* Bitfields inside a PACKED UNION, read back through a byte view — the shape
* every binary protocol header actually has, and one no fixture composes.
*
* WHAT THE COMPOSITION COSTS. Three recovery problems interact here and none of
* them is visible alone:
*
* * a bitfield read is a load, a shift and a mask, and the field's WIDTH is
* encoded only in the mask constant;
* * a union means the same storage is read at two different types, so an
* object model keyed by access width sees conflicting evidence for one
* address rather than two disjoint objects;
* * `packed` removes the padding that would otherwise separate the fields,
* so a byte view straddles bitfield boundaries and the shift amounts stop
* being multiples of eight.
*
* A decompiler that recovers each in isolation can still produce wrong C for
* the combination: the classic failure is folding the union's two views into
* one field of the wider type, which compiles, runs, and silently reinterprets
* every read.
*
* `90_bitfields` covers bitfield layout on its own. `91_union_type_punning`
* covers a union on its own. `161_packed_struct_layout` covers `packed` on its
* own. `163_wire_header_parser` parses a wire header but does it with explicit
* shifts and masks rather than bitfields, which is a different recovery
* problem. This fixture is the intersection, which is what real headers look
* like.
*
* Bit-field layout within a unit is implementation-defined, so every function
* here is written to be layout-AGNOSTIC: values are written through the
* bitfield view and read back through the same view, and the byte view is only
* ever used to observe that SOMETHING changed in a specific byte, never to
* assert which bit. That keeps the differential valid across every target while
* still forcing the recovery to model the storage overlap.
*/
struct __attribute__((packed)) wire_flags {
uint8_t version : 3;
uint8_t urgent : 1;
uint8_t kind : 4;
};
union __attribute__((packed)) wire_head {
struct wire_flags fields;
uint8_t raw;
};
/* Write through the bitfield view, read through the same view. Layout-agnostic
* and exact. */
__attribute__((noinline)) int32_t bitfield_roundtrip(int32_t version,
int32_t urgent,
int32_t kind) {
union wire_head head;
head.raw = 0;
head.fields.version = (uint8_t)(version & 0x7);
head.fields.urgent = (uint8_t)(urgent & 0x1);
head.fields.kind = (uint8_t)(kind & 0xf);
return (int32_t)head.fields.version * 100 + (int32_t)head.fields.urgent * 10 +
(int32_t)head.fields.kind;
}
/* Write through the bitfield view, observe through the BYTE view. The exact bit
* positions are implementation-defined, so only the population count is
* asserted — which is layout-independent and still requires the storage overlap
* to be modelled. */
__attribute__((noinline)) int32_t bitfield_seen_as_byte(int32_t version,
int32_t kind) {
union wire_head head;
head.raw = 0;
head.fields.version = (uint8_t)(version & 0x7);
head.fields.kind = (uint8_t)(kind & 0xf);
return __builtin_popcount((unsigned)head.raw);
}
/* Write through the BYTE view, read through the bitfield view: the reverse
* direction, where a folded union produces a different answer. Again only the
* population count of the reassembled fields is compared. */
__attribute__((noinline)) int32_t byte_seen_as_bitfields(int32_t byte_value) {
union wire_head head;
head.raw = (uint8_t)(byte_value & 0xff);
int32_t total = (int32_t)head.fields.version + (int32_t)head.fields.urgent +
(int32_t)head.fields.kind;
return total;
}
/* A packed record of several such units, walked as an array. This is the shape
* a TLV parser has, and it forces a stride the compiler cannot pad. */
struct __attribute__((packed)) wire_record {
union wire_head head;
uint16_t length;
uint8_t tag;
};
__attribute__((noinline)) int32_t walk_packed_records(const uint8_t *bytes,
int32_t count) {
int32_t total = 0;
if (bytes == 0 || count < 0 || count > 4) {
return -1;
}
for (int32_t i = 0; i < count; i++) {
struct wire_record rec;
const uint8_t *src = bytes + (int32_t)sizeof(struct wire_record) * i;
/* Byte-wise copy: no unaligned load, valid on every target. */
for (uint32_t b = 0; b < sizeof(struct wire_record); b++) {
((uint8_t *)&rec)[b] = src[b];
}
total += (int32_t)rec.head.fields.kind;
total += (int32_t)(rec.length & 0xff);
total += (int32_t)rec.tag;
}
return total;
}
/* CONTROL: the same three fields as ordinary members, with no bitfields, no
* union and no packing. If this fails, the defect is in struct recovery
* generally rather than in the composition. */
struct plain_head {
uint8_t version;
uint8_t urgent;
uint8_t kind;
};
__attribute__((noinline)) int32_t plain_struct_control(int32_t version,
int32_t urgent,
int32_t kind) {
struct plain_head head;
head.version = (uint8_t)(version & 0x7);
head.urgent = (uint8_t)(urgent & 0x1);
head.kind = (uint8_t)(kind & 0xf);
return (int32_t)head.version * 100 + (int32_t)head.urgent * 10 +
(int32_t)head.kind;
} 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
5/5bitfield_roundtrip pass 11 lines
// glaurung: bitfield_roundtrip @ 0x1100
__attribute__((no_stack_protector)) int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
unsigned char local_10[1];
// x86-64 prologue: save rbp
*(signed char *)(&local_10[0]) = 0;
*(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 248) | ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7));
*(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 247) | ((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) & 1) << 3) & 255));
*(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 15) | ((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 15))) & 15) << 4) & 255));
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)((((unsigned int)((unsigned char)((*(char *)(&local_10[0]) & 7))) * 100) + ((unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_10[0]) & 255))) >> 3) & 1))) * 10)))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_10[0]) & 255))) >> 4) & 255)))));
} bitfield_seen_as_byte pass 16 lines
// glaurung: bitfield_seen_as_byte @ 0x1180
__attribute__((no_stack_protector)) int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
unsigned char local_10[1];
int var28;
long var36;
int var45;
// x86-64 prologue: save rbp
*(signed char *)(&local_10[0]) = 0;
*(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 248) | ((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7));
*(signed char *)(&local_10[0]) = ((*(char *)(&local_10[0]) & 15) | ((((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 15))) & 15) << 4) & 255));
var28 = (unsigned int)((unsigned char)(*(char *)(&local_10[0])));
var36 = (unsigned long)((unsigned int)((var28 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var28)) >> 1))) & 0x55555555))))));
var45 = ((unsigned int)(((unsigned long)((unsigned int)(var36)) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var36)) >> 2))) & 0x33333333)));
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var45)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var45)) >> 4)))))) & 0xf0f0f0f))) * 0x1010101))) >> 24));
} byte_seen_as_bitfields pass 10 lines
// glaurung: byte_seen_as_bitfields @ 0x1200
__attribute__((no_stack_protector)) int32_t byte_seen_as_bitfields(int32_t arg0) {
int total;
unsigned char local_8[1];
// x86-64 prologue: save rbp
*(signed char *)(&local_8[0]) = arg0;
total = ((unsigned int)(((unsigned int)((unsigned char)((*(char *)(&local_8[0]) & 7))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_8[0]) & 255))) >> 3) & 1))))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_8[0]) & 255))) >> 4) & 255))));
// x86-64 epilogue: restore rbp
return (unsigned int)(total);
} plain_struct_control pass 10 lines
// glaurung: plain_struct_control @ 0x1320
__attribute__((no_stack_protector)) int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
unsigned char local_10[3];
// x86-64 prologue: save rbp
*(signed char *)(&local_10[0]) = ((unsigned long)((unsigned int)(arg0)) & 7);
*(signed char *)((&local_10[0] + 1)) = ((unsigned long)((unsigned int)(arg1)) & 1);
*(signed char *)((&local_10[0] + 2)) = ((unsigned long)((unsigned int)(arg2)) & 15);
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)((((unsigned int)((unsigned char)(*(char *)(&local_10[0]))) * 100) + ((unsigned int)((unsigned char)(*(char *)((&local_10[0] + 1)))) * 10)))) + (unsigned int)((unsigned char)(*(char *)((&local_10[0] + 2))))));
} walk_packed_records pass 40 lines
// glaurung: walk_packed_records @ 0x1240
__attribute__((no_stack_protector)) int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
int total;
int i;
char * src;
unsigned int b;
unsigned char local_20[4];
int local_4;
// x86-64 prologue: save rbp
total = 0;
if ((arg0 == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((long)(arg1) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 4) | ((long)(arg1) < 4)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
i = 0;
while ((i < arg1)) {
src = (char *)(((long)arg0 + (long)((int)(((unsigned long)((unsigned int)(i)) << 2)))));
for (b = 0; ((unsigned long)(b) < (unsigned long)(4)); b++) {
*(signed char *)((&local_20[0] + b)) = src[b];
}
total = ((unsigned int)((unsigned char)((((unsigned long)((unsigned char)((*(char *)(&local_20[0]) & 255))) >> 4) & 255))) + total);
total = ((unsigned int)(((unsigned int)((unsigned short)(*(short *)((&local_20[0] + 1)))) & 255)) + total);
total = ((unsigned int)((unsigned char)(*(char *)((&local_20[0] + 3)))) + total);
i = ((unsigned int)(i) + 1);
}
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} clang -O2
5/5bitfield_roundtrip pass 6 lines
// glaurung: bitfield_roundtrip @ 0x1100
int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
long var6;
var6 = (unsigned long)((unsigned int)((arg1 & 1)));
return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var6 + (var6 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
} bitfield_seen_as_byte pass 10 lines
// glaurung: bitfield_seen_as_byte @ 0x1120
int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
long var14;
int var23;
long var6;
var6 = (unsigned long)((unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((arg1 << 4))) & 255))) | (unsigned long)((unsigned int)((arg0 & 7))))));
var14 = (unsigned long)((unsigned int)((var6 - (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var6)) >> 1))) & -47))))));
var23 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var14)) >> 2))) & 0x33333333)) + (unsigned int)(((unsigned long)((unsigned int)(var14)) & 0x33333333)));
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var23)) >> 4))) + (unsigned long)((unsigned int)(var23))))) & 0xf0f0f0f))) * 0x1010101))) >> 24));
} byte_seen_as_bitfields pass 5 lines
// glaurung: byte_seen_as_bitfields @ 0x1160
int32_t byte_seen_as_bitfields(int32_t arg0) {
int total;
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 3))) & 1))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7)))))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) >> 4))) & 15)))));
} plain_struct_control pass 6 lines
// glaurung: plain_struct_control @ 0x1200
int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
long var3;
var3 = (unsigned long)((unsigned int)((arg1 & 1)));
return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var3 + (var3 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
} walk_packed_records pass 38 lines
// glaurung: walk_packed_records @ 0x1180
int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
unsigned int b;
int i;
int total;
long ret;
int var10;
int var22;
int var34;
long var35;
ret = 0xffffffff;
if ((arg0 != 0)) {
ret = 0xffffffff;
if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var10 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0))))) >> 4))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x1)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x3)))));
ret = (unsigned long)((unsigned int)(var10));
if (((unsigned long)((unsigned int)(arg1)) == 1)) {
return ret;
}
var22 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var10)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x4))))) >> 4)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x5)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x7)))));
ret = (unsigned long)((unsigned int)(var22));
if (((unsigned long)((unsigned int)(arg1)) == 2)) {
return ret;
}
var34 = ((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var22)) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x8))))) >> 4)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0x9)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xb)))));
var35 = (unsigned long)((unsigned int)(var34));
ret = (unsigned long)((unsigned int)(var34));
if (((unsigned long)((unsigned int)(arg1)) != 3)) {
ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((var35 + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xc))))) >> 4)))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xd))))))) + (unsigned int)((unsigned char)(*(char *)(((long)arg0 + 0xf)))))));
}
}
return ret;
} gcc -O0
5/5bitfield_roundtrip pass 15 lines
// glaurung: bitfield_roundtrip @ 0x1119
__attribute__((no_stack_protector)) int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
unsigned char local_1[1];
int var43;
int var47;
// x86-64 prologue: save rbp
*(signed char *)(&local_1[0]) = 0;
*(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & -8))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7))));
*(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & -9))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) & 1))) * 8))));
*(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 15))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg2)) & 15))) << 4))));
var43 = (unsigned int)((unsigned char)(((unsigned long)((unsigned int)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 255))) >> 3) & 1))) & 255)));
var47 = ((unsigned int)(((unsigned long)((unsigned int)(var43)) << 2)) + var43);
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 255))) >> 4) & 255))) + (unsigned long)((unsigned int)((((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 7))) & 255))) * 100) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var47)) + (unsigned long)((unsigned int)(var47))))))))));
} bitfield_seen_as_byte pass 13 lines
// glaurung: bitfield_seen_as_byte @ 0x11ac
__attribute__((no_stack_protector)) int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
extern unsigned long __popcountdi2(unsigned long);
unsigned char local_1[1];
unsigned long ret;
// x86-64 prologue: save rbp, frame 32 bytes
*(signed char *)(&local_1[0]) = 0;
*(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & -8))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) & 7))));
*(signed char *)(&local_1[0]) = ((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 15))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 15))) << 4))));
ret = __popcountdi2((unsigned long)((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_1[0]))) & 255)))));
// x86-64 epilogue: restore rbp
return ret;
} byte_seen_as_bitfields pass 10 lines
// glaurung: byte_seen_as_bitfields @ 0x1203
__attribute__((no_stack_protector)) int32_t byte_seen_as_bitfields(int32_t arg0) {
int total;
unsigned char local_5[1];
// x86-64 prologue: save rbp
*(signed char *)(&local_5[0]) = arg0;
total = ((unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_5[0]))) & 255))) >> 4) & 255))) + (unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)(*(char *)(&local_5[0]))) & 7))) & 255))) + (unsigned int)((unsigned char)(((unsigned long)((unsigned int)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_5[0]))) & 255))) >> 3) & 1))) & 255))))));
// x86-64 epilogue: restore rbp
return (unsigned int)(total);
} plain_struct_control pass 14 lines
// glaurung: plain_struct_control @ 0x1316
__attribute__((no_stack_protector)) int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
unsigned char local_3[3];
int var13;
int var17;
// x86-64 prologue: save rbp
*(signed char *)(&local_3[0]) = ((unsigned long)((unsigned int)(arg0)) & 7);
*(signed char *)((&local_3[0] + 1)) = ((unsigned long)((unsigned int)(arg1)) & 1);
*(signed char *)((&local_3[0] + 2)) = ((unsigned long)((unsigned int)(arg2)) & 15);
var13 = (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_3[0] + 1)))) & 255)));
var17 = ((unsigned int)(((unsigned long)((unsigned int)(var13)) << 2)) + var13);
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_3[0] + 2)))) & 255))) + (unsigned long)((unsigned int)((((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_3[0]))) & 255))) * 100) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var17)) + (unsigned long)((unsigned int)(var17))))))))));
} walk_packed_records pass 35 lines
// glaurung: walk_packed_records @ 0x1241
int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int total;
int i;
char * src;
unsigned int b;
unsigned char local_14[4];
long local_8;
long ret;
// x86-64 prologue: save rbp, frame 48 bytes
local_8 = (long)(0x28);
total = 0;
if ((((arg0 == 0) || ((long)(arg1) < 0)) || (((unsigned long)((unsigned int)(arg1)) != 4) && (4 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
i = 0;
while ((i < arg1)) {
src = (char *)(((long)arg0 + (long)((int)(((unsigned long)((unsigned int)(i)) << 2)))));
for (b = 0; ((unsigned long)(b) <= (unsigned long)(3)); b++) {
*(signed char *)((b + &local_14[0])) = src[b];
}
total = (total + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_14[0]))) & 255))) >> 4) & 255))));
total = (total + (unsigned int)((unsigned char)(((unsigned int)((unsigned short)(((unsigned int)((unsigned short)(*(short *)((&local_14[0] + 1)))) & 0xffff))) & 255))));
total = (total + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_14[0] + 3)))) & 255))));
i = (i + 1);
}
ret = (unsigned long)((unsigned int)(total));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} gcc -O2
5/5bitfield_roundtrip pass 6 lines
// glaurung: bitfield_roundtrip @ 0x1100
int32_t bitfield_roundtrip(int32_t arg0, int32_t arg1, int32_t arg2) {
long var3;
var3 = (unsigned long)((unsigned int)((arg1 & 1)));
return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var3 + (var3 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
} bitfield_seen_as_byte pass 7 lines
// glaurung: bitfield_seen_as_byte @ 0x1120
int32_t bitfield_seen_as_byte(int32_t arg0, int32_t arg1) {
extern unsigned long __popcountdi2(unsigned long);
unsigned long ret;
ret = __popcountdi2((unsigned int)((unsigned char)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg1 << 4))) | (unsigned long)((unsigned int)((arg0 & 7)))))) & 255))));
return ret;
} byte_seen_as_bitfields pass 5 lines
// glaurung: byte_seen_as_bitfields @ 0x1140
int32_t byte_seen_as_bitfields(int32_t arg0) {
int total;
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg0)) & 7))) + (unsigned long)((unsigned int)((((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(arg0)) & 255))) >> 3) & 1)))))) + (unsigned int)((unsigned char)((((unsigned long)((unsigned char)((arg0 & 255))) >> 4) & 255)))));
} plain_struct_control pass 6 lines
// glaurung: plain_struct_control @ 0x11b0
int32_t plain_struct_control(int32_t arg0, int32_t arg1, int32_t arg2) {
long var3;
var3 = (unsigned long)((unsigned int)((arg1 & 1)));
return (unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)((arg0 & 7))) * 100) + ((unsigned long)((unsigned int)((var3 + (var3 * 4)))) * 2)))) + (unsigned long)((unsigned int)((arg2 & 15)))));
} walk_packed_records pass 28 lines
// glaurung: walk_packed_records @ 0x1160
int32_t walk_packed_records(const uint8_t * arg0, int32_t arg1) {
int i;
int total;
unsigned int b;
long ret;
long var6;
long var7;
if ((arg0 == 0)) {
return 0xffffffff;
}
if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
i = 0;
var6 = 0;
do {
var7 = (unsigned long)((unsigned int)(*(int *)(((long)arg0 + i * 4))));
i = (i + 1);
total = ((unsigned int)(((unsigned int)((unsigned char)((((unsigned long)(var7) >> 8) & 255))) + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)((((unsigned long)((unsigned char)(((unsigned long)((unsigned int)(var7)) & 255))) >> 4) & 255))) + var6))))) + (unsigned int)(((unsigned long)((unsigned int)(var7)) >> 24)));
ret = (unsigned long)((unsigned int)(total));
var6 = (unsigned long)((unsigned int)(total));
} while (((((unsigned int)(arg1) == (unsigned int)(i)) | (arg1 < i)) == 0));
return ret;
}