Working MZ executables that's not large or huge
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 13 Apr 2025 10:27:27 +0000 (11:27 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 13 Apr 2025 10:27:27 +0000 (11:27 +0100)
aout.c
link.c
mz.c

diff --git a/aout.c b/aout.c
index 1427ec5f9b85fe5cc06bc58be35f7d0c0b224fba..4c496107c857e90645a23622b1cbd62d5ebafdc7 100644 (file)
--- a/aout.c
+++ b/aout.c
@@ -17,7 +17,7 @@ static void translate_relocation (struct reloc_entry *reloc, struct aout_relocat
     unsigned long r_symbolnum = array_to_integer (input_reloc->r_symbolnum, 4);
     
     unsigned long r_address = array_to_integer (input_reloc->r_address, 4);
-    long symbolnum = (r_symbolnum & 0x7fffff);
+    long symbolnum = (r_symbolnum & 0xffffff);
     
     if ((r_symbolnum >> 27) & 1) {      /* ext */
     
diff --git a/link.c b/link.c
index 76e7cbc7621341a2d3bf4ad22d3392676ddc9152..578f17cef6e25ef0316f13bd7e9e08eb469bf8bd 100644 (file)
--- a/link.c
+++ b/link.c
@@ -6,7 +6,6 @@
 #include    <stdlib.h>
 #include    <string.h>
 
-#include    "elks.h"
 #include    "ld.h"
 #include    "lib.h"
 #include    "pe.h"
@@ -297,9 +296,7 @@ static void calculate_section_sizes_and_rvas (void) {
 static void reloc_generic (struct section_part *part, struct reloc_entry *rel, struct symbol *symbol) {
 
     unsigned char opcode = (part->content + rel->offset - 1)[0];
-    unsigned int size = rel->howto->size;
-    
-    unsigned long result = 0, offset = rel->offset;
+    unsigned long result = 0, size = rel->howto->size, offset = rel->offset;
     
     switch (size) {
     
@@ -370,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) != N_ABS) {
+                if (((rel->symbolnum >> 27) & 1) || ((rel->symbolnum >> rel->n_type) & 0xff) != 2) {
                     report_at (program_name, 0, REPORT_ERROR, "%s:(%s+%#lu): segment relocation", part->of->filename, part->section->name, offset);
                 }
             
@@ -378,11 +375,11 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s
         
         } else if (state->format == LD_FORMAT_MZ) {
         
-            if (strcmp (symbol->name, "DGROUP")) {
+            if (xstrcasecmp (symbol->name, "DGROUP")) {
             
-                int is_section = (strcmp (symbol->name, ".text") == 0) || (strcmp (symbol->name, ".data") == 0) || (strcmp (symbol->name, ".bss") == 0);
+                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) != N_TEXT && ((rel->symbolnum >> rel->n_type) & 0xff) != N_DATA && ((rel->symbolnum >> rel->n_type) & 0xff) != N_BSS)) {
+                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 (rel->howto == &reloc_howtos[RELOC_TYPE_64]) {
                         rel->howto = &reloc_howtos[RELOC_TYPE_PC64];
@@ -425,27 +422,11 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s
     
     result >>= rel->howto->final_right_shift;
     
-    if (!rel->howto->pc_rel && !rel->howto->no_base) {
-    
-        if (has_dgroup) {
-        
-            if (xstrcasecmp (symbol->name, "__etext") != 0 && xstrcasecmp (symbol->name, "__edata") != 0 && xstrcasecmp (symbol->name, "__end") != 0) {
-            
-                if (result >= dgroup_start) {
-                    result -= (dgroup_start & 0xfffffff0);
-                }
-            
-            }
-        
-        }
-    
-    }
-    
-    if (opcode == 0xff) {
+    if (opcode == 0xff || opcode == 0x9A) {
     
         if (result >= 65535) {
         
-            report_at (program_name, 0, REPORT_ERROR, "%s:(%s+%#lu): call exceeds 65535 bytes", part->of->filename, part->section->name, offset);
+            /*report_at (program_name, 0, REPORT_ERROR, "%s:(%s+%#lu): call exceeds 65535 bytes", part->of->filename, part->section->name, offset);*/
             
             if (rel->howto == &reloc_howtos[RELOC_TYPE_PC64]) {
                 rel->howto = &reloc_howtos[RELOC_TYPE_64];
@@ -477,22 +458,48 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s
             *(p + 0) = 0xE8;
             *(p + 3) = 0x90;
             
-            result -= part->rva + rel->offset;
+            result -= part->rva + offset;
+            result -= size;
             
             while (size > 2) {
             
-                result--;
                 size--;
+                /*result--;*/
             
             }
             
             offset++;
-            result--;
+            result++;
         
         }
     
+    } else {
+    
+        /*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 (xstrcasecmp (symbol->name, "__etext") != 0 && xstrcasecmp (symbol->name, "__edata") != 0 && xstrcasecmp (symbol->name, "__end") != 0) {
+                
+                    if (result >= dgroup_start) {
+                        result -= (dgroup_start & 0xfffffff0);
+                    }
+                
+                }
+            
+            }
+        
+        /*} else if (result >= dgroup_start && ((rel->symbolnum >> rel->n_type) & 0xff) != N_ABS) {
+            printf ("%x, %lx, %lx, %lx\n", opcode, 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) {
     
         case 8: {
@@ -744,7 +751,7 @@ 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);
+            value += align_section_if_needed (section->total_size);
         }
         
         dgroup_start = value;
@@ -766,14 +773,10 @@ void link (void) {
     
     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 += align_section_if_needed (section->total_size);
         }
         
-        value = data_addr;
-        
         if ((section = section_find (".data"))) {
             value += align_section_if_needed (section->total_size);
         }
@@ -784,7 +787,7 @@ void link (void) {
         symbol->name = xstrdup ("DGROUP__edata");
         
         symbol->section_number = ABSOLUTE_SECTION_NUMBER;
-        symbol->value = value - (data_addr & 0xfffffff0);
+        symbol->value = value;
         
         symbol_record_external_symbol (symbol);
     
@@ -794,14 +797,10 @@ void link (void) {
     
     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 += align_section_if_needed (section->total_size);
         }
         
-        value = data_addr;
-        
         if ((section = section_find (".data"))) {
             value += align_section_if_needed (section->total_size);
         }
@@ -816,7 +815,7 @@ void link (void) {
         symbol->name = xstrdup ("DGROUP__end");
         
         symbol->section_number = ABSOLUTE_SECTION_NUMBER;
-        symbol->value = value - (data_addr & 0xfffffff0);
+        symbol->value = value;
         
         symbol_record_external_symbol (symbol);
     
@@ -827,7 +826,7 @@ void link (void) {
     if ((symbol = symbol_find ("__etext")) && symbol_is_undefined (symbol)) {
     
         if ((section = section_find (".text"))) {
-            value = align_section_if_needed (section->total_size);
+            value += align_section_if_needed (section->total_size);
         }
         
         of = object_file_make (FAKE_LD_FILENAME, 1);
@@ -847,7 +846,7 @@ void link (void) {
     if ((symbol = symbol_find ("__edata")) && symbol_is_undefined (symbol)) {
     
         if ((section = section_find (".data"))) {
-            value = align_section_if_needed (section->total_size);
+            value += align_section_if_needed (section->total_size);
         }
         
         of = object_file_make (FAKE_LD_FILENAME, 1);
@@ -867,7 +866,7 @@ void link (void) {
     if ((symbol = symbol_find ("__end")) && symbol_is_undefined (symbol)) {
     
         if ((section = section_find (".bss"))) {
-            value = align_section_if_needed (section->total_size);
+            value += align_section_if_needed (section->total_size);
         }
         
         of = object_file_make (FAKE_LD_FILENAME, 1);
diff --git a/mz.c b/mz.c
index 503dbfe1f4f24bf242aad2dabec6ef8c3bc94fa1..ee382ea0eaee9c3c90044748c81c2c3942d5776c 100644 (file)
--- a/mz.c
+++ b/mz.c
@@ -108,46 +108,25 @@ void mz_write (const char *filename) {
     
     data_size += header_size + reloc_size;
     
-    if (data_section) {
+    if (text_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;
-        
-        }
+        data_size += text_section->total_size;
+        ibss_addr += text_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;
-        
-        }
+    if (data_section) {
     
-    }
+        data_size += data_section->total_size;
+        ibss_addr += data_section->total_size;
     
-    stack_addr = ibss_addr;
+    }
     
     if (bss_section) {
         ibss_size = bss_section->total_size;
     }
     
-    /*stack_addr += ibss_size;*/
+    stack_addr = header_size + reloc_size + ibss_addr + ibss_size;
     stack_size = 0x1000;        /* Maybe get this from command line in the future. */
     
     exec.e_magic[0] = 'M';