Add ELF Tool Chain's brandelf(1) to contrib
Noticed by pfg after r286070 (ar and elfdump)
This commit is contained in:
commit
4fe79be626
9
contrib/elftoolchain/brandelf/Makefile
Normal file
9
contrib/elftoolchain/brandelf/Makefile
Normal 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"
|
151
contrib/elftoolchain/brandelf/brandelf.1
Normal file
151
contrib/elftoolchain/brandelf/brandelf.1
Normal 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 .
|
311
contrib/elftoolchain/brandelf/brandelf.c
Normal file
311
contrib/elftoolchain/brandelf/brandelf.c
Normal 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");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user