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