mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
Partial linking for a single qfo file now seems to work.
This commit is contained in:
parent
bfeece3255
commit
065d3e0dd7
1 changed files with 133 additions and 47 deletions
|
@ -957,63 +957,149 @@ undefined_def (qfo_def_t *def)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
check_defs (void)
|
||||
{
|
||||
defref_t **undef_defs, **defref;
|
||||
int did_self = 0, did_this = 0;
|
||||
|
||||
undef_defs = (defref_t **) Hash_GetList (extern_defs);
|
||||
for (defref = undef_defs; *defref; defref++) {
|
||||
qfo_def_t *def = REF (*defref);
|
||||
const char *name = WORKSTR (def->name);
|
||||
|
||||
if (strcmp (name, ".self") == 0 && !did_self) {
|
||||
defref_t *_d = Hash_Find (defined_defs, "self");
|
||||
if (_d) {
|
||||
qfo_def_t *d = REF (_d);
|
||||
if (QFO_TYPEMETA (work, d->type) == ty_none
|
||||
&& QFO_TYPETYPE (work, d->type) == ev_entity)
|
||||
def_warning (d, "@self and self used together");
|
||||
}
|
||||
define_def (&work->spaces[qfo_near_data_space], ".self",
|
||||
&type_entity, QFOD_GLOBAL, 0);
|
||||
did_self = 1;
|
||||
} else if (strcmp (name, ".this") == 0 && !did_this) {
|
||||
pointer_t offset;
|
||||
type_t *type;
|
||||
int flags;
|
||||
|
||||
if (!class_Class.super_class)
|
||||
class_init ();
|
||||
type = field_type (&type_ClassPtr);
|
||||
offset = defspace_alloc_loc (work_entity_data, 1);
|
||||
flags = (QFOD_GLOBAL | QFOD_CONSTANT
|
||||
| QFOD_INITIALIZED | QFOD_NOSAVE);
|
||||
define_def (&work->spaces[qfo_near_data_space], ".this",
|
||||
type, flags, offset);
|
||||
did_this = 1;
|
||||
}
|
||||
}
|
||||
free (undef_defs);
|
||||
undef_defs = (defref_t **) Hash_GetList (extern_defs);
|
||||
for (defref = undef_defs; *defref; defref++) {
|
||||
qfo_def_t *def = REF (*defref);
|
||||
undefined_def (def);
|
||||
}
|
||||
free (undef_defs);
|
||||
}
|
||||
|
||||
static qfo_t *
|
||||
build_qfo (void)
|
||||
{
|
||||
qfo_t *qfo;
|
||||
int size;
|
||||
int i;
|
||||
qfo_mspace_t *space;
|
||||
qfo_reloc_t *reloc;
|
||||
qfo_def_t **defs;
|
||||
|
||||
qfo = qfo_new ();
|
||||
qfo->spaces = calloc (work->num_spaces, sizeof (qfo_mspace_t));
|
||||
qfo->num_spaces = work->num_spaces;
|
||||
for (i = 0; i < work->num_spaces; i++) {
|
||||
space = &work->spaces[i];
|
||||
qfo->spaces[i].type = work->spaces[i].type;
|
||||
qfo->spaces[i].id = work->spaces[i].id;
|
||||
qfo->spaces[i].d = work->spaces[i].d;
|
||||
qfo->spaces[i].data_size = work->spaces[i].data_size;
|
||||
}
|
||||
// allocate space for all relocs and copy in the loose relocs. bound
|
||||
// relocs will be handled with defs and funcs.
|
||||
size = work->num_relocs + work_num_loose_relocs;
|
||||
qfo->relocs = malloc (size * sizeof (qfo_reloc_t));
|
||||
reloc = qfo->relocs;
|
||||
memcpy (qfo->relocs + work->num_relocs, work_loose_relocs,
|
||||
work_num_loose_relocs * sizeof (qfo_reloc_t));
|
||||
qfo->num_relocs = size;
|
||||
qfo->num_loose_relocs = work_num_loose_relocs;
|
||||
qfo->funcs = work->funcs;
|
||||
qfo->num_funcs = work->num_funcs;
|
||||
qfo->lines = work->lines;
|
||||
qfo->num_lines = work->num_lines;
|
||||
// count final defs
|
||||
for (i = 0; i < num_work_defrefs; i++) {
|
||||
if (work_defrefs[i]->merge)
|
||||
continue;
|
||||
qfo->num_defs++;
|
||||
qfo->spaces[work_defrefs[i]->space].num_defs++;
|
||||
}
|
||||
qfo->defs = malloc (qfo->num_defs * sizeof (qfo_def_t));
|
||||
defs = alloca (qfo->num_spaces * sizeof (qfo_def_t *));
|
||||
defs[0] = qfo->defs;
|
||||
for (i = 1; i < qfo->num_spaces; i++) {
|
||||
defs[i] = defs[i - 1] + qfo->spaces[i - 1].num_defs;
|
||||
if (qfo->spaces[i].num_defs)
|
||||
qfo->spaces[i].defs = defs[i];
|
||||
}
|
||||
for (i = 0; i < num_work_defrefs; i++) {
|
||||
defref_t *r = work_defrefs[i];
|
||||
qfo_def_t d;
|
||||
int space;
|
||||
if (r->merge)
|
||||
continue;
|
||||
space = r->space;
|
||||
d = *REF (r);
|
||||
d.relocs = reloc - qfo->relocs;
|
||||
memcpy (reloc, work->relocs + REF (r)->relocs,
|
||||
REF (r)->num_relocs * sizeof (qfo_reloc_t));
|
||||
reloc += REF (r)->num_relocs;
|
||||
r->def_list = &qfo->spaces[space].defs;
|
||||
r->def = defs[space] - qfo->defs;
|
||||
// copy relocs from merged defs
|
||||
for (r = r->merge_list; r; r = r->next) {
|
||||
memcpy (reloc, work->relocs + REF (r)->relocs,
|
||||
REF (r)->num_relocs * sizeof (qfo_reloc_t));
|
||||
reloc += REF (r)->num_relocs;
|
||||
d.num_relocs += REF (r)->num_relocs;
|
||||
r->def_list = &qfo->spaces[space].defs;
|
||||
r->space = space;
|
||||
r->def = defs[space] - qfo->defs;
|
||||
}
|
||||
*defs[space]++ = d;
|
||||
}
|
||||
for (i = 0; i < qfo->num_funcs; i++) {
|
||||
qfo_func_t *f = &qfo->funcs[i];
|
||||
f->def = work_defrefs[f->def]->def;
|
||||
memcpy (reloc, work->relocs + f->relocs,
|
||||
f->num_relocs * sizeof (qfo_reloc_t));
|
||||
reloc += f->num_relocs;
|
||||
}
|
||||
return qfo;
|
||||
}
|
||||
|
||||
qfo_t *
|
||||
linker_finish (void)
|
||||
{
|
||||
defref_t **undef_defs, **defref;
|
||||
qfo_t *qfo;
|
||||
|
||||
if (!options.partial_link) {
|
||||
int did_self = 0, did_this = 0;
|
||||
|
||||
undef_defs = (defref_t **) Hash_GetList (extern_defs);
|
||||
for (defref = undef_defs; *defref; defref++) {
|
||||
qfo_def_t *def = REF (*defref);
|
||||
const char *name = WORKSTR (def->name);
|
||||
|
||||
if (strcmp (name, ".self") == 0 && !did_self) {
|
||||
defref_t *_d = Hash_Find (defined_defs, "self");
|
||||
if (_d) {
|
||||
qfo_def_t *d = REF (_d);
|
||||
if (QFO_TYPEMETA (work, d->type) == ty_none
|
||||
&& QFO_TYPETYPE (work, d->type) == ev_entity)
|
||||
def_warning (d, "@self and self used together");
|
||||
}
|
||||
define_def (&work->spaces[qfo_near_data_space], ".self",
|
||||
&type_entity, QFOD_GLOBAL, 0);
|
||||
did_self = 1;
|
||||
} else if (strcmp (name, ".this") == 0 && !did_this) {
|
||||
pointer_t offset;
|
||||
type_t *type;
|
||||
int flags;
|
||||
|
||||
if (!class_Class.super_class)
|
||||
class_init ();
|
||||
type = field_type (&type_ClassPtr);
|
||||
offset = defspace_alloc_loc (work_entity_data, 1);
|
||||
flags = (QFOD_GLOBAL | QFOD_CONSTANT
|
||||
| QFOD_INITIALIZED | QFOD_NOSAVE);
|
||||
define_def (&work->spaces[qfo_near_data_space], ".this",
|
||||
type, flags, offset);
|
||||
did_this = 1;
|
||||
}
|
||||
}
|
||||
free (undef_defs);
|
||||
undef_defs = (defref_t **) Hash_GetList (extern_defs);
|
||||
for (defref = undef_defs; *defref; defref++) {
|
||||
qfo_def_t *def = REF (*defref);
|
||||
undefined_def (def);
|
||||
}
|
||||
free (undef_defs);
|
||||
check_defs ();
|
||||
if (pr.error_count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//fixup_relocs ();
|
||||
|
||||
qfo = qfo_new ();
|
||||
|
||||
return work;
|
||||
return build_qfo ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue