brandelf.c revision 87248
118962Ssos/*- 278627Sobrien * Copyright (c) 2000, 2001 David O'Brien 318962Ssos * Copyright (c) 1996 S�ren Schmidt 418962Ssos * All rights reserved. 518962Ssos * 618962Ssos * Redistribution and use in source and binary forms, with or without 718962Ssos * modification, are permitted provided that the following conditions 818962Ssos * are met: 918962Ssos * 1. Redistributions of source code must retain the above copyright 1018962Ssos * notice, this list of conditions and the following disclaimer 1118962Ssos * in this position and unchanged. 1218962Ssos * 2. Redistributions in binary form must reproduce the above copyright 1318962Ssos * notice, this list of conditions and the following disclaimer in the 1418962Ssos * documentation and/or other materials provided with the distribution. 1518962Ssos * 3. The name of the author may not be used to endorse or promote products 1618962Ssos * derived from this software withough specific prior written permission 1718962Ssos * 1818962Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1918962Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2018962Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2118962Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2218962Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2318962Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2418962Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2518962Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2618962Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2718962Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2818962Ssos */ 2918962Ssos 3087248Smarkm#include <sys/cdefs.h> 3176225Sobrien 3287248Smarkm__FBSDID("$FreeBSD: head/usr.bin/brandelf/brandelf.c 87248 2001-12-03 00:00:22Z markm $"); 3387248Smarkm 3476224Sobrien#include <sys/types.h> 3576224Sobrien#include <sys/elf_common.h> 3687248Smarkm#include <sys/errno.h> 3787248Smarkm#include <err.h> 3825984Sjdp#include <fcntl.h> 3925984Sjdp#include <stdio.h> 4018962Ssos#include <stdlib.h> 4122499Sjoerg#include <string.h> 4222499Sjoerg#include <unistd.h> 4318962Ssos 4459342Sobrienstatic int elftype(const char *); 4559342Sobrienstatic const char *iselftype(int); 4655377Swesstatic void printelftypes(void); 4787248Smarkmstatic void usage(void); 4818962Ssos 4959342Sobrienstruct ELFtypes { 5059342Sobrien const char *str; 5159342Sobrien int value; 5259342Sobrien}; 5359342Sobrien/* XXX - any more types? */ 5459342Sobrienstatic struct ELFtypes elftypes[] = { 5559342Sobrien { "FreeBSD", ELFOSABI_FREEBSD }, 5662313Sgreen { "Linux", ELFOSABI_LINUX }, 5762313Sgreen { "Solaris", ELFOSABI_SOLARIS }, 5862313Sgreen { "SVR4", ELFOSABI_SYSV } 5959342Sobrien}; 6059342Sobrien 6122499Sjoergint 6218962Ssosmain(int argc, char **argv) 6318962Ssos{ 6418962Ssos 6559342Sobrien const char *strtype = "FreeBSD"; 6659342Sobrien int type = ELFOSABI_FREEBSD; 6722499Sjoerg int retval = 0; 6855377Swes int ch, change = 0, verbose = 0, force = 0, listed = 0; 6918962Ssos 7059342Sobrien while ((ch = getopt(argc, argv, "f:lt:v")) != -1) 7118962Ssos switch (ch) { 7235364Seivind case 'f': 7359342Sobrien if (change) 7472093Sasmodai errx(1, "f option incompatible with t option"); 7535364Seivind force = 1; 7659342Sobrien type = atoi(optarg); 7759342Sobrien if (errno == ERANGE || type < 0 || type > 255) { 7859342Sobrien warnx("invalid argument to option f: %s", 7959342Sobrien optarg); 8059342Sobrien usage(); 8159342Sobrien } 8235364Seivind break; 8355377Swes case 'l': 8455377Swes printelftypes(); 8555377Swes listed = 1; 8655377Swes break; 8718962Ssos case 'v': 8818962Ssos verbose = 1; 8918962Ssos break; 9018962Ssos case 't': 9159342Sobrien if (force) 9272093Sasmodai errx(1, "t option incompatible with f option"); 9318962Ssos change = 1; 9459342Sobrien strtype = optarg; 9518962Ssos break; 9618962Ssos default: 9718962Ssos usage(); 9818962Ssos } 9918962Ssos argc -= optind; 10018962Ssos argv += optind; 10155377Swes if (!argc) { 10255377Swes if (listed) 10355377Swes exit(0); 10455377Swes else { 10555377Swes warnx("no file(s) specified"); 10655377Swes usage(); 10755377Swes } 10855377Swes } 10935364Seivind 11059342Sobrien if (!force && (type = elftype(strtype)) == -1) { 11159342Sobrien warnx("invalid ELF type '%s'", strtype); 11255377Swes printelftypes(); 11355377Swes usage(); 11455377Swes } 11535364Seivind 11618962Ssos while (argc) { 11718962Ssos int fd; 11825984Sjdp char buffer[EI_NIDENT]; 11918962Ssos 12059342Sobrien if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) { 12128620Sjoerg warn("error opening file %s", argv[0]); 12222499Sjoerg retval = 1; 12318962Ssos goto fail; 12418962Ssos } 12525984Sjdp if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { 12626837Scharnier warnx("file '%s' too short", argv[0]); 12722499Sjoerg retval = 1; 12818962Ssos goto fail; 12918962Ssos } 13018962Ssos if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || 13118962Ssos buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { 13226837Scharnier warnx("file '%s' is not ELF format", argv[0]); 13322499Sjoerg retval = 1; 13418962Ssos goto fail; 13535364Seivind } 13659342Sobrien if (!change && !force) { 13759342Sobrien fprintf(stdout, 13859342Sobrien "File '%s' is of brand '%s' (%u).\n", 13959342Sobrien argv[0], iselftype(buffer[EI_OSABI]), 14059342Sobrien buffer[EI_OSABI]); 14159342Sobrien if (!iselftype(type)) { 14259342Sobrien warnx("ELF ABI Brand '%u' is unknown", 14359342Sobrien type); 14459342Sobrien printelftypes(); 14518962Ssos } 14618962Ssos } 14718962Ssos else { 14859342Sobrien buffer[EI_OSABI] = type; 14918962Ssos lseek(fd, 0, SEEK_SET); 15025984Sjdp if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { 15159342Sobrien warn("error writing %s %d", argv[0], fd); 15226837Scharnier retval = 1; 15318962Ssos goto fail; 15418962Ssos } 15518962Ssos } 15618962Ssosfail: 15762375Simp close(fd); 15818962Ssos argc--; 15918962Ssos argv++; 16018962Ssos } 16122499Sjoerg 16222499Sjoerg return retval; 16318962Ssos} 16418962Ssos 16526837Scharnierstatic void 16687248Smarkmusage(void) 16718962Ssos{ 16859342Sobrienfprintf(stderr, "usage: brandelf [-f ELF ABI number] [-v] [-l] [-t string] file ...\n"); 16922499Sjoerg exit(1); 17018962Ssos} 17135364Seivind 17259342Sobrienstatic const char * 17378627Sobrieniselftype(int etype) 17459342Sobrien{ 17578627Sobrien size_t elfwalk; 17655377Swes 17759342Sobrien for (elfwalk = 0; 17859342Sobrien elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 17959342Sobrien elfwalk++) 18078627Sobrien if (etype == elftypes[elfwalk].value) 18159342Sobrien return elftypes[elfwalk].str; 18259342Sobrien return 0; 18359342Sobrien} 18459342Sobrien 18535366Seivindstatic int 18659342Sobrienelftype(const char *elfstrtype) 18755377Swes{ 18878627Sobrien size_t elfwalk; 18935364Seivind 19035364Seivind for (elfwalk = 0; 19135364Seivind elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 19235364Seivind elfwalk++) 19359342Sobrien if (strcmp(elfstrtype, elftypes[elfwalk].str) == 0) 19459342Sobrien return elftypes[elfwalk].value; 19559342Sobrien return -1; 19635364Seivind} 19755377Swes 19855377Swesstatic void 19987248Smarkmprintelftypes(void) 20055377Swes{ 20178627Sobrien size_t elfwalk; 20255377Swes 20355377Swes fprintf(stderr, "known ELF types are: "); 20455377Swes for (elfwalk = 0; 20555377Swes elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 20655377Swes elfwalk++) 20759342Sobrien fprintf(stderr, "%s(%u) ", elftypes[elfwalk].str, 20859342Sobrien elftypes[elfwalk].value); 20955377Swes fprintf(stderr, "\n"); 21055377Swes} 211