brandelf.c revision 62313
118962Ssos/*- 218962Ssos * Copyright (c) 1996 S�ren Schmidt 318962Ssos * All rights reserved. 418962Ssos * 518962Ssos * Redistribution and use in source and binary forms, with or without 618962Ssos * modification, are permitted provided that the following conditions 718962Ssos * are met: 818962Ssos * 1. Redistributions of source code must retain the above copyright 918962Ssos * notice, this list of conditions and the following disclaimer 1018962Ssos * in this position and unchanged. 1118962Ssos * 2. Redistributions in binary form must reproduce the above copyright 1218962Ssos * notice, this list of conditions and the following disclaimer in the 1318962Ssos * documentation and/or other materials provided with the distribution. 1418962Ssos * 3. The name of the author may not be used to endorse or promote products 1518962Ssos * derived from this software withough specific prior written permission 1618962Ssos * 1718962Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1818962Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1918962Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2018962Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2118962Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2218962Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2318962Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2418962Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2518962Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2618962Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2718962Ssos * 2850477Speter * $FreeBSD: head/usr.bin/brandelf/brandelf.c 62313 2000-07-01 05:48:33Z green $ 2918962Ssos */ 3018962Ssos 3125984Sjdp#include <elf.h> 3225984Sjdp#include <fcntl.h> 3325984Sjdp#include <stdio.h> 3418962Ssos#include <stdlib.h> 3522499Sjoerg#include <string.h> 3622499Sjoerg#include <unistd.h> 3759342Sobrien#include <sys/errno.h> 3826837Scharnier#include <err.h> 3918962Ssos 4059342Sobrienstatic int elftype(const char *); 4159342Sobrienstatic const char *iselftype(int); 4255377Swesstatic void printelftypes(void); 4326837Scharnierstatic void usage __P((void)); 4418962Ssos 4559342Sobrienstruct ELFtypes { 4659342Sobrien const char *str; 4759342Sobrien int value; 4859342Sobrien}; 4959342Sobrien/* XXX - any more types? */ 5059342Sobrienstatic struct ELFtypes elftypes[] = { 5159342Sobrien { "FreeBSD", ELFOSABI_FREEBSD }, 5262313Sgreen { "Linux", ELFOSABI_LINUX }, 5362313Sgreen { "Solaris", ELFOSABI_SOLARIS }, 5462313Sgreen { "SVR4", ELFOSABI_SYSV } 5559342Sobrien}; 5659342Sobrien 5722499Sjoergint 5818962Ssosmain(int argc, char **argv) 5918962Ssos{ 6018962Ssos 6159342Sobrien const char *strtype = "FreeBSD"; 6259342Sobrien int type = ELFOSABI_FREEBSD; 6322499Sjoerg int retval = 0; 6455377Swes int ch, change = 0, verbose = 0, force = 0, listed = 0; 6518962Ssos 6659342Sobrien while ((ch = getopt(argc, argv, "f:lt:v")) != -1) 6718962Ssos switch (ch) { 6835364Seivind case 'f': 6959342Sobrien if (change) 7059342Sobrien errx(1, "f option incompatable with t option"); 7135364Seivind force = 1; 7259342Sobrien type = atoi(optarg); 7359342Sobrien if (errno == ERANGE || type < 0 || type > 255) { 7459342Sobrien warnx("invalid argument to option f: %s", 7559342Sobrien optarg); 7659342Sobrien usage(); 7759342Sobrien } 7835364Seivind break; 7955377Swes case 'l': 8055377Swes printelftypes(); 8155377Swes listed = 1; 8255377Swes break; 8318962Ssos case 'v': 8418962Ssos verbose = 1; 8518962Ssos break; 8618962Ssos case 't': 8759342Sobrien if (force) 8859342Sobrien errx(1, "t option incompatable with f option"); 8918962Ssos change = 1; 9059342Sobrien strtype = optarg; 9118962Ssos break; 9218962Ssos default: 9318962Ssos usage(); 9418962Ssos } 9518962Ssos argc -= optind; 9618962Ssos argv += optind; 9755377Swes if (!argc) { 9855377Swes if (listed) 9955377Swes exit(0); 10055377Swes else { 10155377Swes warnx("no file(s) specified"); 10255377Swes usage(); 10355377Swes } 10455377Swes } 10535364Seivind 10659342Sobrien if (!force && (type = elftype(strtype)) == -1) { 10759342Sobrien warnx("invalid ELF type '%s'", strtype); 10855377Swes printelftypes(); 10955377Swes usage(); 11055377Swes } 11135364Seivind 11218962Ssos while (argc) { 11318962Ssos int fd; 11425984Sjdp char buffer[EI_NIDENT]; 11518962Ssos 11659342Sobrien if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) { 11728620Sjoerg warn("error opening file %s", argv[0]); 11822499Sjoerg retval = 1; 11918962Ssos goto fail; 12018962Ssos } 12125984Sjdp if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { 12226837Scharnier warnx("file '%s' too short", argv[0]); 12322499Sjoerg retval = 1; 12418962Ssos goto fail; 12518962Ssos } 12618962Ssos if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || 12718962Ssos buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { 12826837Scharnier warnx("file '%s' is not ELF format", argv[0]); 12922499Sjoerg retval = 1; 13018962Ssos goto fail; 13135364Seivind } 13259342Sobrien if (!change && !force) { 13359342Sobrien fprintf(stdout, 13459342Sobrien "File '%s' is of brand '%s' (%u).\n", 13559342Sobrien argv[0], iselftype(buffer[EI_OSABI]), 13659342Sobrien buffer[EI_OSABI]); 13759342Sobrien if (!iselftype(type)) { 13859342Sobrien warnx("ELF ABI Brand '%u' is unknown", 13959342Sobrien type); 14059342Sobrien printelftypes(); 14118962Ssos } 14218962Ssos } 14318962Ssos else { 14459342Sobrien buffer[EI_OSABI] = type; 14518962Ssos lseek(fd, 0, SEEK_SET); 14625984Sjdp if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { 14759342Sobrien warn("error writing %s %d", argv[0], fd); 14826837Scharnier retval = 1; 14918962Ssos goto fail; 15018962Ssos } 15118962Ssos } 15218962Ssosfail: 15318962Ssos argc--; 15418962Ssos argv++; 15518962Ssos } 15622499Sjoerg 15722499Sjoerg return retval; 15818962Ssos} 15918962Ssos 16026837Scharnierstatic void 16126837Scharnierusage() 16218962Ssos{ 16359342Sobrienfprintf(stderr, "usage: brandelf [-f ELF ABI number] [-v] [-l] [-t string] file ...\n"); 16422499Sjoerg exit(1); 16518962Ssos} 16635364Seivind 16759342Sobrienstatic const char * 16859342Sobrieniselftype(int elftype) 16959342Sobrien{ 17059342Sobrien int elfwalk; 17155377Swes 17259342Sobrien for (elfwalk = 0; 17359342Sobrien elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 17459342Sobrien elfwalk++) 17559342Sobrien if (elftype == elftypes[elfwalk].value) 17659342Sobrien return elftypes[elfwalk].str; 17759342Sobrien return 0; 17859342Sobrien} 17959342Sobrien 18035366Seivindstatic int 18159342Sobrienelftype(const char *elfstrtype) 18255377Swes{ 18335364Seivind int elfwalk; 18435364Seivind 18535364Seivind for (elfwalk = 0; 18635364Seivind elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 18735364Seivind elfwalk++) 18859342Sobrien if (strcmp(elfstrtype, elftypes[elfwalk].str) == 0) 18959342Sobrien return elftypes[elfwalk].value; 19059342Sobrien return -1; 19135364Seivind} 19255377Swes 19355377Swesstatic void 19455377Swesprintelftypes() 19555377Swes{ 19655377Swes int elfwalk; 19755377Swes 19855377Swes fprintf(stderr, "known ELF types are: "); 19955377Swes for (elfwalk = 0; 20055377Swes elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 20155377Swes elfwalk++) 20259342Sobrien fprintf(stderr, "%s(%u) ", elftypes[elfwalk].str, 20359342Sobrien elftypes[elfwalk].value); 20455377Swes fprintf(stderr, "\n"); 20555377Swes} 206