summaryrefslogtreecommitdiffstats
path: root/sys/kern/imgact_elf.c
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/kern/imgact_elf.c
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/kern/imgact_elf.c')
-rw-r--r--sys/kern/imgact_elf.c55
1 files changed, 26 insertions, 29 deletions
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;
OpenPOWER on IntegriCloud