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. *
This commit is contained in:
parent
8d396be510
commit
c815a20cb2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=59342
@ -40,13 +40,6 @@ SECTION
|
||||
#define ARCH_SIZE 0
|
||||
#include "elf-bfd.h"
|
||||
|
||||
#define EI_BRAND_OFFSET 8 /* should be in binutils/include/elf/common.h */
|
||||
#if defined(__FreeBSD__)
|
||||
#define BRANDING "FreeBSD"
|
||||
#else
|
||||
#define BRANDING ""
|
||||
#endif
|
||||
|
||||
static INLINE struct elf_segment_map *make_mapping
|
||||
PARAMS ((bfd *, asection **, unsigned int, unsigned int, boolean));
|
||||
static boolean map_sections_to_segments PARAMS ((bfd *));
|
||||
@ -2932,9 +2925,24 @@ prep_headers (abfd)
|
||||
bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
|
||||
i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* Quick and dirty hack to brand the file as a FreeBSD ELF file. */
|
||||
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
|
||||
i_ehdrp->e_ident[EI_ABIVERSION] = 0;
|
||||
#endif
|
||||
|
||||
for (count = EI_PAD; count < EI_NIDENT; count++)
|
||||
i_ehdrp->e_ident[count] = 0;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* #ifdef BRANDELF_CHANGE_BOOTSTRAP */
|
||||
#define _OLD_EI_BRAND_OFFSET 8
|
||||
#define _OLD_BRANDING "FreeBSD"
|
||||
strncpy((char *) &i_ehdrp->e_ident[_OLD_EI_BRAND_OFFSET], _OLD_BRANDING,
|
||||
EI_NIDENT-_OLD_EI_BRAND_OFFSET);
|
||||
/* #endif */
|
||||
#endif
|
||||
|
||||
if ((abfd->flags & DYNAMIC) != 0)
|
||||
i_ehdrp->e_type = ET_DYN;
|
||||
else if ((abfd->flags & EXEC_P) != 0)
|
||||
@ -2949,7 +2957,7 @@ prep_headers (abfd)
|
||||
break;
|
||||
case bfd_arch_sparc:
|
||||
if (bed->s->arch_size == 64)
|
||||
i_ehdrp->e_machine = EM_SPARC64;
|
||||
i_ehdrp->e_machine = EM_SPARCV9;
|
||||
else
|
||||
i_ehdrp->e_machine = EM_SPARC;
|
||||
break;
|
||||
@ -3009,11 +3017,6 @@ prep_headers (abfd)
|
||||
i_ehdrp->e_version = bed->s->ev_current;
|
||||
i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
|
||||
|
||||
/* Some OS's brands all ELF binaries so the image loader knows what system
|
||||
call set, etc. to use. */
|
||||
strncpy((char *) &i_ehdrp->e_ident[EI_BRAND_OFFSET], BRANDING,
|
||||
EI_NIDENT-EI_BRAND_OFFSET);
|
||||
|
||||
/* no program header, for now. */
|
||||
i_ehdrp->e_phoff = 0;
|
||||
i_ehdrp->e_phentsize = 0;
|
||||
|
@ -25,6 +25,20 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* See http://www.netbsd.org/Documentation/kernel/elf-notes.html for
|
||||
details on the ELF .note section as we are using it. */
|
||||
.section .note.ABI-tag, "a"
|
||||
.align 4
|
||||
.long 1f - 0f # name length
|
||||
.long 3f - 2f # data length
|
||||
.long 1 # note type
|
||||
0: .asciz "FreeBSD" # vendor name
|
||||
1: .align 4
|
||||
2: .long 500000 # data - ABI tag
|
||||
# (from __FreeBSD_version (param.h))
|
||||
3: .align 4 # pad out section
|
||||
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.align 4
|
||||
.globl _init
|
||||
|
@ -25,6 +25,20 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* See http://www.netbsd.org/Documentation/kernel/elf-notes.html for
|
||||
details on the ELF .note section as we are using it. */
|
||||
.section .note.ABI-tag, "a"
|
||||
.align 4
|
||||
.long 1f - 0f # name length
|
||||
.long 3f - 2f # data length
|
||||
.long 1 # note type
|
||||
0: .asciz "FreeBSD" # vendor name
|
||||
1: .align 4
|
||||
2: .long 500000 # data - ABI tag
|
||||
# (from __FreeBSD_version (param.h))
|
||||
3: .align 4 # pad out section
|
||||
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.align 4
|
||||
.globl _init
|
||||
|
@ -439,14 +439,14 @@ struct sysentvec elf_linux_sysvec = {
|
||||
};
|
||||
|
||||
static Elf32_Brandinfo linux_brand = {
|
||||
"Linux",
|
||||
ELFOSABI_LINUX,
|
||||
"/compat/linux",
|
||||
"/lib/ld-linux.so.1",
|
||||
&elf_linux_sysvec
|
||||
};
|
||||
|
||||
static Elf32_Brandinfo linux_glibc2brand = {
|
||||
"Linux",
|
||||
ELFOSABI_LINUX,
|
||||
"/compat/linux",
|
||||
"/lib/ld-linux.so.2",
|
||||
&elf_linux_sysvec
|
||||
|
@ -155,7 +155,7 @@ int bsd_to_svr4_errno[ELAST+1] = {
|
||||
};
|
||||
|
||||
|
||||
static int svr4_fixup(long **stack_base, struct image_params *imgp);
|
||||
static int svr4_fixup(register_t **stack_base, struct image_params *imgp);
|
||||
|
||||
extern struct sysent svr4_sysent[];
|
||||
#undef szsigcode
|
||||
@ -183,8 +183,8 @@ struct sysentvec svr4_sysvec = {
|
||||
};
|
||||
|
||||
Elf32_Brandinfo svr4_brand = {
|
||||
"SVR4",
|
||||
"/compat/svr4",
|
||||
ELFOSABI_SOLARIS, /* XXX Or should we use ELFOSABI_SYSV here? */
|
||||
svr4_emul_path,
|
||||
"/lib/libc.so.1",
|
||||
&svr4_sysvec
|
||||
};
|
||||
@ -192,10 +192,10 @@ Elf32_Brandinfo svr4_brand = {
|
||||
const char svr4_emul_path[] = "/compat/svr4";
|
||||
|
||||
static int
|
||||
svr4_fixup(long **stack_base, struct image_params *imgp)
|
||||
svr4_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
{
|
||||
Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs;
|
||||
long *pos;
|
||||
register_t *pos;
|
||||
|
||||
pos = *stack_base + (imgp->argc + imgp->envc + 2);
|
||||
|
||||
|
@ -439,14 +439,14 @@ struct sysentvec elf_linux_sysvec = {
|
||||
};
|
||||
|
||||
static Elf32_Brandinfo linux_brand = {
|
||||
"Linux",
|
||||
ELFOSABI_LINUX,
|
||||
"/compat/linux",
|
||||
"/lib/ld-linux.so.1",
|
||||
&elf_linux_sysvec
|
||||
};
|
||||
|
||||
static Elf32_Brandinfo linux_glibc2brand = {
|
||||
"Linux",
|
||||
ELFOSABI_LINUX,
|
||||
"/compat/linux",
|
||||
"/lib/ld-linux.so.2",
|
||||
&elf_linux_sysvec
|
||||
|
@ -65,6 +65,8 @@
|
||||
#include <machine/elf.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#define OLD_EI_BRAND 8
|
||||
|
||||
__ElfType(Brandinfo);
|
||||
__ElfType(Auxargs);
|
||||
|
||||
@ -82,12 +84,6 @@ static int exec_elf_imgact __P((struct image_params *imgp));
|
||||
static int elf_trace = 0;
|
||||
SYSCTL_INT(_debug, OID_AUTO, elf_trace, CTLFLAG_RW, &elf_trace, 0, "");
|
||||
|
||||
/*
|
||||
* XXX Maximum length of an ELF brand (sysctl wants a statically-allocated
|
||||
* buffer).
|
||||
*/
|
||||
#define MAXBRANDLEN 16
|
||||
|
||||
static struct sysentvec elf_freebsd_sysvec = {
|
||||
SYS_MAXSYSCALL,
|
||||
sysent,
|
||||
@ -107,7 +103,7 @@ static struct sysentvec elf_freebsd_sysvec = {
|
||||
};
|
||||
|
||||
static Elf_Brandinfo freebsd_brand_info = {
|
||||
"FreeBSD",
|
||||
ELFOSABI_FREEBSD,
|
||||
"",
|
||||
"/usr/libexec/ld-elf.so.1",
|
||||
&elf_freebsd_sysvec
|
||||
@ -412,9 +408,9 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry)
|
||||
return error;
|
||||
}
|
||||
|
||||
static char fallback_elf_brand[MAXBRANDLEN+1] = { "none" };
|
||||
SYSCTL_STRING(_kern, OID_AUTO, fallback_elf_brand, CTLFLAG_RW,
|
||||
fallback_elf_brand, sizeof(fallback_elf_brand),
|
||||
static int fallback_elf_brand = ELFOSABI_FREEBSD;
|
||||
SYSCTL_INT(_kern, OID_AUTO, fallback_elf_brand, CTLFLAG_RW,
|
||||
&fallback_elf_brand, ELFOSABI_FREEBSD,
|
||||
"ELF brand of last resort");
|
||||
|
||||
static int
|
||||
@ -431,7 +427,6 @@ exec_elf_imgact(struct image_params *imgp)
|
||||
int error, i;
|
||||
const char *interp = NULL;
|
||||
Elf_Brandinfo *brand_info;
|
||||
const char *brand;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
/*
|
||||
@ -526,14 +521,23 @@ exec_elf_imgact(struct image_params *imgp)
|
||||
|
||||
imgp->entry_addr = entry;
|
||||
|
||||
/* If the executable has a brand, search for it in the brand list. */
|
||||
brand_info = NULL;
|
||||
brand = (const char *)&hdr->e_ident[EI_BRAND];
|
||||
if (brand[0] != '\0') {
|
||||
|
||||
/* XXX For now we look for the magic "FreeBSD" that we used to put
|
||||
* into the ELF header at the EI_ABIVERSION location. If found use
|
||||
* that information rather than figuring out the ABI from proper
|
||||
* branding. This should be removed for 5.0-RELEASE. The Linux caes
|
||||
* can be figured out from the `interp_path' field.
|
||||
*/
|
||||
if (strcmp("FreeBSD", (const char *)&hdr->e_ident[OLD_EI_BRAND]) == 0)
|
||||
brand_info = &freebsd_brand_info;
|
||||
|
||||
/* If the executable has a brand, search for it in the brand list. */
|
||||
if (brand_info == NULL) {
|
||||
for (i = 0; i < MAX_BRANDS; i++) {
|
||||
Elf_Brandinfo *bi = elf_brand_list[i];
|
||||
|
||||
if (bi != NULL && strcmp(brand, bi->brand) == 0) {
|
||||
if (bi != NULL && hdr->e_ident[EI_OSABI] == bi->brand) {
|
||||
brand_info = bi;
|
||||
break;
|
||||
}
|
||||
@ -554,31 +558,24 @@ exec_elf_imgact(struct image_params *imgp)
|
||||
}
|
||||
|
||||
/* Lacking a recognized interpreter, try the default brand */
|
||||
if (brand_info == NULL && fallback_elf_brand[0] != '\0') {
|
||||
if (brand_info == NULL) {
|
||||
for (i = 0; i < MAX_BRANDS; i++) {
|
||||
Elf_Brandinfo *bi = elf_brand_list[i];
|
||||
|
||||
if (bi != NULL
|
||||
&& strcmp(fallback_elf_brand, bi->brand) == 0) {
|
||||
if (bi != NULL && fallback_elf_brand == bi->brand) {
|
||||
brand_info = bi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __alpha__
|
||||
/* XXX - Assume FreeBSD on the alpha. */
|
||||
/* XXX - Assume FreeBSD after the branding method change. */
|
||||
if (brand_info == NULL)
|
||||
brand_info = &freebsd_brand_info;
|
||||
#endif
|
||||
|
||||
if (brand_info == NULL) {
|
||||
if (brand[0] == 0)
|
||||
uprintf("ELF binary type not known."
|
||||
" Use \"brandelf\" to brand it.\n");
|
||||
else
|
||||
uprintf("ELF binary type \"%.*s\" not known.\n",
|
||||
EI_NIDENT - EI_BRAND, brand);
|
||||
uprintf("ELF binary type \"%u\" not known.\n",
|
||||
hdr->e_ident[EI_OSABI]);
|
||||
error = ENOEXEC;
|
||||
goto fail;
|
||||
}
|
||||
@ -932,9 +929,9 @@ elf_puthdr(struct proc *p, void *dst, size_t *off, const prstatus_t *status,
|
||||
ehdr->e_ident[EI_CLASS] = ELF_CLASS;
|
||||
ehdr->e_ident[EI_DATA] = ELF_DATA;
|
||||
ehdr->e_ident[EI_VERSION] = EV_CURRENT;
|
||||
ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
|
||||
ehdr->e_ident[EI_ABIVERSION] = 0;
|
||||
ehdr->e_ident[EI_PAD] = 0;
|
||||
strncpy(ehdr->e_ident + EI_BRAND, "FreeBSD",
|
||||
EI_NIDENT - EI_BRAND);
|
||||
ehdr->e_type = ET_CORE;
|
||||
ehdr->e_machine = ELF_ARCH;
|
||||
ehdr->e_version = EV_CURRENT;
|
||||
|
@ -155,7 +155,7 @@ int bsd_to_svr4_errno[ELAST+1] = {
|
||||
};
|
||||
|
||||
|
||||
static int svr4_fixup(long **stack_base, struct image_params *imgp);
|
||||
static int svr4_fixup(register_t **stack_base, struct image_params *imgp);
|
||||
|
||||
extern struct sysent svr4_sysent[];
|
||||
#undef szsigcode
|
||||
@ -183,8 +183,8 @@ struct sysentvec svr4_sysvec = {
|
||||
};
|
||||
|
||||
Elf32_Brandinfo svr4_brand = {
|
||||
"SVR4",
|
||||
"/compat/svr4",
|
||||
ELFOSABI_SOLARIS, /* XXX Or should we use ELFOSABI_SYSV here? */
|
||||
svr4_emul_path,
|
||||
"/lib/libc.so.1",
|
||||
&svr4_sysvec
|
||||
};
|
||||
@ -192,10 +192,10 @@ Elf32_Brandinfo svr4_brand = {
|
||||
const char svr4_emul_path[] = "/compat/svr4";
|
||||
|
||||
static int
|
||||
svr4_fixup(long **stack_base, struct image_params *imgp)
|
||||
svr4_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
{
|
||||
Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs;
|
||||
long *pos;
|
||||
register_t *pos;
|
||||
|
||||
pos = *stack_base + (imgp->argc + imgp->envc + 2);
|
||||
|
||||
|
@ -48,7 +48,8 @@ typedef struct {
|
||||
u_int32_t n_type; /* Type of this note. */
|
||||
} Elf_Note;
|
||||
|
||||
/* Indexes into the e_ident array. */
|
||||
/* Indexes into the e_ident array. Keep synced with
|
||||
http://www.sco.com/developer/gabi/ch4.eheader.html */
|
||||
#define EI_MAG0 0 /* Magic number, byte 0. */
|
||||
#define EI_MAG1 1 /* Magic number, byte 1. */
|
||||
#define EI_MAG2 2 /* Magic number, byte 2. */
|
||||
@ -56,8 +57,10 @@ typedef struct {
|
||||
#define EI_CLASS 4 /* Class of machine. */
|
||||
#define EI_DATA 5 /* Data format. */
|
||||
#define EI_VERSION 6 /* ELF format version. */
|
||||
#define EI_PAD 7 /* Start of padding (per SVR4 ABI). */
|
||||
#define EI_BRAND 8 /* Start of architecture identification. */
|
||||
#define EI_OSABI 7 /* Operating system / ABI identification */
|
||||
#define EI_ABIVERSION 8 /* ABI version */
|
||||
#define OLD_EI_BRAND 8 /* Start of architecture identification. */
|
||||
#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
|
||||
#define EI_NIDENT 16 /* Size of e_ident array. */
|
||||
|
||||
/* Values for the magic number bytes. */
|
||||
@ -80,6 +83,21 @@ typedef struct {
|
||||
#define ELFDATA2LSB 1 /* 2's complement little-endian. */
|
||||
#define ELFDATA2MSB 2 /* 2's complement big-endian. */
|
||||
|
||||
/* Values for e_ident[EI_OSABI]. */
|
||||
#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
|
||||
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
|
||||
#define ELFOSABI_NETBSD 2 /* NetBSD */
|
||||
#define ELFOSABI_LINUX 3 /* GNU/Linux */
|
||||
#define ELFOSABI_HURD 4 /* GNU/Hurd */
|
||||
#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
|
||||
#define ELFOSABI_SOLARIS 6 /* Solaris */
|
||||
#define ELFOSABI_MONTEREY 7 /* Monterey */
|
||||
#define ELFOSABI_IRIX 8 /* IRIX */
|
||||
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
|
||||
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
|
||||
#define ELFOSABI_ARM 97 /* ARM */
|
||||
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
|
||||
|
||||
/* e_ident */
|
||||
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
|
||||
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
|
||||
|
@ -56,9 +56,9 @@ typedef struct {
|
||||
} Elf32_Auxargs;
|
||||
|
||||
typedef struct {
|
||||
char *brand;
|
||||
char *emul_path;
|
||||
char *interp_path;
|
||||
int brand;
|
||||
const char *emul_path;
|
||||
const char *interp_path;
|
||||
struct sysentvec *sysvec;
|
||||
} Elf32_Brandinfo;
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= brandelf
|
||||
CFLAGS+=-Wall
|
||||
CFLAGS+= -Wall
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -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
|
||||
|
@ -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,26 +159,36 @@ main(int argc, char **argv)
|
||||
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 int
|
||||
iselftype(const char *elftype)
|
||||
static const char *
|
||||
iselftype(int elftype)
|
||||
{
|
||||
int elfwalk;
|
||||
|
||||
for (elfwalk = 0;
|
||||
elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
|
||||
elfwalk++)
|
||||
if (strcmp(elftype, elftypes[elfwalk]) == 0)
|
||||
return 1;
|
||||
if (elftype == elftypes[elfwalk].value)
|
||||
return elftypes[elfwalk].str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
elftype(const char *elfstrtype)
|
||||
{
|
||||
int elfwalk;
|
||||
|
||||
for (elfwalk = 0;
|
||||
elfwalk < sizeof(elftypes)/sizeof(elftypes[0]);
|
||||
elfwalk++)
|
||||
if (strcmp(elfstrtype, elftypes[elfwalk].str) == 0)
|
||||
return elftypes[elfwalk].value;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
printelftypes()
|
||||
{
|
||||
@ -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");
|
||||
}
|
||||
|
@ -287,9 +287,9 @@ elf_puthdr(vm_map_entry_t map, void *dst, size_t *off, const prstatus_t *status,
|
||||
ehdr->e_ident[EI_CLASS] = ELF_CLASS;
|
||||
ehdr->e_ident[EI_DATA] = ELF_DATA;
|
||||
ehdr->e_ident[EI_VERSION] = EV_CURRENT;
|
||||
ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
|
||||
ehdr->e_ident[EI_ABIVERSION] = 0;
|
||||
ehdr->e_ident[EI_PAD] = 0;
|
||||
strncpy(ehdr->e_ident + EI_BRAND, "FreeBSD",
|
||||
EI_NIDENT - EI_BRAND);
|
||||
ehdr->e_type = ET_CORE;
|
||||
ehdr->e_machine = ELF_ARCH;
|
||||
ehdr->e_version = EV_CURRENT;
|
||||
|
Loading…
Reference in New Issue
Block a user