vec_push(code_chars, '\0'); /* P */
}
+ /* ensure all data is in LE format */
+ util_endianswap(&code_header.version, 1, sizeof(code_header.version));
+ util_endianswap(&code_header.crc16, 1, sizeof(code_header.crc16));
+ util_endianswap(&code_header.statements, 2, sizeof(code_header.statements.offset));
+ util_endianswap(&code_header.defs, 2, sizeof(code_header.statements.offset));
+ util_endianswap(&code_header.fields, 2, sizeof(code_header.statements.offset));
+ util_endianswap(&code_header.functions, 2, sizeof(code_header.statements.offset));
+ util_endianswap(&code_header.strings, 2, sizeof(code_header.statements.offset));
+ util_endianswap(&code_header.globals, 2, sizeof(code_header.statements.offset));
+ util_endianswap(&code_header.entfield, 1, sizeof(code_header.entfield));
+ util_endianswap(code_statements, vec_size(code_statements), sizeof(prog_section_statement));
+ util_endianswap(code_defs, vec_size(code_defs), sizeof(prog_section_def));
+ util_endianswap(code_fields, vec_size(code_fields), sizeof(prog_section_field));
+ util_endianswap(code_functions, vec_size(code_functions), sizeof(prog_section_function));
+ util_endianswap(code_globals, vec_size(code_globals), sizeof(int32_t));
+
if (lnofile) {
uint32_t lnotype = *(unsigned int*)"LNOF";
uint32_t version = 1;
if (!fp)
return false;
+ util_endianswap(&version, 1, sizeof(version));
+ util_endianswap(code_linenums, vec_size(code_linenums), sizeof(code_linenums[0]));
+
if (fwrite(&lnotype, sizeof(lnotype), 1, fp) != 1 ||
fwrite(&version, sizeof(version), 1, fp) != 1 ||
fwrite(&code_header.defs.length, sizeof(code_header.defs.length), 1, fp) != 1 ||
fp = NULL;
}
- /* ensure all data is in LE format */
- util_endianswap(&code_header, 1, sizeof(prog_header));
- util_endianswap(code_statements, vec_size(code_statements), sizeof(prog_section_statement));
- util_endianswap(code_defs, vec_size(code_defs), sizeof(prog_section_def));
- util_endianswap(code_fields, vec_size(code_fields), sizeof(prog_section_field));
- util_endianswap(code_functions, vec_size(code_functions), sizeof(prog_section_function));
- util_endianswap(code_globals, vec_size(code_globals), sizeof(int32_t));
-
fp = util_fopen(filename, "wb");
if (!fp)
return false;
char *util_strchp (const char *, const char *);
void util_debug (const char *, const char *, ...);
int util_getline (char **, size_t *, FILE *);
-void util_endianswap (void *, int, int);
+void util_endianswap (void *, size_t, unsigned int);
size_t util_strtocmd (const char *, char *, size_t);
size_t util_strtononcmd (const char *, char *, size_t);
* reorders by stride and length, much nicer than other functions for
* certian-sized types like short or int.
*/
+#if 0
void util_endianswap(void *m, int s, int l) {
size_t w = 0;
size_t i = 0;
}
}
}
+#endif
+
+static void util_swap16(uint16_t *d, size_t l) {
+ while (l--) {
+ d[l] = (d[l] << 8) | (d[l] >> 8);
+ }
+}
+
+static void util_swap32(uint32_t *d, size_t l) {
+ while (l--) {
+ uint32_t v;
+ v = ((d[l] << 8) & 0xFF00FF00) | ((d[l] >> 8) & 0x00FF00FF);
+ d[l] = (v << 16) | (v >> 16);
+ }
+}
+
+/* Some strange system doesn't like constants that big, AND doesn't recognize an ULL suffix
+ * so let's go the safe way
+ */
+static void util_swap64(uint32_t *d, size_t l) {
+ /*
+ while (l--) {
+ uint64_t v;
+ v = ((d[l] << 8) & 0xFF00FF00FF00FF00) | ((d[l] >> 8) & 0x00FF00FF00FF00FF);
+ v = ((v << 16) & 0xFFFF0000FFFF0000) | ((v >> 16) & 0x0000FFFF0000FFFF);
+ d[l] = (v << 32) | (v >> 32);
+ }
+ */
+ size_t i;
+ for (i = 0; i < l; i += 2) {
+ uint32_t v1 = d[i];
+ d[i] = d[i+1];
+ d[i+1] = v1;
+ util_swap32(d+i, 2);
+ }
+}
+
+void util_endianswap(void *_data, size_t length, unsigned int typesize) {
+ /* I'm guessing there's no GOOD way to do this at compile time:
+ * FIXME:
+ */
+ if (*((char*)&typesize))
+ return;
+ if (typesize == 1)
+ return;
+ if (typesize == 2) {
+ util_swap16((uint16_t*)_data, length>>1);
+ return;
+ }
+ if (typesize == 4) {
+ util_swap32((uint32_t*)_data, length>>2);
+ return;
+ }
+ if (typesize == 4) {
+ util_swap64((uint32_t*)_data, length>>3);
+ return;
+ }
+}
/*
* CRC algorithms vary in the width of the polynomial, the value of said polynomial,