brandelf.c revision 55377
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 55377 2000-01-04 02:33:54Z wes $ 29 */ 30 31#include <elf.h> 32#include <fcntl.h> 33#include <stdio.h> 34#include <stdlib.h> 35#include <string.h> 36#include <unistd.h> 37#include <err.h> 38 39static int iselftype(const char *); 40static void printelftypes(void); 41static void usage __P((void)); 42 43int 44main(int argc, char **argv) 45{ 46 47 const char *type = "FreeBSD"; 48 int retval = 0; 49 int ch, change = 0, verbose = 0, force = 0, listed = 0; 50 51 while ((ch = getopt(argc, argv, "flt:v")) != -1) 52 switch (ch) { 53 case 'f': 54 force = 1; 55 break; 56 case 'l': 57 printelftypes(); 58 listed = 1; 59 break; 60 case 'v': 61 verbose = 1; 62 break; 63 case 't': 64 change = 1; 65 type = optarg; 66 break; 67 default: 68 usage(); 69 } 70 argc -= optind; 71 argv += optind; 72 if (!argc) { 73 if (listed) 74 exit(0); 75 else { 76 warnx("no file(s) specified"); 77 usage(); 78 } 79 } 80 81 if (!force && !iselftype(type)) { 82 warnx("invalid ELF type '%s'", type); 83 printelftypes(); 84 usage(); 85 } 86 87 while (argc) { 88 int fd; 89 char buffer[EI_NIDENT]; 90 char string[(EI_NIDENT-EI_BRAND)+1]; 91 92 if ((fd = open(argv[0], change? O_RDWR: O_RDONLY, 0)) < 0) { 93 warn("error opening file %s", argv[0]); 94 retval = 1; 95 goto fail; 96 } 97 if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { 98 warnx("file '%s' too short", argv[0]); 99 retval = 1; 100 goto fail; 101 } 102 if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || 103 buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { 104 warnx("file '%s' is not ELF format", argv[0]); 105 retval = 1; 106 goto fail; 107 } 108 if (!change) { 109 bzero(string, sizeof(string)); 110 strncpy(string, &buffer[EI_BRAND], EI_NIDENT-EI_BRAND); 111 if (strlen(string)) { 112 fprintf(stdout, 113 "File '%s' is of brand '%s'.\n", 114 argv[0], string); 115 if (!force && !iselftype(string)) { 116 warnx("Brand '%s' is unknown", 117 string); 118 printelftypes(); 119 } 120 } 121 else 122 fprintf(stdout, "File '%s' has no branding.\n", 123 argv[0]); 124 } 125 else { 126 strncpy(&buffer[EI_BRAND], type, EI_NIDENT-EI_BRAND); 127 lseek(fd, 0, SEEK_SET); 128 if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { 129 warnx("error writing %s", argv[0]); 130 retval = 1; 131 goto fail; 132 } 133 } 134fail: 135 argc--; 136 argv++; 137 } 138 139 return retval; 140} 141 142static void 143usage() 144{ 145 fprintf(stderr, "usage: brandelf [-f] [-v] [-l] [-t string] file ...\n"); 146 exit(1); 147} 148 149/* XXX - any more types? */ 150static const char *elftypes[] = { "FreeBSD", "Linux", "SVR4" }; 151 152static int 153iselftype(const char *elftype) 154{ 155 int elfwalk; 156 157 for (elfwalk = 0; 158 elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 159 elfwalk++) 160 if (strcmp(elftype, elftypes[elfwalk]) == 0) 161 return 1; 162 return 0; 163} 164 165static void 166printelftypes() 167{ 168 int elfwalk; 169 170 fprintf(stderr, "known ELF types are: "); 171 for (elfwalk = 0; 172 elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 173 elfwalk++) 174 fprintf(stderr, "%s ", elftypes[elfwalk]); 175 fprintf(stderr, "\n"); 176} 177