[haiku-commits] Change in haiku[master]: elf2aout: Fix for 32bit

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 5 Feb 2020 11:20:06 +0000

From François Revol <revol@xxxxxxx>:

François Revol has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/2206 ;)


Change subject: elf2aout: Fix for 32bit
......................................................................

elf2aout: Fix for 32bit

Sadly the NetBSD elf2aout only support 32bit, and this one from FreeBSD
only supports 64bit. This one was simpler to fix because it only handles
basic stuff.

Change-Id: I70165f680ec1cd95c156d4116f9d96c6b4ac53b0
---
M src/tools/elf2aout.c
1 file changed, 214 insertions(+), 44 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/06/2206/1

diff --git a/src/tools/elf2aout.c b/src/tools/elf2aout.c
index e5f449c..c588af3 100644
--- a/src/tools/elf2aout.c
+++ b/src/tools/elf2aout.c
@@ -41,6 +41,9 @@

 #include <elf.h>

+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,168 @@
        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:
+                       printf("PT_LOAD\n");
+                       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 +228,63 @@
        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 +310,18 @@

        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

--
To view, visit https://review.haiku-os.org/c/haiku/+/2206
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I70165f680ec1cd95c156d4116f9d96c6b4ac53b0
Gerrit-Change-Number: 2206
Gerrit-PatchSet: 1
Gerrit-Owner: François Revol <revol@xxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: elf2aout: Fix for 32bit - Gerrit