mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
re-write qfo writing from progs, make qfo creation easier, (mostly) finish
the linker. now for testing :)
This commit is contained in:
parent
4b83c6592c
commit
4d1dbc8cc1
4 changed files with 135 additions and 58 deletions
|
@ -132,8 +132,13 @@ typedef struct qfo_s {
|
||||||
#define QFO_POINTER(q, t,o) ((t *)((q)->data + o))
|
#define QFO_POINTER(q, t,o) ((t *)((q)->data + o))
|
||||||
#define QFO_STRUCT(q, t,o) (*QFO_POINTER (q, t, o))
|
#define QFO_STRUCT(q, t,o) (*QFO_POINTER (q, t, o))
|
||||||
|
|
||||||
int write_obj_file (const char *filename);
|
struct pr_info_s;
|
||||||
qfo_t *read_obj_file (const char *filename);
|
|
||||||
|
qfo_t *qfo_from_progs (struct pr_info_s *pr);
|
||||||
|
int qfo_write (qfo_t *qfo, const char *filename);
|
||||||
|
qfo_t *qfo_read (const char *filename);
|
||||||
|
int qfo_to_progs (qfo_t *qfo, struct pr_info_s *pr);
|
||||||
|
|
||||||
qfo_t *qfo_new (void);
|
qfo_t *qfo_new (void);
|
||||||
void qfo_add_code (qfo_t *qfo, dstatement_t *code, int code_size);
|
void qfo_add_code (qfo_t *qfo, dstatement_t *code, int code_size);
|
||||||
void qfo_add_data (qfo_t *qfo, pr_type_t *data, int data_size);
|
void qfo_add_data (qfo_t *qfo, pr_type_t *data, int data_size);
|
||||||
|
@ -142,6 +147,7 @@ void qfo_add_strings (qfo_t *qfo, const char *strings, int strings_size);
|
||||||
void qfo_add_relocs (qfo_t *qfo, qfo_reloc_t *relocs, int num_relocs);
|
void qfo_add_relocs (qfo_t *qfo, qfo_reloc_t *relocs, int num_relocs);
|
||||||
void qfo_add_defs (qfo_t *qfo, qfo_def_t *defs, int num_defs);
|
void qfo_add_defs (qfo_t *qfo, qfo_def_t *defs, int num_defs);
|
||||||
void qfo_add_functions (qfo_t *qfo, qfo_function_t *functions, int num_functions);
|
void qfo_add_functions (qfo_t *qfo, qfo_function_t *functions, int num_functions);
|
||||||
|
void qfo_add_lines (qfo_t *qfo, pr_lineno_t *lines, int num_lines);
|
||||||
void qfo_add_types (qfo_t *qfo, const char *types, int types_size);
|
void qfo_add_types (qfo_t *qfo, const char *types, int types_size);
|
||||||
void qfo_delete (qfo_t *qfo);
|
void qfo_delete (qfo_t *qfo);
|
||||||
|
|
||||||
|
|
|
@ -75,12 +75,18 @@ static struct {
|
||||||
int num_funcs;
|
int num_funcs;
|
||||||
int max_funcs;
|
int max_funcs;
|
||||||
} funcs;
|
} funcs;
|
||||||
|
static struct {
|
||||||
|
pr_lineno_t *lines;
|
||||||
|
int num_lines;
|
||||||
|
int max_lines;
|
||||||
|
} lines;
|
||||||
static int code_base;
|
static int code_base;
|
||||||
static int data_base;
|
static int data_base;
|
||||||
static int far_data_base;
|
static int far_data_base;
|
||||||
static int reloc_base;
|
static int reloc_base;
|
||||||
static int def_base;
|
static int def_base;
|
||||||
static int func_base;
|
static int func_base;
|
||||||
|
static int line_base;
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
defs_get_key (void *_def, void *unused)
|
defs_get_key (void *_def, void *unused)
|
||||||
|
@ -219,10 +225,34 @@ add_funcs (qfo_t *qfo)
|
||||||
func->def += def_base;
|
func->def += def_base;
|
||||||
if (func->local_defs)
|
if (func->local_defs)
|
||||||
func->local_defs += def_base;
|
func->local_defs += def_base;
|
||||||
|
if (func->line_info)
|
||||||
|
func->line_info += line_base;
|
||||||
func->relocs += reloc_base;
|
func->relocs += reloc_base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_lines (qfo_t *qfo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (lines.num_lines + qfo->num_lines > lines.max_lines) {
|
||||||
|
lines.max_lines = RUP (lines.num_lines + qfo->num_lines, 16384);
|
||||||
|
lines.lines = realloc (lines.lines,
|
||||||
|
lines.max_lines * sizeof (pr_lineno_t));
|
||||||
|
}
|
||||||
|
lines.num_lines += qfo->num_lines;
|
||||||
|
memcpy (lines.lines + line_base, qfo->lines,
|
||||||
|
qfo->num_lines * sizeof (pr_lineno_t));
|
||||||
|
for (i = line_base; i < lines.num_lines; i++) {
|
||||||
|
pr_lineno_t *line = lines.lines + i;
|
||||||
|
if (line->line)
|
||||||
|
line->fa.addr += code_base;
|
||||||
|
else
|
||||||
|
line->fa.func += func_base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fixup_relocs (qfo_t *qfo)
|
fixup_relocs (qfo_t *qfo)
|
||||||
{
|
{
|
||||||
|
@ -283,7 +313,7 @@ linker_add_object_file (const char *filename)
|
||||||
{
|
{
|
||||||
qfo_t *qfo;
|
qfo_t *qfo;
|
||||||
|
|
||||||
qfo = read_obj_file (filename);
|
qfo = qfo_read (filename);
|
||||||
if (!qfo)
|
if (!qfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -295,6 +325,7 @@ linker_add_object_file (const char *filename)
|
||||||
reloc_base = relocs.num_relocs;
|
reloc_base = relocs.num_relocs;
|
||||||
def_base = defs.num_defs;
|
def_base = defs.num_defs;
|
||||||
func_base = funcs.num_funcs;
|
func_base = funcs.num_funcs;
|
||||||
|
line_base = lines.num_lines;
|
||||||
|
|
||||||
codespace_addcode (code, qfo->code, qfo->code_size);
|
codespace_addcode (code, qfo->code, qfo->code_size);
|
||||||
defspace_adddata (data, qfo->data, qfo->data_size);
|
defspace_adddata (data, qfo->data, qfo->data_size);
|
||||||
|
@ -303,6 +334,7 @@ linker_add_object_file (const char *filename)
|
||||||
add_relocs (qfo);
|
add_relocs (qfo);
|
||||||
add_defs (qfo);
|
add_defs (qfo);
|
||||||
add_funcs (qfo);
|
add_funcs (qfo);
|
||||||
|
add_lines (qfo);
|
||||||
|
|
||||||
fixup_relocs (qfo);
|
fixup_relocs (qfo);
|
||||||
|
|
||||||
|
|
|
@ -170,9 +170,9 @@ setup_data (void)
|
||||||
pr_type_t *var;
|
pr_type_t *var;
|
||||||
pr_lineno_t *line;
|
pr_lineno_t *line;
|
||||||
|
|
||||||
for (d = pr.scope->head; d; d = d->def_next)
|
for (d = pr.scope->head; d; d = d->def_next, def++)
|
||||||
write_def (d, def++, &reloc);
|
write_def (d, def, &reloc);
|
||||||
for (f = pr.func_head; f; f = f->next) {
|
for (f = pr.func_head; f; f = f->next, func++) {
|
||||||
func->name = LittleLong (f->s_name);
|
func->name = LittleLong (f->s_name);
|
||||||
func->file = LittleLong (f->s_file);
|
func->file = LittleLong (f->s_file);
|
||||||
func->line = LittleLong (f->def->line);
|
func->line = LittleLong (f->def->line);
|
||||||
|
@ -219,71 +219,87 @@ setup_data (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
qfo_t *
|
||||||
write_obj_file (const char *filename)
|
qfo_from_progs (pr_info_t *pr)
|
||||||
{
|
{
|
||||||
qfo_header_t hdr;
|
qfo_t *qfo;
|
||||||
VFile *file;
|
|
||||||
|
|
||||||
types = strpool_new ();
|
types = strpool_new ();
|
||||||
allocate_stuff ();
|
allocate_stuff ();
|
||||||
setup_data ();
|
setup_data ();
|
||||||
|
|
||||||
file = Qopen (filename, "wbz9");
|
pr->strings->size = RUP (pr->strings->size, 4);
|
||||||
|
types->size = RUP (types->size, 4);
|
||||||
|
|
||||||
pr.strings->size = (pr.strings->size + 3) & ~3;
|
qfo = qfo_new ();
|
||||||
types->size = (types->size + 3) & ~3;
|
qfo_add_code (qfo, pr->code->code, pr->code->size);
|
||||||
|
qfo_add_data (qfo, pr->near_data->data, pr->near_data->size);
|
||||||
memset (&hdr, 0, sizeof (hdr));
|
if (pr->far_data)
|
||||||
|
qfo_add_far_data (qfo, pr->far_data->data, pr->far_data->size);
|
||||||
memcpy (hdr.qfo, QFO, sizeof (hdr.qfo));
|
qfo_add_strings (qfo, pr->strings->strings, pr->strings->size);
|
||||||
hdr.version = LittleLong (QFO_VERSION);
|
qfo_add_relocs (qfo, relocs, num_relocs);
|
||||||
hdr.code_size = LittleLong (pr.code->size);
|
qfo_add_defs (qfo, defs, num_defs);
|
||||||
hdr.data_size = LittleLong (pr.near_data->size);
|
qfo_add_functions (qfo, functions, num_functions);
|
||||||
if (pr.far_data) {
|
qfo_add_lines (qfo, linenos, num_linenos);
|
||||||
hdr.far_data_size = LittleLong (pr.far_data->size);
|
qfo_add_types (qfo, types->strings, types->size);
|
||||||
}
|
|
||||||
hdr.strings_size = LittleLong (pr.strings->size);
|
|
||||||
hdr.num_relocs = LittleLong (num_relocs);
|
|
||||||
hdr.num_defs = LittleLong (num_defs);
|
|
||||||
hdr.num_functions = LittleLong (num_functions);
|
|
||||||
hdr.num_lines = LittleLong (num_linenos);
|
|
||||||
hdr.types_size = LittleLong (types->size);
|
|
||||||
|
|
||||||
Qwrite (file, &hdr, sizeof (hdr));
|
|
||||||
if (pr.code->size)
|
|
||||||
Qwrite (file, pr.code->code, pr.code->size * sizeof (dstatement_t));
|
|
||||||
if (pr.near_data->size)
|
|
||||||
Qwrite (file, pr.near_data->data,
|
|
||||||
pr.near_data->size * sizeof (pr_type_t));
|
|
||||||
if (pr.far_data && pr.far_data->size) {
|
|
||||||
Qwrite (file, pr.far_data->data,
|
|
||||||
pr.far_data->size * sizeof (pr_type_t));
|
|
||||||
}
|
|
||||||
if (pr.strings->size)
|
|
||||||
Qwrite (file, pr.strings->strings, pr.strings->size);
|
|
||||||
if (num_relocs)
|
|
||||||
Qwrite (file, relocs, num_relocs * sizeof (qfo_reloc_t));
|
|
||||||
if (num_defs)
|
|
||||||
Qwrite (file, defs, num_defs * sizeof (qfo_def_t));
|
|
||||||
if (num_functions)
|
|
||||||
Qwrite (file, functions, num_functions * sizeof (qfo_function_t));
|
|
||||||
if (num_linenos)
|
|
||||||
Qwrite (file, linenos, num_linenos * sizeof (pr_lineno_t));
|
|
||||||
if (types->size)
|
|
||||||
Qwrite (file, types->strings, types->size);
|
|
||||||
|
|
||||||
Qclose (file);
|
|
||||||
|
|
||||||
free (defs);
|
free (defs);
|
||||||
free (relocs);
|
free (relocs);
|
||||||
free (functions);
|
free (functions);
|
||||||
strpool_delete (types);
|
strpool_delete (types);
|
||||||
|
return qfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qfo_write (qfo_t *qfo, const char *filename)
|
||||||
|
{
|
||||||
|
qfo_header_t hdr;
|
||||||
|
VFile *file;
|
||||||
|
|
||||||
|
file = Qopen (filename, "wbz9");
|
||||||
|
|
||||||
|
memset (&hdr, 0, sizeof (hdr));
|
||||||
|
|
||||||
|
memcpy (hdr.qfo, QFO, sizeof (hdr.qfo));
|
||||||
|
hdr.version = LittleLong (QFO_VERSION);
|
||||||
|
hdr.code_size = LittleLong (qfo->code_size);
|
||||||
|
hdr.data_size = LittleLong (qfo->data_size);
|
||||||
|
hdr.far_data_size = LittleLong (qfo->far_data_size);
|
||||||
|
hdr.strings_size = LittleLong (qfo->strings_size);
|
||||||
|
hdr.num_relocs = LittleLong (qfo->num_relocs);
|
||||||
|
hdr.num_defs = LittleLong (qfo->num_defs);
|
||||||
|
hdr.num_functions = LittleLong (qfo->num_functions);
|
||||||
|
hdr.num_lines = LittleLong (qfo->num_lines);
|
||||||
|
hdr.types_size = LittleLong (qfo->types_size);
|
||||||
|
|
||||||
|
Qwrite (file, &hdr, sizeof (hdr));
|
||||||
|
if (qfo->code_size)
|
||||||
|
Qwrite (file, qfo->code, qfo->code_size * sizeof (dstatement_t));
|
||||||
|
if (qfo->data_size)
|
||||||
|
Qwrite (file, qfo->data, qfo->data_size * sizeof (pr_type_t));
|
||||||
|
if (qfo->far_data_size)
|
||||||
|
Qwrite (file, qfo->far_data, qfo->far_data_size * sizeof (pr_type_t));
|
||||||
|
if (qfo->strings_size)
|
||||||
|
Qwrite (file, qfo->strings, qfo->strings_size);
|
||||||
|
if (qfo->num_relocs)
|
||||||
|
Qwrite (file, qfo->relocs, qfo->num_relocs * sizeof (qfo_reloc_t));
|
||||||
|
if (qfo->num_defs)
|
||||||
|
Qwrite (file, qfo->defs, qfo->num_defs * sizeof (qfo_def_t));
|
||||||
|
if (qfo->num_functions)
|
||||||
|
Qwrite (file, qfo->functions,
|
||||||
|
qfo->num_functions * sizeof (qfo_function_t));
|
||||||
|
if (qfo->num_lines)
|
||||||
|
Qwrite (file, qfo->lines, qfo->num_lines * sizeof (pr_lineno_t));
|
||||||
|
if (qfo->types_size)
|
||||||
|
Qwrite (file, qfo->types, qfo->types_size);
|
||||||
|
|
||||||
|
Qclose (file);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qfo_t *
|
qfo_t *
|
||||||
read_obj_file (const char *filename)
|
qfo_read (const char *filename)
|
||||||
{
|
{
|
||||||
VFile *file;
|
VFile *file;
|
||||||
qfo_header_t hdr;
|
qfo_header_t hdr;
|
||||||
|
@ -510,6 +526,7 @@ void
|
||||||
qfo_add_code (qfo_t *qfo, dstatement_t *code, int code_size)
|
qfo_add_code (qfo_t *qfo, dstatement_t *code, int code_size)
|
||||||
{
|
{
|
||||||
qfo->code = malloc (code_size * sizeof (dstatement_t));
|
qfo->code = malloc (code_size * sizeof (dstatement_t));
|
||||||
|
qfo->code_size = code_size;
|
||||||
memcpy (qfo->code, code, code_size * sizeof (dstatement_t));
|
memcpy (qfo->code, code, code_size * sizeof (dstatement_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,6 +534,7 @@ void
|
||||||
qfo_add_data (qfo_t *qfo, pr_type_t *data, int data_size)
|
qfo_add_data (qfo_t *qfo, pr_type_t *data, int data_size)
|
||||||
{
|
{
|
||||||
qfo->data = malloc (data_size * sizeof (pr_type_t));
|
qfo->data = malloc (data_size * sizeof (pr_type_t));
|
||||||
|
qfo->data_size = data_size;
|
||||||
memcpy (qfo->data, data, data_size * sizeof (pr_type_t));
|
memcpy (qfo->data, data, data_size * sizeof (pr_type_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,6 +542,7 @@ void
|
||||||
qfo_add_far_data (qfo_t *qfo, pr_type_t *far_data, int far_data_size)
|
qfo_add_far_data (qfo_t *qfo, pr_type_t *far_data, int far_data_size)
|
||||||
{
|
{
|
||||||
qfo->far_data = malloc (far_data_size * sizeof (pr_type_t));
|
qfo->far_data = malloc (far_data_size * sizeof (pr_type_t));
|
||||||
|
qfo->far_data_size = far_data_size;
|
||||||
memcpy (qfo->far_data, far_data, far_data_size * sizeof (pr_type_t));
|
memcpy (qfo->far_data, far_data, far_data_size * sizeof (pr_type_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,6 +550,7 @@ void
|
||||||
qfo_add_strings (qfo_t *qfo, const char *strings, int strings_size)
|
qfo_add_strings (qfo_t *qfo, const char *strings, int strings_size)
|
||||||
{
|
{
|
||||||
qfo->strings = malloc (strings_size);
|
qfo->strings = malloc (strings_size);
|
||||||
|
qfo->strings_size = strings_size;
|
||||||
memcpy (qfo->strings, strings, strings_size);
|
memcpy (qfo->strings, strings, strings_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,6 +558,7 @@ void
|
||||||
qfo_add_relocs (qfo_t *qfo, qfo_reloc_t *relocs, int num_relocs)
|
qfo_add_relocs (qfo_t *qfo, qfo_reloc_t *relocs, int num_relocs)
|
||||||
{
|
{
|
||||||
qfo->relocs = malloc (num_relocs * sizeof (qfo_reloc_t));
|
qfo->relocs = malloc (num_relocs * sizeof (qfo_reloc_t));
|
||||||
|
qfo->num_relocs = num_relocs;
|
||||||
memcpy (qfo->relocs, relocs, num_relocs * sizeof (qfo_reloc_t));
|
memcpy (qfo->relocs, relocs, num_relocs * sizeof (qfo_reloc_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,6 +566,7 @@ void
|
||||||
qfo_add_defs (qfo_t *qfo, qfo_def_t *defs, int num_defs)
|
qfo_add_defs (qfo_t *qfo, qfo_def_t *defs, int num_defs)
|
||||||
{
|
{
|
||||||
qfo->defs = malloc (num_defs * sizeof (qfo_def_t));
|
qfo->defs = malloc (num_defs * sizeof (qfo_def_t));
|
||||||
|
qfo->num_defs = num_defs;
|
||||||
memcpy (qfo->defs, defs, num_defs * sizeof (qfo_def_t));
|
memcpy (qfo->defs, defs, num_defs * sizeof (qfo_def_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,13 +574,23 @@ void
|
||||||
qfo_add_functions (qfo_t *qfo, qfo_function_t *functions, int num_functions)
|
qfo_add_functions (qfo_t *qfo, qfo_function_t *functions, int num_functions)
|
||||||
{
|
{
|
||||||
qfo->functions = malloc (num_functions * sizeof (qfo_function_t));
|
qfo->functions = malloc (num_functions * sizeof (qfo_function_t));
|
||||||
|
qfo->num_functions = num_functions;
|
||||||
memcpy (qfo->functions, functions, num_functions * sizeof (qfo_function_t));
|
memcpy (qfo->functions, functions, num_functions * sizeof (qfo_function_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qfo_add_lines (qfo_t *qfo, pr_lineno_t *lines, int num_lines)
|
||||||
|
{
|
||||||
|
qfo->lines = malloc (num_lines * sizeof (pr_lineno_t));
|
||||||
|
qfo->num_lines = num_lines;
|
||||||
|
memcpy (qfo->lines, lines, num_lines * sizeof (pr_lineno_t));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
qfo_add_types (qfo_t *qfo, const char *types, int types_size)
|
qfo_add_types (qfo_t *qfo, const char *types, int types_size)
|
||||||
{
|
{
|
||||||
qfo->types = malloc (types_size);
|
qfo->types = malloc (types_size);
|
||||||
|
qfo->types_size = types_size;
|
||||||
memcpy (qfo->types, types, types_size);
|
memcpy (qfo->types, types, types_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,6 +613,8 @@ qfo_delete (qfo_t *qfo)
|
||||||
free (qfo->defs);
|
free (qfo->defs);
|
||||||
if (qfo->functions)
|
if (qfo->functions)
|
||||||
free (qfo->functions);
|
free (qfo->functions);
|
||||||
|
if (qfo->lines)
|
||||||
|
free (qfo->lines);
|
||||||
if (qfo->types)
|
if (qfo->types)
|
||||||
free (qfo->types);
|
free (qfo->types);
|
||||||
free (qfo);
|
free (qfo);
|
||||||
|
|
|
@ -488,8 +488,11 @@ compile_to_obj (const char *file, const char *obj)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!err)
|
if (!err) {
|
||||||
write_obj_file (obj);
|
qfo_t *qfo = qfo_from_progs (&pr);
|
||||||
|
err = qfo_write (qfo, obj);
|
||||||
|
qfo_delete (qfo);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +618,9 @@ progs_src_compile (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.compile) {
|
if (options.compile) {
|
||||||
write_obj_file (options.output_file);
|
qfo_t *qfo = qfo_from_progs (&pr);
|
||||||
|
qfo_write (qfo, options.output_file);
|
||||||
|
qfo_delete (qfo);
|
||||||
} else {
|
} else {
|
||||||
if (!finish_compilation ()) {
|
if (!finish_compilation ()) {
|
||||||
fprintf (stderr, "compilation errors\n");
|
fprintf (stderr, "compilation errors\n");
|
||||||
|
|
Loading…
Reference in a new issue