brandelf.c revision 55377
1193323Sed/*- 2193323Sed * Copyright (c) 1996 S�ren Schmidt 3193323Sed * All rights reserved. 4193323Sed * 5193323Sed * Redistribution and use in source and binary forms, with or without 6193323Sed * modification, are permitted provided that the following conditions 7193323Sed * are met: 8193323Sed * 1. Redistributions of source code must retain the above copyright 9193323Sed * notice, this list of conditions and the following disclaimer 10193323Sed * in this position and unchanged. 11193323Sed * 2. Redistributions in binary form must reproduce the above copyright 12193323Sed * notice, this list of conditions and the following disclaimer in the 13193323Sed * documentation and/or other materials provided with the distribution. 14193323Sed * 3. The name of the author may not be used to endorse or promote products 15193323Sed * derived from this software withough specific prior written permission 16252723Sdim * 17218893Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18263509Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19252723Sdim * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20252723Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21252723Sdim * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22252723Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23252723Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24252723Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25252723Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26252723Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27252723Sdim * 28235633Sdim * $FreeBSD: head/usr.bin/brandelf/brandelf.c 55377 2000-01-04 02:33:54Z wes $ 29193323Sed */ 30193323Sed 31218893Sdim#include <elf.h> 32193323Sed#include <fcntl.h> 33193323Sed#include <stdio.h> 34218893Sdim#include <stdlib.h> 35193323Sed#include <string.h> 36218893Sdim#include <unistd.h> 37218893Sdim#include <err.h> 38218893Sdim 39218893Sdimstatic int iselftype(const char *); 40245431Sdimstatic void printelftypes(void); 41218893Sdimstatic void usage __P((void)); 42218893Sdim 43263509Sdimint 44263509Sdimmain(int argc, char **argv) 45218893Sdim{ 46218893Sdim 47235633Sdim const char *type = "FreeBSD"; 48235633Sdim int retval = 0; 49235633Sdim int ch, change = 0, verbose = 0, force = 0, listed = 0; 50245431Sdim 51235633Sdim while ((ch = getopt(argc, argv, "flt:v")) != -1) 52235633Sdim switch (ch) { 53235633Sdim case 'f': 54235633Sdim force = 1; 55235633Sdim break; 56235633Sdim case 'l': 57235633Sdim printelftypes(); 58235633Sdim listed = 1; 59235633Sdim break; 60235633Sdim case 'v': 61235633Sdim verbose = 1; 62252723Sdim break; 63235633Sdim case 't': 64235633Sdim change = 1; 65235633Sdim type = optarg; 66235633Sdim break; 67235633Sdim default: 68235633Sdim usage(); 69235633Sdim } 70235633Sdim argc -= optind; 71235633Sdim argv += optind; 72235633Sdim if (!argc) { 73235633Sdim if (listed) 74235633Sdim exit(0); 75235633Sdim else { 76235633Sdim warnx("no file(s) specified"); 77235633Sdim usage(); 78235633Sdim } 79235633Sdim } 80235633Sdim 81235633Sdim if (!force && !iselftype(type)) { 82235633Sdim warnx("invalid ELF type '%s'", type); 83235633Sdim printelftypes(); 84235633Sdim usage(); 85235633Sdim } 86235633Sdim 87235633Sdim while (argc) { 88252723Sdim int fd; 89235633Sdim char buffer[EI_NIDENT]; 90235633Sdim char string[(EI_NIDENT-EI_BRAND)+1]; 91235633Sdim 92235633Sdim if ((fd = open(argv[0], change? O_RDWR: O_RDONLY, 0)) < 0) { 93235633Sdim warn("error opening file %s", argv[0]); 94235633Sdim retval = 1; 95235633Sdim goto fail; 96235633Sdim } 97235633Sdim if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { 98235633Sdim warnx("file '%s' too short", argv[0]); 99235633Sdim retval = 1; 100235633Sdim goto fail; 101235633Sdim } 102235633Sdim if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || 103235633Sdim buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { 104235633Sdim warnx("file '%s' is not ELF format", argv[0]); 105235633Sdim retval = 1; 106235633Sdim goto fail; 107235633Sdim } 108235633Sdim if (!change) { 109235633Sdim bzero(string, sizeof(string)); 110235633Sdim strncpy(string, &buffer[EI_BRAND], EI_NIDENT-EI_BRAND); 111235633Sdim if (strlen(string)) { 112235633Sdim fprintf(stdout, 113235633Sdim "File '%s' is of brand '%s'.\n", 114235633Sdim argv[0], string); 115235633Sdim if (!force && !iselftype(string)) { 116235633Sdim warnx("Brand '%s' is unknown", 117235633Sdim string); 118235633Sdim printelftypes(); 119235633Sdim } 120235633Sdim } 121235633Sdim else 122235633Sdim fprintf(stdout, "File '%s' has no branding.\n", 123235633Sdim argv[0]); 124235633Sdim } 125235633Sdim else { 126235633Sdim strncpy(&buffer[EI_BRAND], type, EI_NIDENT-EI_BRAND); 127235633Sdim lseek(fd, 0, SEEK_SET); 128235633Sdim if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { 129235633Sdim warnx("error writing %s", argv[0]); 130235633Sdim retval = 1; 131235633Sdim goto fail; 132235633Sdim } 133235633Sdim } 134235633Sdimfail: 135235633Sdim argc--; 136245431Sdim argv++; 137235633Sdim } 138235633Sdim 139235633Sdim return retval; 140235633Sdim} 141235633Sdim 142235633Sdimstatic void 143235633Sdimusage() 144235633Sdim{ 145235633Sdim fprintf(stderr, "usage: brandelf [-f] [-v] [-l] [-t string] file ...\n"); 146235633Sdim exit(1); 147235633Sdim} 148235633Sdim 149235633Sdim/* XXX - any more types? */ 150235633Sdimstatic const char *elftypes[] = { "FreeBSD", "Linux", "SVR4" }; 151235633Sdim 152235633Sdimstatic int 153235633Sdimiselftype(const char *elftype) 154235633Sdim{ 155235633Sdim int elfwalk; 156235633Sdim 157235633Sdim for (elfwalk = 0; 158235633Sdim elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 159235633Sdim elfwalk++) 160235633Sdim if (strcmp(elftype, elftypes[elfwalk]) == 0) 161235633Sdim return 1; 162235633Sdim return 0; 163235633Sdim} 164235633Sdim 165235633Sdimstatic void 166235633Sdimprintelftypes() 167235633Sdim{ 168235633Sdim int elfwalk; 169235633Sdim 170235633Sdim fprintf(stderr, "known ELF types are: "); 171235633Sdim for (elfwalk = 0; 172235633Sdim elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 173235633Sdim elfwalk++) 174235633Sdim fprintf(stderr, "%s ", elftypes[elfwalk]); 175235633Sdim fprintf(stderr, "\n"); 176235633Sdim} 177235633Sdim