6943772 Testing for a symbols existence with RTLD_PROBE is compromised by RTLD_BIND_NOW
PSARC/2010/175 Deferred symbol references
6943432 dlsym(RTLD_PROBE) should only bind to symbol definitions
6668759 an external method for determining whether an ELF dependency is optional
--- a/usr/src/cmd/sgs/include/conv.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/include/conv.h Wed May 19 22:33:49 2010 -0700
@@ -23,8 +23,7 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _CONV_H
@@ -208,7 +207,7 @@
} Conv_seg_flags_buf_t;
/* conv_dyn_posflag1() */
-#define CONV_DYN_POSFLAG1_BUFSIZE 57
+#define CONV_DYN_POSFLAG1_BUFSIZE 72
typedef union {
Conv_inv_buf_t inv_buf;
char buf[CONV_DYN_POSFLAG1_BUFSIZE];
@@ -271,7 +270,7 @@
} Conv_dwarf_ehe_buf_t;
/* conv_syminfo_flags() */
-#define CONV_SYMINFO_FLAGS_BUFSIZE 193
+#define CONV_SYMINFO_FLAGS_BUFSIZE 230
typedef union {
Conv_inv_buf_t inv_buf;
char buf[CONV_SYMINFO_FLAGS_BUFSIZE];
--- a/usr/src/cmd/sgs/include/debug.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/include/debug.h Wed May 19 22:33:49 2010 -0700
@@ -330,6 +330,7 @@
#define Dbg_file_config_obj Dbg64_file_config_obj
#define Dbg_file_del_rescan Dbg64_file_del_rescan
#define Dbg_file_delete Dbg64_file_delete
+#define Dbg_file_deferred Dbg64_file_deferred
#define Dbg_file_elf Dbg64_file_elf
#define Dbg_file_filtee Dbg64_file_filtee
#define Dbg_file_filter Dbg64_file_filter
@@ -561,6 +562,7 @@
#define Dbg_file_config_obj Dbg32_file_config_obj
#define Dbg_file_del_rescan Dbg32_file_del_rescan
#define Dbg_file_delete Dbg32_file_delete
+#define Dbg_file_deferred Dbg32_file_deferred
#define Dbg_file_elf Dbg32_file_elf
#define Dbg_file_filtee Dbg32_file_filtee
#define Dbg_file_filter Dbg32_file_filter
@@ -827,6 +829,7 @@
const char *);
extern void Dbg_file_del_rescan(Lm_list *);
extern void Dbg_file_delete(Rt_map *);
+extern void Dbg_file_deferred(Lm_list *, const char *, const char *);
extern void Dbg_file_elf(Lm_list *, const char *, Addr, size_t,
const char *, Aliste);
extern void Dbg_file_filtee(Lm_list *, const char *, const char *, int);
--- a/usr/src/cmd/sgs/include/libld.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/include/libld.h Wed May 19 22:33:49 2010 -0700
@@ -476,6 +476,7 @@
#define FLG_OF1_NOINTRP 0x0000000008 /* -z nointerp flag set */
#define FLG_OF1_ZDIRECT 0x0000000010 /* -z direct flag set */
#define FLG_OF1_NDIRECT 0x0000000020 /* no-direct bindings specified */
+#define FLG_OF1_DEFERRED 0x0000000040 /* deferred dependency recording */
#define FLG_OF1_RELDYN 0x0000000100 /* process .dynamic in rel obj */
#define FLG_OF1_NRLXREL 0x0000000200 /* -z norelaxreloc flag set */
@@ -844,10 +845,8 @@
#define FLG_IF_IGNORE 0x00000080 /* ignore unused dependencies */
#define FLG_IF_NODIRECT 0x00000100 /* object contains symbols that */
/* cannot be directly bound to */
-#define FLG_IF_LAZYLD 0x00000200 /* bindings to this object should be */
- /* lazy loaded */
-#define FLG_IF_GRPPRM 0x00000400 /* this dependency should have the */
- /* DF_P1_GROUPPERM flag set */
+#define FLG_IF_LAZYLD 0x00000200 /* dependency should be lazy loaded */
+#define FLG_IF_GRPPRM 0x00000400 /* dependency establishes a group */
#define FLG_IF_DISPPEND 0x00000800 /* displacement relocation done */
/* in the ld time. */
#define FLG_IF_DISPDONE 0x00001000 /* displacement relocation done */
@@ -862,6 +861,18 @@
/* required */
#define FLG_IF_OTOSCAP 0x00040000 /* convert object capabilities to */
/* symbol capabilities */
+#define FLG_IF_DEFERRED 0x00080000 /* dependency is deferred */
+
+/*
+ * Symbol states that require the generation of a DT_POSFLAG_1 .dynamic entry.
+ */
+#define MSK_IF_POSFLAG1 (FLG_IF_LAZYLD | FLG_IF_GRPPRM | FLG_IF_DEFERRED)
+
+/*
+ * Symbol states that require an associated Syminfo entry.
+ */
+#define MSK_IF_SYMINFO (FLG_IF_LAZYLD | FLG_IF_DIRECT | FLG_IF_DEFERRED)
+
struct is_desc { /* input section descriptor */
const char *is_name; /* original section name */
@@ -1267,6 +1278,8 @@
#define FLG_SY_OVERLAP 0x0080000000000 /* move entry overlap detected */
#define FLG_SY_CAP 0x0100000000000 /* symbol is associated with */
/* capabilities */
+#define FLG_SY_DEFERRED 0x0200000000000 /* symbol should not be bound to */
+ /* during BIND_NOW relocations */
/*
* A symbol can only be truly hidden if it is not a capabilities symbol.
--- a/usr/src/cmd/sgs/include/rtld.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/include/rtld.h Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _RTLD_H
#define _RTLD_H
@@ -597,8 +596,9 @@
* loading and filtee processing.
*/
typedef struct {
- uint_t di_flags;
- void *di_info;
+ uint_t di_flags;
+ void *di_info;
+ const char *di_name;
} Dyninfo;
#define FLG_DI_STDFLTR 0x00001 /* .dynamic entry for DT_FILTER */
@@ -609,14 +609,21 @@
#define FLG_DI_POSFLAG1 0x00010 /* .dynamic entry for DT_POSFLAG_1 */
#define FLG_DI_NEEDED 0x00020 /* .dynamic entry for DT_NEEDED */
-#define FLG_DI_LAZY 0x00100 /* lazy needed entry - preceded by */
+#define FLG_DI_REGISTER 0x00040 /* .dynamic entry for DT_REGISTER */
+#define FLG_DI_IGNORE 0x00080 /* .dynamic entry should be ignored */
+
+#define FLG_DI_LAZY 0x00100 /* lazy needed entry, preceded by */
/* DF_P1_LAZYLOAD (DT_POSFLAG_1) */
-#define FLG_DI_GROUP 0x00200 /* group needed entry - preceded by */
+#define FLG_DI_GROUP 0x00200 /* group needed entry, preceded by */
/* DF_P1_GROUPPERM (DT_POSFLAG_1) */
+#define FLG_DI_DEFERRED 0x00400 /* deferred needed entry, preceded by */
+ /* DF_P1_DEFERRED (DT_POSFLAG_1) */
-#define FLG_DI_LDD_DONE 0x01000 /* entry has been processed (ldd) */
-#define FLG_DI_LAZYFAIL 0x02000 /* the lazy loading of this entry */
+#define FLG_DI_LAZYFAIL 0x01000 /* the lazy loading of this entry */
/* failed */
+#define FLG_DI_LDD_DONE 0x02000 /* entry has been processed (ldd) */
+#define FLG_DI_DEF_DONE 0x04000 /* entry has been processed (dlinfo) */
+
/*
* Data structure to track AVL tree of pathnames. This structure provides the
* basis of both the "not-found" node tree, and the "full-path" node tree. Both
--- a/usr/src/cmd/sgs/ldd/common/ldd.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/ldd/common/ldd.c Wed May 19 22:33:49 2010 -0700
@@ -29,7 +29,7 @@
* Print the list of shared objects required by a dynamic executable or shared
* object.
*
- * usage is: ldd [-d | -r] [-c] [-e envar] [-i] [-f] [-L] [-l] [-p] [-s]
+ * usage is: ldd [-d | -r] [-D] [-c] [-e envar] [-i] [-f] [-L] [-l] [-p] [-s]
* [-U | -u] [-v] [-w] file(s)
*
* ldd opens the file and verifies the information in the elf header.
@@ -54,6 +54,12 @@
* If -c is specified we also set LD_NOCONFIG=1, thus disabling any
* configuration file use.
*
+ * If -D is specified we skip deferred dependency processing. By default,
+ * ldd loads all deferred dependencies. However, during normal process
+ * execution, deferred dependencies are only loaded when an explicit binding
+ * to an individual deferred reference is made. As no user code is executed
+ * under ldd, explicit references to deferred symbols can't be triggered.
+ *
* If -e is specified the associated environment variable is set for the
* child process that will produce ldd's diagnostics.
*
@@ -80,7 +86,7 @@
*
* If -v is specified we also set LD_VERBOSE=1, thus enabling the runtime
* linker to indicate all object dependencies (not just the first object
- * loaded) together with any versionig requirements.
+ * loaded) together with any versioning requirements.
*
* If -U or -u is specified unused dependencies are detected. -u causes
* LD_UNUSED=1 to be set, which causes dependencies that are unused within the
@@ -141,7 +147,8 @@
uref[] = "LD_UNREF= ",
used[] = "LD_UNUSED= ",
weak[] = "LD_NOUNRESWEAK= ",
- nope[] = "LD_NOPAREXT= ";
+ nope[] = "LD_NOPAREXT= ",
+ defr[] = "LD_DEFERRED= ";
static char *load;
static const char *prefile_32, *prefile_64, *prefile;
@@ -155,8 +162,8 @@
Elf *elf;
int cflag = 0, dflag = 0, fflag = 0, iflag = 0, Lflag = 0;
int lflag = 0, rflag = 0, sflag = 0, Uflag = 0, uflag = 0;
- int pflag = 0, vflag = 0, wflag = 0, nfile, var, error = 0;
-
+ int Dflag = 0, pflag = 0, vflag = 0, wflag = 0;
+ int nfile, var, error = 0;
Aliste idx;
/*
@@ -185,6 +192,9 @@
case 'c' : /* enable config search */
cflag = 1;
break;
+ case 'D' : /* skip deferred dependencies */
+ Dflag = 1;
+ break;
case 'd' : /* perform data relocations */
dflag = 1;
if (rflag)
@@ -313,6 +323,7 @@
used[sizeof (used) - 2] = (uflag) ? '1' : '\0';
weak[sizeof (weak) - 2] = (wflag) ? '1' : '\0';
nope[sizeof (nope) - 2] = (pflag) ? '1' : '\0';
+ defr[sizeof (defr) - 2] = (Dflag) ? '\0' : '1';
/*
* coordinate libelf's version information
@@ -722,7 +733,7 @@
(putenv(init) != 0) || (putenv(lazy) != 0) ||
(putenv(uref) != 0) || (putenv(used) != 0) ||
(putenv(weak) != 0) || (putenv(load) != 0) ||
- (putenv(nope) != 0)) {
+ (putenv(nope) != 0) || (putenv(defr) != 0)) {
(void) fprintf(stderr, MSG_INTL(MSG_ENV_FAILED), cname);
exit(1);
}
--- a/usr/src/cmd/sgs/ldd/common/ldd.msg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/ldd/common/ldd.msg Wed May 19 22:33:49 2010 -0700
@@ -31,8 +31,8 @@
# Argument usage messages.
-@ MSG_ARG_USAGE "usage: %s [-d | -r] [-c] [-e envar] [-f] [-i] [-L] \
- [-l] [-p] [-s] [-U | -u] [-v] [-w] file(s)\n"
+@ MSG_ARG_USAGE "usage: %s [-d | -r] [-c] [-D] [-e envar] [-f] [-i] \
+ [-L] [-l] [-p] [-s] [-U | -u] [-v] [-w] file(s)\n"
# Environment messages.
@@ -100,7 +100,7 @@
@ MSG_SUNW_OST_SGS "SUNW_OST_SGS"
-@ MSG_STR_GETOPT "cde:fiLlprsUuvw"
+@ MSG_STR_GETOPT "cDde:fiLlprsUuvw"
@ MSG_STR_FMT1 "%s=./%s %s"
@ MSG_STR_FMT2 "%s=%s %s"
@ MSG_STR_FMT3 "%s:\n"
--- a/usr/src/cmd/sgs/libconv/common/dl.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libconv/common/dl.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <string.h>
@@ -203,11 +202,14 @@
MSG_RTLD_DI_SETSIGNAL, /* MSG_ORIG(MSG_RTLD_DI_SETSIGNAL) */
MSG_RTLD_DI_ARGSINFO, /* MSG_ORIG(MSG_RTLD_DI_ARGSINFO) */
MSG_RTLD_DI_MMAPS, /* MSG_ORIG(MSG_RTLD_DI_MMAPS) */
- MSG_RTLD_DI_MMAPCNT /* MSG_ORIG(MSG_RTLD_DI_MMAPCNT) */
+ MSG_RTLD_DI_MMAPCNT, /* MSG_ORIG(MSG_RTLD_DI_MMAPCNT) */
+ MSG_RTLD_DI_DEFERRED, /* MSG_ORIG(MSG_RTLD_DI_DEFERRED) */
+ MSG_RTLD_DI_DEFERRED_SYM
+ /* MSG_ORIG(MSG_RTLD_DI_DEFERRED_SYM) */
};
static Conv_inv_buf_t inv_buf;
-#if (RTLD_DI_MAX != RTLD_DI_MMAPCNT)
+#if (RTLD_DI_MAX != RTLD_DI_DEFERRED_SYM)
#error "RTLD_DI_MAX has grown"
#endif
if (request && (request <= RTLD_DI_MAX))
--- a/usr/src/cmd/sgs/libconv/common/dl.msg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libconv/common/dl.msg Wed May 19 22:33:49 2010 -0700
@@ -1,6 +1,5 @@
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
#
# CDDL HEADER START
#
@@ -48,19 +47,21 @@
@ MSG_RTLD_NOHEAP "RTLD_NOHEAP"
@ MSG_RTLD_CONFSET "RTLD_CONFSET"
-@ MSG_RTLD_DI_LMID "RTLD_DI_LMID"
-@ MSG_RTLD_DI_LINKMAP "RTLD_DI_LINKMAP"
-@ MSG_RTLD_DI_CONFIGADDR "RTLD_DI_CONFIGADDR"
-@ MSG_RTLD_DI_SERINFO "RTLD_DI_SERINFO"
-@ MSG_RTLD_DI_SERINFOSIZE "RTLD_DI_SERINFOSIZE"
-@ MSG_RTLD_DI_ORIGIN "RTLD_DI_ORIGIN"
-@ MSG_RTLD_DI_PROFILENAME "RTLD_DI_PROFILENAME"
-@ MSG_RTLD_DI_PROFILEOUT "RTLD_DI_PROFILEOUT"
-@ MSG_RTLD_DI_GETSIGNAL "RTLD_DI_GETSIGNAL"
-@ MSG_RTLD_DI_SETSIGNAL "RTLD_DI_SETSIGNAL"
-@ MSG_RTLD_DI_ARGSINFO "RTLD_DI_ARGSINFO"
-@ MSG_RTLD_DI_MMAPS "RTLD_DI_MMAPS"
-@ MSG_RTLD_DI_MMAPCNT "RTLD_DI_MMAPCNT"
+@ MSG_RTLD_DI_LMID "RTLD_DI_LMID"
+@ MSG_RTLD_DI_LINKMAP "RTLD_DI_LINKMAP"
+@ MSG_RTLD_DI_CONFIGADDR "RTLD_DI_CONFIGADDR"
+@ MSG_RTLD_DI_SERINFO "RTLD_DI_SERINFO"
+@ MSG_RTLD_DI_SERINFOSIZE "RTLD_DI_SERINFOSIZE"
+@ MSG_RTLD_DI_ORIGIN "RTLD_DI_ORIGIN"
+@ MSG_RTLD_DI_PROFILENAME "RTLD_DI_PROFILENAME"
+@ MSG_RTLD_DI_PROFILEOUT "RTLD_DI_PROFILEOUT"
+@ MSG_RTLD_DI_GETSIGNAL "RTLD_DI_GETSIGNAL"
+@ MSG_RTLD_DI_SETSIGNAL "RTLD_DI_SETSIGNAL"
+@ MSG_RTLD_DI_ARGSINFO "RTLD_DI_ARGSINFO"
+@ MSG_RTLD_DI_MMAPS "RTLD_DI_MMAPS"
+@ MSG_RTLD_DI_MMAPCNT "RTLD_DI_MMAPCNT"
+@ MSG_RTLD_DI_DEFERRED "RTLD_DI_DEFERRED"
+@ MSG_RTLD_DI_DEFERRED_SYM "RTLD_DI_DEFERRED_SYM"
@ MSG_GBL_SEP " | "
@ MSG_GBL_QUOTE "\""
--- a/usr/src/cmd/sgs/libconv/common/dynamic.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libconv/common/dynamic.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -42,6 +41,7 @@
#define POSSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
MSG_DF_P1_LAZYLOAD_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_DF_P1_GROUPPERM_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_DF_P1_DEFERRED_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
/*
@@ -62,22 +62,26 @@
static const Val_desc vda_def[] = {
{ DF_P1_LAZYLOAD, MSG_DF_P1_LAZYLOAD_DEF },
- { DF_P1_GROUPPERM, MSG_DF_P1_GROUPPERM_CFNP },
+ { DF_P1_GROUPPERM, MSG_DF_P1_GROUPPERM_DEF },
+ { DF_P1_DEFERRED, MSG_DF_P1_DEFERRED_DEF },
{ 0, 0 }
};
static const Val_desc vda_cf[] = {
{ DF_P1_LAZYLOAD, MSG_DF_P1_LAZYLOAD_CF },
{ DF_P1_GROUPPERM, MSG_DF_P1_GROUPPERM_CF },
+ { DF_P1_DEFERRED, MSG_DF_P1_DEFERRED_CF },
{ 0, 0 }
};
static const Val_desc vda_cfnp[] = {
{ DF_P1_LAZYLOAD, MSG_DF_P1_LAZYLOAD_CFNP },
{ DF_P1_GROUPPERM, MSG_DF_P1_GROUPPERM_CFNP },
+ { DF_P1_DEFERRED, MSG_DF_P1_DEFERRED_CFNP },
{ 0, 0 }
};
static const Val_desc vda_nf[] = {
{ DF_P1_LAZYLOAD, MSG_DF_P1_LAZYLOAD_NF },
{ DF_P1_GROUPPERM, MSG_DF_P1_GROUPPERM_NF },
+ { DF_P1_DEFERRED, MSG_DF_P1_DEFERRED_NF },
{ 0, 0 }
};
--- a/usr/src/cmd/sgs/libconv/common/dynamic.msg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libconv/common/dynamic.msg Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
#
@ MSG_DT_NULL_CF "DT_NULL" # 0
@@ -396,6 +395,11 @@
@ MSG_DF_P1_GROUPPERM_CF "DF_P1_GROUPPERM" # 0x00000002
@ MSG_DF_P1_GROUPPERM_CFNP "GROUPPERM"
@ MSG_DF_P1_GROUPPERM_NF "groupperm"
+@ MSG_DF_P1_GROUPPERM_DEF "GROUP"
+@ MSG_DF_P1_DEFERRED_CF "DF_P1_DEFERRED" # 0x00000004
+@ MSG_DF_P1_DEFERRED_CFNP "DEFERRED"
+@ MSG_DF_P1_DEFERRED_NF "deferred"
+@ MSG_DF_P1_DEFERRED_DEF "DEFERRED"
@ MSG_DTF_1_PARINIT_CF "DTF_1_PARINIT" # 0x00000001
--- a/usr/src/cmd/sgs/libconv/common/syminfo.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libconv/common/syminfo.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -46,6 +45,8 @@
MSG_SYMINFO_FLG_NOEXTDIRECT_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_SYMINFO_FLG_AUXILIARY_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
MSG_SYMINFO_FLG_INTERPOSE_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_SYMINFO_FLG_CAP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_SYMINFO_FLG_DEFERRED_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
/*
@@ -74,6 +75,7 @@
{ SYMINFO_FLG_AUXILIARY, MSG_SYMINFO_FLG_AUXILIARY_CF },
{ SYMINFO_FLG_INTERPOSE, MSG_SYMINFO_FLG_INTERPOSE_CF },
{ SYMINFO_FLG_CAP, MSG_SYMINFO_FLG_CAP_CF },
+ { SYMINFO_FLG_DEFERRED, MSG_SYMINFO_FLG_DEFERRED_CF },
{ 0 }
};
static const Val_desc vda_cfnp[] = {
@@ -86,6 +88,7 @@
{ SYMINFO_FLG_AUXILIARY, MSG_SYMINFO_FLG_AUXILIARY_CFNP },
{ SYMINFO_FLG_INTERPOSE, MSG_SYMINFO_FLG_INTERPOSE_CFNP },
{ SYMINFO_FLG_CAP, MSG_SYMINFO_FLG_CAP_CFNP },
+ { SYMINFO_FLG_DEFERRED, MSG_SYMINFO_FLG_DEFERRED_CFNP },
{ 0 }
};
static const Val_desc vda_nf[] = {
@@ -98,6 +101,7 @@
{ SYMINFO_FLG_AUXILIARY, MSG_SYMINFO_FLG_AUXILIARY_NF },
{ SYMINFO_FLG_INTERPOSE, MSG_SYMINFO_FLG_INTERPOSE_NF },
{ SYMINFO_FLG_CAP, MSG_SYMINFO_FLG_CAP_NF },
+ { SYMINFO_FLG_DEFERRED, MSG_SYMINFO_FLG_DEFERRED_NF },
{ 0 }
};
--- a/usr/src/cmd/sgs/libconv/common/syminfo.msg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libconv/common/syminfo.msg Wed May 19 22:33:49 2010 -0700
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
@ MSG_SYMINFO_FLG_DIRECT_CF "SYMINFO_FLG_DIRECT" # 0x001
@@ -50,6 +49,9 @@
@ MSG_SYMINFO_FLG_CAP_CF "SYMINFO_FLG_CAP" # 0x100
@ MSG_SYMINFO_FLG_CAP_CFNP "CAP"
@ MSG_SYMINFO_FLG_CAP_NF "cap"
+@ MSG_SYMINFO_FLG_DEFERRED_CF "SYMINFO_FLG_DEFERRED" # 0x200
+@ MSG_SYMINFO_FLG_DEFERRED_CFNP "DEFERRED"
+@ MSG_SYMINFO_FLG_DEFERRED_NF "deferred"
@ MSG_SYMINFO_BT_EXTERN_CF "SYMINFO_BT_EXTERN" # 0xfffc
@ MSG_SYMINFO_BT_EXTERN_CFNP "EXTERN"
--- a/usr/src/cmd/sgs/libld/common/args.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/args.c Wed May 19 22:33:49 2010 -0700
@@ -175,6 +175,7 @@
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAE));
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAL));
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZC));
+ (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDEF));
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDFS));
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDRS));
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZE));
@@ -213,7 +214,7 @@
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO));
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW));
(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZWRAP));
- (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZV));
+ (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZVER));
}
/*
@@ -1331,12 +1332,14 @@
strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
+ strcmp(optarg, MSG_ORIG(MSG_ARG_NODEFERRED)) &&
strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) &&
strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) &&
strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET),
MSG_ARG_TARGET_SIZE) &&
- strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW))) {
+ strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW)) &&
+ strcmp(optarg, MSG_ORIG(MSG_ARG_DEFERRED))) {
eprintf(ofl->ofl_lml, ERR_FATAL,
MSG_INTL(MSG_ARG_ILLEGAL),
MSG_ORIG(MSG_ARG_Z), optarg);
@@ -1718,6 +1721,12 @@
if (ld_rescan_archives(ofl, 1, ndx) ==
S_ERROR)
return (S_ERROR);
+ } else if (strcmp(optarg,
+ MSG_ORIG(MSG_ARG_DEFERRED)) == 0) {
+ ofl->ofl_flags1 |= FLG_OF1_DEFERRED;
+ } else if (strcmp(optarg,
+ MSG_ORIG(MSG_ARG_NODEFERRED)) == 0) {
+ ofl->ofl_flags1 &= ~FLG_OF1_DEFERRED;
}
default:
break;
--- a/usr/src/cmd/sgs/libld/common/files.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/files.c Wed May 19 22:33:49 2010 -0700
@@ -2203,13 +2203,14 @@
} else if (dyn->d_tag == DT_SUNW_RTLDINF) {
/*
- * If a library has the SUNW_RTLDINF .dynamic entry
- * then we must not permit lazyloading of this library.
- * This is because critical startup information (TLS
- * routines) are provided as part of these interfaces
- * and we must have them as part of process startup.
+ * If this dependency has the DT_SUNW_RTLDINF .dynamic
+ * entry, then ensure no specialized dependency
+ * processing is in effect. This tag identifies libc,
+ * which provides critical startup information (TLS
+ * routines, threads initialization, etc.) that must
+ * be exercised as part of process initialization.
*/
- ifl->ifl_flags &= ~FLG_IF_LAZYLD;
+ ifl->ifl_flags &= ~MSK_IF_POSFLAG1;
}
}
@@ -3279,8 +3280,9 @@
ifl->ifl_soname = soname;
/*
- * If direct bindings, lazy loading, or group
- * permissions need to be established, mark this object.
+ * If direct bindings, lazy loading, group permissions,
+ * or deferred dependencies need to be established, mark
+ * this object.
*/
if (ofl->ofl_flags1 & FLG_OF1_ZDIRECT)
ifl->ifl_flags |= FLG_IF_DIRECT;
@@ -3288,14 +3290,16 @@
ifl->ifl_flags |= FLG_IF_LAZYLD;
if (ofl->ofl_flags1 & FLG_OF1_GRPPRM)
ifl->ifl_flags |= FLG_IF_GRPPRM;
+ if (ofl->ofl_flags1 & FLG_OF1_DEFERRED)
+ ifl->ifl_flags |=
+ (FLG_IF_LAZYLD | FLG_IF_DEFERRED);
+
error = process_elf(ifl, elf, ofl);
/*
- * At this point we know if this file will be
- * lazyloaded, or whether bindings to it must be direct.
- * In either case, a syminfo section is required.
+ * Determine whether this dependency requires a syminfo.
*/
- if (ifl->ifl_flags & (FLG_IF_LAZYLD | FLG_IF_DIRECT))
+ if (ifl->ifl_flags & MSK_IF_SYMINFO)
ofl->ofl_flags |= FLG_OF_SYMINFO;
break;
--- a/usr/src/cmd/sgs/libld/common/libld.msg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/libld.msg Wed May 19 22:33:49 2010 -0700
@@ -144,6 +144,9 @@
sections\n"
@ MSG_ARG_DETAIL_ZNC "\t[-z nocompstrtab]\n\t\t\tdisable compression of \
string tables\n"
+@ MSG_ARG_DETAIL_ZDEF "\t[-z deferred | nodeferred]\n\
+ \t\t\tenable|disable deferred identification of \
+ shared object\n\t\t\tdependencies\n"
@ MSG_ARG_DETAIL_ZDFS "\t[-z defs], [--no-undefined]\n\
\t\t\tdisallow undefined symbol references\n"
@ MSG_ARG_DETAIL_ZDRS "\t[-z direct | nodirect]\n\
@@ -231,7 +234,7 @@
against text\n"
@ MSG_ARG_DETAIL_ZWRAP "\t[-z wrap=symbol], [-wrap=symbol], [--wrap=symbol]\n\
\t\t\twrap symbol references\n"
-@ MSG_ARG_DETAIL_ZV "\t[-z verbose]\t\
+@ MSG_ARG_DETAIL_ZVER "\t[-z verbose]\t\
generate warnings for suspicious processings\n"
#
@@ -1380,6 +1383,8 @@
@ MSG_ARG_REDUCE "reduce"
@ MSG_ARG_STATIC "static"
@ MSG_ARG_SYMBOLCAP "symbolcap"
+@ MSG_ARG_DEFERRED "deferred"
+@ MSG_ARG_NODEFERRED "nodeferred"
@ MSG_ARG_LCOM "L,"
@ MSG_ARG_PCOM "P,"
--- a/usr/src/cmd/sgs/libld/common/relocate.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/relocate.c Wed May 19 22:33:49 2010 -0700
@@ -972,12 +972,15 @@
(*ld_targ.t_mr.mr_assign_plt_ndx)(sdp, ofl);
/*
- * If this symbol is binding to a LAZYLOADED object then
- * set the LAZYLD symbol flag.
+ * If this symbol is binding to a lazy loadable, or deferred
+ * dependency, then identify the symbol.
*/
- if (sdp->sd_file &&
- (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD))
- sdp->sd_flags |= FLG_SY_LAZYLD;
+ if (sdp->sd_file) {
+ if (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD)
+ sdp->sd_flags |= FLG_SY_LAZYLD;
+ if (sdp->sd_file->ifl_flags & FLG_IF_DEFERRED)
+ sdp->sd_flags |= FLG_SY_DEFERRED;
+ }
rsp->rel_rtype = ld_targ.t_m.m_r_jmp_slot;
if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_PLT, rsp, ofl) ==
--- a/usr/src/cmd/sgs/libld/common/sections.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/sections.c Wed May 19 22:33:49 2010 -0700
@@ -995,10 +995,9 @@
}
/*
- * If this object is a lazyload reserve a DT_POSFLAG_1 entry.
+ * If this object requires a DT_POSFLAG_1 entry, reserve it.
*/
- if ((ifl->ifl_flags & (FLG_IF_LAZYLD | FLG_IF_GRPPRM)) &&
- not_relobj)
+ if ((ifl->ifl_flags & MSK_IF_POSFLAG1) && not_relobj)
cnt++;
if (st_insert(strtbl, ifl->ifl_soname) == -1)
@@ -1593,6 +1592,7 @@
ld_cap_move_symtoobj(ofl);
ofl->ofl_capsymcnt = 0;
ofl->ofl_capgroups = NULL;
+ ofl->ofl_flags &= ~FLG_OF_OTOSCAP;
}
/*
--- a/usr/src/cmd/sgs/libld/common/update.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/update.c Wed May 19 22:33:49 2010 -0700
@@ -23,8 +23,7 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -1315,13 +1314,18 @@
* Flag that the symbol has a direct association
* with the external reference (this is an old
* tagging, that has no real effect by itself).
- * And flag whether this reference is lazy
- * loadable.
*/
syminfo[ndx].si_flags |= SYMINFO_FLG_DIRECT;
+
+ /*
+ * Flag any lazy or deferred reference.
+ */
if (sdp->sd_flags & FLG_SY_LAZYLD)
syminfo[ndx].si_flags |=
SYMINFO_FLG_LAZYLOAD;
+ if (sdp->sd_flags & FLG_SY_DEFERRED)
+ syminfo[ndx].si_flags |=
+ SYMINFO_FLG_DEFERRED;
/*
* Enable direct symbol bindings if:
@@ -1415,6 +1419,16 @@
}
/*
+ * Indicate that this symbol is deferred, and
+ * hence should not be bound to during BIND_NOW
+ * relocations.
+ */
+ if (sdp->sd_flags & FLG_SY_DEFERRED) {
+ syminfo[ndx].si_flags |=
+ SYMINFO_FLG_DEFERRED;
+ }
+
+ /*
* If external bindings are allowed, indicate
* the binding, and a direct binding if
* necessary.
@@ -2097,13 +2111,15 @@
/*
* Create and set up the DT_POSFLAG_1 entry here if required.
*/
- if ((ifl->ifl_flags & (FLG_IF_LAZYLD|FLG_IF_GRPPRM)) &&
- (ifl->ifl_flags & (FLG_IF_NEEDED)) && not_relobj) {
+ if ((ifl->ifl_flags & MSK_IF_POSFLAG1) &&
+ (ifl->ifl_flags & FLG_IF_NEEDED) && not_relobj) {
dyn->d_tag = DT_POSFLAG_1;
if (ifl->ifl_flags & FLG_IF_LAZYLD)
dyn->d_un.d_val = DF_P1_LAZYLOAD;
if (ifl->ifl_flags & FLG_IF_GRPPRM)
dyn->d_un.d_val |= DF_P1_GROUPPERM;
+ if (ifl->ifl_flags & FLG_IF_DEFERRED)
+ dyn->d_un.d_val |= DF_P1_DEFERRED;
dyn++;
}
--- a/usr/src/cmd/sgs/liblddbg/common/files.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/files.c Wed May 19 22:33:49 2010 -0700
@@ -589,6 +589,16 @@
}
void
+Dbg_file_deferred(Lm_list *lml, const char *oname, const char *nname)
+{
+ if (DBG_NOTCLASS(DBG_C_FILES))
+ return;
+
+ Dbg_util_nl(lml, DBG_NL_STD);
+ dbg_print(lml, MSG_INTL(MSG_FIL_DEFERRED), oname, nname);
+}
+
+void
Dbg_file_cntl(Lm_list *lml, Aliste flmco, Aliste tlmco)
{
Lm_cntl *lmc;
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg Wed May 19 22:33:49 2010 -0700
@@ -663,6 +663,7 @@
@ MSG_FIL_FILTEE_3 "file=%s; filtee skipped (auditing directed)"
@ MSG_FIL_FIXNAME "file=%s; required name=%s"
@ MSG_FIL_PROMOTE "file=%s; promoting mode to %s"
+@ MSG_FIL_DEFERRED "file=%s; deferred dependency exchanged for file=%s"
@ MSG_FIL_AOUT "file=%s [ AOUT ]; generating link map"
@ MSG_FIL_ELF "file=%s [ ELF ]; generating link map%s"
@ MSG_FIL_LDSO "file=%s [ ELF ]"
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Wed May 19 22:33:49 2010 -0700
@@ -141,6 +141,8 @@
void Dbg64_file_cntl(Lm_list *, Aliste, Aliste);
void Dbg32_file_cleanup(Lm_list *, const char *, Aliste);
void Dbg64_file_cleanup(Lm_list *, const char *, Aliste);
+void Dbg32_file_deferred(Lm_list *, const char *, const char *);
+void Dbg64_file_deferred(Lm_list *, const char *, const char *);
void Dbg32_file_del_rescan(Lm_list *);
void Dbg64_file_del_rescan(Lm_list *);
void Dbg32_file_delete(Rt_map *);
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers Wed May 19 22:33:49 2010 -0700
@@ -150,6 +150,8 @@
Dbg64_file_config_dis;
Dbg32_file_config_obj;
Dbg64_file_config_obj;
+ Dbg32_file_deferred;
+ Dbg64_file_deferred;
Dbg32_file_del_rescan;
Dbg64_file_del_rescan;
Dbg32_file_delete;
--- a/usr/src/cmd/sgs/liblddbg/common/syminfo.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/syminfo.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sgs.h>
#include <stdio.h>
@@ -99,6 +98,10 @@
flagstr[flgndx++] = 'I';
flags &= ~SYMINFO_FLG_INTERPOSE;
}
+ if (flags & SYMINFO_FLG_DEFERRED) {
+ flagstr[flgndx++] = 'P';
+ flags &= ~SYMINFO_FLG_DEFERRED;
+ }
/*
* Did we account for all of the flags?
--- a/usr/src/cmd/sgs/librtld/common/dynamic.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/librtld/common/dynamic.c Wed May 19 22:33:49 2010 -0700
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Update any dynamic entry offsets. One issue with dynamic entries is that
* you only know whether they refer to a value or an offset if you know each
* type. Thus we check for all types we know about, it a type is found that
* we don't know about then return and error as we have no idea what to do.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <libelf.h>
#include <link.h>
@@ -59,30 +57,31 @@
* Loop through the dynamic table updating all offsets.
*/
while (dyn->d_tag != DT_NULL) {
+ Rt_map *dlmp;
+
switch ((Xword)dyn->d_tag) {
case DT_NEEDED:
- if (posdyn) {
- Rt_map *dlmp;
+ if (posdyn == 0)
+ break;
- /*
- * Determine whether this dependency has been
- * loaded (this is the most generic way to check
- * any alias names), and if it has been bound
- * to, undo any lazy-loading position flag.
- */
- if (dlmp = is_so_loaded(LIST(lmp),
- (strs + dyn->d_un.d_val), NULL)) {
- Bnd_desc *bdp;
- Aliste idx;
+ /*
+ * Determine whether this dependency has been loaded
+ * (this is the most generic way to check any alias
+ * names), and if it has been bound to, undo any
+ * lazy-loading or deferred position flag.
+ */
+ if (dlmp = is_so_loaded(LIST(lmp),
+ (strs + dyn->d_un.d_val), NULL)) {
+ Bnd_desc *bdp;
+ Aliste idx;
- for (APLIST_TRAVERSE(DEPENDS(lmp), idx,
- bdp)) {
- if (dlmp == bdp->b_depend) {
- posdyn->d_un.d_val &=
- ~DF_P1_LAZYLOAD;
- break;
- }
- }
+ for (APLIST_TRAVERSE(DEPENDS(lmp), idx, bdp)) {
+ if (dlmp != bdp->b_depend)
+ continue;
+
+ posdyn->d_un.d_val &=
+ ~(DF_P1_LAZYLOAD | DF_P1_DEFERRED);
+ break;
}
}
break;
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README Wed May 19 22:33:49 2010 -0700
@@ -889,6 +889,7 @@
5076838 elfdump(1) is built with a CTF section (the wrong one)
5080344 Hardware capabilities are not enforced for a.out
5079061 RTLD_DEFAULT can be expensive
+ PSARC/2004/747 New dlsym(3c) Handle - RTLD_PROBE
5064973 allow normal relocs against TLS symbols for some sections
5085792 LD_XXXX_64 should override LD_XXXX
5096272 every executable or library has a .SUNW_dof section
@@ -1284,10 +1285,18 @@
Solaris/SunOS 5.10_sparc patch T141444-06
Solaris/SunOS 5.10_x86 patch T141445-06
--------------------------------------------------------------------------------
-All the above changes plus:
- 6850124 dlopen reports "No such file or directory" in spite of ENOMEM
- when mmap fails in anon_map()
-are incorporated in the following patches:
+
+-------------------------------------
+Solaris 10 XXXX (9th Q-update - s10u9)
+-------------------------------------
+Bugid Risk Synopsis
+================================================================================
+6850124 dlopen reports "No such file or directory" in spite of ENOMEM
+ when mmap fails in anon_map()
+6826513 ldd gets confused by a crle(1) LD_PRELOAD setting
+6684577 ld should propagate SHF_LINK_ORDER flag to ET_REL objects
+--------------------------------------------------------------------------------
+All the above changes are incorporated in the following patches:
Solaris/SunOS 5.10_sparc patch T143895-01
Solaris/SunOS 5.10_x86 patch T143896-01
--------------------------------------------------------------------------------
@@ -1450,7 +1459,6 @@
6724774 elfdump -n doesn't print siginfo structure
6728555 Fix for amd64 aw (6617475) breaks pure gcc builds
6734598 ld(1) archive processing failure due to mismatched file descriptors (D)
-6684577 ld should propagate SHF_LINK_ORDER flag to ET_REL objects
6735939 ld(1) discarded symbol relocations errors (Studio and GNU).
6354160 Solaris linker includes more than one copy of code in binary when
linking gnu object code
@@ -1501,7 +1509,6 @@
pfinstall does it again.
6807050 GNU linkonce sections can create duplicate and incompatible
eh_frame FDE entries
-6826513 ldd gets confused by a crle(1) LD_PRELOAD setting
--------------------------------------------------------------------------------
--------------
@@ -1577,5 +1584,8 @@
6938111 nm `No symbol table data' message goes to stdout
6941727 ld relocation cache memory use is excessive
6932220 ld -z allextract skips objects that lack global symbols
-6939573 ldd should provide better diagnostics for incompatible objects
-6948379 nm usage message omits several options
+6943772 Testing for a symbols existence with RTLD_PROBE is compromised by
+ RTLD_BIND_NOW
+ PSARC/2010/XXX Deferred symbol references
+6943432 dlsym(RTLD_PROBE) should only bind to symbol definitions
+6668759 an external method for determining whether an ELF dependency is optional
--- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -42,7 +41,8 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
+#include "_inline_reloc.h"
#include "msg.h"
extern void elf_rtbndr(Rt_map *, ulong_t, caddr_t);
@@ -385,6 +385,7 @@
uchar_t rtype;
long reladd, value, pvalue;
Sym *symref, *psymref, *symdef, *psymdef;
+ Syminfo *sip;
char *name, *pname;
Rt_map *_lmp, *plmp;
int ret = 1, noplt = 0;
@@ -420,7 +421,6 @@
if ((pltbgn = (ulong_t)JMPREL(lmp)) != 0)
pltend = pltbgn + (ulong_t)(PLTRELSZ(lmp));
-
relsiz = (ulong_t)(RELENT(lmp));
basebgn = ADDR(lmp);
@@ -509,6 +509,7 @@
(FLAGS(lmp) & FLG_RT_FIXED))
noplt = 1;
+ sip = SYMINFO(lmp);
/*
* Loop through relocations.
*/
@@ -527,11 +528,12 @@
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
if (relacount) {
relbgn = elf_reloc_relative_count(relbgn,
- relacount, relsiz, basebgn, lmp, textrel);
+ relacount, relsiz, basebgn, lmp,
+ textrel, 0);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, lmp, textrel);
+ relsiz, basebgn, lmp, textrel, 0);
}
if (relbgn >= relend)
break;
@@ -552,26 +554,9 @@
if (plthint && (plt == 0) &&
(rtype == R_AMD64_JUMP_SLOT) &&
((MODE(lmp) & RTLD_NOW) == 0)) {
- /*
- * The PLT relocations (for lazy bindings)
- * are additive to what's already in the GOT.
- * This differs to what happens in
- * elf_reloc_relacount() and that's why we
- * just do it inline here.
- */
- for (roffset = ((Rela *)relbgn)->r_offset;
- plthint; plthint--) {
- roffset += basebgn;
-
- /*
- * Perform the actual relocation.
- */
- *((ulong_t *)roffset) += basebgn;
-
- relbgn += relsiz;
- roffset = ((Rela *)relbgn)->r_offset;
-
- }
+ relbgn = elf_reloc_relative_count(relbgn,
+ plthint, relsiz, basebgn, lmp, textrel, 1);
+ plthint = 0;
continue;
}
roffset += basebgn;
@@ -619,6 +604,14 @@
*/
if (rsymndx) {
/*
+ * If a Syminfo section is provided, determine if this
+ * symbol is deferred, and if so, skip this relocation.
+ */
+ if (sip && is_sym_deferred((ulong_t)rel, basebgn, lmp,
+ textrel, sip, rsymndx))
+ continue;
+
+ /*
* Get the local symbol table entry.
*/
symref = (Sym *)((ulong_t)SYMTAB(lmp) +
--- a/usr/src/cmd/sgs/rtld/amd64/dlamd64getunwind.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/amd64/dlamd64getunwind.c Wed May 19 22:33:49 2010 -0700
@@ -20,10 +20,8 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "@(#)dlamd64getunwind.c 1.10 08/07/30 SMI"
#include <string.h>
#include <dlfcn.h>
@@ -31,7 +29,7 @@
#include <debug.h>
#include "_rtld.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
#include "msg.h"
--- a/usr/src/cmd/sgs/rtld/common/_elf.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/_elf.h Wed May 19 22:33:49 2010 -0700
@@ -23,8 +23,7 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef __ELF_DOT_H
#define __ELF_DOT_H
@@ -71,10 +70,6 @@
extern void elf_reloc_bad(Rt_map *, void *, uchar_t, ulong_t,
ulong_t);
extern int elf_reloc_error(Rt_map *, const char *, void *, uint_t);
-extern ulong_t elf_reloc_relative(ulong_t, ulong_t, ulong_t, ulong_t,
- Rt_map *, APlist **);
-extern ulong_t elf_reloc_relative_count(ulong_t, ulong_t, ulong_t, ulong_t,
- Rt_map *, APlist **);
extern int elf_rtld_load();
extern long elf_static_tls(Rt_map *, Sym *, void *, uchar_t, char *,
ulong_t, long);
--- a/usr/src/cmd/sgs/rtld/common/_inline.h Wed May 19 21:10:39 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * 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.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#ifndef _INLINE_H
-#define _INLINE_H
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-inline static mmapobj_result_t *
-find_segment(caddr_t roffset, Rt_map *lmp)
-{
- mmapobj_result_t *mpp = MMAPS(lmp);
- uint_t mnum = MMAPCNT(lmp);
-
- /*
- * Scan segments backwards. The heaviest use of this function stems
- * from relocation processing. And typically, relocations are against
- * the data segment. By scanning segments in reverse order, the data
- * segment is processed first.
- */
- for (mpp += (mnum - 1); mnum; mnum--, mpp--) {
- if ((roffset >= (mpp->mr_addr + mpp->mr_offset)) &&
- (roffset < (mpp->mr_addr + mpp->mr_msize)))
- return (mpp);
- }
- return (NULL);
-}
-
-#endif /* _INLINE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/sgs/rtld/common/_inline_gen.h Wed May 19 22:33:49 2010 -0700
@@ -0,0 +1,52 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * 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.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+#ifndef _INLINE_GEN_H
+#define _INLINE_GEN_H
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <rtld.h>
+
+inline static mmapobj_result_t *
+find_segment(caddr_t roffset, Rt_map *lmp)
+{
+ mmapobj_result_t *mpp = MMAPS(lmp);
+ uint_t mnum = MMAPCNT(lmp);
+
+ /*
+ * Scan segments backwards. The heaviest use of this function stems
+ * from relocation processing. And typically, relocations are against
+ * the data segment. By scanning segments in reverse order, the data
+ * segment is processed first.
+ */
+ for (mpp += (mnum - 1); mnum; mnum--, mpp--) {
+ if ((roffset >= (mpp->mr_addr + mpp->mr_offset)) &&
+ (roffset < (mpp->mr_addr + mpp->mr_msize)))
+ return (mpp);
+ }
+ return (NULL);
+}
+
+#endif /* _INLINE_GEN_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/sgs/rtld/common/_inline_reloc.h Wed May 19 22:33:49 2010 -0700
@@ -0,0 +1,182 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * 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.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+#ifndef _INLINE_RELOC_H
+#define _INLINE_RELOC_H
+
+#include <sys/types.h>
+#include <rtld.h>
+#include <debug.h>
+
+/*
+ * Generic relative relocation function.
+ */
+inline static ulong_t
+/* LINTED */
+/* ARGSUSED4 */
+_elf_reloc_relative(ulong_t rbgn, ulong_t base, Rt_map *lmp, APlist **textrel,
+ int add)
+{
+ mmapobj_result_t *mpp;
+ ulong_t roffset;
+
+ roffset = ((M_RELOC *)rbgn)->r_offset;
+ roffset += base;
+
+ /*
+ * If this relocation is against an address that is not associated with
+ * a mapped segment, fall back to the generic relocation loop to
+ * collect the associated error.
+ */
+ if ((mpp = find_segment((caddr_t)roffset, lmp)) == NULL)
+ return (0);
+
+ /*
+ * If this relocation is against a segment that does not provide write
+ * access, set the write permission for all non-writable mappings.
+ */
+ if (((mpp->mr_prot & PROT_WRITE) == 0) && textrel &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
+ return (0);
+
+ /*
+ * Perform a base address update. This simple operation is required
+ * for updating .plt relocations in preparation for lazy binding.
+ */
+#if defined(__x86)
+ if (add) {
+ *((ulong_t *)roffset) += base;
+ return (1);
+ }
+#endif
+ /*
+ * Perform the actual relocation. Note, for backward compatibility,
+ * SPARC relocations are added to the offset contents (there was a time
+ * when the offset was used to contain the addend, rather than using
+ * the addend itself).
+ */
+#if defined(__sparc)
+ *((ulong_t *)roffset) += base + ((M_RELOC *)rbgn)->r_addend;
+#elif defined(__amd64)
+ *((ulong_t *)roffset) = base + ((M_RELOC *)rbgn)->r_addend;
+#else
+ *((ulong_t *)roffset) += base;
+#endif
+ return (1);
+}
+
+/*
+ * When a generic relocation loop realizes that it's dealing with relative
+ * relocations, but no DT_RELCOUNT .dynamic tag is present, this tighter loop
+ * is entered as an optimization.
+ */
+inline static ulong_t
+/* LINTED */
+elf_reloc_relative(ulong_t rbgn, ulong_t rend, ulong_t rsize, ulong_t base,
+ Rt_map *lmp, APlist **textrel, int add)
+{
+ uchar_t rtype;
+
+ do {
+ if (_elf_reloc_relative(rbgn, base, lmp, textrel, add) == 0)
+ break;
+
+ rbgn += rsize;
+ if (rbgn >= rend)
+ break;
+
+ /*
+ * Make sure the next type is a relative relocation.
+ */
+ rtype = ELF_R_TYPE(((M_RELOC *)rbgn)->r_info, M_MACH);
+
+ } while (rtype == M_R_RELATIVE);
+
+ return (rbgn);
+}
+
+/*
+ * This is the tightest loop for RELATIVE relocations for those objects built
+ * with the DT_RELACOUNT .dynamic entry.
+ */
+inline static ulong_t
+/* LINTED */
+elf_reloc_relative_count(ulong_t rbgn, ulong_t rcount, ulong_t rsize,
+ ulong_t base, Rt_map *lmp, APlist **textrel, int add)
+{
+ for (; rcount; rcount--) {
+ if (_elf_reloc_relative(rbgn, base, lmp, textrel, add) == 0)
+ break;
+
+ rbgn += rsize;
+ }
+ return (rbgn);
+}
+
+/*
+ * Determine, from a symbols Syminfo information, whether a symbol reference
+ * is deferred. This routine is called from elf_reloc() as part of processing
+ * an objects relocations.
+ */
+inline static int
+/* LINTED */
+is_sym_deferred(ulong_t rbgn, ulong_t base, Rt_map *lmp, APlist **textrel,
+ Syminfo *sip, ulong_t sndx)
+{
+ Syminfo *sipe;
+
+ /*
+ * ldd(1) by default, sets LD_DEFERRED to force deferred dependency
+ * processing. ldd -D disables LD_DEFERRED, which allows ld.so.1's
+ * default action of skipping deferred dependencies.
+ */
+ if (rtld_flags & RT_FL_DEFERRED)
+ return (0);
+
+ /* LINTED */
+ sipe = (Syminfo *)((char *)sip + (sndx * SYMINENT(lmp)));
+ if (sipe->si_flags & SYMINFO_FLG_DEFERRED) {
+ /*
+ * This .plt relocation should be skipped at this time, as
+ * deferred references are only processed when the associated
+ * function is explicitly called.
+ *
+ * On i386 and amd64 platforms the relocation offset needs
+ * adjusting to add this objects base address. If the object
+ * has already been relocated without RTLD_NOW, then this
+ * update will have already been carried out. However, if this
+ * is an initial RTLD_NOW relocation pass, this relocation
+ * offset needs updating now.
+ */
+#if defined(__x86)
+ if ((FLAGS(lmp) & FLG_RT_RELOCED) == 0)
+ (void) _elf_reloc_relative(rbgn, base, lmp, textrel, 1);
+#endif
+ return (1);
+ }
+ return (0);
+}
+
+#endif /* _INLINE_RELOC_H */
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h Wed May 19 22:33:49 2010 -0700
@@ -23,8 +23,7 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef __RTLD_H
#define __RTLD_H
@@ -270,7 +269,7 @@
#define RT_FL_THREADS 0x00000001 /* threads are enabled */
#define RT_FL_WARNFLTR 0x00000002 /* warn of missing filtees (ldd) */
#define RT_FL_DBNOTIF 0x00000004 /* binding activity going on */
-
+#define RT_FL_DEFERRED 0x00000008 /* load deferred dependencies (ldd) */
#define RT_FL_NOBIND 0x00000010 /* don't carry out plt binding */
#define RT_FL_NOVERSION 0x00000020 /* disable version checking */
#define RT_FL_SECURE 0x00000040 /* setuid/segid flag */
--- a/usr/src/cmd/sgs/rtld/common/analyze.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/analyze.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -46,7 +45,7 @@
#include "_audit.h"
#include "_elf.h"
#include "_a.out.h"
-#include "_inline.h"
+#include "_inline_gen.h"
#include "msg.h"
/*
--- a/usr/src/cmd/sgs/rtld/common/audit.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/audit.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Audit interfaces. Auditing can be enabled in two ways:
*
@@ -92,6 +91,7 @@
for (APLIST_TRAVERSE(list, idx, alp)) {
Audit_client *fracp, *feacp;
+ int ret;
if (alp->al_objfilter == NULL)
continue;
@@ -103,10 +103,11 @@
continue;
leave(LIST(alp->al_lmp), thr_flg_reenter);
- if ((*alp->al_objfilter)(&(fracp->ac_cookie), ref,
- &(feacp->ac_cookie), flags) == 0)
+ ret = (*alp->al_objfilter)(&(fracp->ac_cookie), ref,
+ &(feacp->ac_cookie), flags);
+ (void) enter(thr_flg_reenter);
+ if (ret == 0)
return (0);
- (void) enter(thr_flg_reenter);
}
return (1);
}
--- a/usr/src/cmd/sgs/rtld/common/dlfcns.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c Wed May 19 22:33:49 2010 -0700
@@ -20,13 +20,10 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
+ *
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -44,7 +41,7 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
#include "msg.h"
/*
@@ -1184,13 +1181,31 @@
}
/*
+ * Determine whether a symbol resides in a caller. This may be a reference,
+ * which is associated with a specific dependency.
+ */
+inline static Sym *
+sym_lookup_in_caller(Rt_map *clmp, Slookup *slp, Sresult *srp, uint_t *binfo)
+{
+ if (THIS_IS_ELF(clmp) && SYMINTP(clmp)(slp, srp, binfo, NULL)) {
+ Sym *sym = srp->sr_sym;
+
+ slp->sl_rsymndx = (((ulong_t)sym -
+ (ulong_t)SYMTAB(clmp)) / SYMENT(clmp));
+ slp->sl_rsym = sym;
+ return (sym);
+ }
+ return (NULL);
+}
+
+/*
* Core dlsym activity. Selects symbol lookup method from handle.
*/
static void *
dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp,
int *in_nfavl)
{
- Sym *sym = NULL;
+ Sym *sym;
int ret = 0;
Syminfo *sip;
Slookup sl;
@@ -1215,14 +1230,7 @@
SLOOKUP_INIT(sl, name, clmp, clmp, ld_entry_cnt, elf_hash(name),
0, 0, 0, LKUP_SYMNDX);
SRESULT_INIT(sr, name);
-
- if (THIS_IS_ELF(clmp) && SYMINTP(clmp)(&sl, &sr, &binfo, NULL)) {
- sym = sr.sr_sym;
-
- sl.sl_rsymndx = (((ulong_t)sym -
- (ulong_t)SYMTAB(clmp)) / SYMENT(clmp));
- sl.sl_rsym = sym;
- }
+ sym = sym_lookup_in_caller(clmp, &sl, &sr, &binfo);
SRESULT_INIT(sr, name);
@@ -1238,9 +1246,10 @@
DBG_DLSYM_SINGLETON));
sl.sl_imap = hlmp;
- sl.sl_flags = LKUP_SPEC;
if (handle == RTLD_PROBE)
- sl.sl_flags |= LKUP_NOFALLBACK;
+ sl.sl_flags = LKUP_NOFALLBACK;
+ else
+ sl.sl_flags = LKUP_SPEC;
ret = LM_LOOKUP_SYM(clmp)(&sl, &sr, &binfo, in_nfavl);
} else if (handle == RTLD_NEXT) {
@@ -1272,7 +1281,7 @@
}
/*
- * If the handle is RTLD_NEXT start searching in the next link
+ * If the handle is RTLD_NEXT, start searching in the next link
* map from the callers. Determine permissions from the
* present link map. Indicate to lookup_sym() that we're on an
* RTLD_NEXT request so that it will use the callers link map to
@@ -1331,7 +1340,7 @@
DBG_DLSYM_PROBE));
sl.sl_imap = hlmp;
- sl.sl_flags = (LKUP_SPEC | LKUP_NOFALLBACK);
+ sl.sl_flags = LKUP_NOFALLBACK;
ret = LM_LOOKUP_SYM(clmp)(&sl, &sr, &binfo, in_nfavl);
} else {
@@ -1731,6 +1740,31 @@
}
/*
+ * Set a new deferred dependency name.
+ */
+static int
+set_def_need(Lm_list *lml, Dyninfo *dyip, const char *name)
+{
+ /*
+ * If this dependency has already been established, then this dlinfo()
+ * call is too late.
+ */
+ if (dyip->di_info) {
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_DEF_DEPLOADED),
+ dyip->di_name);
+ return (-1);
+ }
+
+ /*
+ * Assign the new dependency name.
+ */
+ DBG_CALL(Dbg_file_deferred(lml, dyip->di_name, name));
+ dyip->di_flags |= FLG_DI_DEF_DONE;
+ dyip->di_name = name;
+ return (0);
+}
+
+/*
* Extract information for a dlopen() handle.
*/
static int
@@ -1947,7 +1981,7 @@
*/
(void) strcpy(strs, pdp->pd_pname);
path->dls_name = strs;
- path->dls_flags = pdp->pd_flags;
+ path->dls_flags = (pdp->pd_flags & LA_SER_MASK);
strs = strs + _size;
path++;
@@ -2003,6 +2037,119 @@
return (0);
}
+ /*
+ * Assign a new dependency name to a deferred dependency.
+ */
+ if ((request == RTLD_DI_DEFERRED) ||
+ (request == RTLD_DI_DEFERRED_SYM)) {
+ Dl_definfo_t *dfip = (Dl_definfo_t *)p;
+ Dyninfo *dyip;
+ const char *dname, *rname;
+
+ /*
+ * Verify the names.
+ */
+ if ((dfip->dld_refname == NULL) ||
+ (dfip->dld_depname == NULL)) {
+ eprintf(LIST(clmp), ERR_FATAL,
+ MSG_INTL(MSG_ARG_ILLNAME));
+ return (-1);
+ }
+
+ dname = dfip->dld_depname;
+ rname = dfip->dld_refname;
+
+ /*
+ * A deferred dependency can be determined by referencing a
+ * symbol family member that is associated to the dependency,
+ * or by looking for the dependency by its name.
+ */
+ if (request == RTLD_DI_DEFERRED_SYM) {
+ Slookup sl;
+ Sresult sr;
+ uint_t binfo;
+ Syminfo *sip;
+
+ /*
+ * Lookup the symbol in the associated object.
+ */
+ SLOOKUP_INIT(sl, rname, lmp, lmp, ld_entry_cnt,
+ elf_hash(rname), 0, 0, 0, LKUP_SYMNDX);
+ SRESULT_INIT(sr, rname);
+ if (sym_lookup_in_caller(clmp, &sl, &sr,
+ &binfo) == NULL) {
+ eprintf(LIST(clmp), ERR_FATAL,
+ MSG_INTL(MSG_DEF_NOSYMFOUND), rname);
+ return (-1);
+ }
+
+ /*
+ * Use the symbols index to reference the Syminfo entry
+ * and thus find the associated dependency.
+ */
+ if (sl.sl_rsymndx && ((sip = SYMINFO(clmp)) != NULL)) {
+ /* LINTED */
+ sip = (Syminfo *)((char *)sip +
+ (sl.sl_rsymndx * SYMINENT(lmp)));
+
+ if ((sip->si_flags & SYMINFO_FLG_DEFERRED) &&
+ (sip->si_boundto < SYMINFO_BT_LOWRESERVE) &&
+ ((dyip = DYNINFO(lmp)) != NULL)) {
+ dyip += sip->si_boundto;
+
+ if (!(dyip->di_flags & FLG_DI_IGNORE))
+ return (set_def_need(lml,
+ dyip, dname));
+ }
+ }
+
+ /*
+ * No deferred symbol found.
+ */
+ eprintf(LIST(clmp), ERR_FATAL,
+ MSG_INTL(MSG_DEF_NOSYMFOUND), rname);
+ return (-1);
+
+ } else {
+ Dyn *dyn;
+
+ /*
+ * Using the target objects dependency information, find
+ * the associated deferred dependency.
+ */
+ for (dyn = DYN(lmp), dyip = DYNINFO(lmp);
+ !(dyip->di_flags & FLG_DI_IGNORE); dyn++, dyip++) {
+ const char *oname;
+
+ if ((dyip->di_flags & FLG_DI_DEFERRED) == 0)
+ continue;
+
+ if (strcmp(rname, dyip->di_name) == 0)
+ return (set_def_need(lml, dyip, dname));
+
+ /*
+ * If this dependency name has been changed by
+ * a previous dlinfo(), check the original
+ * dynamic entry string. The user might be
+ * attempting to re-change an entry using the
+ * original name as the reference.
+ */
+ if ((dyip->di_flags & FLG_DI_DEF_DONE) == 0)
+ continue;
+
+ oname = STRTAB(lmp) + dyn->d_un.d_val;
+ if (strcmp(rname, oname) == 0)
+ return (set_def_need(lml, dyip, dname));
+ }
+
+ /*
+ * No deferred dependency found.
+ */
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_DEF_NODEPFOUND),
+ rname);
+ return (-1);
+ }
+ }
return (0);
}
@@ -2028,7 +2175,6 @@
return (error);
}
-
/*
* GNU defined function to iterate through the program headers for all
* currently loaded dynamic objects. The caller supplies a callback function
--- a/usr/src/cmd/sgs/rtld/common/elf.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/elf.c Wed May 19 22:33:49 2010 -0700
@@ -20,13 +20,10 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
+ *
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -45,7 +42,8 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
+#include "_inline_reloc.h"
#include "msg.h"
/*
@@ -173,7 +171,7 @@
Dyn *dyn = NULL;
char *str = NULL;
Addr base;
- int cnt;
+ uint_t cnt, dyncnt;
/*
* If this is a shared object, the base address of the shared object is
@@ -191,6 +189,7 @@
if (phdr->p_type == PT_DYNAMIC) {
/* LINTED */
dyn = (Dyn *)((uintptr_t)phdr->p_vaddr + base);
+ dyncnt = phdr->p_filesz / sizeof (Dyn);
} else if (phdr->p_type == PT_SUNWCAP) {
/* LINTED */
cap = (Cap *)((uintptr_t)phdr->p_vaddr + base);
@@ -203,14 +202,14 @@
* table. Required for CA_SUNW_MACH and CA_SUNW_PLAT
* processing.
*/
- while (dyn) {
+ while (dyn && dyncnt) {
if (dyn->d_tag == DT_NULL) {
break;
} else if (dyn->d_tag == DT_STRTAB) {
str = (char *)(dyn->d_un.d_ptr + base);
break;
}
- dyn++;
+ dyn++, dyncnt--;
}
}
@@ -311,9 +310,10 @@
* to perform plt relocation on ld.so.1's link-map. The first time lazy loading
* is called we get here to perform these initializations:
*
- * - elf_needed() is called to set up the DYNINFO() indexes for each lazy
- * dependency. Typically, for all other objects, this is called during
- * analyze_so(), but as ld.so.1 is set-contained we skip this processing.
+ * - elf_needed() is called to establish any ld.so.1 dependencies. These
+ * dependencies should all be lazy loaded, so this routine is typically a
+ * no-op. However, we call elf_needed() for completeness, in case any
+ * NEEDED initialization is required.
*
* - For intel, ld.so.1's JMPSLOT relocations need relative updates. These
* are by default skipped thus delaying all relative relocation processing
@@ -328,10 +328,6 @@
if (lml->lm_flags & LML_FLG_PLTREL)
return (1);
- /*
- * As we need to refer to the DYNINFO() information, insure that it has
- * been initialized.
- */
if (elf_needed(lml, ALIST_OFF_DATA, lmp, NULL) == 0)
return (0);
@@ -349,9 +345,8 @@
*/
(void) elf_reloc_relative_count((ulong_t)JMPREL(lmp),
(ulong_t)(PLTRELSZ(lmp) / RELENT(lmp)), (ulong_t)RELENT(lmp),
- (ulong_t)ADDR(lmp), lmp, NULL);
+ (ulong_t)ADDR(lmp), lmp, NULL, 0);
#endif
-
lml->lm_flags |= LML_FLG_PLTREL;
return (1);
}
@@ -371,10 +366,11 @@
Aliste lmco;
/*
- * If this dependency has already been processed, we're done.
+ * If this dependency should be ignored, or has already been processed,
+ * we're done.
*/
if (((nlmp = (Rt_map *)dip->di_info) != NULL) ||
- (dip->di_flags & FLG_DI_LDD_DONE))
+ (dip->di_flags & (FLG_DI_IGNORE | FLG_DI_LDD_DONE)))
return (nlmp);
/*
@@ -391,7 +387,7 @@
/*
* Determine the initial dependency name.
*/
- name = STRTAB(clmp) + DYN(clmp)[ndx].d_un.d_val;
+ name = dip->di_name;
DBG_CALL(Dbg_file_lazyload(clmp, name, sym));
/*
@@ -632,104 +628,71 @@
elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp, int *in_nfavl)
{
Alist *palp = NULL;
- Dyn *dyn, *pdyn;
- ulong_t ndx = 0;
- uint_t lazy, flags;
+ Dyn *dyn;
+ Dyninfo *dip;
Word lmflags = lml->lm_flags;
- Word lmtflags = lml->lm_tflags;
/*
- * Process each shared object on needed list.
+ * A DYNINFO() structure is created during link-map generation that
+ * parallels the DYN() information, and defines any flags that
+ * influence a dependencies loading.
*/
- if (DYN(clmp) == NULL)
- return (1);
+ for (dyn = DYN(clmp), dip = DYNINFO(clmp);
+ !(dip->di_flags & FLG_DI_IGNORE); dyn++, dip++) {
+ uint_t flags = 0, silent = 0;
+ const char *name = dip->di_name;
+ Rt_map *nlmp = NULL;
- for (dyn = (Dyn *)DYN(clmp), pdyn = NULL; dyn->d_tag != DT_NULL;
- pdyn = dyn++, ndx++) {
- Dyninfo *dip = &DYNINFO(clmp)[ndx];
- Rt_map *nlmp = NULL;
- char *name;
- int silent = 0;
+ if ((dip->di_flags & FLG_DI_NEEDED) == 0)
+ continue;
- switch (dyn->d_tag) {
- case DT_POSFLAG_1:
- dip->di_flags |= FLG_DI_POSFLAG1;
+ /*
+ * Skip any deferred dependencies, unless ldd(1) has forced
+ * their processing. By default, deferred dependencies are
+ * only processed when an explicit binding to an individual
+ * deferred reference is made.
+ */
+ if ((dip->di_flags & FLG_DI_DEFERRED) &&
+ ((rtld_flags & RT_FL_DEFERRED) == 0))
continue;
- case DT_NEEDED:
- case DT_USED:
- lazy = flags = 0;
- dip->di_flags |= FLG_DI_NEEDED;
+
+ /*
+ * NOTE, libc.so.1 can't be lazy loaded. Although a lazy
+ * position flag won't be produced when a RTLDINFO .dynamic
+ * entry is found (introduced with the UPM in Solaris 10), it
+ * was possible to mark libc for lazy loading on previous
+ * releases. To reduce the overhead of testing for this
+ * occurrence, only carry out this check for the first object
+ * on the link-map list (there aren't many applications built
+ * without libc).
+ */
+ if ((dip->di_flags & FLG_DI_LAZY) && (lml->lm_head == clmp) &&
+ (strcmp(name, MSG_ORIG(MSG_FIL_LIBC)) == 0))
+ dip->di_flags &= ~FLG_DI_LAZY;
- if (pdyn && (pdyn->d_tag == DT_POSFLAG_1)) {
- if ((pdyn->d_un.d_val & DF_P1_LAZYLOAD) &&
- ((lmtflags & LML_TFLG_NOLAZYLD) == 0)) {
- dip->di_flags |= FLG_DI_LAZY;
- lazy = 1;
- }
- if (pdyn->d_un.d_val & DF_P1_GROUPPERM) {
- dip->di_flags |= FLG_DI_GROUP;
- flags =
- (FLG_RT_SETGROUP | FLG_RT_PUBHDL);
- }
+ /*
+ * Don't bring in lazy loaded objects yet unless we've been
+ * asked to attempt to load all available objects (crle(1) sets
+ * LD_FLAGS=loadavail). Even under RTLD_NOW we don't process
+ * this - RTLD_NOW will cause relocation processing which in
+ * turn might trigger lazy loading, but its possible that the
+ * object has a lazy loaded file with no bindings (i.e., it
+ * should never have been a dependency in the first place).
+ */
+ if (dip->di_flags & FLG_DI_LAZY) {
+ if ((lmflags & LML_FLG_LOADAVAIL) == 0) {
+ LAZY(clmp)++;
+ continue;
}
- name = (char *)STRTAB(clmp) + dyn->d_un.d_val;
-
/*
- * NOTE, libc.so.1 can't be lazy loaded. Although a
- * lazy position flag won't be produced when a RTLDINFO
- * .dynamic entry is found (introduced with the UPM in
- * Solaris 10), it was possible to mark libc for lazy
- * loading on previous releases. To reduce the overhead
- * of testing for this occurrence, only carry out this
- * check for the first object on the link-map list
- * (there aren't many applications built without libc).
- */
- if (lazy && (lml->lm_head == clmp) &&
- (strcmp(name, MSG_ORIG(MSG_FIL_LIBC)) == 0))
- lazy = 0;
-
- /*
- * Don't bring in lazy loaded objects yet unless we've
- * been asked to attempt to load all available objects
- * (crle(1) sets LD_FLAGS=loadavail). Even under
- * RTLD_NOW we don't process this - RTLD_NOW will cause
- * relocation processing which in turn might trigger
- * lazy loading, but its possible that the object has a
- * lazy loaded file with no bindings (i.e., it should
- * never have been a dependency in the first place).
+ * Silence any error messages - see description under
+ * elf_lookup_filtee().
*/
- if (lazy) {
- if ((lmflags & LML_FLG_LOADAVAIL) == 0) {
- LAZY(clmp)++;
- lazy = flags = 0;
- continue;
- }
-
- /*
- * Silence any error messages - see description
- * under elf_lookup_filtee().
- */
- if ((rtld_flags & RT_FL_SILENCERR) == 0) {
- rtld_flags |= RT_FL_SILENCERR;
- silent = 1;
- }
+ if ((rtld_flags & RT_FL_SILENCERR) == 0) {
+ rtld_flags |= RT_FL_SILENCERR;
+ silent = 1;
}
- break;
- case DT_AUXILIARY:
- dip->di_flags |= FLG_DI_AUXFLTR;
- continue;
- case DT_SUNW_AUXILIARY:
- dip->di_flags |= (FLG_DI_AUXFLTR | FLG_DI_SYMFLTR);
- continue;
- case DT_FILTER:
- dip->di_flags |= FLG_DI_STDFLTR;
- continue;
- case DT_SUNW_FILTER:
- dip->di_flags |= (FLG_DI_STDFLTR | FLG_DI_SYMFLTR);
- continue;
- default:
- continue;
}
DBG_CALL(Dbg_file_needed(clmp, name));
@@ -746,6 +709,12 @@
dip->di_flags |= FLG_DI_LDD_DONE;
/*
+ * Identify any group permission requirements.
+ */
+ if (dip->di_flags & FLG_DI_GROUP)
+ flags = (FLG_RT_SETGROUP | FLG_RT_PUBHDL);
+
+ /*
* Establish the objects name, load it and establish a binding
* with the caller.
*/
@@ -889,7 +858,7 @@
* defined. Otherwise, process the filtee reference. Any token
* expansion is also completed at this point (i.e., $PLATFORM).
*/
- filtees = (char *)STRTAB(ilmp) + DYN(ilmp)[ndx].d_un.d_val;
+ filtees = dip->di_name;
if (dip->di_info == NULL) {
if (rtld_flags2 & RT_FL2_FLTCFG) {
elf_config_flt(lml, PATHNAME(ilmp), filtees,
@@ -1777,13 +1746,67 @@
* dynamic structure.
*/
if (dyn) {
- uint_t dynndx = 0;
+ Dyninfo *dip;
+ uint_t dynndx;
Xword pltpadsz = 0;
Rti_desc *rti;
+ Dyn *pdyn;
+ Word lmtflags = lml->lm_tflags;
+ int ignore = 0;
- /* CSTYLED */
- for ( ; dyn->d_tag != DT_NULL; ++dyn, dynndx++) {
+ /*
+ * Note, we use DT_NULL to terminate processing, and the
+ * dynamic entry count as a fall back. Normally, a DT_NULL
+ * entry marks the end of the dynamic section. Any non-NULL
+ * items following the first DT_NULL are silently ignored.
+ * This situation should only occur through use of elfedit(1)
+ * or a similar tool.
+ */
+ for (dynndx = 0, pdyn = NULL, dip = DYNINFO(lmp);
+ dynndx < dyncnt; dynndx++, pdyn = dyn++, dip++) {
+
+ if (ignore) {
+ dip->di_flags |= FLG_DI_IGNORE;
+ continue;
+ }
+
switch ((Xword)dyn->d_tag) {
+ case DT_NULL:
+ dip->di_flags |= ignore = FLG_DI_IGNORE;
+ break;
+ case DT_POSFLAG_1:
+ dip->di_flags |= FLG_DI_POSFLAG1;
+ break;
+ case DT_NEEDED:
+ case DT_USED:
+ dip->di_flags |= FLG_DI_NEEDED;
+
+ /* BEGIN CSTYLED */
+ if (pdyn && (pdyn->d_tag == DT_POSFLAG_1)) {
+ /*
+ * Identify any non-deferred lazy load for
+ * future processing, unless LD_NOLAZYLOAD
+ * has been set.
+ */
+ if ((pdyn->d_un.d_val & DF_P1_LAZYLOAD) &&
+ ((lmtflags & LML_TFLG_NOLAZYLD) == 0))
+ dip->di_flags |= FLG_DI_LAZY;
+
+ /*
+ * Identify any group permission
+ * requirements.
+ */
+ if (pdyn->d_un.d_val & DF_P1_GROUPPERM)
+ dip->di_flags |= FLG_DI_GROUP;
+
+ /*
+ * Identify any deferred dependencies.
+ */
+ if (pdyn->d_un.d_val & DF_P1_DEFERRED)
+ dip->di_flags |= FLG_DI_DEFERRED;
+ }
+ /* END CSTYLED */
+ break;
case DT_SYMTAB:
SYMTAB(lmp) = (void *)(dyn->d_un.d_ptr + base);
break;
@@ -1886,11 +1909,13 @@
rpath = dyn->d_un.d_val;
break;
case DT_FILTER:
+ dip->di_flags |= FLG_DI_STDFLTR;
fltr = dyn->d_un.d_val;
OBJFLTRNDX(lmp) = dynndx;
FLAGS1(lmp) |= FL1_RT_OBJSFLTR;
break;
case DT_AUXILIARY:
+ dip->di_flags |= FLG_DI_AUXFLTR;
if (!(rtld_flags & RT_FL_NOAUXFLTR)) {
fltr = dyn->d_un.d_val;
OBJFLTRNDX(lmp) = dynndx;
@@ -1898,10 +1923,14 @@
FLAGS1(lmp) |= FL1_RT_OBJAFLTR;
break;
case DT_SUNW_FILTER:
+ dip->di_flags |=
+ (FLG_DI_STDFLTR | FLG_DI_SYMFLTR);
SYMSFLTRCNT(lmp)++;
FLAGS1(lmp) |= FL1_RT_SYMSFLTR;
break;
case DT_SUNW_AUXILIARY:
+ dip->di_flags |=
+ (FLG_DI_AUXFLTR | FLG_DI_SYMFLTR);
if (!(rtld_flags & RT_FL_NOAUXFLTR)) {
SYMAFLTRCNT(lmp)++;
}
@@ -2105,6 +2134,7 @@
break;
case DT_DEPRECATED_SPARC_REGISTER:
case M_DT_REGISTER:
+ dip->di_flags |= FLG_DI_REGISTER;
FLAGS(lmp) |= FLG_RT_REGSYMS;
break;
case DT_SUNW_CAP:
@@ -2126,6 +2156,28 @@
}
}
+ /*
+ * Update any Dyninfo string pointers now that STRTAB() is
+ * known.
+ */
+ for (dynndx = 0, dyn = DYN(lmp), dip = DYNINFO(lmp);
+ !(dip->di_flags & FLG_DI_IGNORE); dyn++, dip++) {
+
+ switch ((Xword)dyn->d_tag) {
+ case DT_NEEDED:
+ case DT_USED:
+ case DT_FILTER:
+ case DT_AUXILIARY:
+ case DT_SUNW_FILTER:
+ case DT_SUNW_AUXILIARY:
+ dip->di_name = STRTAB(lmp) + dyn->d_un.d_val;
+ break;
+ }
+ }
+
+ /*
+ * Assign any padding.
+ */
if (PLTPAD(lmp)) {
if (pltpadsz == (Xword)0)
PLTPAD(lmp) = NULL;
@@ -2199,7 +2251,7 @@
RELENT(lmp) = sizeof (M_RELOC);
/*
- * Establish any per-object auditing. If we're establishing `main's
+ * Establish any per-object auditing. If we're establishing main's
* link-map its too early to go searching for audit objects so just
* hold the object name for later (see setup()).
*/
@@ -2667,7 +2719,7 @@
return (NULL);
for (APLIST_TRAVERSE(alist, idx1, lmp1)) {
- uint_t cnt = 0;
+ uint_t dynndx;
Dyninfo *dip, *pdip;
/*
@@ -2677,8 +2729,8 @@
* objects lazy DT_NEEDED entries can be examined.
*/
lmp = lmp1;
- for (dip = DYNINFO(lmp), pdip = NULL; cnt < DYNINFOCNT(lmp);
- cnt++, pdip = dip++) {
+ for (dynndx = 0, dip = DYNINFO(lmp), pdip = NULL;
+ !(dip->di_flags & FLG_DI_IGNORE); dynndx++, pdip = dip++) {
Grp_hdl *ghp;
Grp_desc *gdp;
Rt_map *nlmp, *llmp;
@@ -2743,7 +2795,7 @@
* either case, the handle associated with the object
* is then used to carry out the symbol search.
*/
- if ((nlmp = elf_lazy_load(lmp, &sl1, cnt, name,
+ if ((nlmp = elf_lazy_load(lmp, &sl1, dynndx, name,
FLG_RT_PRIHDL, &ghp, in_nfavl)) == NULL)
continue;
@@ -2957,94 +3009,3 @@
return (0);
}
-
-/*
- * Generic relative relocation function.
- */
-inline static ulong_t
-_elf_reloc_relative(ulong_t rbgn, ulong_t base, Rt_map *lmp, APlist **textrel)
-{
- mmapobj_result_t *mpp;
- ulong_t roffset;
-
- roffset = ((M_RELOC *)rbgn)->r_offset;
- roffset += base;
-
- /*
- * If this relocation is against an address that is not associated with
- * a mapped segment, fall back to the generic relocation loop to
- * collect the associated error.
- */
- if ((mpp = find_segment((caddr_t)roffset, lmp)) == NULL)
- return (0);
-
- /*
- * If this relocation is against a segment that does not provide write
- * access, set the write permission for all non-writable mappings.
- */
- if (((mpp->mr_prot & PROT_WRITE) == 0) && textrel &&
- ((set_prot(lmp, mpp, 1) == 0) ||
- (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
- return (0);
-
- /*
- * Perform the actual relocation. Note, for backward compatibility,
- * SPARC relocations are added to the offset contents (there was a time
- * when the offset was used to contain the addend, rather than using
- * the addend itself).
- */
-#if defined(__sparc)
- *((ulong_t *)roffset) += base + ((M_RELOC *)rbgn)->r_addend;
-#elif defined(__amd64)
- *((ulong_t *)roffset) = base + ((M_RELOC *)rbgn)->r_addend;
-#else
- *((ulong_t *)roffset) += base;
-#endif
- return (1);
-}
-
-/*
- * When a generic relocation loop realizes that it's dealing with relative
- * relocations, but no DT_RELCOUNT .dynamic tag is present, this tighter loop
- * is entered as an optimization.
- */
-ulong_t
-elf_reloc_relative(ulong_t rbgn, ulong_t rend, ulong_t rsize, ulong_t base,
- Rt_map *lmp, APlist **textrel)
-{
- char rtype;
-
- do {
- if (_elf_reloc_relative(rbgn, base, lmp, textrel) == 0)
- break;
-
- rbgn += rsize;
- if (rbgn >= rend)
- break;
-
- /*
- * Make sure the next type is a relative relocation.
- */
- rtype = ELF_R_TYPE(((M_RELOC *)rbgn)->r_info, M_MACH);
-
- } while (rtype == M_R_RELATIVE);
-
- return (rbgn);
-}
-
-/*
- * This is the tightest loop for RELATIVE relocations for those objects built
- * with the DT_RELACOUNT .dynamic entry.
- */
-ulong_t
-elf_reloc_relative_count(ulong_t rbgn, ulong_t rcount, ulong_t rsize,
- ulong_t base, Rt_map *lmp, APlist **textrel)
-{
- for (; rcount; rcount--) {
- if (_elf_reloc_relative(rbgn, base, lmp, textrel) == 0)
- break;
-
- rbgn += rsize;
- }
- return (rbgn);
-}
--- a/usr/src/cmd/sgs/rtld/common/move.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/move.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -37,7 +36,7 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
#include "msg.h"
/*
--- a/usr/src/cmd/sgs/rtld/common/rtld.msg Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/rtld.msg Wed May 19 22:33:49 2010 -0700
@@ -50,6 +50,7 @@
@ MSG_ARG_ILLPATH "illegal pathname"
@ MSG_ARG_ILLSYM "illegal symbol name"
+@ MSG_ARG_ILLNAME "illegal name"
@ MSG_ARG_INVADDR "address 0x%llx does not fall within any mapped object"
@ MSG_ARG_INVHNDL "invalid handle: 0x%llx"
@ MSG_ARG_ILLVAL "illegal request value"
@@ -62,7 +63,6 @@
@ MSG_ARG_ILLINFO "non-null info field required for flags value: %d"
@ MSG_ARG_INVSIG "invalid signal supplied: %d"
-
# General error diagnostics
@ MSG_GEN_NOOPEN "DF_1_NOOPEN tagged object may not be dlopen()'ed"
@@ -245,6 +245,12 @@
@ MSG_ERR_EXPAND1 "%s: %s: path name too long"
@ MSG_ERR_EXPAND2 "%s: %s: token %s could not be expanded"
+# Specific dlinfo() messages.
+
+@ MSG_DEF_NODEPFOUND "%s: no deferred dependency found"
+@ MSG_DEF_NOSYMFOUND "%s: no deferred symbol found"
+@ MSG_DEF_DEPLOADED "%s: deferred dependency is already loaded"
+
# Error diagnostic standard prefixes.
@ MSG_ERR_WARNING "warning: "
@@ -391,6 +397,7 @@
@ MSG_LD_UNREF "UNREF"
@ MSG_LD_UNUSED "UNUSED"
@ MSG_LD_VERBOSE "VERBOSE"
+@ MSG_LD_DEFERRED "DEFERRED"
@ MSG_LD_WARN "WARN"
@ MSG_LD_BRAND_PREFIX "BRAND_"
--- a/usr/src/cmd/sgs/rtld/common/util.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/util.c Wed May 19 22:33:49 2010 -0700
@@ -20,13 +20,10 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
+ *
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -1468,6 +1465,7 @@
#define ENV_FLG_MACHCAP 0x0020000000000ULL
#define ENV_FLG_PLATCAP 0x0040000000000ULL
#define ENV_FLG_CAP_FILES 0x0080000000000ULL
+#define ENV_FLG_DEFERRED 0x0100000000000ULL
#define SEL_REPLACE 0x0001
#define SEL_PERMANT 0x0002
@@ -1603,7 +1601,8 @@
}
}
/*
- * The LD_DEBUG family and LD_DEMANGLE.
+ * The LD_DEBUG family, LD_DEFERRED (internal, used by ldd(1)), and
+ * LD_DEMANGLE.
*/
else if (*s1 == 'D') {
if ((len == MSG_LD_DEBUG_SIZE) && (strncmp(s1,
@@ -1617,6 +1616,11 @@
select |= SEL_ACT_STR;
str = &dbg_file;
variable = ENV_FLG_DEBUG_OUTPUT;
+ } else if ((len == MSG_LD_DEFERRED_SIZE) && (strncmp(s1,
+ MSG_ORIG(MSG_LD_DEFERRED), MSG_LD_DEFERRED_SIZE) == 0)) {
+ select |= SEL_ACT_RT;
+ val = RT_FL_DEFERRED;
+ variable = ENV_FLG_DEFERRED;
} else if ((len == MSG_LD_DEMANGLE_SIZE) && (strncmp(s1,
MSG_ORIG(MSG_LD_DEMANGLE), MSG_LD_DEMANGLE_SIZE) == 0)) {
select |= SEL_ACT_RT;
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c Wed May 19 22:33:49 2010 -0700
@@ -20,13 +20,10 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
+ *
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -47,7 +44,8 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
+#include "_inline_reloc.h"
#include "msg.h"
extern void elf_rtbndr(Rt_map *, ulong_t, caddr_t);
@@ -365,6 +363,7 @@
uchar_t rtype;
long value, pvalue;
Sym *symref, *psymref, *symdef, *psymdef;
+ Syminfo *sip;
char *name, *pname;
Rt_map *_lmp, *plmp;
int ret = 1, noplt = 0;
@@ -488,6 +487,7 @@
(FLAGS(lmp) & FLG_RT_FIXED))
noplt = 1;
+ sip = SYMINFO(lmp);
/*
* Loop through relocations.
*/
@@ -506,11 +506,12 @@
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
if (relacount) {
relbgn = elf_reloc_relative_count(relbgn,
- relacount, relsiz, basebgn, lmp, textrel);
+ relacount, relsiz, basebgn, lmp,
+ textrel, 0);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, lmp, textrel);
+ relsiz, basebgn, lmp, textrel, 0);
}
if (relbgn >= relend)
break;
@@ -532,7 +533,7 @@
(rtype == R_386_JMP_SLOT) &&
((MODE(lmp) & RTLD_NOW) == 0)) {
relbgn = elf_reloc_relative_count(relbgn,
- plthint, relsiz, basebgn, lmp, textrel);
+ plthint, relsiz, basebgn, lmp, textrel, 0);
plthint = 0;
continue;
}
@@ -580,6 +581,14 @@
*/
if (rsymndx) {
/*
+ * If a Syminfo section is provided, determine if this
+ * symbol is deferred, and if so, skip this relocation.
+ */
+ if (sip && is_sym_deferred((ulong_t)rel, basebgn, lmp,
+ textrel, sip, rsymndx))
+ continue;
+
+ /*
* Get the local symbol table entry.
*/
symref = (Sym *)((ulong_t)SYMTAB(lmp) +
--- a/usr/src/cmd/sgs/rtld/sparc/common_sparc.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/sparc/common_sparc.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdio.h>
@@ -93,6 +92,7 @@
elf_regsyms(Rt_map *lmp)
{
Dyn *dyn;
+ Dyninfo *dip;
Sym *symdef;
ulong_t rsymndx;
@@ -102,11 +102,11 @@
* register symbol it identifies and confirm that it doesn't conflict
* with any other register symbols.
*/
- for (dyn = DYN(lmp); dyn->d_tag != DT_NULL; dyn++) {
+ for (dyn = DYN(lmp), dip = DYNINFO(lmp);
+ !(dip->di_flags & FLG_DI_IGNORE); dyn++, dip++) {
Reglist *rp;
- if ((dyn->d_tag != DT_SPARC_REGISTER) &&
- (dyn->d_tag != DT_DEPRECATED_SPARC_REGISTER))
+ if ((dip->di_flags & FLG_DI_REGISTER) == 0)
continue;
/*
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c Wed May 19 22:33:49 2010 -0700
@@ -20,13 +20,10 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
+ *
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -43,7 +40,7 @@
#include "_a.out.h"
#include "_rtld.h"
#include "_audit.h"
-#include "_inline.h"
+#include "_inline_gen.h"
#include "msg.h"
extern void iflush_range(caddr_t, size_t);
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c Wed May 19 22:33:49 2010 -0700
@@ -20,13 +20,10 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
+ *
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -47,7 +44,8 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
+#include "_inline_reloc.h"
#include "msg.h"
extern void iflush_range(caddr_t, size_t);
@@ -539,6 +537,7 @@
uchar_t rtype;
long reladd, value, pvalue, relacount = RELACOUNT(lmp);
Sym *symref, *psymref, *symdef, *psymdef;
+ Syminfo *sip;
char *name, *pname;
Rt_map *_lmp, *plmp;
int ret = 1, noplt = 0;
@@ -638,6 +637,7 @@
if (pltbgn && ((MODE(lmp) & RTLD_NOW) == 0))
noplt = 1;
+ sip = SYMINFO(lmp);
/*
* Loop through relocations.
*/
@@ -657,11 +657,12 @@
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
if (relacount) {
relbgn = elf_reloc_relative_count(relbgn,
- relacount, relsiz, basebgn, lmp, textrel);
+ relacount, relsiz, basebgn, lmp,
+ textrel, 0);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, lmp, textrel);
+ relsiz, basebgn, lmp, textrel, 0);
}
if (relbgn >= relend)
break;
@@ -672,7 +673,6 @@
reladd = (long)(((Rela *)relbgn)->r_addend);
rsymndx = ELF_R_SYM(((Rela *)relbgn)->r_info);
-
rel = (Rela *)relbgn;
relbgn += relsiz;
@@ -736,6 +736,14 @@
*/
if (rsymndx) {
/*
+ * If a Syminfo section is provided, determine if this
+ * symbol is deferred, and if so, skip this relocation.
+ */
+ if (sip && is_sym_deferred((ulong_t)rel, basebgn, lmp,
+ textrel, sip, rsymndx))
+ continue;
+
+ /*
* Get the local symbol table entry.
*/
symref = (Sym *)((ulong_t)SYMTAB(lmp) +
--- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c Wed May 19 22:33:49 2010 -0700
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -42,7 +41,8 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
-#include "_inline.h"
+#include "_inline_gen.h"
+#include "_inline_reloc.h"
#include "msg.h"
extern void iflush_range(caddr_t, size_t);
@@ -740,10 +740,11 @@
ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend;
ulong_t pltndx, roffset, rsymndx, psymndx = 0;
uint_t dsymndx, binfo, pbinfo;
- Byte rtype;
+ uchar_t rtype;
long reladd;
Addr value, pvalue;
Sym *symref, *psymref, *symdef, *psymdef;
+ Syminfo *sip;
char *name, *pname;
Rt_map *_lmp, *plmp;
int ret = 1, noplt = 0;
@@ -864,6 +865,7 @@
if (pltbgn && ((MODE(lmp) & RTLD_NOW) == 0))
noplt = 1;
+ sip = SYMINFO(lmp);
/*
* Loop through relocations.
*/
@@ -872,7 +874,7 @@
uint_t sb_flags = 0;
Addr vaddr;
- rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
+ rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
/*
* If this is a RELATIVE relocation in a shared object
@@ -885,23 +887,22 @@
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
if (relacount) {
relbgn = elf_reloc_relative_count(relbgn,
- relacount, relsiz, basebgn, lmp, textrel);
+ relacount, relsiz, basebgn, lmp,
+ textrel, 0);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, lmp, textrel);
+ relsiz, basebgn, lmp, textrel, 0);
}
if (relbgn >= relend)
break;
- rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info,
- M_MACH);
+ rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
}
roffset = ((Rela *)relbgn)->r_offset;
reladd = (long)(((Rela *)relbgn)->r_addend);
rsymndx = ELF_R_SYM(((Rela *)relbgn)->r_info);
-
rel = (Rela *)relbgn;
relbgn += relsiz;
@@ -962,6 +963,14 @@
*/
if (rsymndx) {
/*
+ * If a Syminfo section is provided, determine if this
+ * symbol is deferred, and if so, skip this relocation.
+ */
+ if (sip && is_sym_deferred((ulong_t)rel, basebgn, lmp,
+ textrel, sip, rsymndx))
+ continue;
+
+ /*
* Get the local symbol table entry.
*/
symref = (Sym *)((ulong_t)SYMTAB(lmp) +
--- a/usr/src/head/dlfcn.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/head/dlfcn.h Wed May 19 22:33:49 2010 -0700
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Copyright (c) 1989 AT&T
* All Rights Reserved
@@ -102,6 +101,11 @@
} Dl_amd64_unwindinfo;
typedef Dl_amd64_unwindinfo Dl_amd64_unwindinfo_t;
+typedef struct {
+ const char *dld_refname; /* reference name */
+ const char *dld_depname; /* new dependency name */
+} Dl_definfo_t;
+
#endif /* !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__) */
@@ -214,19 +218,24 @@
#define RTLD_DI_LINKMAP 2 /* obtain link-map */
#define RTLD_DI_CONFIGADDR 3 /* obtain config addr */
#define RTLD_DI_SERINFO 4 /* obtain search path info or */
-#define RTLD_DI_SERINFOSIZE 5 /* associated info size */
+#define RTLD_DI_SERINFOSIZE 5 /* associated info size */
#define RTLD_DI_ORIGIN 6 /* obtain objects origin */
#define RTLD_DI_PROFILENAME 7 /* obtain profile object name */
- /* internal use only */
+ /* internal use only */
#define RTLD_DI_PROFILEOUT 8 /* obtain profile output name */
- /* internal use only */
+ /* internal use only */
#define RTLD_DI_GETSIGNAL 9 /* get termination signal */
#define RTLD_DI_SETSIGNAL 10 /* set termination signal */
#define RTLD_DI_ARGSINFO 11 /* get process arguments */
- /* environment and auxv */
+ /* environment and auxv */
#define RTLD_DI_MMAPS 12 /* obtain objects mappings or */
-#define RTLD_DI_MMAPCNT 13 /* mapping count */
-#define RTLD_DI_MAX 13
+#define RTLD_DI_MMAPCNT 13 /* mapping count */
+#define RTLD_DI_DEFERRED 14 /* assign new dependency to a */
+ /* deferred dependency */
+#define RTLD_DI_DEFERRED_SYM 15 /* assign new dependency to a */
+ /* deferred dependency */
+ /* using a symbol name */
+#define RTLD_DI_MAX 15
#if !defined(_XOPEN_SOURCE) || defined(__EXTENSIONS__)
/*
--- a/usr/src/uts/common/sys/link.h Wed May 19 21:10:39 2010 -0700
+++ b/usr/src/uts/common/sys/link.h Wed May 19 22:33:49 2010 -0700
@@ -23,8 +23,7 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SYS_LINK_H
@@ -260,6 +259,8 @@
#define DF_P1_GROUPPERM 0x00000002 /* following object's symbols are */
/* not available for general */
/* symbol bindings. */
+#define DF_P1_DEFERRED 0x00000004 /* following object is deferred */
+
/*
* Values for the DT_FLAGS_1 .dynamic entry.
*/
@@ -472,6 +473,8 @@
/* auxiliary filter */
#define SYMINFO_FLG_INTERPOSE 0x0080 /* symbol defines an interposer */
#define SYMINFO_FLG_CAP 0x0100 /* symbol is capabilities specific */
+#define SYMINFO_FLG_DEFERRED 0x0200 /* symbol should not be included in */
+ /* BIND_NOW relocations */
/*
* Syminfo.si_boundto values.