From: Robert Pengelly Date: Tue, 15 Apr 2025 22:18:01 +0000 (+0100) Subject: Bug fixes which allow all models to work X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=9faa511883e33216141af7842b34ed0c645c4e49;p=slink.git Bug fixes which allow all models to work --- diff --git a/aout.c b/aout.c index fd39cb9..215b215 100644 --- a/aout.c +++ b/aout.c @@ -26,6 +26,8 @@ static void translate_relocation (struct reloc_entry *reloc, struct aout_relocat if (xstrcasecmp (reloc->symbol->name, "DGROUP") == 0) { r_symbolnum &= ~(1LU << 27); } + + symbolnum = (reloc->symbol->n_type & N_TYPE); } else { @@ -50,13 +52,14 @@ static void translate_relocation (struct reloc_entry *reloc, struct aout_relocat } - reloc->symbolnum = r_symbolnum; + reloc->symbolnum = symbolnum; reloc->offset = r_address; - reloc->n_ext = 27; reloc->n_type = ((r_symbolnum >> 24) & 0xff); reloc->n_type &= ~(1 << 3); + reloc->n_ext = ((r_symbolnum >> 27) & 1); + switch (1U << ((r_symbolnum >> 25) & 3)) { case 8: diff --git a/elks.c b/elks.c index a74cfad..1240571 100644 --- a/elks.c +++ b/elks.c @@ -27,6 +27,8 @@ static void translate_relocation (struct reloc_entry *reloc, struct elks_relocat if (xstrcasecmp (reloc->symbol->name, "DGROUP") == 0) { r_symbolnum &= ~(1LU << 31); } + + symbolnum = (reloc->symbol->n_type & N_TYPE); } else { @@ -51,13 +53,14 @@ static void translate_relocation (struct reloc_entry *reloc, struct elks_relocat } - reloc->symbolnum = r_symbolnum; + reloc->symbolnum = symbolnum; reloc->offset = r_address; - reloc->n_ext = 31; reloc->n_type = ((r_symbolnum >> 28) & 0xff); reloc->n_type &= ~(1 << 4); + reloc->n_ext = ((r_symbolnum >> 31) & 1); + switch (1U << ((r_symbolnum >> 29) & 3)) { case 8: diff --git a/ld.c b/ld.c index dc16d54..2b1798b 100644 --- a/ld.c +++ b/ld.c @@ -68,6 +68,8 @@ static int read_file_into_memory (const char *filename, unsigned char **memory_p static void read_object_file (const char *filename, unsigned char *data, unsigned long data_size) { + /*printf ("reading: %s\n", filename);*/ + if (data[0] == 0x01 && data[1] == 0x03) { read_elks_object (filename, data, data_size); } else if (data[0] == 0x07 && data[1] == 0x01) { diff --git a/link.c b/link.c index 79670d7..c5cd314 100644 --- a/link.c +++ b/link.c @@ -363,11 +363,11 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s if (state->format == LD_FORMAT_BIN || state->format == LD_FORMAT_COM) { - if (!((rel->symbolnum >> rel->n_ext) & 1)/* || (symbol->n_type & N_TYPE) == N_BSS || (symbol->n_type & N_TYPE) == N_DATA || (symbol->n_type & N_TYPE) == N_TEXT*/) { + if (!rel->n_ext/* || (symbol->n_type & N_TYPE) == N_BSS || (symbol->n_type & N_TYPE) == N_DATA || (symbol->n_type & N_TYPE) == N_TEXT*/) { /*report_at (__FILE__, __LINE__, REPORT_FATAL_ERROR, "symbol: %s, %lx", symbol->name, ((rel->symbolnum) >> 28));*/ - if (((rel->symbolnum >> 27) & 1) || rel->n_type != 2) { + if (rel->n_type != 2) { report_at (program_name, 0, REPORT_ERROR, "%s:(%s+%#lu): segment relocation", part->of->filename, part->section->name, offset); } @@ -379,7 +379,7 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s int is_section = (xstrcasecmp (symbol->name, ".text") == 0) || (xstrcasecmp (symbol->name, ".data") == 0) || (xstrcasecmp (symbol->name, ".bss") == 0); - if (is_section || (rel->n_type != 4 && rel->n_type != 6 && rel->n_type != 8)) { + if (is_section || (rel->n_type != 4 && rel->n_type != 6 && rel->n_type != 8) || rel->symbolnum == 0 || rel->symbolnum == 4 || rel->symbolnum == 8) { if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) { rel->howto = &reloc_howtos[RELOC_TYPE_PC64]; @@ -391,6 +391,8 @@ 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); } } @@ -424,47 +426,45 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s /*printf ("%lx\n", n_type);*/ - if (opcode == 0xFF || opcode == 0x9A || rel->n_type == 0x04) { + if (opcode == 0x9A || opcode == 0xFF || rel->n_type == 4) { - /*printf ("%lx\n", (rel->symbolnum >> rel->n_type) & 0xff);*/ - 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) { + if (opcode == 0xFF) { *(p - 1) = 0x9A; } - *(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]; + } - 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]; - } - - result = (((unsigned long) result / 16) << 16) | (unsigned long) result % 16; - - /*if (opcode != 0x9A && opcode != 0xFF) { - printf ("%x, %lx, %lx, %lx\n", rel->n_type, part->rva + offset + 0x30, result, size); - }*/ - - while (rel->howto->size > 2) { - - rel->howto->size--; - rel->offset++; - - } + while (rel->howto->size > 2) { + rel->howto->size--; + } + rel->offset += 2; + + if (result >= dgroup_start) { + + 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 { + } else if (opcode == 0x9A || opcode == 0xFF) { - /*printf ("%x, %lx, %lx, %lx\n", rel->n_type, part->rva + offset + 0x30, result, size);*/ - if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) { rel->howto = &reloc_howtos[RELOC_TYPE_PC64]; } else if (rel->howto == &reloc_howtos[RELOC_TYPE_32]) { @@ -511,35 +511,20 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s } - } else if (opcode != 0xE8 && rel->n_type != 0x04) { + } else if (opcode != 0xE8 && has_dgroup && result >= dgroup_start) { - /*if (!rel->howto->pc_rel && !rel->howto->no_base) {*/ - /*if (!((rel->symbolnum >> rel->n_ext) & 1) || symbol->section_number == ABSOLUTE_SECTION_NUMBER) {*/ + /*printf ("relocating: %s: %s: %lx, %lx, %d\n", part->of->filename, symbol->name, part->rva + offset + 0x40, rel->symbolnum, rel->n_type);*/ - if (has_dgroup/* && rel->n_type != N_ABS*/) { - - 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 ("%lx, %lx, %lx\n", part->rva + offset + 0x30, 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) { - /*} else if (result >= dgroup_start && rel->n_type != 2) { - printf ("%x, %lx, %lx, %lx\n", opcode, part->rva + offset + 0x30, result, dgroup_start); - }*/ + if (result >= dgroup_start) { + result -= (dgroup_start & 0xfffffff0); + } - /*printf ("%lx, %lx, %lx, %lx\n", (rel->symbolnum >> rel->n_type) & 0xff, part->rva + offset + 0x30, result, dgroup_start);*/ + } - } - /*if (strcmp (part->section->name, ".text")) { - printf ("%lx, %lx, %lx\n", part->rva + offset + 0x30, result, dgroup_start); - }*/ + } switch (size) { @@ -791,8 +776,10 @@ void link (void) { if ((symbol = symbol_find ("DGROUP")) && symbol_is_undefined (symbol)) { - if ((section = section_find (".text"))) { - value += align_section_if_needed (section->total_size); + if ((section = section_find (".data"))) { + value += align_section_if_needed (section->rva); + } else if ((section = section_find (".bss"))) { + value += align_section_if_needed (section->rva); } dgroup_start = value; @@ -814,12 +801,8 @@ void link (void) { if ((symbol = symbol_find ("DGROUP__edata")) && symbol_is_undefined (symbol)) { - if ((section = section_find (".text"))) { - value += align_section_if_needed (section->total_size); - } - if ((section = section_find (".data"))) { - value += align_section_if_needed (section->total_size); + value += align_section_if_needed (section->rva + section->total_size); } of = object_file_make (FAKE_LD_FILENAME, 1); @@ -839,15 +822,14 @@ void link (void) { if ((symbol = symbol_find ("DGROUP__end")) && symbol_is_undefined (symbol)) { - if ((section = section_find (".data"))) { - value += align_section_if_needed (section->total_size); - } - if ((section = section_find (".bss"))) { - value += align_section_if_needed (section->total_size); + value += align_section_if_needed (section->rva + section->total_size); + } else if ((section = section_find (".data"))) { + value += align_section_if_needed (section->rva + section->total_size); } of = object_file_make (FAKE_LD_FILENAME, 1); + value -= (dgroup_start & 0xfffffff0); symbol = of->symbol_arr; symbol->name = xstrdup ("DGROUP__end"); diff --git a/mz.c b/mz.c index ba735db..e9e43f1 100644 --- a/mz.c +++ b/mz.c @@ -106,36 +106,34 @@ void mz_write (const char *filename) { header_size = ALIGN (sizeof (exec), 16); reloc_size = ALIGN (reloc_count * 4, 16); - data_size += header_size + reloc_size; - ibss_addr += header_size + reloc_size; + if (data_section) { - /*stack_addr += header_size + reloc_size;*/ + if (bss_section) { + data_size += bss_section->rva; + } else { + data_size += data_section->rva + data_section->total_size; + } - if (text_section) { + } else { - data_size += text_section->total_size; - ibss_addr += text_section->total_size; - - stack_addr += text_section->total_size; + if (bss_section) { + data_size += bss_section->rva; + } else if (text_section) { + data_size += text_section->total_size; + } } - if (data_section) { - - data_size += data_section->total_size; - ibss_addr += data_section->total_size; - - stack_addr += data_section->total_size; - - } + data_size += header_size + reloc_size; + ibss_addr = data_size; if (bss_section) { ibss_size = bss_section->total_size; } - stack_addr = ALIGN (stack_addr + ibss_size, 16); - /*stack_addr = ALIGN (ibss_addr + ibss_size, 16);*/ - stack_size = 0x1000; /* Maybe get this from command line in the future. */ + stack_addr = ALIGN (ibss_addr + ibss_size, 16); + stack_size = 0x2000; /* Maybe get this from command line in the future. */ + exec.e_magic[0] = 'M'; exec.e_magic[1] = 'Z'; @@ -162,25 +160,35 @@ void mz_write (const char *filename) { pos = data + header_size; - if (text_section) { - pos = write_relocs_for_section (pos, text_section); - } + if (reloc_count) { + + if (text_section) { + pos = write_relocs_for_section (pos, text_section); + } + + if (data_section) { + pos = write_relocs_for_section (pos, data_section); + } - if (data_section) { - pos = write_relocs_for_section (pos, data_section); } - pos = data + header_size + reloc_size; + pos = data; + + pos += header_size; + pos += reloc_size; if (text_section) { + pos += text_section->rva; section_write (text_section, pos); - pos += text_section->total_size; } if (data_section) { + + pos += data_section->rva; section_write (data_section, pos); + } if (fwrite (data, data_size, 1, fp) != 1) {