diff --git a/include/QF/pr_comp.h b/include/QF/pr_comp.h index 185a802ad..6b39ff1bc 100644 --- a/include/QF/pr_comp.h +++ b/include/QF/pr_comp.h @@ -423,6 +423,16 @@ typedef struct ddef_s { pr_int_t s_name; } ddef_t; +typedef struct xdef_s { + pointer_t type; ///< pointer to type definition + pointer_t ofs; ///< 32-bit version of ddef_t.ofs +} xdef_t; + +typedef struct pr_xdefs_s { + pointer_t xdefs; + pr_int_t num_xdefs; +} pr_xdefs_t; + typedef struct dparmsize_s { uint8_t size:5; uint8_t alignment:3; diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 784ed6f9a..c8913933e 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -116,6 +116,9 @@ extern type_t type_va_list; extern type_t type_param; extern type_t type_zero; extern type_t type_type_encodings; +extern type_t type_xdef; +extern type_t type_xdef_pointer; +extern type_t type_xdefs; extern struct symtab_s *vector_struct; extern struct symtab_s *quaternion_struct; diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index d4db18377..79c4effeb 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -879,12 +879,16 @@ qfo_to_progs (qfo_t *qfo, int *size) pr_type_t *locals; pr_type_t *far_data; pr_type_t *type_data; + pr_type_t *xdef_data; dprograms_t *progs; qfo_def_t *types_def = 0; + qfo_def_t *xdefs_def = 0; unsigned i, j; unsigned near_data_size = 0; unsigned locals_size = 0; int locals_start; + int type_encodings_start; + int xdefs_start; unsigned big_locals = 0; int big_func = 0; @@ -893,7 +897,9 @@ qfo_to_progs (qfo_t *qfo, int *size) progs->version = options.code.progsversion; progs->numstatements = qfo->spaces[qfo_code_space].data_size; progs->numglobaldefs = qfo->spaces[qfo_near_data_space].num_defs; - //FIXME ddef offsets are 16 bits + //ddef offsets are 16 bits so the ddef ofs will likely be invalid + //thus it will be forced invalid and the true offset written to the + //symbols file if it is created (fa progs->numglobaldefs += qfo->spaces[qfo_far_data_space].num_defs; progs->numfielddefs = qfo->spaces[qfo_entity_space].num_defs; progs->numfunctions = qfo->num_funcs + 1; @@ -915,7 +921,11 @@ qfo_to_progs (qfo_t *qfo, int *size) near_data_size = progs->numglobals; progs->numglobals = RUP (progs->numglobals, 16 / sizeof (pr_type_t)); progs->numglobals += qfo->spaces[qfo_far_data_space].data_size; + type_encodings_start = progs->numglobals; progs->numglobals += qfo->spaces[qfo_type_space].data_size; + progs->numglobals = RUP (progs->numglobals, type_xdef.alignment); + xdefs_start = progs->numglobals; + progs->numglobals += progs->numglobaldefs * type_size (&type_xdef); progs->entityfields = qfo->spaces[qfo_entity_space].data_size; *size += progs->numstatements * sizeof (dstatement_t); *size += progs->numglobaldefs * sizeof (ddef_t); @@ -954,7 +964,8 @@ qfo_to_progs (qfo_t *qfo, int *size) globals = (pr_type_t*) data; locals = globals + locals_start; far_data = globals + near_data_size; - type_data = far_data + qfo->spaces[qfo_far_data_space].data_size; + type_data = globals + type_encodings_start; + xdef_data = globals + xdefs_start; memcpy (strings, qfo->spaces[qfo_strings_space].d.strings, qfo->spaces[qfo_strings_space].data_size * sizeof (char)); @@ -987,14 +998,18 @@ qfo_to_progs (qfo_t *qfo, int *size) qfo_def_t *def = qfo->spaces[qfo_near_data_space].defs + i; if (!strcmp (QFO_GETSTR (qfo, def->name), ".type_encodings")) types_def = def; + if (!strcmp (QFO_GETSTR (qfo, def->name), ".xdefs")) + xdefs_def = def; convert_def (qfo, def, globaldefs++); } - //FIXME ddef offsets are 16 bits for (i = 0; i < qfo->spaces[qfo_far_data_space].num_defs; i++) { qfo_def_t *def = qfo->spaces[qfo_far_data_space].defs + i; def->offset += far_data - globals; - convert_def (qfo, def, globaldefs++); + convert_def (qfo, def, globaldefs); + // the correct offset will be written to the far data space + globaldefs->ofs = -1; + globaldefs++; } for (i = 0; i < qfo->spaces[qfo_type_space].num_defs; i++) { @@ -1025,9 +1040,27 @@ qfo_to_progs (qfo_t *qfo, int *size) if (types_def) { qfot_type_encodings_t *encodings; encodings = (qfot_type_encodings_t *) &globals[types_def->offset]; - encodings->types = type_data - globals; + encodings->types = type_encodings_start; encodings->size = qfo->spaces[qfo_type_space].data_size; } + if (xdefs_def) { + int xdef_data_size = type_size (&type_xdef); + pr_xdefs_t *xdefs = (pr_xdefs_t *) &globals[xdefs_def->offset]; + xdefs->xdefs = xdefs_start; + xdefs->num_xdefs = progs->numglobaldefs; + for (i = 0; i < qfo->spaces[qfo_near_data_space].num_defs; i++) { + qfo_def_t *def = qfo->spaces[qfo_near_data_space].defs + i; + xdef_data[0].pointer_var = def->type + type_encodings_start; + xdef_data[1].pointer_var = def->offset; + xdef_data += xdef_data_size; + } + for (i = 0; i < qfo->spaces[qfo_far_data_space].num_defs; i++) { + qfo_def_t *def = qfo->spaces[qfo_far_data_space].defs + i; + xdef_data[0].pointer_var = def->type + type_encodings_start; + xdef_data[1].pointer_var = def->offset; + xdef_data += xdef_data_size; + } + } // undo the relocation of the offsets of local defs so the local defs have // the correct offset in the debug info diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 780db073a..9e292d136 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -423,6 +423,7 @@ finish_link (void) ¶m_size); linker_add_def (".param_alignment", &type_integer, flags, ¶m_alignment); + linker_add_def (".xdefs", &type_xdefs, flags, 0); } if (options.code.debug) { diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index e33f0ec34..04c8d7442 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -89,6 +89,9 @@ type_t type_param = { ev_invalid, 0, 0, ty_struct }; type_t type_zero = { ev_invalid, 0, 0, ty_struct }; type_t type_type_encodings = { ev_invalid, "@type_encodings", 0, ty_struct }; +type_t type_xdef = { ev_invalid, "@xdef", 0, ty_struct }; +type_t type_xdef_pointer = { ev_pointer, 0, 1, ty_basic, {{&type_xdef}} }; +type_t type_xdefs = { ev_invalid, "@xdefs", 0, ty_struct }; type_t type_floatfield = { ev_field, ".float", 1, ty_basic, {{&type_float}} }; @@ -1045,6 +1048,16 @@ init_types (void) {"size", &type_integer}, {0, 0} }; + static struct_def_t xdef_struct[] = { + {"types", &type_pointer}, + {"offset", &type_pointer}, + {0, 0} + }; + static struct_def_t xdefs_struct[] = { + {"xdefs", &type_xdef_pointer}, + {"num_xdefs", &type_pointer}, + {0, 0} + }; type_nil = &type_quaternion; type_default = &type_integer; @@ -1066,6 +1079,8 @@ init_types (void) make_structure ("@type_encodings", 's', type_encoding_struct, &type_type_encodings); + make_structure ("@xdef", 's', xdef_struct, &type_xdef); + make_structure ("@xdefs", 's', xdefs_struct, &type_xdefs); if (options.traditional) return; @@ -1120,6 +1135,9 @@ chain_initial_types (void) chain_type (&type_param); chain_type (&type_zero); chain_type (&type_type_encodings); + chain_type (&type_xdef); + chain_type (&type_xdef_pointer); + chain_type (&type_xdefs); va_list_struct[1].type = pointer_type (&type_param); make_structure ("@va_list", 's', va_list_struct, &type_va_list); diff --git a/tools/qwaq/main.qc b/tools/qwaq/main.qc index 1014c1f4d..25cfaabdb 100644 --- a/tools/qwaq/main.qc +++ b/tools/qwaq/main.qc @@ -109,5 +109,6 @@ int main (int argc, string *argv) test_script (); test_plist (); test_types (); + test_xdefs (); return 0; }; diff --git a/tools/qwaq/types.r b/tools/qwaq/types.r index 324185b93..5cf874c61 100644 --- a/tools/qwaq/types.r +++ b/tools/qwaq/types.r @@ -77,6 +77,16 @@ typedef struct qfot_type_encodings_s { int size; } qfot_type_encodings_t; +typedef struct xdef_s { + qfot_type_t *type; + void *offset; +} xdef_t; + +typedef struct pr_xdefs_s { + xdef_t *xdefs; + int num_xdefs; +} pr_xdefs_t; + qfot_type_t * next_type (qfot_type_t *type) { @@ -174,3 +184,20 @@ test_types (void) } } } + +void +test_xdefs (void) +{ + pr_xdefs_t *xdefs; + int i; + + xdefs = PR_FindGlobal (".xdefs"); + if (!xdefs) { + printf ("Can't find xdefs\n"); + return; + } + printf ("%p %i\n", xdefs.xdefs, xdefs.num_xdefs); + for (i = 0; i < xdefs.num_xdefs; i++) { + printf ("%p %p\n", xdefs.xdefs[i].type, xdefs.xdefs[i].offset); + } +}