summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1996-10-16 17:51:08 +0000
committersos <sos@FreeBSD.org>1996-10-16 17:51:08 +0000
commita7dce0775e41a26320ae35eb227c1339ef490017 (patch)
treed72720304037f68df6726fde308a22bc5c01e935 /sys
parent4f23e86b1a5a97ce2cbd515ba8d13c6a63a6e071 (diff)
downloadFreeBSD-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.c11
-rw-r--r--sys/i386/linux/linux_sysvec.c11
-rw-r--r--sys/kern/imgact_elf.c123
-rw-r--r--sys/modules/linux/linux.c8
-rw-r--r--sys/sys/imgact_elf.h17
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_ */
OpenPOWER on IntegriCloud