Re-create a.out executables
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 26 Nov 2024 00:40:15 +0000 (00:40 +0000)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 26 Nov 2024 00:40:15 +0000 (00:40 +0000)
Makefile.p32
Makefile.pdw
Makefile.unix
Makefile.w32
aout.c [new file with mode: 0644]
aout.h
ld.c
lib.c

index 2fc36a51777c8a6b2cd50b7fa2a29a7a1ee329fa..e8360e6ff3ef5562ed08e9e43a0de39248819f22 100644 (file)
@@ -6,7 +6,7 @@ CC=gcc386
 LD=ld386
 
 COPTS=-S -O2 -fno-common -ansi -I. -I./include -I../pdos/pdpclib -I../pdos/src -D__PDOS386__ -D__32BIT__ -D__NOBIVA__ -D__PDOS__ -Wall -Werror -ansi -m32 -pedantic
-COBJ=elks.c hashtab.o ld.o lib.o link.o map.o pe.o report.o section.o symbol.o vector.o write7x.o
+COBJ=aout.0 elks.0 hashtab.o ld.o lib.o link.o map.o pe.o report.o section.o symbol.o vector.o write7x.o
 
 all: clean slink.exe
 
index 017e3f739624bbcbaed8a665a84ea27ad61bb78a..ecb3254a18e9eb0a6c3b7a44348b65efdab57c53 100644 (file)
@@ -6,7 +6,7 @@ CC=gccwin
 LD=ldwin
 
 COPTS=-S -O2 -fno-common -ansi -I. -I./include -I../pdos/pdpclib -I../pdos/src -D__WIN32__ -D__NOBIVA__ -D__PDOS__ -Wall -Werror -ansi -m32 -pedantic
-COBJ=elks.c hashtab.o ld.o lib.o link.o map.o pe.o report.o section.o symbol.o vector.o write7x.o
+COBJ=aout.o elks.o hashtab.o ld.o lib.o link.o map.o pe.o report.o section.o symbol.o vector.o write7x.o
 
 all: clean slink.exe
 
index e49bb9aca91cc6b167d1a1bcef58d8689f10769c..4324f5715364fe4a15572c56e62c93baed1cd7cd 100644 (file)
@@ -9,7 +9,7 @@ VPATH               :=  $(SRCDIR)
 CC                  :=  gcc
 CFLAGS              :=  -D_FILE_OFFSET_BITS=64 -I$(OBJDIR) -I$(SRCDIR)/include -O2 -Wall -Werror -Wextra -ansi -pedantic -std=c90
 
-CSRC                :=  elks.c hashtab.c ld.c lib.c link.c map.c pe.c report.c section.c symbol.c vector.c write7x.c
+CSRC                :=  aout.c elks.c hashtab.c ld.c lib.c link.c map.c pe.c report.c section.c symbol.c vector.c write7x.c
 
 ifeq ($(OS), Windows_NT)
 all: slink.exe
index c9c024147e52d2560c3f14249d84e05c84b66a4e..2067a85fc8eca1dc019a2b72deb1ad3943f8956e 100644 (file)
@@ -9,7 +9,7 @@ VPATH               :=  $(SRCDIR)
 CC                  :=  gcc
 CFLAGS              :=  -D_FILE_OFFSET_BITS=64 -I$(OBJDIR) -I$(SRCDIR)/include -O2 -Wall -Werror -Wextra -ansi -pedantic -std=c90
 
-CSRC                :=  elks.c hashtab.c ld.c lib.c link.c map.c pe.c report.c section.c symbol.c vector.c write7x.c
+CSRC                :=  aout.c elks.c hashtab.c ld.c lib.c link.c map.c pe.c report.c section.c symbol.c vector.c write7x.c
 
 all: slink.exe
 
