From 28b2e385b0fc7109742641c7b92ee049cbab0824 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Tue, 26 Nov 2024 00:40:15 +0000 Subject: [PATCH] Re-create a.out executables --- Makefile.p32 | 2 +- Makefile.pdw | 2 +- Makefile.unix | 2 +- Makefile.w32 | 2 +- aout.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++ aout.h | 2 +- ld.c | 5 +- lib.c | 6 +- 8 files changed, 205 insertions(+), 10 deletions(-) create mode 100644 aout.c diff --git a/Makefile.p32 b/Makefile.p32 index 2fc36a5..e8360e6 100644 --- a/Makefile.p32 +++ b/Makefile.p32 @@ -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 diff --git a/Makefile.pdw b/Makefile.pdw index 017e3f7..ecb3254 100644 --- a/Makefile.pdw +++ b/Makefile.pdw @@ -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 diff --git a/Makefile.unix b/Makefile.unix index e49bb9a..4324f57 100644 --- a/Makefile.unix +++ b/Makefile.unix @@ -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 diff --git a/Makefile.w32 b/Makefile.w32 index c9c0241..2067a85 100644 --- a/Makefile.w32 +++ b/Makefile.w32 @@ -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 index 0000000..5d42839 --- /dev/null +++ b/aout.c @@ -0,0 +1,194 @@ +/****************************************************************************** + * @file aout.c + *****************************************************************************/ +#include +#include +#include + +#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 a7443bb..4113ba3 100644 --- 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 19c6c23..9d0df7b 100644 --- a/ld.c +++ b/ld.c @@ -5,6 +5,7 @@ #include #include +#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 1da8663..d82463c 100644 --- 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
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) { -- 2.34.1