diff options
author | peter <peter@FreeBSD.org> | 2003-12-23 02:42:39 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2003-12-23 02:42:39 +0000 |
commit | 998b79089fba1b775a2a89f2c6d325d97dd21ead (patch) | |
tree | 1907b96bc90f9f9f4007eae1193fdfe639edb170 | |
parent | 47e1d21299b39eba3b43f8b5986b655cadf52175 (diff) | |
download | FreeBSD-src-998b79089fba1b775a2a89f2c6d325d97dd21ead.zip FreeBSD-src-998b79089fba1b775a2a89f2c6d325d97dd21ead.tar.gz |
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.
-rw-r--r-- | sys/alpha/alpha/elf_machdep.c | 20 | ||||
-rw-r--r-- | sys/alpha/linux/linux_sysvec.c | 6 | ||||
-rw-r--r-- | sys/amd64/amd64/elf_machdep.c | 19 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_sysvec.c | 23 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_sysvec.c | 3 | ||||
-rw-r--r-- | sys/i386/i386/elf_machdep.c | 19 | ||||
-rw-r--r-- | sys/i386/linux/linux_sysvec.c | 6 | ||||
-rw-r--r-- | sys/ia64/ia64/elf_machdep.c | 19 | ||||
-rw-r--r-- | sys/kern/imgact_elf.c | 27 | ||||
-rw-r--r-- | sys/powerpc/powerpc/elf_machdep.c | 19 | ||||
-rw-r--r-- | sys/sparc64/sparc64/elf_machdep.c | 19 | ||||
-rw-r--r-- | sys/sys/imgact_elf.h | 5 |
12 files changed, 150 insertions, 35 deletions
diff --git a/sys/alpha/alpha/elf_machdep.c b/sys/alpha/alpha/elf_machdep.c index c76f4d91..794328c 100644 --- a/sys/alpha/alpha/elf_machdep.c +++ b/sys/alpha/alpha/elf_machdep.c @@ -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) diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c index 09cbadd..add35a3 100644 --- a/sys/alpha/linux/linux_sysvec.c +++ b/sys/alpha/linux/linux_sysvec.c @@ -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[] = { diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index 0d80b42..04d81aa 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -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) diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index 67b7db3..0b2d777 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -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) diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c index 61efd49..e312d6a 100644 --- a/sys/compat/svr4/svr4_sysvec.c +++ b/sys/compat/svr4/svr4_sysvec.c @@ -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"; diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index 48cb238..8bed56a 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -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) diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index fc57c1f..e9542cc 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -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[] = { diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index dbb4bf3..1c7f1d2 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -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[]; diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 330437a..ff11078 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -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; + } } /* diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index eab70db..1a4486f 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c @@ -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) diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c index bb2c185..d9d2974 100644 --- a/sys/sparc64/sparc64/elf_machdep.c +++ b/sys/sparc64/sparc64/elf_machdep.c @@ -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 diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h index 93974f3..d69abe6 100644 --- a/sys/sys/imgact_elf.h +++ b/sys/sys/imgact_elf.h @@ -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); |