From: Robert Pengelly Date: Wed, 16 Oct 2024 14:58:42 +0000 (+0100) Subject: Create ELK object file X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=b907d46f45c5b1cc697fec8a177176cb5c08448b;p=sasm.git Create ELK object file --- diff --git a/Makefile.p32 b/Makefile.p32 index 8e6b41e..60facf8 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=as.o bin.o cstr.o eval.o expr.o fixup.o frag.o hashtab.o intel.o kwd.o lex.o lib.o list.o listing.o ll.o macro.o obj.o process.o report.o section.o symbol.o vector.o +COBJ=as.o bin.o cstr.o elks.o eval.o expr.o fixup.o frag.o hashtab.o intel.o kwd.o lex.o lib.o list.o listing.o ll.o macro.o process.o report.o section.o symbol.o vector.o all: clean sasm.exe diff --git a/Makefile.pdw b/Makefile.pdw index 73915de..c33cb87 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=as.o bin.o cstr.o eval.o expr.o fixup.o frag.o hashtab.o intel.o kwd.o lex.o lib.o list.o listing.o ll.o macro.o obj.o process.o report.o section.o symbol.o vector.o +COBJ=as.o bin.o cstr.o elks.o eval.o expr.o fixup.o frag.o hashtab.o intel.o kwd.o lex.o lib.o list.o listing.o ll.o macro.o process.o report.o section.o symbol.o vector.o all: clean sasm.exe diff --git a/Makefile.unix b/Makefile.unix index 44941e1..94b0919 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 := as.c bin.c cstr.c eval.c expr.c fixup.c frag.c hashtab.c intel.c kwd.c lex.c lib.c list.c listing.c ll.c macro.c obj.c process.c report.c section.c symbol.c vector.c +CSRC := as.c bin.c cstr.c elks.c eval.c expr.c fixup.c frag.c hashtab.c intel.c kwd.c lex.c lib.c list.c listing.c ll.c macro.c process.c report.c section.c symbol.c vector.c ifeq ($(OS), Windows_NT) all: sasm.exe diff --git a/Makefile.w32 b/Makefile.w32 index c70d0cf..b3fc631 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 := as.c bin.c cstr.c eval.c expr.c fixup.c frag.c hashtab.c intel.c kwd.c lex.c lib.c list.c listing.c ll.c macro.c obj.c process.c report.c section.c symbol.c vector.c +CSRC := as.c bin.c cstr.c elks.c eval.c expr.c fixup.c frag.c hashtab.c intel.c kwd.c lex.c lib.c list.c listing.c ll.c macro.c process.c report.c section.c symbol.c vector.c all: sasm.exe diff --git a/as.c b/as.c index 3c15e73..961c383 100644 --- a/as.c +++ b/as.c @@ -17,7 +17,7 @@ struct as_state *state = 0; const char *program_name = 0; extern void output_binary (FILE *fp); -extern void output_obj (FILE *fp); +extern void output_elks (FILE *fp); extern void keywords_init (void); extern void sections_init (void); @@ -175,7 +175,7 @@ int main (int argc, char **argv) { } - output_obj (state->ofp); + output_elks (state->ofp); if (get_error_count () > 0) { return EXIT_FAILURE; diff --git a/elks.c b/elks.c new file mode 100644 index 0000000..3f60bb9 --- /dev/null +++ b/elks.c @@ -0,0 +1,322 @@ +/****************************************************************************** + * @file elks.c + *****************************************************************************/ +#include +#include +#include + +#include "as.h" +#include "elks.h" +#include "fixup.h" +#include "frag.h" +#include "report.h" +#include "section.h" +#include "symbol.h" + +static void write_to_byte_array (unsigned char *arr, unsigned long value, int size) { + + int i; + + for (i = 0; i < size; i++) { + arr[i] = (value >> (8 * i)) & 0xff; + } + +} + +static int output_relocation (struct fixup *fixup, unsigned long start_address_of_section, FILE *fp) { + + struct elks_relocation_info reloc; + + long log2_of_size, size; + unsigned long r_symbolnum; + + write_to_byte_array (reloc.r_address, fixup->frag->address + fixup->where - start_address_of_section, 4); + + if (symbol_is_section_symbol (fixup->add_symbol)) { + + if (symbol_get_section (fixup->add_symbol) == text_section) { + r_symbolnum = ELKS_N_TEXT; + } else if (symbol_get_section (fixup->add_symbol) == data_section) { + r_symbolnum = ELKS_N_DATA; + } else if (symbol_get_section (fixup->add_symbol) == bss_section) { + r_symbolnum = ELKS_N_BSS; + } else { + + report_at (__FILE__, __LINE__, REPORT_INTERNAL_ERROR, "invalid section %s", section_get_name (symbol_get_section (fixup->add_symbol))); + exit (EXIT_FAILURE); + + } + + } else { + + struct symbol *symbol; + long symbol_number; + + for (symbol = symbols, symbol_number = 0; symbol && (symbol != fixup->add_symbol); symbol = symbol->next) { + + if (symbol_is_external (symbol) || symbol_is_undefined (symbol)) { + symbol_number++; + } + + } + + r_symbolnum = symbol_number; + r_symbolnum |= (1LU << 31); + + } + + if (fixup->pcrel) { + r_symbolnum |= (1LU << 28); + } + + for (log2_of_size = -1, size = fixup->size; size; size >>= 1, log2_of_size++); + r_symbolnum |= ((unsigned long) log2_of_size << 29); + + if (fixup->reloc_type == RELOC_TYPE_FAR_CALL) { + r_symbolnum |= (1LU << 27); + } + + write_to_byte_array (reloc.r_symbolnum, r_symbolnum, 4); + + if (fwrite (&reloc, sizeof (reloc), 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "error writing text relocations"); + return 1; + + } + + return 0; + +} + +void output_elks (FILE *fp) { + + unsigned long start_address_of_data; + struct fixup *fixup; + + unsigned long symbol_table_size; + struct symbol *symbol; + + unsigned long string_table_pos; + struct frag *frag; + + unsigned long text_size, data_size, bss_size; + unsigned long tr_size, dr_size; + + struct elks_exec header; + memset (&header, 0, sizeof (header)); + + header.a_magic[0] = ((ELKS_MAGIC >> 8) & 0xff); + header.a_magic[1] = (ELKS_MAGIC & 0xff); + + header.a_flags = 0x10; + header.a_cpu = 0x04; + header.a_hdrlen = sizeof (header); + + if ((symbol = state->end_symbol)) { + write_to_byte_array (header.a_entry, symbol_get_value (symbol), 4); + } + + if (fseek (fp, sizeof (header), SEEK_SET)) { + + report_at (program_name, 0, REPORT_ERROR, "failed whilst seeking passed header"); + return; + + } + + section_set (text_section); + text_size = 0; + + for (frag = current_frag_chain->first_frag; frag; frag = frag->next) { + + if (frag->fixed_size == 0) { + continue; + } + + if (fwrite (frag->buf, frag->fixed_size, 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "failed whilst writing text"); + return; + + } + + text_size += frag->fixed_size; + + } + + write_to_byte_array (header.a_text, text_size, 4); + + section_set (data_section); + data_size = 0; + + for (frag = current_frag_chain->first_frag; frag; frag = frag->next) { + + if (frag->fixed_size == 0) { + continue; + } + + if (fwrite (frag->buf, frag->fixed_size, 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "failed whilst writing data"); + return; + + } + + data_size += frag->fixed_size; + + } + + write_to_byte_array (header.a_data, data_size, 4); + + section_set (bss_section); + bss_size = 0; + + for (frag = current_frag_chain->first_frag; frag; frag = frag->next) { + + if (frag->fixed_size == 0) { + continue; + } + + bss_size += frag->fixed_size; + + } + + write_to_byte_array (header.a_bss, bss_size, 4); + + section_set (text_section); + tr_size = 0; + + start_address_of_data = 0; + + for (fixup = current_frag_chain->first_fixup; fixup; fixup = fixup->next) { + + if (fixup->done) { + continue; + } + + if (output_relocation (fixup, start_address_of_data, fp)) { + return; + } + + tr_size += sizeof (struct elks_relocation_info); + + } + + write_to_byte_array (header.a_trsize, tr_size, 4); + + section_set (data_section); + dr_size = 0; + + start_address_of_data = current_frag_chain->first_frag->address; + + for (fixup = current_frag_chain->first_fixup; fixup; fixup = fixup->next) { + + if (fixup->done) { + continue; + } + + if (output_relocation (fixup, start_address_of_data, fp)) { + return; + } + + dr_size += sizeof (struct elks_relocation_info); + + } + + write_to_byte_array (header.a_drsize, dr_size, 4); + + symbol_table_size = 0; + string_table_pos = 4; + + for (symbol = symbols; symbol; symbol = symbol->next) { + + if (symbol_is_external (symbol) || symbol_is_undefined (symbol)) { + + struct elks_nlist symbol_entry; + memset (&symbol_entry, 0, sizeof (symbol_entry)); + + write_to_byte_array (symbol_entry.n_strx, string_table_pos, 4); + string_table_pos += strlen (symbol->name) + 1; + + if (state->ext) { + string_table_pos += strlen (state->ext); + } + + if (symbol->section == undefined_section) { + symbol_entry.n_type = ELKS_N_UNDF; + } else if (symbol->section == text_section) { + symbol_entry.n_type = ELKS_N_TEXT; + } else if (symbol->section == data_section) { + symbol_entry.n_type = ELKS_N_DATA; + } else if (symbol->section == bss_section) { + symbol_entry.n_type = ELKS_N_BSS; + } else if (symbol->section == absolute_section) { + symbol_entry.n_type = ELKS_N_ABS; + } else { + + report_at (__FILE__, __LINE__, REPORT_INTERNAL_ERROR, "invalid section %s", section_get_name (symbol->section)); + exit (EXIT_FAILURE); + + } + + write_to_byte_array (symbol_entry.n_value, symbol_get_value (symbol), 4); + symbol_entry.n_type |= ELKS_N_EXT; + + if (fwrite (&symbol_entry, sizeof (symbol_entry), 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "error writing symbol table"); + return; + + } + + symbol_table_size += sizeof (symbol_entry); + + } + + } + + write_to_byte_array (header.a_syms, symbol_table_size, 4); + + if (fwrite (&string_table_pos, 4, 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "failed to write string table"); + return; + + } + + for (symbol = symbols; symbol; symbol = symbol->next) { + + if (symbol_is_external (symbol) || symbol_is_undefined (symbol)) { + + if (state->ext) { + + if (fwrite (state->ext, strlen (state->ext), 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "failed to write string table"); + return; + + } + + } + + if (fwrite (symbol->name, strlen (symbol->name) + 1, 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "failed to write string table"); + return; + + } + + } + + } + + rewind (fp); + + if (fwrite (&header, sizeof (header), 1, fp) != 1) { + + report_at (program_name, 0, REPORT_ERROR, "failed to write header"); + return; + + } + +} diff --git a/elks.h b/elks.h new file mode 100644 index 0000000..e9d395f --- /dev/null +++ b/elks.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * @file elks.h + *****************************************************************************/ +#ifndef _ELKS_H +#define _ELKS_H + +struct elks_exec { + + unsigned char a_magic[2]; + unsigned char a_flags; + unsigned char a_cpu; + unsigned char a_hdrlen; + unsigned char a_unused; + unsigned char a_version[2]; + + unsigned char a_text[4]; + unsigned char a_data[4]; + unsigned char a_bss[4]; + unsigned char a_entry[4]; + unsigned char a_total[4]; + unsigned char a_syms[4]; + + unsigned char a_trsize[4]; + unsigned char a_drsize[4]; + unsigned char a_trbase[4]; + unsigned char a_drbase[4]; + +}; + +#define ELKS_MAGIC 0403 + +struct elks_relocation_info { + + unsigned char r_address[4]; + unsigned char r_symbolnum[4]; + +}; + +#define ELKS_N_UNDF 0x00 +#define ELKS_N_ABS 0x02 +#define ELKS_N_TEXT 0x04 +#define ELKS_N_DATA 0x06 +#define ELKS_N_BSS 0x08 + +struct elks_nlist { + + unsigned char n_strx[4]; + unsigned char n_type; + + unsigned char n_other; + unsigned char n_desc[2]; + + unsigned char n_value[4]; + +}; + +#define ELKS_N_EXT 0x01 + +#endif /* _ELKS_H */ diff --git a/obj.c b/obj.c deleted file mode 100644 index e9eae02..0000000 --- a/obj.c +++ /dev/null @@ -1,317 +0,0 @@ -/****************************************************************************** - * @file obj.c - *****************************************************************************/ -#include -#include -#include - -#include "as.h" -#include "fixup.h" -#include "frag.h" -#include "obj.h" -#include "report.h" -#include "section.h" -#include "symbol.h" - -static void write_to_byte_array (unsigned char *arr, unsigned long value, int size) { - - int i; - - for (i = 0; i < size; i++) { - arr[i] = (value >> (8 * i)) & 0xff; - } - -} - -static int output_relocation (struct fixup *fixup, unsigned long start_address_of_section, FILE *fp) { - - struct relocation_info reloc; - - long log2_of_size, size; - unsigned long r_symbolnum; - - write_to_byte_array (reloc.r_address, fixup->frag->address + fixup->where - start_address_of_section, 4); - - if (symbol_is_section_symbol (fixup->add_symbol)) { - - if (symbol_get_section (fixup->add_symbol) == text_section) { - r_symbolnum = N_TEXT; - } else if (symbol_get_section (fixup->add_symbol) == data_section) { - r_symbolnum = N_DATA; - } else if (symbol_get_section (fixup->add_symbol) == bss_section) { - r_symbolnum = N_BSS; - } else { - - report_at (__FILE__, __LINE__, REPORT_INTERNAL_ERROR, "invalid section %s", section_get_name (symbol_get_section (fixup->add_symbol))); - exit (EXIT_FAILURE); - - } - - } else { - - struct symbol *symbol; - long symbol_number; - - for (symbol = symbols, symbol_number = 0; symbol && (symbol != fixup->add_symbol); symbol = symbol->next) { - - if (symbol_is_external (symbol) || symbol_is_undefined (symbol)) { - symbol_number++; - } - - } - - r_symbolnum = symbol_number; - r_symbolnum |= (1LU << 31); - - } - - if (fixup->pcrel) { - r_symbolnum |= (1LU << 28); - } - - for (log2_of_size = -1, size = fixup->size; size; size >>= 1, log2_of_size++); - r_symbolnum |= ((unsigned long) log2_of_size << 29); - - if (fixup->reloc_type == RELOC_TYPE_FAR_CALL) { - r_symbolnum |= (1LU << 27); - } - - write_to_byte_array (reloc.r_symbolnum, r_symbolnum, 4); - - if (fwrite (&reloc, sizeof (reloc), 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "error writing text relocations"); - return 1; - - } - - return 0; - -} - -void output_obj (FILE *fp) { - - unsigned long start_address_of_data; - struct fixup *fixup; - - unsigned long symbol_table_size; - struct symbol *symbol; - - unsigned long string_table_pos; - struct frag *frag; - - unsigned long text_size, data_size, bss_size; - unsigned long tr_size, dr_size; - - struct exec header; - memset (&header, 0, sizeof (header)); - - write_to_byte_array (header.a_info, 0x00640000 | MAGIC, 4); - - if ((symbol = state->end_symbol)) { - write_to_byte_array (header.a_entry, symbol_get_value (symbol), 4); - } - - if (fseek (fp, sizeof (header), SEEK_SET)) { - - report_at (program_name, 0, REPORT_ERROR, "failed whilst seeking passed header"); - return; - - } - - section_set (text_section); - text_size = 0; - - for (frag = current_frag_chain->first_frag; frag; frag = frag->next) { - - if (frag->fixed_size == 0) { - continue; - } - - if (fwrite (frag->buf, frag->fixed_size, 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing text"); - return; - - } - - text_size += frag->fixed_size; - - } - - write_to_byte_array (header.a_text, text_size, 4); - - section_set (data_section); - data_size = 0; - - for (frag = current_frag_chain->first_frag; frag; frag = frag->next) { - - if (frag->fixed_size == 0) { - continue; - } - - if (fwrite (frag->buf, frag->fixed_size, 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "failed whilst writing data"); - return; - - } - - data_size += frag->fixed_size; - - } - - write_to_byte_array (header.a_data, data_size, 4); - - section_set (bss_section); - bss_size = 0; - - for (frag = current_frag_chain->first_frag; frag; frag = frag->next) { - - if (frag->fixed_size == 0) { - continue; - } - - bss_size += frag->fixed_size; - - } - - write_to_byte_array (header.a_bss, bss_size, 4); - - section_set (text_section); - tr_size = 0; - - start_address_of_data = 0; - - for (fixup = current_frag_chain->first_fixup; fixup; fixup = fixup->next) { - - if (fixup->done) { - continue; - } - - if (output_relocation (fixup, start_address_of_data, fp)) { - return; - } - - tr_size += sizeof (struct relocation_info); - - } - - write_to_byte_array (header.a_trsize, tr_size, 4); - - section_set (data_section); - dr_size = 0; - - start_address_of_data = current_frag_chain->first_frag->address; - - for (fixup = current_frag_chain->first_fixup; fixup; fixup = fixup->next) { - - if (fixup->done) { - continue; - } - - if (output_relocation (fixup, start_address_of_data, fp)) { - return; - } - - dr_size += sizeof (struct relocation_info); - - } - - write_to_byte_array (header.a_drsize, dr_size, 4); - - symbol_table_size = 0; - string_table_pos = 4; - - for (symbol = symbols; symbol; symbol = symbol->next) { - - if (symbol_is_external (symbol) || symbol_is_undefined (symbol)) { - - struct nlist symbol_entry; - memset (&symbol_entry, 0, sizeof (symbol_entry)); - - write_to_byte_array (symbol_entry.n_strx, string_table_pos, 4); - string_table_pos += strlen (symbol->name) + 1; - - if (state->ext) { - string_table_pos += strlen (state->ext); - } - - if (symbol->section == undefined_section) { - symbol_entry.n_type = N_UNDF; - } else if (symbol->section == text_section) { - symbol_entry.n_type = N_TEXT; - } else if (symbol->section == data_section) { - symbol_entry.n_type = N_DATA; - } else if (symbol->section == bss_section) { - symbol_entry.n_type = N_BSS; - } else if (symbol->section == absolute_section) { - symbol_entry.n_type = N_ABS; - } else { - - report_at (__FILE__, __LINE__, REPORT_INTERNAL_ERROR, "invalid section %s", section_get_name (symbol->section)); - exit (EXIT_FAILURE); - - } - - write_to_byte_array (symbol_entry.n_value, symbol_get_value (symbol), 4); - symbol_entry.n_type |= N_EXT; - - if (fwrite (&symbol_entry, sizeof (symbol_entry), 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "error writing symbol table"); - return; - - } - - symbol_table_size += sizeof (symbol_entry); - - } - - } - - write_to_byte_array (header.a_syms, symbol_table_size, 4); - - if (fwrite (&string_table_pos, 4, 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "failed to write string table"); - return; - - } - - for (symbol = symbols; symbol; symbol = symbol->next) { - - if (symbol_is_external (symbol) || symbol_is_undefined (symbol)) { - - if (state->ext) { - - if (fwrite (state->ext, strlen (state->ext), 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "failed to write string table"); - return; - - } - - } - - if (fwrite (symbol->name, strlen (symbol->name) + 1, 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "failed to write string table"); - return; - - } - - } - - } - - rewind (fp); - - if (fwrite (&header, sizeof (header), 1, fp) != 1) { - - report_at (program_name, 0, REPORT_ERROR, "failed to write header"); - return; - - } - -} diff --git a/obj.h b/obj.h deleted file mode 100644 index a92812e..0000000 --- a/obj.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * @file obj.h - *****************************************************************************/ -#ifndef _OBJ_H -#define _OBJ_H - -struct exec { - - unsigned char a_info[4]; - unsigned char a_text[4]; - unsigned char a_data[4]; - unsigned char a_bss[4]; - unsigned char a_syms[4]; - unsigned char a_entry[4]; - unsigned char a_trsize[4]; - unsigned char a_drsize[4]; - -}; - -#define MAGIC 0471 - -struct relocation_info { - - unsigned char r_address[4]; - unsigned char r_symbolnum[4]; - -}; - -#define N_UNDF 0x00 -#define N_ABS 0x02 -#define N_TEXT 0x04 -#define N_DATA 0x06 -#define N_BSS 0x08 - -struct nlist { - - unsigned char n_strx[4]; - unsigned char n_type; - - unsigned char n_value[4]; - -}; - -#define N_EXT 0x01 - -#endif /* _OBJ_H */