[qfcc] Ensure progs defs are sorted by address

This ensures they can be found by the progs debug support (since they do
a simple bsearch).
This commit is contained in:
Bill Currie 2023-09-12 22:26:30 +09:00
parent 3f93f6b226
commit 862b2669a5
6 changed files with 56 additions and 1 deletions

View file

@ -222,6 +222,8 @@ int defspace_alloc_aligned_highwater (defspace_t *space, int size,
*/
void defspace_reset (defspace_t *space);
void defspace_sort_defs (defspace_t *space);
///@}
#endif//__defspace_h

View file

@ -317,3 +317,33 @@ defspace_reset (defspace_t *space)
memset (space->data, 0, space->max_size * sizeof (pr_type_t));
}
}
void
defspace_sort_defs (defspace_t *space)
{
int num_defs = 0;
for (auto d = space->defs; d; d = d->next) {
num_defs++;
}
if (!num_defs) {
return;
}
def_t *defs[num_defs];
num_defs = 0;
for (auto d = space->defs; d; d = d->next) {
defs[num_defs++] = d;
}
for (int i = 1; i < num_defs; i++) {
auto d = defs[i];
for (int j = i; j-- > 0 && d->offset < defs[j]->offset; ) {
defs[j + 1] = defs[j];
defs[j] = d;
}
}
space->def_tail = &space->defs;
for (int i = 0; i < num_defs; i++) {
*space->def_tail = defs[i];
space->def_tail = &defs[i]->next;
}
*space->def_tail = 0;
}

View file

@ -790,6 +790,8 @@ build_code_function (symbol_t *fsym, expr_t *state_expr, expr_t *statements)
}
}
emit_function (func, statements);
defspace_sort_defs (func->parameters->space);
defspace_sort_defs (func->locals->space);
if (options.code.progsversion < PROG_VERSION) {
// stitch parameter and locals data together with parameters coming
// first

View file

@ -502,7 +502,7 @@ add_defs (qfo_t *qfo, qfo_mspace_t *space, qfo_mspace_t *dest_space,
odef->file = linker_add_string (QFOSTR (qfo, idef->file));
idef->file = -1; // mark def as copied
idef->line = num_work_defrefs; // so def can be found
// In the first passs, process_type_def sets the type meta to -1 and
// In the first pass, process_type_def sets the type meta to -1 and
// class to the offset of the copied type, but the null type encodiing
// is not modified. Other defs are processed in the second pass.
type = QFOTYPE(idef->type);
@ -1293,6 +1293,19 @@ check_defs (void)
free (undef_defs);
}
static void
sort_defs (qfo_mspace_t *space)
{
qfo_def_t *defs = space->defs;
for (pr_uint_t i = 1; i < space->num_defs; i++) {
qfo_def_t d = defs[i];
for (pr_uint_t j = i; j-- > 0 && d.offset < defs[j].offset; ) {
defs[j + 1] = defs[j];
defs[j] = d;
}
}
}
static qfo_t *
build_qfo (void)
{
@ -1305,6 +1318,9 @@ build_qfo (void)
qfo = qfo_new ();
qfo->spaces = calloc (work->num_spaces, sizeof (qfo_mspace_t));
qfo->num_spaces = work->num_spaces;
for (i = qfo_near_data_space; i <= qfo_entity_space; i++) {
sort_defs (&qfo->spaces[i]);
}
for (i = 0; i < work->num_spaces; i++) {
qfo->spaces[i].type = work->spaces[i].type;
qfo->spaces[i].id = work->spaces[i].id;

View file

@ -326,6 +326,10 @@ qfo_from_progs (pr_info_t *pr)
qfo_reloc_t *reloc;
reloc_t *r;
defspace_sort_defs (pr->near_data);
defspace_sort_defs (pr->far_data);
defspace_sort_defs (pr->entity_data);
qfo = calloc (1, sizeof (qfo_t));
qfo->num_spaces = qfo_num_spaces; // certain spaces are always present
qfo_count_stuff (qfo, pr);

View file

@ -63,6 +63,7 @@ __attribute__((const)) symbol_t *new_symbol_type (const char *name, type_t *type
__attribute__((const)) def_t *qfo_encode_type (type_t *type, defspace_t *space) {return 0;}
__attribute__((const)) int obj_types_assignable (const type_t *dst, const type_t *src) {return 0;}
void print_protocollist (struct dstring_s *dstr, protocollist_t *protocollist) {}
void defspace_sort_defs (defspace_t *space) {}
int is_id (const type_t *type){return type->type;}
int is_SEL (const type_t *type){return 0;}
int is_Class (const type_t *type){return 0;}