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:
parent
f0bdb04cd5
commit
d2892b0634
@ -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)
|
||||
|
@ -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[] = {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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";
|
||||
|
@ -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)
|
||||
|
@ -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[] = {
|
||||
|
@ -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[];
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user