From e8408ec562332d5338650957926a7288603314a8 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Fri, 11 Apr 2025 00:33:33 +0100 Subject: [PATCH] Possible bug fixes --- link.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- mz.c | 47 +++++++++++++++++-------------- 2 files changed, 103 insertions(+), 32 deletions(-) diff --git a/link.c b/link.c index 8723bce..76e7cbc 100644 --- a/link.c +++ b/link.c @@ -378,23 +378,29 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s } else if (state->format == LD_FORMAT_MZ) { - if (((rel->symbolnum >> rel->n_type) & 0xff) == N_ABS) { - - 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 (strcmp (symbol->name, "DGROUP")) { + + int is_section = (strcmp (symbol->name, ".text") == 0) || (strcmp (symbol->name, ".data") == 0) || (strcmp (symbol->name, ".bss") == 0); + + if (is_section || (((rel->symbolnum >> rel->n_type) & 0xff) != N_TEXT && ((rel->symbolnum >> rel->n_type) & 0xff) != N_DATA && ((rel->symbolnum >> rel->n_type) & 0xff) != N_BSS)) { + + 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 (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 (rel->howto == &reloc_howtos[RELOC_TYPE_64]) { rel->howto = &reloc_howtos[RELOC_TYPE_PC64]; @@ -758,6 +764,66 @@ void link (void) { value = 0; + if ((symbol = symbol_find ("DGROUP__edata")) && symbol_is_undefined (symbol)) { + + unsigned long data_addr = 0; + + if ((section = section_find (".text"))) { + data_addr = align_section_if_needed (section->total_size); + } + + value = data_addr; + + if ((section = section_find (".data"))) { + value += align_section_if_needed (section->total_size); + } + + of = object_file_make (FAKE_LD_FILENAME, 1); + + symbol = of->symbol_arr; + symbol->name = xstrdup ("DGROUP__edata"); + + symbol->section_number = ABSOLUTE_SECTION_NUMBER; + symbol->value = value - (data_addr & 0xfffffff0); + + symbol_record_external_symbol (symbol); + + } + + value = 0; + + if ((symbol = symbol_find ("DGROUP__end")) && symbol_is_undefined (symbol)) { + + unsigned long data_addr = 0; + + if ((section = section_find (".text"))) { + data_addr = align_section_if_needed (section->total_size); + } + + value = data_addr; + + 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); + } + + of = object_file_make (FAKE_LD_FILENAME, 1); + + symbol = of->symbol_arr; + symbol->name = xstrdup ("DGROUP__end"); + + symbol->section_number = ABSOLUTE_SECTION_NUMBER; + symbol->value = value - (data_addr & 0xfffffff0); + + symbol_record_external_symbol (symbol); + + } + + value = 0; + if ((symbol = symbol_find ("__etext")) && symbol_is_undefined (symbol)) { if ((section = section_find (".text"))) { diff --git a/mz.c b/mz.c index 0a943c7..503dbfe 100644 --- a/mz.c +++ b/mz.c @@ -51,10 +51,10 @@ static unsigned char *write_relocs_for_section (unsigned char *pos, struct secti addr = part->rva + part->reloc_arr[i].offset; - integer_to_array (addr % 16, pos, 2); + integer_to_array (addr % 65536, pos, 2); pos += 2; - integer_to_array (addr / 16, pos, 2); + integer_to_array (addr / 65536, pos, 2); pos += 2; } @@ -71,8 +71,8 @@ void mz_write (const char *filename) { FILE *fp; + unsigned long data_size = 0; unsigned char *data, *pos; - unsigned long data_size; struct section *text_section, *data_section, *bss_section; unsigned long header_size; @@ -103,68 +103,73 @@ void mz_write (const char *filename) { reloc_count += section_get_num_relocs (data_section); } - reloc_size = ALIGN (reloc_count * 4, 32); header_size = ALIGN (sizeof (exec), 16); + reloc_size = ALIGN (reloc_count * 4, 16); + + data_size += header_size + reloc_size; if (data_section) { + data_size += data_section->rva;; ibss_addr += data_section->rva; if (bss_section) { + + data_size += bss_section->rva - data_section->rva; ibss_addr += bss_section->rva - data_section->rva; + } else { + + data_size += data_section->total_size; ibss_addr += data_section->total_size; + } } else { if (bss_section) { + + data_size += bss_section->rva; ibss_addr += bss_section->rva; + } else { + + data_size += text_section ? text_section->total_size : 0; ibss_addr += text_section ? text_section->total_size : 0; + } } - ibss_addr = ibss_addr + reloc_size; + stack_addr = ibss_addr; if (bss_section) { ibss_size = bss_section->total_size; } - stack_addr = ibss_addr + ibss_size; - stack_size = 0x1000; /* Maybe get this from command line in future. */ + /*stack_addr += ibss_size;*/ + stack_size = 0x1000; /* Maybe get this from command line in the future. */ exec.e_magic[0] = 'M'; exec.e_magic[1] = 'Z'; - write721_to_byte_array (exec.e_cblp, (ibss_addr % 512)); + write721_to_byte_array (exec.e_cblp, ibss_addr % 512); write721_to_byte_array (exec.e_cp, ALIGN (ibss_addr, 512) / 512); write721_to_byte_array (exec.e_crlc, reloc_count); write721_to_byte_array (exec.e_cparhdr, (header_size + reloc_size) / 16); - write721_to_byte_array (exec.e_minalloc, (ALIGN (ibss_size + stack_size, 16) / 16)); + write721_to_byte_array (exec.e_minalloc, ALIGN (ibss_size + stack_size, 16) / 16); write721_to_byte_array (exec.e_maxalloc, 0xFFFF); - write721_to_byte_array (exec.e_ss, (stack_addr / 16)); - write721_to_byte_array (exec.e_sp, ALIGN (stack_addr % 16 + stack_size, 16)); + write721_to_byte_array (exec.e_ss, stack_addr / 16); + write721_to_byte_array (exec.e_sp, stack_addr % 16 + stack_size); write721_to_byte_array (exec.e_ip, state->entry_point % 16); write721_to_byte_array (exec.e_cs, state->entry_point / 16); write721_to_byte_array (exec.e_lfarlc, header_size); - data_size = header_size + reloc_size; - - if (text_section) { - data_size += text_section->total_size; - } - - if (data_section) { - data_size += data_section->total_size; - } - data = xmalloc (data_size); memcpy (data, &exec, sizeof (exec)); -- 2.34.1