mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-28 04:43:32 +00:00
Prepare kernel to take advantage of "branded" ELF binaries.
This commit is contained in:
parent
953441e43b
commit
ea5a2b2e00
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18959
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user