diff options
author | sos <sos@FreeBSD.org> | 1996-10-16 17:51:08 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 1996-10-16 17:51:08 +0000 |
commit | a7dce0775e41a26320ae35eb227c1339ef490017 (patch) | |
tree | d72720304037f68df6726fde308a22bc5c01e935 /sys | |
parent | 4f23e86b1a5a97ce2cbd515ba8d13c6a63a6e071 (diff) | |
download | FreeBSD-src-a7dce0775e41a26320ae35eb227c1339ef490017.zip FreeBSD-src-a7dce0775e41a26320ae35eb227c1339ef490017.tar.gz |
Prepare kernel to take advantage of "branded" ELF binaries.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/linux/linux_sysvec.c | 11 | ||||
-rw-r--r-- | sys/i386/linux/linux_sysvec.c | 11 | ||||
-rw-r--r-- | sys/kern/imgact_elf.c | 123 | ||||
-rw-r--r-- | sys/modules/linux/linux.c | 8 | ||||
-rw-r--r-- | sys/sys/imgact_elf.h | 17 |
5 files changed, 102 insertions, 68 deletions
diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c index aa9c2d6..c70daf6 100644 --- a/sys/alpha/linux/linux_sysvec.c +++ b/sys/alpha/linux/linux_sysvec.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_sysvec.c,v 1.7 1996/06/18 05:15:53 dyson Exp $ + * $Id: linux_sysvec.c,v 1.8 1996/10/15 18:24:34 bde Exp $ */ /* XXX we use functions that might not exist. */ @@ -405,10 +405,11 @@ struct sysentvec elf_linux_sysvec = { /* * Installed either via SYSINIT() or via LKM stubs. */ -Elf32_Interp_info linux_interp = { - &elf_linux_sysvec, +Elf32_Brandinfo linux_brand = { + "Linux", + "/compat/linux", "/lib/ld-linux.so.1", - "/compat/linux" + &elf_linux_sysvec }; #ifndef LKM @@ -416,5 +417,5 @@ Elf32_Interp_info linux_interp = { * XXX: this is WRONG, it needs to be SI_SUB_EXEC, but this is just at the * "proof of concept" stage and will be fixed shortly */ -SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, elf_insert_interp, &linux_interp); +SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, elf_insert_brand_entry, &linux_brand); #endif diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index aa9c2d6..c70daf6 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_sysvec.c,v 1.7 1996/06/18 05:15:53 dyson Exp $ + * $Id: linux_sysvec.c,v 1.8 1996/10/15 18:24:34 bde Exp $ */ /* XXX we use functions that might not exist. */ @@ -405,10 +405,11 @@ struct sysentvec elf_linux_sysvec = { /* * Installed either via SYSINIT() or via LKM stubs. */ -Elf32_Interp_info linux_interp = { - &elf_linux_sysvec, +Elf32_Brandinfo linux_brand = { + "Linux", + "/compat/linux", "/lib/ld-linux.so.1", - "/compat/linux" + &elf_linux_sysvec }; #ifndef LKM @@ -416,5 +417,5 @@ Elf32_Interp_info linux_interp = { * XXX: this is WRONG, it needs to be SI_SUB_EXEC, but this is just at the * "proof of concept" stage and will be fixed shortly */ -SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, elf_insert_interp, &linux_interp); +SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, elf_insert_brand_entry, &linux_brand); #endif diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index b646bb1..5815dd1 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_elf.c,v 1.8 1996/08/31 16:52:23 bde Exp $ + * $Id: imgact_elf.c,v 1.9 1996/10/03 06:14:48 peter Exp $ */ #include <sys/param.h> @@ -93,45 +93,46 @@ static struct sysentvec elf_freebsd_sysvec = { "FreeBSD ELF" }; -static Elf32_Interp_info freebsd_interp = { - &elf_freebsd_sysvec, +static Elf32_Brandinfo freebsd_brand_info = { + "FreeBSD", + "", "/usr/libexec/ld-elf.so.1", - "" + &elf_freebsd_sysvec }; -static Elf32_Interp_info *interp_list[MAX_INTERP] = { - &freebsd_interp, +static Elf32_Brandinfo *elf_brand_list[MAX_BRANDS] = { + &freebsd_brand_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int -elf_insert_interp(Elf32_Interp_info *entry) +elf_insert_brand_entry(Elf32_Brandinfo *entry) { int i; - for (i=1; i<MAX_INTERP; i++) { - if (interp_list[i] == NULL) { - interp_list[i] = entry; + for (i=1; i<MAX_BRANDS; i++) { + if (elf_brand_list[i] == NULL) { + elf_brand_list[i] = entry; break; } } - if (i == MAX_INTERP) + if (i == MAX_BRANDS) return -1; return 0; } int -elf_remove_interp(Elf32_Interp_info *entry) +elf_remove_brand_entry(Elf32_Brandinfo *entry) { int i; - for (i=1; i<MAX_INTERP; i++) { - if (interp_list[i] == entry) { - interp_list[i] = NULL; + for (i=1; i<MAX_BRANDS; i++) { + if (elf_brand_list[i] == entry) { + elf_brand_list[i] = NULL; break; } } - if (i == MAX_INTERP) + if (i == MAX_BRANDS) return -1; return 0; } @@ -478,6 +479,8 @@ exec_elf_imgact(struct image_params *imgp) u_long addr, entry = 0, proghdr = 0; int error, i, header_size = 0, interp_len = 0; char *interp = NULL; + char *brand = NULL; + char path[MAXPATHLEN]; /* * Do we have a valid ELF header ? @@ -611,41 +614,67 @@ exec_elf_imgact(struct image_params *imgp) addr = 2*MAXDSIZ; /* May depend on OS type XXX */ - if (interp) { - char path[MAXPATHLEN]; - /* - * So which kind of ELF binary do we have at hand - * FreeBSD, SVR4 or Linux ?? - */ - for (i=0; i<MAX_INTERP; i++) { - if (interp_list[i] != NULL) { - if (!strcmp(interp, interp_list[i]->path)) { - imgp->proc->p_sysent = - interp_list[i]->sysvec; - strcpy(path, interp_list[i]->emul_path); - strcat(path, interp_list[i]->path); - UPRINTF("interpreter=<%s> %s\n", - interp_list[i]->path, - interp_list[i]->emul_path); - break; + imgp->entry_addr = entry; + + /* + * So which kind (brand) of ELF binary do we have at hand + * FreeBSD, Linux, SVR4 or something else ?? + * If its has a interpreter section try that first + */ + if (interp) { + for (i=0; i<MAX_BRANDS; i++) { + if (elf_brand_list[i] != NULL) { + if (!strcmp(interp, elf_brand_list[i]->interp_path)) { + imgp->proc->p_sysent = + elf_brand_list[i]->sysvec; + strcpy(path, elf_brand_list[i]->emul_path); + strcat(path, elf_brand_list[i]->interp_path); + UPRINTF("interpreter=<%s> %s\n", + elf_brand_list[i]->interp_path, + elf_brand_list[i]->emul_path); + break; + } + } + } + } + + /* + * If there is no interpreter, or recognition of it + * failed, se if the binary is branded. + */ + if (!interp || i == MAX_BRANDS) { + brand = (char *)&(hdr->e_ident[EI_BRAND]); + for (i=0; i<MAX_BRANDS; i++) { + if (elf_brand_list[i] != NULL) { + if (!strcmp(brand, elf_brand_list[i]->brand)) { + imgp->proc->p_sysent = elf_brand_list[i]->sysvec; + if (interp) { + strcpy(path, elf_brand_list[i]->emul_path); + strcat(path, elf_brand_list[i]->interp_path); + UPRINTF("interpreter=<%s> %s\n", + elf_brand_list[i]->interp_path, + elf_brand_list[i]->emul_path); + } } } } - if (i == MAX_INTERP) { - uprintf("ELF interpreter %s not known\n", interp); - error = ENOEXEC; - goto fail; - } - if (error = elf_load_file(imgp->proc, - path, - &addr, /* XXX */ - &imgp->entry_addr)) { - uprintf("ELF interpreter %s not found\n", path); - goto fail; - } } - else - imgp->entry_addr = entry; + if (i == MAX_BRANDS) { + uprintf("ELF binary type not known\n"); + error = ENOEXEC; + goto fail; + } + if (interp) { + if (error = elf_load_file(imgp->proc, + path, + &addr, /* XXX */ + &imgp->entry_addr)) { + uprintf("ELF interpreter %s not found\n", path); + goto fail; + } + } + + uprintf("Executing %s binary\n", elf_brand_list[i]->brand); /* * Construct auxargs table (used by the fixup routine) diff --git a/sys/modules/linux/linux.c b/sys/modules/linux/linux.c index dc0d522..2378775 100644 --- a/sys/modules/linux/linux.c +++ b/sys/modules/linux/linux.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux.c,v 1.6 1996/03/10 22:43:37 peter Exp $ + * $Id: linux.c,v 1.7 1996/09/03 22:52:07 bde Exp $ */ #include <sys/param.h> @@ -41,12 +41,12 @@ extern const struct execsw linux_execsw; MOD_EXEC(linux, -1, &linux_execsw); -extern Elf32_Interp_info linux_interp; +extern Elf32_Brandinfo linux_brand; static int linux_load(struct lkm_table *lkmtp, int cmd) { - if (elf_insert_interp(&linux_interp)) + if (elf_insert_brand_entry(&linux_brand)) uprintf("Could not install ELF interpreter entry\n"); uprintf("Linux emulator installed\n"); return 0; @@ -55,7 +55,7 @@ linux_load(struct lkm_table *lkmtp, int cmd) static int linux_unload(struct lkm_table *lkmtp, int cmd) { - if (elf_remove_interp(&linux_interp)) + if (elf_remove_brand_entry(&linux_brand)) uprintf("Could not deinstall ELF interpreter entry\n"); uprintf("Linux emulator removed\n"); return 0; diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h index d24a725..cc0b7e2 100644 --- a/sys/sys/imgact_elf.h +++ b/sys/sys/imgact_elf.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: imgact_elf.h,v 1.1 1996/03/10 08:42:52 sos Exp $ */ #ifndef _IMGACT_ELF_H_ @@ -67,6 +67,8 @@ typedef struct { #define EI_CLASS 4 #define EI_DATA 5 #define EI_VERSION 6 +#define EI_SPARE 8 +#define EI_BRAND 8 #define ELFMAG0 '\177' @@ -200,14 +202,15 @@ typedef struct { } Elf32_Auxargs; typedef struct { - struct sysentvec *sysvec; - char *path; + char *brand; char *emul_path; -} Elf32_Interp_info; + char *interp_path; + struct sysentvec *sysvec; +} Elf32_Brandinfo; -#define MAX_INTERP 8 +#define MAX_BRANDS 8 -int elf_insert_interp __P((Elf32_Interp_info *entry)); -int elf_remove_interp __P((Elf32_Interp_info *entry)); +int elf_insert_brand_entry __P((Elf32_Brandinfo *entry)); +int elf_remove_brand_entry __P((Elf32_Brandinfo *entry)); #endif /* _IMGACT_ELF_H_ */ |