summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sgs
diff options
context:
space:
mode:
authorAli Bahrami <Ali.Bahrami@Sun.COM>2008-12-17 10:52:43 -0700
committerAli Bahrami <Ali.Bahrami@Sun.COM>2008-12-17 10:52:43 -0700
commitcb511613a15cb3949eadffd67b37d3c665b4ef22 (patch)
treed65325047358aac8eee263be91a00c794caa63f1 /usr/src/cmd/sgs
parent1493b746b3204fb3c94653caa19c30e2c54508c8 (diff)
downloadillumos-joyent-cb511613a15cb3949eadffd67b37d3c665b4ef22.tar.gz
6782597 32-bit ld.so.1 needs to accept objects with large inode number
Diffstat (limited to 'usr/src/cmd/sgs')
-rw-r--r--usr/src/cmd/sgs/include/rtld.h38
-rw-r--r--usr/src/cmd/sgs/ldprof/common/profile.c4
-rw-r--r--usr/src/cmd/sgs/libcrle/common/audit.c11
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README1
-rw-r--r--usr/src/cmd/sgs/rtld/common/_rtld.h33
-rw-r--r--usr/src/cmd/sgs/rtld/common/analyze.c26
-rw-r--r--usr/src/cmd/sgs/rtld/common/cache_a.out.c6
-rw-r--r--usr/src/cmd/sgs/rtld/common/config_elf.c10
-rw-r--r--usr/src/cmd/sgs/rtld/common/debug.c18
-rw-r--r--usr/src/cmd/sgs/rtld/common/dlfcns.c10
-rw-r--r--usr/src/cmd/sgs/rtld/common/getcwd.c14
-rw-r--r--usr/src/cmd/sgs/rtld/common/locale.c6
-rw-r--r--usr/src/cmd/sgs/rtld/common/object.c8
-rw-r--r--usr/src/cmd/sgs/rtld/common/remove.c3
-rw-r--r--usr/src/cmd/sgs/rtld/common/setup.c8
-rw-r--r--usr/src/cmd/sgs/rtld/common/tls.c4
-rw-r--r--usr/src/cmd/sgs/rtld/common/tsort.c12
-rw-r--r--usr/src/cmd/sgs/rtld/common/util.c90
-rw-r--r--usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c4
19 files changed, 210 insertions, 96 deletions
diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h
index c8be8e1e17..8652d12a02 100644
--- a/usr/src/cmd/sgs/include/rtld.h
+++ b/usr/src/cmd/sgs/include/rtld.h
@@ -49,6 +49,17 @@ extern "C" {
/*
+ * We use rtld_ino_t instead of ino_t so that we can get
+ * access to large inode values from 32-bit code.
+ */
+#ifdef _LP64
+typedef ino_t rtld_ino_t;
+#else
+typedef ino64_t rtld_ino_t;
+#endif
+
+
+/*
* Linked list of directories or filenames (built from colon separated string).
*/
typedef struct pnode {
@@ -594,7 +605,7 @@ struct rt_map {
int rt_sortval; /* temporary buffer to traverse graph */
uint_t rt_cycgroup; /* cyclic group */
dev_t rt_stdev; /* device id and inode number for .so */
- ino_t rt_stino; /* multiple inclusion checks */
+ rtld_ino_t rt_stino; /* multiple inclusion checks */
char *rt_origname; /* original pathname of loaded object */
size_t rt_dirsz; /* and its size */
Rt_map_copy rt_copy; /* list of copy relocations */
@@ -797,6 +808,31 @@ typedef struct rt_map32 {
#define REFNAME(X) ((X)->rt_public.l_refname)
/*
+ * An Rt_map starts with a Link_map, followed by other information.
+ * ld.so.1 allocates Rt_map structures, and then casts them to Link_map,
+ * and back, depending on context.
+ *
+ * On some platforms, Rt_map can have a higher alignment requirement
+ * than Link_map. On such platforms, the cast from Link_map to Rt_map will
+ * draw an E_BAD_PTR_CAST_ALIGN warning from lint. Since we allocate
+ * the memory as the higher alignment Rt_map, we know that this is a safe
+ * conversion. The LINKMAP_TO_RTMAP macro is used to handle the conversion
+ * in a manner that satisfies lint.
+ */
+#ifdef lint
+#define LINKMAP_TO_RTMAP(X) (Rt_map *)(void *)(X)
+#else
+#define LINKMAP_TO_RTMAP(X) (Rt_map *)(X)
+#endif
+
+/*
+ * Convenience macros for the common case of using
+ * NEXT()/PREV() and casting the result to (Rt_map *)
+ */
+#define NEXT_RT_MAP(X) LINKMAP_TO_RTMAP(NEXT(X))
+#define PREV_RT_MAP(X) LINKMAP_TO_RTMAP(PREV(X))
+
+/*
* Macros for getting to linker private data.
*/
#define PATHNAME(X) ((X)->rt_pathname)
diff --git a/usr/src/cmd/sgs/ldprof/common/profile.c b/usr/src/cmd/sgs/ldprof/common/profile.c
index 90573a9adb..25c1ff5437 100644
--- a/usr/src/cmd/sgs/ldprof/common/profile.c
+++ b/usr/src/cmd/sgs/ldprof/common/profile.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Routines to provide profiling of shared libraries required by the called
* executable.
@@ -407,7 +405,7 @@ la_objopen(Link_map *lmp, Lmid_t lmid, uintptr_t *cookie)
* Don't even try to profile an object that does not have
* auditing enabled on it's link-map. This catches 'ld.so.1'.
*/
- if (LIST((Rt_map *)lmp)->lm_flags & LML_FLG_NOAUDIT)
+ if (LIST(LINKMAP_TO_RTMAP(lmp))->lm_flags & LML_FLG_NOAUDIT)
return (LA_FLG_BINDFROM);
if (profile_open(pname, lmp) == 0)
diff --git a/usr/src/cmd/sgs/libcrle/common/audit.c b/usr/src/cmd/sgs/libcrle/common/audit.c
index a83753ca9e..d5e94d7679 100644
--- a/usr/src/cmd/sgs/libcrle/common/audit.c
+++ b/usr/src/cmd/sgs/libcrle/common/audit.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,10 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/* LINTLIBRARY */
@@ -117,7 +115,8 @@ la_objopen(Link_map * lmp, Lmid_t lmid, uintptr_t *cookie)
if (auflag == CRLE_AUD_DLDUMP)
return (0);
- if ((lmid == LM_ID_BASE) && !(FLAGS((Rt_map *)lmp) & FLG_RT_ISMAIN)) {
+ if ((lmid == LM_ID_BASE) &&
+ !(FLAGS(LINKMAP_TO_RTMAP(lmp)) & FLG_RT_ISMAIN)) {
char buffer[PATH_MAX];
(void) snprintf(buffer, PATH_MAX, MSG_ORIG(MSG_AUD_DEPEND),
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index 56322d4a86..3968c34260 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1413,3 +1413,4 @@ Bugid Risk Synopsis
6782977 ld segfaults after support lib version error sends bad args to vprintf()
6773695 ld -z nopartial can break non-pic objects
6778453 RTLD_GROUP prevents use of application defined malloc
+6782597 32-bit ld.so.1 needs to accept objects with large inode number
diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h
index 59ed5ab21f..4faacfa1ff 100644
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h
@@ -233,7 +233,7 @@ typedef struct {
const char *fd_nname; /* new file (expanded) name */
const char *fd_pname; /* new path (resolved) name */
dev_t fd_dev; /* file device number */
- ino_t fd_ino; /* file inode number */
+ rtld_ino_t fd_ino; /* file inode number */
int fd_fd; /* open file descriptor */
uint_t fd_flags;
avl_index_t fd_avlwhere; /* avl tree insertion index */
@@ -425,6 +425,31 @@ typedef struct {
/* should be retried */
#define BINFO_MSK_REJECTED 0xff0000 /* a mask of bindings that */
/* have been rejected */
+
+/*
+ * The 32-bit version of rtld uses special stat() wrapper functions
+ * that preserve the non-largefile semantics of stat()/fstat() while
+ * allowing for large inode values. The 64-bit rtld uses stat() directly.
+ */
+#ifdef _LP64
+#define rtld_fstat fstat
+#define rtld_stat stat
+typedef struct stat rtld_stat_t;
+#else
+typedef struct {
+ dev_t st_dev;
+ rtld_ino_t st_ino;
+ mode_t st_mode;
+ uid_t st_uid;
+ off_t st_size;
+ timestruc_t st_mtim;
+#ifdef sparc
+ blksize_t st_blksize;
+#endif
+} rtld_stat_t;
+#endif
+
+
/*
* Data declarations.
*/
@@ -525,7 +550,7 @@ extern void addfree(void *, size_t);
extern int append_alias(Rt_map *, const char *, int *);
extern int analyze_lmc(Lm_list *, Aliste, Rt_map *, int *);
extern Am_ret anon_map(Lm_list *, caddr_t *, size_t, int, int);
-extern Fct *are_u_this(Rej_desc *, int, struct stat *,
+extern Fct *are_u_this(Rej_desc *, int, rtld_stat_t *,
const char *);
extern void atexit_fini(void);
extern int bind_one(Rt_map *, Rt_map *, uint_t);
@@ -652,6 +677,10 @@ extern void rtld_db_dlactivity(Lm_list *);
extern void rtld_db_preinit(Lm_list *);
extern void rtld_db_postinit(Lm_list *);
extern void rtldexit(Lm_list *, int);
+#ifndef _LP64
+extern int rtld_fstat(int, rtld_stat_t *restrict);
+extern int rtld_stat(const char *restrict, rtld_stat_t *restrict);
+#endif
extern int rtld_getopt(char **, char ***, auxv_t **, Word *,
Word *, int);
extern void security(uid_t, uid_t, gid_t, gid_t, int);
diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c
index acae11652e..5849e426ed 100644
--- a/usr/src/cmd/sgs/rtld/common/analyze.c
+++ b/usr/src/cmd/sgs/rtld/common/analyze.c
@@ -128,7 +128,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, int *in_nfavl)
nlmc->lc_flags |= LMC_FLG_ANALYZING;
- for (; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (FLAGS(lmp) &
(FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE))
continue;
@@ -294,7 +294,7 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated, int *in_nfavl)
{
Rt_map *lmp;
- for (lmp = nlmp; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
/*
* If this object has already been relocated, we're done. If
* this object is being deleted, skip it, there's probably a
@@ -639,7 +639,7 @@ rejection_inherit(Rej_desc *rej1, Rej_desc *rej2)
* Determine the object type of a file.
*/
Fct *
-are_u_this(Rej_desc *rej, int fd, struct stat *status, const char *name)
+are_u_this(Rej_desc *rej, int fd, rtld_stat_t *status, const char *name)
{
int i;
char *maddr = 0;
@@ -914,7 +914,7 @@ is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl)
* Loop through the callers link-map lists.
*/
for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
- for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (lmp = lmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE))
continue;
@@ -1128,7 +1128,7 @@ append_alias(Rt_map *lmp, const char *str, int *added)
* values.
*/
static Rt_map *
-is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name,
+is_devinode_loaded(rtld_stat_t *status, Lm_list *lml, const char *name,
uint_t flags)
{
Lm_cntl *lmc;
@@ -1164,7 +1164,7 @@ is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name,
for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
Rt_map *nlmp;
- for (nlmp = lmc->lc_head; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) {
+ for (nlmp = lmc->lc_head; nlmp; nlmp = NEXT_RT_MAP(nlmp)) {
if ((FLAGS(nlmp) & FLG_RT_DELETE) ||
(FLAGS1(nlmp) & FL1_RT_LDDSTUB))
continue;
@@ -1246,7 +1246,7 @@ static int
file_open(int err, Lm_list *lml, const char *oname, const char *nname,
Rt_map *clmp, uint_t flags, Fdesc *fdesc, Rej_desc *rej, int *in_nfavl)
{
- struct stat status;
+ rtld_stat_t status;
Rt_map *nlmp;
int resolved = 0;
char *name;
@@ -1288,7 +1288,7 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname,
}
}
- if ((err == 0) && ((stat(nname, &status)) != -1)) {
+ if ((err == 0) && ((rtld_stat(nname, &status)) != -1)) {
char path[PATH_MAX];
int fd, size, added;
@@ -2679,9 +2679,9 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Sym *osym,
sl = *slp;
if (((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) || (sl.sl_flags & LKUP_COPY))
- lmp = (Rt_map *)NEXT(lmp);
+ lmp = NEXT_RT_MAP(lmp);
- for (; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (FLAGS(lmp) & FLG_RT_DELETE)
continue;
if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0)
@@ -2842,11 +2842,11 @@ core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,
* main link-map control list.
*/
if ((off == ALIST_OFF_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp)
- lmp = (Rt_map *)NEXT(ilmp);
+ lmp = NEXT_RT_MAP(ilmp);
else
lmp = ilmp;
- for (; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) {
Sym *sym;
@@ -2866,7 +2866,7 @@ _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,
{
Rt_map *lmp;
- for (lmp = ilmp; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (lmp = ilmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (LAZY(lmp) == 0)
continue;
if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) {
diff --git a/usr/src/cmd/sgs/rtld/common/cache_a.out.c b/usr/src/cmd/sgs/rtld/common/cache_a.out.c
index f825c3b57d..0afdcdb5e5 100644
--- a/usr/src/cmd/sgs/rtld/common/cache_a.out.c
+++ b/usr/src/cmd/sgs/rtld/common/cache_a.out.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* 4.x ld.so directory caching: run-time link-editor specific functions.
*/
@@ -157,7 +155,7 @@ find_so(const char *ds)
int fd; /* descriptor on directory */
int n; /* bytes from getdents */
char *cp; /* working char * */
- struct stat sb; /* buffer for stat'ing directory */
+ rtld_stat_t sb; /* buffer for stat'ing directory */
struct db *dbp; /* database */
static caddr_t buf = NULL; /* buffer for doing getdents */
static long bs; /* cached blocksize for getdents */
@@ -183,7 +181,7 @@ find_so(const char *ds)
* for the first directory we open successfully.
*/
if (!buf) {
- if (fstat(fd, &sb) == -1) {
+ if (rtld_fstat(fd, &sb) == -1) {
(void) close(fd);
return ((struct db *)NULL);
}
diff --git a/usr/src/cmd/sgs/rtld/common/config_elf.c b/usr/src/cmd/sgs/rtld/common/config_elf.c
index d1dddb63ab..47fbb68b61 100644
--- a/usr/src/cmd/sgs/rtld/common/config_elf.c
+++ b/usr/src/cmd/sgs/rtld/common/config_elf.c
@@ -51,7 +51,7 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp)
Rtc_obj *obj;
Rtc_dir *dirtbl;
Rtc_file *filetbl;
- struct stat status;
+ rtld_stat_t status;
int err;
/*
@@ -128,7 +128,7 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp)
str = strtbl + obj->co_name;
- if (stat(str, &status) != 0) {
+ if (rtld_stat(str, &status) != 0) {
err = errno;
eprintf(lml, ERR_WARNING, MSG_INTL(MSG_CONF_DSTAT),
config->c_name, str, strerror(err));
@@ -154,7 +154,7 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp)
(RTC_OBJ_DUMP | RTC_OBJ_REALPTH))
continue;
- if (stat(str, &status) != 0) {
+ if (rtld_stat(str, &status) != 0) {
err = errno;
eprintf(lml, ERR_WARNING,
MSG_INTL(MSG_CONF_FSTAT), config->c_name,
@@ -197,7 +197,7 @@ elf_config(Rt_map *lmp, int aout)
Rtc_id *id;
Rtc_head *head;
int fd, features = 0;
- struct stat status;
+ rtld_stat_t status;
Addr addr;
Pnode *pnp;
const char *str;
@@ -267,7 +267,7 @@ elf_config(Rt_map *lmp, int aout)
/*
* Determine the configuration file size and map the file.
*/
- (void) fstat(fd, &status);
+ (void) rtld_fstat(fd, &status);
if (status.st_size < sizeof (Rtc_head)) {
(void) close(fd);
return (DBG_CONF_CORRUPT);
diff --git a/usr/src/cmd/sgs/rtld/common/debug.c b/usr/src/cmd/sgs/rtld/common/debug.c
index 2168351095..3d8cff944f 100644
--- a/usr/src/cmd/sgs/rtld/common/debug.c
+++ b/usr/src/cmd/sgs/rtld/common/debug.c
@@ -40,10 +40,10 @@
#include "msg.h"
-static int dbg_fd; /* debugging output file descriptor */
-static dev_t dbg_dev;
-static ino_t dbg_ino;
-static pid_t pid;
+static int dbg_fd; /* debugging output file descriptor */
+static dev_t dbg_dev;
+static rtld_ino_t dbg_ino;
+static pid_t pid;
/*
* Enable diagnostic output. All debugging functions reside in the linker
@@ -53,7 +53,7 @@ uintptr_t
dbg_setup(const char *options, Dbg_desc *dbp)
{
uintptr_t ret;
- struct stat status;
+ rtld_stat_t status;
/*
* If we're running secure, only allow debugging if ld.so.1 itself is
@@ -109,7 +109,7 @@ dbg_setup(const char *options, Dbg_desc *dbp)
* the debugging file descriptor is still available once the
* application has been entered.
*/
- (void) fstat(dbg_fd, &status);
+ (void) rtld_fstat(dbg_fd, &status);
dbg_dev = status.st_dev;
dbg_ino = status.st_ino;
pid = getpid();
@@ -140,7 +140,7 @@ dbg_print(Lm_list *lml, const char *format, ...)
va_list args;
char buffer[ERRSIZE + 1];
pid_t _pid;
- struct stat status;
+ rtld_stat_t status;
Prfbuf prf;
/*
@@ -168,7 +168,7 @@ dbg_print(Lm_list *lml, const char *format, ...)
* same descriptor).
*/
if (rtld_flags & RT_FL_APPLIC) {
- if ((fstat(dbg_fd, &status) == -1) ||
+ if ((rtld_fstat(dbg_fd, &status) == -1) ||
(status.st_dev != dbg_dev) ||
(status.st_ino != dbg_ino)) {
if (dbg_file) {
@@ -185,7 +185,7 @@ dbg_print(Lm_list *lml, const char *format, ...)
dbg_desc->d_class = 0;
return;
}
- (void) fstat(dbg_fd, &status);
+ (void) rtld_fstat(dbg_fd, &status);
dbg_dev = status.st_dev;
dbg_ino = status.st_ino;
} else {
diff --git a/usr/src/cmd/sgs/rtld/common/dlfcns.c b/usr/src/cmd/sgs/rtld/common/dlfcns.c
index 192c653b25..715fe38657 100644
--- a/usr/src/cmd/sgs/rtld/common/dlfcns.c
+++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c
@@ -73,7 +73,7 @@ _caller(caddr_t cpc, int flags)
Rt_map *lmp;
for (lmp = lmc->lc_head; lmp;
- lmp = (Rt_map *)NEXT(lmp)) {
+ lmp = NEXT_RT_MAP(lmp)) {
Mmap *mmap;
/*
@@ -650,7 +650,7 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
if ((mode & (RTLD_NOW | RTLD_CONFGEN)) == RTLD_CONFGEN)
return (ghp);
- for (nlmp = lml->lm_head; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) {
+ for (nlmp = lml->lm_head; nlmp; nlmp = NEXT_RT_MAP(nlmp)) {
if (((MODE(nlmp) & RTLD_GLOBAL) == 0) ||
(FLAGS(nlmp) & FLG_RT_DELETE))
continue;
@@ -1022,7 +1022,7 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo,
* traverse the present link-map list looking for promiscuous
* entries.
*/
- for (nlmp = lmp; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) {
+ for (nlmp = lmp; nlmp; nlmp = NEXT_RT_MAP(nlmp)) {
/*
* If this handle indicates we're only to look in the
@@ -1059,7 +1059,7 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo,
sl.sl_flags |= LKUP_NODESCENT;
- for (nlmp = lmp; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) {
+ for (nlmp = lmp; nlmp; nlmp = NEXT_RT_MAP(nlmp)) {
if (!(MODE(nlmp) & RTLD_GLOBAL) || !LAZY(nlmp))
continue;
@@ -1236,7 +1236,7 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp,
* RTLD_NEXT request so that it will use the callers link map to
* start any possible lazy dependency loading.
*/
- sl.sl_imap = nlmp = (Rt_map *)NEXT(clmp);
+ sl.sl_imap = nlmp = NEXT_RT_MAP(clmp);
DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl,
(nlmp ? NAME(nlmp) : MSG_INTL(MSG_STR_NULL)),
diff --git a/usr/src/cmd/sgs/rtld/common/getcwd.c b/usr/src/cmd/sgs/rtld/common/getcwd.c
index 3f8109fb91..1cbf7bb242 100644
--- a/usr/src/cmd/sgs/rtld/common/getcwd.c
+++ b/usr/src/cmd/sgs/rtld/common/getcwd.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -40,7 +38,7 @@
#ifndef EXPAND_RELATIVE
-static struct stat status;
+static rtld_stat_t status;
/*
* Included here (instead of using libc's) to reduce the number of stat calls.
@@ -54,7 +52,7 @@ _opendir(const char *file)
if ((fd = open(file, (O_RDONLY | O_NDELAY), 0)) < 0)
return (0);
- if ((fstat(fd, &status) < 0) ||
+ if ((rtld_fstat(fd, &status) < 0) ||
((status.st_mode & S_IFMT) != S_IFDIR) ||
((dirp = (DIR *)malloc(sizeof (DIR) + DIRBUF)) == NULL)) {
(void) close(fd);
@@ -115,7 +113,7 @@ getcwd(char *path, size_t pathsz)
{
char _path[PATH_MAX], cwd[PATH_MAX];
size_t cwdsz;
- ino_t cino;
+ rtld_ino_t cino;
dev_t cdev;
_path[--pathsz] = '\0';
@@ -127,7 +125,7 @@ getcwd(char *path, size_t pathsz)
(void) strcpy(cwd, MSG_ORIG(MSG_FMT_CWD));
cwdsz = MSG_FMT_CWD_SIZE;
- if (stat(cwd, &status) == -1)
+ if (rtld_stat(cwd, &status) == -1)
return (NULL);
/* LINTED */
@@ -174,7 +172,7 @@ getcwd(char *path, size_t pathsz)
* The parent director is a different filesystem, so
* determine filenames of subdirectories and stat.
*/
- struct stat _status;
+ rtld_stat_t _status;
cwd[cwdsz] = '/';
@@ -196,7 +194,7 @@ getcwd(char *path, size_t pathsz)
/*
* Silently ignore non-stat'able entries.
*/
- if (stat(cwd, &_status) == -1)
+ if (rtld_stat(cwd, &_status) == -1)
continue;
if ((_status.st_ino == cino) &&
diff --git a/usr/src/cmd/sgs/rtld/common/locale.c b/usr/src/cmd/sgs/rtld/common/locale.c
index 91b4448d44..8c743b01b2 100644
--- a/usr/src/cmd/sgs/rtld/common/locale.c
+++ b/usr/src/cmd/sgs/rtld/common/locale.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Messaging support. To minimize ld.so.1's overhead, messaging support isn't
* enabled until we need to contruct a message - Note that we don't rely on the
@@ -146,7 +144,7 @@ open_mofile(Domain * dom)
const char *domain = dom->dom_name;
char path[PATH_MAX];
int fd;
- struct stat status;
+ rtld_stat_t status;
const Msghdr *msghdr;
int count;
size_t size_tot, size_old, size_new;
@@ -159,7 +157,7 @@ open_mofile(Domain * dom)
if ((fd = open(path, O_RDONLY, 0)) == -1)
return;
- if ((fstat(fd, &status) == -1) ||
+ if ((rtld_fstat(fd, &status) == -1) ||
(status.st_size < sizeof (Msghdr))) {
(void) close(fd);
return;
diff --git a/usr/src/cmd/sgs/rtld/common/object.c b/usr/src/cmd/sgs/rtld/common/object.c
index 163ef2de97..8d1cadd25c 100644
--- a/usr/src/cmd/sgs/rtld/common/object.c
+++ b/usr/src/cmd/sgs/rtld/common/object.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Object file dependent suport for ELF objects.
*/
@@ -230,12 +228,12 @@ elf_obj_fini(Lm_list *lml, Rt_map *lmp, int *in_nfavl)
* the contents rather than manipulate the link map pointers as parts
* of the dlopen code have remembered the original link map address).
*/
- NEXT((Rt_map *)PREV(nlmp)) = 0;
+ NEXT(PREV_RT_MAP(nlmp)) = 0;
/* LINTED */
lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(nlmp));
- lmc->lc_tail = (Rt_map *)PREV(nlmp);
+ lmc->lc_tail = PREV_RT_MAP(nlmp);
if (CNTL(nlmp) == ALIST_OFF_DATA)
- lml->lm_tail = (Rt_map *)PREV(nlmp);
+ lml->lm_tail = PREV_RT_MAP(nlmp);
lml->lm_obj--;
PREV(nlmp) = PREV(olmp);
diff --git a/usr/src/cmd/sgs/rtld/common/remove.c b/usr/src/cmd/sgs/rtld/common/remove.c
index 32d7d22125..b6789e3465 100644
--- a/usr/src/cmd/sgs/rtld/common/remove.c
+++ b/usr/src/cmd/sgs/rtld/common/remove.c
@@ -49,7 +49,6 @@
* link-map. If a failures occurs after a handle have been created,
* remove_hdl() is called to remove the handle and the link-map.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <string.h>
#include <stdio.h>
@@ -530,7 +529,7 @@ remove_incomplete(Lm_list *lml, Aliste lmco)
/*
* First, remove any lists that may point between objects.
*/
- for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp))
+ for (lmp = lmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp))
remove_lists(lmp, 1);
/*
diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c
index 6f38807046..20e8a8ed49 100644
--- a/usr/src/cmd/sgs/rtld/common/setup.c
+++ b/usr/src/cmd/sgs/rtld/common/setup.c
@@ -151,7 +151,7 @@ preload(const char *str, Rt_map *lmp)
if (bind_one(clmp, nlmp, BND_REFER) == 0)
continue;
}
- clmp = (Rt_map *)NEXT(lmp);
+ clmp = NEXT_RT_MAP(lmp);
}
} while ((ptr = strtok_r(NULL,
@@ -170,7 +170,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
{
Rt_map *rlmp, *mlmp, **tobj = 0;
Ehdr *ehdr;
- struct stat status;
+ rtld_stat_t status;
int features = 0, ldsoexec = 0;
size_t eaddr, esize;
char *str, *argvname;
@@ -411,7 +411,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
/*
* Find out what type of object we have.
*/
- (void) fstat(fd, &status);
+ (void) rtld_fstat(fd, &status);
if ((ftp = are_u_this(&rej, fd, &status, argvname)) == 0) {
Conv_reject_desc_buf_t rej_buf;
@@ -799,7 +799,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
* load_so() checking for those who might dlopen(a.out).
*/
if ((FLAGS1(mlmp) & FL1_RT_RELATIVE) &&
- (stat(PATHNAME(mlmp), &status) == 0)) {
+ (rtld_stat(PATHNAME(mlmp), &status) == 0)) {
STDEV(mlmp) = status.st_dev;
STINO(mlmp) = status.st_ino;
}
diff --git a/usr/src/cmd/sgs/rtld/common/tls.c b/usr/src/cmd/sgs/rtld/common/tls.c
index 85b1f84fd8..78f049116a 100644
--- a/usr/src/cmd/sgs/rtld/common/tls.c
+++ b/usr/src/cmd/sgs/rtld/common/tls.c
@@ -23,8 +23,6 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <strings.h>
@@ -306,7 +304,7 @@ tls_statmod(Lm_list *lml, Rt_map *lmp)
* Account for the initial dtv ptr in the TLSSIZE calculation.
*/
tlsmodndx = 0;
- for (lmp = lml->lm_head; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (lmp = lml->lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
if ((FCT(lmp) != &elf_fct) ||
(PTTLS(lmp) == 0) || (PTTLS(lmp)->p_memsz == 0))
continue;
diff --git a/usr/src/cmd/sgs/rtld/common/tsort.c b/usr/src/cmd/sgs/rtld/common/tsort.c
index 7afa6c78d9..87f87cb69d 100644
--- a/usr/src/cmd/sgs/rtld/common/tsort.c
+++ b/usr/src/cmd/sgs/rtld/common/tsort.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Utilities to handle shared object dependency graph.
*
@@ -472,7 +470,7 @@ rb_visit(Rt_map * lmp, Sort * sort)
{
Rt_map * nlmp;
- if ((nlmp = (Rt_map *)NEXT(lmp)) != 0)
+ if ((nlmp = NEXT_RT_MAP(lmp)) != 0)
rb_visit(nlmp, sort);
/*
@@ -510,7 +508,7 @@ fb_visit(Rt_map * lmp, Sort * sort, int flag)
FLAGS(lmp) |= FLG_RT_FINICLCT;
}
}
- lmp = (Rt_map *)NEXT(lmp);
+ lmp = NEXT_RT_MAP(lmp);
}
}
#endif
@@ -827,9 +825,9 @@ tsort(Rt_map *lmp, int num, int flag)
* the next object.
*/
if ((FLAGS(ilmp) & MSK_RT_INTPOSE) == 0)
- ilmp = (Rt_map *)NEXT(ilmp);
+ ilmp = NEXT_RT_MAP(ilmp);
- for (; ilmp; ilmp = (Rt_map *)NEXT(ilmp)) {
+ for (; ilmp; ilmp = NEXT_RT_MAP(ilmp)) {
if ((FLAGS(ilmp) & MSK_RT_INTPOSE) == 0)
break;
@@ -857,7 +855,7 @@ tsort(Rt_map *lmp, int num, int flag)
/*
* Inspect any standard objects.
*/
- for (; _lmp; _lmp = (Rt_map *)NEXT(_lmp)) {
+ for (; _lmp; _lmp = NEXT_RT_MAP(_lmp)) {
if (FLAGS(_lmp) & MSK_RT_INTPOSE)
continue;
diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c
index 727a54fb5d..0927232b37 100644
--- a/usr/src/cmd/sgs/rtld/common/util.c
+++ b/usr/src/cmd/sgs/rtld/common/util.c
@@ -1084,7 +1084,7 @@ load_completion(Rt_map *nlmp)
(rtld_flags2 & (RT_FL2_PLMSETUP | RT_FL2_NOPLM)))) {
Rt_map *lmp;
- for (lmp = nlmp; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (PTTLS(lmp) && PTTLS(lmp)->p_memsz)
tls_modaddrem(lmp, TM_FLG_MODADD);
}
@@ -1265,8 +1265,8 @@ lm_append(Lm_list *lml, Aliste lmco, Rt_map *lmp)
* for now only add interposers after the link-map lists head
* object.
*/
- for (tlmp = (Rt_map *)NEXT(lmc->lc_head); tlmp;
- tlmp = (Rt_map *)NEXT(tlmp)) {
+ for (tlmp = NEXT_RT_MAP(lmc->lc_head); tlmp;
+ tlmp = NEXT_RT_MAP(tlmp)) {
if (FLAGS(tlmp) & FLG_RT_OBJINTPO)
continue;
@@ -1275,7 +1275,7 @@ lm_append(Lm_list *lml, Aliste lmco, Rt_map *lmp)
* Insert the new link-map before this non-interposer,
* and indicate an interposer is found.
*/
- NEXT((Rt_map *)PREV(tlmp)) = (Link_map *)lmp;
+ NEXT(PREV_RT_MAP(tlmp)) = (Link_map *)lmp;
PREV(lmp) = PREV(tlmp);
NEXT(lmp) = (Link_map *)tlmp;
@@ -1350,14 +1350,14 @@ lm_delete(Lm_list *lml, Rt_map *lmp)
lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(lmp));
if (lmc->lc_head == lmp)
- lmc->lc_head = (Rt_map *)NEXT(lmp);
+ lmc->lc_head = NEXT_RT_MAP(lmp);
else
- NEXT((Rt_map *)PREV(lmp)) = (void *)NEXT(lmp);
+ NEXT(PREV_RT_MAP(lmp)) = (void *)NEXT(lmp);
if (lmc->lc_tail == lmp)
- lmc->lc_tail = (Rt_map *)PREV(lmp);
+ lmc->lc_tail = PREV_RT_MAP(lmp);
else
- PREV((Rt_map *)NEXT(lmp)) = PREV(lmp);
+ PREV(NEXT_RT_MAP(lmp)) = PREV(lmp);
/*
* For backward compatibility with debuggers, the link-map list contains
@@ -1401,7 +1401,7 @@ lm_move(Lm_list *lml, Aliste nlmco, Aliste plmco, Lm_cntl *nlmc, Lm_cntl *plmc)
* Indicate each new link-map has been moved to the previous link-map
* control list.
*/
- for (lmp = nlmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp))
+ for (lmp = nlmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp))
CNTL(lmp) = plmco;
/*
@@ -3337,7 +3337,7 @@ unused(Lm_list *lml)
* is always used.
*/
nl = 0;
- for (lmp = (Rt_map *)NEXT(lmp); lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (lmp = NEXT_RT_MAP(lmp); lmp; lmp = NEXT_RT_MAP(lmp)) {
/*
* Determine if this object contains any runpaths that have
* not been used.
@@ -3711,10 +3711,10 @@ security(uid_t uid, uid_t euid, gid_t gid, gid_t egid, int auxflags)
int
is_rtld_setuid()
{
- struct stat status;
+ rtld_stat_t status;
if ((rtld_flags2 & RT_FL2_SETUID) ||
- ((stat(NAME(lml_rtld.lm_head), &status) == 0) &&
+ ((rtld_stat(NAME(lml_rtld.lm_head), &status) == 0) &&
(status.st_uid == 0) && (status.st_mode & S_ISUID))) {
rtld_flags2 |= RT_FL2_SETUID;
return (1);
@@ -3758,3 +3758,69 @@ demangle(const char *name)
else
return (name);
}
+
+
+#ifndef _LP64
+/*
+ * Wrappers on stat() and fstat() for 32-bit rtld that uses stat64()
+ * underneath while preserving the object size limits of a non-largefile
+ * enabled 32-bit process. The purpose of this is to prevent large inode
+ * values from causing stat() to fail.
+ */
+inline static int
+rtld_stat_process(int r, struct stat64 *lbuf, rtld_stat_t *restrict buf)
+{
+ extern int errno;
+
+ /*
+ * Although we used a 64-bit capable stat(), the 32-bit rtld
+ * can only handle objects < 2GB in size. If this object is
+ * too big, turn the success into an overflow error.
+ */
+ if ((lbuf->st_size & 0xffffffff80000000) != 0) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+
+ /*
+ * Transfer the information needed by rtld into a rtld_stat_t
+ * structure that preserves the non-largile types for everything
+ * except inode.
+ */
+ buf->st_dev = lbuf->st_dev;
+ buf->st_ino = lbuf->st_ino;
+ buf->st_mode = lbuf->st_mode;
+ buf->st_uid = lbuf->st_uid;
+ buf->st_size = (off_t)lbuf->st_size;
+ buf->st_mtim = lbuf->st_mtim;
+#ifdef sparc
+ buf->st_blksize = lbuf->st_blksize;
+#endif
+
+ return (r);
+}
+
+int
+rtld_stat(const char *restrict path, rtld_stat_t *restrict buf)
+{
+ struct stat64 lbuf;
+ int r;
+
+ r = stat64(path, &lbuf);
+ if (r != -1)
+ r = rtld_stat_process(r, &lbuf, buf);
+ return (r);
+}
+
+int
+rtld_fstat(int fildes, rtld_stat_t *restrict buf)
+{
+ struct stat64 lbuf;
+ int r;
+
+ r = fstat64(fildes, &lbuf);
+ if (r != -1)
+ r = rtld_stat_process(r, &lbuf, buf);
+ return (r);
+}
+#endif
diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
index 0a6b0ef173..216dcd0035 100644
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
@@ -29,8 +29,6 @@
* All Rights Reserved
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* SPARC machine dependent and a.out format file class dependent functions.
* Contains routines for performing function binding and symbol relocations.
@@ -86,7 +84,7 @@ aout_bndr(caddr_t pc)
*/
entry = enter(0);
- for (lmp = lml_main.lm_head; lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ for (lmp = lml_main.lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (FCT(lmp) == &aout_fct) {
if (pc > (caddr_t)(LM2LP(lmp)->lp_plt) &&
pc < (caddr_t)((int)LM2LP(lmp)->lp_plt +