Only relocate MZ and IA16-ELKS
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 15 Apr 2025 23:24:20 +0000 (00:24 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 15 Apr 2025 23:24:20 +0000 (00:24 +0100)
aout.c
elks.c
link.c
reloc.h

diff --git a/aout.c b/aout.c
index 215b215f16ebcfc2c8cddad1e3be44653667b1a2..c1567c7749cb0567634027823cee287eb0e241fa 100644 (file)
--- a/aout.c
+++ b/aout.c
@@ -58,6 +58,7 @@ static void translate_relocation (struct reloc_entry *reloc, struct aout_relocat
     reloc->n_type = ((r_symbolnum >> 24) & 0xff);
     reloc->n_type &= ~(1 << 3);
     
+    reloc->r_symbolnum = r_symbolnum;
     reloc->n_ext = ((r_symbolnum >> 27) & 1);
     
     switch (1U << ((r_symbolnum >> 25) & 3)) {
@@ -437,7 +438,7 @@ static unsigned char *write_relocs_for_section (unsigned char *pos, struct secti
                 r_symbolnum = N_TEXT;
             }
             
-            if ((part->reloc_arr[i].symbolnum >> 27) & 1) {
+            if ((part->reloc_arr[i].r_symbolnum >> 27) & 1) {
             
                 /*report_at (part->of->filename, 0, REPORT_INTERNAL_ERROR, "symbolnum: %lx", part->reloc_arr[i].symbolnum);*/
                 r_symbolnum |= (1LU << 27);
diff --git a/elks.c b/elks.c
index 1240571d5e553b28fd8577679c16f6db3d624590..1c7a2ae54b74838bcdf591924aa995b8cce49bf0 100644 (file)
--- a/elks.c
+++ b/elks.c
@@ -57,8 +57,9 @@ static void translate_relocation (struct reloc_entry *reloc, struct elks_relocat
     reloc->offset = r_address;
     
     reloc->n_type = ((r_symbolnum >> 28) & 0xff);
-    reloc->n_type &= ~(1 << 4);
+    reloc->n_type &= ~(1 << 3);
     
+    reloc->r_symbolnum = r_symbolnum;
     reloc->n_ext = ((r_symbolnum >> 31) & 1);
     
     switch (1U << ((r_symbolnum >> 29) & 3)) {
@@ -438,7 +439,7 @@ static unsigned char *write_relocs_for_section (unsigned char *pos, struct secti
                 r_symbolnum = N_TEXT;
             }
             
-            if ((part->reloc_arr[i].symbolnum >> 27) & 1) {
+            if ((part->reloc_arr[i].r_symbolnum >> 27) & 1) {
                 r_symbolnum |= (1LU << 27);
             }
             
diff --git a/link.c b/link.c
index c5cd31472b4e7a3f61da1e75c10bf0274aa2eb59..b84293b1a572d251f182fb943867d496bd5eb3e3 100644 (file)
--- a/link.c
+++ b/link.c
@@ -391,8 +391,6 @@ 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);
                 }
             
             }
@@ -426,104 +424,107 @@ static void reloc_generic (struct section_part *part, struct reloc_entry *rel, s
     
     /*printf ("%lx\n", n_type);*/
     
-    if (opcode == 0x9A || opcode == 0xFF || rel->n_type == 4) {
+    if (state->format == LD_FORMAT_MZ || state->format == LD_FORMAT_IA16_ELKS) {
     
-        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 || rel->n_type == 4) {
         
-            if (opcode == 0xFF) { *(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];
-            }
-            
-            while (rel->howto->size > 2) {
-                rel->howto->size--;
-            }
-            
-            rel->offset += 2;
+            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 (result >= dgroup_start) {
+            if ((opcode != 0x9A && opcode != 0xFF) || result >= 65535) {
             
-                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 if (opcode == 0x9A || opcode == 0xFF) {
-        
-            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 (opcode == 0x9A) {
-            
-                *(p - 1) = 0x0E;
-                *(p + 0) = 0xE8;
-                *(p + 3) = 0x90;
+                if (opcode == 0xFF) { *(p - 1) = 0x9A; }
                 
-                result -= part->rva + offset;
-                result -= size;
+                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];
+                }
                 
-                while (size > 2) {
-                    size--;
+                while (rel->howto->size > 2) {
+                    rel->howto->size--;
                 }
                 
-                offset++;
-                result++;
-            
-            } else {
-            
-                *(p - 1) = 0x0E;
-                *(p + 0) = 0x3E;
-                *(p + 1) = 0xE8;
+                rel->offset += 2;
                 
-                result -= part->rva + offset;
-                result -= size;
+                if (result >= dgroup_start) {
                 
-                while (size > 2) {
+                    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 if (opcode == 0x9A || opcode == 0xFF) {
+            
+                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 (opcode == 0x9A) {
+                
+                    *(p - 1) = 0x0E;
+                    *(p + 0) = 0xE8;
+                    *(p + 3) = 0x90;
+                    
+                    result -= part->rva + offset;
+                    result -= size;
+                    
+                    while (size > 2) {
+                        size--;
+                    }
+                    
                     offset++;
-                    size--;
+                    result++;
+                
+                } else {
+                
+                    *(p - 1) = 0x0E;
+                    *(p + 0) = 0x3E;
+                    *(p + 1) = 0xE8;
+                    
+                    result -= part->rva + offset;
+                    result -= size;
+                    
+                    while (size > 2) {
+                    
+                        offset++;
+                        size--;
+                    
+                    }
                 
                 }
             
             }
         
-        }
-    
-    } else if (opcode != 0xE8 && has_dgroup && result >= dgroup_start) {
-    
-        /*printf ("relocating: %s: %s: %lx, %lx, %d\n", part->of->filename, symbol->name, part->rva + offset + 0x40, rel->symbolnum, rel->n_type);*/
+        } else if (opcode != 0xE8 && has_dgroup && 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) {
-        
-            if (result >= dgroup_start) {
-                result -= (dgroup_start & 0xfffffff0);
+            /*printf ("relocating: %s: %s: %lx, %lx, %d\n", part->of->filename, symbol->name, part->rva + offset + 0x40, rel->symbolnum, rel->n_type);*/
+            
+            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);
+                }
+            
             }
         
         }
     
-    
     }
     
     switch (size) {
diff --git a/reloc.h b/reloc.h
index 4c5edd095df07ed615483c089e094e165ab8b43f..a4bb555abae01243475bc31a59ca2ea637678fc3 100644 (file)
--- a/reloc.h
+++ b/reloc.h
@@ -49,8 +49,8 @@ struct reloc_entry {
     unsigned long offset;
     unsigned long addend;
     
+    unsigned long symbolnum, r_symbolnum;
     unsigned int n_type, n_ext;
-    unsigned long symbolnum;
     
     struct reloc_howto *howto;