def merging seems to mostly work (have some problems with method lists)

This commit is contained in:
Bill Currie 2002-07-16 06:40:34 +00:00
parent 4d214bfea1
commit 17c2def821
3 changed files with 107 additions and 17 deletions

View file

@ -73,7 +73,7 @@ static defspace_t *data;
static defspace_t *far_data;
static strpool_t *strings;
static strpool_t *type_strings;
static relocgroup_t relocs;
static relocgroup_t relocs, final_relocs;
static defgroup_t global_defs, local_defs, defs;
static funcgroup_t funcs;
static struct {
@ -172,6 +172,7 @@ process_def (qfo_def_t *def)
if ((d = Hash_Find (defined_defs, strings->strings + def->name))) {
def->ofs = d->ofs;
def->flags = d->flags;
Hash_Add (defined_defs, def);
} else {
Hash_Add (extern_defs, def);
}
@ -307,10 +308,11 @@ fixup_relocs ()
{
qfo_reloc_t *reloc;
qfo_def_t *def;
qfo_func_t *func;
int i;
for (reloc = relocs.relocs;
reloc - relocs.relocs < relocs.num_relocs;
reloc++) {
for (i = 0; i < final_relocs.num_relocs; i++) {
reloc = final_relocs.relocs + i;
def = 0;
switch ((reloc_type)reloc->type) {
case rel_none:
@ -362,26 +364,105 @@ fixup_relocs ()
break;
}
}
for (i = 0; i < defs.num_defs; i++) {
def = defs.defs + i;
if (def->basic_type == ev_func
&& (def->flags & QFOD_INITIALIZED)
&& !(def->flags & (QFOD_LOCAL | QFOD_EXTERNAL | QFOD_ABSOLUTE))) {
func = funcs.funcs + data->data[def->ofs].func_var - 1;
func->def = i;
}
}
}
static void
merge_defgroups (void)
{
int local_base, i, j;
qfo_def_t *def;
qfo_def_t *def, *d;
qfo_func_t *func;
defgroup_add_defs (&defs, global_defs.defs, global_defs.num_defs);
for (i = 0; i < global_defs.num_defs; i++) {
int def_num = defs.num_defs;
const char *name;
def = global_defs.defs + i;
name = strings->strings + def->name;
if ((d = Hash_Del (defined_defs, name))) {
defgroup_add_defs (&defs, d, 1);
def = defs.defs + def_num;
def->relocs = final_relocs.num_relocs;
relocgroup_add_relocs (&final_relocs, relocs.relocs + d->relocs,
d->num_relocs);
for (j = 0; j < d->num_relocs; j++)
relocs.relocs[d->relocs + j].type = rel_none;
while ((d = Hash_Del (defined_defs,
strings->strings + def->name))) {
relocgroup_add_relocs (&final_relocs, relocs.relocs + d->relocs,
d->num_relocs);
def->num_relocs += d->num_relocs;
for (j = 0; j < d->num_relocs; j++)
relocs.relocs[d->relocs + j].type = rel_none;
}
} else if ((d = Hash_Del (extern_defs, name))) {
defgroup_add_defs (&defs, d, 1);
def = defs.defs + def_num;
def->relocs = final_relocs.num_relocs;
relocgroup_add_relocs (&final_relocs, relocs.relocs + d->relocs,
d->num_relocs);
for (j = 0; j < d->num_relocs; j++)
relocs.relocs[d->relocs + j].type = rel_none;
while ((d = Hash_Del (extern_defs,
strings->strings + def->name))) {
relocgroup_add_relocs (&final_relocs, relocs.relocs + d->relocs,
d->num_relocs);
def->num_relocs += d->num_relocs;
for (j = 0; j < d->num_relocs; j++)
relocs.relocs[d->relocs + j].type = rel_none;
}
} else if (!(def->flags & (QFOD_GLOBAL | QFOD_EXTERNAL))) {
d = def;
defgroup_add_defs (&defs, d, 1);
def = defs.defs + def_num;
def->relocs = final_relocs.num_relocs;
relocgroup_add_relocs (&final_relocs, relocs.relocs + d->relocs,
d->num_relocs);
for (j = 0; j < d->num_relocs; j++)
relocs.relocs[d->relocs + j].type = rel_none;
}
for (j = 0; j < def->num_relocs; j++)
final_relocs.relocs[def->relocs + j].def = def_num;
}
local_base = defs.num_defs;
defgroup_add_defs (&defs, local_defs.defs, local_defs.num_defs);
for (i = 0; i < local_defs.num_defs; i++) {
int r = final_relocs.num_relocs;
def = local_defs.defs + i;
for (j = def->relocs; j < def->relocs + def->num_relocs; j++)
relocs.relocs[j].def += local_base;
defgroup_add_defs (&defs, def, 1);
def = defs.defs + defs.num_defs - 1;
relocgroup_add_relocs (&final_relocs, relocs.relocs + def->relocs,
def->num_relocs);
for (j = 0; j < def->num_relocs; j++) {
relocs.relocs[def->relocs + j].type = rel_none;
final_relocs.relocs[r + j].def += local_base;
}
def->relocs = r;
}
for (i = 0; i < funcs.num_funcs; i++) {
int r = final_relocs.num_relocs;
func = funcs.funcs + i;
func->local_defs += local_base;
relocgroup_add_relocs (&final_relocs, relocs.relocs + func->relocs,
func->num_relocs);
for (j = 0; j < func->num_relocs; j++)
relocs.relocs[func->relocs + j].type = rel_none;
func->relocs = r;
}
for (i = 0; i < relocs.num_relocs; i = j) {
j = i;
while (j < relocs.num_relocs && relocs.relocs[j].type != rel_none)
j++;
relocgroup_add_relocs (&final_relocs, relocs.relocs + i, j - i);
while (j < relocs.num_relocs && relocs.relocs[j].type == rel_none)
j++;
}
}
@ -399,7 +480,7 @@ define_def (const char *name, etype_t basic_type, const char *full_type)
d.flags = QFOD_GLOBAL;
defspace_adddata (data, &val, 1);
defgroup_add_defs (&global_defs, &d, 1);
process_def (&d);
process_def (global_defs.defs + global_defs.num_defs - 1);
}
void
@ -490,7 +571,7 @@ linker_finish (void)
qfo_add_data (qfo, data->data, data->size);
qfo_add_far_data (qfo, far_data->data, far_data->size);
qfo_add_strings (qfo, strings->strings, strings->size);
qfo_add_relocs (qfo, relocs.relocs, relocs.num_relocs);
qfo_add_relocs (qfo, final_relocs.relocs, final_relocs.num_relocs);
qfo_add_defs (qfo, defs.defs, defs.num_defs);
qfo_add_funcs (qfo, funcs.funcs, funcs.num_funcs);
qfo_add_lines (qfo, lines.lines, lines.num_lines);

View file

@ -224,6 +224,14 @@ setup_data (void)
}
}
static void
round_strings (strpool_t *strings)
{
memset (strings->strings + strings->size, 0,
strings->max_size - strings->size);
strings->size = RUP (strings->size, 4);
}
qfo_t *
qfo_from_progs (pr_info_t *pr)
{
@ -233,8 +241,8 @@ qfo_from_progs (pr_info_t *pr)
allocate_stuff ();
setup_data ();
pr->strings->size = RUP (pr->strings->size, 4);
types->size = RUP (types->size, 4);
round_strings (pr->strings);
round_strings (types);
qfo = qfo_new ();
qfo_add_code (qfo, pr->code->code, pr->code->size);
@ -475,7 +483,7 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr)
*pr->scope->tail = pd;
pr->scope->tail = &pd->def_next;
pd->type = parse_type (qfo->types + qd->full_type);
pd->name = qfo->strings + qd->name;
pd->name = qd->name ? qfo->strings + qd->name : 0;
pd->ofs = qd->ofs;
if (qd->num_relocs) {
pd->refs = relocs + qd->relocs;

View file

@ -79,7 +79,8 @@ dump_defs (qfo_t *qfo)
qfo_func_t *func;
for (def = qfo->defs; def - qfo->defs < qfo->num_defs; def++) {
printf ("%4d %4x %d %s %s %d %d %s:%d\n",
printf ("%5d %4d %4x %d %s %s %d %d %s:%d\n",
def - qfo->defs,
def->ofs,
def->flags,
def->basic_type,
@ -117,7 +118,7 @@ dump_funcs (qfo_t *qfo)
for (i = 0; i < qfo->num_funcs; i++) {
func = qfo->funcs + i;
printf ("%s %s:%d %d?%d %d %d,%d\n",
printf ("%5d %s %s:%d %d?%d %d %d,%d\n", i,
str + func->name, str + func->file, func->line,
func->builtin, func->code, func->def,
func->relocs, func->num_relocs);
@ -146,7 +147,7 @@ dump_relocs (qfo_t *qfo)
for (i = 0; i < qfo->num_relocs; i++) {
reloc = qfo->relocs + i;
printf ("%5d %-10s %d\n", reloc->ofs, reloc_names[reloc->type],
printf ("%5d %5d %-10s %d\n", i, reloc->ofs, reloc_names[reloc->type],
reloc->def);
}
}