brandelf.c revision 76224
1/*- 2 * Copyright (c) 1996 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software withough specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD: head/usr.bin/brandelf/brandelf.c 76224 2001-05-02 23:56:21Z obrien $ 29 */ 30 31#include <sys/types.h> 32#include <sys/elf_common.h> 33#include <fcntl.h> 34#include <stdio.h> 35#include <stdlib.h> 36#include <string.h> 37#include <unistd.h> 38#include <sys/errno.h> 39#include <err.h> 40 41static int elftype(const char *); 42static const char *iselftype(int); 43static void printelftypes(void); 44static void usage __P((void)); 45 46struct ELFtypes { 47 const char *str; 48 int value; 49}; 50/* XXX - any more types? */ 51static struct ELFtypes elftypes[] = { 52 { "FreeBSD", ELFOSABI_FREEBSD }, 53 { "Linux", ELFOSABI_LINUX }, 54 { "Solaris", ELFOSABI_SOLARIS }, 55 { "SVR4", ELFOSABI_SYSV } 56}; 57 58int 59main(int argc, char **argv) 60{ 61 62 const char *strtype = "FreeBSD"; 63 int type = ELFOSABI_FREEBSD; 64 int retval = 0; 65 int ch, change = 0, verbose = 0, force = 0, listed = 0; 66 67 while ((ch = getopt(argc, argv, "f:lt:v")) != -1) 68 switch (ch) { 69 case 'f': 70 if (change) 71 errx(1, "f option incompatible with t option"); 72 force = 1; 73 type = atoi(optarg); 74 if (errno == ERANGE || type < 0 || type > 255) { 75 warnx("invalid argument to option f: %s", 76 optarg); 77 usage(); 78 } 79 break; 80 case 'l': 81 printelftypes(); 82 listed = 1; 83 break; 84 case 'v': 85 verbose = 1; 86 break; 87 case 't': 88 if (force) 89 errx(1, "t option incompatible with f option"); 90 change = 1; 91 strtype = optarg; 92 break; 93 default: 94 usage(); 95 } 96 argc -= optind; 97 argv += optind; 98 if (!argc) { 99 if (listed) 100 exit(0); 101 else { 102 warnx("no file(s) specified"); 103 usage(); 104 } 105 } 106 107 if (!force && (type = elftype(strtype)) == -1) { 108 warnx("invalid ELF type '%s'", strtype); 109 printelftypes(); 110 usage(); 111 } 112 113 while (argc) { 114 int fd; 115 char buffer[EI_NIDENT]; 116 117 if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) { 118 warn("error opening file %s", argv[0]); 119 retval = 1; 120 goto fail; 121 } 122 if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { 123 warnx("file '%s' too short", argv[0]); 124 retval = 1; 125 goto fail; 126 } 127 if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || 128 buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { 129 warnx("file '%s' is not ELF format", argv[0]); 130 retval = 1; 131 goto fail; 132 } 133 if (!change && !force) { 134 fprintf(stdout, 135 "File '%s' is of brand '%s' (%u).\n", 136 argv[0], iselftype(buffer[EI_OSABI]), 137 buffer[EI_OSABI]); 138 if (!iselftype(type)) { 139 warnx("ELF ABI Brand '%u' is unknown", 140 type); 141 printelftypes(); 142 } 143 } 144 else { 145 buffer[EI_OSABI] = type; 146 lseek(fd, 0, SEEK_SET); 147 if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { 148 warn("error writing %s %d", argv[0], fd); 149 retval = 1; 150 goto fail; 151 } 152 } 153fail: 154 close(fd); 155 argc--; 156 argv++; 157 } 158 159 return retval; 160} 161 162static void 163usage() 164{ 165fprintf(stderr, "usage: brandelf [-f ELF ABI number] [-v] [-l] [-t string] file ...\n"); 166 exit(1); 167} 168 169static const char * 170iselftype(int elftype) 171{ 172 int elfwalk; 173 174 for (elfwalk = 0; 175 elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 176 elfwalk++) 177 if (elftype == elftypes[elfwalk].value) 178 return elftypes[elfwalk].str; 179 return 0; 180} 181 182static int 183elftype(const char *elfstrtype) 184{ 185 int elfwalk; 186 187 for (elfwalk = 0; 188 elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 189 elfwalk++) 190 if (strcmp(elfstrtype, elftypes[elfwalk].str) == 0) 191 return elftypes[elfwalk].value; 192 return -1; 193} 194 195static void 196printelftypes() 197{ 198 int elfwalk; 199 200 fprintf(stderr, "known ELF types are: "); 201 for (elfwalk = 0; 202 elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 203 elfwalk++) 204 fprintf(stderr, "%s(%u) ", elftypes[elfwalk].str, 205 elftypes[elfwalk].value); 206 fprintf(stderr, "\n"); 207} 208