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 :)
This commit is contained in:
Bill Currie 2012-11-14 10:29:45 +09:00
parent 31739f4dbf
commit 51236b0693

View file

@ -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 static int
add_relocs (qfo_t *qfo, int start, int count, int target) 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; continue;
} }
reloc->space = qfo->spaces[reloc->space].id; reloc->space = qfo->spaces[reloc->space].id;
if (!reloc->space) { adjust_reloc_offset (reloc);
//FIXME double check
reloc->offset += work_base[qfo_code_space];
} else if (reloc->space < qfo_num_spaces) {
reloc->offset += work_base[reloc->space];
}
reloc->target = target; reloc->target = target;
} }
return work->num_relocs - count; return work->num_relocs - count;
@ -872,12 +881,7 @@ process_loose_relocs (qfo_t *qfo)
} }
if (reloc->type == rel_def_op) if (reloc->type == rel_def_op)
reloc->target += work_base[qfo_code_space]; reloc->target += work_base[qfo_code_space];
if (!reloc->space) { adjust_reloc_offset (reloc);
//FIXME double check
reloc->offset += work_base[qfo_code_space];
} else if (reloc->space < qfo_num_spaces) {
reloc->offset += work_base[reloc->space];
}
} }
} }