Allow testsuite to pass on big endian

Move the progs header and body byteswapping into util functions and
call those functions when either reading or writing the progs.
This commit is contained in:
Jim Thoenen 2014-02-02 19:24:59 -06:00
parent f7e074d88f
commit 69b89dc6ac
4 changed files with 78 additions and 48 deletions

53
code.c
View file

@ -260,59 +260,18 @@ static void code_create_header(code_t *code, prog_header_t *code_header, const c
}
/* 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.offset, 1, sizeof(code_header->statements.offset));
util_endianswap(&code_header->statements.length, 1, sizeof(code_header->statements.length));
util_endianswap(&code_header->defs.offset, 1, sizeof(code_header->defs.offset));
util_endianswap(&code_header->defs.length, 1, sizeof(code_header->defs.length));
util_endianswap(&code_header->fields.offset, 1, sizeof(code_header->fields.offset));
util_endianswap(&code_header->fields.length, 1, sizeof(code_header->fields.length));
util_endianswap(&code_header->functions.offset, 1, sizeof(code_header->functions.offset));
util_endianswap(&code_header->functions.length, 1, sizeof(code_header->functions.length));
util_endianswap(&code_header->strings.offset, 1, sizeof(code_header->strings.offset));
util_endianswap(&code_header->strings.length, 1, sizeof(code_header->strings.length));
util_endianswap(&code_header->globals.offset, 1, sizeof(code_header->globals.offset));
util_endianswap(&code_header->globals.length, 1, sizeof(code_header->globals.length));
util_endianswap(&code_header->entfield, 1, sizeof(code_header->entfield));
util_swap_header(code_header);
/*
* These are not part of the header but we ensure LE format here to save on duplicated
* code.
*/
for (i = 0; i < vec_size(code->statements); ++i) {
util_endianswap(&code->statements[i].opcode, 1, sizeof(code->statements[i].opcode));
util_endianswap(&code->statements[i].o1, 1, sizeof(code->statements[i].o1));
util_endianswap(&code->statements[i].o2, 1, sizeof(code->statements[i].o2));
util_endianswap(&code->statements[i].o3, 1, sizeof(code->statements[i].o3));
}
for (i = 0; i < vec_size(code->defs); ++i) {
util_endianswap(&code->defs[i].type, 1, sizeof(code->defs[i].type));
util_endianswap(&code->defs[i].offset, 1, sizeof(code->defs[i].offset));
util_endianswap(&code->defs[i].name, 1, sizeof(code->defs[i].name));
}
for (i = 0; i < vec_size(code->fields); ++i) {
util_endianswap(&code->fields[i].type, 1, sizeof(code->fields[i].type));
util_endianswap(&code->fields[i].offset, 1, sizeof(code->fields[i].offset));
util_endianswap(&code->fields[i].name, 1, sizeof(code->fields[i].name));
}
for (i = 0; i < vec_size(code->functions); ++i) {
util_endianswap(&code->functions[i].entry, 1, sizeof(code->functions[i].entry));
util_endianswap(&code->functions[i].firstlocal, 1, sizeof(code->functions[i].firstlocal));
util_endianswap(&code->functions[i].locals, 1, sizeof(code->functions[i].locals));
util_endianswap(&code->functions[i].profile, 1, sizeof(code->functions[i].profile));
util_endianswap(&code->functions[i].name, 1, sizeof(code->functions[i].name));
util_endianswap(&code->functions[i].file, 1, sizeof(code->functions[i].file));
util_endianswap(&code->functions[i].nargs, 1, sizeof(code->functions[i].nargs));
/* Don't swap argsize[] - it's just a byte array, which Quake uses only as such. */
}
util_endianswap(code->globals, vec_size(code->globals), sizeof(int32_t));
util_swap_statements (code->statements);
util_swap_defs_fields(code->defs);
util_swap_defs_fields(code->fields);
util_swap_functions (code->functions);
util_swap_globals (code->globals);
if (!OPTS_OPTION_BOOL(OPTION_QUIET)) {
if (lnofile)

8
exec.c
View file

@ -66,6 +66,8 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
return NULL;
}
util_swap_header(&header);
if (!skipversion && header.version != 6) {
loaderror("header says this is a version %i progs, we need version 6\n", header.version);
fs_file_close(file);
@ -114,6 +116,12 @@ qc_program_t* prog_load(const char *filename, bool skipversion)
read_data1(strings);
read_data2(globals, 2); /* reserve more in case a RETURN using with the global at "the end" exists */
util_swap_statements (prog->code);
util_swap_defs_fields(prog->defs);
util_swap_defs_fields(prog->fields);
util_swap_functions (prog->functions);
util_swap_globals (prog->globals);
fs_file_close(file);
/* profile counters */

View file

@ -627,6 +627,11 @@ enum {
/* TODO: elide */
extern const char *util_instr_str[VINSTR_END];
void util_swap_header (prog_header_t *code_header);
void util_swap_statements (prog_section_statement_t *statements);
void util_swap_defs_fields(prog_section_both_t *section);
void util_swap_functions (prog_section_function_t *functions);
void util_swap_globals (int32_t *globals);
typedef float qcfloat_t;
typedef int32_t qcint_t;

60
util.c
View file

@ -85,8 +85,8 @@ const char *util_instr_str[VINSTR_END] = {
d[l] = (v << 32) | (v >> 32);
}
*/
l *= 2;
size_t i;
l *= 2;
for (i = 0; i < l; i += 2) {
uint32_t v1 = d[i];
d[i] = d[i+1];
@ -129,6 +129,64 @@ void util_endianswap(void *_data, size_t count, unsigned int typesize) {
#endif
}
void util_swap_header (prog_header_t *code_header) {
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.offset, 1, sizeof(code_header->statements.offset));
util_endianswap(&code_header->statements.length, 1, sizeof(code_header->statements.length));
util_endianswap(&code_header->defs.offset, 1, sizeof(code_header->defs.offset));
util_endianswap(&code_header->defs.length, 1, sizeof(code_header->defs.length));
util_endianswap(&code_header->fields.offset, 1, sizeof(code_header->fields.offset));
util_endianswap(&code_header->fields.length, 1, sizeof(code_header->fields.length));
util_endianswap(&code_header->functions.offset, 1, sizeof(code_header->functions.offset));
util_endianswap(&code_header->functions.length, 1, sizeof(code_header->functions.length));
util_endianswap(&code_header->strings.offset, 1, sizeof(code_header->strings.offset));
util_endianswap(&code_header->strings.length, 1, sizeof(code_header->strings.length));
util_endianswap(&code_header->globals.offset, 1, sizeof(code_header->globals.offset));
util_endianswap(&code_header->globals.length, 1, sizeof(code_header->globals.length));
util_endianswap(&code_header->entfield, 1, sizeof(code_header->entfield));
}
void util_swap_statements (prog_section_statement_t *statements) {
size_t i;
for (i = 0; i < vec_size(statements); ++i) {
util_endianswap(&statements[i].opcode, 1, sizeof(statements[i].opcode));
util_endianswap(&statements[i].o1, 1, sizeof(statements[i].o1));
util_endianswap(&statements[i].o2, 1, sizeof(statements[i].o2));
util_endianswap(&statements[i].o3, 1, sizeof(statements[i].o3));
}
}
void util_swap_defs_fields (prog_section_both_t *section) {
size_t i;
for (i = 0; i < vec_size(section); ++i) {
util_endianswap(&section[i].type, 1, sizeof(section[i].type));
util_endianswap(&section[i].offset, 1, sizeof(section[i].offset));
util_endianswap(&section[i].name, 1, sizeof(section[i].name));
}
}
void util_swap_functions (prog_section_function_t* functions) {
size_t i;
for (i = 0; i < vec_size(functions); ++i) {
util_endianswap(&functions[i].entry, 1, sizeof(functions[i].entry));
util_endianswap(&functions[i].firstlocal, 1, sizeof(functions[i].firstlocal));
util_endianswap(&functions[i].locals, 1, sizeof(functions[i].locals));
util_endianswap(&functions[i].profile, 1, sizeof(functions[i].profile));
util_endianswap(&functions[i].name, 1, sizeof(functions[i].name));
util_endianswap(&functions[i].file, 1, sizeof(functions[i].file));
util_endianswap(&functions[i].nargs, 1, sizeof(functions[i].nargs));
/* Don't swap argsize[] - it's just a byte array, which Quake uses only as such. */
}
}
void util_swap_globals (int32_t * globals) {
util_endianswap(globals, vec_size(globals), sizeof(int32_t));
}
/*
* Based On:
* Slicing-by-8 algorithms by Michael E.