mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[qfcc] Ensure progs defs are sorted by address
This commit is contained in:
parent
2f9f6d3aa9
commit
9a08a51ebd
1 changed files with 46 additions and 4 deletions
|
@ -31,6 +31,8 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE // for qsort_r
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
@ -860,6 +862,17 @@ align_globals_size (unsigned size)
|
|||
return RUP (size, 16 / sizeof (pr_type_t));
|
||||
}
|
||||
|
||||
static int
|
||||
qfo_def_compare (const void *i1, const void *i2, void *d)
|
||||
{
|
||||
__auto_type defs = (const qfo_def_t *) d;
|
||||
unsigned ind1 = *(unsigned *) i1;
|
||||
unsigned ind2 = *(unsigned *) i2;
|
||||
const qfo_def_t *def1 = defs + ind1;
|
||||
const qfo_def_t *def2 = defs + ind2;
|
||||
return def1->offset - def2->offset;
|
||||
}
|
||||
|
||||
dprograms_t *
|
||||
qfo_to_progs (qfo_t *qfo, int *size)
|
||||
{
|
||||
|
@ -887,6 +900,9 @@ qfo_to_progs (qfo_t *qfo, int *size)
|
|||
int big_func = 0;
|
||||
pr_xdefs_t *xdefs = 0;
|
||||
xdef_t *xdef;
|
||||
unsigned *def_indices;
|
||||
unsigned *far_def_indices;
|
||||
unsigned *field_def_indices;
|
||||
|
||||
*size = RUP (sizeof (dprograms_t), 16);
|
||||
progs = calloc (1, *size);
|
||||
|
@ -895,7 +911,7 @@ qfo_to_progs (qfo_t *qfo, int *size)
|
|||
progs->numglobaldefs = qfo->spaces[qfo_near_data_space].num_defs;
|
||||
//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
|
||||
//.xdefs array in the progs file
|
||||
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;
|
||||
|
@ -936,6 +952,29 @@ qfo_to_progs (qfo_t *qfo, int *size)
|
|||
memset (progs + 1, 0, *size - sizeof (dprograms_t));
|
||||
data += RUP (sizeof (dprograms_t), 16);
|
||||
|
||||
def_indices = alloca ((progs->numglobaldefs + progs->numfielddefs)
|
||||
* sizeof (*def_indices));
|
||||
far_def_indices = def_indices + qfo->spaces[qfo_near_data_space].num_defs;
|
||||
field_def_indices = def_indices + progs->numglobaldefs;
|
||||
for (unsigned i = 0; i < qfo->spaces[qfo_near_data_space].num_defs; i++) {
|
||||
def_indices[i] = i;
|
||||
}
|
||||
for (unsigned i = 0; i < qfo->spaces[qfo_far_data_space].num_defs; i++) {
|
||||
far_def_indices[i] = i;
|
||||
}
|
||||
for (unsigned i = 0; i < qfo->spaces[qfo_entity_space].num_defs; i++) {
|
||||
field_def_indices[i] = i;
|
||||
}
|
||||
qsort_r (def_indices, qfo->spaces[qfo_near_data_space].num_defs,
|
||||
sizeof (unsigned), qfo_def_compare,
|
||||
qfo->spaces[qfo_near_data_space].defs);
|
||||
qsort_r (far_def_indices, qfo->spaces[qfo_far_data_space].num_defs,
|
||||
sizeof (unsigned), qfo_def_compare,
|
||||
qfo->spaces[qfo_far_data_space].defs);
|
||||
qsort_r (field_def_indices, qfo->spaces[qfo_entity_space].num_defs,
|
||||
sizeof (unsigned), qfo_def_compare,
|
||||
qfo->spaces[qfo_entity_space].defs);
|
||||
|
||||
progs->ofs_strings = data - (byte *) progs;
|
||||
strings = (char *) data;
|
||||
data += RUP (progs->numstrings * sizeof (char), 16);
|
||||
|
@ -992,7 +1031,8 @@ qfo_to_progs (qfo_t *qfo, int *size)
|
|||
}
|
||||
|
||||
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;
|
||||
unsigned ind = def_indices[i];
|
||||
qfo_def_t *def = qfo->spaces[qfo_near_data_space].defs + ind;
|
||||
const char *defname = QFO_GETSTR (qfo, def->name);
|
||||
if (!strcmp (defname, ".type_encodings"))
|
||||
types_def = def;
|
||||
|
@ -1002,7 +1042,8 @@ qfo_to_progs (qfo_t *qfo, int *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;
|
||||
unsigned ind = far_def_indices[i];
|
||||
qfo_def_t *def = qfo->spaces[qfo_far_data_space].defs + ind;
|
||||
def->offset += far_data - globals;
|
||||
convert_def (qfo, def, globaldefs);
|
||||
// the correct offset will be written to the far data space
|
||||
|
@ -1015,7 +1056,8 @@ qfo_to_progs (qfo_t *qfo, int *size)
|
|||
}
|
||||
|
||||
for (i = 0; i < qfo->spaces[qfo_entity_space].num_defs; i++) {
|
||||
convert_def (qfo, qfo->spaces[qfo_entity_space].defs + i,
|
||||
unsigned ind = field_def_indices[i];
|
||||
convert_def (qfo, qfo->spaces[qfo_entity_space].defs + ind,
|
||||
fielddefs + i);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue