Index: libexec/rtld-elf/aarch64/rtld_machdep.h =================================================================== --- libexec/rtld-elf/aarch64/rtld_machdep.h +++ libexec/rtld-elf/aarch64/rtld_machdep.h @@ -80,4 +80,6 @@ #define RTLD_DEFAULT_STACK_PF_EXEC PF_X #define RTLD_DEFAULT_STACK_EXEC PROT_EXEC +#define md_abi_variant_hook(x) + #endif Index: libexec/rtld-elf/amd64/rtld_machdep.h =================================================================== --- libexec/rtld-elf/amd64/rtld_machdep.h +++ libexec/rtld-elf/amd64/rtld_machdep.h @@ -79,4 +79,6 @@ #define RTLD_DEFAULT_STACK_PF_EXEC PF_X #define RTLD_DEFAULT_STACK_EXEC PROT_EXEC +#define md_abi_variant_hook(x) + #endif Index: libexec/rtld-elf/arm/reloc.c =================================================================== --- libexec/rtld-elf/arm/reloc.c +++ libexec/rtld-elf/arm/reloc.c @@ -15,6 +15,42 @@ #include "debug.h" #include "rtld.h" +#include "paths.h" + +void +arm_abi_variant_hook(Elf_Auxinfo **aux_info) +{ + Elf_Word ehdr; + + /* + * If we're running an old kenrel that doesn't provide any data fail + * safe by doing nothing. + */ + if (aux_info[AT_EHDRFLAGS] == NULL) + return; + ehdr = aux_info[AT_EHDRFLAGS]->a_un.a_val; + + /* + * Hard float binaries are the default, and use the default paths and + * such. + */ + if (ehdr & EF_ARM_VFP_FLOAT) + return; + + /* + * This is a soft float binary. We need to use the soft float + * settings. For the moment, the standard library path includes the hard + * float paths as well. When upgrading, we need to execute the wrong + * kind of binary until we've installed the new binaries. We could go + * off whether or not /lib/soft exists, but the simplicity of having it + * in the path wins. + */ + ld_path_elf_hints = _PATH_SOFT_ELF_HINTS; + ld_path_libmap_conf = _PATH_SOFT_LIBMAP_CONF; + ld_path_rtld = _PATH_SOFT_RTLD; + ld_standard_library_path = SOFT_STANDARD_LIBRARY_PATH; + ld_env_prefix = LD_SOFT_; +} void init_pltgot(Obj_Entry *obj) Index: libexec/rtld-elf/arm/rtld_machdep.h =================================================================== --- libexec/rtld-elf/arm/rtld_machdep.h +++ libexec/rtld-elf/arm/rtld_machdep.h @@ -75,4 +75,9 @@ #define RTLD_DEFAULT_STACK_PF_EXEC PF_X #define RTLD_DEFAULT_STACK_EXEC PROT_EXEC +extern void arm_abi_variant_hook(Elf_Auxinfo **); + +#define md_abi_variant_hook(x) arm_abi_variant_hook(x) +#define RTLD_VARIANT_ENV_NAMES + #endif Index: libexec/rtld-elf/i386/rtld_machdep.h =================================================================== --- libexec/rtld-elf/i386/rtld_machdep.h +++ libexec/rtld-elf/i386/rtld_machdep.h @@ -80,4 +80,6 @@ #define RTLD_DEFAULT_STACK_PF_EXEC PF_X #define RTLD_DEFAULT_STACK_EXEC PROT_EXEC +#define md_abi_variant_hook(x) + #endif Index: libexec/rtld-elf/libmap.c =================================================================== --- libexec/rtld-elf/libmap.c +++ libexec/rtld-elf/libmap.c @@ -16,15 +16,7 @@ #include "debug.h" #include "rtld.h" #include "libmap.h" - -#ifndef _PATH_LIBMAP_CONF -#define _PATH_LIBMAP_CONF "/etc/libmap.conf" -#endif - -#ifdef COMPAT_32BIT -#undef _PATH_LIBMAP_CONF -#define _PATH_LIBMAP_CONF "/etc/libmap32.conf" -#endif +#include "paths.h" TAILQ_HEAD(lm_list, lm); struct lm { @@ -76,7 +68,7 @@ dbg("lm_init(\"%s\")", libmap_override); TAILQ_INIT(&lmp_head); - lmc_parse_file(_PATH_LIBMAP_CONF); + lmc_parse_file(ld_path_libmap_conf); if (libmap_override) { /* Index: libexec/rtld-elf/malloc.c =================================================================== --- libexec/rtld-elf/malloc.c +++ libexec/rtld-elf/malloc.c @@ -45,7 +45,6 @@ #include #include -#include #include #include #include Index: libexec/rtld-elf/mips/rtld_machdep.h =================================================================== --- libexec/rtld-elf/mips/rtld_machdep.h +++ libexec/rtld-elf/mips/rtld_machdep.h @@ -75,4 +75,6 @@ #define RTLD_DEFAULT_STACK_PF_EXEC PF_X #define RTLD_DEFAULT_STACK_EXEC PROT_EXEC +#define md_abi_variant_hook(x) + #endif Index: libexec/rtld-elf/paths.h =================================================================== --- /dev/null +++ libexec/rtld-elf/paths.h @@ -0,0 +1,74 @@ +/*- + * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra. + * Copyright 2003 Alexander Kabaev . + * Copyright 2009-2012 Konstantin Belousov . + * Copyright 2012 John Marino . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef PATHS_H +#define PATHS_H + +#ifdef COMPAT_32BIT +#define _PATH_ELF_HINTS "/var/run/ld-elf32.so.hints" +#define _PATH_LIBMAP_CONF "/etc/libmap32.conf" +#define _PATH_RTLD "/libexec/ld-elf32.so.1" +#define STANDARD_LIBRARY_PATH "/lib32:/usr/lib32" +#define LD_ "LD_32_" +#endif + +#ifndef _PATH_ELF_HINTS +#define _PATH_ELF_HINTS "/var/run/ld-elf.so.hints" +#endif + +#ifndef _PATH_LIBMAP_CONF +#define _PATH_LIBMAP_CONF "/etc/libmap.conf" +#endif + +#ifndef _PATH_RTLD +#define _PATH_RTLD "/libexec/ld-elf.so.1" +#endif + +#ifndef STANDARD_LIBRARY_PATH +#define STANDARD_LIBRARY_PATH "/lib:/usr/lib" +#endif + +#ifndef LD_ +#define LD_ "LD_" +#endif + +#define _PATH_SOFT_ELF_HINTS "/var/run/ld-elf-soft.so.hints" +#define _PATH_SOFT_LIBMAP_CONF "/etc/libmap-soft.conf" +#define _PATH_SOFT_RTLD "/libexec/ld-elf-soft.so.1" +#define SOFT_STANDARD_LIBRARY_PATH "/lib/soft:/usr/lib/soft:/lib:/usr/lib" +#define LD_SOFT_ "LD_SOFT_" + +extern char *ld_path_elf_hints; +extern char *ld_path_libmap_conf; +extern char *ld_path_rtld; +extern char *ld_standard_library_path; +extern char *ld_env_prefix; + +#endif /* PATHS_H */ Index: libexec/rtld-elf/powerpc/rtld_machdep.h =================================================================== --- libexec/rtld-elf/powerpc/rtld_machdep.h +++ libexec/rtld-elf/powerpc/rtld_machdep.h @@ -90,4 +90,6 @@ #define RTLD_DEFAULT_STACK_PF_EXEC PF_X #define RTLD_DEFAULT_STACK_EXEC PROT_EXEC +#define md_abi_variant_hook(x) + #endif Index: libexec/rtld-elf/powerpc64/rtld_machdep.h =================================================================== --- libexec/rtld-elf/powerpc64/rtld_machdep.h +++ libexec/rtld-elf/powerpc64/rtld_machdep.h @@ -82,4 +82,6 @@ #define RTLD_DEFAULT_STACK_PF_EXEC PF_X #define RTLD_DEFAULT_STACK_EXEC PROT_EXEC +#define md_abi_variant_hook(x) + #endif Index: libexec/rtld-elf/rtld.h =================================================================== --- libexec/rtld-elf/rtld.h +++ libexec/rtld-elf/rtld.h @@ -41,22 +41,6 @@ #include "rtld_lock.h" #include "rtld_machdep.h" -#ifdef COMPAT_32BIT -#undef STANDARD_LIBRARY_PATH -#undef _PATH_ELF_HINTS -#define _PATH_ELF_HINTS "/var/run/ld-elf32.so.hints" -/* For running 32 bit binaries */ -#define STANDARD_LIBRARY_PATH "/lib32:/usr/lib32" -#define LD_ "LD_32_" -#endif - -#ifndef STANDARD_LIBRARY_PATH -#define STANDARD_LIBRARY_PATH "/lib:/usr/lib" -#endif -#ifndef LD_ -#define LD_ "LD_" -#endif - #define NEW(type) ((type *) xmalloc(sizeof(type))) #define CNEW(type) ((type *) xcalloc(1, sizeof(type))) Index: libexec/rtld-elf/rtld.c =================================================================== --- libexec/rtld-elf/rtld.c +++ libexec/rtld-elf/rtld.c @@ -54,18 +54,13 @@ #include #include "debug.h" +#include "paths.h" #include "rtld.h" #include "libmap.h" #include "rtld_tls.h" #include "rtld_printf.h" #include "notes.h" -#ifndef COMPAT_32BIT -#define PATH_RTLD "/libexec/ld-elf.so.1" -#else -#define PATH_RTLD "/libexec/ld-elf32.so.1" -#endif - /* Types. */ typedef void (*func_ptr_type)(); typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg); @@ -260,6 +255,15 @@ bool ld_library_path_rpath = false; /* + * Globals for path names, and such + */ +char *ld_path_elf_hints = _PATH_ELF_HINTS; +char *ld_path_libmap_conf = _PATH_LIBMAP_CONF; +char *ld_path_rtld = _PATH_RTLD; +char *ld_standard_library_path = STANDARD_LIBRARY_PATH; +char *ld_env_prefix = LD_; + +/* * Fill in a DoneList with an allocation large enough to hold all of * the currently-loaded objects. Keep this as a macro since it calls * alloca and we want that to occur within the scope of the caller. @@ -319,6 +323,24 @@ utrace(&ut, sizeof(ut)); } +#ifdef RTLD_VARIANT_ENV_NAMES +/* + * construct the env variable based on the type of binary that's + * running. + */ +static inline const char * +_LD(const char *var) +{ + static char buffer[128]; + + strlcpy(buffer, ld_env_prefix, sizeof(buffer)); + strlcat(buffer, var, sizeof(buffer)); + return buffer; +} +#else +#define _LD(x) LD_ x +#endif + /* * Main entry point for dynamic linking. The first argument is the * stack pointer. The stack is expected to be laid out as described @@ -413,7 +435,9 @@ trust = !issetugid(); - ld_bind_now = getenv(LD_ "BIND_NOW"); + md_abi_variant_hook(aux_info); + + ld_bind_now = getenv(_LD("BIND_NOW")); /* * If the process is tainted, then we un-set the dangerous environment * variables. The process will be marked as tainted until setuid(2) @@ -421,24 +445,24 @@ * future processes to honor the potentially un-safe variables. */ if (!trust) { - if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") || - unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBRARY_PATH_FDS") || - unsetenv(LD_ "LIBMAP_DISABLE") || - unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH") || - unsetenv(LD_ "LOADFLTR") || unsetenv(LD_ "LIBRARY_PATH_RPATH")) { + if (unsetenv(_LD("PRELOAD")) || unsetenv(_LD("LIBMAP")) || + unsetenv(_LD("LIBRARY_PATH")) || unsetenv(_LD("LIBRARY_PATH_FDS")) || + unsetenv(_LD("LIBMAP_DISABLE")) || + unsetenv(_LD("DEBUG")) || unsetenv(_LD("ELF_HINTS_PATH")) || + unsetenv(_LD("LOADFLTR")) || unsetenv(_LD("LIBRARY_PATH_RPATH"))) { _rtld_error("environment corrupt; aborting"); rtld_die(); } } - ld_debug = getenv(LD_ "DEBUG"); - libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL; - libmap_override = getenv(LD_ "LIBMAP"); - ld_library_path = getenv(LD_ "LIBRARY_PATH"); - ld_library_dirs = getenv(LD_ "LIBRARY_PATH_FDS"); - ld_preload = getenv(LD_ "PRELOAD"); - ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH"); - ld_loadfltr = getenv(LD_ "LOADFLTR") != NULL; - library_path_rpath = getenv(LD_ "LIBRARY_PATH_RPATH"); + ld_debug = getenv(_LD("DEBUG")); + libmap_disable = getenv(_LD("LIBMAP_DISABLE")) != NULL; + libmap_override = getenv(_LD("LIBMAP")); + ld_library_path = getenv(_LD("LIBRARY_PATH")); + ld_library_dirs = getenv(_LD("LIBRARY_PATH_FDS")); + ld_preload = getenv(_LD("PRELOAD")); + ld_elf_hints_path = getenv(_LD("ELF_HINTS_PATH")); + ld_loadfltr = getenv(_LD("LOADFLTR")) != NULL; + library_path_rpath = getenv(_LD("LIBRARY_PATH_RPATH")); if (library_path_rpath != NULL) { if (library_path_rpath[0] == 'y' || library_path_rpath[0] == 'Y' || @@ -450,11 +474,11 @@ dangerous_ld_env = libmap_disable || (libmap_override != NULL) || (ld_library_path != NULL) || (ld_preload != NULL) || (ld_elf_hints_path != NULL) || ld_loadfltr; - ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS"); - ld_utrace = getenv(LD_ "UTRACE"); + ld_tracing = getenv(_LD("TRACE_LOADED_OBJECTS")); + ld_utrace = getenv(_LD("UTRACE")); if ((ld_elf_hints_path == NULL) || strlen(ld_elf_hints_path) == 0) - ld_elf_hints_path = _PATH_ELF_HINTS; + ld_elf_hints_path = ld_path_elf_hints; if (ld_debug != NULL && *ld_debug != '\0') debug = 1; @@ -588,7 +612,7 @@ exit(0); } - if (getenv(LD_ "DUMP_REL_PRE") != NULL) { + if (getenv(_LD("DUMP_REL_PRE")) != NULL) { dump_relocations(obj_main); exit (0); } @@ -616,7 +640,7 @@ if (do_copy_relocations(obj_main) == -1) rtld_die(); - if (getenv(LD_ "DUMP_REL_POST") != NULL) { + if (getenv(_LD("DUMP_REL_POST")) != NULL) { dump_relocations(obj_main); exit (0); } @@ -1511,7 +1535,7 @@ (pathname = search_library_path(name, refobj->rpath)) != NULL) || (pathname = search_library_pathfds(name, ld_library_dirs, fdp)) != NULL || (pathname = search_library_path(name, gethints(false))) != NULL || - (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL) + (pathname = search_library_path(name, ld_standard_library_path)) != NULL) return (pathname); } else { nodeflib = objgiven ? refobj->z_nodeflib : false; @@ -1525,7 +1549,7 @@ (pathname = search_library_pathfds(name, ld_library_dirs, fdp)) != NULL || (pathname = search_library_path(name, gethints(nodeflib))) != NULL || (objgiven && !nodeflib && - (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)) + (pathname = search_library_path(name, ld_standard_library_path)) != NULL)) return (pathname); } @@ -1695,7 +1719,7 @@ hargs.request = RTLD_DI_SERINFOSIZE; hargs.serinfo = &hmeta; - path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs); + path_enumerate(ld_standard_library_path, fill_search_info, &sargs); path_enumerate(p, fill_search_info, &hargs); SLPinfo = xmalloc(smeta.dls_size); @@ -1714,7 +1738,7 @@ hargs.serpath = &hintinfo->dls_serpath[0]; hargs.strspace = (char *)&hintinfo->dls_serpath[hmeta.dls_cnt]; - path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs); + path_enumerate(ld_standard_library_path, fill_search_info, &sargs); path_enumerate(p, fill_search_info, &hargs); /* @@ -1892,7 +1916,7 @@ digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname, dyn_runpath); /* Replace the path with a dynamically allocated copy. */ - obj_rtld.path = xstrdup(PATH_RTLD); + obj_rtld.path = xstrdup(ld_path_rtld); r_debug.r_brk = r_debug_state; r_debug.r_state = RT_CONSISTENT; @@ -3506,7 +3530,7 @@ path_enumerate(obj->runpath, fill_search_info, &args); path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args); if (!obj->z_nodeflib) - path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args); + path_enumerate(ld_standard_library_path, fill_search_info, &args); if (request == RTLD_DI_SERINFOSIZE) { @@ -3544,7 +3568,7 @@ args.flags = LA_SER_DEFAULT; if (!obj->z_nodeflib && - path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL) + path_enumerate(ld_standard_library_path, fill_search_info, &args) != NULL) return (-1); return (0); } @@ -4168,16 +4192,16 @@ char *fmt1, *fmt2, *fmt, *main_local, *list_containers; int c; - if ((main_local = getenv(LD_ "TRACE_LOADED_OBJECTS_PROGNAME")) == NULL) + if ((main_local = getenv(_LD("TRACE_LOADED_OBJECTS_PROGNAME"))) == NULL) main_local = ""; - if ((fmt1 = getenv(LD_ "TRACE_LOADED_OBJECTS_FMT1")) == NULL) + if ((fmt1 = getenv(_LD("TRACE_LOADED_OBJECTS_FMT1"))) == NULL) fmt1 = "\t%o => %p (%x)\n"; - if ((fmt2 = getenv(LD_ "TRACE_LOADED_OBJECTS_FMT2")) == NULL) + if ((fmt2 = getenv(_LD("TRACE_LOADED_OBJECTS_FMT2"))) == NULL) fmt2 = "\t%o (%x)\n"; - list_containers = getenv(LD_ "TRACE_LOADED_OBJECTS_ALL"); + list_containers = getenv(_LD("TRACE_LOADED_OBJECTS_ALL")); for (; obj; obj = obj->next) { Needed_Entry *needed; Index: libexec/rtld-elf/sparc64/rtld_machdep.h =================================================================== --- libexec/rtld-elf/sparc64/rtld_machdep.h +++ libexec/rtld-elf/sparc64/rtld_machdep.h @@ -71,4 +71,6 @@ #define RTLD_DEFAULT_STACK_PF_EXEC 0 #define RTLD_DEFAULT_STACK_EXEC 0 +#define md_abi_variant_hook(x) + #endif Index: sys/arm/arm/exception.S =================================================================== --- sys/arm/arm/exception.S +++ sys/arm/arm/exception.S @@ -49,7 +49,6 @@ #include "assym.s" #include "opt_kdtrace.h" -#include #include #include #include @@ -81,7 +80,7 @@ * NOTE: r13 and r14 are stored separately as a work around for the * SA110 rev 2 STM^ bug */ -#if __ARM_ARCH < 6 +#ifdef ARM_TP_ADDRESS #define PUSHFRAME \ sub sp, sp, #4; /* Align the stack */ \ str lr, [sp, #-4]!; /* Push the return address */ \ @@ -115,7 +114,7 @@ * Since the current mode is used, the SVC lr field is ignored. */ -#if __ARM_ARCH < 6 +#ifdef ARM_TP_ADDRESS #define PULLFRAME \ ldr r0, [sp], #4; /* Get the SPSR from stack */ \ msr spsr_fsxc, r0; \ @@ -146,7 +145,7 @@ * NOTE: r13 and r14 are stored separately as a work around for the * SA110 rev 2 STM^ bug */ -#if __ARM_ARCH < 6 +#ifdef ARM_TP_ADDRESS #define PUSHFRAMEINSVC \ stmdb sp, {r0-r3}; /* Save 4 registers */ \ mov r0, lr; /* Save xxx32 r14 */ \ @@ -219,7 +218,7 @@ * exit. */ -#if __ARM_ARCH < 6 +#ifdef ARM_TP_ADDRESS #define PULLFRAMEFROMSVCANDEXIT \ ldr r0, [sp], #4; /* Get the SPSR from stack */ \ msr spsr_fsxc, r0; /* restore SPSR */ \ @@ -469,4 +468,9 @@ */ .global _C_LABEL(fiq_nullhandler_code), _C_LABEL(fiq_nullhandler_size) -_C_LABEL(fiq_nullhandler_c \ No newline at end of file +_C_LABEL(fiq_nullhandler_code): + .word .fiqv +_C_LABEL(fiq_nullhandler_size): + .word 4 + +