1*076b1902SAdrien Destugues /*- 2*076b1902SAdrien Destugues * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*076b1902SAdrien Destugues * 4*076b1902SAdrien Destugues * Copyright (c) 2002 Jake Burkholder 5*076b1902SAdrien Destugues * All rights reserved. 6*076b1902SAdrien Destugues * 7*076b1902SAdrien Destugues * Redistribution and use in source and binary forms, with or without 8*076b1902SAdrien Destugues * modification, are permitted provided that the following conditions 9*076b1902SAdrien Destugues * are met: 10*076b1902SAdrien Destugues * 1. Redistributions of source code must retain the above copyright 11*076b1902SAdrien Destugues * notice, this list of conditions and the following disclaimer. 12*076b1902SAdrien Destugues * 2. Redistributions in binary form must reproduce the above copyright 13*076b1902SAdrien Destugues * notice, this list of conditions and the following disclaimer in the 14*076b1902SAdrien Destugues * documentation and/or other materials provided with the distribution. 15*076b1902SAdrien Destugues * 16*076b1902SAdrien Destugues * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*076b1902SAdrien Destugues * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*076b1902SAdrien Destugues * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*076b1902SAdrien Destugues * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*076b1902SAdrien Destugues * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*076b1902SAdrien Destugues * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*076b1902SAdrien Destugues * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*076b1902SAdrien Destugues * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*076b1902SAdrien Destugues * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*076b1902SAdrien Destugues * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*076b1902SAdrien Destugues * SUCH DAMAGE. 27*076b1902SAdrien Destugues */ 28*076b1902SAdrien Destugues 29*076b1902SAdrien Destugues #include <sys/cdefs.h> 30*076b1902SAdrien Destugues 31*076b1902SAdrien Destugues #include <sys/types.h> 32*076b1902SAdrien Destugues #include <sys/mman.h> 33*076b1902SAdrien Destugues #include <sys/stat.h> 34*076b1902SAdrien Destugues 35*076b1902SAdrien Destugues #include <err.h> 36*076b1902SAdrien Destugues #include <fcntl.h> 37*076b1902SAdrien Destugues #include <stdio.h> 38*076b1902SAdrien Destugues #include <stdlib.h> 39*076b1902SAdrien Destugues #include <string.h> 40*076b1902SAdrien Destugues #include <unistd.h> 41*076b1902SAdrien Destugues 42*076b1902SAdrien Destugues #include <elf.h> 43*076b1902SAdrien Destugues 44*076b1902SAdrien Destugues #define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x)) 45*076b1902SAdrien Destugues #define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 46*076b1902SAdrien Destugues #define xe64toh(x) ((data == ELFDATA2MSB) ? be64toh(x) : le64toh(x)) 47*076b1902SAdrien Destugues #define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 48*076b1902SAdrien Destugues 49*076b1902SAdrien Destugues struct exec { 50*076b1902SAdrien Destugues u_int32_t a_magic; 51*076b1902SAdrien Destugues u_int32_t a_text; 52*076b1902SAdrien Destugues u_int32_t a_data; 53*076b1902SAdrien Destugues u_int32_t a_bss; 54*076b1902SAdrien Destugues u_int32_t a_syms; 55*076b1902SAdrien Destugues u_int32_t a_entry; 56*076b1902SAdrien Destugues u_int32_t a_trsize; 57*076b1902SAdrien Destugues u_int32_t a_drsize; 58*076b1902SAdrien Destugues }; 59*076b1902SAdrien Destugues #define A_MAGIC 0x01030107 60*076b1902SAdrien Destugues 61*076b1902SAdrien Destugues static void usage(void); 62*076b1902SAdrien Destugues 63*076b1902SAdrien Destugues /* 64*076b1902SAdrien Destugues * elf to a.out converter for freebsd/sparc64 bootblocks. 65*076b1902SAdrien Destugues */ 66*076b1902SAdrien Destugues int 67*076b1902SAdrien Destugues main(int ac, char **av) 68*076b1902SAdrien Destugues { 69*076b1902SAdrien Destugues Elf64_Half phentsize; 70*076b1902SAdrien Destugues Elf64_Half machine; 71*076b1902SAdrien Destugues Elf64_Half phnum; 72*076b1902SAdrien Destugues Elf64_Xword filesz; 73*076b1902SAdrien Destugues Elf64_Xword memsz; 74*076b1902SAdrien Destugues Elf64_Addr entry; 75*076b1902SAdrien Destugues Elf64_Off offset; 76*076b1902SAdrien Destugues Elf64_Off phoff; 77*076b1902SAdrien Destugues Elf64_Word type; 78*076b1902SAdrien Destugues unsigned char data; 79*076b1902SAdrien Destugues struct stat sb; 80*076b1902SAdrien Destugues struct exec a; 81*076b1902SAdrien Destugues Elf64_Phdr *p; 82*076b1902SAdrien Destugues Elf64_Ehdr *e; 83*076b1902SAdrien Destugues void *v; 84*076b1902SAdrien Destugues int efd; 85*076b1902SAdrien Destugues int fd; 86*076b1902SAdrien Destugues int c; 87*076b1902SAdrien Destugues int i; 88*076b1902SAdrien Destugues 89*076b1902SAdrien Destugues fd = STDIN_FILENO; 90*076b1902SAdrien Destugues while ((c = getopt(ac, av, "o:")) != -1) 91*076b1902SAdrien Destugues switch (c) { 92*076b1902SAdrien Destugues case 'o': 93*076b1902SAdrien Destugues if ((fd = open(optarg, O_CREAT|O_RDWR, 0644)) < 0) 94*076b1902SAdrien Destugues err(1, "%s", optarg); 95*076b1902SAdrien Destugues break; 96*076b1902SAdrien Destugues case '?': 97*076b1902SAdrien Destugues default: 98*076b1902SAdrien Destugues usage(); 99*076b1902SAdrien Destugues } 100*076b1902SAdrien Destugues ac -= optind; 101*076b1902SAdrien Destugues av += optind; 102*076b1902SAdrien Destugues if (ac == 0) 103*076b1902SAdrien Destugues usage(); 104*076b1902SAdrien Destugues 105*076b1902SAdrien Destugues if ((efd = open(*av, O_RDONLY)) < 0 || fstat(efd, &sb) < 0) 106*076b1902SAdrien Destugues err(1, NULL); 107*076b1902SAdrien Destugues v = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, efd, 0); 108*076b1902SAdrien Destugues if ((e = v) == MAP_FAILED) 109*076b1902SAdrien Destugues err(1, NULL); 110*076b1902SAdrien Destugues 111*076b1902SAdrien Destugues if (!IS_ELF(*e)) 112*076b1902SAdrien Destugues errx(1, "not an elf file"); 113*076b1902SAdrien Destugues if (e->e_ident[EI_CLASS] != ELFCLASS64) 114*076b1902SAdrien Destugues errx(1, "wrong class"); 115*076b1902SAdrien Destugues data = e->e_ident[EI_DATA]; 116*076b1902SAdrien Destugues if (data != ELFDATA2MSB && data != ELFDATA2LSB) 117*076b1902SAdrien Destugues errx(1, "wrong data format"); 118*076b1902SAdrien Destugues if (e->e_ident[EI_VERSION] != EV_CURRENT) 119*076b1902SAdrien Destugues errx(1, "wrong elf version"); 120*076b1902SAdrien Destugues machine = xe16toh(e->e_machine); 121*076b1902SAdrien Destugues if (machine != EM_SPARCV9 && machine != EM_ALPHA) 122*076b1902SAdrien Destugues errx(1, "wrong machine type"); 123*076b1902SAdrien Destugues phentsize = xe16toh(e->e_phentsize); 124*076b1902SAdrien Destugues if (phentsize != sizeof(*p)) 125*076b1902SAdrien Destugues errx(1, "phdr size mismatch"); 126*076b1902SAdrien Destugues 127*076b1902SAdrien Destugues entry = xe64toh(e->e_entry); 128*076b1902SAdrien Destugues phoff = xe64toh(e->e_phoff); 129*076b1902SAdrien Destugues phnum = xe16toh(e->e_phnum); 130*076b1902SAdrien Destugues p = (Elf64_Phdr *)((char *)e + phoff); 131*076b1902SAdrien Destugues bzero(&a, sizeof(a)); 132*076b1902SAdrien Destugues for (i = 0; i < phnum; i++) { 133*076b1902SAdrien Destugues type = xe32toh(p[i].p_type); 134*076b1902SAdrien Destugues switch (type) { 135*076b1902SAdrien Destugues case PT_LOAD: 136*076b1902SAdrien Destugues if (a.a_magic != 0) 137*076b1902SAdrien Destugues errx(1, "too many loadable segments"); 138*076b1902SAdrien Destugues filesz = xe64toh(p[i].p_filesz); 139*076b1902SAdrien Destugues memsz = xe64toh(p[i].p_memsz); 140*076b1902SAdrien Destugues offset = xe64toh(p[i].p_offset); 141*076b1902SAdrien Destugues a.a_magic = htoxe32(A_MAGIC); 142*076b1902SAdrien Destugues a.a_text = htoxe32(filesz); 143*076b1902SAdrien Destugues a.a_bss = htoxe32(memsz - filesz); 144*076b1902SAdrien Destugues a.a_entry = htoxe32(entry); 145*076b1902SAdrien Destugues if (write(fd, &a, sizeof(a)) != sizeof(a) || 146*076b1902SAdrien Destugues write(fd, (char *)e + offset, filesz) != (ssize_t)filesz) 147*076b1902SAdrien Destugues err(1, NULL); 148*076b1902SAdrien Destugues break; 149*076b1902SAdrien Destugues default: 150*076b1902SAdrien Destugues break; 151*076b1902SAdrien Destugues } 152*076b1902SAdrien Destugues } 153*076b1902SAdrien Destugues 154*076b1902SAdrien Destugues return (0); 155*076b1902SAdrien Destugues } 156*076b1902SAdrien Destugues 157*076b1902SAdrien Destugues static void 158*076b1902SAdrien Destugues usage(void) 159*076b1902SAdrien Destugues { 160*076b1902SAdrien Destugues 161*076b1902SAdrien Destugues fprintf(stderr, "usage: elf2aout [-o outfile] infile\n"); 162*076b1902SAdrien Destugues exit(1); 163*076b1902SAdrien Destugues } 164