Bug fixes which allow all models to work
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 15 Apr 2025 22:18:01 +0000 (23:18 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 15 Apr 2025 22:18:01 +0000 (23:18 +0100)
aout.c
elks.c
ld.c
link.c
mz.c

diff --git a/aout.c b/aout.c
index fd39cb90edb83d33b512ddc18247c8f778ca3947..215b215f16ebcfc2c8cddad1e3be44653667b1a2 100644 (file)
--- 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 a74cfadc0f1808e78de1b0b23bb899f3a19f3969..1240571d5e553b28fd8577679c16f6db3d624590 100644 (file)
--- 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 dc16d540bbd5dfb7e18c1fc7cd88bf7a5047a7e2..2b1798bb592f7b4d4b162451c61d817270f06f45 100644 (file)
--- 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 79670d7ca9a5b59a19711dc17a7dfa87ba83645a..c5cd31472b4e7a3f61da1e75c10bf0274aa2eb59 100644 (file)
--- 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 ba735db6a97c5fce2f52ff2e6b301586dab22e1a..e9e43f1648030e6e9886bf42e3c3236841fc94d2 100644 (file)
--- 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) {