From 51236b0693916f5a42fcd08de5055e9f74b3ca7d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 14 Nov 2012 10:29:45 +0900 Subject: [PATCH] Fix the incorrect type space reloc offsets. The problem was caused by add_relocs and process_loose_relocs adjusting the reloc offset based on the reloc's space's base address. This is fine for most relocs, but as relocs for the type space have already been adjusted by process_type_space, those relocs must be left alone by add_relocs and process_loose_relocs. As a bonus, the duplicate code has been refactored into a separate function :) --- tools/qfcc/source/linker.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index 8261ad18f..0e59cae9e 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -401,6 +401,20 @@ process_type_def (defref_t *ref, qfo_mspace_t *space, qfo_def_t *old) } } +static void +adjust_reloc_offset (qfo_reloc_t *reloc) +{ + if (!reloc->space) { + //FIXME double check + reloc->offset += work_base[qfo_code_space]; + } else if (reloc->space < qfo_num_spaces) { + // Relocs in type space are handled by process_type_space, so don't + // touch them here. + if (reloc->space != qfo_type_space) + reloc->offset += work_base[reloc->space]; + } +} + static int add_relocs (qfo_t *qfo, int start, int count, int target) { @@ -420,12 +434,7 @@ add_relocs (qfo_t *qfo, int start, int count, int target) continue; } reloc->space = qfo->spaces[reloc->space].id; - if (!reloc->space) { - //FIXME double check - reloc->offset += work_base[qfo_code_space]; - } else if (reloc->space < qfo_num_spaces) { - reloc->offset += work_base[reloc->space]; - } + adjust_reloc_offset (reloc); reloc->target = target; } return work->num_relocs - count; @@ -872,12 +881,7 @@ process_loose_relocs (qfo_t *qfo) } if (reloc->type == rel_def_op) reloc->target += work_base[qfo_code_space]; - if (!reloc->space) { - //FIXME double check - reloc->offset += work_base[qfo_code_space]; - } else if (reloc->space < qfo_num_spaces) { - reloc->offset += work_base[reloc->space]; - } + adjust_reloc_offset (reloc); } }