Add ELF Tool Chain's brandelf(1) to contrib

Noticed by pfg after r286070 (ar and elfdump)
This commit is contained in:
emaste 2015-07-31 12:37:40 +00:00
commit 4fe79be626
3 changed files with 471 additions and 0 deletions

View File

@ -0,0 +1,9 @@
# $Id: Makefile 2066 2011-10-26 15:40:28Z jkoshy $
TOP= ..
PROG= brandelf
WARNS?= 6
LDADD= -lelftc -lelf
.include "${TOP}/mk/elftoolchain.prog.mk"

View File

@ -0,0 +1,151 @@
.\" Copyright (c) 1997
.\" John-Mark Gurney. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY John-Mark Gurney AND CONTRIBUTORS ``AS IS''
.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD: src/usr.bin/brandelf/brandelf.1,v 1.17 2007/03/09 14:36:18 ru Exp $
.\" $Id: brandelf.1 3195 2015-05-12 17:22:19Z emaste $
.\"
.Dd October 27, 2014
.Dt BRANDELF 1
.Os
.Sh NAME
.Nm brandelf
.Nd mark an ELF binary for a specific ABI
.Sh SYNOPSIS
.Nm
.Op Fl V | Fl -version
.Op Fl f Ar ELF_ABI_number
.Op Fl h | Fl -help
.Op Fl l
.Op Fl t Ar brand
.Op Fl v
.Ar
.Sh DESCRIPTION
The
.Nm
utility marks an ELF binary to be run under a certain ABI.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl f Ar ELF_ABI_number
Forces branding with the supplied ELF ABI number.
Incompatible with the
.Fl t
option.
These values are assigned by SCO/USL.
.It Fl h | Fl -help
Print a usage message and exit.
.It Fl l
Writes the list of all known ELF types to standard output.
.It Fl t Ar brand
Brands the given ELF binaries to be of the ABI specified by argument
.Ar brand .
Supported ABIs include
.Dq Li 86Open ,
.Dq Li AIX ,
.Dq Li ARM ,
.Dq Li AROS ,
.Dq Li FreeBSD ,
.Dq Li GNU ,
.Dq Li HP/UX ,
.Dq Li Hurd ,
.Dq Li IRIX ,
.Dq Li Linux
(an alias for
.Dq Li GNU ) ,
.Dq Li Modesto ,
.Dq Li NSK ,
.Dq Li NetBSD ,
.Dq Li None ,
.Dq Li OpenBSD ,
.Dq Li OpenVMS ,
.Dq Li Standalone ,
.Dq Li SVR4
(an alias for
.Dq Li None ) ,
.Dq Li Solaris
and
.Dq Li Tru64 .
.It Fl v
This option is accepted for compatibility with other versions of
.Nm ,
but is otherwise ignored.
.It Fl V | Fl -version
Print a version identifier and exit.
.El
.Pp
If the options
.Fl f Ar ELF_ABI_number
or
.Fl t Ar brand
were specified,
.Nm
will brand the files named by command-line arguments
.Ar
to be of type
.Ar ELF_ABI_number
or
.Ar brand
respectively.
.Pp
If neither of the
.Fl f
or
.Fl t
options were specified,
.Nm
will display the current branding for the files named by the arguments
.Ar .
.Sh EXIT STATUS
Exit status is 0 on success, and 1 if the command
fails if a file does not exist, is too short, fails to brand properly,
or the brand requested is not one of the known types and the
.Fl f
option is not set.
.Sh EXAMPLES
The following is an example of a typical usage
of the
.Nm
command:
.Bd -literal -offset indent
brandelf file
brandelf -t GNU file
.Ed
.Sh SEE ALSO
.Rs
.%A The Santa Cruz Operation, Inc.
.%T System V Application Binary Interface
.%D April 29, 1998 (DRAFT)
.%O http://www.sco.com/developer/devspecs/
.Re
.Sh HISTORY
The
.Nm
manual page first appeared in
.Fx 2.2 .
.Sh AUTHORS
This manual page was written by
.An John-Mark Gurney Aq Mt gurney_j@efn.org .

View File