diff --git a/aout.c b/aout.c
new file mode 100644 (file)
index 0000000..5d42839
--- /dev/null
+++ b/aout.c
@@ -0,0 +1,194 @@
+/******************************************************************************
+ * @file            aout.c
+ *****************************************************************************/
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <string.h>
+
+#include    "aout.h"
+#include    "ld.h"
+#include    "lib.h"
+#include    "report.h"
+#include    "section.h"
+#include    "symbol.h"
+
+static unsigned long section_get_num_relocs (struct section *section) {
+
+    unsigned long num_relocs = 0, i;
+    
+    struct section_part *part;
+    struct reloc_howto *howto;
+    
+    for (part = section->first_part; part; part = part->next) {
+    
+        for (i = 0; i < part->reloc_cnt; i++) {
+        
+            howto = part->reloc_arr[i].howto;
+            
+            if (howto == &reloc_howtos[RELOC_TYPE_64] || howto == &reloc_howtos[RELOC_TYPE_32] || howto == &reloc_howtos[RELOC_TYPE_16] || howto == &reloc_howtos[RELOC_TYPE_8]) {
+                num_relocs++;
+            }
+        
+        }
+    
+    }
+    
+    return num_relocs;
+
+}
+
+static unsigned char *write_relocs_for_section (unsigned char *pos, struct section *section) {
+
+    struct section_part *part;
+    struct relocation_info rel;
+    
+    struct symbol *symbol;
+    unsigned long size_log2, i, r_symbolnum;
+    
+    for (part = section->first_part; part; part = part->next) {
+    
+        for (i = 0; i < part->reloc_cnt; i++) {
+        
+            memset (&rel, 0, sizeof (rel));
+            
+            if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_64]) {
+                size_log2 = 3;
+            } else if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_32]) {
+                size_log2 = 2;
+            } else if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_16]) {
+                size_log2 = 1;
+            } else if (part->reloc_arr[i].howto == &reloc_howtos[RELOC_TYPE_8]) {
+                size_log2 = 0;
+            } else {
+                continue;
+            }
+            
+            symbol = part->reloc_arr[i].symbol;
+            
+            if (symbol_is_undefined (symbol)) {
+                symbol = symbol_find (symbol->name);
+            }
+            
+            integer_to_array (part->rva - part->section->rva + part->reloc_arr[i].offset, rel.r_address, 4);
+            
+            if (strcmp (symbol->part->section->name, ".text") == 0) {
+                r_symbolnum = N_TEXT;
+            } else if (strcmp (symbol->part->section->name, ".data") == 0) {
+                r_symbolnum = N_DATA;
+            } else if (strcmp (symbol->part->section->name, ".bss") == 0) {
+                r_symbolnum = N_BSS;
+            } else {
+                r_symbolnum = N_TEXT;
+            }
+            
+            integer_to_array (r_symbolnum | (size_log2 << 25), rel.r_symbolnum, 4);
+            
+            memcpy (pos, &rel, sizeof (rel));
+            pos += sizeof (rel);
+        
+        }
+    
+    }
+    
+    return pos;
+
+}
+
+void aout_write (const char *filename) {
+
+    FILE *fp;
+    
+    unsigned char *data, *pos;
+    unsigned long data_size;
+    
+    struct section *text_section, *data_section, *bss_section;
+    struct aout_exec exec = { 0 };
+    
+    if (!(fp = fopen (filename, "wb"))) {
+    
+        report_at (program_name, 0, REPORT_ERROR, "failed to open '%s' for writing", filename);
+        return;
+    
+    }
+    
+    text_section = section_find (".text");
+    data_section = section_find (".data");
+    bss_section  = section_find (".bss");
+    
+    integer_to_array (OMAGIC, exec.a_info, 4);
+    
+    if (data_section) {
+    
+        integer_to_array (data_section->rva, exec.a_text, 4);
+        
+        if (bss_section) {
+            integer_to_array (bss_section->rva - data_section->rva, exec.a_data, 4);
+        } else {
+            integer_to_array (data_section->total_size, exec.a_data, 4);
+        }
+    
+    } else {
+    
+        if (bss_section) {
+            integer_to_array (bss_section->rva - data_section->rva, exec.a_text, 4);
+        } else {
+            integer_to_array (text_section ? text_section->total_size : 0, exec.a_text, 4);
+        }
+        
+        integer_to_array (0, exec.a_data, 4);
+    
+    }
+    
+    integer_to_array (bss_section ? bss_section->total_size : 0, exec.a_bss, 4);
+    integer_to_array (state->entry_point, exec.a_entry, 4);
+    
+    if (text_section) {
+        integer_to_array (section_get_num_relocs (text_section) * sizeof (struct relocation_info), exec.a_trsize, 4);
+    }
+    
+    if (data_section) {
+        integer_to_array (section_get_num_relocs (data_section) * sizeof (struct relocation_info), exec.a_drsize, 4);
+    }
+    
+    data_size = sizeof (exec);
+    
+    data_size += (array_to_integer (exec.a_text, 4) + array_to_integer (exec.a_data, 4));
+    data_size += (array_to_integer (exec.a_trsize, 4) + array_to_integer (exec.a_drsize, 4));
+    
+    data_size += 4;
+    
+    data = xmalloc (data_size);
+    memcpy (data, &exec, sizeof (exec));
+    
+    pos = data + sizeof (exec);
+    
+    if (text_section) {
+        section_write (text_section, pos);
+    }
+    
+    pos += array_to_integer (exec.a_text, 4);
+    
+    if (data_section) {
+        section_write (data_section, pos);
+    }
+    
+    pos += array_to_integer (exec.a_data, 4);
+    
+    if (text_section) {
+        pos = write_relocs_for_section (pos, text_section);
+    }
+    
+    if (data_section) {
+        pos = write_relocs_for_section (pos, data_section);
+    }
+    
+    integer_to_array (4, pos, 4);
+    
+    if (fwrite (data, data_size, 1, fp) != 1) {
+        report_at (program_name, 0, REPORT_ERROR, "failed to write data to '%s'", filename);
+    }
+    
+    free (data);
+    fclose (fp);
+
+}
diff --git a/aout.h b/aout.h
index a7443bbc6ffd01e034bb3e771f7cce502e4a4b9e..4113ba3ca7b364d5c918fa63b002599b6a926ab1 100644 (file)
--- a/aout.h
+++ b/aout.h
@@ -45,7 +45,7 @@ struct relocation_info {
 };*/
 
 #define     N_TYPE                      0x1e
