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 /sys/kern/imgact_elf.c | |
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 'sys/kern/imgact_elf.c')
-rw-r--r-- | sys/kern/imgact_elf.c | 55 |
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; |