summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2000-04-18 02:39:26 +0000
committerobrien <obrien@FreeBSD.org>2000-04-18 02:39:26 +0000
commit0eac6bbc676f298cf518321aa0d24cc001c69611 (patch)
tree0215bcb520740db905cae767cb8c981d2e3f8a50 /sys
parent2e1592d902d16ed9876e30509b0d925e1a30e2c7 (diff)
downloadFreeBSD-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 'sys')
-rw-r--r--sys/alpha/linux/linux_sysvec.c4
-rw-r--r--sys/compat/svr4/svr4_sysvec.c10
-rw-r--r--sys/i386/linux/linux_sysvec.c4
-rw-r--r--sys/kern/imgact_elf.c55
-rw-r--r--sys/svr4/svr4_sysvec.c10
-rw-r--r--sys/sys/elf_common.h24
-rw-r--r--sys/sys/imgact_elf.h6
7 files changed, 64 insertions, 49 deletions
diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c
index 39f3000..a92cd8ad 100644
--- a/sys/alpha/linux/linux_sysvec.c
+++ b/sys/alpha/linux/linux_sysvec.c
@@ -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
diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c
index b470157..c66e61b 100644
--- a/sys/compat/svr4/svr4_sysvec.c
+++ b/sys/compat/svr4/svr4_sysvec.c
@@ -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);
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 39f3000..a92cd8ad 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -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
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 6a0e0ef..8fe3362 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -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 @@ fail:
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;
diff --git a/sys/svr4/svr4_sysvec.c b/sys/svr4/svr4_sysvec.c
index b470157..c66e61b 100644
--- a/sys/svr4/svr4_sysvec.c
+++ b/sys/svr4/svr4_sysvec.c
@@ -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);
diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h
index 207050d..f63f384 100644
--- a/sys/sys/elf_common.h
+++ b/sys/sys/elf_common.h
@@ -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 && \
diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h
index 065d5b5..b781552 100644
--- a/sys/sys/imgact_elf.h
+++ b/sys/sys/imgact_elf.h
@@ -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;
OpenPOWER on IntegriCloud