From aedc48935730437ea2216688cea90c2eb12538e8 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Tue, 8 Apr 2014 20:46:27 +0000 Subject: [PATCH] replace ehdr.e_wident[4] junk with standard e_ident[EI_NIDENT], add top-level Makefile, add TODO --- Makefile | 10 ++++++++++ TODO | 29 +++++++++++++++++++++++++++++ as/output.c | 27 +++++++++++++++------------ include/pdp10-elf36.h | 8 +------- lib/pdp10-elf36.c | 24 ++++++++++++++---------- nm/nm.c | 38 +++++--------------------------------- readelf/gen-test1.c | 22 ++++++++++------------ readelf/readelf.c | 41 +++++++---------------------------------- 8 files changed, 91 insertions(+), 108 deletions(-) create mode 100644 Makefile create mode 100644 TODO diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aae147b --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +SUBDIRS= lib 8to9 ar as nm od readelf + +all: + make TARGET= subdirs + +clean: + make TARGET=clean subdirs + +subdirs: + for d in $(SUBDIRS); do make -C $$d $(TARGET); done diff --git a/TODO b/TODO new file mode 100644 index 0000000..97884a0 --- /dev/null +++ b/TODO @@ -0,0 +1,29 @@ +Elf36 Specification: + +- Do we want to adjust SHN_LORESERVE up to SHN_HIRESERVE, including SHN_XINDEX, to + account for the fact that we have 2 more bits available in Elf36_Half? + I'm inclined not to change, but to allow indices in [SHN_HIRESERVE+1,PDP10_UINT18_MAX] + as-is without going through SHN_XINDEX. + +- Same question for PN_XNUM? + +- Summarize the differences between Elf32 and Elf36 in a document somewhere. + +pdp10-stdio: + +- Handle non-seekable output files better (i.e., allow 8to9 to write to stdout) + +Tools: + +- size: implement it +- strip: implement it +- ld: implement it +- readelf: add support for relocs +- readelf: add support for program headers +- as: + * add support for named sections + * add support for sub-sections + * add support for data directives (.word, .asciz, etc) + * add support for relocs + * add support for extended opcodes (emit second opcode after current .text section) + * add support for symbolic references to 30 or 36-bit addresses via something like %hi/%lo functions diff --git a/as/output.c b/as/output.c index 12adb62..2962197 100644 --- a/as/output.c +++ b/as/output.c @@ -346,18 +346,21 @@ int output(struct tunit *tunit, const char *outfile) context.offset = 0; } - ehdr.e_wident[0] = (((pdp10_uint36_t)ELFMAG0 << 28) - | (ELFMAG1 << 20) - | (ELFMAG2 << 12) - | (ELFMAG3 << 4) - | (ELFCLASS36 >> 4)); - ehdr.e_wident[1] = (((pdp10_uint36_t)(ELFCLASS36 & 0x0f) << 32) - | (ELFDATA2MSB << 24) - | (EV_CURRENT << 16) - | (ELFOSABI_NONE << 8) - | 0); /* EI_ABIVERSION */ - ehdr.e_wident[2] = 0; - ehdr.e_wident[3] = 0; + ehdr.e_ident[EI_MAG0] = ELFMAG0; + ehdr.e_ident[EI_MAG1] = ELFMAG1; + ehdr.e_ident[EI_MAG2] = ELFMAG2; + ehdr.e_ident[EI_MAG3] = ELFMAG3; + ehdr.e_ident[EI_CLASS] = ELFCLASS36; + ehdr.e_ident[EI_DATA] = ELFDATA2MSB; + ehdr.e_ident[EI_VERSION] = EV_CURRENT; + ehdr.e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr.e_ident[EI_ABIVERSION] = 0; + { + int i; + + for (i = EI_PAD; i < EI_NIDENT; ++i) + ehdr.e_ident[i] = 0; + } ehdr.e_type = ET_REL; ehdr.e_machine = EM_PDP10; ehdr.e_version = EV_CURRENT; diff --git a/include/pdp10-elf36.h b/include/pdp10-elf36.h index c31f59b..0be824d 100644 --- a/include/pdp10-elf36.h +++ b/include/pdp10-elf36.h @@ -22,13 +22,7 @@ typedef pdp10_uint36_t Elf36_Word; #define EI_NIDENT 16 typedef struct { - /* In the standard 32 and 64 bit ELF specifications the ELF header starts - * with a 16-octet e_ident[] array, of which the first 9 octets are defined, - * and the last 7 octets should be zero. To enable a binary-compatible - * e_ident with Elf36, we pack the first 9 octets in two 36-bit words, and - * add two words of padding, making e_ident 16 bits larger in Elf36. - */ - Elf36_Word e_wident[4]; /* e_ident[] indices 0 to 4.5 */ + Elf36_Uchar e_ident[EI_NIDENT]; /* ELF magic */ Elf36_Half e_type; /* Identifies object file type */ Elf36_Half e_machine; /* Specifies required architecture */ Elf36_Word e_version; /* Identifies object file version */ diff --git a/lib/pdp10-elf36.c b/lib/pdp10-elf36.c index 545bff8..17d9dcf 100644 --- a/lib/pdp10-elf36.c +++ b/lib/pdp10-elf36.c @@ -95,11 +95,13 @@ int pdp10_elf36_read_sint36(PDP10_FILE *pdp10fp, pdp10_int36_t *dst) int pdp10_elf36_write_ehdr(PDP10_FILE *pdp10fp, const Elf36_Ehdr *ehdr) { - if (pdp10_elf36_write_uint36(pdp10fp, ehdr->e_wident[0]) < 0 - || pdp10_elf36_write_uint36(pdp10fp, ehdr->e_wident[1]) < 0 - || pdp10_elf36_write_uint36(pdp10fp, ehdr->e_wident[2]) < 0 - || pdp10_elf36_write_uint36(pdp10fp, ehdr->e_wident[3]) < 0 - || pdp10_elf36_write_uint18(pdp10fp, ehdr->e_type) < 0 + int i; + + for (i = 0; i < EI_NIDENT; ++i) + if (pdp10_elf36_write_uint9(pdp10fp, ehdr->e_ident[i]) < 0) + return -1; + + if (pdp10_elf36_write_uint18(pdp10fp, ehdr->e_type) < 0 || pdp10_elf36_write_uint18(pdp10fp, ehdr->e_machine) < 0 || pdp10_elf36_write_uint36(pdp10fp, ehdr->e_version) < 0 || pdp10_elf36_write_uint36(pdp10fp, ehdr->e_entry) < 0 @@ -118,11 +120,13 @@ int pdp10_elf36_write_ehdr(PDP10_FILE *pdp10fp, const Elf36_Ehdr *ehdr) int pdp10_elf36_read_ehdr(PDP10_FILE *pdp10fp, Elf36_Ehdr *ehdr) { - if (pdp10_elf36_read_uint36(pdp10fp, &ehdr->e_wident[0]) < 0 - || pdp10_elf36_read_uint36(pdp10fp, &ehdr->e_wident[1]) < 0 - || pdp10_elf36_read_uint36(pdp10fp, &ehdr->e_wident[2]) < 0 - || pdp10_elf36_read_uint36(pdp10fp, &ehdr->e_wident[3]) < 0 - || pdp10_elf36_read_uint18(pdp10fp, &ehdr->e_type) < 0 + int i; + + for (i = 0; i < EI_NIDENT; ++i) + if (pdp10_elf36_read_uint9(pdp10fp, &ehdr->e_ident[i]) < 0) + return -1; + + if (pdp10_elf36_read_uint18(pdp10fp, &ehdr->e_type) < 0 || pdp10_elf36_read_uint18(pdp10fp, &ehdr->e_machine) < 0 || pdp10_elf36_read_uint36(pdp10fp, &ehdr->e_version) < 0 || pdp10_elf36_read_uint36(pdp10fp, &ehdr->e_entry) < 0 diff --git a/nm/nm.c b/nm/nm.c index 41ee3ca..480f66e 100644 --- a/nm/nm.c +++ b/nm/nm.c @@ -81,28 +81,11 @@ static void params_file_fini(struct params *params) pdp10_fclose(params->pdp10fp); } -static void ehdr_unpack_ident(const Elf36_Ehdr *ehdr, unsigned char *e_ident) +static int check_ehdr(struct params *params) { - pdp10_uint36_t wident[4]; - unsigned int w, i, b; + Elf36_Ehdr *ehdr = ¶ms->ehdr; + Elf36_Uchar *e_ident = ehdr->e_ident; - for (w = 0; w < 4; ++w) - wident[w] = ehdr->e_wident[w]; - - for (i = 0; i < EI_NIDENT; ++i) { - for (w = 0; w < 4; ++w) { - b = (wident[w] >> (36 - 8)) & 0xff; - if (w == 0) - e_ident[i] = b; - else - wident[w - 1] |= b; - wident[w] = (wident[w] & ((1 << (36 - 8)) - 1)) << 8; - } - } -} - -static int check_eident(struct params *params, const unsigned char *e_ident) -{ if (e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 || e_ident[EI_MAG2] != ELFMAG2 @@ -145,13 +128,6 @@ static int check_eident(struct params *params, const unsigned char *e_ident) return -1; } - return 0; -} - -static int check_ehdr(struct params *params) -{ - Elf36_Ehdr *ehdr = ¶ms->ehdr; - switch (ehdr->e_type) { case ET_REL: case ET_EXEC: @@ -593,16 +569,12 @@ static int print_symtab(struct params *params) static int nm1(struct params *params) { - unsigned char e_ident[EI_NIDENT]; - if (pdp10_elf36_read_ehdr(params->pdp10fp, ¶ms->ehdr) < 0) { fprintf(stderr, "%s: %s: failed to read ELF header: %s\n", params->progname, params->filename, strerror(errno)); return -1; } - ehdr_unpack_ident(¶ms->ehdr, e_ident); - if (check_eident(params, e_ident) < 0 - || check_ehdr(params) < 0) + if (check_ehdr(params) < 0) return -1; if (read_shtab(params) < 0) { @@ -677,7 +649,7 @@ static const struct option long_options[] = { */ { "no-demangle", no_argument, 0, LOPT_no_demangle }, { "special-syms", no_argument, 0, LOPT_special_syms }, - { "defined-only", no_argument, 0, LOPT_defined_only }, + { "defined-only", no_argument, 0, LOPT_defined_only }, /* * Long aliases for short options: */ diff --git a/readelf/gen-test1.c b/readelf/gen-test1.c index 825c4e4..0902179 100644 --- a/readelf/gen-test1.c +++ b/readelf/gen-test1.c @@ -168,18 +168,16 @@ static int write_elf(PDP10_FILE *pdp10fp) }, }; static const Elf36_Ehdr ehdr = { - .e_wident[0] = (((pdp10_uint36_t)ELFMAG0 << 28) - | (ELFMAG1 << 20) - | (ELFMAG2 << 12) - | (ELFMAG3 << 4) - | (ELFCLASS36 >> 4)), - .e_wident[1] = (((pdp10_uint36_t)(ELFCLASS36 & 0x0f) << 32) - | (ELFDATA2MSB << 24) - | (EV_CURRENT << 16) - | (ELFOSABI_NONE << 8) - | 0), /* EI_ABIVERSION */ - .e_wident[2] = 0, - .e_wident[3] = 0, + .e_ident[EI_MAG0] = ELFMAG0, + .e_ident[EI_MAG1] = ELFMAG1, + .e_ident[EI_MAG2] = ELFMAG2, + .e_ident[EI_MAG3] = ELFMAG3, + .e_ident[EI_CLASS] = ELFCLASS36, + .e_ident[EI_DATA] = ELFDATA2MSB, + .e_ident[EI_VERSION] = EV_CURRENT, + .e_ident[EI_OSABI] = ELFOSABI_NONE, + .e_ident[EI_ABIVERSION] = 0, + .e_ident[EI_PAD ... EI_NIDENT - 1] = 0, .e_type = ET_REL, .e_machine = EM_PDP10, .e_version = EV_CURRENT, diff --git a/readelf/readelf.c b/readelf/readelf.c index 86dfe0f..89a4000 100644 --- a/readelf/readelf.c +++ b/readelf/readelf.c @@ -158,28 +158,11 @@ static const char *machine_name(unsigned int e_machine) } } -static void ehdr_unpack_ident(const Elf36_Ehdr *ehdr, unsigned char *e_ident) +static int check_ehdr(struct params *params) { - pdp10_uint36_t wident[4]; - unsigned int w, i, b; + const Elf36_Ehdr *ehdr = ¶ms->ehdr; + const Elf36_Uchar *e_ident = ehdr->e_ident; - for (w = 0; w < 4; ++w) - wident[w] = ehdr->e_wident[w]; - - for (i = 0; i < EI_NIDENT; ++i) { - for (w = 0; w < 4; ++w) { - b = (wident[w] >> (36 - 8)) & 0xff; - if (w == 0) - e_ident[i] = b; - else - wident[w - 1] |= b; - wident[w] = (wident[w] & ((1 << (36 - 8)) - 1)) << 8; - } - } -} - -static int check_eident(struct params *params, const unsigned char *e_ident) -{ if (e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 || e_ident[EI_MAG2] != ELFMAG2 @@ -222,13 +205,6 @@ static int check_eident(struct params *params, const unsigned char *e_ident) return -1; } - return 0; -} - -static int check_ehdr(struct params *params) -{ - Elf36_Ehdr *ehdr = ¶ms->ehdr; - switch (ehdr->e_type) { case ET_REL: case ET_EXEC: @@ -268,8 +244,9 @@ static int check_ehdr(struct params *params) return 0; } -static void print_ehdr(const Elf36_Ehdr *ehdr, const unsigned char *e_ident) +static void print_ehdr(const Elf36_Ehdr *ehdr) { + const Elf36_Uchar *e_ident = ehdr->e_ident; unsigned int i; printf("ELF Header:\n"); @@ -837,20 +814,16 @@ static int disassemble_all(struct params *params) static int readelf(struct params *params) { - unsigned char e_ident[EI_NIDENT]; - if (pdp10_elf36_read_ehdr(params->pdp10fp, ¶ms->ehdr) < 0) { fprintf(stderr, "%s: %s: failed to read ELF header: %s\n", params->progname, params->filename, strerror(errno)); return -1; } - ehdr_unpack_ident(¶ms->ehdr, e_ident); - if (check_eident(params, e_ident) < 0 - || check_ehdr(params) < 0) + if (check_ehdr(params) < 0) return -1; if (params->opts.file_header) - print_ehdr(¶ms->ehdr, e_ident); + print_ehdr(¶ms->ehdr); if (read_shtab(params) < 0) { fprintf(stderr, "%s: %s: failed to read section header table\n",