Write extended ddef information to progs far data

I was originally going to put it in the debug syms file, but I realized
that the data persistence code would need access to both def type and
certainly correct def offsets for defs in far data.
This commit is contained in:
Bill Currie 2020-02-22 14:11:15 +09:00
parent e7b4eedc07
commit 4df926e531
7 changed files with 98 additions and 5 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -423,6 +423,7 @@ finish_link (void)
&param_size);
linker_add_def (".param_alignment", &type_integer, flags,
&param_alignment);
linker_add_def (".xdefs", &type_xdefs, flags, 0);
}
if (options.code.debug) {

View File

@ -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);

View File

@ -109,5 +109,6 @@ int main (int argc, string *argv)
test_script ();
test_plist ();
test_types ();
test_xdefs ();
return 0;
};

View File

@ -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);
}
}