Add an additional field to the elf brandinfo structure to support

quicker exec-time replacement of the elf interpreter on an emulation
environment where an entire /compat/* tree isn't really warranted.
This commit is contained in:
Peter Wemm 2003-12-23 02:42:39 +00:00
parent feb5832efb
commit 9b68618df0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=123742
12 changed files with 150 additions and 35 deletions

View File

@ -81,15 +81,31 @@ static Elf64_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD,
EM_ALPHA,
"FreeBSD",
"",
NULL,
"/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info);
static Elf64_Brandinfo freebsd_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_ALPHA,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_oinfo);
/* Process one elf relocation with addend. */
static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

View File

@ -210,7 +210,8 @@ static Elf64_Brandinfo linux_brand = {
"Linux",
"/compat/linux",
"/lib/ld-linux.so.1",
&elf_linux_sysvec
&elf_linux_sysvec,
NULL,
};
static Elf64_Brandinfo linux_glibc2brand = {
@ -219,7 +220,8 @@ static Elf64_Brandinfo linux_glibc2brand = {
"Linux",
"/compat/linux",
"/lib/ld-linux.so.2",
&elf_linux_sysvec
&elf_linux_sysvec,
NULL,
};
Elf64_Brandinfo *linux_brandlist[] = {

View File

@ -78,15 +78,30 @@ static Elf64_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD,
EM_X86_64,
"FreeBSD",
"",
NULL,
"/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info);
static Elf64_Brandinfo freebsd_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_X86_64,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_oinfo);
/* Process one elf relocation with addend. */
static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

View File

@ -129,21 +129,34 @@ struct sysentvec ia32_freebsd_sysvec = {
};
const char freebsd32_emul_path[] = "/compat/ia32";
static Elf32_Brandinfo ia32_brand_info = {
ELFOSABI_FREEBSD,
EM_386,
"FreeBSD",
"/compat/ia32",
"/usr/libexec/ld-elf.so.1",
&ia32_freebsd_sysvec
NULL,
"/libexec/ld-elf.so.1",
&ia32_freebsd_sysvec,
"/libexec/ld-elf-32.so.1",
};
SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&ia32_brand_info);
static Elf32_Brandinfo ia32_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_386,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&ia32_freebsd_sysvec,
"/usr/libexec/ld-elf-32.so.1",
};
SYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&ia32_brand_oinfo);
/* XXX may be freebsd32 MI */
static register_t *
ia32_copyout_strings(struct image_params *imgp)

View File

@ -199,7 +199,8 @@ Elf32_Brandinfo svr4_brand = {
"SVR4",
svr4_emul_path,
"/lib/libc.so.1",
&svr4_sysvec
&svr4_sysvec,
NULL,
};
const char svr4_emul_path[] = "/compat/svr4";

View File

@ -78,15 +78,30 @@ static Elf32_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD,
EM_386,
"FreeBSD",
"",
NULL,
"/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec
&elf32_freebsd_sysvec,
NULL,
};
SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info);
static Elf32_Brandinfo freebsd_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_386,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec,
NULL,
};
SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_oinfo);
/* Process one elf relocation with addend. */
static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

View File

@ -899,7 +899,8 @@ static Elf32_Brandinfo linux_brand = {
"Linux",
"/compat/linux",
"/lib/ld-linux.so.1",
&elf_linux_sysvec
&elf_linux_sysvec,
NULL,
};
static Elf32_Brandinfo linux_glibc2brand = {
@ -908,7 +909,8 @@ static Elf32_Brandinfo linux_glibc2brand = {
"Linux",
"/compat/linux",
"/lib/ld-linux.so.2",
&elf_linux_sysvec
&elf_linux_sysvec,
NULL,
};
Elf32_Brandinfo *linux_brandlist[] = {

View File

@ -84,15 +84,30 @@ static Elf64_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD,
EM_IA_64,
"FreeBSD",
"",
NULL,
"/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info);
static Elf64_Brandinfo freebsd_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_IA_64,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_oinfo);
Elf_Addr link_elf_get_gp(linker_file_t);
extern Elf_Addr fptr_storage[];

View File

@ -708,6 +708,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
goto fail;
}
sv = brand_info->sysvec;
if (interp != NULL && brand_info->interp_newpath != NULL)
interp = brand_info->interp_newpath;
if ((error = exec_extract_strings(imgp)) != 0)
goto fail;
@ -818,21 +820,24 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
imgp->entry_addr = entry;
imgp->proc->p_sysent = sv;
if (interp != NULL) {
if (interp != NULL && brand_info->emul_path != NULL &&
brand_info->emul_path[0] != '\0') {
path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
snprintf(path, MAXPATHLEN, "%s%s", brand_info->emul_path,
interp);
if ((error = __elfN(load_file)(imgp->proc, path, &addr,
&imgp->entry_addr, sv->sv_pagesize)) != 0) {
if ((error = __elfN(load_file)(imgp->proc, interp,
&addr, &imgp->entry_addr, sv->sv_pagesize)) != 0) {
uprintf("ELF interpreter %s not found\n",
path);
free(path, M_TEMP);
goto fail;
}
}
error = __elfN(load_file)(imgp->proc, path, &addr,
&imgp->entry_addr, sv->sv_pagesize);
free(path, M_TEMP);
if (error == 0)
interp = NULL;
}
if (interp != NULL) {
error = __elfN(load_file)(imgp->proc, interp, &addr,
&imgp->entry_addr, sv->sv_pagesize);
if (error != 0) {
uprintf("ELF interpreter %s not found\n", interp);
goto fail;
}
}
/*

View File

@ -80,15 +80,30 @@ static Elf32_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD,
EM_PPC,
"FreeBSD",
"",
NULL,
"/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec
&elf32_freebsd_sysvec,
NULL,
};
SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info);
static Elf32_Brandinfo freebsd_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_PPC,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec,
NULL,
};
SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_oinfo);
/* Process one elf relocation with addend. */
static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

View File

@ -91,15 +91,30 @@ static Elf64_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD,
EM_SPARCV9,
"FreeBSD",
"",
NULL,
"/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info);
static Elf64_Brandinfo freebsd_brand_oinfo = {
ELFOSABI_FREEBSD,
EM_SPARCV9,
"FreeBSD",
NULL,
"/usr/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec,
NULL,
};
SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_oinfo);
/*
* The following table holds for each relocation type:
* - the width in bits of the memory location the relocation

View File

@ -61,13 +61,14 @@ typedef struct {
const char *compat_3_brand; /* pre Binutils 2.10 method (FBSD 3) */
const char *emul_path;
const char *interp_path;
struct sysentvec *sysvec;
struct sysentvec *sysvec;
const char *interp_newpath;
} __ElfN(Brandinfo);
__ElfType(Auxargs);
__ElfType(Brandinfo);
#define MAX_BRANDS 8
#define MAX_BRANDS 8
int __elfN(brand_inuse)(Elf_Brandinfo *entry);
int __elfN(insert_brand_entry)(Elf_Brandinfo *entry);