From: Robert Pengelly Date: Mon, 14 Apr 2025 03:34:54 +0000 (+0100) Subject: Fixes for large model X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=db15f87346868651da82c2525e4a96fcfea6cccc;p=slink.git Fixes for large model --- diff --git a/aout.c b/aout.c index 4c49610..fd39cb9 100644 --- a/aout.c +++ b/aout.c @@ -52,9 +52,11 @@ static void translate_relocation (struct reloc_entry *reloc, struct aout_relocat reloc->symbolnum = r_symbolnum; reloc->offset = r_address; - reloc->n_type = 24; reloc->n_ext = 27; + reloc->n_type = ((r_symbolnum >> 24) & 0xff); + reloc->n_type &= ~(1 << 3); + switch (1U << ((r_symbolnum >> 25) & 3)) { case 8: diff --git a/elks.c b/elks.c index 6db7e50..a74cfad 100644 --- a/elks.c +++ b/elks.c @@ -53,9 +53,11 @@ static void translate_relocation (struct reloc_entry *reloc, struct elks_relocat reloc->symbolnum = r_symbolnum; reloc->offset = r_address; - reloc->n_type = 28; reloc->n_ext = 31; + reloc->n_type = ((r_symbolnum >> 28) & 0xff); + reloc->n_type &= ~(1 << 4); + switch (1U << ((r_symbolnum >> 29) & 3)) { case 8: diff --git a/link.c b/link.c index 578f17c..79670d7 100644 --- a/link.c +++ b/link.c @@ -367,7 +367,7 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s /*report_at (__FILE__, __LINE__, REPORT_FATAL_ERROR, "symbol: %s, %lx", symbol->name, ((rel->symbolnum) >> 28));*/ - if (((rel->symbolnum >> 27) & 1) || ((rel->symbolnum >> rel->n_type) & 0xff) != 2) { + if (((rel->symbolnum >> 27) & 1) || 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->symbolnum >> rel->n_type) & 0xff) != 4 && ((rel->symbolnum >> rel->n_type) & 0xff) != 6 && ((rel->symbolnum >> rel->n_type) & 0xff) != 8)) { + if (is_section || (rel->n_type != 4 && rel->n_type != 6 && rel->n_type != 8)) { if (rel->howto == &reloc_howtos[RELOC_TYPE_64]) { rel->howto = &reloc_howtos[RELOC_TYPE_PC64]; @@ -397,7 +397,7 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s } - 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 (strcasecmp (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 (rel->howto == &reloc_howtos[RELOC_TYPE_64]) { rel->howto = &reloc_howtos[RELOC_TYPE_PC64]; @@ -422,27 +422,48 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s result >>= rel->howto->final_right_shift; - if (opcode == 0xff || opcode == 0x9A) { + /*printf ("%lx\n", n_type);*/ - if (result >= 65535) { + if (opcode == 0xFF || opcode == 0x9A || rel->n_type == 0x04) { + + /*printf ("%lx\n", (rel->symbolnum >> rel->n_type) & 0xff);*/ + + unsigned char *p = part->content + offset; - /*report_at (program_name, 0, REPORT_ERROR, "%s:(%s+%#lu): call exceeds 65535 bytes", part->of->filename, part->section->name, offset);*/ + if ((opcode != 0x9A && opcode != 0xFF) || result >= 65535) { + + if (opcode == 0x9A || opcode == 0xFF) { - 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]; - } + *(p - 1) = 0x9A; - result = (((unsigned long) result / 16) << 16) | (unsigned long) result % 16; + 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++; + + } + + } } else { - unsigned char *p = part->content + offset; + /*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]; @@ -454,45 +475,65 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s rel->howto = &reloc_howtos[RELOC_TYPE_PC8]; } - *(p - 1) = 0x0E; - *(p + 0) = 0xE8; - *(p + 3) = 0x90; + if (opcode == 0x9A) { - result -= part->rva + offset; - result -= size; + *(p - 1) = 0x0E; + *(p + 0) = 0xE8; + *(p + 3) = 0x90; + + result -= part->rva + offset; + result -= size; + + while (size > 2) { + size--; + } + + offset++; + result++; - while (size > 2) { + } else { - size--; - /*result--;*/ + *(p - 1) = 0x0E; + *(p + 0) = 0x3E; + *(p + 1) = 0xE8; + + result -= part->rva + offset; + result -= size; + + while (size > 2) { + + offset++; + size--; + + } } - - offset++; - result++; } - } else { + } else if (opcode != 0xE8 && rel->n_type != 0x04) { /*if (!rel->howto->pc_rel && !rel->howto->no_base) {*/ /*if (!((rel->symbolnum >> rel->n_ext) & 1) || symbol->section_number == ABSOLUTE_SECTION_NUMBER) {*/ - if (has_dgroup/* && ((rel->symbolnum >> rel->n_type) & 0xff) != N_ABS*/) { + if (has_dgroup/* && rel->n_type != N_ABS*/) { - if (xstrcasecmp (symbol->name, "__etext") != 0 && xstrcasecmp (symbol->name, "__edata") != 0 && xstrcasecmp (symbol->name, "__end") != 0) { + 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);*/ } } } - /*} else if (result >= dgroup_start && ((rel->symbolnum >> rel->n_type) & 0xff) != N_ABS) { + /*} else if (result >= dgroup_start && rel->n_type != 2) { printf ("%x, %lx, %lx, %lx\n", opcode, part->rva + offset + 0x30, result, dgroup_start); }*/ + + /*printf ("%lx, %lx, %lx, %lx\n", (rel->symbolnum >> rel->n_type) & 0xff, part->rva + offset + 0x30, result, dgroup_start);*/ } @@ -782,6 +823,7 @@ void link (void) { } of = object_file_make (FAKE_LD_FILENAME, 1); + value -= (dgroup_start & 0xfffffff0); symbol = of->symbol_arr; symbol->name = xstrdup ("DGROUP__edata"); @@ -797,10 +839,6 @@ void link (void) { if ((symbol = symbol_find ("DGROUP__end")) && 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); } diff --git a/mz.c b/mz.c index ee382ea..ba735db 100644 --- a/mz.c +++ b/mz.c @@ -107,11 +107,16 @@ void mz_write (const char *filename) { reloc_size = ALIGN (reloc_count * 4, 16); data_size += header_size + reloc_size; + ibss_addr += header_size + reloc_size; + + /*stack_addr += header_size + reloc_size;*/ if (text_section) { data_size += text_section->total_size; ibss_addr += text_section->total_size; + + stack_addr += text_section->total_size; } @@ -119,6 +124,8 @@ void mz_write (const char *filename) { data_size += data_section->total_size; ibss_addr += data_section->total_size; + + stack_addr += data_section->total_size; } @@ -126,7 +133,8 @@ void mz_write (const char *filename) { ibss_size = bss_section->total_size; } - stack_addr = header_size + reloc_size + ibss_addr + ibss_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. */ exec.e_magic[0] = 'M';