From 2565e0db323f49ae95619b99d1ad3da7f8443c96 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 4 Mar 2011 21:29:47 +0900 Subject: [PATCH] Update reloc targets when linking. --- tools/qfcc/source/linker.c | 42 +++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index 1f431c8cb..0594a6b97 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -770,7 +770,16 @@ process_loose_relocs (qfo_t *qfo) reloc->type = rel_none; continue; } + if (reloc->space == qfo_type_defs - qfo->spaces) { + // loose relocs in the type space become invalid + reloc->type = rel_none; + continue; + } reloc->space = qfo->spaces[reloc->space].id; + if (reloc->type == rel_def_string) { + const char *str = QFO_GSTRING (qfo, reloc->space, reloc->offset); + reloc->target = linker_add_string (str); + } if (reloc->space < qfo_num_spaces) reloc->offset += work_base[reloc->space]; } @@ -1028,7 +1037,7 @@ build_qfo (void) { qfo_t *qfo; int size; - int i; + int i, j; qfo_mspace_t *space; qfo_reloc_t *reloc; qfo_def_t **defs; @@ -1073,25 +1082,34 @@ build_qfo (void) } for (i = 0; i < num_work_defrefs; i++) { defref_t *r = work_defrefs[i]; + qfo_def_t *def; qfo_def_t d; int space; if (r->merge) continue; space = r->space; - d = *REF (r); + def = REF (r); + d = *def; 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; + memcpy (reloc, work->relocs + def->relocs, + def->num_relocs * sizeof (qfo_reloc_t)); r->def = defs[space] - qfo->defs; + for (j = 0; j < def->num_relocs; j++) { + reloc->target = r->def; + reloc++; + } // 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; + def = REF (r); + memcpy (reloc, work->relocs + def->relocs, + def->num_relocs * sizeof (qfo_reloc_t)); + d.num_relocs += def->num_relocs; r->space = space; r->def = defs[space] - qfo->defs; + for (j = 0; j < def->num_relocs; j++) { + reloc->target = r->def; + reloc++; + } } *defs[space]++ = d; } @@ -1100,7 +1118,11 @@ build_qfo (void) f->def = work_defrefs[f->def]->def; memcpy (reloc, work->relocs + f->relocs, f->num_relocs * sizeof (qfo_reloc_t)); - reloc += f->num_relocs; + f->relocs = reloc - qfo->relocs; + for (j = 0; j < f->num_relocs; j++) { + reloc->target = i; + reloc++; + } } return qfo; }