setup.c revision 11827:d7ef53deac3f
1193323Sed/* 2193323Sed * CDDL HEADER START 3193323Sed * 4193323Sed * The contents of this file are subject to the terms of the 5193323Sed * Common Development and Distribution License (the "License"). 6193323Sed * You may not use this file except in compliance with the License. 7193323Sed * 8193323Sed * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9193323Sed * or http://www.opensolaris.org/os/licensing. 10193323Sed * See the License for the specific language governing permissions 11193323Sed * and limitations under the License. 12193323Sed * 13193323Sed * When distributing Covered Code, include this CDDL HEADER in each 14193323Sed * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15193323Sed * If applicable, add the following below this CDDL HEADER, with the 16193323Sed * fields enclosed by brackets "[]" replaced with your own identifying 17193323Sed * information: Portions Copyright [yyyy] [name of copyright owner] 18193323Sed * 19193323Sed * CDDL HEADER END 20193323Sed */ 21193323Sed 22193323Sed/* 23198090Srdivacky * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24193323Sed * Use is subject to license terms. 25193323Sed */ 26193323Sed 27193323Sed/* 28193323Sed * Copyright (c) 1988 AT&T 29193323Sed * All Rights Reserved 30193323Sed */ 31193323Sed 32193323Sed/* 33198090Srdivacky * Run time linker common setup. 34198090Srdivacky * 35198090Srdivacky * Called from _setup to get the process going at startup. 36193323Sed */ 37193323Sed 38193323Sed#include <stdlib.h> 39193323Sed#include <fcntl.h> 40193323Sed#include <stdio.h> 41193323Sed#include <sys/types.h> 42193323Sed#include <sys/stat.h> 43193323Sed#include <sys/mman.h> 44195098Sed#include <string.h> 45193323Sed#include <unistd.h> 46193323Sed#include <dlfcn.h> 47193323Sed#include <sys/sysconfig.h> 48193323Sed#include <sys/auxv.h> 49193323Sed#include <debug.h> 50193323Sed#include <conv.h> 51198090Srdivacky#include "_rtld.h" 52198090Srdivacky#include "_audit.h" 53198090Srdivacky#include "_elf.h" 54193323Sed#include "_a.out.h" 55193323Sed#include "msg.h" 56193323Sed 57193323Sed 58193323Sedextern int _end, _edata, _etext; 59194612Sedextern void _init(void); 60194612Sedextern int _brk_unlocked(void *); 61198090Srdivacky 62198090Srdivacky#ifndef SGS_PRE_UNIFIED_PROCESS 63194612Sed/* needed for _brk_unlocked() */ 64194612Sedvoid *_nd = &_end; 65194612Sed#endif 66194612Sed 67193323Sed/* 68193323Sed * Counters that are incremented every time an object is mapped/unmapped. 69195340Sed * 70195340Sed * Note that exec() will usually map 2 objects before we receive control, 71193323Sed * but this can be 1 if ld.so.1 is executed directly. We count one of these 72193323Sed * here, and add another as necessary in setup(). 73193323Sed */ 74193323Sedu_longlong_t cnt_map = 1; 75193323Sedu_longlong_t cnt_unmap = 0; 76193323Sed 77193323Sed 78193323Sed/* 79198090Srdivacky * Define for the executable's interpreter. 80198090Srdivacky * Usually it is ld.so.1, but for the first release of ICL binaries 81193323Sed * it is libc.so.1. We keep this information so that we don't end 82193323Sed * up mapping libc twice if it is the interpreter. 83195340Sed */ 84199481Srdivackystatic Interp _interp; 85193323Sed 86193323Sed/* 87195340Sed * LD_PRELOAD objects. 88193323Sed */ 89193323Sedstatic int 90193323Sedpreload(const char *str, Rt_map *mlmp, Rt_map **clmp) 91193323Sed{ 92193323Sed Alist *palp = NULL; 93193323Sed char *objs, *ptr, *next; 94193323Sed Word lmflags = lml_main.lm_flags; 95193323Sed int lddstub; 96193323Sed 97193323Sed DBG_CALL(Dbg_util_nl(&lml_main, DBG_NL_STD)); 98193323Sed 99193323Sed if ((objs = strdup(str)) == NULL) 100193323Sed return (0); 101193323Sed 102193323Sed /* 103195098Sed * Determine if we've been called from lddstub. 104195098Sed */ 105195340Sed lddstub = (lmflags & LML_FLG_TRC_ENABLE) && 106195340Sed (FLAGS1(*clmp) & FL1_RT_LDDSTUB); 107195340Sed 108195340Sed ptr = strtok_r(objs, MSG_ORIG(MSG_STR_DELIMIT), &next); 109195340Sed do { 110195340Sed Rt_map *nlmp = NULL; 111195340Sed uint_t flags; 112195340Sed 113195340Sed DBG_CALL(Dbg_file_preload(&lml_main, ptr)); 114195340Sed 115195340Sed /* 116193323Sed * Establish the flags for loading each object. If we're 117193323Sed * called via lddstub, then the first preloaded object is the 118193323Sed * object being inspected by ldd(1). This object should not be 119193323Sed * marked as an interposer, as this object is intended to act 120195340Sed * as the target object of the process. 121195340Sed */ 122195340Sed if (lddstub) 123195340Sed flags = FLG_RT_PRELOAD; 124195340Sed else 125198090Srdivacky flags = (FLG_RT_PRELOAD | FLG_RT_OBJINTPO); 126198090Srdivacky 127195340Sed /* 128198090Srdivacky * If this a secure application, then preload errors are 129198090Srdivacky * reduced to warnings, as the errors are non-fatal. 130198090Srdivacky */ 131198090Srdivacky if (rtld_flags & RT_FL_SECURE) 132198090Srdivacky rtld_flags2 |= RT_FL2_FTL2WARN; 133198090Srdivacky if (expand_paths(*clmp, ptr, &palp, AL_CNT_NEEDED, 134198090Srdivacky PD_FLG_EXTLOAD, 0) != 0) 135198113Srdivacky nlmp = load_one(&lml_main, ALIST_OFF_DATA, palp, *clmp, 136198113Srdivacky MODE(mlmp), flags, 0, NULL); 137198113Srdivacky remove_plist(&palp, 0); 138198113Srdivacky if (rtld_flags & RT_FL_SECURE) 139198113Srdivacky rtld_flags2 &= ~RT_FL2_FTL2WARN; 140198113Srdivacky if (nlmp && (bind_one(*clmp, nlmp, BND_NEEDED) == 0)) 141198113Srdivacky nlmp = NULL; 142198090Srdivacky 143198090Srdivacky if (lddstub && nlmp) { 144198090Srdivacky lddstub = 0; 145198090Srdivacky 146198090Srdivacky /* 147198090Srdivacky * Fabricate a binding between the target shared object 148198090Srdivacky * and lddstub so that the target object isn't called 149198090Srdivacky * out from unused() processing. 150198090Srdivacky */ 151198090Srdivacky if (lmflags & 152195340Sed (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED)) { 153195340Sed if (bind_one(*clmp, nlmp, BND_REFER) == 0) 154195340Sed nlmp = NULL; 155195340Sed } 156195340Sed 157198090Srdivacky /* 158198090Srdivacky * By identifying lddstub as the caller, several 159198090Srdivacky * confusing ldd() diagnostics get suppressed. These 160198090Srdivacky * diagnostics would reveal how the target shared object 161193323Sed * was found from lddstub. Now that the real target is 162193323Sed * loaded, identify the target as the caller so that all 163193323Sed * ldd() diagnostics are enabled for subsequent objects. 164198090Srdivacky */ 165198090Srdivacky if (nlmp) 166198090Srdivacky *clmp = nlmp; 167198090Srdivacky } 168198090Srdivacky 169198090Srdivacky /* 170198090Srdivacky * If no error occurred with loading this object, indicate that 171198090Srdivacky * this link-map list contains an interposer. 172198090Srdivacky */ 173198090Srdivacky if (nlmp == NULL) { 174198090Srdivacky if ((lmflags & LML_FLG_TRC_ENABLE) || 175198090Srdivacky (rtld_flags & RT_FL_SECURE)) 176198090Srdivacky continue; 177198090Srdivacky else 178198090Srdivacky return (0); 179198090Srdivacky } 180198090Srdivacky if (flags & FLG_RT_OBJINTPO) 181198090Srdivacky lml_main.lm_flags |= LML_FLG_INTRPOSE; 182198090Srdivacky 183198090Srdivacky } while ((ptr = strtok_r(NULL, 184198090Srdivacky MSG_ORIG(MSG_STR_DELIMIT), &next)) != NULL); 185198090Srdivacky 186198090Srdivacky free(palp); 187198090Srdivacky free(objs); 188198090Srdivacky return (1); 189193323Sed} 190193323Sed 191193323SedRt_map * 192193323Sedsetup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, 193193323Sed char *_rtldname, ulong_t ld_base, ulong_t interp_base, int fd, Phdr *phdr, 194195340Sed char *execname, char **argv, uid_t uid, uid_t euid, gid_t gid, gid_t egid, 195195340Sed void *aoutdyn, int auxflags, uint_t hwcap_1) 196195340Sed{ 197195340Sed Rt_map *rlmp, *mlmp, *clmp, **tobj = NULL; 198195340Sed Ehdr *ehdr; 199195340Sed rtld_stat_t status; 200195340Sed int features = 0, ldsoexec = 0; 201195340Sed size_t eaddr, esize; 202195340Sed char *str, *argvname; 203195340Sed Word lmflags; 204198090Srdivacky mmapobj_result_t *mpp; 205195340Sed Fdesc fdr = { 0 }, fdm = { 0 }; 206195340Sed Rej_desc rej = { 0 }; 207195340Sed 208195340Sed /* 209195340Sed * Now that ld.so has relocated itself, initialize our own 'environ' so 210195340Sed * as to establish an address suitable for any libc requirements. 211195340Sed */ 212195340Sed _environ = (char **)((ulong_t)auxv - sizeof (char *)); 213195340Sed _init(); 214195340Sed _environ = envp; 215195340Sed 216195340Sed /* 217195340Sed * Establish a base time. Total time diagnostics start from entering 218193323Sed * ld.so.1 here, however the base time is reset each time the ld.so.1 219193323Sed * is re-entered. Note also, there will be a large time associated 220193323Sed * with the first diagnostic from ld.so.1, as bootstrapping ld.so.1 221193323Sed * and establishing the liblddbg infrastructure takes some time. 222193323Sed */ 223193323Sed (void) gettimeofday(&DBG_TOTALTIME, NULL); 224193323Sed DBG_DELTATIME = DBG_TOTALTIME; 225193323Sed 226193323Sed /* 227193323Sed * Determine how ld.so.1 has been executed. 228193323Sed */ 229193323Sed if ((fd == -1) && (phdr == NULL)) { 230193323Sed /* 231193323Sed * If we received neither the AT_EXECFD nor the AT_PHDR aux 232193323Sed * vector, ld.so.1 must have been invoked directly from the 233193323Sed * command line. 234193323Sed */ 235193323Sed ldsoexec = 1; 236193323Sed 237193323Sed /* 238193323Sed * AT_SUN_EXECNAME provides the most precise name, if it is 239193323Sed * available, otherwise fall back to argv[0]. At this time, 240193323Sed * there is no process name. 241193323Sed */ 242193323Sed if (execname) 243193323Sed rtldname = execname; 244193323Sed else if (argv[0]) 245193323Sed rtldname = argv[0]; 246193323Sed else 247193323Sed rtldname = (char *)MSG_INTL(MSG_STR_UNKNOWN); 248193323Sed } else { 249193323Sed /* 250193323Sed * Otherwise, we have a standard process. AT_SUN_EXECNAME 251193323Sed * provides the most precise name, if it is available, 252193323Sed * otherwise fall back to argv[0]. Provided the application 253193323Sed * is already mapped, the process is the application, so 254193323Sed * simplify the application name for use in any diagnostics. 255193323Sed */ 256193323Sed if (execname) 257193323Sed argvname = execname; 258198090Srdivacky else if (argv[0]) 259193323Sed argvname = execname = argv[0]; 260193323Sed else 261193323Sed argvname = execname = (char *)MSG_INTL(MSG_STR_UNKNOWN); 262193323Sed 263193323Sed if (fd == -1) { 264193323Sed if ((str = strrchr(argvname, '/')) != NULL) 265193323Sed procname = ++str; 266193323Sed else 267193323Sed procname = argvname; 268193323Sed } 269193323Sed 270193323Sed /* 271193323Sed * At this point, we don't know the runtime linkers full path 272193323Sed * name. The _rtldname passed to us is the SONAME of the 273193323Sed * runtime linker, which is typically /lib/ld.so.1 no matter 274193323Sed * what the full path is. Use this for now, we'll reset the 275193323Sed * runtime linkers name once the application is analyzed. 276193323Sed */ 277193323Sed if (_rtldname) { 278193323Sed if ((str = strrchr(_rtldname, '/')) != NULL) 279193323Sed rtldname = ++str; 280193323Sed else 281193323Sed rtldname = _rtldname; 282193323Sed } else 283198090Srdivacky rtldname = (char *)MSG_INTL(MSG_STR_UNKNOWN); 284198892Srdivacky 285193323Sed /* exec() brought in two objects for us. Count the second one */ 286193323Sed cnt_map++; 287193323Sed } 288198090Srdivacky 289193323Sed /* 290193323Sed * Initialize any global variables. 291198090Srdivacky */ 292193323Sed at_flags = _flags; 293193323Sed 294193323Sed if ((org_scapset->sc_plat = _platform) != NULL) 295193323Sed org_scapset->sc_platsz = strlen(_platform); 296193323Sed 297193323Sed if (org_scapset->sc_plat == NULL) 298193323Sed platform_name(org_scapset); 299193323Sed if (org_scapset->sc_mach == NULL) 300193323Sed machine_name(org_scapset); 301193323Sed 302193323Sed /* 303198090Srdivacky * If pagesize is unspecified find its value. 304193323Sed */ 305193323Sed if ((syspagsz = _syspagsz) == 0) 306193323Sed syspagsz = _sysconfig(_CONFIG_PAGESIZE); 307193323Sed 308193323Sed /* 309193323Sed * Add the unused portion of the last data page to the free space list. 310193323Sed * The page size must be set before doing this. Here, _end refers to 311193323Sed * the end of the runtime linkers bss. Note that we do not use the 312193323Sed * unused data pages from any included .so's to supplement this free 313193323Sed * space as badly behaved .os's may corrupt this data space, and in so 314193323Sed * doing ruin our data. 315193323Sed */ 316193323Sed eaddr = S_DROUND((size_t)&_end); 317193323Sed esize = eaddr % syspagsz; 318193323Sed if (esize) { 319193323Sed esize = syspagsz - esize; 320198090Srdivacky addfree((void *)eaddr, esize); 321193323Sed } 322193323Sed 323193323Sed /* 324193323Sed * Establish initial link-map list flags, and link-map list alists. 325193323Sed */ 326193323Sed if (alist_append(&lml_main.lm_lists, NULL, sizeof (Lm_cntl), 327193323Sed AL_CNT_LMLISTS) == NULL) 328193323Sed return (0); 329193323Sed lml_main.lm_flags |= LML_FLG_BASELM; 330193323Sed lml_main.lm_lmid = LM_ID_BASE; 331193323Sed lml_main.lm_lmidstr = (char *)MSG_ORIG(MSG_LMID_BASE); 332193323Sed 333193323Sed if (alist_append(&lml_rtld.lm_lists, NULL, sizeof (Lm_cntl), 334193323Sed AL_CNT_LMLISTS) == NULL) 335193323Sed return (0); 336193323Sed lml_rtld.lm_flags |= (LML_FLG_RTLDLM | LML_FLG_NOAUDIT | 337193323Sed LML_FLG_HOLDLOCK); 338193323Sed lml_rtld.lm_lmid = LM_ID_LDSO; 339193323Sed lml_rtld.lm_lmidstr = (char *)MSG_ORIG(MSG_LMID_LDSO); 340193323Sed 341193323Sed /* 342193323Sed * Determine whether we have a secure executable. 343193323Sed */ 344193323Sed security(uid, euid, gid, egid, auxflags); 345193323Sed 346193323Sed /* 347193323Sed * Look for environment strings (allows things like LD_NOAUDIT to be 348193323Sed * established, although debugging isn't enabled until later). 349193323Sed */ 350193323Sed if ((readenv_user((const char **)envp, &(lml_main.lm_flags), 351193323Sed &(lml_main.lm_tflags), (aoutdyn != 0))) == 1) 352193323Sed return (0); 353193323Sed 354193323Sed /* 355193323Sed * Initialize a hardware capability descriptor for use in comparing 356193323Sed * each loaded object. The aux vector must provide AF_SUN_HWCAPVERIFY, 357193323Sed * as prior to this setting any hardware capabilities that were found 358193323Sed * could not be relied upon. Set any alternative system capabilities. 359193323Sed */ 360193323Sed if (auxflags & AF_SUN_HWCAPVERIFY) { 361193323Sed rtld_flags2 |= RT_FL2_HWCAP; 362193323Sed org_scapset->sc_hw_1 = (Xword)hwcap_1; 363193323Sed } 364193323Sed if (cap_alternative() == 0) 365193323Sed return (0); 366193323Sed 367193323Sed /* 368193323Sed * Create a mapping descriptor for ld.so.1. We can determine our 369193323Sed * two segments information from known symbols. 370193323Sed */ 371193323Sed if ((mpp = calloc(2, sizeof (mmapobj_result_t))) == NULL) 372193323Sed return (0); 373193323Sed mpp[0].mr_addr = (caddr_t)M_PTRUNC(ld_base); 374193323Sed mpp[0].mr_msize = (caddr_t)&_etext - mpp[0].mr_addr; 375198090Srdivacky mpp[0].mr_fsize = mpp[0].mr_msize; 376193323Sed mpp[0].mr_prot = (PROT_READ | PROT_EXEC); 377193323Sed 378193323Sed mpp[1].mr_addr = (caddr_t)M_PTRUNC((uintptr_t)&r_debug); 379193323Sed mpp[1].mr_msize = (caddr_t)&_end - mpp[1].mr_addr; 380193323Sed mpp[1].mr_fsize = (caddr_t)&_edata - mpp[1].mr_addr; 381193323Sed mpp[1].mr_prot = (PROT_READ | PROT_WRITE | PROT_EXEC); 382193323Sed 383193323Sed if ((fdr.fd_nname = stravl_insert(_rtldname, 0, 0, 0)) == NULL) 384193323Sed return (0); 385193323Sed if ((rlmp = elf_new_lmp(&lml_rtld, ALIST_OFF_DATA, &fdr, 386198090Srdivacky (Addr)mpp->mr_addr, (size_t)((uintptr_t)eaddr - (uintptr_t)ld_base), 387193323Sed NULL, NULL)) == NULL) 388193323Sed return (0); 389193323Sed 390193323Sed MMAPS(rlmp) = mpp; 391193323Sed MMAPCNT(rlmp) = 2; 392193323Sed PADSTART(rlmp) = (ulong_t)mpp[0].mr_addr; 393193323Sed PADIMLEN(rlmp) = (ulong_t)mpp[0].mr_addr + (ulong_t)mpp[1].mr_addr + 394193323Sed (ulong_t)mpp[1].mr_msize; 395193323Sed 396193323Sed MODE(rlmp) |= (RTLD_LAZY | RTLD_NODELETE | RTLD_GLOBAL | RTLD_WORLD); 397193323Sed FLAGS(rlmp) |= (FLG_RT_ANALYZED | FLG_RT_RELOCED | FLG_RT_INITDONE | 398193323Sed FLG_RT_INITCLCT | FLG_RT_FINICLCT | FLG_RT_MODESET); 399193323Sed 400193323Sed /* 401193323Sed * Initialize the runtime linkers information. 402193323Sed */ 403193323Sed interp = &_interp; 404193323Sed interp->i_name = (char *)rtldname; 405193323Sed interp->i_faddr = (caddr_t)ADDR(rlmp); 406193323Sed ldso_plt_init(rlmp); 407193323Sed 408198090Srdivacky /* 409193323Sed * If ld.so.1 has been invoked directly, process its arguments. 410193323Sed */ 411193323Sed if (ldsoexec) { 412193323Sed /* 413193323Sed * Process any arguments that are specific to ld.so.1, and 414193323Sed * reorganize the process stack to effectively remove ld.so.1 415193323Sed * from it. Reinitialize the environment pointer, as this may 416193323Sed * have been shifted after skipping ld.so.1's arguments. 417193323Sed */ 418193323Sed if (rtld_getopt(argv, &envp, &auxv, &(lml_main.lm_flags), 419193323Sed &(lml_main.lm_tflags), (aoutdyn != 0)) == 1) { 420193323Sed eprintf(&lml_main, ERR_NONE, MSG_INTL(MSG_USG_BADOPT)); 421193323Sed return (0); 422193323Sed } 423193323Sed _environ = envp; 424193323Sed 425193323Sed /* 426193323Sed * Open the object that ld.so.1 is to execute. 427193323Sed */ 428193323Sed argvname = execname = argv[0]; 429193323Sed 430193323Sed if ((fd = open(argvname, O_RDONLY)) == -1) { 431193323Sed int err = errno; 432193323Sed eprintf(&lml_main, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), 433193323Sed argvname, strerror(err)); 434193323Sed return (0); 435193323Sed } 436193323Sed } 437198090Srdivacky 438198090Srdivacky /* 439198090Srdivacky * Map in the file, if exec has not already done so, or if the file 440198090Srdivacky * was passed as an argument to an explicit execution of ld.so.1 from 441198090Srdivacky * the command line. 442198090Srdivacky */ 443193323Sed if (fd != -1) { 444193323Sed /* 445193323Sed * Map the file. Once the object is mapped we no longer need 446193323Sed * the file descriptor. 447193323Sed */ 448193323Sed (void) rtld_fstat(fd, &status); 449193323Sed fdm.fd_ftp = map_obj(&lml_main, &fdm, status.st_size, argvname, 450193323Sed fd, &rej); 451193323Sed (void) close(fd); 452193323Sed 453193323Sed if (fdm.fd_ftp == NULL) { 454193323Sed Conv_reject_desc_buf_t rej_buf; 455193323Sed 456193323Sed eprintf(&lml_main, ERR_FATAL, 457193323Sed MSG_INTL(err_reject[rej.rej_type]), argvname, 458198090Srdivacky conv_reject_desc(&rej, &rej_buf, M_MACH)); 459193323Sed return (0); 460193323Sed } 461193323Sed 462193323Sed /* 463193323Sed * Finish processing the loading of the file. 464193323Sed */ 465193323Sed if ((fdm.fd_nname = stravl_insert(argvname, 0, 0, 0)) == NULL) 466193323Sed return (0); 467193323Sed fdm.fd_dev = status.st_dev; 468193323Sed fdm.fd_ino = status.st_ino; 469193323Sed 470193323Sed if ((mlmp = load_file(&lml_main, ALIST_OFF_DATA, &fdm, 471193323Sed NULL)) == NULL) 472193323Sed return (0); 473193323Sed 474193323Sed /* 475193323Sed * We now have a process name for error diagnostics. 476193323Sed */ 477193323Sed if ((str = strrchr(argvname, '/')) != NULL) 478193323Sed procname = ++str; 479193323Sed else 480193323Sed procname = argvname; 481193323Sed 482193323Sed if (ldsoexec) { 483198090Srdivacky mmapobj_result_t *mpp = MMAPS(mlmp); 484193323Sed uint_t mnum, mapnum = MMAPCNT(mlmp); 485193323Sed void *brkbase = NULL; 486193323Sed 487193323Sed /* 488193323Sed * Since ld.so.1 was the primary executed object - the 489193323Sed * brk() base has not yet been initialized, we need to 490195340Sed * initialize it. For an executable, initialize it to 491195340Sed * the end of the object. For a shared object (ET_DYN) 492199481Srdivacky * initialize it to the first page in memory. 493195340Sed */ 494198090Srdivacky for (mnum = 0; mnum < mapnum; mnum++, mpp++) 495195340Sed brkbase = mpp->mr_addr + mpp->mr_msize; 496195340Sed 497199481Srdivacky if (brkbase == NULL) 498199481Srdivacky brkbase = (void *)syspagsz; 499195340Sed 500195340Sed if (_brk_unlocked(brkbase) == -1) { 501195340Sed int err = errno; 502193323Sed 503198090Srdivacky eprintf(&lml_main, ERR_FATAL, 504193323Sed MSG_INTL(MSG_SYS_BRK), argvname, 505193323Sed strerror(err)); 506193323Sed return (0); 507193323Sed } 508193323Sed } 509193323Sed } else { 510193323Sed /* 511193323Sed * Set up function ptr and arguments according to the type 512193323Sed * of file class the executable is. (Currently only supported 513193323Sed * types are ELF and a.out format.) Then create a link map 514193323Sed * for the executable. 515193323Sed */ 516193323Sed if (aoutdyn) { 517193323Sed#ifdef A_OUT 518193323Sed mmapobj_result_t *mpp; 519198090Srdivacky 520198090Srdivacky /* 521198090Srdivacky * Create a mapping structure sufficient to describe 522198090Srdivacky * a single two segments. The ADDR() of the a.out is 523198090Srdivacky * established as 0, which is required but the AOUT 524193323Sed * relocation code. 525193323Sed */ 526193323Sed if ((mpp = 527193323Sed calloc(sizeof (mmapobj_result_t), 2)) == NULL) 528193323Sed return (0); 529193323Sed 530193323Sed if ((fdm.fd_nname = 531193323Sed stravl_insert(execname, 0, 0, 0)) == NULL) 532193323Sed return (0); 533193323Sed if ((mlmp = aout_new_lmp(&lml_main, ALIST_OFF_DATA, 534193323Sed &fdm, 0, 0, aoutdyn, NULL)) == NULL) 535193323Sed return (0); 536193323Sed 537193323Sed /* 538193323Sed * Establish the true mapping information for the a.out. 539193323Sed */ 540193323Sed if (aout_get_mmap(&lml_main, mpp)) { 541193323Sed free(mpp); 542193323Sed return (0); 543193323Sed } 544193323Sed 545193323Sed MSIZE(mlmp) = 546193323Sed (size_t)(mpp[1].mr_addr + mpp[1].mr_msize) - 547193323Sed S_ALIGN((size_t)mpp[0].mr_addr, syspagsz); 548193323Sed MMAPS(mlmp) = mpp; 549193323Sed MMAPCNT(mlmp) = 2; 550193323Sed PADSTART(mlmp) = (ulong_t)mpp->mr_addr; 551193323Sed PADIMLEN(mlmp) = mpp->mr_msize; 552193323Sed 553193323Sed /* 554193323Sed * Disable any object configuration cache (BCP apps 555193323Sed * bring in sbcp which can benefit from any object 556193323Sed * cache, but both the app and sbcp can't use the same 557193323Sed * objects). 558193323Sed */ 559193323Sed rtld_flags |= RT_FL_NOOBJALT; 560193323Sed 561193323Sed /* 562193323Sed * Make sure no-direct bindings are in effect. 563193323Sed */ 564193323Sed lml_main.lm_tflags |= LML_TFLG_NODIRECT; 565193323Sed#else 566193323Sed eprintf(&lml_main, ERR_FATAL, 567193323Sed MSG_INTL(MSG_ERR_REJ_UNKFILE), argvname); 568193323Sed return (0); 569193323Sed#endif 570193323Sed } else if (phdr) { 571193323Sed Phdr *pptr; 572193323Sed Off i_offset = 0; 573193323Sed Addr base = 0; 574193323Sed ulong_t phsize; 575193323Sed mmapobj_result_t *mpp, *fmpp, *hmpp = NULL; 576193323Sed uint_t mapnum = 0; 577193323Sed int i; 578193323Sed size_t msize; 579193323Sed 580193323Sed /* 581193323Sed * Using the executables phdr address determine the base 582193323Sed * address of the input file. NOTE, this assumes the 583193323Sed * program headers and elf header are part of the same 584193323Sed * mapped segment. Although this has held for many 585193323Sed * years now, it might be more flexible if the kernel 586193323Sed * gave use the ELF headers start address, rather than 587193323Sed * the Program headers. 588193323Sed * 589193323Sed * Determine from the ELF header if we're been called 590193323Sed * from a shared object or dynamic executable. If the 591193323Sed * latter, then any addresses within the object are used 592193323Sed * as is. Addresses within shared objects must be added 593193323Sed * to the process's base address. 594193323Sed */ 595193323Sed ehdr = (Ehdr *)((Addr)phdr - phdr->p_offset); 596193323Sed phsize = ehdr->e_phentsize; 597193323Sed if (ehdr->e_type == ET_DYN) 598193323Sed base = (Addr)ehdr; 599193323Sed 600193323Sed /* 601193323Sed * Allocate a mapping array to retain mapped segment 602193323Sed * information. 603193323Sed */ 604193323Sed if ((fmpp = mpp = calloc(ehdr->e_phnum, 605193323Sed sizeof (mmapobj_result_t))) == NULL) 606193323Sed return (0); 607193323Sed 608193323Sed /* 609193323Sed * Extract the needed information from the segment 610193323Sed * headers. 611193323Sed */ 612193323Sed for (i = 0, pptr = phdr; i < ehdr->e_phnum; i++) { 613193323Sed if (pptr->p_type == PT_INTERP) { 614193323Sed i_offset = pptr->p_offset; 615193323Sed interp->i_faddr = 616193323Sed (caddr_t)interp_base; 617193323Sed } 618193323Sed if ((pptr->p_type == PT_LOAD) && 619193323Sed (pptr->p_filesz || pptr->p_memsz)) { 620193323Sed int perm = (PROT_READ | PROT_EXEC); 621193323Sed size_t off; 622193323Sed 623193323Sed if (i_offset && pptr->p_filesz && 624193323Sed (i_offset >= pptr->p_offset) && 625193323Sed (i_offset <= 626193323Sed (pptr->p_memsz + pptr->p_offset))) { 627193323Sed interp->i_name = (char *) 628193323Sed pptr->p_vaddr + i_offset - 629193323Sed pptr->p_offset + base; 630193323Sed i_offset = 0; 631193323Sed } 632193323Sed 633198090Srdivacky if (pptr->p_flags & PF_W) 634193323Sed perm |= PROT_WRITE; 635193323Sed 636193323Sed /* 637195098Sed * Retain segments mapping info. Round 638195098Sed * each segment to a page boundary, as 639195098Sed * this insures addresses are suitable 640195098Sed * for mprotect() if required. 641195098Sed */ 642195098Sed off = pptr->p_vaddr + base; 643195098Sed if (hmpp == NULL) { 644195098Sed hmpp = mpp; 645195098Sed mpp->mr_addr = (caddr_t)ehdr; 646195098Sed } else 647195098Sed mpp->mr_addr = (caddr_t)off; 648195098Sed 649195098Sed off -= (size_t)(uintptr_t)mpp->mr_addr; 650195098Sed mpp->mr_msize = pptr->p_memsz + off; 651195098Sed mpp->mr_fsize = pptr->p_filesz + off; 652195098Sed mpp->mr_prot = perm; 653195098Sed 654195098Sed mpp++, mapnum++; 655195098Sed } 656195098Sed 657195340Sed pptr = (Phdr *)((ulong_t)pptr + phsize); 658195340Sed } 659195340Sed 660195340Sed mpp--; 661198090Srdivacky msize = (size_t)(mpp->mr_addr + mpp->mr_msize) - 662198090Srdivacky S_ALIGN((size_t)fmpp->mr_addr, syspagsz); 663198090Srdivacky 664198090Srdivacky if ((fdm.fd_nname = 665198090Srdivacky stravl_insert(execname, 0, 0, 0)) == NULL) 666198090Srdivacky return (0); 667198090Srdivacky if ((mlmp = elf_new_lmp(&lml_main, ALIST_OFF_DATA, &fdm, 668198090Srdivacky (Addr)hmpp->mr_addr, msize, NULL, NULL)) == NULL) 669198090Srdivacky return (0); 670198090Srdivacky 671198090Srdivacky MMAPS(mlmp) = fmpp; 672198090Srdivacky MMAPCNT(mlmp) = mapnum; 673198090Srdivacky PADSTART(mlmp) = (ulong_t)fmpp->mr_addr; 674198090Srdivacky PADIMLEN(mlmp) = (ulong_t)fmpp->mr_addr + 675198090Srdivacky (ulong_t)mpp->mr_addr + (ulong_t)mpp->mr_msize; 676198090Srdivacky } 677198090Srdivacky } 678198090Srdivacky 679195340Sed /* 680198090Srdivacky * Establish the interpretors name as that defined within the initial 681198090Srdivacky * object (executable). This provides for ORIGIN processing of ld.so.1 682198090Srdivacky * dependencies. Note, the NAME() of the object remains that which was 683198090Srdivacky * passed to us as the SONAME on execution. 684195340Sed */ 685198090Srdivacky if (ldsoexec == 0) { 686198090Srdivacky size_t len = strlen(interp->i_name); 687198090Srdivacky 688198090Srdivacky if (expand(&interp->i_name, &len, 0, 0, 689195340Sed (PD_TKN_ISALIST | PD_TKN_CAP), rlmp) & PD_TKN_RESOLVED) 690198090Srdivacky fdr.fd_flags |= FLG_FD_RESOLVED; 691198090Srdivacky } 692198090Srdivacky fdr.fd_pname = interp->i_name; 693198090Srdivacky (void) fullpath(rlmp, &fdr); 694195340Sed 695195340Sed /* 696195340Sed * The runtime linker acts as a filtee for various dl*() functions that 697195340Sed * are defined in libc (and libdl). Make sure this standard name for 698195340Sed * the runtime linker is also registered in the FullPathNode AVL tree. 699198090Srdivacky */ 700198090Srdivacky (void) fpavl_insert(&lml_rtld, rlmp, _rtldname, 0); 701198090Srdivacky 702198090Srdivacky /* 703195340Sed * Having established the true runtime linkers name, simplify the name 704195340Sed * for error diagnostics. 705195340Sed */ 706195340Sed if ((str = strrchr(PATHNAME(rlmp), '/')) != NULL) 707198090Srdivacky rtldname = ++str; 708198090Srdivacky else 709195340Sed rtldname = PATHNAME(rlmp); 710198090Srdivacky 711198090Srdivacky /* 712198090Srdivacky * Expand the fullpath name of the application. This typically occurs 713198090Srdivacky * as a part of loading an object, but as the kernel probably mapped 714198090Srdivacky * it in, complete this processing now. 715198090Srdivacky */ 716198090Srdivacky (void) fullpath(mlmp, 0); 717198090Srdivacky 718198090Srdivacky /* 719198090Srdivacky * Some troublesome programs will change the value of argv[0]. Dupping 720195340Sed * the process string protects us, and insures the string is left in 721195340Sed * any core files. 722195340Sed */ 723195340Sed if ((str = (char *)strdup(procname)) == NULL) 724195340Sed return (0); 725195340Sed procname = str; 726195340Sed 727195340Sed#if defined(_ELF64) 728195340Sed /* 729195340Sed * If this is a 64-bit process, determine whether this process has 730195340Sed * restricted the process address space to 32-bits. Any dependencies 731195340Sed * that are restricted to a 32-bit address space can only be loaded if 732195340Sed * the executable has established this requirement. 733195340Sed */ 734195340Sed if (CAPSET(mlmp).sc_sf_1 & SF1_SUNW_ADDR32) 735195340Sed rtld_flags2 |= RT_FL2_ADDR32; 736195340Sed#endif 737195340Sed /* 738198090Srdivacky * Establish any alternative capabilities, and validate this object 739195340Sed * if it defines it's own capabilities information. 740195340Sed */ 741195340Sed if (cap_check_lmp(mlmp, &rej) == 0) { 742195340Sed if (lml_main.lm_flags & LML_FLG_TRC_ENABLE) { 743195340Sed /* LINTED */ 744195340Sed (void) printf(MSG_INTL(ldd_warn[rej.rej_type]), 745195340Sed NAME(mlmp), rej.rej_str); 746195340Sed } else { 747195340Sed /* LINTED */ 748195340Sed eprintf(&lml_main, ERR_FATAL, 749195340Sed MSG_INTL(err_reject[rej.rej_type]), 750195340Sed NAME(mlmp), rej.rej_str); 751195340Sed return (0); 752195340Sed } 753198090Srdivacky } 754198090Srdivacky 755195340Sed FLAGS(mlmp) |= (FLG_RT_ISMAIN | FLG_RT_MODESET); 756195340Sed FLAGS1(mlmp) |= FL1_RT_USED; 757195340Sed 758195340Sed /* 759195340Sed * It's the responsibility of MAIN(crt0) to call it's _init and _fini 760195340Sed * section, therefore null out any INIT/FINI so that this object isn't 761195340Sed * collected during tsort processing. And, if the application has no 762195340Sed * initarray or finiarray we can economize on establishing bindings. 763195340Sed */ 764195340Sed INIT(mlmp) = FINI(mlmp) = NULL; 765195340Sed if ((INITARRAY(mlmp) == NULL) && (FINIARRAY(mlmp) == NULL)) 766195340Sed FLAGS1(mlmp) |= FL1_RT_NOINIFIN; 767195340Sed 768195340Sed /* 769195340Sed * Identify lddstub if necessary. 770195340Sed */ 771195340Sed if (lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) 772195340Sed FLAGS1(mlmp) |= FL1_RT_LDDSTUB; 773195340Sed 774195340Sed /* 775195340Sed * Retain our argument information for use in dlinfo. 776195340Sed */ 777198090Srdivacky argsinfo.dla_argv = argv--; 778198090Srdivacky argsinfo.dla_argc = (long)*argv; 779198090Srdivacky argsinfo.dla_envp = envp; 780198090Srdivacky argsinfo.dla_auxv = auxv; 781198090Srdivacky 782198090Srdivacky (void) enter(0); 783198090Srdivacky 784198090Srdivacky /* 785198090Srdivacky * Add our two main link-maps to the dynlm_list 786198090Srdivacky */ 787198090Srdivacky if (aplist_append(&dynlm_list, &lml_main, AL_CNT_DYNLIST) == NULL) 788195340Sed return (0); 789195340Sed 790195340Sed if (aplist_append(&dynlm_list, &lml_rtld, AL_CNT_DYNLIST) == NULL) 791195340Sed return (0); 792195340Sed 793195340Sed /* 794195340Sed * Reset the link-map counts for both lists. The init count is used to 795195340Sed * track how many objects have pending init sections, this gets incre- 796195340Sed * mented each time an object is relocated. Since ld.so.1 relocates 797195340Sed * itself, it's init count will remain zero. 798195340Sed * The object count is used to track how many objects have pending fini 799195340Sed * sections, as ld.so.1 handles its own fini we can zero its count. 800195340Sed */ 801198090Srdivacky lml_main.lm_obj = 1; 802198090Srdivacky lml_rtld.lm_obj = 0; 803195340Sed 804195340Sed /* 805195340Sed * Initialize debugger information structure. Some parts of this 806195340Sed * structure were initialized statically. 807195340Sed */ 808195340Sed r_debug.rtd_rdebug.r_map = (Link_map *)lml_main.lm_head; 809195340Sed r_debug.rtd_rdebug.r_ldsomap = (Link_map *)lml_rtld.lm_head; 810195340Sed r_debug.rtd_rdebug.r_ldbase = r_debug.rtd_rdebug.r_ldsomap->l_addr; 811195340Sed r_debug.rtd_dynlmlst = &dynlm_list; 812195340Sed 813195340Sed /* 814195340Sed * Determine the dev/inode information for the executable to complete 815195340Sed * load_so() checking for those who might dlopen(a.out). 816198090Srdivacky */ 817198090Srdivacky if (rtld_stat(PATHNAME(mlmp), &status) == 0) { 818195340Sed STDEV(mlmp) = status.st_dev; 819195340Sed STINO(mlmp) = status.st_ino; 820195340Sed } 821195340Sed 822195340Sed /* 823195340Sed * Initialize any configuration information. 824195340Sed */ 825193323Sed if (!(rtld_flags & RT_FL_NOCFG)) { 826193323Sed if ((features = elf_config(mlmp, (aoutdyn != 0))) == -1) 827193323Sed return (0); 828193323Sed 829193323Sed if (cap_alternative() == 0) 830195340Sed return (0); 831195340Sed } 832195340Sed 833195340Sed /* 834195340Sed * Establish the modes of the initial object. These modes are 835193323Sed * propagated to any preloaded objects and explicit shared library 836198090Srdivacky * dependencies. 837195340Sed * 838195340Sed * If we're generating a configuration file using crle(1), remove 839195340Sed * any RTLD_NOW use, as we don't want to trigger any relocation proc- 840195340Sed * essing during crle(1)'s first past (this would just be unnecessary 841195340Sed * overhead). Any filters are explicitly loaded, and thus RTLD_NOW is 842195340Sed * not required to trigger filter loading. 843195340Sed * 844195340Sed * Note, RTLD_NOW may have been established during analysis of the 845195340Sed * application had the application been built -z now. 846195340Sed */ 847195340Sed MODE(mlmp) |= (RTLD_NODELETE | RTLD_GLOBAL | RTLD_WORLD); 848195340Sed 849195340Sed if (rtld_flags & RT_FL_CONFGEN) { 850195340Sed MODE(mlmp) |= RTLD_CONFGEN; 851195340Sed MODE(mlmp) &= ~RTLD_NOW; 852195340Sed rtld_flags2 &= ~RT_FL2_BINDNOW; 853195340Sed } 854195340Sed 855195340Sed if ((MODE(mlmp) & RTLD_NOW) == 0) { 856195340Sed if (rtld_flags2 & RT_FL2_BINDNOW) 857195340Sed MODE(mlmp) |= RTLD_NOW; 858195340Sed else 859195340Sed MODE(mlmp) |= RTLD_LAZY; 860195340Sed } 861195340Sed 862195340Sed /* 863195340Sed * If debugging was requested initialize things now that any cache has 864195340Sed * been established. A user can specify LD_DEBUG=help to discover the 865195340Sed * list of debugging tokens available without running the application. 866195340Sed * However, don't allow this setting from a configuration file. 867195340Sed * 868195340Sed * Note, to prevent recursion issues caused by loading and binding the 869195340Sed * debugging libraries themselves, a local debugging descriptor is 870198090Srdivacky * initialized. Once the debugging setup has completed, this local 871198090Srdivacky * descriptor is copied to the global descriptor which effectively 872195340Sed * enables diagnostic output. 873195340Sed * 874195340Sed * Ignore any debugging request if we're being monitored by a process 875195340Sed * that expects the old getpid() initialization handshake. 876195340Sed */ 877195340Sed if ((rpl_debug || prm_debug) && ((rtld_flags & RT_FL_DEBUGGER) == 0)) { 878195340Sed Dbg_desc _dbg_desc = {0}; 879195340Sed struct timeval total = DBG_TOTALTIME; 880195340Sed struct timeval delta = DBG_DELTATIME; 881195340Sed 882195340Sed if (rpl_debug) { 883198090Srdivacky if (dbg_setup(rpl_debug, &_dbg_desc) == 0) 884195340Sed return (0); 885195340Sed if (_dbg_desc.d_extra & DBG_E_HELP_EXIT) 886195340Sed rtldexit(&lml_main, 0); 887195340Sed } 888195340Sed if (prm_debug) 889195340Sed (void) dbg_setup(prm_debug, &_dbg_desc); 890198090Srdivacky 891195340Sed *dbg_desc = _dbg_desc; 892195340Sed DBG_TOTALTIME = total; 893195340Sed DBG_DELTATIME = delta; 894195340Sed } 895195340Sed 896195340Sed /* 897195340Sed * Now that debugging is enabled generate any diagnostics from any 898195340Sed * previous events. 899195340Sed */ 900195340Sed if (DBG_ENABLED) { 901195340Sed DBG_CALL(Dbg_cap_val(&lml_main, org_scapset, alt_scapset, 902195340Sed M_MACH)); 903195340Sed DBG_CALL(Dbg_file_config_dis(&lml_main, config->c_name, 904195340Sed features)); 905195340Sed 906195340Sed DBG_CALL(Dbg_file_ldso(rlmp, envp, auxv, 907195340Sed LIST(rlmp)->lm_lmidstr, ALIST_OFF_DATA)); 908195340Sed 909195340Sed if (THIS_IS_ELF(mlmp)) { 910195340Sed DBG_CALL(Dbg_file_elf(&lml_main, PATHNAME(mlmp), 911195340Sed ADDR(mlmp), MSIZE(mlmp), LIST(mlmp)->lm_lmidstr, 912195340Sed ALIST_OFF_DATA)); 913195340Sed } else { 914195340Sed DBG_CALL(Dbg_file_aout(&lml_main, PATHNAME(mlmp), 915195340Sed ADDR(mlmp), MSIZE(mlmp), LIST(mlmp)->lm_lmidstr, 916195340Sed ALIST_OFF_DATA)); 917195340Sed } 918198090Srdivacky } 919198090Srdivacky 920195340Sed /* 921195340Sed * Enable auditing. 922195340Sed */ 923195340Sed if (rpl_audit || prm_audit || profile_lib) { 924195340Sed int ndx; 925198090Srdivacky const char *aud[3]; 926198090Srdivacky 927198090Srdivacky aud[0] = rpl_audit; 928198090Srdivacky aud[1] = prm_audit; 929198090Srdivacky aud[2] = profile_lib; 930198090Srdivacky 931198090Srdivacky /* 932198090Srdivacky * Any global auditing (set using LD_AUDIT or LD_PROFILE) that 933198090Srdivacky * can't be established is non-fatal. 934198090Srdivacky */ 935198090Srdivacky if ((auditors = calloc(1, sizeof (Audit_desc))) == NULL) 936198090Srdivacky return (0); 937198090Srdivacky 938198090Srdivacky for (ndx = 0; ndx < 3; ndx++) { 939198090Srdivacky if (aud[ndx]) { 940195340Sed if ((auditors->ad_name = 941198090Srdivacky strdup(aud[ndx])) == NULL) 942198090Srdivacky return (0); 943198090Srdivacky rtld_flags2 |= RT_FL2_FTL2WARN; 944198090Srdivacky (void) audit_setup(mlmp, auditors, 945198090Srdivacky PD_FLG_EXTLOAD, NULL); 946198090Srdivacky rtld_flags2 &= ~RT_FL2_FTL2WARN; 947198090Srdivacky } 948198090Srdivacky } 949198090Srdivacky lml_main.lm_tflags |= auditors->ad_flags; 950198090Srdivacky } 951198090Srdivacky if (AUDITORS(mlmp)) { 952198090Srdivacky /* 953198090Srdivacky * Any object required auditing (set with a DT_DEPAUDIT dynamic 954198090Srdivacky * entry) that can't be established is fatal. 955198090Srdivacky */ 956198090Srdivacky if (FLAGS1(mlmp) & FL1_RT_GLOBAUD) { 957198090Srdivacky /* 958198090Srdivacky * If this object requires global auditing, use the 959198090Srdivacky * local auditing information to set the global 960198090Srdivacky * auditing descriptor. The effect is that a 961198090Srdivacky * DT_DEPAUDIT act as an LD_AUDIT. 962198090Srdivacky */ 963198090Srdivacky if ((auditors == NULL) && ((auditors = calloc(1, 964198090Srdivacky sizeof (Audit_desc))) == NULL)) 965198090Srdivacky return (0); 966198090Srdivacky 967198090Srdivacky auditors->ad_name = AUDITORS(mlmp)->ad_name; 968198090Srdivacky if (audit_setup(mlmp, auditors, 0, NULL) == 0) 969198090Srdivacky return (0); 970198090Srdivacky lml_main.lm_tflags |= auditors->ad_flags; 971198090Srdivacky 972198090Srdivacky /* 973198090Srdivacky * Clear the local auditor information. 974198090Srdivacky */ 975198090Srdivacky free((void *) AUDITORS(mlmp)); 976198090Srdivacky AUDITORS(mlmp) = NULL; 977198090Srdivacky 978198090Srdivacky } else { 979198090Srdivacky /* 980198090Srdivacky * Establish any local auditing. 981198090Srdivacky */ 982198090Srdivacky if (audit_setup(mlmp, AUDITORS(mlmp), 0, NULL) == 0) 983198090Srdivacky return (0); 984198090Srdivacky 985198090Srdivacky AFLAGS(mlmp) |= AUDITORS(mlmp)->ad_flags; 986198090Srdivacky lml_main.lm_flags |= LML_FLG_LOCAUDIT; 987198090Srdivacky } 988198090Srdivacky } 989198090Srdivacky 990198090Srdivacky /* 991198090Srdivacky * Explicitly add the initial object and ld.so.1 to those objects being 992198090Srdivacky * audited. Note, although the ld.so.1 link-map isn't auditable, 993198090Srdivacky * establish a cookie for ld.so.1 as this may be bound to via the 994198090Srdivacky * dl*() family. 995198090Srdivacky */ 996198090Srdivacky if ((lml_main.lm_tflags | AFLAGS(mlmp)) & LML_TFLG_AUD_MASK) { 997198090Srdivacky if (((audit_objopen(mlmp, mlmp) == 0) || 998198090Srdivacky (audit_objopen(mlmp, rlmp) == 0)) && 999198090Srdivacky (AFLAGS(mlmp) & LML_TFLG_AUD_MASK)) 1000198090Srdivacky return (0); 1001198090Srdivacky } 1002198090Srdivacky 1003198090Srdivacky /* 1004198090Srdivacky * Map in any preloadable shared objects. Establish the caller as the 1005198090Srdivacky * head of the main link-map list. In the case of being exercised from 1006198090Srdivacky * lddstub, the caller gets reassigned to the first target shared object 1007198090Srdivacky * so as to provide intuitive diagnostics from ldd(). 1008198090Srdivacky * 1009198090Srdivacky * Note, it is valid to preload a 4.x shared object with a 5.0 1010198090Srdivacky * executable (or visa-versa), as this functionality is required by 1011198090Srdivacky * ldd(1). 1012198090Srdivacky */ 1013199481Srdivacky clmp = mlmp; 1014199481Srdivacky if (rpl_preload && (preload(rpl_preload, mlmp, &clmp) == 0)) 1015198090Srdivacky return (0); 1016198090Srdivacky if (prm_preload && (preload(prm_preload, mlmp, &clmp) == 0)) 1017198090Srdivacky return (0); 1018198090Srdivacky 1019198090Srdivacky /* 1020198090Srdivacky * Load all dependent (needed) objects. 1021198090Srdivacky */ 1022198090Srdivacky if (analyze_lmc(&lml_main, ALIST_OFF_DATA, mlmp, NULL) == NULL) 1023198090Srdivacky return (0); 1024198090Srdivacky 1025198090Srdivacky /* 1026198090Srdivacky * Relocate all the dependencies we've just added. 1027198090Srdivacky * 1028198090Srdivacky * If this process has been established via crle(1), the environment 1029198090Srdivacky * variable LD_CONFGEN will have been set. crle(1) may create this 1030198090Srdivacky * process twice. The first time crle only needs to gather dependency 1031198090Srdivacky * information. The second time, is to dldump() the images. 1032198090Srdivacky * 1033198090Srdivacky * If we're only gathering dependencies, relocation is unnecessary. 1034198090Srdivacky * As crle(1) may be building an arbitrary family of objects, they may 1035198090Srdivacky * not fully relocate either. Hence the relocation phase is not carried 1036198090Srdivacky * out now, but will be called by crle(1) once all objects have been 1037198090Srdivacky * loaded. 1038198090Srdivacky */ 1039199481Srdivacky if ((rtld_flags & RT_FL_CONFGEN) == 0) { 1040198090Srdivacky 1041198090Srdivacky DBG_CALL(Dbg_util_nl(&lml_main, DBG_NL_STD)); 1042199481Srdivacky 1043198090Srdivacky if (relocate_lmc(&lml_main, ALIST_OFF_DATA, mlmp, 1044198090Srdivacky mlmp, NULL) == 0) 1045198090Srdivacky return (0); 1046198090Srdivacky 1047198090Srdivacky /* 1048198090Srdivacky * Inform the debuggers that basic process initialization is 1049198090Srdivacky * complete, and that the state of ld.so.1 (link-map lists, 1050199481Srdivacky * etc.) is stable. This handshake enables the debugger to 1051198090Srdivacky * initialize themselves, and consequently allows the user to 1052198090Srdivacky * set break points in .init code. 1053199481Srdivacky * 1054198090Srdivacky * Most new debuggers use librtld_db to monitor activity events. 1055198090Srdivacky * Older debuggers indicated their presence by setting the 1056198090Srdivacky * DT_DEBUG entry in the dynamic executable (see elf_new_lm()). 1057198090Srdivacky * In this case, getpid() is called so that the debugger can 1058198090Srdivacky * catch the system call. This old mechanism has some 1059198090Srdivacky * restrictions, as getpid() should not be called prior to 1060198090Srdivacky * basic process initialization being completed. This 1061198090Srdivacky * restriction has become increasingly difficult to maintain, 1062198090Srdivacky * as the use of auditors, LD_DEBUG, and the initialization 1063198090Srdivacky * handshake with libc can result in "premature" getpid() 1064198090Srdivacky * calls. The use of this getpid() handshake is expected to 1065198090Srdivacky * disappear at some point in the future, and there is intent 1066198090Srdivacky * to work towards that goal. 1067198090Srdivacky */ 1068198090Srdivacky rd_event(&lml_main, RD_DLACTIVITY, RT_CONSISTENT); 1069198090Srdivacky rd_event(&lml_rtld, RD_DLACTIVITY, RT_CONSISTENT); 1070198090Srdivacky 1071198090Srdivacky if (rtld_flags & RT_FL_DEBUGGER) { 1072198113Srdivacky r_debug.rtd_rdebug.r_flags |= RD_FL_ODBG; 1073198090Srdivacky (void) getpid(); 1074199481Srdivacky } 1075199481Srdivacky } 1076198090Srdivacky 1077198090Srdivacky /* 1078198113Srdivacky * Indicate preinit activity, and call any auditing routines. These 1079198090Srdivacky * routines are called before initializing any threads via libc, or 1080199481Srdivacky * before collecting the complete set of .inits on the primary link-map. 1081199481Srdivacky * Although most libc interfaces are encapsulated in local routines 1082199481Srdivacky * within libc, they have been known to escape (ie. call a .plt). As 1083198090Srdivacky * the appcert auditor uses preinit as a trigger to establish some 1084198090Srdivacky * external interfaces to the main link-maps libc, we need to activate 1085198090Srdivacky * this trigger before exercising any code within libc. Additionally, 1086198090Srdivacky * I wouldn't put it past an auditor to add additional objects to the 1087198090Srdivacky * primary link-map. Hence, we collect .inits after the audit call. 1088198090Srdivacky */ 1089198090Srdivacky rd_event(&lml_main, RD_PREINIT, 0); 1090198090Srdivacky 1091198090Srdivacky if ((lml_main.lm_tflags | AFLAGS(mlmp)) & LML_TFLG_AUD_ACTIVITY) 1092198090Srdivacky audit_activity(mlmp, LA_ACT_CONSISTENT); 1093198090Srdivacky if ((lml_main.lm_tflags | AFLAGS(mlmp)) & LML_TFLG_AUD_PREINIT) 1094198090Srdivacky audit_preinit(mlmp); 1095198113Srdivacky 1096198113Srdivacky /* 1097198113Srdivacky * If we're creating initial configuration information, we're done 1098198113Srdivacky * now that the auditing step has been called. 1099198113Srdivacky */ 1100198113Srdivacky if (rtld_flags & RT_FL_CONFGEN) { 1101198113Srdivacky leave(LIST(mlmp), 0); 1102199481Srdivacky return (mlmp); 1103199481Srdivacky } 1104198113Srdivacky 1105198113Srdivacky /* 1106198113Srdivacky * Sort the .init sections of all objects we've added. If we're 1107198113Srdivacky * tracing we only need to execute this under ldd(1) with the -i or -u 1108198113Srdivacky * options. 1109198113Srdivacky */ 1110198113Srdivacky lmflags = lml_main.lm_flags; 1111198113Srdivacky if (((lmflags & LML_FLG_TRC_ENABLE) == 0) || 1112198113Srdivacky (lmflags & (LML_FLG_TRC_INIT | LML_FLG_TRC_UNREF))) { 1113198113Srdivacky if ((tobj = tsort(mlmp, LIST(mlmp)->lm_init, 1114198113Srdivacky RT_SORT_REV)) == (Rt_map **)S_ERROR) 1115198113Srdivacky return (0); 1116198113Srdivacky } 1117198113Srdivacky 1118198113Srdivacky /* 1119198113Srdivacky * If we are tracing we're done. This is the one legitimate use of a 1120198113Srdivacky * direct call to rtldexit() rather than return, as we don't want to 1121198113Srdivacky * return and jump to the application. 1122198113Srdivacky */ 1123198113Srdivacky if (lmflags & LML_FLG_TRC_ENABLE) { 1124198113Srdivacky unused(&lml_main); 1125198113Srdivacky rtldexit(&lml_main, 0); 1126198113Srdivacky } 1127198113Srdivacky 1128198113Srdivacky /* 1129198113Srdivacky * Check if this instance of the linker should have a primary link 1130199481Srdivacky * map. This flag allows multiple copies of the -same- -version- 1131198113Srdivacky * of the linker (and libc) to run in the same address space. 1132198113Srdivacky * 1133198113Srdivacky * Without this flag we only support one copy of the linker in a 1134198113Srdivacky * process because by default the linker will always try to 1135198113Srdivacky * initialize at one primary link map The copy of libc which is 1136198113Srdivacky * initialized on a primary link map will initialize global TLS 1137199481Srdivacky * data which can be shared with other copies of libc in the 1138198113Srdivacky * process. The problem is that if there is more than one copy 1139198113Srdivacky * of the linker, only one copy should link libc onto a primary 1140198113Srdivacky * link map, otherwise libc will attempt to re-initialize global 1141198113Srdivacky * TLS data. So when a copy of the linker is loaded with this 1142198113Srdivacky * flag set, it will not initialize any primary link maps since 1143198113Srdivacky * presumably another copy of the linker will do this. 1144198113Srdivacky * 1145198113Srdivacky * Note that this flag only allows multiple copies of the -same- 1146198113Srdivacky * -version- of the linker (and libc) to coexist. This approach 1147198113Srdivacky * will not work if we are trying to load different versions of 1148198113Srdivacky * the linker and libc into the same process. The reason for 1149198113Srdivacky * this is that the format of the global TLS data may not be 1150198113Srdivacky * the same for different versions of libc. In this case each 1151198113Srdivacky * different version of libc must have it's own primary link map 1152199481Srdivacky * and be able to maintain it's own TLS data. The only way this 1153198113Srdivacky * can be done is by carefully managing TLS pointers on transitions 1154198113Srdivacky * between code associated with each of the different linkers. 1155198113Srdivacky * Note that this is actually what is done for processes in lx 1156198113Srdivacky * branded zones. Although in the lx branded zone case, the 1157198113Srdivacky * other linker and libc are actually gld and glibc. But the 1158198113Srdivacky * same general TLS management mechanism used by the lx brand 1159198113Srdivacky * would apply to any attempts to run multiple versions of the 1160198113Srdivacky * solaris linker and libc in a single process. 1161198113Srdivacky */ 1162198113Srdivacky if (auxflags & AF_SUN_NOPLM) 1163198113Srdivacky rtld_flags2 |= RT_FL2_NOPLM; 1164198113Srdivacky 1165198113Srdivacky /* 1166198113Srdivacky * Establish any static TLS for this primary link-map. Note, regardless 1167198113Srdivacky * of whether TLS is available, an initial handshake occurs with libc to 1168199481Srdivacky * indicate we're processing the primary link-map. Having identified 1169198113Srdivacky * the primary link-map, initialize threads. 1170198113Srdivacky */ 1171198113Srdivacky if (rt_get_extern(&lml_main, mlmp) == 0) 1172198113Srdivacky return (0); 1173198113Srdivacky 1174199481Srdivacky if ((rtld_flags2 & RT_FL2_NOPLM) == 0) { 1175198113Srdivacky if (tls_statmod(&lml_main, mlmp) == 0) 1176199481Srdivacky return (0); 1177198113Srdivacky rt_thr_init(&lml_main); 1178198113Srdivacky rtld_flags2 |= RT_FL2_PLMSETUP; 1179199481Srdivacky } else { 1180198113Srdivacky rt_thr_init(&lml_main); 1181198113Srdivacky } 1182198113Srdivacky 1183198113Srdivacky rtld_flags |= RT_FL_APPLIC; 1184198113Srdivacky 1185198090Srdivacky /* 1186198090Srdivacky * Fire all dependencies .init sections. Identify any unused 1187198090Srdivacky * dependencies, and leave the runtime linker - effectively calling 1188198090Srdivacky * the dynamic executables entry point. 1189198090Srdivacky */ 1190198090Srdivacky call_array(PREINITARRAY(mlmp), (uint_t)PREINITARRAYSZ(mlmp), mlmp, 1191198090Srdivacky SHT_PREINIT_ARRAY); 1192198090Srdivacky 1193199481Srdivacky if (tobj) 1194199481Srdivacky call_init(tobj, DBG_INIT_SORT); 1195198090Srdivacky 1196198090Srdivacky rd_event(&lml_main, RD_POSTINIT, 0); 1197198090Srdivacky 1198198090Srdivacky unused(&lml_main); 1199198090Srdivacky 1200198090Srdivacky DBG_CALL(Dbg_util_call_main(mlmp)); 1201198090Srdivacky 1202198090Srdivacky rtld_flags |= RT_FL_OPERATION; 1203198090Srdivacky leave(LIST(mlmp), 0); 1204198090Srdivacky 1205198090Srdivacky return (mlmp); 1206198090Srdivacky} 1207198090Srdivacky