diff --git a/src/tools/elf2aout.c b/src/tools/elf2aout.c index e5f449ce9f..df1129af71 100644 --- a/src/tools/elf2aout.c +++ b/src/tools/elf2aout.c @@ -41,6 +41,9 @@ #include +int elf2aout32(void *v, int fd); +int elf2aout64(void *v, int fd); + #define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x)) #define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) #define xe64toh(x) ((data == ELFDATA2MSB) ? be64toh(x) : le64toh(x)) @@ -56,18 +59,167 @@ struct exec { u_int32_t a_trsize; u_int32_t a_drsize; }; -#define A_MAGIC 0x01030107 + +/* we only support OMAGIC */ +#define OMAGIC 0407 static void usage(void); -/* - * elf to a.out converter for freebsd/sparc64 bootblocks. - */ +/* parts from NetBSD */ + +#define MID_ZERO 0x000 /* unknown - implementation dependent */ +#define MID_SUN010 0x001 /* sun 68010/68020 binary */ +#define MID_SUN020 0x002 /* sun 68020-only binary */ + +#define MID_PC386 0x064 /* 386 PC binary. (so quoth BFD) */ + +#define MID_I386 0x086 /* i386 BSD binary */ +#define MID_M68K 0x087 /* m68k BSD binary with 8K page sizes */ +#define MID_M68K4K 0x088 /* m68k BSD binary with 4K page sizes */ +#define MID_NS32532 0x089 /* ns32532 */ +#define MID_SPARC 0x08a /* sparc */ +#define MID_PMAX 0x08b /* pmax */ +#define MID_VAX1K 0x08c /* VAX 1K page size binaries */ +#define MID_ALPHA 0x08d /* Alpha BSD binary */ +#define MID_MIPS 0x08e /* big-endian MIPS */ +#define MID_ARM6 0x08f /* ARM6 */ +#define MID_M680002K 0x090 /* m68000 with 2K page sizes */ +#define MID_SH3 0x091 /* SH3 */ + +#define MID_POWERPC64 0x094 /* big-endian PowerPC 64 */ +#define MID_POWERPC 0x095 /* big-endian PowerPC */ +#define MID_VAX 0x096 /* VAX */ +#define MID_MIPS1 0x097 /* MIPS1 */ +#define MID_MIPS2 0x098 /* MIPS2 */ +#define MID_M88K 0x099 /* m88k BSD */ +#define MID_HPPA 0x09a /* HP PARISC */ +#define MID_SH5_64 0x09b /* LP64 SH5 */ +#define MID_SPARC64 0x09c /* LP64 sparc */ +#define MID_X86_64 0x09d /* AMD x86-64 */ +#define MID_SH5_32 0x09e /* ILP32 SH5 */ +#define MID_IA64 0x09f /* Itanium */ + +#define MID_AARCH64 0x0b7 /* ARM AARCH64 */ +#define MID_OR1K 0x0b8 /* OpenRISC 1000 */ +#define MID_RISCV 0x0b9 /* Risc-V */ + +#define MID_HP200 0x0c8 /* hp200 (68010) BSD binary */ + +#define MID_HP300 0x12c /* hp300 (68020+68881) BSD binary */ + +#define MID_HPUX800 0x20b /* hp800 HP-UX binary */ +#define MID_HPUX 0x20c /* hp200/300 HP-UX binary */ + +//(ex->e_machine, ex->e_ident[EI_DATA], ex->e_ident[EI_CLASS]) +static uint32_t +get_mid(int m, int e, int c) +{ + switch (m) { + case EM_AARCH64: + return MID_AARCH64; + case EM_ALPHA: + return MID_ALPHA; + case EM_ARM: + return MID_ARM6; + case EM_PARISC: + return MID_HPPA; + case EM_386: + return MID_I386; + case EM_68K: + return MID_M68K; +/* case EM_OR1K: + return MID_OR1K;*/ + case EM_MIPS: + if (e == ELFDATA2LSB) + return MID_PMAX; + else + return MID_MIPS; + case EM_PPC: + return MID_POWERPC; + case EM_PPC64: + return MID_POWERPC64; + break; + case EM_RISCV: + return MID_RISCV; + case EM_SH: + return MID_SH3; + case EM_SPARC: + case EM_SPARC32PLUS: + case EM_SPARCV9: + if (c == ELFCLASS32) + return MID_SPARC; + return MID_SPARC64; + case EM_X86_64: + return MID_X86_64; + case EM_VAX: + return MID_VAX; + case EM_NONE: + return MID_ZERO; + default: + break; + } + return MID_ZERO; +} + int -main(int ac, char **av) +elf2aout32(void *v, int fd) +{ + Elf32_Half phentsize; + Elf32_Half phnum; + Elf32_Word filesz; + Elf32_Word memsz; + Elf32_Addr entry; + Elf32_Off offset; + Elf32_Off phoff; + Elf32_Word type; + + Elf32_Phdr *p; + Elf32_Ehdr *e = v; + + unsigned char data = e->e_ident[EI_DATA]; + struct exec a; + int i; + uint32_t mid; + + mid = get_mid(xe16toh(e->e_machine), e->e_ident[EI_DATA], e->e_ident[EI_CLASS]); + phentsize = xe16toh(e->e_phentsize); + if (phentsize != sizeof(*p)) + errx(1, "phdr size mismatch"); + + entry = xe32toh(e->e_entry); + phoff = xe32toh(e->e_phoff); + phnum = xe16toh(e->e_phnum); + p = (Elf32_Phdr *)((char *)e + phoff); + bzero(&a, sizeof(a)); + for (i = 0; i < phnum; i++) { + type = xe32toh(p[i].p_type); + switch (type) { + case PT_LOAD: + if (a.a_magic != 0) + errx(1, "too many loadable segments"); + filesz = xe32toh(p[i].p_filesz); + memsz = xe32toh(p[i].p_memsz); + offset = xe32toh(p[i].p_offset); + a.a_magic = htoxe32(((uint32_t)mid << 16) | OMAGIC); + a.a_text = htoxe32(filesz); + a.a_bss = htoxe32(memsz - filesz); + a.a_entry = htoxe32(entry); + if (write(fd, &a, sizeof(a)) != sizeof(a) || + write(fd, (char *)e + offset, filesz) != (ssize_t)filesz) + err(1, NULL); + break; + default: + break; + } + } + return (0); +} + + +int +elf2aout64(void *v, int fd) { Elf64_Half phentsize; - Elf64_Half machine; Elf64_Half phnum; Elf64_Xword filesz; Elf64_Xword memsz; @@ -75,16 +227,63 @@ main(int ac, char **av) Elf64_Off offset; Elf64_Off phoff; Elf64_Word type; + + Elf64_Phdr *p; + Elf64_Ehdr *e = v; + + unsigned char data = e->e_ident[EI_DATA]; + struct exec a; + int i; + uint32_t mid; + + mid = get_mid(xe16toh(e->e_machine), e->e_ident[EI_DATA], e->e_ident[EI_CLASS]); + phentsize = xe16toh(e->e_phentsize); + if (phentsize != sizeof(*p)) + errx(1, "phdr size mismatch"); + + entry = xe64toh(e->e_entry); + phoff = xe64toh(e->e_phoff); + phnum = xe16toh(e->e_phnum); + p = (Elf64_Phdr *)((char *)e + phoff); + bzero(&a, sizeof(a)); + for (i = 0; i < phnum; i++) { + type = xe32toh(p[i].p_type); + switch (type) { + case PT_LOAD: + if (a.a_magic != 0) + errx(1, "too many loadable segments"); + filesz = xe64toh(p[i].p_filesz); + memsz = xe64toh(p[i].p_memsz); + offset = xe64toh(p[i].p_offset); + a.a_magic = htoxe32(((uint32_t)mid << 16) | OMAGIC); + a.a_text = htoxe32(filesz); + a.a_bss = htoxe32(memsz - filesz); + a.a_entry = htoxe32(entry); + if (write(fd, &a, sizeof(a)) != sizeof(a) || + write(fd, (char *)e + offset, filesz) != (ssize_t)filesz) + err(1, NULL); + break; + default: + break; + } + } + return (0); +} + + +/* + * elf to a.out converter for freebsd/sparc64 bootblocks. + */ +int +main(int ac, char **av) +{ unsigned char data; struct stat sb; - struct exec a; - Elf64_Phdr *p; Elf64_Ehdr *e; void *v; int efd; int fd; int c; - int i; fd = STDIN_FILENO; while ((c = getopt(ac, av, "o:")) != -1) @@ -110,48 +309,18 @@ main(int ac, char **av) if (!IS_ELF(*e)) errx(1, "not an elf file"); - if (e->e_ident[EI_CLASS] != ELFCLASS64) + if (e->e_ident[EI_CLASS] != ELFCLASS64 && e->e_ident[EI_CLASS] != ELFCLASS32) errx(1, "wrong class"); data = e->e_ident[EI_DATA]; if (data != ELFDATA2MSB && data != ELFDATA2LSB) errx(1, "wrong data format"); if (e->e_ident[EI_VERSION] != EV_CURRENT) errx(1, "wrong elf version"); - machine = xe16toh(e->e_machine); - if (machine != EM_SPARCV9 && machine != EM_ALPHA) - errx(1, "wrong machine type"); - phentsize = xe16toh(e->e_phentsize); - if (phentsize != sizeof(*p)) - errx(1, "phdr size mismatch"); - entry = xe64toh(e->e_entry); - phoff = xe64toh(e->e_phoff); - phnum = xe16toh(e->e_phnum); - p = (Elf64_Phdr *)((char *)e + phoff); - bzero(&a, sizeof(a)); - for (i = 0; i < phnum; i++) { - type = xe32toh(p[i].p_type); - switch (type) { - case PT_LOAD: - if (a.a_magic != 0) - errx(1, "too many loadable segments"); - filesz = xe64toh(p[i].p_filesz); - memsz = xe64toh(p[i].p_memsz); - offset = xe64toh(p[i].p_offset); - a.a_magic = htoxe32(A_MAGIC); - a.a_text = htoxe32(filesz); - a.a_bss = htoxe32(memsz - filesz); - a.a_entry = htoxe32(entry); - if (write(fd, &a, sizeof(a)) != sizeof(a) || - write(fd, (char *)e + offset, filesz) != (ssize_t)filesz) - err(1, NULL); - break; - default: - break; - } - } - - return (0); + if (e->e_ident[EI_CLASS] == ELFCLASS64) + return elf2aout64(v, fd); + else + return elf2aout32(v, fd); } static void