From 87356861ae7054cbec44b3978eb32dfe0e26a8fa Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Wed, 17 Jul 2024 04:25:33 +0200 Subject: Bit order --- bxgen.c | 343 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 188 insertions(+), 155 deletions(-) (limited to 'bxgen.c') diff --git a/bxgen.c b/bxgen.c index 680e114..2395a0f 100755 --- a/bxgen.c +++ b/bxgen.c @@ -829,159 +829,182 @@ void unit_set_entry_point(Pool *pool, i64 unit, i64 entry_point_proc) { // // ================================================================ -u16 read_u16(i32 endianness, u8 *v, u8 *v_end) { +typedef struct { + unsigned little:1; +} Bits; + +i32 host_bit_order() { + if ((*(Bits *) &(u8) { 1 }).little == 1) + return LE; + return BE; +} + +i32 host_byte_order() { + if (((u8 *) &(u32) { 1 })[0] == 1) + return LE; + return BE; +} + +u8 read_u8(i32 bit_order, u8 *v) { + if (bit_order == host_bit_order()) + return *v; + + return + ((*v >> 7) & 1) | + (((*v >> 6) & 1) << 1) | + (((*v >> 5) & 1) << 2) | + (((*v >> 4) & 1) << 3) | + (((*v >> 3) & 1) << 4) | + (((*v >> 2) & 1) << 5) | + (((*v >> 1) & 1) << 6) | + (((*v) & 1) << 7); +} + +u16 read_u16(i32 bit_order, i32 byte_order, u8 *v, u8 *v_end) { BX_ASSERT(v != NULL); BX_ASSERT(v + 2 <= v_end); - if (endianness == LE) - return ((u16) v[0]) | - (((u16) v[1]) << 8); + if (byte_order == host_byte_order()) + return ((u16) read_u8(bit_order, v)) | + (((u16) read_u8(bit_order, v + 1)) << 8); - if (endianness == BE) - return ((u16) v[1]) | - (((u16) v[0]) << 8); - - BX_ASSERT(0); - return 0; + return ((u16) read_u8(bit_order, v + 1)) | + (((u16) read_u8(bit_order, v)) << 8); } -u32 read_u32(i32 endianness, u8 *v, u8 *v_end) { +u32 read_u32(i32 bit_order, i32 byte_order, u8 *v, u8 *v_end) { BX_ASSERT(v != NULL); BX_ASSERT(v + 4 <= v_end); - if (endianness == LE) - return ((u32) v[0]) | - (((u32) v[1]) << 8) | - (((u32) v[2]) << 16) | - (((u32) v[3]) << 24); - - if (endianness == BE) - return ((u32) v[3]) | - (((u32) v[2]) << 8) | - (((u32) v[1]) << 16) | - (((u32) v[0]) << 24); - + if (byte_order == host_byte_order()) + return ((u32) read_u8(bit_order, v)) | + (((u32) read_u8(bit_order, v + 1)) << 8) | + (((u32) read_u8(bit_order, v + 2)) << 16) | + (((u32) read_u8(bit_order, v + 3)) << 24); - BX_ASSERT(0); - return 0; + return ((u32) read_u8(bit_order, v + 3)) | + (((u32) read_u8(bit_order, v + 2)) << 8) | + (((u32) read_u8(bit_order, v + 1)) << 16) | + (((u32) read_u8(bit_order, v)) << 24); } -u64 read_u64(i32 endianness, u8 *v, u8 *v_end) { +u64 read_u64(i32 bit_order, i32 byte_order, u8 *v, u8 *v_end) { BX_ASSERT(v != NULL); BX_ASSERT(v + 8 <= v_end); - if (endianness == LE) - return ((u64) v[0]) | - (((u64) v[1]) << 8) | - (((u64) v[2]) << 16) | - (((u64) v[3]) << 24) | - (((u64) v[4]) << 32) | - (((u64) v[5]) << 40) | - (((u64) v[6]) << 48) | - (((u64) v[7]) << 56); - - if (endianness == BE) - return ((u64) v[7]) | - (((u64) v[6]) << 8) | - (((u64) v[5]) << 16) | - (((u64) v[4]) << 24) | - (((u64) v[3]) << 32) | - (((u64) v[2]) << 40) | - (((u64) v[1]) << 48) | - (((u64) v[0]) << 56); - - BX_ASSERT(0); - return 0; -} + if (byte_order == host_byte_order()) + return ((u64) read_u8(bit_order, v)) | + (((u64) read_u8(bit_order, v + 1)) << 8) | + (((u64) read_u8(bit_order, v + 2)) << 16) | + (((u64) read_u8(bit_order, v + 3)) << 24) | + (((u64) read_u8(bit_order, v + 4)) << 32) | + (((u64) read_u8(bit_order, v + 5)) << 40) | + (((u64) read_u8(bit_order, v + 6)) << 48) | + (((u64) read_u8(bit_order, v + 7)) << 56); + + return ((u64) read_u8(bit_order, v + 7)) | + (((u64) read_u8(bit_order, v + 6)) << 8) | + (((u64) read_u8(bit_order, v + 5)) << 16) | + (((u64) read_u8(bit_order, v + 4)) << 24) | + (((u64) read_u8(bit_order, v + 3)) << 32) | + (((u64) read_u8(bit_order, v + 2)) << 40) | + (((u64) read_u8(bit_order, v + 1)) << 48) | + (((u64) read_u8(bit_order, v)) << 56); +} + +void write_u8(i32 bit_order, u8 x, u8 *v) { + BX_ASSERT(v != NULL); -void write_u16(i32 endianness, u16 x, u8 *v, u8 *v_end) { + if (bit_order == host_bit_order()) + *v = x; + else + *v = + ((x >> 7) & 1) | + (((x >> 6) & 1) << 1) | + (((x >> 5) & 1) << 2) | + (((x >> 4) & 1) << 3) | + (((x >> 3) & 1) << 4) | + (((x >> 2) & 1) << 5) | + (((x >> 1) & 1) << 6) | + (((x) & 1) << 7); +} + +void write_u16(i32 bit_order, i32 byte_order, u16 x, u8 *v, u8 *v_end) { BX_ASSERT(v != NULL); BX_ASSERT(v + 2 <= v_end); - if (endianness == LE) { - v[0] = (u8) ( x & 0xff); - v[1] = (u8) ((x >> 8) & 0xff); + if (byte_order == host_byte_order()) { + write_u8(bit_order, (u8) ( x & 0xff), v); + write_u8(bit_order, (u8) ((x >> 8) & 0xff), v + 1); + } else { + write_u8(bit_order, (u8) ( x & 0xff), v + 1); + write_u8(bit_order, (u8) ((x >> 8) & 0xff), v); } - - if (endianness == BE) { - v[1] = (u8) ( x & 0xff); - v[0] = (u8) ((x >> 8) & 0xff); - } - - BX_ASSERT(0); } -void write_u32(i32 endianness, u32 x, u8 *v, u8 *v_end) { +void write_u32(i32 bit_order, i32 byte_order, u32 x, u8 *v, u8 *v_end) { BX_ASSERT(v != NULL); BX_ASSERT(v + 4 <= v_end); - if (endianness == LE) { - v[0] = (u8) ( x & 0xff); - v[1] = (u8) ((x >> 8) & 0xff); - v[2] = (u8) ((x >> 16) & 0xff); - v[3] = (u8) ((x >> 24) & 0xff); - } - - if (endianness == BE) { - v[3] = (u8) ( x & 0xff); - v[2] = (u8) ((x >> 8) & 0xff); - v[1] = (u8) ((x >> 16) & 0xff); - v[0] = (u8) ((x >> 24) & 0xff); + if (byte_order == host_byte_order()) { + write_u8(bit_order, (u8) ( x & 0xff), v); + write_u8(bit_order, (u8) ((x >> 8) & 0xff), v + 1); + write_u8(bit_order, (u8) ((x >> 16) & 0xff), v + 2); + write_u8(bit_order, (u8) ((x >> 24) & 0xff), v + 3); + } else { + write_u8(bit_order, (u8) ( x & 0xff), v + 3); + write_u8(bit_order, (u8) ((x >> 8) & 0xff), v + 2); + write_u8(bit_order, (u8) ((x >> 16) & 0xff), v + 1); + write_u8(bit_order, (u8) ((x >> 24) & 0xff), v); } - - BX_ASSERT(0); } -void write_u64(i32 endianness, u64 x, u8 *v, u8 *v_end) { +void write_u64(i32 bit_order, i32 byte_order, u64 x, u8 *v, u8 *v_end) { BX_ASSERT(v != NULL); BX_ASSERT(v + 8 <= v_end); - if (endianness == LE) { - v[0] = (u8) ( x & 0xff); - v[1] = (u8) ((x >> 8) & 0xff); - v[2] = (u8) ((x >> 16) & 0xff); - v[3] = (u8) ((x >> 24) & 0xff); - v[4] = (u8) ((x >> 32) & 0xff); - v[5] = (u8) ((x >> 40) & 0xff); - v[6] = (u8) ((x >> 48) & 0xff); - v[7] = (u8) ((x >> 56) & 0xff); - } - - if (endianness == BE) { - v[7] = (u8) ( x & 0xff); - v[6] = (u8) ((x >> 8) & 0xff); - v[5] = (u8) ((x >> 16) & 0xff); - v[4] = (u8) ((x >> 24) & 0xff); - v[3] = (u8) ((x >> 32) & 0xff); - v[2] = (u8) ((x >> 40) & 0xff); - v[1] = (u8) ((x >> 48) & 0xff); - v[0] = (u8) ((x >> 56) & 0xff); + if (byte_order == host_byte_order()) { + write_u8(bit_order, (u8) ( x & 0xff), v); + write_u8(bit_order, (u8) ((x >> 8) & 0xff), v + 1); + write_u8(bit_order, (u8) ((x >> 16) & 0xff), v + 2); + write_u8(bit_order, (u8) ((x >> 24) & 0xff), v + 3); + write_u8(bit_order, (u8) ((x >> 32) & 0xff), v + 4); + write_u8(bit_order, (u8) ((x >> 40) & 0xff), v + 5); + write_u8(bit_order, (u8) ((x >> 48) & 0xff), v + 6); + write_u8(bit_order, (u8) ((x >> 56) & 0xff), v + 7); + } else { + write_u8(bit_order, (u8) ( x & 0xff), v + 7); + write_u8(bit_order, (u8) ((x >> 8) & 0xff), v + 6); + write_u8(bit_order, (u8) ((x >> 16) & 0xff), v + 5); + write_u8(bit_order, (u8) ((x >> 24) & 0xff), v + 4); + write_u8(bit_order, (u8) ((x >> 32) & 0xff), v + 3); + write_u8(bit_order, (u8) ((x >> 40) & 0xff), v + 2); + write_u8(bit_order, (u8) ((x >> 48) & 0xff), v + 1); + write_u8(bit_order, (u8) ((x >> 56) & 0xff), v); } - - BX_ASSERT(0); } -i16 read_i16(i32 endianness, void *v, void *v_end) { - return (i16) read_u16(endianness, v, v_end); +i16 read_i16(i32 bit_order, i32 byte_order, void *v, void *v_end) { + return (i16) read_u16(bit_order, byte_order, v, v_end); } -i32 read_i32(i32 endianness, void *v, void *v_end) { - return (i32) read_u32(endianness, v, v_end); +i32 read_i32(i32 bit_order, i32 byte_order, void *v, void *v_end) { + return (i32) read_u32(bit_order, byte_order, v, v_end); } -i64 read_i64(i32 endianness, void *v, void *v_end) { - return (i64) read_u64(endianness, v, v_end); +i64 read_i64(i32 bit_order, i32 byte_order, void *v, void *v_end) { + return (i64) read_u64(bit_order, byte_order, v, v_end); } -f32 read_f32(i32 endianness, void *v, void *v_end) { +f32 read_f32(i32 bit_order, i32 byte_order, void *v, void *v_end) { if ((*(u64 *) &(f64) { -1.4575323640233e-306 } & 0xffffffffull) != 0x40301fcbull && (*(u64 *) &(f64) { -1.4575323640233e-306 } & 0xffffffff00000000ull) != 0x40301fcb00000000ull) BX_ASSERT(0 && "Unknown native floating-point number format"); - return *(f32 *) &(u32) { read_u32(endianness, v, v_end) }; + return *(f32 *) &(u32) { read_u32(bit_order, byte_order, v, v_end) }; } -f32 read_f64(i32 endianness, i32 f64_word_order, void *v, void *v_end) { +f32 read_f64(i32 bit_order, i32 byte_order, i32 f64_word_order, void *v, void *v_end) { b8 native_word_order_same; if ( (*(u64 *) &(f64) { -1.4575323640233e-306 } & 0xffffffffull) == 0x40301fcbull) @@ -991,35 +1014,35 @@ f32 read_f64(i32 endianness, i32 f64_word_order, void *v, void *v_end) { else BX_ASSERT(0 && "Unknown native floating-point number format"); - u64 x = read_u64(endianness, v, v_end); + u64 x = read_u64(bit_order, byte_order, v, v_end); - if (native_word_order_same != (endianness == f64_word_order)) + if (native_word_order_same != (byte_order == f64_word_order)) x = ((x & 0xffffffffull) << 32) | ((x >> 32) & 0xffffffffull); return *(f64 *) &x; } -void write_i16(i32 endianness, i16 x, void *v, void *v_end) { - write_u16(endianness, (u16) x, v, v_end); +void write_i16(i32 bit_order, i32 byte_order, i16 x, void *v, void *v_end) { + write_u16(bit_order, byte_order, (u16) x, v, v_end); } -void write_i32(i32 endianness, i32 x, void *v, void *v_end) { - write_u32(endianness, (u32) x, v, v_end); +void write_i32(i32 bit_order, i32 byte_order, i32 x, void *v, void *v_end) { + write_u32(bit_order, byte_order, (u32) x, v, v_end); } -void write_i64(i32 endianness, i64 x, void *v, void *v_end) { - write_u64(endianness, (u64) x, v, v_end); +void write_i64(i32 bit_order, i32 byte_order, i64 x, void *v, void *v_end) { + write_u64(bit_order, byte_order, (u64) x, v, v_end); } -void write_f32(i32 endianness, f32 x, void *v, void *v_end) { +void write_f32(i32 bit_order, i32 byte_order, f32 x, void *v, void *v_end) { if ((*(u64 *) &(f64) { -1.4575323640233e-306 } & 0xffffffffull) != 0x40301fcbull && (*(u64 *) &(f64) { -1.4575323640233e-306 } & 0xffffffff00000000ull) != 0x40301fcb00000000ull) BX_ASSERT(0 && "Unknown native floating-point number format"); - write_u32(endianness, *(u32 *) &x, v, v_end); + write_u32(bit_order, byte_order, *(u32 *) &x, v, v_end); } -void write_f64(i32 endianness, i32 f64_word_order, f64 x, void *v, void *v_end) { +void write_f64(i32 bit_order, i32 byte_order, i32 f64_word_order, f64 x, void *v, void *v_end) { b8 native_word_order_same; if ( (*(u64 *) &(f64) { -1.4575323640233e-306 } & 0xffffffffull) == 0x40301fcbull) @@ -1029,14 +1052,17 @@ void write_f64(i32 endianness, i32 f64_word_order, f64 x, void *v, void *v_end) else BX_ASSERT(0 && "Unknown native floating-point number format"); - if (native_word_order_same == (endianness == f64_word_order)) - write_u64(endianness, *(u64 *) &x, v, v_end); + if (native_word_order_same == (byte_order == f64_word_order)) + write_u64(bit_order, byte_order, *(u64 *) &x, v, v_end); else { - write_u32(endianness, *(((u32 *) &x) + 1), (u8 *) v, v_end); - write_u32(endianness, * (u32 *) &x, ((u8 *) v) + 4, v_end); + write_u32(bit_order, byte_order, *(((u32 *) &x) + 1), (u8 *) v, v_end); + write_u32(bit_order, byte_order, * (u32 *) &x, ((u8 *) v) + 4, v_end); } } +#define HBIO host_bit_order() +#define HBYO host_byte_order() + // ================================================================ // // * Code generation and linking @@ -1198,7 +1224,7 @@ u32 ar_find_symbol_offset_by_name(u8 *ar_symbol_table, u8 *ar_end, c8 *name, c8 BX_ASSERT(name != NULL); BX_ASSERT(name_end > name); - u32 count = read_u32(BE, ar_symbol_table, ar_end); + u32 count = read_u32(HBIO, BE, ar_symbol_table, ar_end); i64 len = name_end - name; @@ -1208,7 +1234,7 @@ u32 ar_find_symbol_offset_by_name(u8 *ar_symbol_table, u8 *ar_end, c8 *name, c8 for (; index < count; ++index) { BX_ASSERT(s + len <= (c8 *) ar_end); if (s[len] == '\0' && bx_mem_eq(s, name, len)) - return read_u32(BE, ar_symbol_table + 4 * (index + 1), ar_end); + return read_u32(HBIO, BE, ar_symbol_table + 4 * (index + 1), ar_end); while (*s != '\0' && s < (c8 *) ar_end) ++s; BX_ASSERT(s < (c8 *) ar_end); @@ -1224,7 +1250,7 @@ u16 elf_section_names_table_index( u8 *elf_begin, u8 *elf_end ) { - return read_u16(LE, elf_begin + 62, elf_end); + return read_u16(HBIO, HBYO, elf_begin + 62, elf_end); } Offset_Count elf_section_headers( @@ -1232,8 +1258,8 @@ Offset_Count elf_section_headers( u8 *elf_end ) { return (Offset_Count) { - .offset = read_u64(LE, elf_begin + 40, elf_end), - .count = read_u16(LE, elf_begin + 60, elf_end), + .offset = read_u64(HBIO, HBYO, elf_begin + 40, elf_end), + .count = read_u16(HBIO, HBYO, elf_begin + 60, elf_end), }; } @@ -1254,8 +1280,8 @@ Offset_Size elf_section_names_data( u8 *begin = elf_begin + elf_section_header_offset(elf_begin, elf_end, string_table_index); return (Offset_Size) { - .offset = read_u64(LE, begin + 24, elf_end), - .size = read_u64(LE, begin + 32, elf_end), + .offset = read_u64(HBIO, HBYO, begin + 24, elf_end), + .size = read_u64(HBIO, HBYO, begin + 32, elf_end), }; } @@ -1288,7 +1314,7 @@ u64 elf_find_section_header_by_name( for (u16 i = 0; i < headers.count; ++i) { u8 *begin = elf_begin + headers.offset + i * ELF_SECTION_HEADER_SIZE; - u32 name_offset = read_u32(LE, begin, elf_end); + u32 name_offset = read_u32(HBIO, HBYO, begin, elf_end); if (name_offset + name_size <= names.size && bx_mem_eq(elf_begin + names.offset + name_offset, name, name_size)) @@ -1306,7 +1332,7 @@ Section_Header elf_section_data_by_offset( ) { Offset_Size names = elf_section_names_data(elf_begin, elf_end); u8 * begin = elf_begin + offset; - u32 name_index = read_u32(LE, begin, elf_end); + u32 name_index = read_u32(HBIO, HBYO, begin, elf_end); return (Section_Header) { .name = elf_name_in_string_table( @@ -1315,11 +1341,11 @@ Section_Header elf_section_data_by_offset( names, name_index ), - .type = read_u32(LE, begin + 4, elf_end), - .flags = read_u64(LE, begin + 8, elf_end), + .type = read_u32(HBIO, HBYO, begin + 4, elf_end), + .flags = read_u64(HBIO, HBYO, begin + 8, elf_end), .data = { - .offset = read_u64(LE, begin + 24, elf_end), - .size = read_u64(LE, begin + 32, elf_end), + .offset = read_u64(HBIO, HBYO, begin + 24, elf_end), + .size = read_u64(HBIO, HBYO, begin + 32, elf_end), }, }; } @@ -1510,31 +1536,35 @@ void unit_write(Pool *pool, i64 unit, u16 target, i64 io_out, void *io_user_data u16 string_table_index; u16 string_table_offset; - BX_ASSERT(bx_mem_eq(elf_begin, ELF_MAGIC, 4)); - BX_ASSERT(elf_begin[4] == ELF_64); - BX_ASSERT(elf_begin[5] == ELF_2_LE); - BX_ASSERT(elf_begin[6] == ELF_VERSION); - BX_ASSERT(elf_begin[7] == ELF_SYS_V || elf_begin[7] == ELF_LINUX); - BX_ASSERT(elf_begin[8] == ELF_ABI_VERSION); + BX_ASSERT(read_u8(HBIO, elf_begin) == ELF_MAGIC[0]); + BX_ASSERT(read_u8(HBIO, elf_begin + 1) == ELF_MAGIC[1]); + BX_ASSERT(read_u8(HBIO, elf_begin + 2) == ELF_MAGIC[2]); + BX_ASSERT(read_u8(HBIO, elf_begin + 3) == ELF_MAGIC[3]); + BX_ASSERT(read_u8(HBIO, elf_begin + 4) == ELF_64); + BX_ASSERT(read_u8(HBIO, elf_begin + 5) == ELF_2_LE); + BX_ASSERT(read_u8(HBIO, elf_begin + 6) == ELF_VERSION); + u8 osabi = read_u8(HBIO, elf_begin + 7); + BX_ASSERT(osabi == ELF_SYS_V || osabi == ELF_LINUX); + BX_ASSERT(read_u8(HBIO, elf_begin + 8) == ELF_ABI_VERSION); - BX_ASSERT(read_u16(LE, elf_begin + 16, elf_end) == ELF_RELOCATABLE); - BX_ASSERT(read_u16(LE, elf_begin + 18, elf_end) == ELF_X86_64); - BX_ASSERT(read_u32(LE, elf_begin + 20, elf_end) == ELF_VERSION); - BX_ASSERT(read_u64(LE, elf_begin + 24, elf_end) == 0); // entry - BX_ASSERT(read_u64(LE, elf_begin + 32, elf_end) == 0); // program header offset + BX_ASSERT(read_u16(HBIO, HBYO, elf_begin + 16, elf_end) == ELF_RELOCATABLE); + BX_ASSERT(read_u16(HBIO, HBYO, elf_begin + 18, elf_end) == ELF_X86_64); + BX_ASSERT(read_u32(HBIO, HBYO, elf_begin + 20, elf_end) == ELF_VERSION); + BX_ASSERT(read_u64(HBIO, HBYO, elf_begin + 24, elf_end) == 0); // entry + BX_ASSERT(read_u64(HBIO, HBYO, elf_begin + 32, elf_end) == 0); // program header offset - section_header_offset = read_u64(LE, elf_begin + 40, elf_end); + section_header_offset = read_u64(HBIO, HBYO, elf_begin + 40, elf_end); - BX_ASSERT(read_u32(LE, elf_begin + 48, elf_end) == 0); // flags - BX_ASSERT(read_u16(LE, elf_begin + 52, elf_end) == ELF_HEADER_SIZE); - BX_ASSERT(read_u16(LE, elf_begin + 54, elf_end) == 0); // program header size - BX_ASSERT(read_u16(LE, elf_begin + 56, elf_end) == 0); // program header count - BX_ASSERT(read_u16(LE, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE); + BX_ASSERT(read_u32(HBIO, HBYO, elf_begin + 48, elf_end) == 0); // flags + BX_ASSERT(read_u16(HBIO, HBYO, elf_begin + 52, elf_end) == ELF_HEADER_SIZE); + BX_ASSERT(read_u16(HBIO, HBYO, elf_begin + 54, elf_end) == 0); // program header size + BX_ASSERT(read_u16(HBIO, HBYO, elf_begin + 56, elf_end) == 0); // program header count + BX_ASSERT(read_u16(HBIO, HBYO, elf_begin + 58, elf_end) == ELF_SECTION_HEADER_SIZE); - section_count = read_u16(LE, elf_begin + 60, elf_end); - string_table_index = read_u16(LE, elf_begin + 62, elf_end); + section_count = read_u16(HBIO, HBYO, elf_begin + 60, elf_end); + string_table_index = read_u16(HBIO, HBYO, elf_begin + 62, elf_end); - string_table_offset = read_u64(LE, elf_begin + section_header_offset + string_table_index * ELF_SECTION_HEADER_SIZE + 24, elf_end); + string_table_offset = read_u64(HBIO, HBYO, elf_begin + section_header_offset + string_table_index * ELF_SECTION_HEADER_SIZE + 24, elf_end); (void) ar_symbol_table; (void) ar_string_table; @@ -2521,6 +2551,9 @@ int main(int argc, char **argv) { (void) argc; (void) argv; + printf("host bit order: %s\n", host_bit_order() == LE ? "LE" : "BE"); + printf("host byte order: %s\n\n", host_byte_order() == LE ? "LE" : "BE"); + printf("entity - %d bytes\n", (i32) sizeof(Entity)); printf("binary output buffer - %d MB\n\n", (i32) sizeof(Binary_Output) / (1024 * 1024)); -- cgit v1.2.3