134192Sjdp/*- 255687Sjdp * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra. 3110804Skan * Copyright 2003 Alexander Kabaev <kan@FreeBSD.ORG>. 4235396Skib * Copyright 2009-2012 Konstantin Belousov <kib@FreeBSD.ORG>. 5235396Skib * Copyright 2012 John Marino <draco@marino.st>. 634192Sjdp * All rights reserved. 734192Sjdp * 834192Sjdp * Redistribution and use in source and binary forms, with or without 934192Sjdp * modification, are permitted provided that the following conditions 1034192Sjdp * are met: 1134192Sjdp * 1. Redistributions of source code must retain the above copyright 1234192Sjdp * notice, this list of conditions and the following disclaimer. 1334192Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1434192Sjdp * notice, this list of conditions and the following disclaimer in the 1534192Sjdp * documentation and/or other materials provided with the distribution. 1634192Sjdp * 1734192Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1834192Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1934192Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2034192Sjdp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2134192Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2234192Sjdp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2334192Sjdp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2434192Sjdp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2534192Sjdp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2634192Sjdp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2734192Sjdp * 2850476Speter * $FreeBSD$ 2934192Sjdp */ 3034192Sjdp 3134192Sjdp/* 3234192Sjdp * Dynamic linker for ELF. 3334192Sjdp * 3434192Sjdp * John Polstra <jdp@polstra.com>. 3534192Sjdp */ 3634192Sjdp 3734192Sjdp#ifndef __GNUC__ 3834192Sjdp#error "GCC is needed to compile this file" 3934192Sjdp#endif 4034192Sjdp 4134192Sjdp#include <sys/param.h> 42144062Scperciva#include <sys/mount.h> 4334192Sjdp#include <sys/mman.h> 4450609Sjdp#include <sys/stat.h> 45211413Skib#include <sys/sysctl.h> 46165916Sjhb#include <sys/uio.h> 47189959Skib#include <sys/utsname.h> 48165916Sjhb#include <sys/ktrace.h> 4934192Sjdp 5034192Sjdp#include <dlfcn.h> 5134192Sjdp#include <err.h> 5234192Sjdp#include <errno.h> 5334192Sjdp#include <fcntl.h> 5434192Sjdp#include <stdarg.h> 5534192Sjdp#include <stdio.h> 5634192Sjdp#include <stdlib.h> 5734192Sjdp#include <string.h> 5834192Sjdp#include <unistd.h> 5934192Sjdp 6034192Sjdp#include "debug.h" 6134192Sjdp#include "rtld.h" 62113229Smdodd#include "libmap.h" 63133063Sdfr#include "rtld_tls.h" 64225152Skib#include "rtld_printf.h" 65233694Skib#include "notes.h" 6634192Sjdp 67127250Speter#ifndef COMPAT_32BIT 68119014Sgordon#define PATH_RTLD "/libexec/ld-elf.so.1" 69127250Speter#else 70127250Speter#define PATH_RTLD "/libexec/ld-elf32.so.1" 71127250Speter#endif 7234192Sjdp 7334192Sjdp/* Types. */ 7434192Sjdptypedef void (*func_ptr_type)(); 75110804Skantypedef void * (*path_enum_proc) (const char *path, size_t len, void *arg); 7634192Sjdp 7762801Sjdp/* 7834192Sjdp * Function declarations. 7934192Sjdp */ 8045890Sjdpstatic const char *basename(const char *); 81153515Skanstatic void die(void) __dead2; 82211413Skibstatic void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **, 83240308Skib const Elf_Dyn **, const Elf_Dyn **); 84240308Skibstatic void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *, 85240308Skib const Elf_Dyn *); 8693610Sjakestatic void digest_dynamic(Obj_Entry *, int); 8748871Sjdpstatic Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *); 8834192Sjdpstatic Obj_Entry *dlcheck(void *); 89230410Skibstatic Obj_Entry *dlopen_object(const char *name, int fd, Obj_Entry *refobj, 90234454Skib int lo_flags, int mode, RtldLockState *lockstate); 91199829Skibstatic Obj_Entry *do_load_object(int, const char *, char *, struct stat *, int); 92110804Skanstatic int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *); 9366056Sjdpstatic bool donelist_check(DoneList *, const Obj_Entry *); 9470677Sjdpstatic void errmsg_restore(char *); 9570677Sjdpstatic char *errmsg_save(void); 96110804Skanstatic void *fill_search_info(const char *, size_t, void *); 9734192Sjdpstatic char *find_library(const char *, const Obj_Entry *); 98240308Skibstatic const char *gethints(bool); 9950608Sjdpstatic void init_dag(Obj_Entry *); 100211413Skibstatic void init_rtld(caddr_t, Elf_Auxinfo **); 101162449Sjkimstatic void initlist_add_neededs(Needed_Entry *, Objlist *); 102162449Sjkimstatic void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *); 10338739Sjdpstatic void linkmap_add(Obj_Entry *); 10438739Sjdpstatic void linkmap_delete(Obj_Entry *); 105216695Skibstatic void load_filtees(Obj_Entry *, int flags, RtldLockState *); 106216695Skibstatic void unload_filtees(Obj_Entry *); 107199829Skibstatic int load_needed_objects(Obj_Entry *, int); 10839551Sjdpstatic int load_preload_objects(void); 109230410Skibstatic Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int); 110217223Skibstatic void map_stacks_exec(RtldLockState *); 11134192Sjdpstatic Obj_Entry *obj_from_addr(const void *); 112216695Skibstatic void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *); 113216695Skibstatic void objlist_call_init(Objlist *, RtldLockState *); 11463870Sjdpstatic void objlist_clear(Objlist *); 11550608Sjdpstatic Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *); 11663870Sjdpstatic void objlist_init(Objlist *); 11763870Sjdpstatic void objlist_push_head(Objlist *, Obj_Entry *); 11863870Sjdpstatic void objlist_push_tail(Objlist *, Obj_Entry *); 119256436Skibstatic void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *); 12050608Sjdpstatic void objlist_remove(Objlist *, Obj_Entry *); 121110804Skanstatic void *path_enumerate(const char *, path_enum_proc, void *); 122238133Skibstatic int relocate_object_dag(Obj_Entry *root, bool bind_now, 123238133Skib Obj_Entry *rtldobj, int flags, RtldLockState *lockstate); 124238133Skibstatic int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj, 125238133Skib int flags, RtldLockState *lockstate); 126233831Skibstatic int relocate_objects(Obj_Entry *, bool, Obj_Entry *, int, 127233831Skib RtldLockState *); 128229503Skibstatic int resolve_objects_ifunc(Obj_Entry *first, bool bind_now, 129233831Skib int flags, RtldLockState *lockstate); 130110804Skanstatic int rtld_dirname(const char *, char *); 131189959Skibstatic int rtld_dirname_abs(const char *, char *); 132230410Skibstatic void *rtld_dlopen(const char *name, int fd, int mode); 13334192Sjdpstatic void rtld_exit(void); 13434192Sjdpstatic char *search_library_path(const char *, const char *); 135217223Skibstatic const void **get_program_var_addr(const char *, RtldLockState *); 13645890Sjdpstatic void set_program_var(const char *, const void *); 137216695Skibstatic int symlook_default(SymLook *, const Obj_Entry *refobj); 138217223Skibstatic int symlook_global(SymLook *, DoneList *); 139216695Skibstatic void symlook_init_from_req(SymLook *, const SymLook *); 140216695Skibstatic int symlook_list(SymLook *, const Objlist *, DoneList *); 141216695Skibstatic int symlook_needed(SymLook *, const Needed_Entry *, DoneList *); 142235396Skibstatic int symlook_obj1_sysv(SymLook *, const Obj_Entry *); 143235396Skibstatic int symlook_obj1_gnu(SymLook *, const Obj_Entry *); 144162449Sjkimstatic void trace_loaded_objects(Obj_Entry *); 145111054Skanstatic void unlink_object(Obj_Entry *); 14655687Sjdpstatic void unload_object(Obj_Entry *); 14750608Sjdpstatic void unref_dag(Obj_Entry *); 148114826Skanstatic void ref_dag(Obj_Entry *); 149250040Skibstatic char *origin_subst_one(char *, const char *, const char *, bool); 150250040Skibstatic char *origin_subst(char *, const char *); 151233694Skibstatic void preinit_main(void); 152153515Skanstatic int rtld_verify_versions(const Objlist *); 153153515Skanstatic int rtld_verify_object_versions(Obj_Entry *); 154153515Skanstatic void object_add_name(Obj_Entry *, const char *); 155153515Skanstatic int object_match_name(const Obj_Entry *, const char *); 156165916Sjhbstatic void ld_utrace_log(int, void *, void *, size_t, int, const char *); 157211705Skibstatic void rtld_fill_dl_phdr_info(const Obj_Entry *obj, 158211705Skib struct dl_phdr_info *phdr_info); 159235396Skibstatic uint32_t gnu_hash(const char *); 160235396Skibstatic bool matched_symbol(SymLook *, const Obj_Entry *, Sym_Match_Result *, 161235396Skib const unsigned long); 16234192Sjdp 163225366Sdimvoid r_debug_state(struct r_debug *, struct link_map *) __noinline; 16434192Sjdp 16534192Sjdp/* 16634192Sjdp * Data declarations. 16734192Sjdp */ 16834192Sjdpstatic char *error_message; /* Message for dlerror(), or NULL */ 169110804Skanstruct r_debug r_debug; /* for GDB; */ 170115444Smdoddstatic bool libmap_disable; /* Disable libmap */ 171216695Skibstatic bool ld_loadfltr; /* Immediate filters processing */ 172141232Smdoddstatic char *libmap_override; /* Maps to use in addition to libmap.conf */ 17334192Sjdpstatic bool trust; /* False for setuid and setgid programs */ 174144062Scpercivastatic bool dangerous_ld_env; /* True if environment variables have been 175144062Scperciva used to affect the libraries loaded */ 17634192Sjdpstatic char *ld_bind_now; /* Environment variable for immediate binding */ 17734192Sjdpstatic char *ld_debug; /* Environment variable for debugging */ 17834192Sjdpstatic char *ld_library_path; /* Environment variable for search path */ 17939551Sjdpstatic char *ld_preload; /* Environment variable for libraries to 18039551Sjdp load first */ 181190324Sdelphijstatic char *ld_elf_hints_path; /* Environment variable for alternative hints path */ 18235574Sdfrstatic char *ld_tracing; /* Called from ldd to print libs */ 183165916Sjhbstatic char *ld_utrace; /* Use utrace() to log events. */ 18434192Sjdpstatic Obj_Entry *obj_list; /* Head of linked list of shared objects */ 18534192Sjdpstatic Obj_Entry **obj_tail; /* Link field of last object in list */ 18634192Sjdpstatic Obj_Entry *obj_main; /* The main program shared object */ 18734192Sjdpstatic Obj_Entry obj_rtld; /* The dynamic linker shared object */ 18862801Sjdpstatic unsigned int obj_count; /* Number of objects in obj_list */ 189168312Skanstatic unsigned int obj_loads; /* Number of objects in obj_list */ 19034192Sjdp 19150608Sjdpstatic Objlist list_global = /* Objects dlopened with RTLD_GLOBAL */ 19250608Sjdp STAILQ_HEAD_INITIALIZER(list_global); 19350608Sjdpstatic Objlist list_main = /* Objects loaded at program startup */ 19450608Sjdp STAILQ_HEAD_INITIALIZER(list_main); 19563870Sjdpstatic Objlist list_fini = /* Objects needing fini() calls */ 19663870Sjdp STAILQ_HEAD_INITIALIZER(list_fini); 19750608Sjdp 198212497SnwhitehornElf_Sym sym_zero; /* For resolving undefined weak refs. */ 19945320Sjdp 20065109Sjwd#define GDB_STATE(s,m) r_debug.r_state = s; r_debug_state(&r_debug,m); 20135529Sdfr 20238816Sdfrextern Elf_Dyn _DYNAMIC; 20345501Sjdp#pragma weak _DYNAMIC 204130661Stmm#ifndef RTLD_IS_DYNAMIC 205130661Stmm#define RTLD_IS_DYNAMIC() (&_DYNAMIC != NULL) 206130661Stmm#endif 20738816Sdfr 208211413Skibint osreldate, pagesize; 209211413Skib 210233695Skiblong __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 211233695Skib 212217851Skibstatic int stack_prot = PROT_READ | PROT_WRITE | RTLD_DEFAULT_STACK_EXEC; 213217153Skibstatic int max_stack_flags; 214217153Skib 21534192Sjdp/* 21634192Sjdp * Global declarations normally provided by crt1. The dynamic linker is 21755687Sjdp * not built with crt1, so we have to provide them ourselves. 21834192Sjdp */ 21934192Sjdpchar *__progname; 22034192Sjdpchar **environ; 22134192Sjdp 22262801Sjdp/* 223233694Skib * Used to pass argc, argv to init functions. 224233694Skib */ 225233694Skibint main_argc; 226233694Skibchar **main_argv; 227233694Skib 228233694Skib/* 229133063Sdfr * Globals to control TLS allocation. 230133063Sdfr */ 231133063Sdfrsize_t tls_last_offset; /* Static TLS offset of last module */ 232133063Sdfrsize_t tls_last_size; /* Static TLS size of last module */ 233133063Sdfrsize_t tls_static_space; /* Static TLS space allocated */ 234259293Skibsize_t tls_static_max_align; 235133063Sdfrint tls_dtv_generation = 1; /* Used to detect when dtv size changes */ 236133063Sdfrint tls_max_index = 1; /* Largest module index allocated */ 237133063Sdfr 238240308Skibbool ld_library_path_rpath = true; 239240308Skib 240133063Sdfr/* 24162801Sjdp * Fill in a DoneList with an allocation large enough to hold all of 24262801Sjdp * the currently-loaded objects. Keep this as a macro since it calls 24362801Sjdp * alloca and we want that to occur within the scope of the caller. 24462801Sjdp */ 24562801Sjdp#define donelist_init(dlp) \ 24662801Sjdp ((dlp)->objs = alloca(obj_count * sizeof (dlp)->objs[0]), \ 24762801Sjdp assert((dlp)->objs != NULL), \ 24862801Sjdp (dlp)->num_alloc = obj_count, \ 24962801Sjdp (dlp)->num_used = 0) 25062801Sjdp 251165916Sjhb#define UTRACE_DLOPEN_START 1 252165916Sjhb#define UTRACE_DLOPEN_STOP 2 253165916Sjhb#define UTRACE_DLCLOSE_START 3 254165916Sjhb#define UTRACE_DLCLOSE_STOP 4 255165916Sjhb#define UTRACE_LOAD_OBJECT 5 256165916Sjhb#define UTRACE_UNLOAD_OBJECT 6 257165916Sjhb#define UTRACE_ADD_RUNDEP 7 258165916Sjhb#define UTRACE_PRELOAD_FINISHED 8 259165916Sjhb#define UTRACE_INIT_CALL 9 260165916Sjhb#define UTRACE_FINI_CALL 10 261165916Sjhb 262165916Sjhbstruct utrace_rtld { 263165916Sjhb char sig[4]; /* 'RTLD' */ 264165916Sjhb int event; 265165916Sjhb void *handle; 266165916Sjhb void *mapbase; /* Used for 'parent' and 'init/fini' */ 267165916Sjhb size_t mapsize; 268165916Sjhb int refcnt; /* Used for 'mode' */ 269165916Sjhb char name[MAXPATHLEN]; 270165916Sjhb}; 271165916Sjhb 272165916Sjhb#define LD_UTRACE(e, h, mb, ms, r, n) do { \ 273165916Sjhb if (ld_utrace != NULL) \ 274165916Sjhb ld_utrace_log(e, h, mb, ms, r, n); \ 275165916Sjhb} while (0) 276165916Sjhb 277165916Sjhbstatic void 278165916Sjhbld_utrace_log(int event, void *handle, void *mapbase, size_t mapsize, 279165916Sjhb int refcnt, const char *name) 280165916Sjhb{ 281165916Sjhb struct utrace_rtld ut; 282165916Sjhb 283165916Sjhb ut.sig[0] = 'R'; 284165916Sjhb ut.sig[1] = 'T'; 285165916Sjhb ut.sig[2] = 'L'; 286165916Sjhb ut.sig[3] = 'D'; 287165916Sjhb ut.event = event; 288165916Sjhb ut.handle = handle; 289165916Sjhb ut.mapbase = mapbase; 290165916Sjhb ut.mapsize = mapsize; 291165916Sjhb ut.refcnt = refcnt; 292165916Sjhb bzero(ut.name, sizeof(ut.name)); 293165916Sjhb if (name) 294165916Sjhb strlcpy(ut.name, name, sizeof(ut.name)); 295165916Sjhb utrace(&ut, sizeof(ut)); 296165916Sjhb} 297165916Sjhb 29834192Sjdp/* 29934192Sjdp * Main entry point for dynamic linking. The first argument is the 30034192Sjdp * stack pointer. The stack is expected to be laid out as described 30134192Sjdp * in the SVR4 ABI specification, Intel 386 Processor Supplement. 30234192Sjdp * Specifically, the stack pointer points to a word containing 30334192Sjdp * ARGC. Following that in the stack is a null-terminated sequence 30434192Sjdp * of pointers to argument strings. Then comes a null-terminated 30534192Sjdp * sequence of pointers to environment strings. Finally, there is a 30634192Sjdp * sequence of "auxiliary vector" entries. 30734192Sjdp * 30834192Sjdp * The second argument points to a place to store the dynamic linker's 30938816Sdfr * exit procedure pointer and the third to a place to store the main 31038816Sdfr * program's object. 31134192Sjdp * 31234192Sjdp * The return value is the main program's entry point. 31334192Sjdp */ 31434192Sjdpfunc_ptr_type 31538816Sdfr_rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) 31634192Sjdp{ 31738816Sdfr Elf_Auxinfo *aux_info[AT_COUNT]; 31834192Sjdp int i; 31934192Sjdp int argc; 32034192Sjdp char **argv; 32134192Sjdp char **env; 32238816Sdfr Elf_Auxinfo *aux; 32338816Sdfr Elf_Auxinfo *auxp; 32448871Sjdp const char *argv0; 325133063Sdfr Objlist_Entry *entry; 32650608Sjdp Obj_Entry *obj; 32763870Sjdp Obj_Entry **preload_tail; 328256436Skib Obj_Entry *last_interposer; 32963870Sjdp Objlist initlist; 330216695Skib RtldLockState lockstate; 331240308Skib char *library_path_rpath; 332233695Skib int mib[2]; 333233695Skib size_t len; 33434192Sjdp 33534192Sjdp /* 33634192Sjdp * On entry, the dynamic linker itself has not been relocated yet. 33734192Sjdp * Be very careful not to reference any global data until after 33834192Sjdp * init_rtld has returned. It is OK to reference file-scope statics 33934192Sjdp * and string constants, and to call static and global functions. 34034192Sjdp */ 34134192Sjdp 34234192Sjdp /* Find the auxiliary vector on the stack. */ 34334192Sjdp argc = *sp++; 34434192Sjdp argv = (char **) sp; 34534192Sjdp sp += argc + 1; /* Skip over arguments and NULL terminator */ 34634192Sjdp env = (char **) sp; 34734192Sjdp while (*sp++ != 0) /* Skip over environment, and NULL terminator */ 34834192Sjdp ; 34938816Sdfr aux = (Elf_Auxinfo *) sp; 35034192Sjdp 35134192Sjdp /* Digest the auxiliary vector. */ 35234192Sjdp for (i = 0; i < AT_COUNT; i++) 35334192Sjdp aux_info[i] = NULL; 35434192Sjdp for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { 35534192Sjdp if (auxp->a_type < AT_COUNT) 35634192Sjdp aux_info[auxp->a_type] = auxp; 35734192Sjdp } 35834192Sjdp 35934192Sjdp /* Initialize and relocate ourselves. */ 36034192Sjdp assert(aux_info[AT_BASE] != NULL); 361211413Skib init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info); 36234192Sjdp 36334192Sjdp __progname = obj_rtld.path; 36448871Sjdp argv0 = argv[0] != NULL ? argv[0] : "(null)"; 36534192Sjdp environ = env; 366233694Skib main_argc = argc; 367233694Skib main_argv = argv; 36834192Sjdp 369234012Skib if (aux_info[AT_CANARY] != NULL && 370234012Skib aux_info[AT_CANARY]->a_un.a_ptr != NULL) { 371233695Skib i = aux_info[AT_CANARYLEN]->a_un.a_val; 372233695Skib if (i > sizeof(__stack_chk_guard)) 373233695Skib i = sizeof(__stack_chk_guard); 374233695Skib memcpy(__stack_chk_guard, aux_info[AT_CANARY]->a_un.a_ptr, i); 375233695Skib } else { 376233695Skib mib[0] = CTL_KERN; 377233695Skib mib[1] = KERN_ARND; 378233695Skib 379233695Skib len = sizeof(__stack_chk_guard); 380233695Skib if (sysctl(mib, 2, __stack_chk_guard, &len, NULL, 0) == -1 || 381233695Skib len != sizeof(__stack_chk_guard)) { 382233695Skib /* If sysctl was unsuccessful, use the "terminator canary". */ 383233695Skib ((unsigned char *)(void *)__stack_chk_guard)[0] = 0; 384233695Skib ((unsigned char *)(void *)__stack_chk_guard)[1] = 0; 385233695Skib ((unsigned char *)(void *)__stack_chk_guard)[2] = '\n'; 386233695Skib ((unsigned char *)(void *)__stack_chk_guard)[3] = 255; 387233695Skib } 388233695Skib } 389233695Skib 390115448Smdodd trust = !issetugid(); 39134192Sjdp 392127250Speter ld_bind_now = getenv(LD_ "BIND_NOW"); 393169661Scsjp /* 394169661Scsjp * If the process is tainted, then we un-set the dangerous environment 395169661Scsjp * variables. The process will be marked as tainted until setuid(2) 396169661Scsjp * is called. If any child process calls setuid(2) we do not want any 397169661Scsjp * future processes to honor the potentially un-safe variables. 398169661Scsjp */ 399169661Scsjp if (!trust) { 400199979Scperciva if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") || 401199979Scperciva unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBMAP_DISABLE") || 402216695Skib unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH") || 403240308Skib unsetenv(LD_ "LOADFLTR") || unsetenv(LD_ "LIBRARY_PATH_RPATH")) { 404199979Scperciva _rtld_error("environment corrupt; aborting"); 405199979Scperciva die(); 406199979Scperciva } 407169661Scsjp } 408169661Scsjp ld_debug = getenv(LD_ "DEBUG"); 409169661Scsjp libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL; 410169661Scsjp libmap_override = getenv(LD_ "LIBMAP"); 411169661Scsjp ld_library_path = getenv(LD_ "LIBRARY_PATH"); 412169661Scsjp ld_preload = getenv(LD_ "PRELOAD"); 413190324Sdelphij ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH"); 414216695Skib ld_loadfltr = getenv(LD_ "LOADFLTR") != NULL; 415240308Skib library_path_rpath = getenv(LD_ "LIBRARY_PATH_RPATH"); 416240308Skib if (library_path_rpath != NULL) { 417240308Skib if (library_path_rpath[0] == 'y' || 418240308Skib library_path_rpath[0] == 'Y' || 419240308Skib library_path_rpath[0] == '1') 420240308Skib ld_library_path_rpath = true; 421240308Skib else 422240308Skib ld_library_path_rpath = false; 423240308Skib } 424169661Scsjp dangerous_ld_env = libmap_disable || (libmap_override != NULL) || 425190324Sdelphij (ld_library_path != NULL) || (ld_preload != NULL) || 426216695Skib (ld_elf_hints_path != NULL) || ld_loadfltr; 427127250Speter ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS"); 428165916Sjhb ld_utrace = getenv(LD_ "UTRACE"); 42934192Sjdp 430190324Sdelphij if ((ld_elf_hints_path == NULL) || strlen(ld_elf_hints_path) == 0) 431190324Sdelphij ld_elf_hints_path = _PATH_ELF_HINTS; 432190324Sdelphij 43334192Sjdp if (ld_debug != NULL && *ld_debug != '\0') 43434192Sjdp debug = 1; 43534192Sjdp dbg("%s is initialized, base address = %p", __progname, 43634192Sjdp (caddr_t) aux_info[AT_BASE]->a_un.a_ptr); 43745501Sjdp dbg("RTLD dynamic = %p", obj_rtld.dynamic); 43845501Sjdp dbg("RTLD pltgot = %p", obj_rtld.pltgot); 43934192Sjdp 440216695Skib dbg("initializing thread locks"); 441216695Skib lockdflt_init(); 442216695Skib 44334192Sjdp /* 44434192Sjdp * Load the main program, or process its program header if it is 44534192Sjdp * already loaded. 44634192Sjdp */ 44734192Sjdp if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */ 44834192Sjdp int fd = aux_info[AT_EXECFD]->a_un.a_val; 44934192Sjdp dbg("loading main program"); 45050609Sjdp obj_main = map_object(fd, argv0, NULL); 45134192Sjdp close(fd); 45234192Sjdp if (obj_main == NULL) 45334192Sjdp die(); 454217153Skib max_stack_flags = obj->stack_flags; 45534192Sjdp } else { /* Main program already loaded. */ 45638816Sdfr const Elf_Phdr *phdr; 45734192Sjdp int phnum; 45834192Sjdp caddr_t entry; 45934192Sjdp 46034192Sjdp dbg("processing main program's program header"); 46134192Sjdp assert(aux_info[AT_PHDR] != NULL); 46238816Sdfr phdr = (const Elf_Phdr *) aux_info[AT_PHDR]->a_un.a_ptr; 46334192Sjdp assert(aux_info[AT_PHNUM] != NULL); 46434192Sjdp phnum = aux_info[AT_PHNUM]->a_un.a_val; 46534192Sjdp assert(aux_info[AT_PHENT] != NULL); 46638816Sdfr assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr)); 46734192Sjdp assert(aux_info[AT_ENTRY] != NULL); 46834192Sjdp entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr; 46948871Sjdp if ((obj_main = digest_phdr(phdr, phnum, entry, argv0)) == NULL) 47048871Sjdp die(); 47134192Sjdp } 47234192Sjdp 473189959Skib if (aux_info[AT_EXECPATH] != 0) { 474189959Skib char *kexecpath; 475189959Skib char buf[MAXPATHLEN]; 476189959Skib 477189959Skib kexecpath = aux_info[AT_EXECPATH]->a_un.a_ptr; 478189959Skib dbg("AT_EXECPATH %p %s", kexecpath, kexecpath); 479189959Skib if (kexecpath[0] == '/') 480189959Skib obj_main->path = kexecpath; 481189959Skib else if (getcwd(buf, sizeof(buf)) == NULL || 482189959Skib strlcat(buf, "/", sizeof(buf)) >= sizeof(buf) || 483189959Skib strlcat(buf, kexecpath, sizeof(buf)) >= sizeof(buf)) 484189959Skib obj_main->path = xstrdup(argv0); 485189959Skib else 486189959Skib obj_main->path = xstrdup(buf); 487189959Skib } else { 488189959Skib dbg("No AT_EXECPATH"); 489189959Skib obj_main->path = xstrdup(argv0); 490189959Skib } 491189959Skib dbg("obj_main path %s", obj_main->path); 49234192Sjdp obj_main->mainprog = true; 49350610Sjdp 494217153Skib if (aux_info[AT_STACKPROT] != NULL && 495217153Skib aux_info[AT_STACKPROT]->a_un.a_val != 0) 496217153Skib stack_prot = aux_info[AT_STACKPROT]->a_un.a_val; 497217153Skib 49850610Sjdp /* 49950610Sjdp * Get the actual dynamic linker pathname from the executable if 50050610Sjdp * possible. (It should always be possible.) That ensures that 50150610Sjdp * gdb will find the right dynamic linker even if a non-standard 50250610Sjdp * one is being used. 50350610Sjdp */ 50450610Sjdp if (obj_main->interp != NULL && 50550610Sjdp strcmp(obj_main->interp, obj_rtld.path) != 0) { 50650610Sjdp free(obj_rtld.path); 50750610Sjdp obj_rtld.path = xstrdup(obj_main->interp); 508127579Sdfr __progname = obj_rtld.path; 50950610Sjdp } 51050610Sjdp 51193610Sjake digest_dynamic(obj_main, 0); 512235396Skib dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d", 513235396Skib obj_main->path, obj_main->valid_hash_sysv, obj_main->valid_hash_gnu, 514235396Skib obj_main->dynsymcount); 51534192Sjdp 51635529Sdfr linkmap_add(obj_main); 51735529Sdfr linkmap_add(&obj_rtld); 51835529Sdfr 51934192Sjdp /* Link the main program into the list of objects. */ 52034192Sjdp *obj_tail = obj_main; 52134192Sjdp obj_tail = &obj_main->next; 52262801Sjdp obj_count++; 523168312Skan obj_loads++; 52434192Sjdp 52545320Sjdp /* Initialize a fake symbol for resolving undefined weak references. */ 52645320Sjdp sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); 52795544Smarcel sym_zero.st_shndx = SHN_UNDEF; 528197931Skib sym_zero.st_value = -(uintptr_t)obj_main->relocbase; 52945320Sjdp 530115444Smdodd if (!libmap_disable) 531141232Smdodd libmap_disable = (bool)lm_init(libmap_override); 532113229Smdodd 53339551Sjdp dbg("loading LD_PRELOAD libraries"); 53439551Sjdp if (load_preload_objects() == -1) 53539551Sjdp die(); 53663870Sjdp preload_tail = obj_tail; 53739551Sjdp 53834192Sjdp dbg("loading needed objects"); 539199829Skib if (load_needed_objects(obj_main, 0) == -1) 54034192Sjdp die(); 54134192Sjdp 54263870Sjdp /* Make a list of all objects loaded at startup. */ 543256436Skib last_interposer = obj_main; 544114826Skan for (obj = obj_list; obj != NULL; obj = obj->next) { 545256436Skib if (obj->z_interpose && obj != obj_main) { 546256436Skib objlist_put_after(&list_main, last_interposer, obj); 547256436Skib last_interposer = obj; 548256436Skib } else { 549256436Skib objlist_push_tail(&list_main, obj); 550256436Skib } 551114826Skan obj->refcount++; 552114826Skan } 55350608Sjdp 554153515Skan dbg("checking for required versions"); 555153515Skan if (rtld_verify_versions(&list_main) == -1 && !ld_tracing) 556153515Skan die(); 557153515Skan 55835574Sdfr if (ld_tracing) { /* We're done */ 55935574Sdfr trace_loaded_objects(obj_main); 56035574Sdfr exit(0); 56135574Sdfr } 56235574Sdfr 563127250Speter if (getenv(LD_ "DUMP_REL_PRE") != NULL) { 564116563Smdodd dump_relocations(obj_main); 565116563Smdodd exit (0); 566116563Smdodd } 567116563Smdodd 568226214Skib /* 569226214Skib * Processing tls relocations requires having the tls offsets 570226214Skib * initialized. Prepare offsets before starting initial 571226214Skib * relocation processing. 572226214Skib */ 573226214Skib dbg("initializing initial thread local storage offsets"); 574137121Sssouhlal STAILQ_FOREACH(entry, &list_main, link) { 575137121Sssouhlal /* 576137121Sssouhlal * Allocate all the initial objects out of the static TLS 577137121Sssouhlal * block even if they didn't ask for it. 578137121Sssouhlal */ 579137121Sssouhlal allocate_tls_offset(entry->obj); 580137121Sssouhlal } 581137121Sssouhlal 58234192Sjdp if (relocate_objects(obj_main, 583233831Skib ld_bind_now != NULL && *ld_bind_now != '\0', 584233831Skib &obj_rtld, SYMLOOK_EARLY, NULL) == -1) 58534192Sjdp die(); 58634192Sjdp 58734192Sjdp dbg("doing copy relocations"); 58834192Sjdp if (do_copy_relocations(obj_main) == -1) 58934192Sjdp die(); 59034192Sjdp 591127250Speter if (getenv(LD_ "DUMP_REL_POST") != NULL) { 592116563Smdodd dump_relocations(obj_main); 593116563Smdodd exit (0); 594116563Smdodd } 595116563Smdodd 596226214Skib /* 597226214Skib * Setup TLS for main thread. This must be done after the 598226214Skib * relocations are processed, since tls initialization section 599226214Skib * might be the subject for relocations. 600226214Skib */ 601226214Skib dbg("initializing initial thread local storage"); 602226214Skib allocate_initial_tls(obj_list); 603226214Skib 60445890Sjdp dbg("initializing key program variables"); 60545890Sjdp set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : ""); 60645890Sjdp set_program_var("environ", env); 607211414Skib set_program_var("__elf_aux_vector", aux); 60845890Sjdp 60963870Sjdp /* Make a list of init functions to call. */ 61063870Sjdp objlist_init(&initlist); 61163870Sjdp initlist_add_objects(obj_list, preload_tail, &initlist); 61263870Sjdp 61365109Sjwd r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */ 61448543Sjdp 615217223Skib map_stacks_exec(NULL); 616217153Skib 617229769Skib dbg("resolving ifuncs"); 618229769Skib if (resolve_objects_ifunc(obj_main, 619233831Skib ld_bind_now != NULL && *ld_bind_now != '\0', SYMLOOK_EARLY, 620233831Skib NULL) == -1) 621229769Skib die(); 622229769Skib 623233694Skib if (!obj_main->crt_no_init) { 624233694Skib /* 625233694Skib * Make sure we don't call the main program's init and fini 626233694Skib * functions for binaries linked with old crt1 which calls 627233694Skib * _init itself. 628233694Skib */ 629233694Skib obj_main->init = obj_main->fini = (Elf_Addr)NULL; 630233694Skib obj_main->preinit_array = obj_main->init_array = 631233694Skib obj_main->fini_array = (Elf_Addr)NULL; 632233694Skib } 633233694Skib 634216695Skib wlock_acquire(rtld_bind_lock, &lockstate); 635233694Skib if (obj_main->crt_no_init) 636233694Skib preinit_main(); 637182698Skan objlist_call_init(&initlist, &lockstate); 63863870Sjdp objlist_clear(&initlist); 639216695Skib dbg("loading filtees"); 640216695Skib for (obj = obj_list->next; obj != NULL; obj = obj->next) { 641216695Skib if (ld_loadfltr || obj->z_loadfltr) 642216695Skib load_filtees(obj, 0, &lockstate); 643216695Skib } 644216695Skib lock_release(rtld_bind_lock, &lockstate); 64534192Sjdp 64634192Sjdp dbg("transferring control to program entry point = %p", obj_main->entry); 64734192Sjdp 64834192Sjdp /* Return the exit procedure and the program entry point. */ 64938816Sdfr *exit_proc = rtld_exit; 65038816Sdfr *objp = obj_main; 65134192Sjdp return (func_ptr_type) obj_main->entry; 65234192Sjdp} 65334192Sjdp 654229503Skibvoid * 655229503Skibrtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def) 656229503Skib{ 657229503Skib void *ptr; 658229503Skib Elf_Addr target; 659229503Skib 660229503Skib ptr = (void *)make_function_pointer(def, obj); 661229503Skib target = ((Elf_Addr (*)(void))ptr)(); 662229503Skib return ((void *)target); 663229503Skib} 664229503Skib 66548205SjdpElf_Addr 666153504Smarcel_rtld_bind(Obj_Entry *obj, Elf_Size reloff) 66734192Sjdp{ 66838816Sdfr const Elf_Rel *rel; 66938816Sdfr const Elf_Sym *def; 67034192Sjdp const Obj_Entry *defobj; 67138816Sdfr Elf_Addr *where; 67248205Sjdp Elf_Addr target; 673216695Skib RtldLockState lockstate; 67434192Sjdp 675216695Skib rlock_acquire(rtld_bind_lock, &lockstate); 676218476Skib if (sigsetjmp(lockstate.env, 0) != 0) 677216695Skib lock_upgrade(rtld_bind_lock, &lockstate); 67838816Sdfr if (obj->pltrel) 67938816Sdfr rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff); 68038816Sdfr else 68138816Sdfr rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff); 68234192Sjdp 68338816Sdfr where = (Elf_Addr *) (obj->relocbase + rel->r_offset); 684216695Skib def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL, 685216695Skib &lockstate); 68634192Sjdp if (def == NULL) 68734192Sjdp die(); 688229503Skib if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) 689229503Skib target = (Elf_Addr)rtld_resolve_ifunc(defobj, def); 690229503Skib else 691229503Skib target = (Elf_Addr)(defobj->relocbase + def->st_value); 69234192Sjdp 69334192Sjdp dbg("\"%s\" in \"%s\" ==> %p in \"%s\"", 69434192Sjdp defobj->strtab + def->st_name, basename(obj->path), 69548205Sjdp (void *)target, basename(defobj->path)); 69634192Sjdp 69785004Sdfr /* 69885004Sdfr * Write the new contents for the jmpslot. Note that depending on 69985004Sdfr * architecture, the value which we need to return back to the 70085004Sdfr * lazy binding trampoline may or may not be the target 70185004Sdfr * address. The value returned from reloc_jmpslot() is the value 70285004Sdfr * that the trampoline needs. 70385004Sdfr */ 704107071Stmm target = reloc_jmpslot(where, target, defobj, obj, rel); 705216695Skib lock_release(rtld_bind_lock, &lockstate); 70634192Sjdp return target; 70734192Sjdp} 70834192Sjdp 70934192Sjdp/* 71034192Sjdp * Error reporting function. Use it like printf. If formats the message 71134192Sjdp * into a buffer, and sets things up so that the next call to dlerror() 71234192Sjdp * will return the message. 71334192Sjdp */ 71434192Sjdpvoid 71534192Sjdp_rtld_error(const char *fmt, ...) 71634192Sjdp{ 71734192Sjdp static char buf[512]; 71834192Sjdp va_list ap; 71934192Sjdp 72034192Sjdp va_start(ap, fmt); 721225152Skib rtld_vsnprintf(buf, sizeof buf, fmt, ap); 72234192Sjdp error_message = buf; 72334192Sjdp va_end(ap); 72434192Sjdp} 72534192Sjdp 72670677Sjdp/* 72770677Sjdp * Return a dynamically-allocated copy of the current error message, if any. 72870677Sjdp */ 72970677Sjdpstatic char * 73070677Sjdperrmsg_save(void) 73170677Sjdp{ 73270677Sjdp return error_message == NULL ? NULL : xstrdup(error_message); 73370677Sjdp} 73470677Sjdp 73570677Sjdp/* 73670677Sjdp * Restore the current error message from a copy which was previously saved 73770677Sjdp * by errmsg_save(). The copy is freed. 73870677Sjdp */ 73970677Sjdpstatic void 74070677Sjdperrmsg_restore(char *saved_msg) 74170677Sjdp{ 74270677Sjdp if (saved_msg == NULL) 74370677Sjdp error_message = NULL; 74470677Sjdp else { 74570677Sjdp _rtld_error("%s", saved_msg); 74670677Sjdp free(saved_msg); 74770677Sjdp } 74870677Sjdp} 74970677Sjdp 75034192Sjdpstatic const char * 75134192Sjdpbasename(const char *name) 75234192Sjdp{ 75334192Sjdp const char *p = strrchr(name, '/'); 75434192Sjdp return p != NULL ? p + 1 : name; 75534192Sjdp} 75634192Sjdp 757189959Skibstatic struct utsname uts; 758189959Skib 759250040Skibstatic char * 760250040Skiborigin_subst_one(char *real, const char *kw, const char *subst, 761250040Skib bool may_free) 762189959Skib{ 763250040Skib char *p, *p1, *res, *resp; 764250040Skib int subst_len, kw_len, subst_count, old_len, new_len; 765189959Skib 766250040Skib kw_len = strlen(kw); 767250040Skib 768250040Skib /* 769250040Skib * First, count the number of the keyword occurences, to 770250040Skib * preallocate the final string. 771250040Skib */ 772250040Skib for (p = real, subst_count = 0;; p = p1 + kw_len, subst_count++) { 773250040Skib p1 = strstr(p, kw); 774250040Skib if (p1 == NULL) 775250040Skib break; 776250040Skib } 777250040Skib 778250040Skib /* 779250040Skib * If the keyword is not found, just return. 780250040Skib */ 781250040Skib if (subst_count == 0) 782250040Skib return (may_free ? real : xstrdup(real)); 783250040Skib 784250040Skib /* 785250040Skib * There is indeed something to substitute. Calculate the 786250040Skib * length of the resulting string, and allocate it. 787250040Skib */ 788250040Skib subst_len = strlen(subst); 789250040Skib old_len = strlen(real); 790250040Skib new_len = old_len + (subst_len - kw_len) * subst_count; 791250040Skib res = xmalloc(new_len + 1); 792250040Skib 793250040Skib /* 794250040Skib * Now, execute the substitution loop. 795250040Skib */ 796250170Skib for (p = real, resp = res, *resp = '\0';;) { 797250040Skib p1 = strstr(p, kw); 798250040Skib if (p1 != NULL) { 799250040Skib /* Copy the prefix before keyword. */ 800250040Skib memcpy(resp, p, p1 - p); 801250040Skib resp += p1 - p; 802250040Skib /* Keyword replacement. */ 803250040Skib memcpy(resp, subst, subst_len); 804250040Skib resp += subst_len; 805250170Skib *resp = '\0'; 806250040Skib p = p1 + kw_len; 807250040Skib } else 808250040Skib break; 809250040Skib } 810250040Skib 811250040Skib /* Copy to the end of string and finish. */ 812250040Skib strcat(resp, p); 813250040Skib if (may_free) 814250040Skib free(real); 815250040Skib return (res); 816189959Skib} 817189959Skib 818189959Skibstatic char * 819250040Skiborigin_subst(char *real, const char *origin_path) 820189959Skib{ 821250040Skib char *res1, *res2, *res3, *res4; 822189959Skib 823250040Skib if (uts.sysname[0] == '\0') { 824250040Skib if (uname(&uts) != 0) { 825250040Skib _rtld_error("utsname failed: %d", errno); 826250040Skib return (NULL); 827250040Skib } 828189959Skib } 829250040Skib res1 = origin_subst_one(real, "$ORIGIN", origin_path, false); 830250040Skib res2 = origin_subst_one(res1, "$OSNAME", uts.sysname, true); 831250040Skib res3 = origin_subst_one(res2, "$OSREL", uts.release, true); 832250040Skib res4 = origin_subst_one(res3, "$PLATFORM", uts.machine, true); 833250040Skib return (res4); 834189959Skib} 835189959Skib 83634192Sjdpstatic void 83734192Sjdpdie(void) 83834192Sjdp{ 83934192Sjdp const char *msg = dlerror(); 84034192Sjdp 84134192Sjdp if (msg == NULL) 84234192Sjdp msg = "Fatal error"; 843225152Skib rtld_fdputstr(STDERR_FILENO, msg); 844231820Skib rtld_fdputchar(STDERR_FILENO, '\n'); 845225152Skib _exit(1); 84634192Sjdp} 84734192Sjdp 84834192Sjdp/* 84934192Sjdp * Process a shared object's DYNAMIC section, and save the important 85034192Sjdp * information in its Obj_Entry structure. 85134192Sjdp */ 85234192Sjdpstatic void 853211413Skibdigest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath, 854240308Skib const Elf_Dyn **dyn_soname, const Elf_Dyn **dyn_runpath) 85534192Sjdp{ 85638816Sdfr const Elf_Dyn *dynp; 85734192Sjdp Needed_Entry **needed_tail = &obj->needed; 858216695Skib Needed_Entry **needed_filtees_tail = &obj->needed_filtees; 859216695Skib Needed_Entry **needed_aux_filtees_tail = &obj->needed_aux_filtees; 860235396Skib const Elf_Hashelt *hashtab; 861235396Skib const Elf32_Word *hashval; 862235396Skib Elf32_Word bkt, nmaskwords; 863235396Skib int bloom_size32; 864235396Skib bool nmw_power2; 86538816Sdfr int plttype = DT_REL; 86634192Sjdp 867211413Skib *dyn_rpath = NULL; 868211413Skib *dyn_soname = NULL; 869240308Skib *dyn_runpath = NULL; 870211413Skib 871124020Sdfr obj->bind_now = false; 87234192Sjdp for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) { 87334192Sjdp switch (dynp->d_tag) { 87434192Sjdp 87534192Sjdp case DT_REL: 87638816Sdfr obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr); 87734192Sjdp break; 87834192Sjdp 87934192Sjdp case DT_RELSZ: 88034192Sjdp obj->relsize = dynp->d_un.d_val; 88134192Sjdp break; 88234192Sjdp 88334192Sjdp case DT_RELENT: 88438816Sdfr assert(dynp->d_un.d_val == sizeof(Elf_Rel)); 88534192Sjdp break; 88634192Sjdp 88734192Sjdp case DT_JMPREL: 88838816Sdfr obj->pltrel = (const Elf_Rel *) 88934192Sjdp (obj->relocbase + dynp->d_un.d_ptr); 89034192Sjdp break; 89134192Sjdp 89234192Sjdp case DT_PLTRELSZ: 89334192Sjdp obj->pltrelsize = dynp->d_un.d_val; 89434192Sjdp break; 89534192Sjdp 89634192Sjdp case DT_RELA: 89738816Sdfr obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr); 89838816Sdfr break; 89938816Sdfr 90034192Sjdp case DT_RELASZ: 90138816Sdfr obj->relasize = dynp->d_un.d_val; 90238816Sdfr break; 90338816Sdfr 90434192Sjdp case DT_RELAENT: 90538816Sdfr assert(dynp->d_un.d_val == sizeof(Elf_Rela)); 90634192Sjdp break; 90734192Sjdp 90834192Sjdp case DT_PLTREL: 90938816Sdfr plttype = dynp->d_un.d_val; 91038816Sdfr assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA); 91134192Sjdp break; 91234192Sjdp 91334192Sjdp case DT_SYMTAB: 91438816Sdfr obj->symtab = (const Elf_Sym *) 91534192Sjdp (obj->relocbase + dynp->d_un.d_ptr); 91634192Sjdp break; 91734192Sjdp 91834192Sjdp case DT_SYMENT: 91938816Sdfr assert(dynp->d_un.d_val == sizeof(Elf_Sym)); 92034192Sjdp break; 92134192Sjdp 92234192Sjdp case DT_STRTAB: 92334192Sjdp obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr); 92434192Sjdp break; 92534192Sjdp 92634192Sjdp case DT_STRSZ: 92734192Sjdp obj->strsize = dynp->d_un.d_val; 92834192Sjdp break; 92934192Sjdp 930153515Skan case DT_VERNEED: 931153515Skan obj->verneed = (const Elf_Verneed *) (obj->relocbase + 932153515Skan dynp->d_un.d_val); 933153515Skan break; 934153515Skan 935153515Skan case DT_VERNEEDNUM: 936153515Skan obj->verneednum = dynp->d_un.d_val; 937153515Skan break; 938153515Skan 939153515Skan case DT_VERDEF: 940153515Skan obj->verdef = (const Elf_Verdef *) (obj->relocbase + 941153515Skan dynp->d_un.d_val); 942153515Skan break; 943153515Skan 944153515Skan case DT_VERDEFNUM: 945153515Skan obj->verdefnum = dynp->d_un.d_val; 946153515Skan break; 947153515Skan 948153515Skan case DT_VERSYM: 949153515Skan obj->versyms = (const Elf_Versym *)(obj->relocbase + 950153515Skan dynp->d_un.d_val); 951153515Skan break; 952153515Skan 95334192Sjdp case DT_HASH: 95434192Sjdp { 955235396Skib hashtab = (const Elf_Hashelt *)(obj->relocbase + 956235396Skib dynp->d_un.d_ptr); 95734192Sjdp obj->nbuckets = hashtab[0]; 95834192Sjdp obj->nchains = hashtab[1]; 95934192Sjdp obj->buckets = hashtab + 2; 96034192Sjdp obj->chains = obj->buckets + obj->nbuckets; 961235396Skib obj->valid_hash_sysv = obj->nbuckets > 0 && obj->nchains > 0 && 962235396Skib obj->buckets != NULL; 96334192Sjdp } 96434192Sjdp break; 96534192Sjdp 966235396Skib case DT_GNU_HASH: 967235396Skib { 968235396Skib hashtab = (const Elf_Hashelt *)(obj->relocbase + 969235396Skib dynp->d_un.d_ptr); 970235396Skib obj->nbuckets_gnu = hashtab[0]; 971235396Skib obj->symndx_gnu = hashtab[1]; 972235396Skib nmaskwords = hashtab[2]; 973235396Skib bloom_size32 = (__ELF_WORD_SIZE / 32) * nmaskwords; 974235396Skib /* Number of bitmask words is required to be power of 2 */ 975235396Skib nmw_power2 = ((nmaskwords & (nmaskwords - 1)) == 0); 976235396Skib obj->maskwords_bm_gnu = nmaskwords - 1; 977235396Skib obj->shift2_gnu = hashtab[3]; 978235396Skib obj->bloom_gnu = (Elf_Addr *) (hashtab + 4); 979235396Skib obj->buckets_gnu = hashtab + 4 + bloom_size32; 980235396Skib obj->chain_zero_gnu = obj->buckets_gnu + obj->nbuckets_gnu - 981235396Skib obj->symndx_gnu; 982235396Skib obj->valid_hash_gnu = nmw_power2 && obj->nbuckets_gnu > 0 && 983235396Skib obj->buckets_gnu != NULL; 984235396Skib } 985235396Skib break; 986235396Skib 98734192Sjdp case DT_NEEDED: 98845501Sjdp if (!obj->rtld) { 98934192Sjdp Needed_Entry *nep = NEW(Needed_Entry); 99034192Sjdp nep->name = dynp->d_un.d_val; 99134192Sjdp nep->obj = NULL; 99234192Sjdp nep->next = NULL; 99334192Sjdp 99434192Sjdp *needed_tail = nep; 99534192Sjdp needed_tail = &nep->next; 99634192Sjdp } 99734192Sjdp break; 99834192Sjdp 999216695Skib case DT_FILTER: 1000216695Skib if (!obj->rtld) { 1001216695Skib Needed_Entry *nep = NEW(Needed_Entry); 1002216695Skib nep->name = dynp->d_un.d_val; 1003216695Skib nep->obj = NULL; 1004216695Skib nep->next = NULL; 1005216695Skib 1006216695Skib *needed_filtees_tail = nep; 1007216695Skib needed_filtees_tail = &nep->next; 1008216695Skib } 1009216695Skib break; 1010216695Skib 1011216695Skib case DT_AUXILIARY: 1012216695Skib if (!obj->rtld) { 1013216695Skib Needed_Entry *nep = NEW(Needed_Entry); 1014216695Skib nep->name = dynp->d_un.d_val; 1015216695Skib nep->obj = NULL; 1016216695Skib nep->next = NULL; 1017216695Skib 1018216695Skib *needed_aux_filtees_tail = nep; 1019216695Skib needed_aux_filtees_tail = &nep->next; 1020216695Skib } 1021216695Skib break; 1022216695Skib 102334192Sjdp case DT_PLTGOT: 102445501Sjdp obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr); 102534192Sjdp break; 102634192Sjdp 102734192Sjdp case DT_TEXTREL: 102834192Sjdp obj->textrel = true; 102934192Sjdp break; 103034192Sjdp 103134192Sjdp case DT_SYMBOLIC: 103234192Sjdp obj->symbolic = true; 103334192Sjdp break; 103434192Sjdp 103534192Sjdp case DT_RPATH: 103634192Sjdp /* 103734192Sjdp * We have to wait until later to process this, because we 103834192Sjdp * might not have gotten the address of the string table yet. 103934192Sjdp */ 1040211413Skib *dyn_rpath = dynp; 104134192Sjdp break; 104234192Sjdp 104334192Sjdp case DT_SONAME: 1044211413Skib *dyn_soname = dynp; 104534192Sjdp break; 104634192Sjdp 1047240308Skib case DT_RUNPATH: 1048240308Skib *dyn_runpath = dynp; 1049240308Skib break; 1050240308Skib 105134192Sjdp case DT_INIT: 105285677Speter obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr); 105334192Sjdp break; 105434192Sjdp 1055233694Skib case DT_PREINIT_ARRAY: 1056233694Skib obj->preinit_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr); 1057233694Skib break; 1058233694Skib 1059233694Skib case DT_PREINIT_ARRAYSZ: 1060233694Skib obj->preinit_array_num = dynp->d_un.d_val / sizeof(Elf_Addr); 1061233694Skib break; 1062233694Skib 1063233694Skib case DT_INIT_ARRAY: 1064233694Skib obj->init_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr); 1065233694Skib break; 1066233694Skib 1067233694Skib case DT_INIT_ARRAYSZ: 1068233694Skib obj->init_array_num = dynp->d_un.d_val / sizeof(Elf_Addr); 1069233694Skib break; 1070233694Skib 107134192Sjdp case DT_FINI: 107285677Speter obj->fini = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr); 107334192Sjdp break; 107434192Sjdp 1075233694Skib case DT_FINI_ARRAY: 1076233694Skib obj->fini_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr); 1077233694Skib break; 1078233694Skib 1079233694Skib case DT_FINI_ARRAYSZ: 1080233694Skib obj->fini_array_num = dynp->d_un.d_val / sizeof(Elf_Addr); 1081233694Skib break; 1082233694Skib 1083177924Simp /* 1084177924Simp * Don't process DT_DEBUG on MIPS as the dynamic section 1085177924Simp * is mapped read-only. DT_MIPS_RLD_MAP is used instead. 1086177924Simp */ 1087177924Simp 1088177924Simp#ifndef __mips__ 108934192Sjdp case DT_DEBUG: 109034192Sjdp /* XXX - not implemented yet */ 109193610Sjake if (!early) 109293610Sjake dbg("Filling in DT_DEBUG entry"); 109338816Sdfr ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug; 109434192Sjdp break; 1095177924Simp#endif 109638816Sdfr 1097116511Smdodd case DT_FLAGS: 1098199828Skib if ((dynp->d_un.d_val & DF_ORIGIN) && trust) 1099189959Skib obj->z_origin = true; 1100116511Smdodd if (dynp->d_un.d_val & DF_SYMBOLIC) 1101116511Smdodd obj->symbolic = true; 1102116511Smdodd if (dynp->d_un.d_val & DF_TEXTREL) 1103116511Smdodd obj->textrel = true; 1104116511Smdodd if (dynp->d_un.d_val & DF_BIND_NOW) 1105116511Smdodd obj->bind_now = true; 1106223262Sbenl /*if (dynp->d_un.d_val & DF_STATIC_TLS) 1107223262Sbenl ;*/ 1108116511Smdodd break; 1109177924Simp#ifdef __mips__ 1110177924Simp case DT_MIPS_LOCAL_GOTNO: 1111177924Simp obj->local_gotno = dynp->d_un.d_val; 1112177924Simp break; 1113116511Smdodd 1114177924Simp case DT_MIPS_SYMTABNO: 1115177924Simp obj->symtabno = dynp->d_un.d_val; 1116177924Simp break; 1117177924Simp 1118177924Simp case DT_MIPS_GOTSYM: 1119177924Simp obj->gotsym = dynp->d_un.d_val; 1120177924Simp break; 1121177924Simp 1122177924Simp case DT_MIPS_RLD_MAP: 1123177924Simp#ifdef notyet 1124177924Simp if (!early) 1125177924Simp dbg("Filling in DT_DEBUG entry"); 1126177924Simp ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug; 1127177924Simp#endif 1128177924Simp break; 1129177924Simp#endif 1130177924Simp 1131189959Skib case DT_FLAGS_1: 1132199829Skib if (dynp->d_un.d_val & DF_1_NOOPEN) 1133199829Skib obj->z_noopen = true; 1134189959Skib if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust) 1135189959Skib obj->z_origin = true; 1136223262Sbenl /*if (dynp->d_un.d_val & DF_1_GLOBAL) 1137223262Sbenl XXX ;*/ 1138189959Skib if (dynp->d_un.d_val & DF_1_BIND_NOW) 1139189959Skib obj->bind_now = true; 1140190543Skib if (dynp->d_un.d_val & DF_1_NODELETE) 1141190543Skib obj->z_nodelete = true; 1142216695Skib if (dynp->d_un.d_val & DF_1_LOADFLTR) 1143216695Skib obj->z_loadfltr = true; 1144256436Skib if (dynp->d_un.d_val & DF_1_INTERPOSE) 1145256436Skib obj->z_interpose = true; 1146240308Skib if (dynp->d_un.d_val & DF_1_NODEFLIB) 1147240308Skib obj->z_nodeflib = true; 1148189959Skib break; 1149189959Skib 115038816Sdfr default: 115193610Sjake if (!early) { 115293610Sjake dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag, 115393610Sjake (long)dynp->d_tag); 115493610Sjake } 115550928Sjdp break; 115634192Sjdp } 115734192Sjdp } 115834192Sjdp 115938816Sdfr obj->traced = false; 116038816Sdfr 116138816Sdfr if (plttype == DT_RELA) { 116238816Sdfr obj->pltrela = (const Elf_Rela *) obj->pltrel; 116338816Sdfr obj->pltrel = NULL; 116438816Sdfr obj->pltrelasize = obj->pltrelsize; 116538816Sdfr obj->pltrelsize = 0; 116638816Sdfr } 1167235396Skib 1168235396Skib /* Determine size of dynsym table (equal to nchains of sysv hash) */ 1169235396Skib if (obj->valid_hash_sysv) 1170235396Skib obj->dynsymcount = obj->nchains; 1171235396Skib else if (obj->valid_hash_gnu) { 1172235396Skib obj->dynsymcount = 0; 1173235396Skib for (bkt = 0; bkt < obj->nbuckets_gnu; bkt++) { 1174235396Skib if (obj->buckets_gnu[bkt] == 0) 1175235396Skib continue; 1176235396Skib hashval = &obj->chain_zero_gnu[obj->buckets_gnu[bkt]]; 1177235396Skib do 1178235396Skib obj->dynsymcount++; 1179235396Skib while ((*hashval++ & 1u) == 0); 1180235396Skib } 1181235396Skib obj->dynsymcount += obj->symndx_gnu; 1182235396Skib } 1183211413Skib} 118438816Sdfr 1185211413Skibstatic void 1186211413Skibdigest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath, 1187240308Skib const Elf_Dyn *dyn_soname, const Elf_Dyn *dyn_runpath) 1188211413Skib{ 1189211413Skib 1190189959Skib if (obj->z_origin && obj->origin_path == NULL) { 1191189959Skib obj->origin_path = xmalloc(PATH_MAX); 1192189959Skib if (rtld_dirname_abs(obj->path, obj->origin_path) == -1) 1193189959Skib die(); 1194189959Skib } 1195153515Skan 1196240308Skib if (dyn_runpath != NULL) { 1197240308Skib obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val; 1198240308Skib if (obj->z_origin) 1199240308Skib obj->runpath = origin_subst(obj->runpath, obj->origin_path); 1200240308Skib } 1201240308Skib else if (dyn_rpath != NULL) { 1202189959Skib obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val; 1203189959Skib if (obj->z_origin) 1204189959Skib obj->rpath = origin_subst(obj->rpath, obj->origin_path); 1205189959Skib } 1206189959Skib 1207153515Skan if (dyn_soname != NULL) 1208153515Skan object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val); 120934192Sjdp} 121034192Sjdp 1211211413Skibstatic void 1212211413Skibdigest_dynamic(Obj_Entry *obj, int early) 1213211413Skib{ 1214211413Skib const Elf_Dyn *dyn_rpath; 1215211413Skib const Elf_Dyn *dyn_soname; 1216240308Skib const Elf_Dyn *dyn_runpath; 1217211413Skib 1218240308Skib digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath); 1219240308Skib digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath); 1220211413Skib} 1221211413Skib 122234192Sjdp/* 122334192Sjdp * Process a shared object's program header. This is used only for the 122434192Sjdp * main program, when the kernel has already loaded the main program 122534192Sjdp * into memory before calling the dynamic linker. It creates and 122634192Sjdp * returns an Obj_Entry structure. 122734192Sjdp */ 122834192Sjdpstatic Obj_Entry * 122948871Sjdpdigest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) 123034192Sjdp{ 123150608Sjdp Obj_Entry *obj; 123238816Sdfr const Elf_Phdr *phlimit = phdr + phnum; 123338816Sdfr const Elf_Phdr *ph; 1234233694Skib Elf_Addr note_start, note_end; 123534192Sjdp int nsegs = 0; 123634192Sjdp 123750608Sjdp obj = obj_new(); 123834192Sjdp for (ph = phdr; ph < phlimit; ph++) { 1239197931Skib if (ph->p_type != PT_PHDR) 1240197931Skib continue; 1241197931Skib 1242197931Skib obj->phdr = phdr; 1243197931Skib obj->phsize = ph->p_memsz; 1244197931Skib obj->relocbase = (caddr_t)phdr - ph->p_vaddr; 1245197931Skib break; 1246197931Skib } 1247197931Skib 1248217153Skib obj->stack_flags = PF_X | PF_R | PF_W; 1249217153Skib 1250197931Skib for (ph = phdr; ph < phlimit; ph++) { 125134192Sjdp switch (ph->p_type) { 125234192Sjdp 125350610Sjdp case PT_INTERP: 1254197931Skib obj->interp = (const char *)(ph->p_vaddr + obj->relocbase); 125550610Sjdp break; 125650610Sjdp 125734192Sjdp case PT_LOAD: 125834192Sjdp if (nsegs == 0) { /* First load segment */ 125934192Sjdp obj->vaddrbase = trunc_page(ph->p_vaddr); 1260197931Skib obj->mapbase = obj->vaddrbase + obj->relocbase; 126134192Sjdp obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) - 126234192Sjdp obj->vaddrbase; 126334192Sjdp } else { /* Last load segment */ 126434192Sjdp obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) - 126534192Sjdp obj->vaddrbase; 126634192Sjdp } 126734192Sjdp nsegs++; 126834192Sjdp break; 126934192Sjdp 127034192Sjdp case PT_DYNAMIC: 1271197931Skib obj->dynamic = (const Elf_Dyn *)(ph->p_vaddr + obj->relocbase); 127234192Sjdp break; 1273133063Sdfr 1274133063Sdfr case PT_TLS: 1275133063Sdfr obj->tlsindex = 1; 1276133063Sdfr obj->tlssize = ph->p_memsz; 1277133063Sdfr obj->tlsalign = ph->p_align; 1278133063Sdfr obj->tlsinitsize = ph->p_filesz; 1279197931Skib obj->tlsinit = (void*)(ph->p_vaddr + obj->relocbase); 1280133063Sdfr break; 1281217153Skib 1282217153Skib case PT_GNU_STACK: 1283217153Skib obj->stack_flags = ph->p_flags; 1284217153Skib break; 1285231579Skib 1286231579Skib case PT_GNU_RELRO: 1287231579Skib obj->relro_page = obj->relocbase + trunc_page(ph->p_vaddr); 1288231579Skib obj->relro_size = round_page(ph->p_memsz); 1289231579Skib break; 1290233694Skib 1291233694Skib case PT_NOTE: 1292233694Skib note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr; 1293233694Skib note_end = note_start + ph->p_filesz; 1294233694Skib digest_notes(obj, note_start, note_end); 1295233694Skib break; 129634192Sjdp } 129734192Sjdp } 1298107390Skan if (nsegs < 1) { 1299107390Skan _rtld_error("%s: too few PT_LOAD segments", path); 1300107390Skan return NULL; 1301107390Skan } 130234192Sjdp 130334192Sjdp obj->entry = entry; 130434192Sjdp return obj; 130534192Sjdp} 130634192Sjdp 1307233694Skibvoid 1308233694Skibdigest_notes(Obj_Entry *obj, Elf_Addr note_start, Elf_Addr note_end) 1309233694Skib{ 1310233694Skib const Elf_Note *note; 1311233694Skib const char *note_name; 1312233694Skib uintptr_t p; 1313233694Skib 1314233694Skib for (note = (const Elf_Note *)note_start; (Elf_Addr)note < note_end; 1315233694Skib note = (const Elf_Note *)((const char *)(note + 1) + 1316233694Skib roundup2(note->n_namesz, sizeof(Elf32_Addr)) + 1317233694Skib roundup2(note->n_descsz, sizeof(Elf32_Addr)))) { 1318233694Skib if (note->n_namesz != sizeof(NOTE_FREEBSD_VENDOR) || 1319233694Skib note->n_descsz != sizeof(int32_t)) 1320233694Skib continue; 1321233694Skib if (note->n_type != ABI_NOTETYPE && 1322233694Skib note->n_type != CRT_NOINIT_NOTETYPE) 1323233694Skib continue; 1324233694Skib note_name = (const char *)(note + 1); 1325233694Skib if (strncmp(NOTE_FREEBSD_VENDOR, note_name, 1326233694Skib sizeof(NOTE_FREEBSD_VENDOR)) != 0) 1327233694Skib continue; 1328233694Skib switch (note->n_type) { 1329233694Skib case ABI_NOTETYPE: 1330233694Skib /* FreeBSD osrel note */ 1331233694Skib p = (uintptr_t)(note + 1); 1332233694Skib p += roundup2(note->n_namesz, sizeof(Elf32_Addr)); 1333233694Skib obj->osrel = *(const int32_t *)(p); 1334233694Skib dbg("note osrel %d", obj->osrel); 1335233694Skib break; 1336233694Skib case CRT_NOINIT_NOTETYPE: 1337233694Skib /* FreeBSD 'crt does not call init' note */ 1338233694Skib obj->crt_no_init = true; 1339233694Skib dbg("note crt_no_init"); 1340233694Skib break; 1341233694Skib } 1342233694Skib } 1343233694Skib} 1344233694Skib 134534192Sjdpstatic Obj_Entry * 134634192Sjdpdlcheck(void *handle) 134734192Sjdp{ 134834192Sjdp Obj_Entry *obj; 134934192Sjdp 135034192Sjdp for (obj = obj_list; obj != NULL; obj = obj->next) 135134192Sjdp if (obj == (Obj_Entry *) handle) 135234192Sjdp break; 135334192Sjdp 135470677Sjdp if (obj == NULL || obj->refcount == 0 || obj->dl_refcount == 0) { 135534192Sjdp _rtld_error("Invalid shared object handle %p", handle); 135634192Sjdp return NULL; 135734192Sjdp } 135834192Sjdp return obj; 135934192Sjdp} 136034192Sjdp 136134192Sjdp/* 136262801Sjdp * If the given object is already in the donelist, return true. Otherwise 136362801Sjdp * add the object to the list and return false. 136462801Sjdp */ 136562801Sjdpstatic bool 136666056Sjdpdonelist_check(DoneList *dlp, const Obj_Entry *obj) 136762801Sjdp{ 136862801Sjdp unsigned int i; 136962801Sjdp 137062801Sjdp for (i = 0; i < dlp->num_used; i++) 137162801Sjdp if (dlp->objs[i] == obj) 137262801Sjdp return true; 137362801Sjdp /* 137462801Sjdp * Our donelist allocation should always be sufficient. But if 137562801Sjdp * our threads locking isn't working properly, more shared objects 137662801Sjdp * could have been loaded since we allocated the list. That should 137762801Sjdp * never happen, but we'll handle it properly just in case it does. 137862801Sjdp */ 137962801Sjdp if (dlp->num_used < dlp->num_alloc) 138062801Sjdp dlp->objs[dlp->num_used++] = obj; 138162801Sjdp return false; 138262801Sjdp} 138362801Sjdp 138462801Sjdp/* 138534192Sjdp * Hash function for symbol table lookup. Don't even think about changing 138634192Sjdp * this. It is specified by the System V ABI. 138734192Sjdp */ 138838816Sdfrunsigned long 138934192Sjdpelf_hash(const char *name) 139034192Sjdp{ 139134192Sjdp const unsigned char *p = (const unsigned char *) name; 139234192Sjdp unsigned long h = 0; 139334192Sjdp unsigned long g; 139434192Sjdp 139534192Sjdp while (*p != '\0') { 139634192Sjdp h = (h << 4) + *p++; 139734192Sjdp if ((g = h & 0xf0000000) != 0) 139834192Sjdp h ^= g >> 24; 139934192Sjdp h &= ~g; 140034192Sjdp } 140134192Sjdp return h; 140234192Sjdp} 140334192Sjdp 140434192Sjdp/* 1405235396Skib * The GNU hash function is the Daniel J. Bernstein hash clipped to 32 bits 1406235396Skib * unsigned in case it's implemented with a wider type. 1407235396Skib */ 1408235396Skibstatic uint32_t 1409235396Skibgnu_hash(const char *s) 1410235396Skib{ 1411235396Skib uint32_t h; 1412235396Skib unsigned char c; 1413235396Skib 1414235396Skib h = 5381; 1415235396Skib for (c = *s; c != '\0'; c = *++s) 1416235396Skib h = h * 33 + c; 1417235396Skib return (h & 0xffffffff); 1418235396Skib} 1419235396Skib 1420235396Skib/* 142134192Sjdp * Find the library with the given name, and return its full pathname. 142234192Sjdp * The returned string is dynamically allocated. Generates an error 142334192Sjdp * message and returns NULL if the library cannot be found. 142434192Sjdp * 142534192Sjdp * If the second argument is non-NULL, then it refers to an already- 142634192Sjdp * loaded shared object, whose library search path will be searched. 142738836Sjdp * 142838836Sjdp * The search order is: 1429240308Skib * DT_RPATH in the referencing file _unless_ DT_RUNPATH is present (1) 1430240308Skib * DT_RPATH of the main object if DSO without defined DT_RUNPATH (1) 1431122665Stobez * LD_LIBRARY_PATH 1432240308Skib * DT_RUNPATH in the referencing file 1433240308Skib * ldconfig hints (if -z nodefaultlib, filter out default library directories 1434240308Skib * from list) 1435240308Skib * /lib:/usr/lib _unless_ the referencing file is linked with -z nodefaultlib 1436240308Skib * 1437240308Skib * (1) Handled in digest_dynamic2 - rpath left NULL if runpath defined. 143834192Sjdp */ 143934192Sjdpstatic char * 1440113229Smdoddfind_library(const char *xname, const Obj_Entry *refobj) 144134192Sjdp{ 144234192Sjdp char *pathname; 1443113229Smdodd char *name; 1444240801Skib bool nodeflib, objgiven; 144534192Sjdp 1446240308Skib objgiven = refobj != NULL; 1447113229Smdodd if (strchr(xname, '/') != NULL) { /* Hard coded pathname */ 1448113229Smdodd if (xname[0] != '/' && !trust) { 144934192Sjdp _rtld_error("Absolute pathname required for shared object \"%s\"", 1450113229Smdodd xname); 145134192Sjdp return NULL; 145234192Sjdp } 1453250040Skib if (objgiven && refobj->z_origin) { 1454250040Skib return (origin_subst(__DECONST(char *, xname), 1455250040Skib refobj->origin_path)); 1456250040Skib } else { 1457250040Skib return (xstrdup(xname)); 1458250040Skib } 145934192Sjdp } 146034192Sjdp 1461240308Skib if (libmap_disable || !objgiven || 1462116539Smdodd (name = lm_find(refobj->path, xname)) == NULL) 1463113229Smdodd name = (char *)xname; 1464113229Smdodd 146534192Sjdp dbg(" Searching for \"%s\"", name); 146634192Sjdp 1467240308Skib /* 1468240308Skib * If refobj->rpath != NULL, then refobj->runpath is NULL. Fall 1469240308Skib * back to pre-conforming behaviour if user requested so with 1470240308Skib * LD_LIBRARY_PATH_RPATH environment variable and ignore -z 1471240308Skib * nodeflib. 1472240308Skib */ 1473240308Skib if (objgiven && refobj->rpath != NULL && ld_library_path_rpath) { 1474240308Skib if ((pathname = search_library_path(name, ld_library_path)) != NULL || 1475240308Skib (refobj != NULL && 1476240308Skib (pathname = search_library_path(name, refobj->rpath)) != NULL) || 1477240308Skib (pathname = search_library_path(name, gethints(false))) != NULL || 1478240308Skib (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL) 1479240308Skib return (pathname); 1480240308Skib } else { 1481240801Skib nodeflib = objgiven ? refobj->z_nodeflib : false; 1482240308Skib if ((objgiven && 1483240308Skib (pathname = search_library_path(name, refobj->rpath)) != NULL) || 1484240308Skib (objgiven && refobj->runpath == NULL && refobj != obj_main && 1485240308Skib (pathname = search_library_path(name, obj_main->rpath)) != NULL) || 1486240308Skib (pathname = search_library_path(name, ld_library_path)) != NULL || 1487240308Skib (objgiven && 1488240308Skib (pathname = search_library_path(name, refobj->runpath)) != NULL) || 1489240801Skib (pathname = search_library_path(name, gethints(nodeflib))) != NULL || 1490240801Skib (objgiven && !nodeflib && 1491240308Skib (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)) 1492240308Skib return (pathname); 1493240308Skib } 149434192Sjdp 1495240308Skib if (objgiven && refobj->path != NULL) { 1496129792Seik _rtld_error("Shared object \"%s\" not found, required by \"%s\"", 1497129792Seik name, basename(refobj->path)); 1498129792Seik } else { 1499129792Seik _rtld_error("Shared object \"%s\" not found", name); 1500129792Seik } 150134192Sjdp return NULL; 150234192Sjdp} 150334192Sjdp 150434192Sjdp/* 150534192Sjdp * Given a symbol number in a referencing object, find the corresponding 150634192Sjdp * definition of the symbol. Returns a pointer to the symbol, or NULL if 150734192Sjdp * no definition was found. Returns a pointer to the Obj_Entry of the 150834192Sjdp * defining object via the reference parameter DEFOBJ_OUT. 150934192Sjdp */ 151038816Sdfrconst Elf_Sym * 151166056Sjdpfind_symdef(unsigned long symnum, const Obj_Entry *refobj, 1512216695Skib const Obj_Entry **defobj_out, int flags, SymCache *cache, 1513216695Skib RtldLockState *lockstate) 151434192Sjdp{ 151538816Sdfr const Elf_Sym *ref; 151650606Sjdp const Elf_Sym *def; 151750606Sjdp const Obj_Entry *defobj; 1518216695Skib SymLook req; 151934192Sjdp const char *name; 1520216695Skib int res; 152134192Sjdp 152276296Sjdp /* 152376296Sjdp * If we have already found this symbol, get the information from 152476296Sjdp * the cache. 152576296Sjdp */ 1526235396Skib if (symnum >= refobj->dynsymcount) 152776296Sjdp return NULL; /* Bad object */ 152876296Sjdp if (cache != NULL && cache[symnum].sym != NULL) { 152976296Sjdp *defobj_out = cache[symnum].obj; 153076296Sjdp return cache[symnum].sym; 153176296Sjdp } 153276296Sjdp 153334192Sjdp ref = refobj->symtab + symnum; 153434192Sjdp name = refobj->strtab + ref->st_name; 1535216695Skib def = NULL; 153650607Sjdp defobj = NULL; 153734192Sjdp 153895539Smarcel /* 153995539Smarcel * We don't have to do a full scale lookup if the symbol is local. 154095539Smarcel * We know it will bind to the instance in this load module; to 154195539Smarcel * which we already have a pointer (ie ref). By not doing a lookup, 154295539Smarcel * we not only improve performance, but it also avoids unresolvable 154395539Smarcel * symbols when local symbols are not in the hash table. This has 154495539Smarcel * been seen with the ia64 toolchain. 154595539Smarcel */ 154695539Smarcel if (ELF_ST_BIND(ref->st_info) != STB_LOCAL) { 154795539Smarcel if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) { 154893610Sjake _rtld_error("%s: Bogus symbol table entry %lu", refobj->path, 154993610Sjake symnum); 155093610Sjake } 1551216695Skib symlook_init(&req, name); 1552216695Skib req.flags = flags; 1553216695Skib req.ventry = fetch_ventry(refobj, symnum); 1554216695Skib req.lockstate = lockstate; 1555216695Skib res = symlook_default(&req, refobj); 1556216695Skib if (res == 0) { 1557216695Skib def = req.sym_out; 1558216695Skib defobj = req.defobj_out; 1559216695Skib } 156095539Smarcel } else { 156193610Sjake def = ref; 156293610Sjake defobj = refobj; 156395539Smarcel } 156434192Sjdp 156550606Sjdp /* 156650608Sjdp * If we found no definition and the reference is weak, treat the 156750606Sjdp * symbol as having the value zero. 156850606Sjdp */ 156950608Sjdp if (def == NULL && ELF_ST_BIND(ref->st_info) == STB_WEAK) { 157050608Sjdp def = &sym_zero; 157150608Sjdp defobj = obj_main; 157245320Sjdp } 157345320Sjdp 157476296Sjdp if (def != NULL) { 157550608Sjdp *defobj_out = defobj; 157676296Sjdp /* Record the information in the cache to avoid subsequent lookups. */ 157776296Sjdp if (cache != NULL) { 157876296Sjdp cache[symnum].sym = def; 157976296Sjdp cache[symnum].obj = defobj; 158076296Sjdp } 158185004Sdfr } else { 158285004Sdfr if (refobj != &obj_rtld) 158385004Sdfr _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name); 158485004Sdfr } 158550608Sjdp return def; 158634192Sjdp} 158734192Sjdp 158834192Sjdp/* 158938836Sjdp * Return the search path from the ldconfig hints file, reading it if 1590240308Skib * necessary. If nostdlib is true, then the default search paths are 1591240308Skib * not added to result. 1592240308Skib * 1593240308Skib * Returns NULL if there are problems with the hints file, 159438836Sjdp * or if the search path there is empty. 159538836Sjdp */ 159638836Sjdpstatic const char * 1597240308Skibgethints(bool nostdlib) 159838836Sjdp{ 1599240308Skib static char *hints, *filtered_path; 160038836Sjdp struct elfhints_hdr hdr; 1601240308Skib struct fill_search_info_args sargs, hargs; 1602240308Skib struct dl_serinfo smeta, hmeta, *SLPinfo, *hintinfo; 1603240308Skib struct dl_serpath *SLPpath, *hintpath; 160438836Sjdp char *p; 1605240308Skib unsigned int SLPndx, hintndx, fndx, fcount; 1606240308Skib int fd; 1607240308Skib size_t flen; 1608240308Skib bool skip; 160938836Sjdp 1610240308Skib /* First call, read the hints file */ 1611240308Skib if (hints == NULL) { 1612240308Skib /* Keep from trying again in case the hints file is bad. */ 1613240308Skib hints = ""; 161438836Sjdp 1615240308Skib if ((fd = open(ld_elf_hints_path, O_RDONLY)) == -1) 1616240308Skib return (NULL); 1617240308Skib if (read(fd, &hdr, sizeof hdr) != sizeof hdr || 1618240308Skib hdr.magic != ELFHINTS_MAGIC || 1619240308Skib hdr.version != 1) { 1620240308Skib close(fd); 1621240308Skib return (NULL); 1622240308Skib } 1623240308Skib p = xmalloc(hdr.dirlistlen + 1); 1624240308Skib if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 || 1625240308Skib read(fd, p, hdr.dirlistlen + 1) != 1626240308Skib (ssize_t)hdr.dirlistlen + 1) { 1627240308Skib free(p); 1628240308Skib close(fd); 1629240308Skib return (NULL); 1630240308Skib } 1631240308Skib hints = p; 1632240308Skib close(fd); 163338836Sjdp } 1634240308Skib 1635240308Skib /* 1636240308Skib * If caller agreed to receive list which includes the default 1637240308Skib * paths, we are done. Otherwise, if we still did not 1638240308Skib * calculated filtered result, do it now. 1639240308Skib */ 1640240308Skib if (!nostdlib) 1641240308Skib return (hints[0] != '\0' ? hints : NULL); 1642240308Skib if (filtered_path != NULL) 1643240308Skib goto filt_ret; 1644240308Skib 1645240308Skib /* 1646240308Skib * Obtain the list of all configured search paths, and the 1647240308Skib * list of the default paths. 1648240308Skib * 1649240308Skib * First estimate the size of the results. 1650240308Skib */ 1651240308Skib smeta.dls_size = __offsetof(struct dl_serinfo, dls_serpath); 1652240308Skib smeta.dls_cnt = 0; 1653240308Skib hmeta.dls_size = __offsetof(struct dl_serinfo, dls_serpath); 1654240308Skib hmeta.dls_cnt = 0; 1655240308Skib 1656240308Skib sargs.request = RTLD_DI_SERINFOSIZE; 1657240308Skib sargs.serinfo = &smeta; 1658240308Skib hargs.request = RTLD_DI_SERINFOSIZE; 1659240308Skib hargs.serinfo = &hmeta; 1660240308Skib 1661240308Skib path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs); 1662240308Skib path_enumerate(p, fill_search_info, &hargs); 1663240308Skib 1664240308Skib SLPinfo = xmalloc(smeta.dls_size); 1665240308Skib hintinfo = xmalloc(hmeta.dls_size); 1666240308Skib 1667240308Skib /* 1668240308Skib * Next fetch both sets of paths. 1669240308Skib */ 1670240308Skib sargs.request = RTLD_DI_SERINFO; 1671240308Skib sargs.serinfo = SLPinfo; 1672240308Skib sargs.serpath = &SLPinfo->dls_serpath[0]; 1673240308Skib sargs.strspace = (char *)&SLPinfo->dls_serpath[smeta.dls_cnt]; 1674240308Skib 1675240308Skib hargs.request = RTLD_DI_SERINFO; 1676240308Skib hargs.serinfo = hintinfo; 1677240308Skib hargs.serpath = &hintinfo->dls_serpath[0]; 1678240308Skib hargs.strspace = (char *)&hintinfo->dls_serpath[hmeta.dls_cnt]; 1679240308Skib 1680240308Skib path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs); 1681240308Skib path_enumerate(p, fill_search_info, &hargs); 1682240308Skib 1683240308Skib /* 1684240308Skib * Now calculate the difference between two sets, by excluding 1685240308Skib * standard paths from the full set. 1686240308Skib */ 1687240308Skib fndx = 0; 1688240308Skib fcount = 0; 1689240308Skib filtered_path = xmalloc(hdr.dirlistlen + 1); 1690240308Skib hintpath = &hintinfo->dls_serpath[0]; 1691240308Skib for (hintndx = 0; hintndx < hmeta.dls_cnt; hintndx++, hintpath++) { 1692240308Skib skip = false; 1693240308Skib SLPpath = &SLPinfo->dls_serpath[0]; 1694240308Skib /* 1695240308Skib * Check each standard path against current. 1696240308Skib */ 1697240308Skib for (SLPndx = 0; SLPndx < smeta.dls_cnt; SLPndx++, SLPpath++) { 1698240308Skib /* matched, skip the path */ 1699240308Skib if (!strcmp(hintpath->dls_name, SLPpath->dls_name)) { 1700240308Skib skip = true; 1701240308Skib break; 1702240308Skib } 1703240308Skib } 1704240308Skib if (skip) 1705240308Skib continue; 1706240308Skib /* 1707240308Skib * Not matched against any standard path, add the path 1708240308Skib * to result. Separate consequtive paths with ':'. 1709240308Skib */ 1710240308Skib if (fcount > 0) { 1711240308Skib filtered_path[fndx] = ':'; 1712240308Skib fndx++; 1713240308Skib } 1714240308Skib fcount++; 1715240308Skib flen = strlen(hintpath->dls_name); 1716240308Skib strncpy((filtered_path + fndx), hintpath->dls_name, flen); 1717240308Skib fndx += flen; 171838836Sjdp } 1719240308Skib filtered_path[fndx] = '\0'; 1720240308Skib 1721240308Skib free(SLPinfo); 1722240308Skib free(hintinfo); 1723240308Skib 1724240308Skibfilt_ret: 1725240308Skib return (filtered_path[0] != '\0' ? filtered_path : NULL); 172638836Sjdp} 172738836Sjdp 172850608Sjdpstatic void 172950608Sjdpinit_dag(Obj_Entry *root) 173050608Sjdp{ 1731218051Skan const Needed_Entry *needed; 1732218051Skan const Objlist_Entry *elm; 173362801Sjdp DoneList donelist; 173462801Sjdp 1735214728Skib if (root->dag_inited) 1736214776Skib return; 173762801Sjdp donelist_init(&donelist); 173850608Sjdp 1739218051Skan /* Root object belongs to own DAG. */ 1740218051Skan objlist_push_tail(&root->dldags, root); 1741218051Skan objlist_push_tail(&root->dagmembers, root); 1742218051Skan donelist_check(&donelist, root); 174350608Sjdp 1744218051Skan /* 1745218051Skan * Add dependencies of root object to DAG in breadth order 1746218051Skan * by exploiting the fact that each new object get added 1747218051Skan * to the tail of the dagmembers list. 1748218051Skan */ 1749218051Skan STAILQ_FOREACH(elm, &root->dagmembers, link) { 1750218051Skan for (needed = elm->obj->needed; needed != NULL; needed = needed->next) { 1751218051Skan if (needed->obj == NULL || donelist_check(&donelist, needed->obj)) 1752218051Skan continue; 1753218051Skan objlist_push_tail(&needed->obj->dldags, root); 1754218051Skan objlist_push_tail(&root->dagmembers, needed->obj); 1755218051Skan } 1756218051Skan } 1757218051Skan root->dag_inited = true; 175850608Sjdp} 175950608Sjdp 1760239439Skanstatic void 1761239439Skanprocess_nodelete(Obj_Entry *root) 1762239439Skan{ 1763239439Skan const Objlist_Entry *elm; 1764239439Skan 1765239439Skan /* 1766239439Skan * Walk over object DAG and process every dependent object that 1767239439Skan * is marked as DF_1_NODELETE. They need to grow their own DAG, 1768239439Skan * which then should have its reference upped separately. 1769239439Skan */ 1770239439Skan STAILQ_FOREACH(elm, &root->dagmembers, link) { 1771239439Skan if (elm->obj != NULL && elm->obj->z_nodelete && 1772239439Skan !elm->obj->ref_nodel) { 1773239439Skan dbg("obj %s nodelete", elm->obj->path); 1774239439Skan init_dag(elm->obj); 1775239439Skan ref_dag(elm->obj); 1776239439Skan elm->obj->ref_nodel = true; 1777239439Skan } 1778239439Skan } 1779239439Skan} 178038836Sjdp/* 178134192Sjdp * Initialize the dynamic linker. The argument is the address at which 178234192Sjdp * the dynamic linker has been mapped into memory. The primary task of 178334192Sjdp * this function is to relocate the dynamic linker. 178434192Sjdp */ 178534192Sjdpstatic void 1786211413Skibinit_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info) 178734192Sjdp{ 178893610Sjake Obj_Entry objtmp; /* Temporary rtld object */ 1789211413Skib const Elf_Dyn *dyn_rpath; 1790211413Skib const Elf_Dyn *dyn_soname; 1791240308Skib const Elf_Dyn *dyn_runpath; 179293610Sjake 179339306Sjdp /* 179439306Sjdp * Conjure up an Obj_Entry structure for the dynamic linker. 179539306Sjdp * 1796194689Sed * The "path" member can't be initialized yet because string constants 1797194705Sed * cannot yet be accessed. Below we will set it correctly. 179839306Sjdp */ 1799124020Sdfr memset(&objtmp, 0, sizeof(objtmp)); 180093610Sjake objtmp.path = NULL; 180193610Sjake objtmp.rtld = true; 180293610Sjake objtmp.mapbase = mapbase; 180345501Sjdp#ifdef PIC 180493610Sjake objtmp.relocbase = mapbase; 180538816Sdfr#endif 1806130661Stmm if (RTLD_IS_DYNAMIC()) { 180793610Sjake objtmp.dynamic = rtld_dynamic(&objtmp); 1808240308Skib digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname, &dyn_runpath); 180993610Sjake assert(objtmp.needed == NULL); 1810177924Simp#if !defined(__mips__) 1811218025Spluknet /* MIPS has a bogus DT_TEXTREL. */ 181293610Sjake assert(!objtmp.textrel); 1813177924Simp#endif 181434192Sjdp 181545501Sjdp /* 181645501Sjdp * Temporarily put the dynamic linker entry into the object list, so 181745501Sjdp * that symbols can be found. 181845501Sjdp */ 181934192Sjdp 1820233831Skib relocate_objects(&objtmp, true, &objtmp, 0, NULL); 182145501Sjdp } 182234192Sjdp 182393610Sjake /* Initialize the object list. */ 182434192Sjdp obj_tail = &obj_list; 182535529Sdfr 182693610Sjake /* Now that non-local variables can be accesses, copy out obj_rtld. */ 182793610Sjake memcpy(&obj_rtld, &objtmp, sizeof(obj_rtld)); 182893610Sjake 1829211413Skib if (aux_info[AT_PAGESZ] != NULL) 1830211413Skib pagesize = aux_info[AT_PAGESZ]->a_un.a_val; 1831211413Skib if (aux_info[AT_OSRELDATE] != NULL) 1832211413Skib osreldate = aux_info[AT_OSRELDATE]->a_un.a_val; 1833211413Skib 1834240308Skib digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname, dyn_runpath); 1835211413Skib 183639306Sjdp /* Replace the path with a dynamically allocated copy. */ 183793610Sjake obj_rtld.path = xstrdup(PATH_RTLD); 183839306Sjdp 183935529Sdfr r_debug.r_brk = r_debug_state; 184035529Sdfr r_debug.r_state = RT_CONSISTENT; 184134192Sjdp} 184234192Sjdp 184363870Sjdp/* 184463870Sjdp * Add the init functions from a needed object list (and its recursive 184563870Sjdp * needed objects) to "list". This is not used directly; it is a helper 184663870Sjdp * function for initlist_add_objects(). The write lock must be held 184763870Sjdp * when this function is called. 184863870Sjdp */ 184963870Sjdpstatic void 185063870Sjdpinitlist_add_neededs(Needed_Entry *needed, Objlist *list) 185163870Sjdp{ 185263870Sjdp /* Recursively process the successor needed objects. */ 185363870Sjdp if (needed->next != NULL) 185463870Sjdp initlist_add_neededs(needed->next, list); 185563870Sjdp 185663870Sjdp /* Process the current needed object. */ 185763870Sjdp if (needed->obj != NULL) 185863870Sjdp initlist_add_objects(needed->obj, &needed->obj->next, list); 185963870Sjdp} 186063870Sjdp 186163870Sjdp/* 186263870Sjdp * Scan all of the DAGs rooted in the range of objects from "obj" to 186363870Sjdp * "tail" and add their init functions to "list". This recurses over 186463870Sjdp * the DAGs and ensure the proper init ordering such that each object's 186563870Sjdp * needed libraries are initialized before the object itself. At the 186663870Sjdp * same time, this function adds the objects to the global finalization 186763870Sjdp * list "list_fini" in the opposite order. The write lock must be 186863870Sjdp * held when this function is called. 186963870Sjdp */ 187063870Sjdpstatic void 187163870Sjdpinitlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, Objlist *list) 187263870Sjdp{ 1873233831Skib 1874194531Skan if (obj->init_scanned || obj->init_done) 187563870Sjdp return; 1876194531Skan obj->init_scanned = true; 187763870Sjdp 187863870Sjdp /* Recursively process the successor objects. */ 187963870Sjdp if (&obj->next != tail) 188063870Sjdp initlist_add_objects(obj->next, tail, list); 188163870Sjdp 188263870Sjdp /* Recursively process the needed objects. */ 188363870Sjdp if (obj->needed != NULL) 188463870Sjdp initlist_add_neededs(obj->needed, list); 1885233831Skib if (obj->needed_filtees != NULL) 1886233831Skib initlist_add_neededs(obj->needed_filtees, list); 1887233831Skib if (obj->needed_aux_filtees != NULL) 1888233831Skib initlist_add_neededs(obj->needed_aux_filtees, list); 188963870Sjdp 189063870Sjdp /* Add the object to the init list. */ 1891233694Skib if (obj->preinit_array != (Elf_Addr)NULL || obj->init != (Elf_Addr)NULL || 1892233694Skib obj->init_array != (Elf_Addr)NULL) 189363870Sjdp objlist_push_tail(list, obj); 189463870Sjdp 189563870Sjdp /* Add the object to the global fini list in the reverse order. */ 1896233694Skib if ((obj->fini != (Elf_Addr)NULL || obj->fini_array != (Elf_Addr)NULL) 1897233694Skib && !obj->on_fini_list) { 189863870Sjdp objlist_push_head(&list_fini, obj); 1899194531Skan obj->on_fini_list = true; 1900194531Skan } 190163870Sjdp} 190263870Sjdp 190385004Sdfr#ifndef FPTR_TARGET 190485004Sdfr#define FPTR_TARGET(f) ((Elf_Addr) (f)) 190585004Sdfr#endif 190685004Sdfr 1907216695Skibstatic void 1908216695Skibfree_needed_filtees(Needed_Entry *n) 1909216695Skib{ 1910216695Skib Needed_Entry *needed, *needed1; 1911216695Skib 1912216695Skib for (needed = n; needed != NULL; needed = needed->next) { 1913216695Skib if (needed->obj != NULL) { 1914216695Skib dlclose(needed->obj); 1915216695Skib needed->obj = NULL; 1916216695Skib } 1917216695Skib } 1918216695Skib for (needed = n; needed != NULL; needed = needed1) { 1919216695Skib needed1 = needed->next; 1920216695Skib free(needed); 1921216695Skib } 1922216695Skib} 1923216695Skib 1924216695Skibstatic void 1925216695Skibunload_filtees(Obj_Entry *obj) 1926216695Skib{ 1927216695Skib 1928216695Skib free_needed_filtees(obj->needed_filtees); 1929216695Skib obj->needed_filtees = NULL; 1930216695Skib free_needed_filtees(obj->needed_aux_filtees); 1931216695Skib obj->needed_aux_filtees = NULL; 1932216695Skib obj->filtees_loaded = false; 1933216695Skib} 1934216695Skib 1935216695Skibstatic void 1936234454Skibload_filtee1(Obj_Entry *obj, Needed_Entry *needed, int flags, 1937234454Skib RtldLockState *lockstate) 1938216695Skib{ 1939216695Skib 1940216695Skib for (; needed != NULL; needed = needed->next) { 1941230410Skib needed->obj = dlopen_object(obj->strtab + needed->name, -1, obj, 1942216695Skib flags, ((ld_loadfltr || obj->z_loadfltr) ? RTLD_NOW : RTLD_LAZY) | 1943234454Skib RTLD_LOCAL, lockstate); 1944216695Skib } 1945216695Skib} 1946216695Skib 1947216695Skibstatic void 1948216695Skibload_filtees(Obj_Entry *obj, int flags, RtldLockState *lockstate) 1949216695Skib{ 1950216695Skib 1951216695Skib lock_restart_for_upgrade(lockstate); 1952216695Skib if (!obj->filtees_loaded) { 1953234454Skib load_filtee1(obj, obj->needed_filtees, flags, lockstate); 1954234454Skib load_filtee1(obj, obj->needed_aux_filtees, flags, lockstate); 1955216695Skib obj->filtees_loaded = true; 1956216695Skib } 1957216695Skib} 1958216695Skib 1959216695Skibstatic int 1960216695Skibprocess_needed(Obj_Entry *obj, Needed_Entry *needed, int flags) 1961216695Skib{ 1962216695Skib Obj_Entry *obj1; 1963216695Skib 1964216695Skib for (; needed != NULL; needed = needed->next) { 1965230410Skib obj1 = needed->obj = load_object(obj->strtab + needed->name, -1, obj, 1966216695Skib flags & ~RTLD_LO_NOLOAD); 1967216695Skib if (obj1 == NULL && !ld_tracing && (flags & RTLD_LO_FILTEES) == 0) 1968216695Skib return (-1); 1969216695Skib } 1970216695Skib return (0); 1971216695Skib} 1972216695Skib 197334192Sjdp/* 197434192Sjdp * Given a shared object, traverse its list of needed objects, and load 197534192Sjdp * each of them. Returns 0 on success. Generates an error message and 197634192Sjdp * returns -1 on failure. 197734192Sjdp */ 197834192Sjdpstatic int 1979199829Skibload_needed_objects(Obj_Entry *first, int flags) 198034192Sjdp{ 1981216695Skib Obj_Entry *obj; 198234192Sjdp 198334192Sjdp for (obj = first; obj != NULL; obj = obj->next) { 1984216695Skib if (process_needed(obj, obj->needed, flags) == -1) 1985216695Skib return (-1); 198634192Sjdp } 1987216695Skib return (0); 198834192Sjdp} 198934192Sjdp 199039551Sjdpstatic int 199139551Sjdpload_preload_objects(void) 199239551Sjdp{ 199339551Sjdp char *p = ld_preload; 1994256436Skib Obj_Entry *obj; 199556405Sjdp static const char delim[] = " \t:;"; 199639551Sjdp 199739551Sjdp if (p == NULL) 1998126643Smarkm return 0; 199939551Sjdp 200056405Sjdp p += strspn(p, delim); 200139551Sjdp while (*p != '\0') { 200256405Sjdp size_t len = strcspn(p, delim); 200339551Sjdp char savech; 200439551Sjdp 200539551Sjdp savech = p[len]; 200639551Sjdp p[len] = '\0'; 2007256436Skib obj = load_object(p, -1, NULL, 0); 2008256436Skib if (obj == NULL) 200939551Sjdp return -1; /* XXX - cleanup */ 2010256436Skib obj->z_interpose = true; 201139551Sjdp p[len] = savech; 201239551Sjdp p += len; 201356405Sjdp p += strspn(p, delim); 201439551Sjdp } 2015165916Sjhb LD_UTRACE(UTRACE_PRELOAD_FINISHED, NULL, NULL, 0, 0, NULL); 201639551Sjdp return 0; 201739551Sjdp} 201839551Sjdp 2019230410Skibstatic const char * 2020230410Skibprintable_path(const char *path) 2021230410Skib{ 2022230410Skib 2023230410Skib return (path == NULL ? "<unknown>" : path); 2024230410Skib} 2025230410Skib 202634192Sjdp/* 2027230410Skib * Load a shared object into memory, if it is not already loaded. The 2028230410Skib * object may be specified by name or by user-supplied file descriptor 2029230410Skib * fd_u. In the later case, the fd_u descriptor is not closed, but its 2030230410Skib * duplicate is. 203134192Sjdp * 203234192Sjdp * Returns a pointer to the Obj_Entry for the object. Returns NULL 203334192Sjdp * on failure. 203434192Sjdp */ 203534192Sjdpstatic Obj_Entry * 2036230410Skibload_object(const char *name, int fd_u, const Obj_Entry *refobj, int flags) 203734192Sjdp{ 203834192Sjdp Obj_Entry *obj; 2039230410Skib int fd; 204050609Sjdp struct stat sb; 2041153515Skan char *path; 204234192Sjdp 2043230410Skib if (name != NULL) { 2044230410Skib for (obj = obj_list->next; obj != NULL; obj = obj->next) { 2045230410Skib if (object_match_name(obj, name)) 2046230410Skib return (obj); 2047230410Skib } 204834192Sjdp 2049230410Skib path = find_library(name, refobj); 2050230410Skib if (path == NULL) 2051230410Skib return (NULL); 2052230410Skib } else 2053230410Skib path = NULL; 2054153515Skan 205550609Sjdp /* 2056230410Skib * If we didn't find a match by pathname, or the name is not 2057230410Skib * supplied, open the file and check again by device and inode. 2058230410Skib * This avoids false mismatches caused by multiple links or ".." 2059230410Skib * in pathnames. 206050609Sjdp * 206150609Sjdp * To avoid a race, we open the file and use fstat() rather than 206250609Sjdp * using stat(). 206350609Sjdp */ 2064230410Skib fd = -1; 2065230410Skib if (fd_u == -1) { 2066230410Skib if ((fd = open(path, O_RDONLY)) == -1) { 2067230410Skib _rtld_error("Cannot open \"%s\"", path); 2068230410Skib free(path); 2069230410Skib return (NULL); 2070230410Skib } 2071230410Skib } else { 2072230410Skib fd = dup(fd_u); 2073230410Skib if (fd == -1) { 2074230410Skib _rtld_error("Cannot dup fd"); 2075230410Skib free(path); 2076230410Skib return (NULL); 2077230410Skib } 2078153515Skan } 2079153515Skan if (fstat(fd, &sb) == -1) { 2080230410Skib _rtld_error("Cannot fstat \"%s\"", printable_path(path)); 2081153515Skan close(fd); 2082153515Skan free(path); 2083153515Skan return NULL; 2084153515Skan } 2085220004Savg for (obj = obj_list->next; obj != NULL; obj = obj->next) 2086220004Savg if (obj->ino == sb.st_ino && obj->dev == sb.st_dev) 2087153515Skan break; 2088230410Skib if (obj != NULL && name != NULL) { 2089153515Skan object_add_name(obj, name); 2090153515Skan free(path); 2091153515Skan close(fd); 2092153515Skan return obj; 2093153515Skan } 2094208763Skan if (flags & RTLD_LO_NOLOAD) { 2095208763Skan free(path); 2096227965Skib close(fd); 2097195745Skib return (NULL); 2098208763Skan } 209950609Sjdp 2100153515Skan /* First use of this object, so we must map it in */ 2101199829Skib obj = do_load_object(fd, name, path, &sb, flags); 2102153515Skan if (obj == NULL) 2103153515Skan free(path); 2104153515Skan close(fd); 2105153515Skan 2106153515Skan return obj; 2107153515Skan} 2108153515Skan 2109153515Skanstatic Obj_Entry * 2110199829Skibdo_load_object(int fd, const char *name, char *path, struct stat *sbp, 2111199829Skib int flags) 2112153515Skan{ 2113153515Skan Obj_Entry *obj; 2114153515Skan struct statfs fs; 2115153515Skan 2116153515Skan /* 2117153515Skan * but first, make sure that environment variables haven't been 2118153515Skan * used to circumvent the noexec flag on a filesystem. 2119153515Skan */ 2120153515Skan if (dangerous_ld_env) { 2121153515Skan if (fstatfs(fd, &fs) != 0) { 2122230410Skib _rtld_error("Cannot fstatfs \"%s\"", printable_path(path)); 2123230410Skib return NULL; 2124144062Scperciva } 2125153515Skan if (fs.f_flags & MNT_NOEXEC) { 2126153515Skan _rtld_error("Cannot execute objects on %s\n", fs.f_mntonname); 212734192Sjdp return NULL; 212834192Sjdp } 2129153515Skan } 2130230410Skib dbg("loading \"%s\"", printable_path(path)); 2131230410Skib obj = map_object(fd, printable_path(path), sbp); 2132153515Skan if (obj == NULL) 2133153515Skan return NULL; 213434192Sjdp 2135230410Skib /* 2136230410Skib * If DT_SONAME is present in the object, digest_dynamic2 already 2137230410Skib * added it to the object names. 2138230410Skib */ 2139230410Skib if (name != NULL) 2140230410Skib object_add_name(obj, name); 2141153515Skan obj->path = path; 2142153515Skan digest_dynamic(obj, 0); 2143235396Skib dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d", obj->path, 2144235396Skib obj->valid_hash_sysv, obj->valid_hash_gnu, obj->dynsymcount); 2145199877Skib if (obj->z_noopen && (flags & (RTLD_LO_DLOPEN | RTLD_LO_TRACE)) == 2146199877Skib RTLD_LO_DLOPEN) { 2147199829Skib dbg("refusing to load non-loadable \"%s\"", obj->path); 2148199877Skib _rtld_error("Cannot dlopen non-loadable %s", obj->path); 2149199829Skib munmap(obj->mapbase, obj->mapsize); 2150199829Skib obj_free(obj); 2151199829Skib return (NULL); 2152199829Skib } 215334192Sjdp 2154153515Skan *obj_tail = obj; 2155153515Skan obj_tail = &obj->next; 2156153515Skan obj_count++; 2157168312Skan obj_loads++; 2158153515Skan linkmap_add(obj); /* for GDB & dlinfo() */ 2159217153Skib max_stack_flags |= obj->stack_flags; 216034192Sjdp 2161153515Skan dbg(" %p .. %p: %s", obj->mapbase, 2162153515Skan obj->mapbase + obj->mapsize - 1, obj->path); 2163153515Skan if (obj->textrel) 2164153515Skan dbg(" WARNING: %s has impure text", obj->path); 2165165916Sjhb LD_UTRACE(UTRACE_LOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0, 2166165916Sjhb obj->path); 216734192Sjdp 216834192Sjdp return obj; 216934192Sjdp} 217034192Sjdp 217134192Sjdpstatic Obj_Entry * 217234192Sjdpobj_from_addr(const void *addr) 217334192Sjdp{ 217434192Sjdp Obj_Entry *obj; 217534192Sjdp 217634192Sjdp for (obj = obj_list; obj != NULL; obj = obj->next) { 217734192Sjdp if (addr < (void *) obj->mapbase) 217834192Sjdp continue; 2179126236Skan if (addr < (void *) (obj->mapbase + obj->mapsize)) 218034192Sjdp return obj; 218134192Sjdp } 218234192Sjdp return NULL; 218334192Sjdp} 218434192Sjdp 2185233694Skibstatic void 2186233694Skibpreinit_main(void) 2187233694Skib{ 2188233694Skib Elf_Addr *preinit_addr; 2189233694Skib int index; 2190233694Skib 2191233694Skib preinit_addr = (Elf_Addr *)obj_main->preinit_array; 2192233694Skib if (preinit_addr == NULL) 2193233694Skib return; 2194233694Skib 2195233694Skib for (index = 0; index < obj_main->preinit_array_num; index++) { 2196233694Skib if (preinit_addr[index] != 0 && preinit_addr[index] != 1) { 2197233694Skib dbg("calling preinit function for %s at %p", obj_main->path, 2198233694Skib (void *)preinit_addr[index]); 2199233694Skib LD_UTRACE(UTRACE_INIT_CALL, obj_main, (void *)preinit_addr[index], 2200233694Skib 0, 0, obj_main->path); 2201233694Skib call_init_pointer(obj_main, preinit_addr[index]); 2202233694Skib } 2203233694Skib } 2204233694Skib} 2205233694Skib 220663870Sjdp/* 220763870Sjdp * Call the finalization functions for each of the objects in "list" 2208216489Sjh * belonging to the DAG of "root" and referenced once. If NULL "root" 2209216489Sjh * is specified, every finalization function will be called regardless 2210216489Sjh * of the reference count and the list elements won't be freed. All of 2211216489Sjh * the objects are expected to have non-NULL fini functions. 221263870Sjdp */ 221350608Sjdpstatic void 2214216695Skibobjlist_call_fini(Objlist *list, Obj_Entry *root, RtldLockState *lockstate) 221550608Sjdp{ 2216216489Sjh Objlist_Entry *elm; 221770677Sjdp char *saved_msg; 2218233694Skib Elf_Addr *fini_addr; 2219233694Skib int index; 222050608Sjdp 2221216489Sjh assert(root == NULL || root->refcount == 1); 2222216489Sjh 222370677Sjdp /* 222470677Sjdp * Preserve the current error message since a fini function might 222570677Sjdp * call into the dynamic linker and overwrite it. 222670677Sjdp */ 222770677Sjdp saved_msg = errmsg_save(); 2228216489Sjh do { 2229216489Sjh STAILQ_FOREACH(elm, list, link) { 2230216489Sjh if (root != NULL && (elm->obj->refcount != 1 || 2231216489Sjh objlist_find(&root->dagmembers, elm->obj) == NULL)) 2232216489Sjh continue; 2233194531Skan /* Remove object from fini list to prevent recursive invocation. */ 2234194531Skan STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link); 2235216489Sjh /* 2236216489Sjh * XXX: If a dlopen() call references an object while the 2237216489Sjh * fini function is in progress, we might end up trying to 2238216489Sjh * unload the referenced object in dlclose() or the object 2239216489Sjh * won't be unloaded although its fini function has been 2240216489Sjh * called. 2241216489Sjh */ 2242216695Skib lock_release(rtld_bind_lock, lockstate); 2243233694Skib 2244233694Skib /* 2245233694Skib * It is legal to have both DT_FINI and DT_FINI_ARRAY defined. 2246233694Skib * When this happens, DT_FINI_ARRAY is processed first. 2247233694Skib */ 2248233694Skib fini_addr = (Elf_Addr *)elm->obj->fini_array; 2249233694Skib if (fini_addr != NULL && elm->obj->fini_array_num > 0) { 2250233694Skib for (index = elm->obj->fini_array_num - 1; index >= 0; 2251233694Skib index--) { 2252233694Skib if (fini_addr[index] != 0 && fini_addr[index] != 1) { 2253233694Skib dbg("calling fini function for %s at %p", 2254233694Skib elm->obj->path, (void *)fini_addr[index]); 2255233694Skib LD_UTRACE(UTRACE_FINI_CALL, elm->obj, 2256233694Skib (void *)fini_addr[index], 0, 0, elm->obj->path); 2257233694Skib call_initfini_pointer(elm->obj, fini_addr[index]); 2258233694Skib } 2259233694Skib } 2260233694Skib } 2261233694Skib if (elm->obj->fini != (Elf_Addr)NULL) { 2262233694Skib dbg("calling fini function for %s at %p", elm->obj->path, 2263233694Skib (void *)elm->obj->fini); 2264233694Skib LD_UTRACE(UTRACE_FINI_CALL, elm->obj, (void *)elm->obj->fini, 2265233694Skib 0, 0, elm->obj->path); 2266233694Skib call_initfini_pointer(elm->obj, elm->obj->fini); 2267233694Skib } 2268216695Skib wlock_acquire(rtld_bind_lock, lockstate); 2269194531Skan /* No need to free anything if process is going down. */ 2270216489Sjh if (root != NULL) 2271194531Skan free(elm); 2272216489Sjh /* 2273216489Sjh * We must restart the list traversal after every fini call 2274216489Sjh * because a dlclose() call from the fini function or from 2275216489Sjh * another thread might have modified the reference counts. 2276216489Sjh */ 2277216489Sjh break; 227863870Sjdp } 2279216489Sjh } while (elm != NULL); 228070677Sjdp errmsg_restore(saved_msg); 228150608Sjdp} 228250608Sjdp 228363870Sjdp/* 228463870Sjdp * Call the initialization functions for each of the objects in 228563870Sjdp * "list". All of the objects are expected to have non-NULL init 228663870Sjdp * functions. 228763870Sjdp */ 228863870Sjdpstatic void 2289216695Skibobjlist_call_init(Objlist *list, RtldLockState *lockstate) 229063870Sjdp{ 229163870Sjdp Objlist_Entry *elm; 2292194531Skan Obj_Entry *obj; 229370677Sjdp char *saved_msg; 2294233694Skib Elf_Addr *init_addr; 2295233694Skib int index; 229663870Sjdp 229770677Sjdp /* 2298194531Skan * Clean init_scanned flag so that objects can be rechecked and 2299194531Skan * possibly initialized earlier if any of vectors called below 2300194531Skan * cause the change by using dlopen. 2301194531Skan */ 2302194531Skan for (obj = obj_list; obj != NULL; obj = obj->next) 2303194531Skan obj->init_scanned = false; 2304194531Skan 2305194531Skan /* 230670677Sjdp * Preserve the current error message since an init function might 230770677Sjdp * call into the dynamic linker and overwrite it. 230870677Sjdp */ 230970677Sjdp saved_msg = errmsg_save(); 231063870Sjdp STAILQ_FOREACH(elm, list, link) { 2311194531Skan if (elm->obj->init_done) /* Initialized early. */ 2312194531Skan continue; 2313194531Skan /* 2314194531Skan * Race: other thread might try to use this object before current 2315194531Skan * one completes the initilization. Not much can be done here 2316194531Skan * without better locking. 2317194531Skan */ 2318194531Skan elm->obj->init_done = true; 2319216695Skib lock_release(rtld_bind_lock, lockstate); 2320233694Skib 2321233694Skib /* 2322233694Skib * It is legal to have both DT_INIT and DT_INIT_ARRAY defined. 2323233694Skib * When this happens, DT_INIT is processed first. 2324233694Skib */ 2325233694Skib if (elm->obj->init != (Elf_Addr)NULL) { 2326233694Skib dbg("calling init function for %s at %p", elm->obj->path, 2327233694Skib (void *)elm->obj->init); 2328233694Skib LD_UTRACE(UTRACE_INIT_CALL, elm->obj, (void *)elm->obj->init, 2329233694Skib 0, 0, elm->obj->path); 2330233694Skib call_initfini_pointer(elm->obj, elm->obj->init); 2331233694Skib } 2332233694Skib init_addr = (Elf_Addr *)elm->obj->init_array; 2333233694Skib if (init_addr != NULL) { 2334233694Skib for (index = 0; index < elm->obj->init_array_num; index++) { 2335233694Skib if (init_addr[index] != 0 && init_addr[index] != 1) { 2336233694Skib dbg("calling init function for %s at %p", elm->obj->path, 2337233694Skib (void *)init_addr[index]); 2338233694Skib LD_UTRACE(UTRACE_INIT_CALL, elm->obj, 2339233694Skib (void *)init_addr[index], 0, 0, elm->obj->path); 2340233694Skib call_init_pointer(elm->obj, init_addr[index]); 2341233694Skib } 2342233694Skib } 2343233694Skib } 2344216695Skib wlock_acquire(rtld_bind_lock, lockstate); 234563870Sjdp } 234670677Sjdp errmsg_restore(saved_msg); 234763870Sjdp} 234863870Sjdp 234963870Sjdpstatic void 235063870Sjdpobjlist_clear(Objlist *list) 235163870Sjdp{ 235263870Sjdp Objlist_Entry *elm; 235363870Sjdp 235463870Sjdp while (!STAILQ_EMPTY(list)) { 235563870Sjdp elm = STAILQ_FIRST(list); 235663870Sjdp STAILQ_REMOVE_HEAD(list, link); 235763870Sjdp free(elm); 235863870Sjdp } 235963870Sjdp} 236063870Sjdp 236150608Sjdpstatic Objlist_Entry * 236250608Sjdpobjlist_find(Objlist *list, const Obj_Entry *obj) 236350608Sjdp{ 236450608Sjdp Objlist_Entry *elm; 236550608Sjdp 236650608Sjdp STAILQ_FOREACH(elm, list, link) 236750608Sjdp if (elm->obj == obj) 236850608Sjdp return elm; 236950608Sjdp return NULL; 237050608Sjdp} 237150608Sjdp 237250608Sjdpstatic void 237363870Sjdpobjlist_init(Objlist *list) 237463870Sjdp{ 237563870Sjdp STAILQ_INIT(list); 237663870Sjdp} 237763870Sjdp 237863870Sjdpstatic void 237963870Sjdpobjlist_push_head(Objlist *list, Obj_Entry *obj) 238063870Sjdp{ 238163870Sjdp Objlist_Entry *elm; 238263870Sjdp 238363870Sjdp elm = NEW(Objlist_Entry); 238463870Sjdp elm->obj = obj; 238563870Sjdp STAILQ_INSERT_HEAD(list, elm, link); 238663870Sjdp} 238763870Sjdp 238863870Sjdpstatic void 238963870Sjdpobjlist_push_tail(Objlist *list, Obj_Entry *obj) 239063870Sjdp{ 239163870Sjdp Objlist_Entry *elm; 239263870Sjdp 239363870Sjdp elm = NEW(Objlist_Entry); 239463870Sjdp elm->obj = obj; 239563870Sjdp STAILQ_INSERT_TAIL(list, elm, link); 239663870Sjdp} 239763870Sjdp 239863870Sjdpstatic void 2399256436Skibobjlist_put_after(Objlist *list, Obj_Entry *listobj, Obj_Entry *obj) 2400256436Skib{ 2401256436Skib Objlist_Entry *elm, *listelm; 2402256436Skib 2403256436Skib STAILQ_FOREACH(listelm, list, link) { 2404256436Skib if (listelm->obj == listobj) 2405256436Skib break; 2406256436Skib } 2407256436Skib elm = NEW(Objlist_Entry); 2408256436Skib elm->obj = obj; 2409256436Skib if (listelm != NULL) 2410256436Skib STAILQ_INSERT_AFTER(list, listelm, elm, link); 2411256436Skib else 2412256436Skib STAILQ_INSERT_TAIL(list, elm, link); 2413256436Skib} 2414256436Skib 2415256436Skibstatic void 241650608Sjdpobjlist_remove(Objlist *list, Obj_Entry *obj) 241750608Sjdp{ 241850608Sjdp Objlist_Entry *elm; 241950608Sjdp 242050608Sjdp if ((elm = objlist_find(list, obj)) != NULL) { 242160938Sjake STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link); 242250608Sjdp free(elm); 242350608Sjdp } 242450608Sjdp} 242550608Sjdp 242634192Sjdp/* 2427238133Skib * Relocate dag rooted in the specified object. 2428238133Skib * Returns 0 on success, or -1 on failure. 242934192Sjdp */ 2430238133Skib 243134192Sjdpstatic int 2432238133Skibrelocate_object_dag(Obj_Entry *root, bool bind_now, Obj_Entry *rtldobj, 2433233831Skib int flags, RtldLockState *lockstate) 243434192Sjdp{ 2435238133Skib Objlist_Entry *elm; 2436238133Skib int error; 243734192Sjdp 2438238133Skib error = 0; 2439238133Skib STAILQ_FOREACH(elm, &root->dagmembers, link) { 2440238133Skib error = relocate_object(elm->obj, bind_now, rtldobj, flags, 2441238133Skib lockstate); 2442238133Skib if (error == -1) 2443238133Skib break; 2444238133Skib } 2445238133Skib return (error); 2446238133Skib} 2447238133Skib 2448238133Skib/* 2449238133Skib * Relocate single object. 2450238133Skib * Returns 0 on success, or -1 on failure. 2451238133Skib */ 2452238133Skibstatic int 2453238133Skibrelocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj, 2454238133Skib int flags, RtldLockState *lockstate) 2455238133Skib{ 2456238133Skib 2457233831Skib if (obj->relocated) 2458238133Skib return (0); 2459233831Skib obj->relocated = true; 246093610Sjake if (obj != rtldobj) 2461238133Skib dbg("relocating \"%s\"", obj->path); 2462233831Skib 2463235396Skib if (obj->symtab == NULL || obj->strtab == NULL || 2464238133Skib !(obj->valid_hash_sysv || obj->valid_hash_gnu)) { 2465238133Skib _rtld_error("%s: Shared object has no run-time symbol table", 2466238133Skib obj->path); 2467238133Skib return (-1); 246834192Sjdp } 246934192Sjdp 247034192Sjdp if (obj->textrel) { 2471238133Skib /* There are relocations to the write-protected text segment. */ 2472238133Skib if (mprotect(obj->mapbase, obj->textsize, 2473238133Skib PROT_READ|PROT_WRITE|PROT_EXEC) == -1) { 2474238133Skib _rtld_error("%s: Cannot write-enable text segment: %s", 2475238133Skib obj->path, rtld_strerror(errno)); 2476238133Skib return (-1); 2477238133Skib } 247834192Sjdp } 247934192Sjdp 248034192Sjdp /* Process the non-PLT relocations. */ 2481233831Skib if (reloc_non_plt(obj, rtldobj, flags, lockstate)) 2482238133Skib return (-1); 248334192Sjdp 248434192Sjdp if (obj->textrel) { /* Re-protected the text segment. */ 2485238133Skib if (mprotect(obj->mapbase, obj->textsize, 2486238133Skib PROT_READ|PROT_EXEC) == -1) { 2487238133Skib _rtld_error("%s: Cannot write-protect text segment: %s", 2488238133Skib obj->path, rtld_strerror(errno)); 2489238133Skib return (-1); 2490238133Skib } 249134192Sjdp } 249234192Sjdp 2493229503Skib 2494229503Skib /* Set the special PLT or GOT entries. */ 2495229503Skib init_pltgot(obj); 2496229503Skib 249734192Sjdp /* Process the PLT relocations. */ 249856780Sjdp if (reloc_plt(obj) == -1) 2499238133Skib return (-1); 250056780Sjdp /* Relocate the jump slots if we are doing immediate binding. */ 2501116511Smdodd if (obj->bind_now || bind_now) 2502238133Skib if (reloc_jmpslots(obj, flags, lockstate) == -1) 2503238133Skib return (-1); 250434192Sjdp 2505231579Skib if (obj->relro_size > 0) { 2506238133Skib if (mprotect(obj->relro_page, obj->relro_size, 2507238133Skib PROT_READ) == -1) { 2508238133Skib _rtld_error("%s: Cannot enforce relro protection: %s", 2509238133Skib obj->path, rtld_strerror(errno)); 2510238133Skib return (-1); 2511238133Skib } 2512231579Skib } 2513231579Skib 251434192Sjdp /* 251534192Sjdp * Set up the magic number and version in the Obj_Entry. These 251634192Sjdp * were checked in the crt1.o from the original ElfKit, so we 251734192Sjdp * set them for backward compatibility. 251834192Sjdp */ 251934192Sjdp obj->magic = RTLD_MAGIC; 252034192Sjdp obj->version = RTLD_VERSION; 252134192Sjdp 2522238133Skib return (0); 252334192Sjdp} 252434192Sjdp 252534192Sjdp/* 2526238133Skib * Relocate newly-loaded shared objects. The argument is a pointer to 2527238133Skib * the Obj_Entry for the first such object. All objects from the first 2528238133Skib * to the end of the list of objects are relocated. Returns 0 on success, 2529238133Skib * or -1 on failure. 2530238133Skib */ 2531238133Skibstatic int 2532238133Skibrelocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj, 2533238133Skib int flags, RtldLockState *lockstate) 2534238133Skib{ 2535238133Skib Obj_Entry *obj; 2536238133Skib int error; 2537238133Skib 2538238133Skib for (error = 0, obj = first; obj != NULL; obj = obj->next) { 2539238133Skib error = relocate_object(obj, bind_now, rtldobj, flags, 2540238133Skib lockstate); 2541238133Skib if (error == -1) 2542238133Skib break; 2543238133Skib } 2544238133Skib return (error); 2545238133Skib} 2546238133Skib 2547238133Skib/* 2548229503Skib * The handling of R_MACHINE_IRELATIVE relocations and jumpslots 2549229503Skib * referencing STT_GNU_IFUNC symbols is postponed till the other 2550229503Skib * relocations are done. The indirect functions specified as 2551229503Skib * ifunc are allowed to call other symbols, so we need to have 2552229503Skib * objects relocated before asking for resolution from indirects. 2553229503Skib * 2554229503Skib * The R_MACHINE_IRELATIVE slots are resolved in greedy fashion, 2555229503Skib * instead of the usual lazy handling of PLT slots. It is 2556229503Skib * consistent with how GNU does it. 2557229503Skib */ 2558229503Skibstatic int 2559233831Skibresolve_object_ifunc(Obj_Entry *obj, bool bind_now, int flags, 2560233831Skib RtldLockState *lockstate) 2561229503Skib{ 2562229503Skib if (obj->irelative && reloc_iresolve(obj, lockstate) == -1) 2563229503Skib return (-1); 2564229503Skib if ((obj->bind_now || bind_now) && obj->gnu_ifunc && 2565233831Skib reloc_gnu_ifunc(obj, flags, lockstate) == -1) 2566229503Skib return (-1); 2567229503Skib return (0); 2568229503Skib} 2569229503Skib 2570229503Skibstatic int 2571233831Skibresolve_objects_ifunc(Obj_Entry *first, bool bind_now, int flags, 2572233831Skib RtldLockState *lockstate) 2573229503Skib{ 2574229503Skib Obj_Entry *obj; 2575229503Skib 2576229503Skib for (obj = first; obj != NULL; obj = obj->next) { 2577233831Skib if (resolve_object_ifunc(obj, bind_now, flags, lockstate) == -1) 2578229503Skib return (-1); 2579229503Skib } 2580229503Skib return (0); 2581229503Skib} 2582229503Skib 2583229503Skibstatic int 2584233831Skibinitlist_objects_ifunc(Objlist *list, bool bind_now, int flags, 2585233831Skib RtldLockState *lockstate) 2586229503Skib{ 2587229503Skib Objlist_Entry *elm; 2588229503Skib 2589229503Skib STAILQ_FOREACH(elm, list, link) { 2590233831Skib if (resolve_object_ifunc(elm->obj, bind_now, flags, 2591233831Skib lockstate) == -1) 2592229503Skib return (-1); 2593229503Skib } 2594229503Skib return (0); 2595229503Skib} 2596229503Skib 2597229503Skib/* 259834192Sjdp * Cleanup procedure. It will be called (by the atexit mechanism) just 259934192Sjdp * before the process exits. 260034192Sjdp */ 260134192Sjdpstatic void 260234192Sjdprtld_exit(void) 260334192Sjdp{ 2604216695Skib RtldLockState lockstate; 260555687Sjdp 2606216695Skib wlock_acquire(rtld_bind_lock, &lockstate); 260734192Sjdp dbg("rtld_exit()"); 2608216489Sjh objlist_call_fini(&list_fini, NULL, &lockstate); 260963870Sjdp /* No need to remove the items from the list, since we are exiting. */ 2610115444Smdodd if (!libmap_disable) 2611115444Smdodd lm_fini(); 2612216695Skib lock_release(rtld_bind_lock, &lockstate); 261334192Sjdp} 261434192Sjdp 2615263031Sdes/* 2616263031Sdes * Iterate over a search path, translate each element, and invoke the 2617263031Sdes * callback on the result. 2618263031Sdes */ 2619110804Skanstatic void * 2620110804Skanpath_enumerate(const char *path, path_enum_proc callback, void *arg) 262134192Sjdp{ 2622127250Speter const char *trans; 2623110804Skan if (path == NULL) 2624110804Skan return (NULL); 262534192Sjdp 2626110804Skan path += strspn(path, ":;"); 2627110804Skan while (*path != '\0') { 2628110804Skan size_t len; 2629110804Skan char *res; 263034192Sjdp 2631110804Skan len = strcspn(path, ":;"); 2632127250Speter trans = lm_findn(NULL, path, len); 2633127250Speter if (trans) 2634127250Speter res = callback(trans, strlen(trans), arg); 2635127250Speter else 2636263031Sdes res = callback(path, len, arg); 263734192Sjdp 2638110804Skan if (res != NULL) 2639110804Skan return (res); 264034192Sjdp 2641110804Skan path += len; 2642110804Skan path += strspn(path, ":;"); 2643110804Skan } 264434192Sjdp 2645110804Skan return (NULL); 2646110804Skan} 264734192Sjdp 2648110804Skanstruct try_library_args { 2649110804Skan const char *name; 2650110804Skan size_t namelen; 2651110804Skan char *buffer; 2652110804Skan size_t buflen; 2653110804Skan}; 2654110804Skan 2655110804Skanstatic void * 2656110804Skantry_library_path(const char *dir, size_t dirlen, void *param) 2657110804Skan{ 2658110804Skan struct try_library_args *arg; 2659110804Skan 2660110804Skan arg = param; 2661110804Skan if (*dir == '/' || trust) { 2662110804Skan char *pathname; 2663110804Skan 2664110804Skan if (dirlen + 1 + arg->namelen + 1 > arg->buflen) 2665110804Skan return (NULL); 2666110804Skan 2667110804Skan pathname = arg->buffer; 2668110804Skan strncpy(pathname, dir, dirlen); 2669110804Skan pathname[dirlen] = '/'; 2670110804Skan strcpy(pathname + dirlen + 1, arg->name); 2671110804Skan 2672110804Skan dbg(" Trying \"%s\"", pathname); 2673110804Skan if (access(pathname, F_OK) == 0) { /* We found it */ 2674110804Skan pathname = xmalloc(dirlen + 1 + arg->namelen + 1); 2675110804Skan strcpy(pathname, arg->buffer); 2676110804Skan return (pathname); 267734192Sjdp } 267834192Sjdp } 2679110804Skan return (NULL); 2680110804Skan} 268134192Sjdp 2682110804Skanstatic char * 2683110804Skansearch_library_path(const char *name, const char *path) 2684110804Skan{ 2685110804Skan char *p; 2686110804Skan struct try_library_args arg; 2687110804Skan 2688110804Skan if (path == NULL) 2689110804Skan return NULL; 2690110804Skan 2691110804Skan arg.name = name; 2692110804Skan arg.namelen = strlen(name); 2693110804Skan arg.buffer = xmalloc(PATH_MAX); 2694110804Skan arg.buflen = PATH_MAX; 2695110804Skan 2696110804Skan p = path_enumerate(path, try_library_path, &arg); 2697110804Skan 2698110804Skan free(arg.buffer); 2699110804Skan 2700110804Skan return (p); 270134192Sjdp} 270234192Sjdp 270334192Sjdpint 270434192Sjdpdlclose(void *handle) 270534192Sjdp{ 270655122Sjdp Obj_Entry *root; 2707216695Skib RtldLockState lockstate; 270834192Sjdp 2709216695Skib wlock_acquire(rtld_bind_lock, &lockstate); 271055122Sjdp root = dlcheck(handle); 271155122Sjdp if (root == NULL) { 2712216695Skib lock_release(rtld_bind_lock, &lockstate); 271334192Sjdp return -1; 271455122Sjdp } 2715165916Sjhb LD_UTRACE(UTRACE_DLCLOSE_START, handle, NULL, 0, root->dl_refcount, 2716165916Sjhb root->path); 271734192Sjdp 271855687Sjdp /* Unreference the object and its dependencies. */ 271934192Sjdp root->dl_refcount--; 2720114826Skan 2721216489Sjh if (root->refcount == 1) { 272255687Sjdp /* 2723216489Sjh * The object will be no longer referenced, so we must unload it. 2724182698Skan * First, call the fini functions. 272555687Sjdp */ 2726216489Sjh objlist_call_fini(&list_fini, root, &lockstate); 272755687Sjdp 2728216489Sjh unref_dag(root); 2729216489Sjh 273055687Sjdp /* Finish cleaning up the newly-unreferenced objects. */ 273165109Sjwd GDB_STATE(RT_DELETE,&root->linkmap); 273255687Sjdp unload_object(root); 273365109Sjwd GDB_STATE(RT_CONSISTENT,NULL); 2734216489Sjh } else 2735216489Sjh unref_dag(root); 2736216489Sjh 2737165916Sjhb LD_UTRACE(UTRACE_DLCLOSE_STOP, handle, NULL, 0, 0, NULL); 2738216695Skib lock_release(rtld_bind_lock, &lockstate); 273934192Sjdp return 0; 274034192Sjdp} 274134192Sjdp 2742205606Sgahrchar * 274334192Sjdpdlerror(void) 274434192Sjdp{ 274534192Sjdp char *msg = error_message; 274634192Sjdp error_message = NULL; 274734192Sjdp return msg; 274834192Sjdp} 274934192Sjdp 275062801Sjdp/* 275162801Sjdp * This function is deprecated and has no effect. 275262801Sjdp */ 275355122Sjdpvoid 275455122Sjdpdllockinit(void *context, 275555122Sjdp void *(*lock_create)(void *context), 275655122Sjdp void (*rlock_acquire)(void *lock), 275755122Sjdp void (*wlock_acquire)(void *lock), 275855122Sjdp void (*lock_release)(void *lock), 275955122Sjdp void (*lock_destroy)(void *lock), 276055122Sjdp void (*context_destroy)(void *context)) 276155122Sjdp{ 276262801Sjdp static void *cur_context; 276362801Sjdp static void (*cur_context_destroy)(void *); 276456780Sjdp 276562801Sjdp /* Just destroy the context from the previous call, if necessary. */ 276662801Sjdp if (cur_context_destroy != NULL) 276762801Sjdp cur_context_destroy(cur_context); 276862801Sjdp cur_context = context; 276962801Sjdp cur_context_destroy = context_destroy; 277055122Sjdp} 277155122Sjdp 277234192Sjdpvoid * 277334192Sjdpdlopen(const char *name, int mode) 277434192Sjdp{ 2775230410Skib 2776230410Skib return (rtld_dlopen(name, -1, mode)); 2777230410Skib} 2778230410Skib 2779230410Skibvoid * 2780230410Skibfdlopen(int fd, int mode) 2781230410Skib{ 2782230410Skib 2783230410Skib return (rtld_dlopen(NULL, fd, mode)); 2784230410Skib} 2785230410Skib 2786230410Skibstatic void * 2787230410Skibrtld_dlopen(const char *name, int fd, int mode) 2788230410Skib{ 2789217223Skib RtldLockState lockstate; 2790216695Skib int lo_flags; 279134192Sjdp 2792165916Sjhb LD_UTRACE(UTRACE_DLOPEN_START, NULL, NULL, 0, mode, name); 279390172Ssobomax ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1"; 2794217223Skib if (ld_tracing != NULL) { 2795217223Skib rlock_acquire(rtld_bind_lock, &lockstate); 2796218476Skib if (sigsetjmp(lockstate.env, 0) != 0) 2797217223Skib lock_upgrade(rtld_bind_lock, &lockstate); 2798217223Skib environ = (char **)*get_program_var_addr("environ", &lockstate); 2799217223Skib lock_release(rtld_bind_lock, &lockstate); 2800217223Skib } 2801199829Skib lo_flags = RTLD_LO_DLOPEN; 2802216695Skib if (mode & RTLD_NODELETE) 2803216695Skib lo_flags |= RTLD_LO_NODELETE; 2804199829Skib if (mode & RTLD_NOLOAD) 2805199829Skib lo_flags |= RTLD_LO_NOLOAD; 2806199877Skib if (ld_tracing != NULL) 2807199877Skib lo_flags |= RTLD_LO_TRACE; 280890172Ssobomax 2809230410Skib return (dlopen_object(name, fd, obj_main, lo_flags, 2810234454Skib mode & (RTLD_MODEMASK | RTLD_GLOBAL), NULL)); 2811216695Skib} 2812216695Skib 2813229503Skibstatic void 2814229503Skibdlopen_cleanup(Obj_Entry *obj) 2815229503Skib{ 2816229503Skib 2817229503Skib obj->dl_refcount--; 2818229503Skib unref_dag(obj); 2819229503Skib if (obj->refcount == 0) 2820229503Skib unload_object(obj); 2821229503Skib} 2822229503Skib 2823216695Skibstatic Obj_Entry * 2824230410Skibdlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags, 2825234454Skib int mode, RtldLockState *lockstate) 2826216695Skib{ 2827216695Skib Obj_Entry **old_obj_tail; 2828216695Skib Obj_Entry *obj; 2829216695Skib Objlist initlist; 2830234454Skib RtldLockState mlockstate; 2831216695Skib int result; 2832216695Skib 283363870Sjdp objlist_init(&initlist); 283455687Sjdp 2835234454Skib if (lockstate == NULL && !(lo_flags & RTLD_LO_EARLY)) { 2836234454Skib wlock_acquire(rtld_bind_lock, &mlockstate); 2837234454Skib lockstate = &mlockstate; 2838234454Skib } 283965109Sjwd GDB_STATE(RT_ADD,NULL); 284035529Sdfr 284155122Sjdp old_obj_tail = obj_tail; 284255122Sjdp obj = NULL; 2843230410Skib if (name == NULL && fd == -1) { 284434192Sjdp obj = obj_main; 284548208Sjdp obj->refcount++; 284648208Sjdp } else { 2847230410Skib obj = load_object(name, fd, refobj, lo_flags); 284834192Sjdp } 284934192Sjdp 285035529Sdfr if (obj) { 285135529Sdfr obj->dl_refcount++; 285250608Sjdp if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL) 285363870Sjdp objlist_push_tail(&list_global, obj); 285435529Sdfr if (*old_obj_tail != NULL) { /* We loaded something new. */ 285535529Sdfr assert(*old_obj_tail == obj); 2856233831Skib result = load_needed_objects(obj, 2857233831Skib lo_flags & (RTLD_LO_DLOPEN | RTLD_LO_EARLY)); 2858153648Skan init_dag(obj); 2859214777Skib ref_dag(obj); 2860153515Skan if (result != -1) 2861153515Skan result = rtld_verify_versions(&obj->dagmembers); 2862105439Ssobomax if (result != -1 && ld_tracing) 2863105439Ssobomax goto trace; 2864238133Skib if (result == -1 || relocate_object_dag(obj, 2865238133Skib (mode & RTLD_MODEMASK) == RTLD_NOW, &obj_rtld, 2866233831Skib (lo_flags & RTLD_LO_EARLY) ? SYMLOOK_EARLY : 0, 2867238133Skib lockstate) == -1) { 2868229503Skib dlopen_cleanup(obj); 286935529Sdfr obj = NULL; 2870233831Skib } else if (lo_flags & RTLD_LO_EARLY) { 2871233831Skib /* 2872233831Skib * Do not call the init functions for early loaded 2873233831Skib * filtees. The image is still not initialized enough 2874233831Skib * for them to work. 2875233831Skib * 2876233831Skib * Our object is found by the global object list and 2877233831Skib * will be ordered among all init calls done right 2878233831Skib * before transferring control to main. 2879233831Skib */ 288055687Sjdp } else { 288163870Sjdp /* Make list of init functions to call. */ 288263870Sjdp initlist_add_objects(obj, &obj->next, &initlist); 288355687Sjdp } 2884239439Skan /* 2885239439Skan * Process all no_delete objects here, given them own 2886239439Skan * DAGs to prevent their dependencies from being unloaded. 2887239439Skan * This has to be done after we have loaded all of the 2888239439Skan * dependencies, so that we do not miss any. 2889239439Skan */ 2890239471Skan if (obj != NULL) 2891239471Skan process_nodelete(obj); 2892114826Skan } else { 2893214728Skib /* 2894214728Skib * Bump the reference counts for objects on this DAG. If 2895214728Skib * this is the first dlopen() call for the object that was 2896214728Skib * already loaded as a dependency, initialize the dag 2897214728Skib * starting at it. 2898214728Skib */ 2899214777Skib init_dag(obj); 2900214777Skib ref_dag(obj); 2901114826Skan 2902216695Skib if ((lo_flags & RTLD_LO_TRACE) != 0) 2903114826Skan goto trace; 2904114826Skan } 2905216695Skib if (obj != NULL && ((lo_flags & RTLD_LO_NODELETE) != 0 || 2906216695Skib obj->z_nodelete) && !obj->ref_nodel) { 2907190543Skib dbg("obj %s nodelete", obj->path); 2908190543Skib ref_dag(obj); 2909190543Skib obj->z_nodelete = obj->ref_nodel = true; 2910190543Skib } 291134192Sjdp } 291235529Sdfr 2913165916Sjhb LD_UTRACE(UTRACE_DLOPEN_STOP, obj, NULL, 0, obj ? obj->dl_refcount : 0, 2914165916Sjhb name); 291565109Sjwd GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL); 291655687Sjdp 2917233831Skib if (!(lo_flags & RTLD_LO_EARLY)) { 2918234454Skib map_stacks_exec(lockstate); 2919233831Skib } 2920217153Skib 2921229503Skib if (initlist_objects_ifunc(&initlist, (mode & RTLD_MODEMASK) == RTLD_NOW, 2922233831Skib (lo_flags & RTLD_LO_EARLY) ? SYMLOOK_EARLY : 0, 2923234454Skib lockstate) == -1) { 2924229503Skib objlist_clear(&initlist); 2925229503Skib dlopen_cleanup(obj); 2926234454Skib if (lockstate == &mlockstate) 2927234454Skib lock_release(rtld_bind_lock, lockstate); 2928229503Skib return (NULL); 2929229503Skib } 2930229503Skib 2931233831Skib if (!(lo_flags & RTLD_LO_EARLY)) { 2932233831Skib /* Call the init functions. */ 2933234454Skib objlist_call_init(&initlist, lockstate); 2934233831Skib } 293563870Sjdp objlist_clear(&initlist); 2936234454Skib if (lockstate == &mlockstate) 2937234454Skib lock_release(rtld_bind_lock, lockstate); 293834192Sjdp return obj; 2939105439Ssobomaxtrace: 2940105439Ssobomax trace_loaded_objects(obj); 2941234454Skib if (lockstate == &mlockstate) 2942234454Skib lock_release(rtld_bind_lock, lockstate); 2943105439Ssobomax exit(0); 294434192Sjdp} 294534192Sjdp 2946153515Skanstatic void * 2947153515Skando_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve, 2948153515Skan int flags) 294934192Sjdp{ 2950162449Sjkim DoneList donelist; 2951162449Sjkim const Obj_Entry *obj, *defobj; 2952216695Skib const Elf_Sym *def; 2953216695Skib SymLook req; 2954216695Skib RtldLockState lockstate; 2955233833Skib#ifndef __ia64__ 2956233833Skib tls_index ti; 2957233833Skib#endif 2958216695Skib int res; 295934192Sjdp 296038737Sjdp def = NULL; 296150608Sjdp defobj = NULL; 2962216695Skib symlook_init(&req, name); 2963216695Skib req.ventry = ve; 2964216695Skib req.flags = flags | SYMLOOK_IN_PLT; 2965216695Skib req.lockstate = &lockstate; 296634192Sjdp 2967216695Skib rlock_acquire(rtld_bind_lock, &lockstate); 2968218476Skib if (sigsetjmp(lockstate.env, 0) != 0) 2969216695Skib lock_upgrade(rtld_bind_lock, &lockstate); 2970110804Skan if (handle == NULL || handle == RTLD_NEXT || 2971110804Skan handle == RTLD_DEFAULT || handle == RTLD_SELF) { 297234192Sjdp 297334192Sjdp if ((obj = obj_from_addr(retaddr)) == NULL) { 297434192Sjdp _rtld_error("Cannot determine caller's shared object"); 2975216695Skib lock_release(rtld_bind_lock, &lockstate); 297634192Sjdp return NULL; 297734192Sjdp } 297850608Sjdp if (handle == NULL) { /* Just the caller's shared object. */ 2979216695Skib res = symlook_obj(&req, obj); 2980216695Skib if (res == 0) { 2981216695Skib def = req.sym_out; 2982216695Skib defobj = req.defobj_out; 2983216695Skib } 2984110804Skan } else if (handle == RTLD_NEXT || /* Objects after caller's */ 2985110804Skan handle == RTLD_SELF) { /* ... caller included */ 2986110804Skan if (handle == RTLD_NEXT) 2987110804Skan obj = obj->next; 2988110804Skan for (; obj != NULL; obj = obj->next) { 2989216695Skib res = symlook_obj(&req, obj); 2990216695Skib if (res == 0) { 2991216695Skib if (def == NULL || 2992216695Skib ELF_ST_BIND(req.sym_out->st_info) != STB_WEAK) { 2993216695Skib def = req.sym_out; 2994216695Skib defobj = req.defobj_out; 2995183737Skan if (ELF_ST_BIND(def->st_info) != STB_WEAK) 2996183737Skan break; 2997183737Skan } 299850608Sjdp } 299950608Sjdp } 3000183737Skan /* 3001183737Skan * Search the dynamic linker itself, and possibly resolve the 3002183737Skan * symbol from there. This is how the application links to 3003211749Skib * dynamic linker services such as dlopen. 3004183737Skan */ 3005183737Skan if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) { 3006216695Skib res = symlook_obj(&req, &obj_rtld); 3007216695Skib if (res == 0) { 3008216695Skib def = req.sym_out; 3009216695Skib defobj = req.defobj_out; 3010183737Skan } 3011183737Skan } 301266056Sjdp } else { 301366056Sjdp assert(handle == RTLD_DEFAULT); 3014216728Skan res = symlook_default(&req, obj); 3015216695Skib if (res == 0) { 3016216695Skib defobj = req.defobj_out; 3017216695Skib def = req.sym_out; 3018216695Skib } 301938737Sjdp } 302034192Sjdp } else { 302155122Sjdp if ((obj = dlcheck(handle)) == NULL) { 3022216695Skib lock_release(rtld_bind_lock, &lockstate); 302334192Sjdp return NULL; 302455122Sjdp } 302538737Sjdp 3026162156Skib donelist_init(&donelist); 302738737Sjdp if (obj->mainprog) { 3028218051Skan /* Handle obtained by dlopen(NULL, ...) implies global scope. */ 3029218051Skan res = symlook_global(&req, &donelist); 3030216695Skib if (res == 0) { 3031216695Skib def = req.sym_out; 3032216695Skib defobj = req.defobj_out; 3033218051Skan } 3034218051Skan /* 3035218051Skan * Search the dynamic linker itself, and possibly resolve the 3036218051Skan * symbol from there. This is how the application links to 3037218051Skan * dynamic linker services such as dlopen. 3038218051Skan */ 3039218051Skan if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) { 3040218051Skan res = symlook_obj(&req, &obj_rtld); 3041216695Skib if (res == 0) { 3042216695Skib def = req.sym_out; 3043216695Skib defobj = req.defobj_out; 3044216695Skib } 3045216695Skib } 3046218051Skan } 3047218051Skan else { 3048162156Skib /* Search the whole DAG rooted at the given object. */ 3049218051Skan res = symlook_list(&req, &obj->dagmembers, &donelist); 3050216695Skib if (res == 0) { 3051216695Skib def = req.sym_out; 3052216695Skib defobj = req.defobj_out; 3053216695Skib } 305438737Sjdp } 305534192Sjdp } 305634192Sjdp 305755122Sjdp if (def != NULL) { 3058216695Skib lock_release(rtld_bind_lock, &lockstate); 305985004Sdfr 306085004Sdfr /* 306185004Sdfr * The value required by the caller is derived from the value 306285004Sdfr * of the symbol. For the ia64 architecture, we need to 306385004Sdfr * construct a function descriptor which the caller can use to 306485004Sdfr * call the function with the right 'gp' value. For other 306585004Sdfr * architectures and for non-functions, the value is simply 306685004Sdfr * the relocated value of the symbol. 306785004Sdfr */ 306885004Sdfr if (ELF_ST_TYPE(def->st_info) == STT_FUNC) 3069229503Skib return (make_function_pointer(def, defobj)); 3070229503Skib else if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) 3071229503Skib return (rtld_resolve_ifunc(defobj, def)); 3072233833Skib else if (ELF_ST_TYPE(def->st_info) == STT_TLS) { 3073233833Skib#ifdef __ia64__ 3074233833Skib return (__tls_get_addr(defobj->tlsindex, def->st_value)); 3075233833Skib#else 3076233833Skib ti.ti_module = defobj->tlsindex; 3077233833Skib ti.ti_offset = def->st_value; 3078233833Skib return (__tls_get_addr(&ti)); 3079233833Skib#endif 3080233833Skib } else 3081229503Skib return (defobj->relocbase + def->st_value); 308255122Sjdp } 308334192Sjdp 308434192Sjdp _rtld_error("Undefined symbol \"%s\"", name); 3085216695Skib lock_release(rtld_bind_lock, &lockstate); 308634192Sjdp return NULL; 308734192Sjdp} 308834192Sjdp 3089153515Skanvoid * 3090153515Skandlsym(void *handle, const char *name) 3091153515Skan{ 3092153515Skan return do_dlsym(handle, name, __builtin_return_address(0), NULL, 3093153515Skan SYMLOOK_DLSYM); 3094153515Skan} 3095153515Skan 3096190673Skibdlfunc_t 3097190673Skibdlfunc(void *handle, const char *name) 3098190673Skib{ 3099190673Skib union { 3100190673Skib void *d; 3101190673Skib dlfunc_t f; 3102190673Skib } rv; 3103190673Skib 3104190673Skib rv.d = do_dlsym(handle, name, __builtin_return_address(0), NULL, 3105190673Skib SYMLOOK_DLSYM); 3106190673Skib return (rv.f); 3107190673Skib} 3108190673Skib 3109153515Skanvoid * 3110153515Skandlvsym(void *handle, const char *name, const char *version) 3111153515Skan{ 3112153515Skan Ver_Entry ventry; 3113153515Skan 3114153515Skan ventry.name = version; 3115153515Skan ventry.file = NULL; 3116153515Skan ventry.hash = elf_hash(version); 3117153515Skan ventry.flags= 0; 3118153515Skan return do_dlsym(handle, name, __builtin_return_address(0), &ventry, 3119153515Skan SYMLOOK_DLSYM); 3120153515Skan} 3121153515Skan 312245015Snateint 3123211705Skib_rtld_addr_phdr(const void *addr, struct dl_phdr_info *phdr_info) 3124211705Skib{ 3125211705Skib const Obj_Entry *obj; 3126216695Skib RtldLockState lockstate; 3127211705Skib 3128216695Skib rlock_acquire(rtld_bind_lock, &lockstate); 3129211705Skib obj = obj_from_addr(addr); 3130211705Skib if (obj == NULL) { 3131211705Skib _rtld_error("No shared object contains address"); 3132216695Skib lock_release(rtld_bind_lock, &lockstate); 3133211705Skib return (0); 3134211705Skib } 3135211705Skib rtld_fill_dl_phdr_info(obj, phdr_info); 3136216695Skib lock_release(rtld_bind_lock, &lockstate); 3137211705Skib return (1); 3138211705Skib} 3139211705Skib 3140211705Skibint 314145015Snatedladdr(const void *addr, Dl_info *info) 314245015Snate{ 314345015Snate const Obj_Entry *obj; 314445015Snate const Elf_Sym *def; 314545015Snate void *symbol_addr; 314645015Snate unsigned long symoffset; 3147216695Skib RtldLockState lockstate; 3148115396Skan 3149216695Skib rlock_acquire(rtld_bind_lock, &lockstate); 315045018Snate obj = obj_from_addr(addr); 315145015Snate if (obj == NULL) { 315245018Snate _rtld_error("No shared object contains address"); 3153216695Skib lock_release(rtld_bind_lock, &lockstate); 315445015Snate return 0; 315545015Snate } 315645015Snate info->dli_fname = obj->path; 315745018Snate info->dli_fbase = obj->mapbase; 315845015Snate info->dli_saddr = (void *)0; 315945015Snate info->dli_sname = NULL; 316045015Snate 316145015Snate /* 316245399Sjdp * Walk the symbol list looking for the symbol whose address is 316345015Snate * closest to the address sent in. 316445015Snate */ 3165235396Skib for (symoffset = 0; symoffset < obj->dynsymcount; symoffset++) { 316645015Snate def = obj->symtab + symoffset; 316745018Snate 316845015Snate /* 316945018Snate * For skip the symbol if st_shndx is either SHN_UNDEF or 317045018Snate * SHN_COMMON. 317145018Snate */ 317245018Snate if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON) 317345018Snate continue; 317445018Snate 317545018Snate /* 317645399Sjdp * If the symbol is greater than the specified address, or if it 317745015Snate * is further away from addr than the current nearest symbol, 317845015Snate * then reject it. 317945015Snate */ 318045018Snate symbol_addr = obj->relocbase + def->st_value; 318145018Snate if (symbol_addr > addr || symbol_addr < info->dli_saddr) 318245015Snate continue; 318345015Snate 318445015Snate /* Update our idea of the nearest symbol. */ 318545015Snate info->dli_sname = obj->strtab + def->st_name; 318645015Snate info->dli_saddr = symbol_addr; 318745015Snate 318845015Snate /* Exact match? */ 318945015Snate if (info->dli_saddr == addr) 319045015Snate break; 319145015Snate } 3192216695Skib lock_release(rtld_bind_lock, &lockstate); 319345015Snate return 1; 319445015Snate} 319545015Snate 3196110804Skanint 3197110804Skandlinfo(void *handle, int request, void *p) 3198110804Skan{ 3199110804Skan const Obj_Entry *obj; 3200216695Skib RtldLockState lockstate; 3201216695Skib int error; 3202110804Skan 3203216695Skib rlock_acquire(rtld_bind_lock, &lockstate); 3204110804Skan 3205110804Skan if (handle == NULL || handle == RTLD_SELF) { 3206110804Skan void *retaddr; 3207110804Skan 3208110804Skan retaddr = __builtin_return_address(0); /* __GNUC__ only */ 3209110804Skan if ((obj = obj_from_addr(retaddr)) == NULL) 3210110804Skan _rtld_error("Cannot determine caller's shared object"); 3211110804Skan } else 3212110804Skan obj = dlcheck(handle); 3213110804Skan 3214110804Skan if (obj == NULL) { 3215216695Skib lock_release(rtld_bind_lock, &lockstate); 3216110804Skan return (-1); 3217110804Skan } 3218110804Skan 3219110804Skan error = 0; 3220110804Skan switch (request) { 3221110804Skan case RTLD_DI_LINKMAP: 3222110804Skan *((struct link_map const **)p) = &obj->linkmap; 3223110804Skan break; 3224110804Skan case RTLD_DI_ORIGIN: 3225110804Skan error = rtld_dirname(obj->path, p); 3226110804Skan break; 3227110804Skan 3228110804Skan case RTLD_DI_SERINFOSIZE: 3229110804Skan case RTLD_DI_SERINFO: 3230110804Skan error = do_search_info(obj, request, (struct dl_serinfo *)p); 3231110804Skan break; 3232110804Skan 3233110804Skan default: 3234110804Skan _rtld_error("Invalid request %d passed to dlinfo()", request); 3235110804Skan error = -1; 3236110804Skan } 3237110804Skan 3238216695Skib lock_release(rtld_bind_lock, &lockstate); 3239110804Skan 3240110804Skan return (error); 3241110804Skan} 3242110804Skan 3243211705Skibstatic void 3244211705Skibrtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info) 3245211705Skib{ 3246211705Skib 3247211705Skib phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase; 3248211705Skib phdr_info->dlpi_name = STAILQ_FIRST(&obj->names) ? 3249211705Skib STAILQ_FIRST(&obj->names)->name : obj->path; 3250211705Skib phdr_info->dlpi_phdr = obj->phdr; 3251211705Skib phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]); 3252211705Skib phdr_info->dlpi_tls_modid = obj->tlsindex; 3253211705Skib phdr_info->dlpi_tls_data = obj->tlsinit; 3254211705Skib phdr_info->dlpi_adds = obj_loads; 3255211705Skib phdr_info->dlpi_subs = obj_loads - obj_count; 3256211705Skib} 3257211705Skib 3258168312Skanint 3259168312Skandl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param) 3260168312Skan{ 3261168312Skan struct dl_phdr_info phdr_info; 3262168312Skan const Obj_Entry *obj; 3263216695Skib RtldLockState bind_lockstate, phdr_lockstate; 3264216695Skib int error; 3265168312Skan 3266216695Skib wlock_acquire(rtld_phdr_lock, &phdr_lockstate); 3267216695Skib rlock_acquire(rtld_bind_lock, &bind_lockstate); 3268168312Skan 3269168312Skan error = 0; 3270168312Skan 3271168312Skan for (obj = obj_list; obj != NULL; obj = obj->next) { 3272211705Skib rtld_fill_dl_phdr_info(obj, &phdr_info); 3273168312Skan if ((error = callback(&phdr_info, sizeof phdr_info, param)) != 0) 3274168312Skan break; 3275168312Skan 3276168312Skan } 3277216695Skib lock_release(rtld_bind_lock, &bind_lockstate); 3278216695Skib lock_release(rtld_phdr_lock, &phdr_lockstate); 3279168312Skan 3280168312Skan return (error); 3281168312Skan} 3282168312Skan 3283110804Skanstatic void * 3284110804Skanfill_search_info(const char *dir, size_t dirlen, void *param) 3285110804Skan{ 3286110804Skan struct fill_search_info_args *arg; 3287110804Skan 3288110804Skan arg = param; 3289110804Skan 3290110804Skan if (arg->request == RTLD_DI_SERINFOSIZE) { 3291110804Skan arg->serinfo->dls_cnt ++; 3292240308Skib arg->serinfo->dls_size += sizeof(struct dl_serpath) + dirlen + 1; 3293110804Skan } else { 3294110804Skan struct dl_serpath *s_entry; 3295110804Skan 3296110804Skan s_entry = arg->serpath; 3297110804Skan s_entry->dls_name = arg->strspace; 3298110804Skan s_entry->dls_flags = arg->flags; 3299110804Skan 3300110804Skan strncpy(arg->strspace, dir, dirlen); 3301110804Skan arg->strspace[dirlen] = '\0'; 3302110804Skan 3303110804Skan arg->strspace += dirlen + 1; 3304110804Skan arg->serpath++; 3305110804Skan } 3306110804Skan 3307110804Skan return (NULL); 3308110804Skan} 3309110804Skan 3310110804Skanstatic int 3311110804Skando_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info) 3312110804Skan{ 3313110804Skan struct dl_serinfo _info; 3314110804Skan struct fill_search_info_args args; 3315110804Skan 3316110804Skan args.request = RTLD_DI_SERINFOSIZE; 3317110804Skan args.serinfo = &_info; 3318110804Skan 3319110804Skan _info.dls_size = __offsetof(struct dl_serinfo, dls_serpath); 3320110804Skan _info.dls_cnt = 0; 3321110804Skan 3322240308Skib path_enumerate(obj->rpath, fill_search_info, &args); 3323110804Skan path_enumerate(ld_library_path, fill_search_info, &args); 3324240308Skib path_enumerate(obj->runpath, fill_search_info, &args); 3325240308Skib path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args); 3326240308Skib if (!obj->z_nodeflib) 3327240308Skib path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args); 3328110804Skan 3329110804Skan 3330110804Skan if (request == RTLD_DI_SERINFOSIZE) { 3331110804Skan info->dls_size = _info.dls_size; 3332110804Skan info->dls_cnt = _info.dls_cnt; 3333110804Skan return (0); 3334110804Skan } 3335110804Skan 3336110804Skan if (info->dls_cnt != _info.dls_cnt || info->dls_size != _info.dls_size) { 3337110804Skan _rtld_error("Uninitialized Dl_serinfo struct passed to dlinfo()"); 3338110804Skan return (-1); 3339110804Skan } 3340110804Skan 3341110804Skan args.request = RTLD_DI_SERINFO; 3342110804Skan args.serinfo = info; 3343110804Skan args.serpath = &info->dls_serpath[0]; 3344110804Skan args.strspace = (char *)&info->dls_serpath[_info.dls_cnt]; 3345110804Skan 3346240308Skib args.flags = LA_SER_RUNPATH; 3347240308Skib if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL) 3348240308Skib return (-1); 3349240308Skib 3350110804Skan args.flags = LA_SER_LIBPATH; 3351110804Skan if (path_enumerate(ld_library_path, fill_search_info, &args) != NULL) 3352110804Skan return (-1); 3353110804Skan 3354110804Skan args.flags = LA_SER_RUNPATH; 3355240308Skib if (path_enumerate(obj->runpath, fill_search_info, &args) != NULL) 3356110804Skan return (-1); 3357110804Skan 3358110804Skan args.flags = LA_SER_CONFIG; 3359240308Skib if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args) 3360240308Skib != NULL) 3361110804Skan return (-1); 3362110804Skan 3363110804Skan args.flags = LA_SER_DEFAULT; 3364240308Skib if (!obj->z_nodeflib && 3365240308Skib path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL) 3366110804Skan return (-1); 3367110804Skan return (0); 3368110804Skan} 3369110804Skan 3370110804Skanstatic int 3371110804Skanrtld_dirname(const char *path, char *bname) 3372110804Skan{ 3373110804Skan const char *endp; 3374110804Skan 3375110804Skan /* Empty or NULL string gets treated as "." */ 3376110804Skan if (path == NULL || *path == '\0') { 3377110804Skan bname[0] = '.'; 3378110834Skan bname[1] = '\0'; 3379110804Skan return (0); 3380110804Skan } 3381110804Skan 3382110804Skan /* Strip trailing slashes */ 3383110804Skan endp = path + strlen(path) - 1; 3384110804Skan while (endp > path && *endp == '/') 3385110804Skan endp--; 3386110804Skan 3387110804Skan /* Find the start of the dir */ 3388110804Skan while (endp > path && *endp != '/') 3389110804Skan endp--; 3390110804Skan 3391110804Skan /* Either the dir is "/" or there are no slashes */ 3392110804Skan if (endp == path) { 3393110804Skan bname[0] = *endp == '/' ? '/' : '.'; 3394110804Skan bname[1] = '\0'; 3395110804Skan return (0); 3396110804Skan } else { 3397110804Skan do { 3398110804Skan endp--; 3399110804Skan } while (endp > path && *endp == '/'); 3400110804Skan } 3401110804Skan 3402110804Skan if (endp - path + 2 > PATH_MAX) 3403110804Skan { 3404110804Skan _rtld_error("Filename is too long: %s", path); 3405110804Skan return(-1); 3406110804Skan } 3407110804Skan 3408110804Skan strncpy(bname, path, endp - path + 1); 3409110804Skan bname[endp - path + 1] = '\0'; 3410110804Skan return (0); 3411110804Skan} 3412110804Skan 3413189959Skibstatic int 3414189959Skibrtld_dirname_abs(const char *path, char *base) 3415189959Skib{ 3416189959Skib char base_rel[PATH_MAX]; 3417189959Skib 3418189959Skib if (rtld_dirname(path, base) == -1) 3419189959Skib return (-1); 3420189959Skib if (base[0] == '/') 3421189959Skib return (0); 3422189959Skib if (getcwd(base_rel, sizeof(base_rel)) == NULL || 3423189959Skib strlcat(base_rel, "/", sizeof(base_rel)) >= sizeof(base_rel) || 3424189959Skib strlcat(base_rel, base, sizeof(base_rel)) >= sizeof(base_rel)) 3425189959Skib return (-1); 3426189959Skib strcpy(base, base_rel); 3427189959Skib return (0); 3428189959Skib} 3429189959Skib 343034192Sjdpstatic void 343135529Sdfrlinkmap_add(Obj_Entry *obj) 343235529Sdfr{ 343335529Sdfr struct link_map *l = &obj->linkmap; 343435529Sdfr struct link_map *prev; 343535529Sdfr 343635529Sdfr obj->linkmap.l_name = obj->path; 343735529Sdfr obj->linkmap.l_addr = obj->mapbase; 343835529Sdfr obj->linkmap.l_ld = obj->dynamic; 343935529Sdfr#ifdef __mips__ 344035529Sdfr /* GDB needs load offset on MIPS to use the symbols */ 344135529Sdfr obj->linkmap.l_offs = obj->relocbase; 344235529Sdfr#endif 344335529Sdfr 344435529Sdfr if (r_debug.r_map == NULL) { 344535529Sdfr r_debug.r_map = l; 344635529Sdfr return; 344735529Sdfr } 3448110804Skan 344939321Sjdp /* 345039321Sjdp * Scan to the end of the list, but not past the entry for the 345139321Sjdp * dynamic linker, which we want to keep at the very end. 345239321Sjdp */ 345339321Sjdp for (prev = r_debug.r_map; 345439321Sjdp prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap; 345539321Sjdp prev = prev->l_next) 345635529Sdfr ; 345739321Sjdp 345839321Sjdp /* Link in the new entry. */ 345935529Sdfr l->l_prev = prev; 346039321Sjdp l->l_next = prev->l_next; 346139321Sjdp if (l->l_next != NULL) 346239321Sjdp l->l_next->l_prev = l; 346335529Sdfr prev->l_next = l; 346435529Sdfr} 346535529Sdfr 346638739Sjdpstatic void 346738739Sjdplinkmap_delete(Obj_Entry *obj) 346835529Sdfr{ 346935529Sdfr struct link_map *l = &obj->linkmap; 347035529Sdfr 347135529Sdfr if (l->l_prev == NULL) { 347235529Sdfr if ((r_debug.r_map = l->l_next) != NULL) 347335529Sdfr l->l_next->l_prev = NULL; 347435529Sdfr return; 347535529Sdfr } 347635529Sdfr 347735529Sdfr if ((l->l_prev->l_next = l->l_next) != NULL) 347835529Sdfr l->l_next->l_prev = l->l_prev; 347935529Sdfr} 348035574Sdfr 348138739Sjdp/* 348238739Sjdp * Function for the debugger to set a breakpoint on to gain control. 348365109Sjwd * 348465109Sjwd * The two parameters allow the debugger to easily find and determine 348565109Sjwd * what the runtime loader is doing and to whom it is doing it. 348665109Sjwd * 348765109Sjwd * When the loadhook trap is hit (r_debug_state, set at program 348865109Sjwd * initialization), the arguments can be found on the stack: 348965109Sjwd * 349065109Sjwd * +8 struct link_map *m 349165109Sjwd * +4 struct r_debug *rd 349265109Sjwd * +0 RetAddr 349338739Sjdp */ 349438739Sjdpvoid 349565109Sjwdr_debug_state(struct r_debug* rd, struct link_map *m) 349635574Sdfr{ 3497225366Sdim /* 3498225366Sdim * The following is a hack to force the compiler to emit calls to 3499225366Sdim * this function, even when optimizing. If the function is empty, 3500225366Sdim * the compiler is not obliged to emit any code for calls to it, 3501225366Sdim * even when marked __noinline. However, gdb depends on those 3502225366Sdim * calls being made. 3503225366Sdim */ 3504225366Sdim __asm __volatile("" : : : "memory"); 350538739Sjdp} 350638739Sjdp 350738739Sjdp/* 350890172Ssobomax * Get address of the pointer variable in the main program. 3509217223Skib * Prefer non-weak symbol over the weak one. 351045890Sjdp */ 351190172Ssobomaxstatic const void ** 3512217223Skibget_program_var_addr(const char *name, RtldLockState *lockstate) 351345890Sjdp{ 3514216695Skib SymLook req; 3515217223Skib DoneList donelist; 351645890Sjdp 3517216695Skib symlook_init(&req, name); 3518217223Skib req.lockstate = lockstate; 3519217223Skib donelist_init(&donelist); 3520217223Skib if (symlook_global(&req, &donelist) != 0) 3521217223Skib return (NULL); 3522217849Skib if (ELF_ST_TYPE(req.sym_out->st_info) == STT_FUNC) 3523217849Skib return ((const void **)make_function_pointer(req.sym_out, 3524217849Skib req.defobj_out)); 3525229503Skib else if (ELF_ST_TYPE(req.sym_out->st_info) == STT_GNU_IFUNC) 3526229503Skib return ((const void **)rtld_resolve_ifunc(req.defobj_out, req.sym_out)); 3527217849Skib else 3528217849Skib return ((const void **)(req.defobj_out->relocbase + 3529217849Skib req.sym_out->st_value)); 353045890Sjdp} 353145890Sjdp 353266056Sjdp/* 353390172Ssobomax * Set a pointer variable in the main program to the given value. This 353490172Ssobomax * is used to set key variables such as "environ" before any of the 353590172Ssobomax * init functions are called. 353690172Ssobomax */ 353790172Ssobomaxstatic void 353890172Ssobomaxset_program_var(const char *name, const void *value) 353990172Ssobomax{ 354090172Ssobomax const void **addr; 354190172Ssobomax 3542217223Skib if ((addr = get_program_var_addr(name, NULL)) != NULL) { 354390172Ssobomax dbg("\"%s\": *%p <-- %p", name, addr, value); 354490172Ssobomax *addr = value; 354590172Ssobomax } 354690172Ssobomax} 354790172Ssobomax 354890172Ssobomax/* 3549217223Skib * Search the global objects, including dependencies and main object, 3550217223Skib * for the given symbol. 3551217223Skib */ 3552217223Skibstatic int 3553217223Skibsymlook_global(SymLook *req, DoneList *donelist) 3554217223Skib{ 3555217223Skib SymLook req1; 3556217223Skib const Objlist_Entry *elm; 3557217223Skib int res; 3558217223Skib 3559217223Skib symlook_init_from_req(&req1, req); 3560217223Skib 3561217223Skib /* Search all objects loaded at program start up. */ 3562217223Skib if (req->defobj_out == NULL || 3563217223Skib ELF_ST_BIND(req->sym_out->st_info) == STB_WEAK) { 3564217223Skib res = symlook_list(&req1, &list_main, donelist); 3565217223Skib if (res == 0 && (req->defobj_out == NULL || 3566217223Skib ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) { 3567217223Skib req->sym_out = req1.sym_out; 3568217223Skib req->defobj_out = req1.defobj_out; 3569217223Skib assert(req->defobj_out != NULL); 3570217223Skib } 3571217223Skib } 3572217223Skib 3573217223Skib /* Search all DAGs whose roots are RTLD_GLOBAL objects. */ 3574217223Skib STAILQ_FOREACH(elm, &list_global, link) { 3575217223Skib if (req->defobj_out != NULL && 3576217223Skib ELF_ST_BIND(req->sym_out->st_info) != STB_WEAK) 3577217223Skib break; 3578217223Skib res = symlook_list(&req1, &elm->obj->dagmembers, donelist); 3579217223Skib if (res == 0 && (req->defobj_out == NULL || 3580217223Skib ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) { 3581217223Skib req->sym_out = req1.sym_out; 3582217223Skib req->defobj_out = req1.defobj_out; 3583217223Skib assert(req->defobj_out != NULL); 3584217223Skib } 3585217223Skib } 3586217223Skib 3587217223Skib return (req->sym_out != NULL ? 0 : ESRCH); 3588217223Skib} 3589217223Skib 3590217223Skib/* 359166056Sjdp * Given a symbol name in a referencing object, find the corresponding 359266056Sjdp * definition of the symbol. Returns a pointer to the symbol, or NULL if 359366056Sjdp * no definition was found. Returns a pointer to the Obj_Entry of the 359466056Sjdp * defining object via the reference parameter DEFOBJ_OUT. 359566056Sjdp */ 3596216695Skibstatic int 3597216695Skibsymlook_default(SymLook *req, const Obj_Entry *refobj) 359866056Sjdp{ 359966056Sjdp DoneList donelist; 360066056Sjdp const Objlist_Entry *elm; 3601216695Skib SymLook req1; 3602216695Skib int res; 3603217223Skib 360466056Sjdp donelist_init(&donelist); 3605216695Skib symlook_init_from_req(&req1, req); 360666056Sjdp 360766056Sjdp /* Look first in the referencing object if linked symbolically. */ 360866056Sjdp if (refobj->symbolic && !donelist_check(&donelist, refobj)) { 3609216695Skib res = symlook_obj(&req1, refobj); 3610216695Skib if (res == 0) { 3611217223Skib req->sym_out = req1.sym_out; 3612217223Skib req->defobj_out = req1.defobj_out; 3613217223Skib assert(req->defobj_out != NULL); 361466056Sjdp } 361566056Sjdp } 361666056Sjdp 3617217223Skib symlook_global(req, &donelist); 361866056Sjdp 3619105492Skan /* Search all dlopened DAGs containing the referencing object. */ 3620105492Skan STAILQ_FOREACH(elm, &refobj->dldags, link) { 3621217223Skib if (req->sym_out != NULL && 3622217223Skib ELF_ST_BIND(req->sym_out->st_info) != STB_WEAK) 3623105492Skan break; 3624216695Skib res = symlook_list(&req1, &elm->obj->dagmembers, &donelist); 3625217223Skib if (res == 0 && (req->sym_out == NULL || 3626217223Skib ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) { 3627217223Skib req->sym_out = req1.sym_out; 3628217223Skib req->defobj_out = req1.defobj_out; 3629217223Skib assert(req->defobj_out != NULL); 363066056Sjdp } 363166056Sjdp } 363266056Sjdp 363366056Sjdp /* 363466056Sjdp * Search the dynamic linker itself, and possibly resolve the 363566056Sjdp * symbol from there. This is how the application links to 3636211749Skib * dynamic linker services such as dlopen. 363766056Sjdp */ 3638217223Skib if (req->sym_out == NULL || 3639217223Skib ELF_ST_BIND(req->sym_out->st_info) == STB_WEAK) { 3640216695Skib res = symlook_obj(&req1, &obj_rtld); 3641216695Skib if (res == 0) { 3642217223Skib req->sym_out = req1.sym_out; 3643217223Skib req->defobj_out = req1.defobj_out; 3644217223Skib assert(req->defobj_out != NULL); 364566056Sjdp } 364666056Sjdp } 364766056Sjdp 3648217223Skib return (req->sym_out != NULL ? 0 : ESRCH); 364966056Sjdp} 365066056Sjdp 3651216695Skibstatic int 3652216695Skibsymlook_list(SymLook *req, const Objlist *objlist, DoneList *dlp) 365350608Sjdp{ 365450608Sjdp const Elf_Sym *def; 365550608Sjdp const Obj_Entry *defobj; 365650608Sjdp const Objlist_Entry *elm; 3657216695Skib SymLook req1; 3658216695Skib int res; 365950608Sjdp 366050608Sjdp def = NULL; 366150608Sjdp defobj = NULL; 366250608Sjdp STAILQ_FOREACH(elm, objlist, link) { 366362801Sjdp if (donelist_check(dlp, elm->obj)) 366450608Sjdp continue; 3665216695Skib symlook_init_from_req(&req1, req); 3666216695Skib if ((res = symlook_obj(&req1, elm->obj)) == 0) { 3667216695Skib if (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK) { 3668216695Skib def = req1.sym_out; 3669216695Skib defobj = req1.defobj_out; 367050608Sjdp if (ELF_ST_BIND(def->st_info) != STB_WEAK) 367150608Sjdp break; 367250608Sjdp } 367350608Sjdp } 367450608Sjdp } 3675216695Skib if (def != NULL) { 3676216695Skib req->sym_out = def; 3677216695Skib req->defobj_out = defobj; 3678216695Skib return (0); 3679216695Skib } 3680216695Skib return (ESRCH); 368150608Sjdp} 368250608Sjdp 368345890Sjdp/* 3684218051Skan * Search the chain of DAGS cointed to by the given Needed_Entry 3685218051Skan * for a symbol of the given name. Each DAG is scanned completely 3686218051Skan * before advancing to the next one. Returns a pointer to the symbol, 3687218051Skan * or NULL if no definition was found. 3688162438Skib */ 3689216695Skibstatic int 3690216695Skibsymlook_needed(SymLook *req, const Needed_Entry *needed, DoneList *dlp) 3691162438Skib{ 3692218051Skan const Elf_Sym *def; 3693162438Skib const Needed_Entry *n; 3694218051Skan const Obj_Entry *defobj; 3695216695Skib SymLook req1; 3696216695Skib int res; 3697162449Sjkim 3698218051Skan def = NULL; 3699162438Skib defobj = NULL; 3700216695Skib symlook_init_from_req(&req1, req); 3701162438Skib for (n = needed; n != NULL; n = n->next) { 3702218051Skan if (n->obj == NULL || 3703218051Skan (res = symlook_list(&req1, &n->obj->dagmembers, dlp)) != 0) 3704162449Sjkim continue; 3705218051Skan if (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK) { 3706218051Skan def = req1.sym_out; 3707218051Skan defobj = req1.defobj_out; 3708218051Skan if (ELF_ST_BIND(def->st_info) != STB_WEAK) 3709218051Skan break; 3710162438Skib } 3711162438Skib } 3712216695Skib if (def != NULL) { 3713216695Skib req->sym_out = def; 3714216695Skib req->defobj_out = defobj; 3715216695Skib return (0); 3716216695Skib } 3717216695Skib return (ESRCH); 3718162438Skib} 3719162438Skib 3720162438Skib/* 372138739Sjdp * Search the symbol table of a single shared object for a symbol of 3722153515Skan * the given name and version, if requested. Returns a pointer to the 3723216695Skib * symbol, or NULL if no definition was found. If the object is 3724216695Skib * filter, return filtered symbol from filtee. 372538739Sjdp * 372638739Sjdp * The symbol's hash value is passed in for efficiency reasons; that 372738739Sjdp * eliminates many recomputations of the hash value. 372838739Sjdp */ 3729216695Skibint 3730216695Skibsymlook_obj(SymLook *req, const Obj_Entry *obj) 373138739Sjdp{ 3732216695Skib DoneList donelist; 3733216695Skib SymLook req1; 3734233831Skib int flags, res, mres; 3735216695Skib 3736235396Skib /* 3737235396Skib * If there is at least one valid hash at this point, we prefer to 3738235396Skib * use the faster GNU version if available. 3739235396Skib */ 3740235396Skib if (obj->valid_hash_gnu) 3741235396Skib mres = symlook_obj1_gnu(req, obj); 3742235396Skib else if (obj->valid_hash_sysv) 3743235396Skib mres = symlook_obj1_sysv(req, obj); 3744235396Skib else 3745235396Skib return (EINVAL); 3746235396Skib 3747216695Skib if (mres == 0) { 3748216695Skib if (obj->needed_filtees != NULL) { 3749233831Skib flags = (req->flags & SYMLOOK_EARLY) ? RTLD_LO_EARLY : 0; 3750233831Skib load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate); 3751216695Skib donelist_init(&donelist); 3752216695Skib symlook_init_from_req(&req1, req); 3753216695Skib res = symlook_needed(&req1, obj->needed_filtees, &donelist); 3754216695Skib if (res == 0) { 3755216695Skib req->sym_out = req1.sym_out; 3756216695Skib req->defobj_out = req1.defobj_out; 3757216695Skib } 3758216695Skib return (res); 3759216695Skib } 3760216695Skib if (obj->needed_aux_filtees != NULL) { 3761233831Skib flags = (req->flags & SYMLOOK_EARLY) ? RTLD_LO_EARLY : 0; 3762233831Skib load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate); 3763216695Skib donelist_init(&donelist); 3764216695Skib symlook_init_from_req(&req1, req); 3765216695Skib res = symlook_needed(&req1, obj->needed_aux_filtees, &donelist); 3766216695Skib if (res == 0) { 3767216695Skib req->sym_out = req1.sym_out; 3768216695Skib req->defobj_out = req1.defobj_out; 3769216695Skib return (res); 3770216695Skib } 3771216695Skib } 3772216695Skib } 3773216695Skib return (mres); 3774216695Skib} 3775216695Skib 3776235396Skib/* Symbol match routine common to both hash functions */ 3777235396Skibstatic bool 3778235396Skibmatched_symbol(SymLook *req, const Obj_Entry *obj, Sym_Match_Result *result, 3779235396Skib const unsigned long symnum) 3780216695Skib{ 3781235396Skib Elf_Versym verndx; 3782153515Skan const Elf_Sym *symp; 3783153515Skan const char *strp; 3784153515Skan 3785153515Skan symp = obj->symtab + symnum; 3786153515Skan strp = obj->strtab + symp->st_name; 378738739Sjdp 3788153515Skan switch (ELF_ST_TYPE(symp->st_info)) { 3789153515Skan case STT_FUNC: 3790153515Skan case STT_NOTYPE: 3791153515Skan case STT_OBJECT: 3792235396Skib case STT_COMMON: 3793229503Skib case STT_GNU_IFUNC: 3794235396Skib if (symp->st_value == 0) 3795235396Skib return (false); 3796153515Skan /* fallthrough */ 3797153515Skan case STT_TLS: 3798235396Skib if (symp->st_shndx != SHN_UNDEF) 3799235396Skib break; 3800177924Simp#ifndef __mips__ 3801235396Skib else if (((req->flags & SYMLOOK_IN_PLT) == 0) && 3802235396Skib (ELF_ST_TYPE(symp->st_info) == STT_FUNC)) 3803235396Skib break; 3804153515Skan /* fallthrough */ 3805177924Simp#endif 3806153515Skan default: 3807235396Skib return (false); 380845501Sjdp } 3809216695Skib if (req->name[0] != strp[0] || strcmp(req->name, strp) != 0) 3810235396Skib return (false); 3811153515Skan 3812216695Skib if (req->ventry == NULL) { 3813235396Skib if (obj->versyms != NULL) { 3814235396Skib verndx = VER_NDX(obj->versyms[symnum]); 3815235396Skib if (verndx > obj->vernum) { 3816235396Skib _rtld_error( 3817235396Skib "%s: symbol %s references wrong version %d", 3818235396Skib obj->path, obj->strtab + symnum, verndx); 3819235396Skib return (false); 3820235396Skib } 3821235396Skib /* 3822235396Skib * If we are not called from dlsym (i.e. this 3823235396Skib * is a normal relocation from unversioned 3824235396Skib * binary), accept the symbol immediately if 3825235396Skib * it happens to have first version after this 3826235396Skib * shared object became versioned. Otherwise, 3827235396Skib * if symbol is versioned and not hidden, 3828235396Skib * remember it. If it is the only symbol with 3829235396Skib * this name exported by the shared object, it 3830235396Skib * will be returned as a match by the calling 3831235396Skib * function. If symbol is global (verndx < 2) 3832235396Skib * accept it unconditionally. 3833235396Skib */ 3834235396Skib if ((req->flags & SYMLOOK_DLSYM) == 0 && 3835235396Skib verndx == VER_NDX_GIVEN) { 3836235396Skib result->sym_out = symp; 3837235396Skib return (true); 3838235396Skib } 3839235396Skib else if (verndx >= VER_NDX_GIVEN) { 3840235396Skib if ((obj->versyms[symnum] & VER_NDX_HIDDEN) 3841235396Skib == 0) { 3842235396Skib if (result->vsymp == NULL) 3843235396Skib result->vsymp = symp; 3844235396Skib result->vcount++; 3845235396Skib } 3846235396Skib return (false); 3847235396Skib } 3848153515Skan } 3849235396Skib result->sym_out = symp; 3850235396Skib return (true); 3851235396Skib } 3852235396Skib if (obj->versyms == NULL) { 3853235396Skib if (object_match_name(obj, req->ventry->name)) { 3854235396Skib _rtld_error("%s: object %s should provide version %s " 3855235396Skib "for symbol %s", obj_rtld.path, obj->path, 3856235396Skib req->ventry->name, obj->strtab + symnum); 3857235396Skib return (false); 3858216695Skib } 3859153515Skan } else { 3860153515Skan verndx = VER_NDX(obj->versyms[symnum]); 3861153515Skan if (verndx > obj->vernum) { 3862235396Skib _rtld_error("%s: symbol %s references wrong version %d", 3863235396Skib obj->path, obj->strtab + symnum, verndx); 3864235396Skib return (false); 3865153515Skan } 3866216695Skib if (obj->vertab[verndx].hash != req->ventry->hash || 3867216695Skib strcmp(obj->vertab[verndx].name, req->ventry->name)) { 3868235396Skib /* 3869235396Skib * Version does not match. Look if this is a 3870235396Skib * global symbol and if it is not hidden. If 3871235396Skib * global symbol (verndx < 2) is available, 3872235396Skib * use it. Do not return symbol if we are 3873235396Skib * called by dlvsym, because dlvsym looks for 3874235396Skib * a specific version and default one is not 3875235396Skib * what dlvsym wants. 3876235396Skib */ 3877235396Skib if ((req->flags & SYMLOOK_DLSYM) || 3878235396Skib (verndx >= VER_NDX_GIVEN) || 3879235396Skib (obj->versyms[symnum] & VER_NDX_HIDDEN)) 3880235396Skib return (false); 3881153515Skan } 3882153515Skan } 3883235396Skib result->sym_out = symp; 3884235396Skib return (true); 388538739Sjdp} 388638739Sjdp 3887235396Skib/* 3888235396Skib * Search for symbol using SysV hash function. 3889235396Skib * obj->buckets is known not to be NULL at this point; the test for this was 3890235396Skib * performed with the obj->valid_hash_sysv assignment. 3891235396Skib */ 3892235396Skibstatic int 3893235396Skibsymlook_obj1_sysv(SymLook *req, const Obj_Entry *obj) 3894235396Skib{ 3895235396Skib unsigned long symnum; 3896235396Skib Sym_Match_Result matchres; 3897235396Skib 3898235396Skib matchres.sym_out = NULL; 3899235396Skib matchres.vsymp = NULL; 3900235396Skib matchres.vcount = 0; 3901235396Skib 3902235396Skib for (symnum = obj->buckets[req->hash % obj->nbuckets]; 3903235396Skib symnum != STN_UNDEF; symnum = obj->chains[symnum]) { 3904235396Skib if (symnum >= obj->nchains) 3905235396Skib return (ESRCH); /* Bad object */ 3906235396Skib 3907235396Skib if (matched_symbol(req, obj, &matchres, symnum)) { 3908235396Skib req->sym_out = matchres.sym_out; 3909235396Skib req->defobj_out = obj; 3910235396Skib return (0); 3911235396Skib } 3912235396Skib } 3913235396Skib if (matchres.vcount == 1) { 3914235396Skib req->sym_out = matchres.vsymp; 3915235396Skib req->defobj_out = obj; 3916235396Skib return (0); 3917235396Skib } 3918235396Skib return (ESRCH); 3919235396Skib} 3920235396Skib 3921235396Skib/* Search for symbol using GNU hash function */ 3922235396Skibstatic int 3923235396Skibsymlook_obj1_gnu(SymLook *req, const Obj_Entry *obj) 3924235396Skib{ 3925235396Skib Elf_Addr bloom_word; 3926235396Skib const Elf32_Word *hashval; 3927235396Skib Elf32_Word bucket; 3928235396Skib Sym_Match_Result matchres; 3929235396Skib unsigned int h1, h2; 3930235396Skib unsigned long symnum; 3931235396Skib 3932235396Skib matchres.sym_out = NULL; 3933235396Skib matchres.vsymp = NULL; 3934235396Skib matchres.vcount = 0; 3935235396Skib 3936235396Skib /* Pick right bitmask word from Bloom filter array */ 3937235396Skib bloom_word = obj->bloom_gnu[(req->hash_gnu / __ELF_WORD_SIZE) & 3938235396Skib obj->maskwords_bm_gnu]; 3939235396Skib 3940235396Skib /* Calculate modulus word size of gnu hash and its derivative */ 3941235396Skib h1 = req->hash_gnu & (__ELF_WORD_SIZE - 1); 3942235396Skib h2 = ((req->hash_gnu >> obj->shift2_gnu) & (__ELF_WORD_SIZE - 1)); 3943235396Skib 3944235396Skib /* Filter out the "definitely not in set" queries */ 3945235396Skib if (((bloom_word >> h1) & (bloom_word >> h2) & 1) == 0) 3946235396Skib return (ESRCH); 3947235396Skib 3948235396Skib /* Locate hash chain and corresponding value element*/ 3949235396Skib bucket = obj->buckets_gnu[req->hash_gnu % obj->nbuckets_gnu]; 3950235396Skib if (bucket == 0) 3951235396Skib return (ESRCH); 3952235396Skib hashval = &obj->chain_zero_gnu[bucket]; 3953235396Skib do { 3954235396Skib if (((*hashval ^ req->hash_gnu) >> 1) == 0) { 3955235396Skib symnum = hashval - obj->chain_zero_gnu; 3956235396Skib if (matched_symbol(req, obj, &matchres, symnum)) { 3957235396Skib req->sym_out = matchres.sym_out; 3958235396Skib req->defobj_out = obj; 3959235396Skib return (0); 3960235396Skib } 3961235396Skib } 3962235396Skib } while ((*hashval++ & 1) == 0); 3963235396Skib if (matchres.vcount == 1) { 3964235396Skib req->sym_out = matchres.vsymp; 3965235396Skib req->defobj_out = obj; 3966235396Skib return (0); 3967235396Skib } 3968235396Skib return (ESRCH); 3969235396Skib} 3970235396Skib 397138739Sjdpstatic void 397238739Sjdptrace_loaded_objects(Obj_Entry *obj) 397338739Sjdp{ 397490755Sobrien char *fmt1, *fmt2, *fmt, *main_local, *list_containers; 397535574Sdfr int c; 397635574Sdfr 3977127250Speter if ((main_local = getenv(LD_ "TRACE_LOADED_OBJECTS_PROGNAME")) == NULL) 397835574Sdfr main_local = ""; 397935574Sdfr 3980127250Speter if ((fmt1 = getenv(LD_ "TRACE_LOADED_OBJECTS_FMT1")) == NULL) 398135574Sdfr fmt1 = "\t%o => %p (%x)\n"; 398235574Sdfr 3983127250Speter if ((fmt2 = getenv(LD_ "TRACE_LOADED_OBJECTS_FMT2")) == NULL) 398435574Sdfr fmt2 = "\t%o (%x)\n"; 398535574Sdfr 3986127250Speter list_containers = getenv(LD_ "TRACE_LOADED_OBJECTS_ALL"); 398790755Sobrien 398835574Sdfr for (; obj; obj = obj->next) { 398935574Sdfr Needed_Entry *needed; 399035574Sdfr char *name, *path; 399135574Sdfr bool is_lib; 399235574Sdfr 399390755Sobrien if (list_containers && obj->needed != NULL) 3994225152Skib rtld_printf("%s:\n", obj->path); 399535574Sdfr for (needed = obj->needed; needed; needed = needed->next) { 399638740Sjdp if (needed->obj != NULL) { 399790755Sobrien if (needed->obj->traced && !list_containers) 399838740Sjdp continue; 399938740Sjdp needed->obj->traced = true; 400038740Sjdp path = needed->obj->path; 400138740Sjdp } else 400238740Sjdp path = "not found"; 400338740Sjdp 400435574Sdfr name = (char *)obj->strtab + needed->name; 400538740Sjdp is_lib = strncmp(name, "lib", 3) == 0; /* XXX - bogus */ 400635574Sdfr 400735574Sdfr fmt = is_lib ? fmt1 : fmt2; 400835574Sdfr while ((c = *fmt++) != '\0') { 400935574Sdfr switch (c) { 401035574Sdfr default: 4011225152Skib rtld_putchar(c); 401235574Sdfr continue; 401335574Sdfr case '\\': 401435574Sdfr switch (c = *fmt) { 401535574Sdfr case '\0': 401635574Sdfr continue; 401735574Sdfr case 'n': 4018225152Skib rtld_putchar('\n'); 401935574Sdfr break; 402035574Sdfr case 't': 4021225152Skib rtld_putchar('\t'); 402235574Sdfr break; 402335574Sdfr } 402435574Sdfr break; 402535574Sdfr case '%': 402635574Sdfr switch (c = *fmt) { 402735574Sdfr case '\0': 402835574Sdfr continue; 402935574Sdfr case '%': 403035574Sdfr default: 4031225152Skib rtld_putchar(c); 403235574Sdfr break; 403335574Sdfr case 'A': 4034225152Skib rtld_putstr(main_local); 403535574Sdfr break; 403635574Sdfr case 'a': 4037225152Skib rtld_putstr(obj_main->path); 403835574Sdfr break; 403935574Sdfr case 'o': 4040225152Skib rtld_putstr(name); 404135574Sdfr break; 404235574Sdfr#if 0 404335574Sdfr case 'm': 4044225152Skib rtld_printf("%d", sodp->sod_major); 404535574Sdfr break; 404635574Sdfr case 'n': 4047225152Skib rtld_printf("%d", sodp->sod_minor); 404835574Sdfr break; 404935574Sdfr#endif 405035574Sdfr case 'p': 4051225152Skib rtld_putstr(path); 405235574Sdfr break; 405335574Sdfr case 'x': 4054225152Skib rtld_printf("%p", needed->obj ? needed->obj->mapbase : 4055225152Skib 0); 405635574Sdfr break; 405735574Sdfr } 405835574Sdfr break; 405935574Sdfr } 406035574Sdfr ++fmt; 406135574Sdfr } 406235574Sdfr } 406335574Sdfr } 406435574Sdfr} 406538739Sjdp 406650608Sjdp/* 406755687Sjdp * Unload a dlopened object and its dependencies from memory and from 406855687Sjdp * our data structures. It is assumed that the DAG rooted in the 406955687Sjdp * object has already been unreferenced, and that the object has a 407055687Sjdp * reference count of 0. 407150608Sjdp */ 407238739Sjdpstatic void 407355687Sjdpunload_object(Obj_Entry *root) 407448708Sjdp{ 407555687Sjdp Obj_Entry *obj; 407655687Sjdp Obj_Entry **linkp; 407748708Sjdp 407855687Sjdp assert(root->refcount == 0); 407948708Sjdp 4080111054Skan /* 4081111054Skan * Pass over the DAG removing unreferenced objects from 4082111054Skan * appropriate lists. 4083115396Skan */ 4084111054Skan unlink_object(root); 4085111054Skan 408655687Sjdp /* Unmap all objects that are no longer referenced. */ 408755687Sjdp linkp = &obj_list->next; 408855687Sjdp while ((obj = *linkp) != NULL) { 408955687Sjdp if (obj->refcount == 0) { 4090165916Sjhb LD_UTRACE(UTRACE_UNLOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0, 4091165916Sjhb obj->path); 409255687Sjdp dbg("unloading \"%s\"", obj->path); 4093216695Skib unload_filtees(root); 409455687Sjdp munmap(obj->mapbase, obj->mapsize); 409555687Sjdp linkmap_delete(obj); 409655687Sjdp *linkp = obj->next; 409762801Sjdp obj_count--; 409855687Sjdp obj_free(obj); 409955687Sjdp } else 410055687Sjdp linkp = &obj->next; 410148708Sjdp } 410255687Sjdp obj_tail = linkp; 410348708Sjdp} 410448708Sjdp 410548708Sjdpstatic void 4106111054Skanunlink_object(Obj_Entry *root) 410738739Sjdp{ 4108110659Skan Objlist_Entry *elm; 410950096Sjdp 4110110659Skan if (root->refcount == 0) { 4111110659Skan /* Remove the object from the RTLD_GLOBAL list. */ 4112110659Skan objlist_remove(&list_global, root); 4113110659Skan 4114110659Skan /* Remove the object from all objects' DAG lists. */ 4115153515Skan STAILQ_FOREACH(elm, &root->dagmembers, link) { 4116110659Skan objlist_remove(&elm->obj->dldags, root); 4117114826Skan if (elm->obj != root) 4118114826Skan unlink_object(elm->obj); 4119114826Skan } 4120110659Skan } 4121114826Skan} 4122111054Skan 4123114826Skanstatic void 4124114826Skanref_dag(Obj_Entry *root) 4125114826Skan{ 4126114826Skan Objlist_Entry *elm; 4127114826Skan 4128214777Skib assert(root->dag_inited); 4129153515Skan STAILQ_FOREACH(elm, &root->dagmembers, link) 4130114826Skan elm->obj->refcount++; 413138739Sjdp} 4132111054Skan 4133111054Skanstatic void 4134111054Skanunref_dag(Obj_Entry *root) 4135111054Skan{ 4136114826Skan Objlist_Entry *elm; 4137111054Skan 4138214777Skib assert(root->dag_inited); 4139153515Skan STAILQ_FOREACH(elm, &root->dagmembers, link) 4140114826Skan elm->obj->refcount--; 4141111054Skan} 4142115396Skan 4143133063Sdfr/* 4144133063Sdfr * Common code for MD __tls_get_addr(). 4145133063Sdfr */ 4146233063Skibstatic void *tls_get_addr_slow(Elf_Addr **, int, size_t) __noinline; 4147233063Skibstatic void * 4148233063Skibtls_get_addr_slow(Elf_Addr **dtvp, int index, size_t offset) 4149133063Sdfr{ 4150233063Skib Elf_Addr *newdtv, *dtv; 4151216695Skib RtldLockState lockstate; 4152233063Skib int to_copy; 4153115396Skan 4154233063Skib dtv = *dtvp; 4155133063Sdfr /* Check dtv generation in case new modules have arrived */ 4156133063Sdfr if (dtv[0] != tls_dtv_generation) { 4157216695Skib wlock_acquire(rtld_bind_lock, &lockstate); 4158233922Skib newdtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); 4159133063Sdfr to_copy = dtv[1]; 4160133063Sdfr if (to_copy > tls_max_index) 4161133063Sdfr to_copy = tls_max_index; 4162133063Sdfr memcpy(&newdtv[2], &dtv[2], to_copy * sizeof(Elf_Addr)); 4163133063Sdfr newdtv[0] = tls_dtv_generation; 4164133063Sdfr newdtv[1] = tls_max_index; 4165133063Sdfr free(dtv); 4166216695Skib lock_release(rtld_bind_lock, &lockstate); 4167225582Skib dtv = *dtvp = newdtv; 4168133063Sdfr } 4169133063Sdfr 4170133063Sdfr /* Dynamically allocate module TLS if necessary */ 4171233063Skib if (dtv[index + 1] == 0) { 4172143893Sdavidxu /* Signal safe, wlock will block out signals. */ 4173233063Skib wlock_acquire(rtld_bind_lock, &lockstate); 4174143893Sdavidxu if (!dtv[index + 1]) 4175143893Sdavidxu dtv[index + 1] = (Elf_Addr)allocate_module_tls(index); 4176216695Skib lock_release(rtld_bind_lock, &lockstate); 4177143893Sdavidxu } 4178233063Skib return ((void *)(dtv[index + 1] + offset)); 4179133063Sdfr} 4180133063Sdfr 4181233063Skibvoid * 4182233063Skibtls_get_addr_common(Elf_Addr **dtvp, int index, size_t offset) 4183233063Skib{ 4184233063Skib Elf_Addr *dtv; 4185233063Skib 4186233063Skib dtv = *dtvp; 4187233063Skib /* Check dtv generation in case new modules have arrived */ 4188233063Skib if (__predict_true(dtv[0] == tls_dtv_generation && 4189233063Skib dtv[index + 1] != 0)) 4190233063Skib return ((void *)(dtv[index + 1] + offset)); 4191233063Skib return (tls_get_addr_slow(dtvp, index, offset)); 4192233063Skib} 4193233063Skib 4194237394Smarius#if defined(__arm__) || defined(__ia64__) || defined(__powerpc__) 4195133063Sdfr 4196133063Sdfr/* 4197133063Sdfr * Allocate Static TLS using the Variant I method. 4198133063Sdfr */ 4199133063Sdfrvoid * 4200161800Smarcelallocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) 4201133063Sdfr{ 4202133063Sdfr Obj_Entry *obj; 4203161800Smarcel char *tcb; 4204161800Smarcel Elf_Addr **tls; 4205161800Smarcel Elf_Addr *dtv; 4206133063Sdfr Elf_Addr addr; 4207133063Sdfr int i; 4208133063Sdfr 4209161800Smarcel if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE) 4210161800Smarcel return (oldtcb); 4211133063Sdfr 4212161800Smarcel assert(tcbsize >= TLS_TCB_SIZE); 4213233922Skib tcb = xcalloc(1, tls_static_space - TLS_TCB_SIZE + tcbsize); 4214161800Smarcel tls = (Elf_Addr **)(tcb + tcbsize - TLS_TCB_SIZE); 4215133063Sdfr 4216161800Smarcel if (oldtcb != NULL) { 4217161800Smarcel memcpy(tls, oldtcb, tls_static_space); 4218161800Smarcel free(oldtcb); 4219133063Sdfr 4220161800Smarcel /* Adjust the DTV. */ 4221161800Smarcel dtv = tls[0]; 4222161800Smarcel for (i = 0; i < dtv[1]; i++) { 4223161800Smarcel if (dtv[i+2] >= (Elf_Addr)oldtcb && 4224161800Smarcel dtv[i+2] < (Elf_Addr)oldtcb + tls_static_space) { 4225161800Smarcel dtv[i+2] = dtv[i+2] - (Elf_Addr)oldtcb + (Elf_Addr)tls; 4226133063Sdfr } 4227133063Sdfr } 4228161800Smarcel } else { 4229233922Skib dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); 4230161800Smarcel tls[0] = dtv; 4231161800Smarcel dtv[0] = tls_dtv_generation; 4232161800Smarcel dtv[1] = tls_max_index; 4233133063Sdfr 4234133063Sdfr for (obj = objs; obj; obj = obj->next) { 4235203947Smarcel if (obj->tlsoffset > 0) { 4236133063Sdfr addr = (Elf_Addr)tls + obj->tlsoffset; 4237203947Smarcel if (obj->tlsinitsize > 0) 4238203947Smarcel memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize); 4239203947Smarcel if (obj->tlssize > obj->tlsinitsize) 4240203947Smarcel memset((void*) (addr + obj->tlsinitsize), 0, 4241203947Smarcel obj->tlssize - obj->tlsinitsize); 4242133063Sdfr dtv[obj->tlsindex + 1] = addr; 4243133063Sdfr } 4244133063Sdfr } 4245133063Sdfr } 4246133063Sdfr 4247161800Smarcel return (tcb); 4248133063Sdfr} 4249133063Sdfr 4250133063Sdfrvoid 4251161800Smarcelfree_tls(void *tcb, size_t tcbsize, size_t tcbalign) 4252133063Sdfr{ 4253161800Smarcel Elf_Addr *dtv; 4254161800Smarcel Elf_Addr tlsstart, tlsend; 4255133063Sdfr int dtvsize, i; 4256133063Sdfr 4257161800Smarcel assert(tcbsize >= TLS_TCB_SIZE); 4258133063Sdfr 4259161800Smarcel tlsstart = (Elf_Addr)tcb + tcbsize - TLS_TCB_SIZE; 4260161800Smarcel tlsend = tlsstart + tls_static_space; 4261161800Smarcel 4262161800Smarcel dtv = *(Elf_Addr **)tlsstart; 4263133063Sdfr dtvsize = dtv[1]; 4264133063Sdfr for (i = 0; i < dtvsize; i++) { 4265161800Smarcel if (dtv[i+2] && (dtv[i+2] < tlsstart || dtv[i+2] >= tlsend)) { 4266161800Smarcel free((void*)dtv[i+2]); 4267133063Sdfr } 4268133063Sdfr } 4269161800Smarcel free(dtv); 4270161800Smarcel free(tcb); 4271133063Sdfr} 4272133063Sdfr 4273133063Sdfr#endif 4274133063Sdfr 4275135680Scognet#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \ 4276237394Smarius defined(__mips__) 4277133063Sdfr 4278133063Sdfr/* 4279133063Sdfr * Allocate Static TLS using the Variant II method. 4280133063Sdfr */ 4281133063Sdfrvoid * 4282133063Sdfrallocate_tls(Obj_Entry *objs, void *oldtls, size_t tcbsize, size_t tcbalign) 4283133063Sdfr{ 4284133063Sdfr Obj_Entry *obj; 4285259293Skib size_t size, ralign; 4286133063Sdfr char *tls; 4287133063Sdfr Elf_Addr *dtv, *olddtv; 4288133063Sdfr Elf_Addr segbase, oldsegbase, addr; 4289133063Sdfr int i; 4290133063Sdfr 4291259293Skib ralign = tcbalign; 4292259293Skib if (tls_static_max_align > ralign) 4293259293Skib ralign = tls_static_max_align; 4294259293Skib size = round(tls_static_space, ralign) + round(tcbsize, ralign); 4295133063Sdfr 4296133063Sdfr assert(tcbsize >= 2*sizeof(Elf_Addr)); 4297259293Skib tls = malloc_aligned(size, ralign); 4298233922Skib dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); 4299133063Sdfr 4300259293Skib segbase = (Elf_Addr)(tls + round(tls_static_space, ralign)); 4301133063Sdfr ((Elf_Addr*)segbase)[0] = segbase; 4302133063Sdfr ((Elf_Addr*)segbase)[1] = (Elf_Addr) dtv; 4303133063Sdfr 4304133063Sdfr dtv[0] = tls_dtv_generation; 4305133063Sdfr dtv[1] = tls_max_index; 4306133063Sdfr 4307133063Sdfr if (oldtls) { 4308133063Sdfr /* 4309133063Sdfr * Copy the static TLS block over whole. 4310133063Sdfr */ 4311133063Sdfr oldsegbase = (Elf_Addr) oldtls; 4312133063Sdfr memcpy((void *)(segbase - tls_static_space), 4313133063Sdfr (const void *)(oldsegbase - tls_static_space), 4314133063Sdfr tls_static_space); 4315133063Sdfr 4316133063Sdfr /* 4317133063Sdfr * If any dynamic TLS blocks have been created tls_get_addr(), 4318133063Sdfr * move them over. 4319133063Sdfr */ 4320133063Sdfr olddtv = ((Elf_Addr**)oldsegbase)[1]; 4321133063Sdfr for (i = 0; i < olddtv[1]; i++) { 4322133063Sdfr if (olddtv[i+2] < oldsegbase - size || olddtv[i+2] > oldsegbase) { 4323133063Sdfr dtv[i+2] = olddtv[i+2]; 4324133063Sdfr olddtv[i+2] = 0; 4325133063Sdfr } 4326133063Sdfr } 4327133063Sdfr 4328133063Sdfr /* 4329133063Sdfr * We assume that this block was the one we created with 4330133063Sdfr * allocate_initial_tls(). 4331133063Sdfr */ 4332133063Sdfr free_tls(oldtls, 2*sizeof(Elf_Addr), sizeof(Elf_Addr)); 4333133063Sdfr } else { 4334133063Sdfr for (obj = objs; obj; obj = obj->next) { 4335133063Sdfr if (obj->tlsoffset) { 4336133063Sdfr addr = segbase - obj->tlsoffset; 4337133063Sdfr memset((void*) (addr + obj->tlsinitsize), 4338133063Sdfr 0, obj->tlssize - obj->tlsinitsize); 4339133063Sdfr if (obj->tlsinit) 4340133063Sdfr memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize); 4341133063Sdfr dtv[obj->tlsindex + 1] = addr; 4342133063Sdfr } 4343133063Sdfr } 4344133063Sdfr } 4345133063Sdfr 4346133063Sdfr return (void*) segbase; 4347133063Sdfr} 4348133063Sdfr 4349133063Sdfrvoid 4350133063Sdfrfree_tls(void *tls, size_t tcbsize, size_t tcbalign) 4351133063Sdfr{ 4352133063Sdfr Elf_Addr* dtv; 4353259293Skib size_t size, ralign; 4354133063Sdfr int dtvsize, i; 4355133063Sdfr Elf_Addr tlsstart, tlsend; 4356133063Sdfr 4357133063Sdfr /* 4358133063Sdfr * Figure out the size of the initial TLS block so that we can 4359133063Sdfr * find stuff which ___tls_get_addr() allocated dynamically. 4360133063Sdfr */ 4361259293Skib ralign = tcbalign; 4362259293Skib if (tls_static_max_align > ralign) 4363259293Skib ralign = tls_static_max_align; 4364259293Skib size = round(tls_static_space, ralign); 4365133063Sdfr 4366133063Sdfr dtv = ((Elf_Addr**)tls)[1]; 4367133063Sdfr dtvsize = dtv[1]; 4368133063Sdfr tlsend = (Elf_Addr) tls; 4369133063Sdfr tlsstart = tlsend - size; 4370133063Sdfr for (i = 0; i < dtvsize; i++) { 4371259293Skib if (dtv[i + 2] != 0 && (dtv[i + 2] < tlsstart || dtv[i + 2] > tlsend)) { 4372259293Skib free_aligned((void *)dtv[i + 2]); 4373133063Sdfr } 4374133063Sdfr } 4375133063Sdfr 4376259293Skib free_aligned((void *)tlsstart); 4377169276Sdavidxu free((void*) dtv); 4378133063Sdfr} 4379133063Sdfr 4380133063Sdfr#endif 4381133063Sdfr 4382133063Sdfr/* 4383133063Sdfr * Allocate TLS block for module with given index. 4384133063Sdfr */ 4385133063Sdfrvoid * 4386133063Sdfrallocate_module_tls(int index) 4387133063Sdfr{ 4388133063Sdfr Obj_Entry* obj; 4389133063Sdfr char* p; 4390133063Sdfr 4391133063Sdfr for (obj = obj_list; obj; obj = obj->next) { 4392133063Sdfr if (obj->tlsindex == index) 4393133063Sdfr break; 4394133063Sdfr } 4395133063Sdfr if (!obj) { 4396133063Sdfr _rtld_error("Can't find module with TLS index %d", index); 4397133063Sdfr die(); 4398133063Sdfr } 4399133063Sdfr 4400259293Skib p = malloc_aligned(obj->tlssize, obj->tlsalign); 4401133063Sdfr memcpy(p, obj->tlsinit, obj->tlsinitsize); 4402133063Sdfr memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize); 4403133063Sdfr 4404133063Sdfr return p; 4405133063Sdfr} 4406133063Sdfr 4407133063Sdfrbool 4408133063Sdfrallocate_tls_offset(Obj_Entry *obj) 4409133063Sdfr{ 4410133063Sdfr size_t off; 4411133063Sdfr 4412133063Sdfr if (obj->tls_done) 4413133063Sdfr return true; 4414133063Sdfr 4415133063Sdfr if (obj->tlssize == 0) { 4416133063Sdfr obj->tls_done = true; 4417133063Sdfr return true; 4418133063Sdfr } 4419133063Sdfr 4420133063Sdfr if (obj->tlsindex == 1) 4421133063Sdfr off = calculate_first_tls_offset(obj->tlssize, obj->tlsalign); 4422133063Sdfr else 4423133063Sdfr off = calculate_tls_offset(tls_last_offset, tls_last_size, 4424133063Sdfr obj->tlssize, obj->tlsalign); 4425133063Sdfr 4426133063Sdfr /* 4427133063Sdfr * If we have already fixed the size of the static TLS block, we 4428133063Sdfr * must stay within that size. When allocating the static TLS, we 4429133063Sdfr * leave a small amount of space spare to be used for dynamically 4430133063Sdfr * loading modules which use static TLS. 4431133063Sdfr */ 4432259293Skib if (tls_static_space != 0) { 4433133063Sdfr if (calculate_tls_end(off, obj->tlssize) > tls_static_space) 4434133063Sdfr return false; 4435259293Skib } else if (obj->tlsalign > tls_static_max_align) { 4436259293Skib tls_static_max_align = obj->tlsalign; 4437133063Sdfr } 4438133063Sdfr 4439133063Sdfr tls_last_offset = obj->tlsoffset = off; 4440133063Sdfr tls_last_size = obj->tlssize; 4441133063Sdfr obj->tls_done = true; 4442133063Sdfr 4443133063Sdfr return true; 4444133063Sdfr} 4445133063Sdfr 4446142645Sdfrvoid 4447142645Sdfrfree_tls_offset(Obj_Entry *obj) 4448142645Sdfr{ 4449203947Smarcel 4450142645Sdfr /* 4451142645Sdfr * If we were the last thing to allocate out of the static TLS 4452142645Sdfr * block, we give our space back to the 'allocator'. This is a 4453142645Sdfr * simplistic workaround to allow libGL.so.1 to be loaded and 4454203947Smarcel * unloaded multiple times. 4455142645Sdfr */ 4456142645Sdfr if (calculate_tls_end(obj->tlsoffset, obj->tlssize) 4457142645Sdfr == calculate_tls_end(tls_last_offset, tls_last_size)) { 4458142645Sdfr tls_last_offset -= obj->tlssize; 4459142645Sdfr tls_last_size = 0; 4460142645Sdfr } 4461142645Sdfr} 4462142645Sdfr 4463133063Sdfrvoid * 4464133063Sdfr_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) 4465133063Sdfr{ 4466143893Sdavidxu void *ret; 4467216695Skib RtldLockState lockstate; 4468143893Sdavidxu 4469216695Skib wlock_acquire(rtld_bind_lock, &lockstate); 4470143893Sdavidxu ret = allocate_tls(obj_list, oldtls, tcbsize, tcbalign); 4471216695Skib lock_release(rtld_bind_lock, &lockstate); 4472143893Sdavidxu return (ret); 4473133063Sdfr} 4474133063Sdfr 4475133063Sdfrvoid 4476133063Sdfr_rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign) 4477133063Sdfr{ 4478216695Skib RtldLockState lockstate; 4479143893Sdavidxu 4480216695Skib wlock_acquire(rtld_bind_lock, &lockstate); 4481133063Sdfr free_tls(tcb, tcbsize, tcbalign); 4482216695Skib lock_release(rtld_bind_lock, &lockstate); 4483133063Sdfr} 4484153515Skan 4485153515Skanstatic void 4486153515Skanobject_add_name(Obj_Entry *obj, const char *name) 4487153515Skan{ 4488153515Skan Name_Entry *entry; 4489153515Skan size_t len; 4490153515Skan 4491153515Skan len = strlen(name); 4492153515Skan entry = malloc(sizeof(Name_Entry) + len); 4493153515Skan 4494153515Skan if (entry != NULL) { 4495153515Skan strcpy(entry->name, name); 4496153515Skan STAILQ_INSERT_TAIL(&obj->names, entry, link); 4497153515Skan } 4498153515Skan} 4499153515Skan 4500153515Skanstatic int 4501153515Skanobject_match_name(const Obj_Entry *obj, const char *name) 4502153515Skan{ 4503153515Skan Name_Entry *entry; 4504153515Skan 4505153515Skan STAILQ_FOREACH(entry, &obj->names, link) { 4506153515Skan if (strcmp(name, entry->name) == 0) 4507153515Skan return (1); 4508153515Skan } 4509153515Skan return (0); 4510153515Skan} 4511153515Skan 4512153515Skanstatic Obj_Entry * 4513153515Skanlocate_dependency(const Obj_Entry *obj, const char *name) 4514153515Skan{ 4515153515Skan const Objlist_Entry *entry; 4516153515Skan const Needed_Entry *needed; 4517153515Skan 4518153515Skan STAILQ_FOREACH(entry, &list_main, link) { 4519153515Skan if (object_match_name(entry->obj, name)) 4520153515Skan return entry->obj; 4521153515Skan } 4522153515Skan 4523153515Skan for (needed = obj->needed; needed != NULL; needed = needed->next) { 4524218098Skib if (strcmp(obj->strtab + needed->name, name) == 0 || 4525218098Skib (needed->obj != NULL && object_match_name(needed->obj, name))) { 4526218098Skib /* 4527218098Skib * If there is DT_NEEDED for the name we are looking for, 4528218098Skib * we are all set. Note that object might not be found if 4529218098Skib * dependency was not loaded yet, so the function can 4530218098Skib * return NULL here. This is expected and handled 4531218099Skib * properly by the caller. 4532218098Skib */ 4533218098Skib return (needed->obj); 4534218098Skib } 4535153515Skan } 4536209558Snwhitehorn _rtld_error("%s: Unexpected inconsistency: dependency %s not found", 4537209558Snwhitehorn obj->path, name); 4538209558Snwhitehorn die(); 4539153515Skan} 4540153515Skan 4541153515Skanstatic int 4542153515Skancheck_object_provided_version(Obj_Entry *refobj, const Obj_Entry *depobj, 4543153515Skan const Elf_Vernaux *vna) 4544153515Skan{ 4545153515Skan const Elf_Verdef *vd; 4546153515Skan const char *vername; 4547153515Skan 4548153515Skan vername = refobj->strtab + vna->vna_name; 4549153515Skan vd = depobj->verdef; 4550153515Skan if (vd == NULL) { 4551153703Skan _rtld_error("%s: version %s required by %s not defined", 4552153703Skan depobj->path, vername, refobj->path); 4553153515Skan return (-1); 4554153515Skan } 4555153515Skan for (;;) { 4556153515Skan if (vd->vd_version != VER_DEF_CURRENT) { 4557153703Skan _rtld_error("%s: Unsupported version %d of Elf_Verdef entry", 4558153515Skan depobj->path, vd->vd_version); 4559153515Skan return (-1); 4560153515Skan } 4561153515Skan if (vna->vna_hash == vd->vd_hash) { 4562153515Skan const Elf_Verdaux *aux = (const Elf_Verdaux *) 4563153515Skan ((char *)vd + vd->vd_aux); 4564153515Skan if (strcmp(vername, depobj->strtab + aux->vda_name) == 0) 4565153515Skan return (0); 4566153515Skan } 4567153515Skan if (vd->vd_next == 0) 4568153515Skan break; 4569153515Skan vd = (const Elf_Verdef *) ((char *)vd + vd->vd_next); 4570153515Skan } 4571153515Skan if (vna->vna_flags & VER_FLG_WEAK) 4572153515Skan return (0); 4573153703Skan _rtld_error("%s: version %s required by %s not found", 4574153703Skan depobj->path, vername, refobj->path); 4575153515Skan return (-1); 4576153515Skan} 4577153515Skan 4578153515Skanstatic int 4579153515Skanrtld_verify_object_versions(Obj_Entry *obj) 4580153515Skan{ 4581153515Skan const Elf_Verneed *vn; 4582153515Skan const Elf_Verdef *vd; 4583153515Skan const Elf_Verdaux *vda; 4584153515Skan const Elf_Vernaux *vna; 4585153515Skan const Obj_Entry *depobj; 4586153515Skan int maxvernum, vernum; 4587153515Skan 4588233832Skib if (obj->ver_checked) 4589233832Skib return (0); 4590233832Skib obj->ver_checked = true; 4591233832Skib 4592153515Skan maxvernum = 0; 4593153515Skan /* 4594153515Skan * Walk over defined and required version records and figure out 4595153515Skan * max index used by any of them. Do very basic sanity checking 4596153515Skan * while there. 4597153515Skan */ 4598153515Skan vn = obj->verneed; 4599153515Skan while (vn != NULL) { 4600153515Skan if (vn->vn_version != VER_NEED_CURRENT) { 4601153703Skan _rtld_error("%s: Unsupported version %d of Elf_Verneed entry", 4602153515Skan obj->path, vn->vn_version); 4603153515Skan return (-1); 4604153515Skan } 4605153515Skan vna = (const Elf_Vernaux *) ((char *)vn + vn->vn_aux); 4606153515Skan for (;;) { 4607153515Skan vernum = VER_NEED_IDX(vna->vna_other); 4608153515Skan if (vernum > maxvernum) 4609153515Skan maxvernum = vernum; 4610153515Skan if (vna->vna_next == 0) 4611153515Skan break; 4612153515Skan vna = (const Elf_Vernaux *) ((char *)vna + vna->vna_next); 4613153515Skan } 4614153515Skan if (vn->vn_next == 0) 4615153515Skan break; 4616153515Skan vn = (const Elf_Verneed *) ((char *)vn + vn->vn_next); 4617153515Skan } 4618153515Skan 4619153515Skan vd = obj->verdef; 4620153515Skan while (vd != NULL) { 4621153515Skan if (vd->vd_version != VER_DEF_CURRENT) { 4622153703Skan _rtld_error("%s: Unsupported version %d of Elf_Verdef entry", 4623153703Skan obj->path, vd->vd_version); 4624153515Skan return (-1); 4625153515Skan } 4626153515Skan vernum = VER_DEF_IDX(vd->vd_ndx); 4627153515Skan if (vernum > maxvernum) 4628153515Skan maxvernum = vernum; 4629153515Skan if (vd->vd_next == 0) 4630153515Skan break; 4631153515Skan vd = (const Elf_Verdef *) ((char *)vd + vd->vd_next); 4632153515Skan } 4633153515Skan 4634153515Skan if (maxvernum == 0) 4635153515Skan return (0); 4636153515Skan 4637153515Skan /* 4638153515Skan * Store version information in array indexable by version index. 4639153515Skan * Verify that object version requirements are satisfied along the 4640153515Skan * way. 4641153515Skan */ 4642153515Skan obj->vernum = maxvernum + 1; 4643233922Skib obj->vertab = xcalloc(obj->vernum, sizeof(Ver_Entry)); 4644153515Skan 4645153515Skan vd = obj->verdef; 4646153515Skan while (vd != NULL) { 4647153515Skan if ((vd->vd_flags & VER_FLG_BASE) == 0) { 4648153515Skan vernum = VER_DEF_IDX(vd->vd_ndx); 4649153515Skan assert(vernum <= maxvernum); 4650153515Skan vda = (const Elf_Verdaux *)((char *)vd + vd->vd_aux); 4651153515Skan obj->vertab[vernum].hash = vd->vd_hash; 4652153515Skan obj->vertab[vernum].name = obj->strtab + vda->vda_name; 4653153515Skan obj->vertab[vernum].file = NULL; 4654153515Skan obj->vertab[vernum].flags = 0; 4655153515Skan } 4656153515Skan if (vd->vd_next == 0) 4657153515Skan break; 4658153515Skan vd = (const Elf_Verdef *) ((char *)vd + vd->vd_next); 4659153515Skan } 4660153515Skan 4661153515Skan vn = obj->verneed; 4662153515Skan while (vn != NULL) { 4663153515Skan depobj = locate_dependency(obj, obj->strtab + vn->vn_file); 4664218098Skib if (depobj == NULL) 4665218098Skib return (-1); 4666153515Skan vna = (const Elf_Vernaux *) ((char *)vn + vn->vn_aux); 4667153515Skan for (;;) { 4668153515Skan if (check_object_provided_version(obj, depobj, vna)) 4669153515Skan return (-1); 4670153515Skan vernum = VER_NEED_IDX(vna->vna_other); 4671153515Skan assert(vernum <= maxvernum); 4672153515Skan obj->vertab[vernum].hash = vna->vna_hash; 4673153515Skan obj->vertab[vernum].name = obj->strtab + vna->vna_name; 4674153515Skan obj->vertab[vernum].file = obj->strtab + vn->vn_file; 4675153515Skan obj->vertab[vernum].flags = (vna->vna_other & VER_NEED_HIDDEN) ? 4676153515Skan VER_INFO_HIDDEN : 0; 4677153515Skan if (vna->vna_next == 0) 4678153515Skan break; 4679153515Skan vna = (const Elf_Vernaux *) ((char *)vna + vna->vna_next); 4680153515Skan } 4681153515Skan if (vn->vn_next == 0) 4682153515Skan break; 4683153515Skan vn = (const Elf_Verneed *) ((char *)vn + vn->vn_next); 4684153515Skan } 4685153515Skan return 0; 4686153515Skan} 4687153515Skan 4688153515Skanstatic int 4689153515Skanrtld_verify_versions(const Objlist *objlist) 4690153515Skan{ 4691153515Skan Objlist_Entry *entry; 4692153515Skan int rc; 4693153515Skan 4694153515Skan rc = 0; 4695153515Skan STAILQ_FOREACH(entry, objlist, link) { 4696153515Skan /* 4697153515Skan * Skip dummy objects or objects that have their version requirements 4698153515Skan * already checked. 4699153515Skan */ 4700153515Skan if (entry->obj->strtab == NULL || entry->obj->vertab != NULL) 4701153515Skan continue; 4702153515Skan if (rtld_verify_object_versions(entry->obj) == -1) { 4703153515Skan rc = -1; 4704153515Skan if (ld_tracing == NULL) 4705153515Skan break; 4706153515Skan } 4707153515Skan } 4708168479Skan if (rc == 0 || ld_tracing != NULL) 4709168479Skan rc = rtld_verify_object_versions(&obj_rtld); 4710153515Skan return rc; 4711153515Skan} 4712153515Skan 4713153515Skanconst Ver_Entry * 4714153515Skanfetch_ventry(const Obj_Entry *obj, unsigned long symnum) 4715153515Skan{ 4716153515Skan Elf_Versym vernum; 4717153515Skan 4718153515Skan if (obj->vertab) { 4719153515Skan vernum = VER_NDX(obj->versyms[symnum]); 4720153515Skan if (vernum >= obj->vernum) { 4721153515Skan _rtld_error("%s: symbol %s has wrong verneed value %d", 4722153515Skan obj->path, obj->strtab + symnum, vernum); 4723153515Skan } else if (obj->vertab[vernum].hash != 0) { 4724153515Skan return &obj->vertab[vernum]; 4725153515Skan } 4726153515Skan } 4727153515Skan return NULL; 4728153515Skan} 4729211413Skib 4730217153Skibint 4731217153Skib_rtld_get_stack_prot(void) 4732217153Skib{ 4733217153Skib 4734217153Skib return (stack_prot); 4735217153Skib} 4736217153Skib 4737217153Skibstatic void 4738217223Skibmap_stacks_exec(RtldLockState *lockstate) 4739217153Skib{ 4740217153Skib void (*thr_map_stacks_exec)(void); 4741217153Skib 4742217153Skib if ((max_stack_flags & PF_X) == 0 || (stack_prot & PROT_EXEC) != 0) 4743217153Skib return; 4744217153Skib thr_map_stacks_exec = (void (*)(void))(uintptr_t) 4745217223Skib get_program_var_addr("__pthread_map_stacks_exec", lockstate); 4746217153Skib if (thr_map_stacks_exec != NULL) { 4747217153Skib stack_prot |= PROT_EXEC; 4748217153Skib thr_map_stacks_exec(); 4749217153Skib } 4750217153Skib} 4751217153Skib 4752216695Skibvoid 4753216695Skibsymlook_init(SymLook *dst, const char *name) 4754216695Skib{ 4755216695Skib 4756216695Skib bzero(dst, sizeof(*dst)); 4757216695Skib dst->name = name; 4758216695Skib dst->hash = elf_hash(name); 4759235396Skib dst->hash_gnu = gnu_hash(name); 4760216695Skib} 4761216695Skib 4762216695Skibstatic void 4763216695Skibsymlook_init_from_req(SymLook *dst, const SymLook *src) 4764216695Skib{ 4765216695Skib 4766216695Skib dst->name = src->name; 4767216695Skib dst->hash = src->hash; 4768235396Skib dst->hash_gnu = src->hash_gnu; 4769216695Skib dst->ventry = src->ventry; 4770216695Skib dst->flags = src->flags; 4771216695Skib dst->defobj_out = NULL; 4772216695Skib dst->sym_out = NULL; 4773216695Skib dst->lockstate = src->lockstate; 4774216695Skib} 4775216695Skib 4776211706Skib/* 4777211706Skib * Overrides for libc_pic-provided functions. 4778211706Skib */ 4779211706Skib 4780211413Skibint 4781211413Skib__getosreldate(void) 4782211413Skib{ 4783211413Skib size_t len; 4784211413Skib int oid[2]; 4785211413Skib int error, osrel; 4786211413Skib 4787211413Skib if (osreldate != 0) 4788211413Skib return (osreldate); 4789211413Skib 4790211413Skib oid[0] = CTL_KERN; 4791211413Skib oid[1] = KERN_OSRELDATE; 4792211413Skib osrel = 0; 4793211413Skib len = sizeof(osrel); 4794211413Skib error = sysctl(oid, 2, &osrel, &len, NULL, 0); 4795211413Skib if (error == 0 && osrel > 0 && len == sizeof(osrel)) 4796211413Skib osreldate = osrel; 4797211413Skib return (osreldate); 4798211413Skib} 4799211706Skib 4800233986Skibvoid 4801233986Skibexit(int status) 4802233986Skib{ 4803233986Skib 4804233986Skib _exit(status); 4805233986Skib} 4806233986Skib 4807233986Skibvoid (*__cleanup)(void); 4808233986Skibint __isthreaded = 0; 4809233986Skibint _thread_autoinit_dummy_decl = 1; 4810233986Skib 4811211706Skib/* 4812211706Skib * No unresolved symbols for rtld. 4813211706Skib */ 4814211706Skibvoid 4815211706Skib__pthread_cxa_finalize(struct dl_phdr_info *a) 4816211706Skib{ 4817211706Skib} 4818233695Skib 4819233695Skibvoid 4820233695Skib__stack_chk_fail(void) 4821233695Skib{ 4822233695Skib 4823233695Skib _rtld_error("stack overflow detected; terminated"); 4824233695Skib die(); 4825233695Skib} 4826233987Skib__weak_reference(__stack_chk_fail, __stack_chk_fail_local); 4827233695Skib 4828233695Skibvoid 4829233695Skib__chk_fail(void) 4830233695Skib{ 4831233695Skib 4832233695Skib _rtld_error("buffer overflow detected; terminated"); 4833233695Skib die(); 4834233695Skib} 4835233697Skib 4836233697Skibconst char * 4837233697Skibrtld_strerror(int errnum) 4838233697Skib{ 4839233697Skib 4840233697Skib if (errnum < 0 || errnum >= sys_nerr) 4841233697Skib return ("Unknown error"); 4842233697Skib return (sys_errlist[errnum]); 4843233697Skib} 4844