-int create_executable_from_aout_objects (void);
+void aout_write (const char *filename);
 
 #define     OMAGIC                      0407
 #define     ZMAGIC                      0413
diff --git a/ld.c b/ld.c
index 19c6c23944f7c507d97be7fc0d057212ec7ffc9f..9d0df7bcc8cececd1cb0dd5f1eb49e93d4203115 100644 (file)
--- a/ld.c
+++ b/ld.c
@@ -5,6 +5,7 @@
 #include    <stdlib.h>
 #include    <string.h>
 
+#include    "aout.h"
 #include    "elks.h"
 #include    "ld.h"
 #include    "lib.h"
@@ -193,9 +194,9 @@ int main (int argc, char **argv) {
         free (data);
         fclose (fp);
     
-    }/* else if (state->format == LD_FORMAT_I386_AOUT) {
+    } else if (state->format == LD_FORMAT_I386_AOUT) {
         aout_write (state->output_filename);
-    } else if (state->format == LD_FORMAT_I386_ELKS || state->format == LD_FORMAT_IA16_ELKS) {
+    }/* else if (state->format == LD_FORMAT_I386_ELKS || state->format == LD_FORMAT_IA16_ELKS) {
         elks_write (state->output_filename);
     }*/ else if (state->format == LD_FORMAT_I386_PE) {
     
diff --git a/lib.c b/lib.c
index 1da8663ca99c4fc83084cd24c32829a21f39f383..d82463c99f93d60d876e816b7d375fbf4488c59b 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -94,7 +94,7 @@ static void print_usage (void) {
         fprintf (stderr, "    --oformat FORMAT                  Specify the format of output file (default msdos)\n");
         fprintf (stderr, "                                          Supported formats are:\n");
         /*fprintf (stderr, "                                              a.out-i386, elks-ia16, elks-i386,\n");*/
-        fprintf (stderr, "                                              pe-i386, binary, msdos\n");
+        fprintf (stderr, "                                              a.out-i386, pe-i386, binary, msdos\n");
         fprintf (stderr, "    --image-base <address>            Set base address of the executable.\n");
         
         fprintf (stderr, "\n");
@@ -170,12 +170,12 @@ static void use_option (const char *cmd_arg, int idx, const char *optarg) {
             
             }*/
             
-            /*if (xstrcasecmp (optarg, "a.out-i386") == 0) {
+            if (xstrcasecmp (optarg, "a.out-i386") == 0) {
             
                 state->format = LD_FORMAT_I386_AOUT;
                 break;
             
-            }*/
+            }
             
             if (xstrcasecmp (optarg, "pe-i386") == 0) {