Prepare kernel to take advantage of "branded" ELF binaries.

This commit is contained in:
Søren Schmidt 1996-10-16 17:51:08 +00:00
parent 953441e43b
commit ea5a2b2e00
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18959
6 changed files with 106 additions and 72 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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_ */