diff options
author | obrien <obrien@FreeBSD.org> | 2000-04-18 02:39:26 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-04-18 02:39:26 +0000 |
commit | 0eac6bbc676f298cf518321aa0d24cc001c69611 (patch) | |
tree | 0215bcb520740db905cae767cb8c981d2e3f8a50 /usr.bin/brandelf | |
parent | 2e1592d902d16ed9876e30509b0d925e1a30e2c7 (diff) | |
download | FreeBSD-src-0eac6bbc676f298cf518321aa0d24cc001c69611.zip FreeBSD-src-0eac6bbc676f298cf518321aa0d24cc001c69611.tar.gz |
Change our ELF binary branding to something more acceptable to the Binutils
maintainers.
After we established our branding method of writing upto 8 characters of
the OS name into the ELF header in the padding; the Binutils maintainers
and/or SCO (as USL) decided that instead the ELF header should grow two new
fields -- EI_OSABI and EI_ABIVERSION. Each of these are an 8-bit unsigned
integer. SCO has assigned official values for the EI_OSABI field. In
addition to this, the Binutils maintainers and NetBSD decided that a better
ELF branding method was to include ABI information in a ".note" ELF
section.
With this set of changes, we will now create ELF binaries branded using
both "official" methods. Due to the complexity of adding a section to a
binary, binaries branded with ``brandelf'' will only brand using the
EI_OSABI method. Also due to the complexity of pulling a section out of an
ELF file vs. poking around in the ELF header, our image activator only
looks at the EI_OSABI header field.
Note that a new kernel can still properly load old binaries except for
Linux static binaries branded in our old method.
*
* For a short period of time, ``ld'' will also brand ELF binaries
* using our old method. This is so people can still use kernel.old
* with a new world. This support will be removed before 5.0-RELEASE,
* and may not last anywhere upto the actual release. My expiration
* time for this is about 6mo.
*
Diffstat (limited to 'usr.bin/brandelf')
-rw-r--r-- | usr.bin/brandelf/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/brandelf/brandelf.1 | 22 | ||||
-rw-r--r-- | usr.bin/brandelf/brandelf.c | 94 |
3 files changed, 79 insertions, 41 deletions
diff --git a/usr.bin/brandelf/Makefile b/usr.bin/brandelf/Makefile index 81d0039..8767913 100644 --- a/usr.bin/brandelf/Makefile +++ b/usr.bin/brandelf/Makefile @@ -1,4 +1,6 @@ +# $FreeBSD$ + PROG= brandelf -CFLAGS+=-Wall +CFLAGS+= -Wall .include <bsd.prog.mk> diff --git a/usr.bin/brandelf/brandelf.1 b/usr.bin/brandelf/brandelf.1 index c7d69b3..713b491 100644 --- a/usr.bin/brandelf/brandelf.1 +++ b/usr.bin/brandelf/brandelf.1 @@ -35,7 +35,7 @@ .Nd mark an ELF binary for a specific ABI .Sh SYNOPSIS .Nm brandelf -.Op Fl f +.Op Fl f Ar ELF ABI number .Op Fl l .Op Fl v .Op Fl t Ar string @@ -46,17 +46,18 @@ This command marks an ELF binary to be run under a certain ABI for .Pp The options are as follows: .Bl -tag -width Fl -.It Fl f -forces branding even if the brand requested is unknown, and disables -warnings for unknown brands. +.It Fl f Ar ELF ABI number +forces branding with the supplied ELF ABI number. In compatable with the +.It Fl t +option. These values are assigned by SCO/USL. .It Fl l lists all known ELF types on the standard error channel. .It Fl v turns on verbose reporting .It Fl t Ar string -Brands the given ELF binaries with +Brands the given ELF binaries to be of the .Ar string -as the ABI type. Currently supported ABI's are +ABI type. Currently supported ABI's are .Dq Tn FreeBSD and .Dq Linux . @@ -65,7 +66,7 @@ If .Fl t Ar string is given it will brand .Ar file -with +to be of type .Ar string , otherwise it will simply display the branding of .Ar file . @@ -84,6 +85,13 @@ fails if a file doesn't 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 SEE ALSO +.Rs +.%A The Scanta 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 diff --git a/usr.bin/brandelf/brandelf.c b/usr.bin/brandelf/brandelf.c index 65b473d..7993bf9 100644 --- a/usr.bin/brandelf/brandelf.c +++ b/usr.bin/brandelf/brandelf.c @@ -34,24 +34,46 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/errno.h> #include <err.h> -static int iselftype(const char *); +static int elftype(const char *); +static const char *iselftype(int); static void printelftypes(void); static void usage __P((void)); +struct ELFtypes { + const char *str; + int value; +}; +/* XXX - any more types? */ +static struct ELFtypes elftypes[] = { + { "FreeBSD", ELFOSABI_FREEBSD }, + { "SVR4", ELFOSABI_SYSV }, + { "Linux", ELFOSABI_LINUX } +}; + int main(int argc, char **argv) { - const char *type = "FreeBSD"; + const char *strtype = "FreeBSD"; + int type = ELFOSABI_FREEBSD; int retval = 0; int ch, change = 0, verbose = 0, force = 0, listed = 0; - while ((ch = getopt(argc, argv, "flt:v")) != -1) + while ((ch = getopt(argc, argv, "f:lt:v")) != -1) switch (ch) { case 'f': + if (change) + errx(1, "f option incompatable with t option"); force = 1; + type = atoi(optarg); + if (errno == ERANGE || type < 0 || type > 255) { + warnx("invalid argument to option f: %s", + optarg); + usage(); + } break; case 'l': printelftypes(); @@ -61,8 +83,10 @@ main(int argc, char **argv) verbose = 1; break; case 't': + if (force) + errx(1, "t option incompatable with f option"); change = 1; - type = optarg; + strtype = optarg; break; default: usage(); @@ -78,8 +102,8 @@ main(int argc, char **argv) } } - if (!force && !iselftype(type)) { - warnx("invalid ELF type '%s'", type); + if (!force && (type = elftype(strtype)) == -1) { + warnx("invalid ELF type '%s'", strtype); printelftypes(); usage(); } @@ -87,9 +111,8 @@ main(int argc, char **argv) while (argc) { int fd; char buffer[EI_NIDENT]; - char string[(EI_NIDENT-EI_BRAND)+1]; - if ((fd = open(argv[0], change? O_RDWR: O_RDONLY, 0)) < 0) { + if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) { warn("error opening file %s", argv[0]); retval = 1; goto fail; @@ -105,28 +128,22 @@ main(int argc, char **argv) retval = 1; goto fail; } - if (!change) { - bzero(string, sizeof(string)); - strncpy(string, &buffer[EI_BRAND], EI_NIDENT-EI_BRAND); - if (strlen(string)) { - fprintf(stdout, - "File '%s' is of brand '%s'.\n", - argv[0], string); - if (!force && !iselftype(string)) { - warnx("Brand '%s' is unknown", - string); - printelftypes(); - } + if (!change && !force) { + fprintf(stdout, + "File '%s' is of brand '%s' (%u).\n", + argv[0], iselftype(buffer[EI_OSABI]), + buffer[EI_OSABI]); + if (!iselftype(type)) { + warnx("ELF ABI Brand '%u' is unknown", + type); + printelftypes(); } - else - fprintf(stdout, "File '%s' has no branding.\n", - argv[0]); } else { - strncpy(&buffer[EI_BRAND], type, EI_NIDENT-EI_BRAND); + buffer[EI_OSABI] = type; lseek(fd, 0, SEEK_SET); if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { - warnx("error writing %s", argv[0]); + warn("error writing %s %d", argv[0], fd); retval = 1; goto fail; } @@ -142,24 +159,34 @@ fail: static void usage() { - fprintf(stderr, "usage: brandelf [-f] [-v] [-l] [-t string] file ...\n"); +fprintf(stderr, "usage: brandelf [-f ELF ABI number] [-v] [-l] [-t string] file ...\n"); exit(1); } -/* XXX - any more types? */ -static const char *elftypes[] = { "FreeBSD", "Linux", "SVR4" }; +static const char * +iselftype(int elftype) +{ + int elfwalk; + + for (elfwalk = 0; + elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); + elfwalk++) + if (elftype == elftypes[elfwalk].value) + return elftypes[elfwalk].str; + return 0; +} static int -iselftype(const char *elftype) +elftype(const char *elfstrtype) { int elfwalk; for (elfwalk = 0; elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); elfwalk++) - if (strcmp(elftype, elftypes[elfwalk]) == 0) - return 1; - return 0; + if (strcmp(elfstrtype, elftypes[elfwalk].str) == 0) + return elftypes[elfwalk].value; + return -1; } static void @@ -171,6 +198,7 @@ printelftypes() for (elfwalk = 0; elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); elfwalk++) - fprintf(stderr, "%s ", elftypes[elfwalk]); + fprintf(stderr, "%s(%u) ", elftypes[elfwalk].str, + elftypes[elfwalk].value); fprintf(stderr, "\n"); } |