diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 3eb673fbc..db3bb308f 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -65,6 +65,8 @@ typedef struct pr_info_s { string_t source_file; int source_line; int error_count; + + struct reloc_s *relocs; } pr_info_t; extern pr_info_t pr; diff --git a/tools/qfcc/source/immediate.c b/tools/qfcc/source/immediate.c index a4b717f77..0942a4f7c 100644 --- a/tools/qfcc/source/immediate.c +++ b/tools/qfcc/source/immediate.c @@ -38,6 +38,7 @@ static const char rcsid[] = #include "def.h" #include "expr.h" #include "immediate.h" +#include "reloc.h" #include "strpool.h" #include "type.h" @@ -109,6 +110,7 @@ ReuseConstant (expr_t *expr, def_t *def) hashtab_t *tab = 0; type_t *type; expr_t e = *expr; + reloc_t *reloc = 0; if (!rep) rep = dstring_newstr (); @@ -218,8 +220,21 @@ ReuseConstant (expr_t *expr, def_t *def) } cn->initialized = cn->constant = 1; // copy the immediate to the global area - if (e.type == ex_string) - e.e.integer_val = ReuseString (rep->str); + switch (e.type) { + case ex_string: + e.e.integer_val = ReuseString (rep->str); + reloc = new_reloc (cn->ofs, rel_def_string); + break; + case ex_func: + reloc = new_reloc (cn->ofs, rel_def_func); + break; + default: + break; + } + if (reloc) { + reloc->next = pr.relocs; + pr.relocs = reloc; + } memcpy (G_POINTER (void, cn->ofs), &e.e, 4 * type_size (type)); diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 88204cb02..95ba9e571 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -96,6 +96,7 @@ allocate_stuff (void) } } } + num_relocs += count_relocs (pr.relocs); defs = calloc (num_defs, sizeof (qfo_def_t)); functions = calloc (num_functions, sizeof (qfo_function_t)); relocs = calloc (num_relocs, sizeof (qfo_reloc_t)); @@ -200,6 +201,7 @@ setup_data (void) for (d = f->scope->head; d; d = d->def_next) write_def (d, def++, &reloc); } + write_relocs (pr.relocs, &reloc); for (st = pr.code->code; st - pr.code->code < pr.code->size; st++) { st->op = LittleLong (st->op); st->a = LittleLong (st->a); @@ -428,9 +430,10 @@ defspace_t * init_space (int size, pr_type_t *data) { defspace_t *space = new_defspace (); - space->max_size = space->size = size; + space->size = size; + space->max_size = RUP (space->size, 65536); if (size && data) { - space->data = malloc (size * sizeof (pr_type_t)); + space->data = malloc (space->max_size * sizeof (pr_type_t)); memcpy (space->data, data, size * sizeof (pr_type_t)); } return space; @@ -461,11 +464,12 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr) pr->near_data = init_space (qfo->data_size, qfo->data); pr->far_data = init_space (qfo->far_data_size, qfo->far_data); + pr->entity_data = new_defspace (); pr->scope = new_scope (sc_global, pr->near_data, 0); pr->scope->num_defs = qfo->num_defs; pr->scope->head = calloc (pr->scope->num_defs, sizeof (def_t)); for (i = 0, pd = pr->scope->head, qd = qfo->defs; - i < pr->scope->num_defs; i++) { + i < pr->scope->num_defs; i++, pd++) { *pr->scope->tail = pd; pr->scope->tail = &pd->def_next; pd->type = parse_type (qfo->types + qd->full_type); @@ -488,7 +492,7 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr) pr->func_head = calloc (pr->num_functions, sizeof (function_t)); pr->func_tail = &pr->func_head; for (i = 0, pf = pr->func_head, qf = qfo->functions; - i < pr->num_functions; i++) { + i < pr->num_functions; i++, pf++) { *pr->func_tail = pf; pr->func_tail = &pf->next; pf->aux = new_auxfunction (); @@ -501,12 +505,15 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr) pf->code = qf->code; pf->function_num = i + 1; pf->s_file = qf->file; + pf->s_name = qf->name; pf->file_line = qf->line; + pf->def = pr->scope->head + qf->def; pf->scope = new_scope (sc_params, init_space (qf->locals_size, 0), pr->scope); if (qf->num_local_defs) { pf->scope->head = pr->scope->head + qf->local_defs; pf->scope->tail = &pf->scope->head[qf->num_local_defs - 1].def_next; + *pf->scope->tail = 0; } if (qf->num_relocs) { pf->refs = relocs + qf->relocs; diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index e7b3fd0b7..1fb440dab 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -548,6 +548,7 @@ separate_compile (void) qfo = linker_finish (); if (qfo) { qfo_to_progs (qfo, &pr); + setup_sym_file (options.output_file); finish_compilation (); WriteData (0); }