mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-06-03 01:51:02 +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
|
#ifndef __idstuff_h
|
||||||
#define __idstuff_h
|
#define __idstuff_h
|
||||||
|
|
||||||
|
#include "QF/pr_comp.h"
|
||||||
|
|
||||||
//XXX eww :/
|
//XXX eww :/
|
||||||
void PrecacheSound (const char *, int ch);
|
void PrecacheSound (const char *, int ch);
|
||||||
void PrecacheModel (const char *, int ch);
|
void PrecacheModel (const char *, int ch);
|
||||||
void PrecacheFile (const char *, int ch);
|
void PrecacheFile (const char *, int ch);
|
||||||
int WriteFiles (const char *sourcedir);
|
int WriteFiles (const char *sourcedir);
|
||||||
int WriteProgdefs (const char *filename);
|
int WriteProgdefs (dprograms_t *progs, const char *filename);
|
||||||
|
|
||||||
#endif//__idstuff_h
|
#endif//__idstuff_h
|
||||||
|
|
|
@ -461,7 +461,7 @@ qfo_t *qfo_read (QFile *file);
|
||||||
*/
|
*/
|
||||||
qfo_t *qfo_open (const char *filename);
|
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
|
/** Create a new ::qfo_t struct
|
||||||
\return pointer to new ::qfo_t struct, or 0 on error.
|
\return pointer to new ::qfo_t struct, or 0 on error.
|
||||||
|
|
|
@ -193,12 +193,15 @@ WriteFiles (const char *sourcedir)
|
||||||
at load time.
|
at load time.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
WriteProgdefs (const char *filename)
|
WriteProgdefs (dprograms_t *progs, const char *filename)
|
||||||
{
|
{
|
||||||
def_t *d;
|
ddef_t *d;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
unsigned short crc;
|
unsigned short crc;
|
||||||
int c;
|
int c;
|
||||||
|
unsigned i;
|
||||||
|
const char *strings;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
if (options.verbosity >= 1)
|
if (options.verbosity >= 1)
|
||||||
printf ("writing %s\n", filename);
|
printf ("writing %s\n", filename);
|
||||||
|
@ -209,35 +212,38 @@ WriteProgdefs (const char *filename)
|
||||||
"\n\ntypedef struct\n{\tint\tpad[%i];\n",
|
"\n\ntypedef struct\n{\tint\tpad[%i];\n",
|
||||||
RESERVED_OFS);
|
RESERVED_OFS);
|
||||||
|
|
||||||
for (d = pr.near_data->defs; d; d = d->next) {
|
strings = (char *) progs + progs->ofs_strings;
|
||||||
if (d->name && !strcmp (d->name, "end_sys_globals"))
|
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;
|
break;
|
||||||
if (!d->offset)
|
if (!d->ofs)
|
||||||
continue;
|
continue;
|
||||||
if (!d->name || *d->name == '.' || !*d->name)
|
if (*name == '.' || !*name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (d->type->type) {
|
switch (d->type) {
|
||||||
case ev_float:
|
case ev_float:
|
||||||
fprintf (f, "\tfloat\t%s;\n", d->name);
|
fprintf (f, "\tfloat\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_vector:
|
case ev_vector:
|
||||||
fprintf (f, "\tvec3_t\t%s;\n", d->name);
|
fprintf (f, "\tvec3_t\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_quat:
|
case ev_quat:
|
||||||
fprintf (f, "\tquat_t\t%s;\n", d->name);
|
fprintf (f, "\tquat_t\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_string:
|
case ev_string:
|
||||||
fprintf (f, "\tstring_t\t%s;\n", d->name);
|
fprintf (f, "\tstring_t\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_func:
|
case ev_func:
|
||||||
fprintf (f, "\tfunc_t\t%s;\n", d->name);
|
fprintf (f, "\tfunc_t\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_entity:
|
case ev_entity:
|
||||||
fprintf (f, "\tint\t%s;\n", d->name);
|
fprintf (f, "\tint\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (f, "\tint\t%s;\n", d->name);
|
fprintf (f, "\tint\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,31 +251,33 @@ WriteProgdefs (const char *filename)
|
||||||
|
|
||||||
// print all fields
|
// print all fields
|
||||||
fprintf (f, "typedef struct\n{\n");
|
fprintf (f, "typedef struct\n{\n");
|
||||||
for (d = pr.near_data->defs; d; d = d->next) {
|
for (i = 0; i < progs->numglobaldefs; i++) {
|
||||||
if (d->name && !strcmp (d->name, "end_sys_fields"))
|
d = (ddef_t *) ((char *) progs + progs->ofs_fielddefs) + i;
|
||||||
|
name = strings + d->s_name;
|
||||||
|
if (!strcmp (name, "end_sys_fields"))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!d->name || !d->offset || d->type->type != ev_field)
|
if (!d->ofs)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (d->type->t.fldptr.type->type) {
|
switch (d->type) {
|
||||||
case ev_float:
|
case ev_float:
|
||||||
fprintf (f, "\tfloat\t%s;\n", d->name);
|
fprintf (f, "\tfloat\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_vector:
|
case ev_vector:
|
||||||
fprintf (f, "\tvec3_t\t%s;\n", d->name);
|
fprintf (f, "\tvec3_t\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_string:
|
case ev_string:
|
||||||
fprintf (f, "\tstring_t\t%s;\n", d->name);
|
fprintf (f, "\tstring_t\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_func:
|
case ev_func:
|
||||||
fprintf (f, "\tfunc_t\t%s;\n", d->name);
|
fprintf (f, "\tfunc_t\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
case ev_entity:
|
case ev_entity:
|
||||||
fprintf (f, "\tint\t%s;\n", d->name);
|
fprintf (f, "\tint\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (f, "\tint\t%s;\n", d->name);
|
fprintf (f, "\tint\t%s;\n", name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -693,7 +693,7 @@ convert_def (qfo_t *qfo, const qfo_def_t *def, ddef_t *ddef)
|
||||||
}
|
}
|
||||||
|
|
||||||
dprograms_t *
|
dprograms_t *
|
||||||
qfo_to_progs (qfo_t *qfo)
|
qfo_to_progs (qfo_t *qfo, int *size)
|
||||||
{
|
{
|
||||||
char *strings;
|
char *strings;
|
||||||
dstatement_t *statements;
|
dstatement_t *statements;
|
||||||
|
@ -703,12 +703,12 @@ qfo_to_progs (qfo_t *qfo)
|
||||||
pr_type_t *globals;
|
pr_type_t *globals;
|
||||||
dprograms_t *progs;
|
dprograms_t *progs;
|
||||||
int i;
|
int i;
|
||||||
int size = sizeof (dprograms_t);
|
|
||||||
int locals_size = 0;
|
int locals_size = 0;
|
||||||
int locals_start;
|
int locals_start;
|
||||||
int big_locals = 0;
|
int big_locals = 0;
|
||||||
|
|
||||||
progs = calloc (1, size);
|
*size = sizeof (dprograms_t);
|
||||||
|
progs = calloc (1, *size);
|
||||||
progs->version = options.code.progsversion;
|
progs->version = options.code.progsversion;
|
||||||
progs->numstatements = qfo->spaces[qfo_code_space].data_size;
|
progs->numstatements = qfo->spaces[qfo_code_space].data_size;
|
||||||
progs->numglobaldefs = qfo->spaces[qfo_near_data_space].num_defs;
|
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;
|
progs->entityfields = qfo->spaces[qfo_entity_space].data_size;
|
||||||
size += progs->numstatements * sizeof (dstatement_t);
|
*size += progs->numstatements * sizeof (dstatement_t);
|
||||||
size += progs->numglobaldefs * sizeof (ddef_t);
|
*size += progs->numglobaldefs * sizeof (ddef_t);
|
||||||
size += progs->numfielddefs * sizeof (ddef_t);
|
*size += progs->numfielddefs * sizeof (ddef_t);
|
||||||
size += progs->numfunctions * sizeof (dfunction_t);
|
*size += progs->numfunctions * sizeof (dfunction_t);
|
||||||
size += progs->numstrings * sizeof (char);
|
*size += progs->numstrings * sizeof (char);
|
||||||
size += (progs->numglobals + locals_size) * sizeof (pr_type_t);
|
*size += (progs->numglobals + locals_size) * sizeof (pr_type_t);
|
||||||
progs = realloc (progs, size);
|
progs = realloc (progs, *size);
|
||||||
|
|
||||||
strings = (char *) (progs + 1);
|
strings = (char *) (progs + 1);
|
||||||
memcpy (strings, qfo->spaces[qfo_strings_space].d.strings,
|
memcpy (strings, qfo->spaces[qfo_strings_space].d.strings,
|
||||||
|
|
|
@ -157,50 +157,57 @@ InitData (void)
|
||||||
numfielddefs = 1;
|
numfielddefs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
WriteData (int crc)
|
WriteData (dprograms_t *progs, int size)
|
||||||
{
|
{
|
||||||
def_t *def;
|
//pr_debug_header_t debug;
|
||||||
ddef_t *dd;
|
|
||||||
dprograms_t progs;
|
|
||||||
pr_debug_header_t debug;
|
|
||||||
QFile *h;
|
QFile *h;
|
||||||
int i;
|
unsigned i;
|
||||||
int num_defs = 0;
|
|
||||||
|
|
||||||
for (def = pr.data->defs; def; def = def->next)
|
dstatement_t *statements;
|
||||||
num_defs++;
|
dfunction_t *functions;
|
||||||
globals = calloc (num_defs + 1, sizeof (ddef_t));
|
ddef_t *globaldefs;
|
||||||
fields = calloc (num_defs + 1, sizeof (ddef_t));
|
ddef_t *fielddefs;
|
||||||
|
pr_type_t *globals;
|
||||||
|
|
||||||
for (def = pr.data->defs; def; def = def->next) {
|
#define P(t,o) ((t *)((char *)progs + progs->o))
|
||||||
if (def->local || !def->name)
|
statements = P (dstatement_t, ofs_statements);
|
||||||
continue;
|
functions = P (dfunction_t, ofs_functions);
|
||||||
if (options.code.progsversion == PROG_ID_VERSION && *def->name == '.'
|
globaldefs = P (ddef_t, ofs_globaldefs);
|
||||||
&& strcmp (def->name, ".imm") != 0
|
fielddefs = P (ddef_t, ofs_fielddefs);
|
||||||
&& strcmp (def->name, ".debug_file") != 0)
|
globals = P (pr_type_t, ofs_globals);
|
||||||
continue;
|
#undef P
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
dd = &globals[numglobaldefs++];
|
for (i = 0; i < progs->numstatements; i++) {
|
||||||
def_to_ddef (def, dd, 0);
|
statements[i].op = LittleShort (statements[i].op);
|
||||||
if (!def->nosave
|
statements[i].a = LittleShort (statements[i].a);
|
||||||
&& !def->constant
|
statements[i].b = LittleShort (statements[i].b);
|
||||||
&& def->type->type != ev_func
|
statements[i].c = LittleShort (statements[i].c);
|
||||||
&& def->type->type != ev_field && def->global)
|
|
||||||
dd->type |= DEF_SAVEGLOBAL;
|
|
||||||
}
|
}
|
||||||
|
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)
|
#if 0 //FIXME
|
||||||
pr.strings->strings[pr.strings->size++] = 0;
|
|
||||||
|
|
||||||
if (options.verbosity >= 0) {
|
if (options.verbosity >= 0) {
|
||||||
if (!big_function)
|
if (!big_function)
|
||||||
big_function = "";
|
big_function = "";
|
||||||
|
@ -215,86 +222,21 @@ WriteData (int crc)
|
||||||
printf (" %6i far globals\n", pr.far_data->size);
|
printf (" %6i far globals\n", pr.far_data->size);
|
||||||
printf ("%6i entity fields\n", pr.entity_data->size);
|
printf ("%6i entity fields\n", pr.entity_data->size);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(h = Qopen (options.output_file, "wb")))
|
if (!(h = Qopen (options.output_file, "wb")))
|
||||||
Sys_Error ("%s: %s\n", options.output_file, strerror(errno));
|
Sys_Error ("%s: %s\n", options.output_file, strerror(errno));
|
||||||
memset (&progs, 0, sizeof (progs));
|
Qwrite (h, progs, size);
|
||||||
Qwrite (h, &progs, sizeof (progs));
|
|
||||||
|
|
||||||
progs.ofs_strings = Qtell (h);
|
// if (options.verbosity >= -1)
|
||||||
progs.numstrings = pr.strings->size;
|
// printf ("%6i TOTAL SIZE\n", (int) Qtell (h));
|
||||||
Qwrite (h, pr.strings->strings, pr.strings->size);
|
|
||||||
|
|
||||||
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);
|
Qclose (h);
|
||||||
|
|
||||||
if (!options.code.debug) {
|
if (!options.code.debug) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#if 0 //FIXME
|
||||||
if (!(h = Qopen (options.output_file, "rb")))
|
if (!(h = Qopen (options.output_file, "rb")))
|
||||||
Sys_Error ("%s: %s\n", options.output_file, strerror(errno));
|
Sys_Error ("%s: %s\n", options.output_file, strerror(errno));
|
||||||
|
|
||||||
|
@ -343,6 +285,7 @@ WriteData (int crc)
|
||||||
Qseek (h, 0, SEEK_SET);
|
Qseek (h, 0, SEEK_SET);
|
||||||
Qwrite (h, &debug, sizeof (debug));
|
Qwrite (h, &debug, sizeof (debug));
|
||||||
Qclose (h);
|
Qclose (h);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,172 +297,6 @@ begin_compilation (void)
|
||||||
pr.error_count = 0;
|
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 *
|
const char *
|
||||||
strip_path (const char *filename)
|
strip_path (const char *filename)
|
||||||
{
|
{
|
||||||
|
@ -595,6 +372,47 @@ compile_to_obj (const char *file, const char *obj)
|
||||||
return err;
|
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
|
static int
|
||||||
separate_compile (void)
|
separate_compile (void)
|
||||||
{
|
{
|
||||||
|
@ -654,7 +472,6 @@ separate_compile (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!err && !options.compile) {
|
if (!err && !options.compile) {
|
||||||
qfo_t *qfo;
|
|
||||||
linker_begin ();
|
linker_begin ();
|
||||||
for (file = source_files; *file; file++) {
|
for (file = source_files; *file; file++) {
|
||||||
if (strncmp (*file, "-l", 2)) {
|
if (strncmp (*file, "-l", 2)) {
|
||||||
|
@ -670,28 +487,7 @@ separate_compile (void)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
qfo = linker_finish ();
|
err = finish_link ();
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (!options.save_temps)
|
if (!options.save_temps)
|
||||||
for (file = temp_files; *file; file++)
|
for (file = temp_files; *file; file++)
|
||||||
unlink (*file);
|
unlink (*file);
|
||||||
|
@ -775,9 +571,10 @@ progs_src_compile (void)
|
||||||
dstring_t *qc_filename = dstring_newstr ();
|
dstring_t *qc_filename = dstring_newstr ();
|
||||||
dstring_t *single_name = dstring_newstr ();
|
dstring_t *single_name = dstring_newstr ();
|
||||||
const char *src;
|
const char *src;
|
||||||
int crc = 0;
|
//int crc = 0;
|
||||||
script_t *script;
|
script_t *script;
|
||||||
FILE *single = 0;
|
FILE *single = 0;
|
||||||
|
qfo_t *qfo;
|
||||||
|
|
||||||
if (options.verbosity >= 1 && strcmp (sourcedir, "")) {
|
if (options.verbosity >= 1 && strcmp (sourcedir, "")) {
|
||||||
printf ("Source directory: %s\n", sourcedir);
|
printf ("Source directory: %s\n", sourcedir);
|
||||||
|
@ -843,9 +640,6 @@ progs_src_compile (void)
|
||||||
|
|
||||||
begin_compilation ();
|
begin_compilation ();
|
||||||
|
|
||||||
if (!options.compile)
|
|
||||||
setup_param_block ();
|
|
||||||
|
|
||||||
// compile all the files
|
// compile all the files
|
||||||
while (Script_GetToken (script, 1)) {
|
while (Script_GetToken (script, 1)) {
|
||||||
if (strcmp (script->token->str, "#") == 0) {
|
if (strcmp (script->token->str, "#") == 0) {
|
||||||
|
@ -891,30 +685,23 @@ progs_src_compile (void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class_finish_module ();
|
||||||
|
qfo = qfo_from_progs (&pr);
|
||||||
if (options.compile) {
|
if (options.compile) {
|
||||||
qfo_t *qfo = qfo_from_progs (&pr);
|
|
||||||
qfo_write (qfo, options.output_file);
|
qfo_write (qfo, options.output_file);
|
||||||
qfo_delete (qfo);
|
|
||||||
} else {
|
} else {
|
||||||
class_finish_module ();
|
linker_begin ();
|
||||||
if (!finish_compilation ()) {
|
if (linker_add_qfo (qfo) || finish_link ()) {
|
||||||
fprintf (stderr, "compilation errors\n");
|
fprintf (stderr, "compilation errors\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write progdefs.h
|
|
||||||
if (options.progdefs_h)
|
|
||||||
crc = WriteProgdefs ("progdefs.h");
|
|
||||||
|
|
||||||
// write data file
|
|
||||||
if (WriteData (crc))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// write files.dat
|
// write files.dat
|
||||||
if (options.files_dat)
|
if (options.files_dat)
|
||||||
if (WriteFiles (sourcedir))
|
if (WriteFiles (sourcedir))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
qfo_delete (qfo);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,9 +258,11 @@ init_qf (void)
|
||||||
static void
|
static void
|
||||||
convert_qfo (void)
|
convert_qfo (void)
|
||||||
{
|
{
|
||||||
|
int size;
|
||||||
int i;
|
int i;
|
||||||
ddef_t *ld;
|
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_statements = P (dstatement_t, ofs_statements);
|
||||||
pr.pr_strings = P (char, ofs_strings);
|
pr.pr_strings = P (char, ofs_strings);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue