Mercurial > illumos > illumos-gate
changeset 6:9049f50e2cc0
6276905 dlinfo gives inconsistent results (relative vs absolute linkname)
PSARC/2005/357 dlinfo(3c) RTLD_DI_ARGSINFO
line wrap: on
line diff
--- a/usr/src/cmd/sgs/include/debug.h Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/include/debug.h Wed Jun 15 08:20:19 2005 -0700 @@ -318,8 +318,8 @@ extern void Dbg_file_hdl_title(int); extern void Dbg_file_lazyload(const char *, const char *, const char *); -extern void Dbg_file_ldso(const char *, ulong_t, ulong_t, ulong_t, - ulong_t); +extern void Dbg_file_ldso(const char *, ulong_t, ulong_t, char **, + auxv_t *); extern void Dbg_file_mode_promote(const char *, int); extern void Dbg_file_needed(const char *, const char *); extern void Dbg_file_nl(void);
--- a/usr/src/cmd/sgs/include/rtld.h Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/include/rtld.h Wed Jun 15 08:20:19 2005 -0700 @@ -254,6 +254,7 @@ Audit_list *lm_alp; /* audit list descripter */ avl_tree_t *lm_fpavl; /* avl tree of objects loaded */ Alist *lm_lists; /* active and pending link-map lists */ + char ***lm_environ; /* pointer to environment array */ Word lm_tflags; /* transferable flags */ int lm_obj; /* total number of objs on link-map */ int lm_init; /* new obj since last init processing */ @@ -278,6 +279,7 @@ Elf32_Addr lm_alp; Elf32_Addr lm_fpavl; Elf32_Addr lm_lists; + Elf32_Addr lm_environ; Elf32_Word lm_tflags; int lm_obj; int lm_init;
--- a/usr/src/cmd/sgs/liblddbg/common/files.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/liblddbg/common/files.c Wed Jun 15 08:20:19 2005 -0700 @@ -27,6 +27,7 @@ #include "_synonyms.h" +#include <sys/auxv.h> #include <string.h> #include <unistd.h> #include <fcntl.h> @@ -130,8 +131,8 @@ } void -Dbg_file_ldso(const char *name, ulong_t dynamic, ulong_t base, ulong_t envp, - ulong_t auxv) +Dbg_file_ldso(const char *name, ulong_t dynamic, ulong_t base, char **envp, + auxv_t *auxv) { if (DBG_NOTCLASS(DBG_FILES)) return;
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Wed Jun 15 08:20:19 2005 -0700 @@ -30,6 +30,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> +#include <sys/auxv.h> #include <gelf.h> #include "debug.h" @@ -99,8 +100,8 @@ void Dbg_file_handle64(Grp_hdl *, Rt_map *, int); void Dbg_file_lazyload(const char *, const char *, const char *); void Dbg_file_lazyload64(const char *, const char *, const char *); -void Dbg_file_ldso(const char *, ulong_t, ulong_t, ulong_t, ulong_t); -void Dbg_file_ldso64(const char *, ulong_t, ulong_t, ulong_t, ulong_t); +void Dbg_file_ldso(const char *, ulong_t, ulong_t, char **, auxv_t *); +void Dbg_file_ldso64(const char *, ulong_t, ulong_t, char **, auxv_t *); void Dbg_file_mode_promote(const char *, int); void Dbg_file_needed(const char *, const char *); void Dbg_file_needed64(const char *, const char *);
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README Wed Jun 15 08:20:19 2005 -0700 @@ -1475,3 +1475,5 @@ -------------------------------------------------------------------------------- 6283601 The usr/src/cmd/sgs/packages/common/copyright contains old information legally problematic +6276905 dlinfo gives inconsistent results (relative vs absolute linkname) (D) + PSARC/2005/357 dlinfo(3c) RTLD_DI_ARGSINFO
--- a/usr/src/cmd/sgs/rtld/amd64/_setup.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/amd64/_setup.c Wed Jun 15 08:20:19 2005 -0700 @@ -220,10 +220,10 @@ /* * Continue with generic startup processing. */ - if ((lmp = setup((unsigned long)_envp, (unsigned long)_auxv, _flags, - _platform, _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, - fd, phdr, _execname, _argv, dz_fd, uid, euid, gid, egid, - NULL, auxflags, hwcap_1)) == NULL) { + if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform, + _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr, + _execname, _argv, dz_fd, uid, euid, gid, egid, NULL, auxflags, + hwcap_1)) == NULL) { rtldexit(&lml_main, 1); }
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h Wed Jun 15 08:20:19 2005 -0700 @@ -410,11 +410,11 @@ extern int dyn_plt_ent_size; /* Size of dynamic plt's */ extern ulong_t at_flags; /* machine specific file flags */ -extern const char *pr_name; /* file name of executing process */ +extern const char *procname; /* file name of executing process */ extern Rtld_db_priv r_debug; /* debugging information */ extern char *lasterr; /* string describing last error */ extern Interp *interp; /* ELF executable interpreter info */ -extern const char *rt_name; /* name of the dynamic linker */ +extern const char *rtldname; /* name of the dynamic linker */ extern List hdl_list[]; /* dlopen() handle list */ extern size_t syspagsz; /* system page size */ extern char *platform; /* platform name */ @@ -478,6 +478,9 @@ extern const char *profile_out; /* profile output file */ extern const char *profile_lib; /* audit library to perform profile */ +extern Dl_argsinfo argsinfo; /* process argument, environment and */ + /* auxv information */ + extern const char *err_strs[]; /* diagnostic error string headers */ extern const char *nosym_str; /* MSG_GEN_NOSYM message cache */ @@ -613,10 +616,11 @@ extern void rtld_db_preinit(void); extern void rtld_db_postinit(void); extern void rtldexit(Lm_list *, int); -extern int rtld_getopt(char **, Word *, Word *, int); +extern int rtld_getopt(char **, char ***, auxv_t **, Word *, + Word *, int); extern void security(uid_t, uid_t, gid_t, gid_t, int); extern void set_environ(Lm_list *); -extern Rt_map *setup(ulong_t, ulong_t, Word, char *, int, char *, +extern Rt_map *setup(char **, auxv_t *, Word, char *, int, char *, Dyn *, ulong_t, ulong_t, int fd, Phdr *, char *, char **, int, uid_t, uid_t, gid_t, gid_t, void *, int, uint_t);
--- a/usr/src/cmd/sgs/rtld/common/a.out.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/a.out.c Wed Jun 15 08:20:19 2005 -0700 @@ -504,20 +504,11 @@ caddr_t addr; /* mmap result temporary */ struct link_dynamic *ld; /* dynamic pointer of object mapped */ size_t size; /* size of object */ - const char *name; /* actual name stored for pathname */ Rt_map *lmp; /* link map created */ int err; struct nlist *nl; /* - * Is object the executable? - */ - if (pname == (char *)0) - name = pr_name; - else - name = pname; - - /* * Map text and allocate enough address space to fit the whole * library. Note that we map enough to catch the first symbol * in the symbol table and thereby avoid an "lseek" & "read" @@ -529,7 +520,7 @@ if ((addr = mmap(0, size, (PROT_READ | PROT_EXEC), MAP_PRIVATE, fd, 0)) == MAP_FAILED) { err = errno; - eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), name, + eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), pname, strerror(err)); return (0); } @@ -558,7 +549,7 @@ (int)exec->a_data, (PROT_READ | PROT_WRITE | PROT_EXEC), (MAP_FIXED | MAP_PRIVATE), fd, (off_t)exec->a_text) == MAP_FAILED) { err = errno; - eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), name, + eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), pname, strerror(err)); return (0); } @@ -601,8 +592,8 @@ Rt_map *lmp; caddr_t offset; - DBG_CALL(Dbg_file_aout((pname ? pname : pr_name), (ulong_t)ld, - (ulong_t)addr, (ulong_t)size)); + DBG_CALL(Dbg_file_aout(pname, (ulong_t)ld, (ulong_t)addr, + (ulong_t)size)); /* * Allocate space for the link-map and private a.out information. Once @@ -637,7 +628,7 @@ /* * Specific settings for a.out format. */ - if (pname == 0) { + if (lml->lm_head == 0) { offset = (caddr_t)MAIN_BASE; FLAGS(lmp) |= FLG_RT_FIXED; } else
--- a/usr/src/cmd/sgs/rtld/common/dlfcns.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c Wed Jun 15 08:20:19 2005 -0700 @@ -1509,9 +1509,8 @@ return ((Lmid_t)lml); } - /* - * Extract information for a dlopen() handle. The valid request are: + * Extract information for a dlopen() handle. */ static int dlinfo_core(void *handle, int request, void *p, Rt_map *clmp) @@ -1604,6 +1603,22 @@ } /* + * Obtain the process arguments, environment and auxv. Note, as the + * environment can be modified by the user (putenv(3c)), reinitialize + * the environment pointer on each request. + */ + if (request == RTLD_DI_ARGSINFO) { + Dl_argsinfo *aip = (Dl_argsinfo *)p; + Lm_list *lml = LIST(lmp); + + *aip = argsinfo; + if (lml->lm_flags & LML_FLG_ENVIRON) + aip->dla_envp = *(lml->lm_environ); + + return (0); + } + + /* * Return Lmid_t of the Link-Map list that the specified object is * loaded on. */ @@ -1708,17 +1723,13 @@ * Basically return the dirname(1) of the objects fullpath. */ if (request == RTLD_DI_ORIGIN) { - char *str; - - if ((str = strrchr(PATHNAME(lmp), '/')) != 0) { - size_t len = str - PATHNAME(lmp); + char *str = (char *)p; - (void) strncpy((char *)p, PATHNAME(lmp), len); - str = (char *)p + len; - } else { - str = (char *)p; - *str++ = '.'; - } + if (DIRSZ(lmp) == 0) + (void) fullpath(lmp, 0); + + (void) strncpy(str, ORIGNAME(lmp), DIRSZ(lmp)); + str += DIRSZ(lmp); *str = '\0'; return (0);
--- a/usr/src/cmd/sgs/rtld/common/elf.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/elf.c Wed Jun 15 08:20:19 2005 -0700 @@ -740,8 +740,7 @@ if (ioctl(pfd, PIOCNMAP, (void *)&num) == -1) { err = errno; - eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_PROC), pr_name, - strerror(err)); + eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_PROC), name, strerror(err)); return (1); } @@ -750,8 +749,7 @@ if (ioctl(pfd, PIOCMAP, (void *)maps) == -1) { err = errno; - eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_PROC), pr_name, - strerror(err)); + eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_PROC), name, strerror(err)); free(maps); return (1); } @@ -2416,7 +2414,7 @@ remove_so(0, lmp); return (0); } - if (NAME(lmp)) { + if (lml_main.lm_head) { if (audit_setup(lmp, AUDITORS(lmp)) == 0) { remove_so(0, lmp); return (0); @@ -2491,21 +2489,12 @@ Rt_map *lmp; /* link map created */ caddr_t paddr; /* start of padded image */ Off plen; /* size of image including padding */ - const char *name; Half etype; int fixed; Mmap *mmaps; uint_t mmapcnt = 0; Xword align = 0; - /* - * Establish the objects name. - */ - if (pname == (char *)0) - name = pr_name; - else - name = pname; - /* LINTED */ ehdr = (Ehdr *)fmap->fm_maddr; @@ -2513,7 +2502,7 @@ * If this a relocatable object then special processing is required. */ if ((etype = ehdr->e_type) == ET_REL) - return (elf_obj_file(lml, lmco, name, fd)); + return (elf_obj_file(lml, lmco, pname, fd)); /* * If this isn't a dynamic executable or shared object we can't process @@ -2524,7 +2513,7 @@ else if (etype == ET_DYN) fixed = 0; else { - eprintf(ERR_ELF, MSG_INTL(MSG_GEN_BADTYPE), name, + eprintf(ERR_ELF, MSG_INTL(MSG_GEN_BADTYPE), pname, conv_etype_str(etype)); return (0); } @@ -2536,7 +2525,7 @@ size = (size_t)((char *)ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)); if (size > fmap->fm_fsize) { - eprintf(ERR_FATAL, MSG_INTL(MSG_GEN_CORTRUNC), name); + eprintf(ERR_FATAL, MSG_INTL(MSG_GEN_CORTRUNC), pname); return (0); } if (size > fmap->fm_msize) { @@ -2544,7 +2533,7 @@ if ((fmap->fm_maddr = mmap(fmap->fm_maddr, size, PROT_READ, fmap->fm_mflags, fd, 0)) == MAP_FAILED) { int err = errno; - eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), name, + eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), pname, strerror(err)); return (0); } @@ -2573,7 +2562,7 @@ /* LINTED argument lph is initialized in first pass */ } else if (pptr->p_vaddr <= lph->p_vaddr) { eprintf(ERR_ELF, MSG_INTL(MSG_GEN_INVPRGHDR), - name); + pname); return (0); } @@ -2611,7 +2600,7 @@ * specified file and memory size. */ if ((fph == 0) || (lmph == 0) || (lfph == 0)) { - eprintf(ERR_ELF, MSG_INTL(MSG_GEN_NOLOADSEG), name); + eprintf(ERR_ELF, MSG_INTL(MSG_GEN_NOLOADSEG), pname); return (0); } @@ -2621,7 +2610,7 @@ * bus errors if we're given a truncated file). */ if (fmap->fm_fsize < ((size_t)lfph->p_offset + lfph->p_filesz)) { - eprintf(ERR_FATAL, MSG_INTL(MSG_GEN_CORTRUNC), name); + eprintf(ERR_FATAL, MSG_INTL(MSG_GEN_CORTRUNC), pname); return (0); } @@ -2636,7 +2625,7 @@ * Determine if an existing mapping is acceptable. */ if (interp && (lml->lm_flags & LML_FLG_BASELM) && - (strcmp(name, interp->i_name) == 0)) { + (strcmp(pname, interp->i_name) == 0)) { /* * If this is the interpreter then it has already been mapped * and we have the address so don't map it again. Note that @@ -2707,7 +2696,7 @@ /* * Map the file. */ - if (!(faddr = elf_map_it(name, memsize, ehdr, fph, lph, + if (!(faddr = elf_map_it(pname, memsize, ehdr, fph, lph, &phdr, &paddr, &plen, fixed, fd, align, mmaps, &mmapcnt))) return (0); }
--- a/usr/src/cmd/sgs/rtld/common/getcwd.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/getcwd.c Wed Jun 15 08:20:19 2005 -0700 @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -224,6 +224,13 @@ /* * Take the given link-map file/pathname and prepend the current working * directory. + * + * When $ORIGIN was first introduced, the expansion of a relative pathname was + * deferred until it was required. However now we insure a full pathname is + * always created - things like the analyzer wish to rely on librtld_db + * returning a full path. The overhead of this is perceived to be low, + * providing the associated libc version of getcwd is available (see 4336878). + * This getcwd() was ported back to Solaris 8.1. */ size_t fullpath(Rt_map *lmp, const char *rpath)
--- a/usr/src/cmd/sgs/rtld/common/globals.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/globals.c Wed Jun 15 08:20:19 2005 -0700 @@ -24,7 +24,7 @@ * All Rights Reserved * * - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -99,8 +99,9 @@ /* * Various other global data. */ -const char *pr_name; -const char *rt_name; /* the run time linkers name */ +const char *procname = (const char *)0; +const char *rtldname = MSG_ORIG(MSG_FIL_RTLD); + char *lasterr = (char *)0; /* string describing last error */ /* cleared by each dlerror() */ Interp *interp = 0; /* ELF interpreter info */ @@ -154,6 +155,9 @@ 0 }; +Dl_argsinfo argsinfo = { 0 }; /* process argument, environment and */ + /* auxv information. */ + /* * Frequently used messages are cached here to reduce _dgettext() overhead and * also provide for resetting should the locale change (see _ld_libc()).
--- a/usr/src/cmd/sgs/rtld/common/rtld.msg Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/rtld.msg Wed Jun 15 08:20:19 2005 -0700 @@ -32,7 +32,7 @@ # Usage error @ MSG_USG_BADOPT "usage: ld.so.1 [-e option,...] \ - <dynamic object> [exec args ...]" + dynamic-object [object args,...]" # Message formatting error. @ MSG_EMG_BUFOVRFLW "ld.so.1: internal: message buffer overflow"
--- a/usr/src/cmd/sgs/rtld/common/setup.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/setup.c Wed Jun 15 08:20:19 2005 -0700 @@ -164,29 +164,109 @@ } Rt_map * -setup(ulong_t envp, ulong_t _auxv, Word _flags, char *_platform, int _syspagsz, - char *_rt_name, Dyn *dyn_ptr, ulong_t ld_base, ulong_t interp_base, int fd, - Phdr *phdr, char *_execname, char **_argv, int dz_fd, uid_t uid, uid_t euid, - gid_t gid, gid_t egid, void *aoutdyn, int auxflags, uint_t hwcap_1) +setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, + char *_rtldname, Dyn *dyn_ptr, ulong_t ld_base, ulong_t interp_base, int fd, + Phdr *phdr, char *execname, char **argv, int dz_fd, uid_t uid, + uid_t euid, gid_t gid, gid_t egid, void *aoutdyn, int auxflags, + uint_t hwcap_1) { Rt_map *rlmp, *mlmp, **tobj = 0; - ulong_t etext; Ehdr *ehdr; struct stat status; - int features = 0, _name, i, ldsoexec = 0; + int features = 0, ldsoexec = 0; size_t eaddr, esize; - char *c; + char *str, *argvname; Mmap *mmaps; /* - * Now that ld.so has relocated itself, initialize any global variables. - * Initialize our own 'environ' so as to establish an address suitable - * for libc's hardware mul/div magic (libc/sparc/crt/hwmuldiv.o). + * Now that ld.so has relocated itself, initialize our own 'environ' so + * as to establish an address suitable for libc's hardware mul/div + * magic (libc/sparc/crt/hwmuldiv.o). + */ + _environ = (char **)((ulong_t)auxv - sizeof (char *)); + _init(); + _environ = envp; + + /* + * Far the most common application execution revolves around appending + * the application name to the users PATH definition, thus a full name + * is passed to exec() which will in turn be returned via + * AT_SUN_EXECNAME. Applications may also be invoked from the current + * working directory, or via a relative name. + * + * Determine whether the kernel has supplied a AT_SUN_EXECNAME aux + * vector. This vector points to the full pathname, on the stack, of + * the object that started the process. If this is null, then + * AT_SUN_EXECNAME isn't supported (if the pathname exceeded the system + * limit (PATH_MAX) the exec would have failed). This flag is used to + * determine whether we can call resolvepath(). + */ + if (execname) + rtld_flags |= RT_FL_EXECNAME; + + /* + * Determine how ld.so.1 has been executed. */ - _environ = (char **)((ulong_t)_auxv - sizeof (char *)); - _init(); - _environ = (char **)envp; + if ((fd == -1) && (phdr == 0)) { + /* + * If we received neither the AT_EXECFD nor the AT_PHDR aux + * vector, ld.so.1 must have been invoked directly from the + * command line. + */ + ldsoexec = 1; + /* + * AT_SUN_EXECNAME provides the most precise name, if it is + * available, otherwise fall back to argv[0]. At this time, + * there is no process name. + */ + if (execname) + rtldname = execname; + else if (argv[0]) + rtldname = argv[0]; + else + rtldname = (char *)MSG_INTL(MSG_STR_UNKNOWN); + } else { + /* + * Otherwise, we have a standard process. AT_SUN_EXECNAME + * provides the most precise name, if it is available, + * otherwise fall back to argv[0]. Provided the application + * is already mapped, the process is the application, so + * simplify the application name for use in any diagnostics. + */ + if (execname) + argvname = execname; + else if (argv[0]) + argvname = execname = argv[0]; + else + argvname = execname = (char *)MSG_INTL(MSG_STR_UNKNOWN); + + if (fd == -1) { + if ((str = strrchr(argvname, '/')) != 0) + procname = ++str; + else + procname = argvname; + } + + /* + * At this point, we don't know the runtime linkers full path + * name. The _rtldname passed to us is the SONAME of the + * runtime linker, which is typically /lib/ld.so.1 no matter + * what the full path is. Use this for now, we'll reset the + * runtime linkers name once the application is analyzed. + */ + if (_rtldname) { + if ((str = strrchr(_rtldname, '/')) != 0) + rtldname = ++str; + else + rtldname = _rtldname; + } else + rtldname = (char *)MSG_INTL(MSG_STR_UNKNOWN); + } + + /* + * Initialize any global variables. + */ at_flags = _flags; if (dz_fd != FD_UNAVAIL) dz_init(dz_fd); @@ -243,7 +323,6 @@ hwcap = (ulong_t)hwcap_1; } #endif - /* * Look for environment strings (allows things like LD_NOAUDIT to be * established, although debugging isn't enabled until later). @@ -268,84 +347,57 @@ mmaps[1].m_perm = (PROT_READ | PROT_WRITE | PROT_EXEC); /* - * Create a link map structure for ld.so. We assign the NAME() after - * link-map creation to avoid fullpath() processing within elf_new_lm(). - * This is carried out later when the true interpretor path (as defined - * within the application) is known. + * Create a link map structure for ld.so.1. */ - if ((rlmp = elf_new_lm(&lml_rtld, 0, 0, dyn_ptr, ld_base, + if ((rlmp = elf_new_lm(&lml_rtld, _rtldname, rtldname, dyn_ptr, ld_base, (ulong_t)&_etext, ALO_DATA, (ulong_t)(eaddr - ld_base), 0, ld_base, (ulong_t)(eaddr - ld_base), mmaps, 2)) == 0) { return (0); } - NAME(rlmp) = _rt_name; + MODE(rlmp) |= (RTLD_LAZY | RTLD_NODELETE | RTLD_GLOBAL | RTLD_WORLD); FLAGS(rlmp) |= (FLG_RT_ANALYZED | FLG_RT_RELOCED | FLG_RT_INITDONE | FLG_RT_INITCLCT | FLG_RT_FINICLCT | FLG_RT_MODESET); + + /* + * Initialize the runtime linkers information. + */ + interp = &_interp; + interp->i_name = NAME(rlmp); + interp->i_faddr = (caddr_t)ADDR(rlmp); ldso_plt_init(rlmp); /* - * If we received neither the AT_EXECFD nor the AT_PHDR aux vector, - * ld.so.1 must have been invoked directly from the command line. In - * this case examine argv to determine what file to execute. + * If ld.so.1 has been invoked directly, process its arguments. */ - if ((fd == -1) && (!phdr)) { + if (ldsoexec) { /* - * Set pr_name now to print error messages if required. It will - * be reset below if an executable is found. + * Process any arguments that are specific to ld.so.1, and + * reorganize the process stack to effectively remove ld.so.1 + * from it. Reinitialize the environment pointer, as this may + * have been shifted after skipping ld.so.1's arguments. */ - rt_name = pr_name = _argv[0]; - if (rtld_getopt(_argv, &(lml_main.lm_flags), - &(lml_main.lm_tflags), (aoutdyn != 0)) == 1) + if (rtld_getopt(argv, &envp, &auxv, &(lml_main.lm_flags), + &(lml_main.lm_tflags), (aoutdyn != 0)) == 1) { + eprintf(ERR_NONE, MSG_INTL(MSG_USG_BADOPT)); return (0); - if ((fd = open(_argv[0], O_RDONLY)) == -1) { + } + _environ = envp; + + /* + * Open the object that ld.so.1 is to execute. + */ + argvname = execname = argv[0]; + + if ((fd = open(argvname, O_RDONLY)) == -1) { int err = errno; - eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), _argv[0], + eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), argvname, strerror(err)); return (0); } - NAME(rlmp) = _execname; - interp = &_interp; - interp->i_name = NAME(rlmp); - interp->i_faddr = (caddr_t)ADDR(rlmp); - ldsoexec = 1; } /* - * Duplicate the runtime linkers name so that it is available in a core - * file. - */ - if ((NAME(rlmp) = strdup(NAME(rlmp))) == 0) - return (0); - - /* - * Get the filename of the rtld for use in any diagnostics (but - * save the full name in the link map for future comparisons) - */ - rt_name = c = NAME(rlmp); - while (*c) { - if (*c++ == '/') - rt_name = c; - } - - /* - * Establish the applications name. Note, if ld.so.1 was executed with - * the application as its argument, argv[0] will now reflect the - * application name. - */ - if (_argv[0]) { - /* - * Some troublesome programs will change the value of argv[0]. - * Dupping this string protects ourselves from such programs. - */ - if ((pr_name = (const char *)strdup(_argv[0])) == 0) - return (0); - } else - pr_name = (const char *)MSG_INTL(MSG_STR_UNKNOWN); - - _name = 0; - - /* * Map in the file, if exec has not already done so. If it has, * simply create a new link map structure for the executable. */ @@ -357,19 +409,27 @@ * Find out what type of object we have. */ (void) fstat(fd, &status); - if ((ftp = are_u_this(&rej, fd, &status, pr_name)) == 0) { + if ((ftp = are_u_this(&rej, fd, &status, argvname)) == 0) { eprintf(ERR_FATAL, MSG_INTL(err_reject[rej.rej_type]), - pr_name, conv_reject_str(&rej)); + argvname, conv_reject_str(&rej)); return (0); } /* * Map in object. */ - mlmp = (ftp->fct_map_so)(&lml_main, ALO_DATA, 0, pr_name, fd); - if (mlmp == 0) + if ((mlmp = (ftp->fct_map_so)(&lml_main, ALO_DATA, execname, + argvname, fd)) == 0) return (0); + /* + * We now have a process name for error diagnostics. + */ + if ((str = strrchr(argvname, '/')) != 0) + procname = ++str; + else + procname = argvname; + if (ldsoexec) { Addr brkbase = 0; @@ -384,6 +444,7 @@ if ((FCT(mlmp) == &elf_fct) && (ehdr->e_type == ET_EXEC)) { + int i; Phdr * _phdr = (Phdr *)((uintptr_t)ADDR(mlmp) + ehdr->e_phoff); @@ -405,13 +466,13 @@ if (_brk_unlocked((void *)brkbase) == -1) { int err = errno; eprintf(ERR_FATAL, MSG_INTL(MSG_SYS_BRK), - pr_name, strerror(err)); + argvname, strerror(err)); } } /* - * Object has now been mmaped in, we no longer - * need the file descriptor. + * The object has now been mmaped, we no longer need the file + * descriptor. */ (void) close(fd); @@ -424,10 +485,9 @@ */ if (aoutdyn) { #ifdef A_OUT - if ((mlmp = aout_new_lm(&lml_main, 0, 0, aoutdyn, 0, 0, - ALO_DATA)) == 0) { + if ((mlmp = aout_new_lm(&lml_main, execname, argvname, + aoutdyn, 0, 0, ALO_DATA)) == 0) return (0); - } /* * Set the memory size. Note, we only know the end of @@ -453,23 +513,21 @@ * Make sure no-direct bindings are in effect. */ lml_main.lm_tflags |= LML_TFLG_NODIRECT; - #else eprintf(ERR_FATAL, MSG_INTL(MSG_ERR_REJ_UNKFILE), - pr_name); + argvname); return (0); #endif } else if (phdr) { Phdr *pptr, *firstptr = 0, *lastptr; - Phdr *tlsphdr = 0; - Phdr *unwindphdr = 0; + Phdr *tlsphdr = 0, *unwindphdr = 0; Dyn *dyn = 0; Cap *cap = 0; - Off i_offset; + Off i_offset = 0; Addr base = 0; - char *name = 0; - ulong_t memsize, phsize, entry; + ulong_t memsize, phsize, entry, etext; uint_t mmapcnt = 0; + int i; /* * Using the executables phdr address determine the base @@ -488,11 +546,8 @@ */ ehdr = (Ehdr *)((Addr)phdr - phdr->p_offset); phsize = ehdr->e_phentsize; - if (ehdr->e_type == ET_DYN) { + if (ehdr->e_type == ET_DYN) base = (Addr)ehdr; - name = (char *)pr_name; - _name = 1; - } /* * Allocate a mapping array to retain mapped segment @@ -507,7 +562,6 @@ */ for (i = 0, pptr = phdr; i < ehdr->e_phnum; i++) { if (pptr->p_type == PT_INTERP) { - interp = &_interp; i_offset = pptr->p_offset; interp->i_faddr = (caddr_t)interp_base; @@ -520,13 +574,14 @@ if (!firstptr) firstptr = pptr; lastptr = pptr; - if (!interp->i_name && pptr->p_filesz && + if (i_offset && pptr->p_filesz && (i_offset >= pptr->p_offset) && (i_offset <= (pptr->p_memsz + pptr->p_offset))) { interp->i_name = (char *) pptr->p_vaddr + i_offset - pptr->p_offset + base; + i_offset = 0; } if ((pptr->p_flags & (PF_R | PF_W)) == PF_R) @@ -571,8 +626,8 @@ if (ehdr->e_type == ET_DYN) entry += (ulong_t)ehdr; - if ((mlmp = elf_new_lm(&lml_main, name, 0, dyn, - (Addr)ehdr, etext, ALO_DATA, memsize, entry, + if ((mlmp = elf_new_lm(&lml_main, execname, argvname, + dyn, (Addr)ehdr, etext, ALO_DATA, memsize, entry, (ulong_t)ehdr, memsize, mmaps, mmapcnt)) == 0) { return (0); } @@ -588,53 +643,47 @@ } /* - * Determine whether the kernel has supplied a AT_SUN_EXECNAME aux - * vector. This vector points to the full pathname, on the stack, of - * the object that started the process. If this is null, then - * AT_SUN_EXECNAME isn't supported (if the pathname exceeded the system - * limit (PATH_MAX) the exec would have failed). + * Establish the interpretors name as that defined within the initial + * object (executable). This provides for ORIGIN processing of ld.so.1 + * dependencies. */ - if (_execname) - rtld_flags |= RT_FL_EXECNAME; + if (ldsoexec == 0) { + size_t len = strlen(interp->i_name); + (void) expand(&interp->i_name, &len, 0, 0, + (PN_TKN_ISALIST | PN_TKN_HWCAP), rlmp); + } + PATHNAME(rlmp) = interp->i_name; + + if (FLAGS1(rlmp) & FL1_RT_RELATIVE) + (void) fullpath(rlmp, 0); + else + ORIGNAME(rlmp) = PATHNAME(rlmp) = NAME(rlmp); /* - * Having mapped the executable in and created its link map, initialize - * the name and flags entries as necessary. - * - * Note that any object that starts the process is identified as `main', - * even shared objects. This assumes that the starting object will call - * .init and .fini from its own crt use (this is a pretty valid - * assumption as the crts also provide the necessary entry point). - * However, newer objects may contain .initarray or .finiarray which - * the runtime linker must execute, and which require bindings to be - * established to main for proper initarray/finiarray ordering. + * Having established the true runtime linkers name, simplify the name + * for error diagnostics. */ - if (_name == 0) { - /* - * If the argv[0] name is a full path, and an AT_SUN_EXECNAME - * exists, and we haven't executed ld.so.1 directly, then use - * this name for diagnostics. Various commands use isaexec(3C) - * to execute their 64-bit counterparts, however, the 64-bit - * application simply obtains its argv[] from the parent, and - * thus will contain the 32-bit application name. - */ - if ((*pr_name == '/') && _execname && (ldsoexec == 0)) - pr_name = _execname; - NAME(mlmp) = (char *)pr_name; - } + if ((str = strrchr(PATHNAME(rlmp), '/')) != 0) + rtldname = ++str; + else + rtldname = PATHNAME(rlmp); /* - * Setup the PATHNAME()/ORIGNAME() for the main primary object and - * for ld.so.1. If we didn't receive a AT_SUN_EXECNAME or it - * was ld.so.1 itself that was executed, then PATHNAME() will be - * based off of argv[0]. Otherwise - the PATHNAME is AT_SUN_EXECNAME. + * Expand the fullpath name of the application. This typically occurs + * as a part of loading an object, but as the kernel probably mapped + * it in, complete this processing now. */ - if ((ldsoexec) || (_execname == 0)) - PATHNAME(mlmp) = NAME(mlmp); - else - PATHNAME(mlmp) = _execname; + if (FLAGS1(mlmp) & FL1_RT_RELATIVE) + (void) fullpath(mlmp, 0); - ORIGNAME(mlmp) = PATHNAME(mlmp); + /* + * Some troublesome programs will change the value of argv[0]. Dupping + * the process string protects us, and insures the string is left in + * any core files. + */ + if ((str = (char *)strdup(procname)) == 0) + return (0); + procname = str; /* * If the kernel has provided hardware capabilities information, and @@ -663,48 +712,19 @@ FLAGS1(mlmp) |= FL1_RT_NOINIFIN; /* - * Establish the interpretors name as that defined within the initial - * object (executable). This provides for ORIGIN processing of ld.so.1 - * dependencies. - */ - if (interp) { - size_t len; - ORIGNAME(rlmp) = interp->i_name; - len = strlen(interp->i_name); - (void) expand(&interp->i_name, &len, 0, 0, - (PN_TKN_ISALIST | PN_TKN_HWCAP), mlmp); - PATHNAME(rlmp) = interp->i_name; - } else { - ORIGNAME(rlmp) = PATHNAME(rlmp) = NAME(rlmp); - } - - /* - * Far the most common application execution revolves around appending - * the application name to the users PATH definition, thus a full name - * is passed to exec() which will in turn be returned via - * AT_SUN_EXECNAME. Applications may also be invoked from the current - * working directory, or via a relative name. - * - * When $ORIGIN was first introduced, the expansion of a relative - * pathname was deferred until it was required. However now we insure - * a full pathname is always created - things like the analyzer wish to - * rely on librtld_db returning a full path. The overhead of this is - * perceived to be low, providing the associated libc version of getcwd - * is available (see 4336878), plus it only affects execing relative - * paths. Here we expand the application and ld.so.1 - see - * elf_new_lm() for the expansion of all other dependencies. - */ - if (FLAGS1(mlmp) & FL1_RT_RELATIVE) - (void) fullpath(mlmp, 0); - if (FLAGS1(rlmp) & FL1_RT_RELATIVE) - (void) fullpath(rlmp, 0); - - /* * Identify lddstub if necessary. */ if (lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) FLAGS1(mlmp) |= FL1_RT_LDDSTUB; + /* + * Retain our argument information for use in dlinfo. + */ + argsinfo.dla_argv = argv--; + argsinfo.dla_argc = (long)*argv; + argsinfo.dla_envp = envp; + argsinfo.dla_auxv = auxv; + (void) enter(); /* @@ -776,15 +796,18 @@ /* * Establish the modes of the initial object. These modes are * propagated to any preloaded objects and explicit shared library - * dependencies. + * dependencies. Note, RTLD_NOW may have been established during + * analysis of the application had it been built -z now. */ MODE(mlmp) |= (RTLD_NODELETE | RTLD_GLOBAL | RTLD_WORLD); if (rtld_flags & RT_FL_CONFGEN) MODE(mlmp) |= RTLD_CONFGEN; - if (rtld_flags2 & RT_FL2_BINDNOW) - MODE(mlmp) |= RTLD_NOW; - else - MODE(mlmp) |= RTLD_LAZY; + if ((MODE(mlmp) & RTLD_NOW) == 0) { + if (rtld_flags2 & RT_FL2_BINDNOW) + MODE(mlmp) |= RTLD_NOW; + else + MODE(mlmp) |= RTLD_LAZY; + } /* * If debugging was requested initialize things now that any cache has @@ -805,8 +828,8 @@ DBG_CALL(Dbg_file_config_dis(config->c_name, features)); if (dbg_mask) { - DBG_CALL(Dbg_file_ldso(rt_name, (ulong_t)DYN(rlmp), - ADDR(rlmp), envp, _auxv)); + DBG_CALL(Dbg_file_ldso(PATHNAME(rlmp), (ulong_t)DYN(rlmp), + ADDR(rlmp), envp, auxv)); if (FCT(mlmp) == &elf_fct) { DBG_CALL(Dbg_file_elf(PATHNAME(mlmp),
--- a/usr/src/cmd/sgs/rtld/common/util.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/common/util.c Wed Jun 15 08:20:19 2005 -0700 @@ -208,7 +208,7 @@ * accordingly. * * While the stack layout is platform specific - it just so happens that x86, - * sparc, & sparcv9 all share the following initial stack layout. + * sparc, sparcv9, and amd64 all share the following initial stack layout. * * !_______________________! high addresses * ! ! @@ -243,44 +243,52 @@ * */ static void -stack_cleanup(char **argv, int rmcnt) +stack_cleanup(char **argv, char ***envp, auxv_t **auxv, int rmcnt) { - int i; + int ndx; long *argc; - char **_argv, **envp, **_envp; - auxv_t *auxv, *_auxv; + char **oargv, **nargv; + char **oenvp, **nenvp; + auxv_t *oauxv, *nauxv; /* - * Slide ARGV[] and update argc. + * Slide ARGV[] and update argc. The argv pointer remains the same, + * however slide the applications arguments over the arguments to + * ld.so.1. */ - _argv = argv; - argv = &argv[rmcnt]; - for (i = 0; argv[i]; i++) { - _argv[i] = argv[i]; - } - _argv[i] = argv[i]; - argc = (long *)((uintptr_t)_argv - sizeof (long *)); + nargv = &argv[0]; + oargv = &argv[rmcnt]; + + for (ndx = 0; oargv[ndx]; ndx++) + nargv[ndx] = oargv[ndx]; + nargv[ndx] = oargv[ndx]; + + argc = (long *)((uintptr_t)argv - sizeof (long *)); *argc -= rmcnt; /* - * Slide ENVP[]. + * Slide ENVP[], and update the environment array pointer. */ - envp = &argv[i + 1]; - _envp = &_argv[i + 1]; - for (i = 0; envp[i]; i++) { - _envp[i] = envp[i]; - } - _envp[i] = envp[i]; + ndx++; + nenvp = &nargv[ndx]; + oenvp = &oargv[ndx]; + *envp = nenvp; + + for (ndx = 0; oenvp[ndx]; ndx++) + nenvp[ndx] = oenvp[ndx]; + nenvp[ndx] = oenvp[ndx]; /* - * Slide AUXV[]. + * Slide AUXV[], and update the aux vector pointer. */ - auxv = (auxv_t *)&envp[i + 1]; - _auxv = (auxv_t *)&_envp[i + 1]; - for (i = 0; auxv[i].a_type != AT_NULL; i++) { - _auxv[i] = auxv[i]; - } - _auxv[i] = auxv[i]; + ndx++; + nauxv = (auxv_t *)&nenvp[ndx]; + oauxv = (auxv_t *)&oenvp[ndx]; + *auxv = nauxv; + + for (ndx = 0; (oauxv[ndx].a_type != AT_NULL); ndx++) + nauxv[ndx] = oauxv[ndx]; + nauxv[ndx] = oauxv[ndx]; } #else /* @@ -290,57 +298,61 @@ #endif /* - * The only command line argument recognized is -e, followed by an rtld - * environment variable. + * The only command line argument recognized is -e, followed by a runtime + * linker environment variable. */ int -rtld_getopt(char **argv, Word *lmflags, Word *lmtflags, int aout) +rtld_getopt(char **argv, char ***envp, auxv_t **auxv, Word *lmflags, + Word *lmtflags, int aout) { - int i, errflg = 0; - - for (i = 1; argv[i]; i++) { + int ndx; + + for (ndx = 1; argv[ndx]; ndx++) { char *str; - if (argv[i][0] != '-') + if (argv[ndx][0] != '-') break; - if (argv[i][1] == '\0') { - i++; + if (argv[ndx][1] == '\0') { + ndx++; break; } - if (argv[i][1] != 'e') { - errflg++; - break; - } - - if (argv[i][2] == '\0') { - i++; - if (argv[i] == NULL) { - errflg++; - break; - } - str = argv[i]; + if (argv[ndx][1] != 'e') + return (1); + + if (argv[ndx][2] == '\0') { + ndx++; + if (argv[ndx] == NULL) + return (1); + str = argv[ndx]; } else - str = &argv[i][2]; - + str = &argv[ndx][2]; + + /* + * If the environment variable starts with LD_, strip the LD_. + * Otherwise, take things as is. + */ + if ((str[0] == 'L') && (str[1] == 'D') && (str[2] == '_') && + (str[3] != '\0')) + str += 3; if (ld_flags_env(str, lmflags, lmtflags, 0, aout) == 1) return (1); } - if (errflg || (argv[i] == 0)) { - eprintf(ERR_FATAL, MSG_INTL(MSG_USG_BADOPT)); + /* + * Make sure an object file has been specified. + */ + if (argv[ndx] == 0) return (1); - } /* * Having gotten the arguments, clean ourselves off of the stack. */ - stack_cleanup(argv, i); + stack_cleanup(argv, envp, auxv, ndx); return (0); } - /* * Compare function for FullpathNode AVL tree. */ @@ -2707,10 +2719,16 @@ if (err_strs[ERR_ELF] == 0) err_strs[ERR_ELF] = MSG_INTL(MSG_ERR_ELF); } - if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR1), - rt_name, pr_name, err_strs[error]) == 0) { - overflow = 1; + if (procname) { + if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR1), + rtldname, procname, err_strs[error]) == 0) + overflow = 1; } else { + if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR2), + rtldname, err_strs[error]) == 0) + overflow = 1; + } + if (overflow == 0) { /* * Remove the terminating '\0'. */ @@ -3302,8 +3320,8 @@ * o after loading a new shared object. We can add shared objects to various * link-maps, and any link-map dependencies requiring getopt() require * their own environ. In addition, lazy loading might bring in the - * supplier of environ (libc) after the link-map has been established and - * other objects are present. + * supplier of environ (libc used to be a lazy loading candidate) after + * the link-map has been established and other objects are present. * * This routine handles all these scenarios, without adding unnecessary overhead * to ld.so.1. @@ -3324,12 +3342,13 @@ sl.sl_flags = LKUP_WEAK; if (sym = LM_LOOKUP_SYM(lml->lm_head)(&sl, &dlmp, &binfo)) { - char ** addr = (char **)sym->st_value; + lml->lm_environ = (char ***)sym->st_value; if (!(FLAGS(dlmp) & FLG_RT_FIXED)) - addr = (char **)((uintptr_t)addr + - (uintptr_t)ADDR(dlmp)); - *addr = (char *)environ; + lml->lm_environ = + (char ***)((uintptr_t)lml->lm_environ + + (uintptr_t)ADDR(dlmp)); + *(lml->lm_environ) = (char **)environ; lml->lm_flags |= LML_FLG_ENVIRON; } }
--- a/usr/src/cmd/sgs/rtld/i386/_setup.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/i386/_setup.c Wed Jun 15 08:20:19 2005 -0700 @@ -237,10 +237,10 @@ /* * Continue with generic startup processing. */ - if ((lmp = setup((unsigned long)_envp, (unsigned long)_auxv, _flags, - _platform, _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, - fd, phdr, _execname, _argv, dz_fd, uid, euid, gid, egid, - NULL, auxflags, hwcap_1)) == NULL) { + if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform, + _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr, + _execname, _argv, dz_fd, uid, euid, gid, egid, NULL, auxflags, + hwcap_1)) == NULL) { rtldexit(&lml_main, 1); }
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c Wed Jun 15 08:20:19 2005 -0700 @@ -1043,7 +1043,7 @@ r_debug.rtd_rdebug.r_ldbase) && !(strcmp(interp->i_name, MSG_ORIG(MSG_PTH_LIBC)))) { - DBG_CALL(Dbg_reloc_run(pr_name, M_REL_SHT_TYPE, 0, + DBG_CALL(Dbg_reloc_run(NAME(lmp), M_REL_SHT_TYPE, 0, DBG_REL_START)); if (_elf_copy_reloc(MSG_ORIG(MSG_SYM_CTYPE), lmp,
--- a/usr/src/cmd/sgs/rtld/sparc/_setup.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/sparc/_setup.c Wed Jun 15 08:20:19 2005 -0700 @@ -232,9 +232,9 @@ /* * Continue with generic startup processing. */ - if ((lmp = setup((unsigned long)_envp, (unsigned long)_auxv, _flags, - _platform, _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, - fd, phdr, _execname, _argv, dz_fd, uid, euid, gid, egid, + if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform, + _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr, + _execname, _argv, dz_fd, uid, euid, gid, egid, #ifdef A_OUT aoutdyn, auxflags, hwcap_1)) == (Rt_map *)0) { #else
--- a/usr/src/cmd/sgs/rtld/sparcv9/_setup.c Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/cmd/sgs/rtld/sparcv9/_setup.c Wed Jun 15 08:20:19 2005 -0700 @@ -228,10 +228,10 @@ /* * Continue with generic startup processing. */ - if ((lmp = setup((unsigned long)_envp, (unsigned long)_auxv, _flags, - _platform, _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, - fd, phdr, _execname, _argv, dz_fd, uid, euid, gid, egid, - NULL, auxflags, hwcap_1)) == NULL) { + if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform, + _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr, + _execname, _argv, dz_fd, uid, euid, gid, egid, NULL, auxflags, + hwcap_1)) == NULL) { rtldexit(&lml_main, 1); }
--- a/usr/src/head/dlfcn.h Tue Jun 14 19:12:41 2005 -0700 +++ b/usr/src/head/dlfcn.h Wed Jun 15 08:20:19 2005 -0700 @@ -35,13 +35,14 @@ #include <sys/feature_tests.h> #include <sys/types.h> +#include <sys/auxv.h> #ifdef __cplusplus extern "C" { #endif /* - * Information structure for libpath dlinfo() and dlamd64getunwind() request. + * Information structures for various dlinfo() requests. */ #if !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) #ifdef __STDC__ @@ -59,13 +60,7 @@ void *dli_saddr; } Dl_info; #endif /* __STDC__ */ -#endif /* !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) */ - -/* - * Information structure for libpath dlinfo() request. - */ -#if !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) typedef struct dl_serpath { char *dls_name; /* library search path name */ uint_t dls_flags; /* path information */ @@ -88,6 +83,13 @@ void *dlui_segend; /* end of segment described */ /* by unwind block */ } Dl_amd64_unwindinfo; + +typedef struct dl_argsinfo { + long dla_argc; /* process argument count */ + char **dla_argv; /* process arguments */ + char **dla_envp; /* process environment variables */ + auxv_t *dla_auxv; /* process auxv vectors */ +} Dl_argsinfo; #endif /* !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) */ @@ -208,7 +210,9 @@ /* internal use only */ #define RTLD_DI_GETSIGNAL 9 /* get termination signal */ #define RTLD_DI_SETSIGNAL 10 /* set termination signal */ -#define RTLD_DI_MAX 10 +#define RTLD_DI_ARGSINFO 11 /* get process arguments */ + /* environment and auxv */ +#define RTLD_DI_MAX 11 #if !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) /*