Possible bug fixes
authorRobert Pengelly <robertapengelly@hotmail.com>
Thu, 10 Apr 2025 23:33:33 +0000 (00:33 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Thu, 10 Apr 2025 23:33:33 +0000 (00:33 +0100)
link.c
mz.c

diff --git a/link.c b/link.c
index 8723bcefa7dfa993e693b6eaece2012a4a4445e2..76e7cbc7621341a2d3bf4ad22d3392676ddc9152 100644 (file)
--- 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 0a943c7e80d4f58caab403454484cbd01dbabdc3..503dbfe1f4f24bf242aad2dabec6ef8c3bc94fa1 100644 (file)
--- 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));