@ -0,0 +1,311 @@
/*-
* Copyright (c) 2008 Hyogeol Lee
* Copyright (c) 2000, 2001 David O'Brien
* Copyright (c) 1996 Søren Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <gelf.h>
#include <getopt.h>
#include <libelf.h>
#include <libelftc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "_elftc.h"
ELFTC_VCSID("$Id: brandelf.c 3174 2015-03-27 17:13:41Z emaste $");
static int elftype(const char *);
static const char *iselftype(int);
static void printelftypes(void);
static void printversion(void);
static void usage(void);
struct ELFtypes {
const char *str;
int value;
};
/* XXX - any more types? */
static struct ELFtypes elftypes[] = {
{ "86Open", ELFOSABI_86OPEN },
{ "AIX", ELFOSABI_AIX },
{ "ARM", ELFOSABI_ARM },
{ "AROS", ELFOSABI_AROS },
{ "FreeBSD", ELFOSABI_FREEBSD },
{ "GNU", ELFOSABI_GNU },
{ "HP/UX", ELFOSABI_HPUX},
{ "Hurd", ELFOSABI_HURD },
{ "IRIX", ELFOSABI_IRIX },
{ "Linux", ELFOSABI_GNU },
{ "Modesto", ELFOSABI_MODESTO },
{ "NSK", ELFOSABI_NSK },
{ "NetBSD", ELFOSABI_NETBSD},
{ "None", ELFOSABI_NONE},
{ "OpenBSD", ELFOSABI_OPENBSD },
{ "OpenVMS", ELFOSABI_OPENVMS },
{ "Standalone", ELFOSABI_STANDALONE },
{ "SVR4", ELFOSABI_NONE },
{ "Solaris", ELFOSABI_SOLARIS },
{ "Tru64", ELFOSABI_TRU64 }
};
static struct option brandelf_longopts[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
};
int
main(int argc, char **argv)
{
GElf_Ehdr ehdr;
Elf *elf;
Elf_Kind kind;
int type = ELFOSABI_NONE;
int retval = 0;
int ch, change = 0, force = 0, listed = 0;
if (elf_version(EV_CURRENT) == EV_NONE)
errx(EXIT_FAILURE, "elf_version error");
while ((ch = getopt_long(argc, argv, "Vf:hlt:v", brandelf_longopts,
NULL)) != -1)
switch (ch) {
case 'f':
if (change)
errx(EXIT_FAILURE, "ERROR: the -f option is "
"incompatible with the -t option.");
force = 1;
type = atoi(optarg);
if (errno == ERANGE || type < 0 || type > 255) {
warnx("ERROR: invalid argument to option "
"-f: %s", optarg);
usage();
}
break;
case 'h':
usage();
break;
case 'l':
printelftypes();
listed = 1;
break;
case 'v':
/* This flag is ignored. */
break;
case 't':
if (force)
errx(EXIT_FAILURE, "the -t option is "
"incompatible with the -f option.");
if ((type = elftype(optarg)) == -1) {
warnx("ERROR: invalid ELF type '%s'", optarg);
usage();
}
change = 1;
break;
case 'V':
printversion();
break;
default:
usage();
}
argc -= optind;
argv += optind;
if (!argc) {
if (listed)
exit(0);
else {
warnx("no file(s) specified");
usage();
}
}
while (argc) {
int fd;
elf = NULL;
if ((fd = open(argv[0], (change || force) ? O_RDWR :
O_RDONLY, 0)) < 0) {
warn("error opening file %s", argv[0]);
retval = 1;
goto fail;
}
if ((elf = elf_begin(fd, (change || force) ? ELF_C_RDWR :
ELF_C_READ, NULL)) == NULL) {
warnx("elf_begin failed: %s", elf_errmsg(-1));
retval = 1;
goto fail;
}
if ((kind = elf_kind(elf)) != ELF_K_ELF) {
if (kind == ELF_K_AR)
warnx("file '%s' is an archive.", argv[0]);
else
warnx("file '%s' is not an ELF file.",
argv[0]);
retval = 1;
goto fail;
}
if (gelf_getehdr(elf, &ehdr) == NULL) {
warnx("gelf_getehdr: %s", elf_errmsg(-1));
retval = 1;
goto fail;
}
if (!change && !force) {
fprintf(stdout,
"File '%s' is of brand '%s' (%u).\n",
argv[0], iselftype(ehdr.e_ident[EI_OSABI]),
ehdr.e_ident[EI_OSABI]);
if (!iselftype(type)) {
warnx("ELF ABI Brand '%u' is unknown",
type);
printelftypes();
}
} else {
/*
* Keep the existing layout of the ELF object.
*/
if (elf_flagelf(elf, ELF_C_SET, ELF_F_LAYOUT) == 0) {
warnx("elf_flagelf failed: %s",
elf_errmsg(-1));
retval = 1;
goto fail;
}
/*
* Update the ABI type.
*/
ehdr.e_ident[EI_OSABI] = type;
if (gelf_update_ehdr(elf, &ehdr) == 0) {
warnx("gelf_update_ehdr error: %s",
elf_errmsg(-1));
retval = 1;
goto fail;
}
/*
* Write back changes.
*/
if (elf_update(elf, ELF_C_WRITE) == -1) {
warnx("elf_update error: %s", elf_errmsg(-1));
retval = 1;
goto fail;
}
}
fail:
if (elf)
elf_end(elf);
if (fd >= 0 && close(fd) == -1) {
warnx("%s: close error", argv[0]);
retval = 1;
}
argc--;
argv++;
}
return (retval);
}
#define USAGE_MESSAGE "\
Usage: %s [options] file...\n\
Set or display the ABI field for an ELF object.\n\n\
Supported options are:\n\
-f NUM Set the ELF ABI to the number 'NUM'.\n\
-h | --help Print a usage message and exit.\n\
-l List known ELF ABI names.\n\
-t ABI Set the ELF ABI to the value named by \"ABI\".\n\
-V | --version Print a version identifier and exit.\n"
static void
usage(void)
{
(void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME());
exit(1);
}
static void
printversion(void)
{
(void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version());
exit(0);
}
static const char *
iselftype(int etype)
{
size_t elfwalk;
for (elfwalk = 0;
elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
elfwalk++)
if (etype == elftypes[elfwalk].value)
return (elftypes[elfwalk].str);
return (0);
}
static int
elftype(const char *elfstrtype)
{
size_t elfwalk;
for (elfwalk = 0;
elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
elfwalk++)
if (strcasecmp(elfstrtype, elftypes[elfwalk].str) == 0)
return (elftypes[elfwalk].value);
return (-1);
}
static void
printelftypes(void)
{
size_t elfwalk;
(void) printf("Known ELF types are: ");
for (elfwalk = 0;
elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
elfwalk++)
(void) printf("%s(%u) ", elftypes[elfwalk].str,
elftypes[elfwalk].value);
(void) printf("\n");
}