From: Robert Pengelly Date: Tue, 15 Apr 2025 23:24:20 +0000 (+0100) Subject: Only relocate MZ and IA16-ELKS X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=9a57d526e7dd89beb1185fef089718679a30c27e;p=slink.git Only relocate MZ and IA16-ELKS --- diff --git a/aout.c b/aout.c index 215b215..c1567c7 100644 --- a/aout.c +++ b/aout.c @@ -58,6 +58,7 @@ static void translate_relocation (struct reloc_entry *reloc, struct aout_relocat reloc->n_type = ((r_symbolnum >> 24) & 0xff); reloc->n_type &= ~(1 << 3); + reloc->r_symbolnum = r_symbolnum; reloc->n_ext = ((r_symbolnum >> 27) & 1); switch (1U << ((r_symbolnum >> 25) & 3)) { @@ -437,7 +438,7 @@ static unsigned char *write_relocs_for_section (unsigned char *pos, struct secti r_symbolnum = N_TEXT; } - if ((part->reloc_arr[i].symbolnum >> 27) & 1) { + if ((part->reloc_arr[i].r_symbolnum >> 27) & 1) { /*report_at (part->of->filename, 0, REPORT_INTERNAL_ERROR, "symbolnum: %lx", part->reloc_arr[i].symbolnum);*/ r_symbolnum |= (1LU << 27); diff --git a/elks.c b/elks.c index 1240571..1c7a2ae 100644 --- a/elks.c +++ b/elks.c @@ -57,8 +57,9 @@ static void translate_relocation (struct reloc_entry *reloc, struct elks_relocat reloc->offset = r_address; reloc->n_type = ((r_symbolnum >> 28) & 0xff); - reloc->n_type &= ~(1 << 4); + reloc->n_type &= ~(1 << 3); + reloc->r_symbolnum = r_symbolnum; reloc->n_ext = ((r_symbolnum >> 31) & 1); switch (1U << ((r_symbolnum >> 29) & 3)) { @@ -438,7 +439,7 @@ static unsigned char *write_relocs_for_section (unsigned char *pos, struct secti r_symbolnum = N_TEXT; } - if ((part->reloc_arr[i].symbolnum >> 27) & 1) { + if ((part->reloc_arr[i].r_symbolnum >> 27) & 1) { r_symbolnum |= (1LU << 27); } diff --git a/link.c b/link.c index c5cd314..b84293b 100644 --- a/link.c +++ b/link.c @@ -391,8 +391,6 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s rel->howto = &reloc_howtos[RELOC_TYPE_PC8]; } - } else { - printf ("%d, %d\n", is_section, rel->n_type); } } @@ -426,104 +424,107 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s /*printf ("%lx\n", n_type);*/ - if (opcode == 0x9A || opcode == 0xFF || rel->n_type == 4) { + if (state->format == LD_FORMAT_MZ || state->format == LD_FORMAT_IA16_ELKS) { - unsigned char *p = part->content + offset; - /*printf ("relocating: %s: %s: %lx, %lx, %d\n", part->of->filename, symbol->name, part->rva + offset + 0x40, rel->symbolnum, rel->n_type);*/ - - if ((opcode != 0x9A && opcode != 0xFF) || result >= 65535) { + if (opcode == 0x9A || opcode == 0xFF || rel->n_type == 4) { - if (opcode == 0xFF) { *(p - 1) = 0x9A; } - - if (rel->howto == &reloc_howtos[RELOC_TYPE_PC64]) { - rel->howto = &reloc_howtos[RELOC_TYPE_64]; - } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC32]) { - rel->howto = &reloc_howtos[RELOC_TYPE_32]; - } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC16]) { - rel->howto = &reloc_howtos[RELOC_TYPE_16]; - } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC8]) { - rel->howto = &reloc_howtos[RELOC_TYPE_8]; - } - - while (rel->howto->size > 2) { - rel->howto->size--; - } - - rel->offset += 2; + unsigned char *p = part->content + offset; + /*printf ("relocating: %s: %s: %lx, %lx, %d\n", part->of->filename, symbol->name, part->rva + offset + 0x40, rel->symbolnum, rel->n_type);*/ - if (result >= dgroup_start) { + if ((opcode != 0x9A && opcode != 0xFF) || result >= 65535) { - unsigned long temp = result - (dgroup_start & 0xfffffff0); - result = (((unsigned long) dgroup_start / 16) << 16) | (unsigned long) temp; - - } else { - result = (((unsigned long) result / 16) << 16) | (unsigned long) result % 16; - } - - /*printf ("relocating: %s: %lx, %lx, %lx\n", rel->symbol->name, part->rva + offset + 0x60, result, size);*/ - size = 4; - - } else if (opcode == 0x9A || opcode == 0xFF) { - - if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) { - rel->howto = &reloc_howtos[RELOC_TYPE_PC64]; - } else if (rel->howto == &reloc_howtos[RELOC_TYPE_32]) { - rel->howto = &reloc_howtos[RELOC_TYPE_PC32]; - } else if (rel->howto == &reloc_howtos[RELOC_TYPE_16]) { - rel->howto = &reloc_howtos[RELOC_TYPE_PC16]; - } else if (rel->howto == &reloc_howtos[RELOC_TYPE_8]) { - rel->howto = &reloc_howtos[RELOC_TYPE_PC8]; - } - - if (opcode == 0x9A) { - - *(p - 1) = 0x0E; - *(p + 0) = 0xE8; - *(p + 3) = 0x90; + if (opcode == 0xFF) { *(p - 1) = 0x9A; } - result -= part->rva + offset; - result -= size; + if (rel->howto == &reloc_howtos[RELOC_TYPE_PC64]) { + rel->howto = &reloc_howtos[RELOC_TYPE_64]; + } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC32]) { + rel->howto = &reloc_howtos[RELOC_TYPE_32]; + } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC16]) { + rel->howto = &reloc_howtos[RELOC_TYPE_16]; + } else if (rel->howto == &reloc_howtos[RELOC_TYPE_PC8]) { + rel->howto = &reloc_howtos[RELOC_TYPE_8]; + } - while (size > 2) { - size--; + while (rel->howto->size > 2) { + rel->howto->size--; } - offset++; - result++; - - } else { - - *(p - 1) = 0x0E; - *(p + 0) = 0x3E; - *(p + 1) = 0xE8; + rel->offset += 2; - result -= part->rva + offset; - result -= size; + if (result >= dgroup_start) { - while (size > 2) { + unsigned long temp = result - (dgroup_start & 0xfffffff0); + result = (((unsigned long) dgroup_start / 16) << 16) | (unsigned long) temp; + } else { + result = (((unsigned long) result / 16) << 16) | (unsigned long) result % 16; + } + + /*printf ("relocating: %s: %lx, %lx, %lx\n", rel->symbol->name, part->rva + offset + 0x60, result, size);*/ + size = 4; + + } else if (opcode == 0x9A || opcode == 0xFF) { + + if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) { + rel->howto = &reloc_howtos[RELOC_TYPE_PC64]; + } else if (rel->howto == &reloc_howtos[RELOC_TYPE_32]) { + rel->howto = &reloc_howtos[RELOC_TYPE_PC32]; + } else if (rel->howto == &reloc_howtos[RELOC_TYPE_16]) { + rel->howto = &reloc_howtos[RELOC_TYPE_PC16]; + } else if (rel->howto == &reloc_howtos[RELOC_TYPE_8]) { + rel->howto = &reloc_howtos[RELOC_TYPE_PC8]; + } + + if (opcode == 0x9A) { + + *(p - 1) = 0x0E; + *(p + 0) = 0xE8; + *(p + 3) = 0x90; + + result -= part->rva + offset; + result -= size; + + while (size > 2) { + size--; + } + offset++; - size--; + result++; + + } else { + + *(p - 1) = 0x0E; + *(p + 0) = 0x3E; + *(p + 1) = 0xE8; + + result -= part->rva + offset; + result -= size; + + while (size > 2) { + + offset++; + size--; + + } } } - } - - } else if (opcode != 0xE8 && has_dgroup && result >= dgroup_start) { - - /*printf ("relocating: %s: %s: %lx, %lx, %d\n", part->of->filename, symbol->name, part->rva + offset + 0x40, rel->symbolnum, rel->n_type);*/ + } else if (opcode != 0xE8 && has_dgroup && result >= dgroup_start) { - if (xstrcasecmp (symbol->name, "DGROUP__edata") != 0 && xstrcasecmp (symbol->name, "DGROUP__end") != 0 && xstrcasecmp (symbol->name, "__etext") != 0 && xstrcasecmp (symbol->name, "__edata") != 0 && xstrcasecmp (symbol->name, "__end") != 0) { - - if (result >= dgroup_start) { - result -= (dgroup_start & 0xfffffff0); + /*printf ("relocating: %s: %s: %lx, %lx, %d\n", part->of->filename, symbol->name, part->rva + offset + 0x40, rel->symbolnum, rel->n_type);*/ + + if (xstrcasecmp (symbol->name, "DGROUP__edata") != 0 && xstrcasecmp (symbol->name, "DGROUP__end") != 0 && xstrcasecmp (symbol->name, "__etext") != 0 && xstrcasecmp (symbol->name, "__edata") != 0 && xstrcasecmp (symbol->name, "__end") != 0) { + + if (result >= dgroup_start) { + result -= (dgroup_start & 0xfffffff0); + } + } } - } switch (size) { diff --git a/reloc.h b/reloc.h index 4c5edd0..a4bb555 100644 --- a/reloc.h +++ b/reloc.h @@ -49,8 +49,8 @@ struct reloc_entry { unsigned long offset; unsigned long addend; + unsigned long symbolnum, r_symbolnum; unsigned int n_type, n_ext; - unsigned long symbolnum; struct reloc_howto *howto;