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 2003-12-23 02:42:39 +00:00
parent f0bdb04cd5
commit d2892b0634
12 changed files with 150 additions and 35 deletions

View File

@ -81,15 +81,31 @@ static Elf64_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD, ELFOSABI_FREEBSD,
EM_ALPHA, EM_ALPHA,
"FreeBSD", "FreeBSD",
"", NULL,
"/libexec/ld-elf.so.1", "/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec &elf64_freebsd_sysvec,
NULL,
}; };
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry, (sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info); &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. */ /* Process one elf relocation with addend. */
static int static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) 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", "Linux",
"/compat/linux", "/compat/linux",
"/lib/ld-linux.so.1", "/lib/ld-linux.so.1",
&elf_linux_sysvec &elf_linux_sysvec,
NULL,
}; };
static Elf64_Brandinfo linux_glibc2brand = { static Elf64_Brandinfo linux_glibc2brand = {
@ -219,7 +220,8 @@ static Elf64_Brandinfo linux_glibc2brand = {
"Linux", "Linux",
"/compat/linux", "/compat/linux",
"/lib/ld-linux.so.2", "/lib/ld-linux.so.2",
&elf_linux_sysvec &elf_linux_sysvec,
NULL,
}; };
Elf64_Brandinfo *linux_brandlist[] = { Elf64_Brandinfo *linux_brandlist[] = {

View File

@ -78,15 +78,30 @@ static Elf64_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD, ELFOSABI_FREEBSD,
EM_X86_64, EM_X86_64,
"FreeBSD", "FreeBSD",
"", NULL,
"/libexec/ld-elf.so.1", "/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec &elf64_freebsd_sysvec,
NULL,
}; };
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry, (sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info); &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. */ /* Process one elf relocation with addend. */
static int static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) 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 = { static Elf32_Brandinfo ia32_brand_info = {
ELFOSABI_FREEBSD, ELFOSABI_FREEBSD,
EM_386, EM_386,
"FreeBSD", "FreeBSD",
"/compat/ia32", NULL,
"/usr/libexec/ld-elf.so.1", "/libexec/ld-elf.so.1",
&ia32_freebsd_sysvec &ia32_freebsd_sysvec,
"/libexec/ld-elf-32.so.1",
}; };
SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry, (sysinit_cfunc_t) elf32_insert_brand_entry,
&ia32_brand_info); &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 */ /* XXX may be freebsd32 MI */
static register_t * static register_t *
ia32_copyout_strings(struct image_params *imgp) ia32_copyout_strings(struct image_params *imgp)

View File

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

View File

@ -78,15 +78,30 @@ static Elf32_Brandinfo freebsd_brand_info = {
ELFOSABI_FREEBSD, ELFOSABI_FREEBSD,
EM_386, EM_386,
"FreeBSD", "FreeBSD",
"", NULL,
"/libexec/ld-elf.so.1", "/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec &elf32_freebsd_sysvec,
NULL,
}; };
SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry, (sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info); &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. */ /* Process one elf relocation with addend. */
static int static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) 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", "Linux",
"/compat/linux", "/compat/linux",
"/lib/ld-linux.so.1", "/lib/ld-linux.so.1",
&elf_linux_sysvec &elf_linux_sysvec,
NULL,
}; };
static Elf32_Brandinfo linux_glibc2brand = { static Elf32_Brandinfo linux_glibc2brand = {
@ -908,7 +909,8 @@ static Elf32_Brandinfo linux_glibc2brand = {
"Linux", "Linux",
"/compat/linux", "/compat/linux",
"/lib/ld-linux.so.2", "/lib/ld-linux.so.2",
&elf_linux_sysvec &elf_linux_sysvec,
NULL,
}; };
Elf32_Brandinfo *linux_brandlist[] = { Elf32_Brandinfo *linux_brandlist[] = {

View File

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

View File

@ -708,6 +708,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
goto fail; goto fail;
} }
sv = brand_info->sysvec; sv = brand_info->sysvec;
if (interp != NULL && brand_info->interp_newpath != NULL)
interp = brand_info->interp_newpath;
if ((error = exec_extract_strings(imgp)) != 0) if ((error = exec_extract_strings(imgp)) != 0)
goto fail; goto fail;
@ -818,21 +820,24 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
imgp->entry_addr = entry; imgp->entry_addr = entry;
imgp->proc->p_sysent = sv; 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); path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
snprintf(path, MAXPATHLEN, "%s%s", brand_info->emul_path, snprintf(path, MAXPATHLEN, "%s%s", brand_info->emul_path,
interp); interp);
if ((error = __elfN(load_file)(imgp->proc, path, &addr, error = __elfN(load_file)(imgp->proc, path, &addr,
&imgp->entry_addr, sv->sv_pagesize)) != 0) { &imgp->entry_addr, sv->sv_pagesize);
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;
}
}
free(path, M_TEMP); 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, ELFOSABI_FREEBSD,
EM_PPC, EM_PPC,
"FreeBSD", "FreeBSD",
"", NULL,
"/libexec/ld-elf.so.1", "/libexec/ld-elf.so.1",
&elf32_freebsd_sysvec &elf32_freebsd_sysvec,
NULL,
}; };
SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf32_insert_brand_entry, (sysinit_cfunc_t) elf32_insert_brand_entry,
&freebsd_brand_info); &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. */ /* Process one elf relocation with addend. */
static int static int
elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) 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, ELFOSABI_FREEBSD,
EM_SPARCV9, EM_SPARCV9,
"FreeBSD", "FreeBSD",
"", NULL,
"/libexec/ld-elf.so.1", "/libexec/ld-elf.so.1",
&elf64_freebsd_sysvec &elf64_freebsd_sysvec,
NULL,
}; };
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
(sysinit_cfunc_t) elf64_insert_brand_entry, (sysinit_cfunc_t) elf64_insert_brand_entry,
&freebsd_brand_info); &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 following table holds for each relocation type:
* - the width in bits of the memory location the relocation * - 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 *compat_3_brand; /* pre Binutils 2.10 method (FBSD 3) */
const char *emul_path; const char *emul_path;
const char *interp_path; const char *interp_path;
struct sysentvec *sysvec; struct sysentvec *sysvec;
const char *interp_newpath;
} __ElfN(Brandinfo); } __ElfN(Brandinfo);
__ElfType(Auxargs); __ElfType(Auxargs);
__ElfType(Brandinfo); __ElfType(Brandinfo);
#define MAX_BRANDS 8 #define MAX_BRANDS 8
int __elfN(brand_inuse)(Elf_Brandinfo *entry); int __elfN(brand_inuse)(Elf_Brandinfo *entry);
int __elfN(insert_brand_entry)(Elf_Brandinfo *entry); int __elfN(insert_brand_entry)(Elf_Brandinfo *entry);