mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
Write the linker output to progs.dat.
There is much breakage, but qfcc now produces a progs.dat from either progs.src or object files. Better yet, the progs.src result is passed through the linker, removing much duplicate code.
This commit is contained in:
parent
29985efcef
commit
4a99f8dcbd
6 changed files with 147 additions and 348 deletions
|
@ -32,11 +32,13 @@
|
|||
#ifndef __idstuff_h
|
||||
#define __idstuff_h
|
||||
|
||||
#include "QF/pr_comp.h"
|
||||
|
||||
//XXX eww :/
|
||||
void PrecacheSound (const char *, int ch);
|
||||
void PrecacheModel (const char *, int ch);
|
||||
void PrecacheFile (const char *, int ch);
|
||||
int WriteFiles (const char *sourcedir);
|
||||
int WriteProgdefs (const char *filename);
|
||||
int WriteProgdefs (dprograms_t *progs, const char *filename);
|
||||
|
||||
#endif//__idstuff_h
|
||||
|
|
|
@ -461,7 +461,7 @@ qfo_t *qfo_read (QFile *file);
|
|||
*/
|
||||
qfo_t *qfo_open (const char *filename);
|
||||
|
||||
dprograms_t *qfo_to_progs (qfo_t *qfo);
|
||||
dprograms_t *qfo_to_progs (qfo_t *qfo, int *size);
|
||||
|
||||
/** Create a new ::qfo_t struct
|
||||
\return pointer to new ::qfo_t struct, or 0 on error.
|
||||
|
|
|
@ -193,12 +193,15 @@ WriteFiles (const char *sourcedir)
|
|||
at load time.
|
||||
*/
|
||||
int
|
||||
WriteProgdefs (const char *filename)
|
||||
WriteProgdefs (dprograms_t *progs, const char *filename)
|
||||
{
|
||||
def_t *d;
|
||||
ddef_t *d;
|
||||
FILE *f;
|
||||
unsigned short crc;
|
||||
int c;
|
||||
unsigned i;
|
||||
const char *strings;
|
||||
const char *name;
|
||||
|
||||
if (options.verbosity >= 1)
|
||||
printf ("writing %s\n", filename);
|
||||
|
@ -209,35 +212,38 @@ WriteProgdefs (const char *filename)
|
|||
"\n\ntypedef struct\n{\tint\tpad[%i];\n",
|
||||
RESERVED_OFS);
|
||||
|
||||
for (d = pr.near_data->defs; d; d = d->next) {
|
||||
if (d->name && !strcmp (d->name, "end_sys_globals"))
|
||||
strings = (char *) progs + progs->ofs_strings;
|
||||
for (i = 0; i < progs->numglobaldefs; i++) {
|
||||
d = (ddef_t *) ((char *) progs + progs->ofs_globaldefs) + i;
|
||||
name = strings + d->s_name;
|
||||
if (!strcmp (name, "end_sys_globals"))
|
||||
break;
|
||||
if (!d->offset)
|
||||
if (!d->ofs)
|
||||
continue;
|
||||
if (!d->name || *d->name == '.' || !*d->name)
|
||||
if (*name == '.' || !*name)
|
||||
continue;
|
||||
|
||||
switch (d->type->type) {
|
||||
switch (d->type) {
|
||||
case ev_float:
|
||||
fprintf (f, "\tfloat\t%s;\n", d->name);
|
||||
fprintf (f, "\tfloat\t%s;\n", name);
|
||||
break;
|
||||
case ev_vector:
|
||||
fprintf (f, "\tvec3_t\t%s;\n", d->name);
|
||||
fprintf (f, "\tvec3_t\t%s;\n", name);
|
||||
break;
|
||||
case ev_quat:
|
||||
fprintf (f, "\tquat_t\t%s;\n", d->name);
|
||||
fprintf (f, "\tquat_t\t%s;\n", name);
|
||||
break;
|
||||
case ev_string:
|
||||
fprintf (f, "\tstring_t\t%s;\n", d->name);
|
||||
fprintf (f, "\tstring_t\t%s;\n", name);
|
||||
break;
|
||||
case ev_func:
|
||||
fprintf (f, "\tfunc_t\t%s;\n", d->name);
|
||||
fprintf (f, "\tfunc_t\t%s;\n", name);
|
||||
break;
|
||||
case ev_entity:
|
||||
fprintf (f, "\tint\t%s;\n", d->name);
|
||||
fprintf (f, "\tint\t%s;\n", name);
|
||||
break;
|
||||
default:
|
||||
fprintf (f, "\tint\t%s;\n", d->name);
|
||||
fprintf (f, "\tint\t%s;\n", name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -245,31 +251,33 @@ WriteProgdefs (const char *filename)
|
|||
|
||||
// print all fields
|
||||
fprintf (f, "typedef struct\n{\n");
|
||||
for (d = pr.near_data->defs; d; d = d->next) {
|
||||
if (d->name && !strcmp (d->name, "end_sys_fields"))
|
||||
for (i = 0; i < progs->numglobaldefs; i++) {
|
||||
d = (ddef_t *) ((char *) progs + progs->ofs_fielddefs) + i;
|
||||
name = strings + d->s_name;
|
||||
if (!strcmp (name, "end_sys_fields"))
|
||||
break;
|
||||
|
||||
if (!d->name || !d->offset || d->type->type != ev_field)
|
||||
if (!d->ofs)
|
||||
continue;
|
||||
|
||||
switch (d->type->t.fldptr.type->type) {
|
||||
switch (d->type) {
|
||||
case ev_float:
|
||||
fprintf (f, "\tfloat\t%s;\n", d->name);
|
||||
fprintf (f, "\tfloat\t%s;\n", name);
|
||||
break;
|
||||
case ev_vector:
|
||||
fprintf (f, "\tvec3_t\t%s;\n", d->name);
|
||||
fprintf (f, "\tvec3_t\t%s;\n", name);
|
||||
break;
|
||||
case ev_string:
|
||||
fprintf (f, "\tstring_t\t%s;\n", d->name);
|
||||
fprintf (f, "\tstring_t\t%s;\n", name);
|
||||
break;
|
||||
case ev_func:
|
||||
fprintf (f, "\tfunc_t\t%s;\n", d->name);
|
||||
fprintf (f, "\tfunc_t\t%s;\n", name);
|
||||
break;
|
||||
case ev_entity:
|
||||
fprintf (f, "\tint\t%s;\n", d->name);
|
||||
fprintf (f, "\tint\t%s;\n", name);
|
||||
break;
|
||||
default:
|
||||
fprintf (f, "\tint\t%s;\n", d->name);
|
||||
fprintf (f, "\tint\t%s;\n", name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -693,7 +693,7 @@ convert_def (qfo_t *qfo, const qfo_def_t *def, ddef_t *ddef)
|
|||
}
|
||||
|
||||
dprograms_t *
|
||||
qfo_to_progs (qfo_t *qfo)
|
||||
qfo_to_progs (qfo_t *qfo, int *size)
|
||||
{
|
||||
char *strings;
|
||||
dstatement_t *statements;
|
||||
|
@ -703,12 +703,12 @@ qfo_to_progs (qfo_t *qfo)
|
|||
pr_type_t *globals;
|
||||
dprograms_t *progs;
|
||||
int i;
|
||||
int size = sizeof (dprograms_t);
|
||||
int locals_size = 0;
|
||||
int locals_start;
|
||||
int big_locals = 0;
|
||||
|
||||
progs = calloc (1, size);
|
||||
*size = sizeof (dprograms_t);
|
||||
progs = calloc (1, *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;
|
||||
|
@ -729,13 +729,13 @@ qfo_to_progs (qfo_t *qfo)
|
|||
}
|
||||
}
|
||||
progs->entityfields = qfo->spaces[qfo_entity_space].data_size;
|
||||
size += progs->numstatements * sizeof (dstatement_t);
|
||||
size += progs->numglobaldefs * sizeof (ddef_t);
|
||||
size += progs->numfielddefs * sizeof (ddef_t);
|
||||
size += progs->numfunctions * sizeof (dfunction_t);
|
||||
size += progs->numstrings * sizeof (char);
|
||||
size += (progs->numglobals + locals_size) * sizeof (pr_type_t);
|
||||
progs = realloc (progs, size);
|
||||
*size += progs->numstatements * sizeof (dstatement_t);
|
||||
*size += progs->numglobaldefs * sizeof (ddef_t);
|
||||
*size += progs->numfielddefs * sizeof (ddef_t);
|
||||
*size += progs->numfunctions * sizeof (dfunction_t);
|
||||
*size += progs->numstrings * sizeof (char);
|
||||
*size += (progs->numglobals + locals_size) * sizeof (pr_type_t);
|
||||
progs = realloc (progs, *size);
|
||||
|
||||
strings = (char *) (progs + 1);
|
||||
memcpy (strings, qfo->spaces[qfo_strings_space].d.strings,
|
||||
|
|
|
@ -157,50 +157,57 @@ InitData (void)
|
|||
numfielddefs = 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
WriteData (int crc)
|
||||
WriteData (dprograms_t *progs, int size)
|
||||
{
|
||||
def_t *def;
|
||||
ddef_t *dd;
|
||||
dprograms_t progs;
|
||||
pr_debug_header_t debug;
|
||||
//pr_debug_header_t debug;
|
||||
QFile *h;
|
||||
int i;
|
||||
int num_defs = 0;
|
||||
unsigned i;
|
||||
|
||||
for (def = pr.data->defs; def; def = def->next)
|
||||
num_defs++;
|
||||
globals = calloc (num_defs + 1, sizeof (ddef_t));
|
||||
fields = calloc (num_defs + 1, sizeof (ddef_t));
|
||||
dstatement_t *statements;
|
||||
dfunction_t *functions;
|
||||
ddef_t *globaldefs;
|
||||
ddef_t *fielddefs;
|
||||
pr_type_t *globals;
|
||||
|
||||
for (def = pr.data->defs; def; def = def->next) {
|
||||
if (def->local || !def->name)
|
||||
continue;
|
||||
if (options.code.progsversion == PROG_ID_VERSION && *def->name == '.'
|
||||
&& strcmp (def->name, ".imm") != 0
|
||||
&& strcmp (def->name, ".debug_file") != 0)
|
||||
continue;
|
||||
if (def->type->type == ev_func) {
|
||||
} else if (def->type->type == ev_field
|
||||
&& strcmp (def->name, ".imm") != 0) {
|
||||
dd = &fields[numfielddefs++];
|
||||
def_to_ddef (def, dd, 1);
|
||||
dd->ofs = D_INT (def);
|
||||
}
|
||||
#define P(t,o) ((t *)((char *)progs + progs->o))
|
||||
statements = P (dstatement_t, ofs_statements);
|
||||
functions = P (dfunction_t, ofs_functions);
|
||||
globaldefs = P (ddef_t, ofs_globaldefs);
|
||||
fielddefs = P (ddef_t, ofs_fielddefs);
|
||||
globals = P (pr_type_t, ofs_globals);
|
||||
#undef P
|
||||
|
||||
dd = &globals[numglobaldefs++];
|
||||
def_to_ddef (def, dd, 0);
|
||||
if (!def->nosave
|
||||
&& !def->constant
|
||||
&& def->type->type != ev_func
|
||||
&& def->type->type != ev_field && def->global)
|
||||
dd->type |= DEF_SAVEGLOBAL;
|
||||
for (i = 0; i < progs->numstatements; i++) {
|
||||
statements[i].op = LittleShort (statements[i].op);
|
||||
statements[i].a = LittleShort (statements[i].a);
|
||||
statements[i].b = LittleShort (statements[i].b);
|
||||
statements[i].c = LittleShort (statements[i].c);
|
||||
}
|
||||
for (i = 0; i < (unsigned) progs->numfunctions; i++) {
|
||||
dfunction_t *func = functions + i;
|
||||
func->first_statement = LittleLong (func->first_statement);
|
||||
func->parm_start = LittleLong (func->parm_start);
|
||||
func->locals = LittleLong (func->locals);
|
||||
func->profile = LittleLong (func->profile);
|
||||
func->s_name = LittleLong (func->s_name);
|
||||
func->s_file = LittleLong (func->s_file);
|
||||
func->numparms = LittleLong (func->numparms);
|
||||
}
|
||||
for (i = 0; i < progs->numglobaldefs; i++) {
|
||||
globaldefs[i].type = LittleShort (globaldefs[i].type);
|
||||
globaldefs[i].ofs = LittleShort (globaldefs[i].ofs);
|
||||
globaldefs[i].s_name = LittleLong (globaldefs[i].s_name);
|
||||
}
|
||||
for (i = 0; i < progs->numfielddefs; i++) {
|
||||
fielddefs[i].type = LittleShort (fielddefs[i].type);
|
||||
fielddefs[i].ofs = LittleShort (fielddefs[i].ofs);
|
||||
fielddefs[i].s_name = LittleLong (fielddefs[i].s_name);
|
||||
}
|
||||
for (i = 0; i < progs->numglobals; i++)
|
||||
globals[i].integer_var = LittleLong (globals[i].integer_var);
|
||||
|
||||
while (pr.strings->size & 3)
|
||||
pr.strings->strings[pr.strings->size++] = 0;
|
||||
|
||||
#if 0 //FIXME
|
||||
if (options.verbosity >= 0) {
|
||||
if (!big_function)
|
||||
big_function = "";
|
||||
|
@ -215,86 +222,21 @@ WriteData (int crc)
|
|||
printf (" %6i far globals\n", pr.far_data->size);
|
||||
printf ("%6i entity fields\n", pr.entity_data->size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(h = Qopen (options.output_file, "wb")))
|
||||
Sys_Error ("%s: %s\n", options.output_file, strerror(errno));
|
||||
memset (&progs, 0, sizeof (progs));
|
||||
Qwrite (h, &progs, sizeof (progs));
|
||||
Qwrite (h, progs, size);
|
||||
|
||||
progs.ofs_strings = Qtell (h);
|
||||
progs.numstrings = pr.strings->size;
|
||||
Qwrite (h, pr.strings->strings, pr.strings->size);
|
||||
// if (options.verbosity >= -1)
|
||||
// printf ("%6i TOTAL SIZE\n", (int) Qtell (h));
|
||||
|
||||
progs.ofs_statements = Qtell (h);
|
||||
progs.numstatements = pr.code->size;
|
||||
for (i = 0; i < pr.code->size; i++) {
|
||||
pr.code->code[i].op = LittleShort (pr.code->code[i].op);
|
||||
pr.code->code[i].a = LittleShort (pr.code->code[i].a);
|
||||
pr.code->code[i].b = LittleShort (pr.code->code[i].b);
|
||||
pr.code->code[i].c = LittleShort (pr.code->code[i].c);
|
||||
}
|
||||
Qwrite (h, pr.code->code, pr.code->size * sizeof (dstatement_t));
|
||||
|
||||
{
|
||||
dfunction_t *df;
|
||||
|
||||
progs.ofs_functions = Qtell (h);
|
||||
progs.numfunctions = pr.num_functions;
|
||||
for (i = 0, df = pr.functions + 1; i < pr.num_functions; i++, df++) {
|
||||
df->first_statement = LittleLong (df->first_statement);
|
||||
df->parm_start = LittleLong (df->parm_start);
|
||||
df->s_name = LittleLong (df->s_name);
|
||||
df->s_file = LittleLong (df->s_file);
|
||||
df->numparms = LittleLong (df->numparms);
|
||||
df->locals = LittleLong (df->locals);
|
||||
}
|
||||
Qwrite (h, pr.functions, pr.num_functions * sizeof (dfunction_t));
|
||||
}
|
||||
|
||||
progs.ofs_globaldefs = Qtell (h);
|
||||
progs.numglobaldefs = numglobaldefs;
|
||||
for (i = 0; i < numglobaldefs; i++) {
|
||||
globals[i].type = LittleShort (globals[i].type);
|
||||
globals[i].ofs = LittleShort (globals[i].ofs);
|
||||
globals[i].s_name = LittleLong (globals[i].s_name);
|
||||
}
|
||||
Qwrite (h, globals, numglobaldefs * sizeof (ddef_t));
|
||||
|
||||
progs.ofs_fielddefs = Qtell (h);
|
||||
progs.numfielddefs = numfielddefs;
|
||||
for (i = 0; i < numfielddefs; i++) {
|
||||
fields[i].type = LittleShort (fields[i].type);
|
||||
fields[i].ofs = LittleShort (fields[i].ofs);
|
||||
fields[i].s_name = LittleLong (fields[i].s_name);
|
||||
}
|
||||
Qwrite (h, fields, numfielddefs * sizeof (ddef_t));
|
||||
|
||||
progs.ofs_globals = Qtell (h);
|
||||
progs.numglobals = pr.data->size;
|
||||
for (i = 0; i < pr.data->size; i++)
|
||||
pr.data->data[i] = LittleLong (pr.data->data[i]);
|
||||
Qwrite (h, pr.data->data, pr.data->size * 4);
|
||||
|
||||
if (options.verbosity >= -1)
|
||||
printf ("%6i TOTAL SIZE\n", (int) Qtell (h));
|
||||
|
||||
progs.entityfields = pr.entity_data->size;
|
||||
|
||||
progs.version = options.code.progsversion;
|
||||
progs.crc = crc;
|
||||
|
||||
// byte swap the header and write it out
|
||||
for (i = 0; i < (int) sizeof (progs) / 4; i++)
|
||||
((int *) &progs)[i] = LittleLong (((int *) &progs)[i]);
|
||||
|
||||
Qseek (h, 0, SEEK_SET);
|
||||
Qwrite (h, &progs, sizeof (progs));
|
||||
Qclose (h);
|
||||
|
||||
if (!options.code.debug) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 //FIXME
|
||||
if (!(h = Qopen (options.output_file, "rb")))
|
||||
Sys_Error ("%s: %s\n", options.output_file, strerror(errno));
|
||||
|
||||
|
@ -343,6 +285,7 @@ WriteData (int crc)
|
|||
Qseek (h, 0, SEEK_SET);
|
||||
Qwrite (h, &debug, sizeof (debug));
|
||||
Qclose (h);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -354,172 +297,6 @@ begin_compilation (void)
|
|||
pr.error_count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_param_block (void)
|
||||
{
|
||||
static struct_def_t defs[] = {
|
||||
{".zero", &type_zero},
|
||||
{".return", &type_param},
|
||||
{".param_0", &type_param},
|
||||
{".param_1", &type_param},
|
||||
{".param_2", &type_param},
|
||||
{".param_3", &type_param},
|
||||
{".param_4", &type_param},
|
||||
{".param_5", &type_param},
|
||||
{".param_6", &type_param},
|
||||
{".param_7", &type_param},
|
||||
};
|
||||
size_t i;
|
||||
symbol_t *sym;
|
||||
|
||||
for (i = 0; i < sizeof (defs) / sizeof (defs[0]); i++) {
|
||||
sym = make_symbol (defs[i].name, defs[i].type, pr.symtab->space,
|
||||
st_global);
|
||||
symtab_addsymbol (pr.symtab, sym);
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean
|
||||
finish_compilation (void)
|
||||
{
|
||||
def_t *d;
|
||||
qboolean errors = false;
|
||||
function_t *f;
|
||||
def_t *def;
|
||||
dfunction_t *df;
|
||||
int far_base;
|
||||
|
||||
for (d = pr.near_data->defs; d; d = d->next) {
|
||||
if (d->external && d->relocs) {
|
||||
#if 0 //FIXME
|
||||
if (strcmp (d->name, ".self") == 0) {
|
||||
get_def (d->type, ".self", pr.scope, st_global);
|
||||
} else if (strcmp (d->name, ".this") == 0) {
|
||||
get_def (d->type, ".this", pr.scope, st_global);
|
||||
} else {
|
||||
#endif
|
||||
errors = true;
|
||||
error (0, "undefined global %s", d->name);
|
||||
//FIXME }
|
||||
}
|
||||
}
|
||||
for (d = pr.far_data->defs; d; d = d->next) {
|
||||
if (d->external && d->relocs) {
|
||||
errors = true;
|
||||
error (0, "undefined global %s", d->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors)
|
||||
return !errors;
|
||||
|
||||
pr.functions = calloc (pr.num_functions + 1, sizeof (dfunction_t));
|
||||
for (df = pr.functions + 1, f = pr.func_head; f; df++, f = f->next) {
|
||||
df->s_name = f->s_name;
|
||||
df->s_file = f->s_file;
|
||||
df->numparms = function_parms (f, df->parm_size);
|
||||
if (f->symtab && f->symtab->space)
|
||||
df->locals = f->symtab->space->size;
|
||||
if (f->builtin) {
|
||||
df->first_statement = -f->builtin;
|
||||
continue;
|
||||
}
|
||||
if (!f->code)
|
||||
continue;
|
||||
df->first_statement = f->code;
|
||||
if (options.code.local_merging) {
|
||||
if (f->symtab->space->size > num_localdefs) {
|
||||
num_localdefs = f->symtab->space->size;
|
||||
big_function = f->def->name;
|
||||
}
|
||||
df->parm_start = pr.near_data->size;
|
||||
} else {
|
||||
df->parm_start = defspace_alloc_loc (pr.near_data,
|
||||
f->symtab->space->size);
|
||||
num_localdefs += f->symtab->space->size;
|
||||
}
|
||||
for (def = f->symtab->space->defs; def; def = def->next) {
|
||||
if (!def->local)
|
||||
continue;
|
||||
def->offset += df->parm_start;
|
||||
}
|
||||
}
|
||||
if (options.code.local_merging)
|
||||
defspace_alloc_loc (pr.near_data, num_localdefs);
|
||||
|
||||
if (options.code.progsversion != PROG_ID_VERSION) {
|
||||
//FIXME better init code
|
||||
symbol_t *sym = new_symbol (".param_size");
|
||||
initialize_def (sym, &type_integer, 0, pr.far_data, st_global);
|
||||
D_INT (sym->s.def) = type_size (&type_param);
|
||||
}
|
||||
|
||||
if (options.code.debug) {
|
||||
//FIXME better init code
|
||||
symbol_t *sym = new_symbol (".debug_file");
|
||||
initialize_def (sym, &type_string, 0, pr.far_data, st_global);
|
||||
EMIT_STRING (sym->s.def->space, D_STRUCT (string_t, sym->s.def),
|
||||
debugfile);
|
||||
}
|
||||
|
||||
// merge near and far data
|
||||
defspace_add_data (pr.data, pr.near_data->data, pr.near_data->size);
|
||||
far_base = pr.data->size;
|
||||
defspace_add_data (pr.data, pr.far_data->data, pr.far_data->size);
|
||||
for (d = pr.far_data->defs; d; d = d->next) {
|
||||
if (!d->external)
|
||||
d->offset += far_base;
|
||||
}
|
||||
if (pr.near_data->defs) {
|
||||
pr.data->defs = pr.near_data->defs;
|
||||
pr.data->def_tail = pr.near_data->def_tail;
|
||||
pr.near_data->defs = 0;
|
||||
pr.near_data->def_tail = &pr.near_data->defs;
|
||||
}
|
||||
if (pr.far_data->defs) {
|
||||
*pr.data->def_tail = pr.far_data->defs;
|
||||
pr.data->def_tail = pr.far_data->def_tail;
|
||||
pr.far_data->defs = 0;
|
||||
pr.far_data->def_tail = &pr.far_data->defs;
|
||||
}
|
||||
// point near and far data spaces into the merged data. this allows
|
||||
// relocations to work without having to adjust their location.
|
||||
pr.near_data->data = pr.data->data;
|
||||
pr.far_data->data = pr.data->data + far_base;
|
||||
|
||||
// check to make sure all functions prototyped have code
|
||||
if (options.warnings.undefined_function) {
|
||||
for (d = pr.data->defs; d; d = d->next) {
|
||||
if (d->type->type == ev_func && d->global) {
|
||||
// function args ok
|
||||
//FIXME if (d->used) {
|
||||
if (!d->initialized) {
|
||||
warning (0, "function %s was called but not defined\n",
|
||||
d->name);
|
||||
}
|
||||
//FIXME }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (def = pr.data->defs; def; def = def->next)
|
||||
relocate_refs (def->relocs, def->offset);
|
||||
|
||||
for (df = pr.functions + 1, f = pr.func_head; f; df++, f = f->next) {
|
||||
relocate_refs (f->refs, f->function_num);
|
||||
if (!f->code)
|
||||
continue;
|
||||
for (def = f->symtab->space->defs; def; def = def->next) {
|
||||
if (!def->local)
|
||||
continue;
|
||||
relocate_refs (def->relocs, def->offset);
|
||||
}
|
||||
}
|
||||
|
||||
return !errors;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
strip_path (const char *filename)
|
||||
{
|
||||
|
@ -595,6 +372,47 @@ compile_to_obj (const char *file, const char *obj)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
finish_link (void)
|
||||
{
|
||||
qfo_t *qfo;
|
||||
int flags;
|
||||
|
||||
flags = (QFOD_GLOBAL | QFOD_CONSTANT | QFOD_INITIALIZED | QFOD_NOSAVE);
|
||||
if (options.code.progsversion != PROG_ID_VERSION) {
|
||||
linker_add_def (".param_size", &type_integer, flags,
|
||||
type_size (&type_param));
|
||||
}
|
||||
|
||||
if (options.code.debug) {
|
||||
int str = linker_add_string (debugfile);
|
||||
linker_add_def (".debug_file", &type_string, flags, str);
|
||||
}
|
||||
|
||||
qfo = linker_finish ();
|
||||
if (!qfo)
|
||||
return 1;
|
||||
if (!options.output_file)
|
||||
options.output_file = "progs.dat";
|
||||
if (options.partial_link) {
|
||||
qfo_write (qfo, options.output_file);
|
||||
} else {
|
||||
int size;
|
||||
dprograms_t *progs;
|
||||
|
||||
progs = qfo_to_progs (qfo, &size);
|
||||
setup_sym_file (options.output_file);
|
||||
//finish_compilation ();
|
||||
|
||||
// write progdefs.h
|
||||
if (options.progdefs_h)
|
||||
progs->crc = WriteProgdefs (progs, "progdefs.h");
|
||||
|
||||
WriteData (progs, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
separate_compile (void)
|
||||
{
|
||||
|
@ -654,7 +472,6 @@ separate_compile (void)
|
|||
}
|
||||
}
|
||||
if (!err && !options.compile) {
|
||||
qfo_t *qfo;
|
||||
linker_begin ();
|
||||
for (file = source_files; *file; file++) {
|
||||
if (strncmp (*file, "-l", 2)) {
|
||||
|
@ -670,28 +487,7 @@ separate_compile (void)
|
|||
if (err)
|
||||
return err;
|
||||
}
|
||||
qfo = linker_finish ();
|
||||
if (qfo) {
|
||||
if (!options.output_file)
|
||||
options.output_file = "progs.dat";
|
||||
if (options.partial_link) {
|
||||
qfo_write (qfo, options.output_file);
|
||||
} else {
|
||||
int crc = 0;
|
||||
|
||||
//qfo_to_progs (qfo, &pr);
|
||||
setup_sym_file (options.output_file);
|
||||
finish_compilation ();
|
||||
|
||||
// write progdefs.h
|
||||
if (options.progdefs_h)
|
||||
crc = WriteProgdefs ("progdefs.h");
|
||||
|
||||
WriteData (crc);
|
||||
}
|
||||
} else {
|
||||
err = 1;
|
||||
}
|
||||
err = finish_link ();
|
||||
if (!options.save_temps)
|
||||
for (file = temp_files; *file; file++)
|
||||
unlink (*file);
|
||||
|
@ -775,9 +571,10 @@ progs_src_compile (void)
|
|||
dstring_t *qc_filename = dstring_newstr ();
|
||||
dstring_t *single_name = dstring_newstr ();
|
||||
const char *src;
|
||||
int crc = 0;
|
||||
//int crc = 0;
|
||||
script_t *script;
|
||||
FILE *single = 0;
|
||||
qfo_t *qfo;
|
||||
|
||||
if (options.verbosity >= 1 && strcmp (sourcedir, "")) {
|
||||
printf ("Source directory: %s\n", sourcedir);
|
||||
|
@ -843,9 +640,6 @@ progs_src_compile (void)
|
|||
|
||||
begin_compilation ();
|
||||
|
||||
if (!options.compile)
|
||||
setup_param_block ();
|
||||
|
||||
// compile all the files
|
||||
while (Script_GetToken (script, 1)) {
|
||||
if (strcmp (script->token->str, "#") == 0) {
|
||||
|
@ -891,30 +685,23 @@ progs_src_compile (void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
class_finish_module ();
|
||||
qfo = qfo_from_progs (&pr);
|
||||
if (options.compile) {
|
||||
qfo_t *qfo = qfo_from_progs (&pr);
|
||||
qfo_write (qfo, options.output_file);
|
||||
qfo_delete (qfo);
|
||||
} else {
|
||||
class_finish_module ();
|
||||
if (!finish_compilation ()) {
|
||||
linker_begin ();
|
||||
if (linker_add_qfo (qfo) || finish_link ()) {
|
||||
fprintf (stderr, "compilation errors\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// write progdefs.h
|
||||
if (options.progdefs_h)
|
||||
crc = WriteProgdefs ("progdefs.h");
|
||||
|
||||
// write data file
|
||||
if (WriteData (crc))
|
||||
return 1;
|
||||
|
||||
// write files.dat
|
||||
if (options.files_dat)
|
||||
if (WriteFiles (sourcedir))
|
||||
return 1;
|
||||
}
|
||||
qfo_delete (qfo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -258,9 +258,11 @@ init_qf (void)
|
|||
static void
|
||||
convert_qfo (void)
|
||||
{
|
||||
int size;
|
||||
int i;
|
||||
ddef_t *ld;
|
||||
pr.progs = qfo_to_progs (qfo);
|
||||
|
||||
pr.progs = qfo_to_progs (qfo, &size);
|
||||
|
||||
pr.pr_statements = P (dstatement_t, ofs_statements);
|
||||
pr.pr_strings = P (char, ofs_strings);
|
||||
|
|
Loading…
Reference in a new issue