6686372 ld.so.1 should use mmapobj(2)
6726108 dlopen() performance could be improved.
--- a/usr/src/cmd/sgs/Makefile.com Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/Makefile.com Wed Jan 21 11:00:19 2009 -0800
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
.KEEP_STATE:
.KEEP_STATE_FILE: .make.state.$(MACH)
@@ -33,7 +31,7 @@
SRCBASE = ../../../..
-i386_ARCH = $(VAR_I386_ARCH)
+i386_ARCH = intel
sparc_ARCH = sparc
ARCH = $($(MACH)_ARCH)
--- a/usr/src/cmd/sgs/Makefile.var Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/Makefile.var Wed Jan 21 11:00:19 2009 -0800
@@ -20,83 +20,27 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# The link-editor related source files and Makefile files are normally unified
-# across all presently maintained release gates. However, some of the compiler
-# pre-processor flags, linker flags are different among the releases. This
-# file is used to specify such flags.
+# The link-editor related source files and Makefile files have at times been
+# unified across all presently maintained release gates. However, some of the
+# compiler pre-processor flags and link-editor flags are different among the
+# releases. This file is used to specify such flags.
#
-# This file is included by ./Makefile.com, but may also be included directly
-# in the case where the utility is relying on the contents of
-# ../../Makefile.com.
+# This file is included by ./Makefile.com, but may also be included directly in
+# the case where the utility is relying on the contents of ../../Makefile.com.
#
# This file should be the only file which is different among the presently
-# maintained release workspaces and the files that generate the link-editors
-# and related tools.
-
+# maintained release workspaces, when the sources are unified.
#
# CPPFEATUREMACROS provides for selectively turning on/off features within the
-# build of ld.so.1 and liblddbg.so.
-#
-# Current values for ld.so.1 are:
-#
-# LD_BREADTH_DISABLED
-# per bug id 4313765, the LD_BREADTH= environment variable is no
-# longer checked. However, on older releases we still want to
-# keep this check valid.
-#
-# EXPAND_RELATIVE
-# per bug id 4336980 (and 4336878), relative path expansion is
-# insured at process startup. This implementation can come at
-# some cost unless the corresponding getcwd() implementation from
-# libc_pic.a is also available. On older releases defer any
-# relative pathname expansion until it is required.
+# various link-editor components. Presently, none are set.
#
-# ISSOLOAD_BASENAME_DISABLED
-# The bugfix for bug#4469400 updates the logic by which
-# shared objects are loaded into memory (and makes it
-# more precise). However - this update to logic can
-# mess up the loading of objects which have a dependency
-# on both '/usr/lib/lwp/libthread.so.1' and
-# '/usr/lib/libthread.so.1'. The error that occurs is that
-# both libraries are loaded into memory - which doesn't
-# work out very well. This fix re-enables the `loose'
-# logic which was implemented on older releases to avoid
-# exposing problems with multiple libthreads. Since Soliars9
-# again only has one libthread - we can use the more precise
-# logic.
-#
-# SIEBEL_DISABLE
-# Prior to Solaris 10, bug fixes 4651709 and 4651493 were deter-
-# mined to be inappropriate for patch releases as they broke the
-# Siebel server. Siebel agree to fix their code in preparation
-# for these changes to become default in Solaris 10. Users who
-# want these fixes in patch releases can set LD__FIX__1.
-#
-#
-# Current value for liblddbg.so is:
-#
-# DEMANGLE
-# enable use of the "demangle" debug token. Old versions of the
-# demangle library libdemangle.so.1 used an excessive amount of
-# stack space that could cause debugging a threaded application
-# (with say LD_DEBUG=symbols,demangle) to segv because of an
-# exhausted stack. See 4376081. DEMANGLE should not be enabled
-# for patch builds.
-#
-# Note that demangling support within liblddbg.so.1 is always
-# available, as tools such as elfdump(1) and pvs(1) may call this
-# directly. These tools aren't threaded, and thus don't expose
-# the problems raised by enabling ld.so.1's debugging output.
-#
-#
-# Although most files are unified among on10-gate, on81-patch, and on28-patch
-# gates, some files in libld and rtld need to use #ifdef to distinguish between
-# the patch release, and for the packages targeting to the pre-libc/libthread
-# unified environment. These values are available for CPPFLAGS:
+# Some source files need to use #ifdef to distinguish between the patch release,
+# and for the packages targeting to the pre-libc/libthread unified environment.
+# These values are available for CPPFLAGS:
#
# SGS_PRE_UNIFIED_PROCESS
#
@@ -107,9 +51,7 @@
# Common Macro definitions
#
VAR_CPPFLAGS=
-
VAR_LINTFLAGS64= -m64
-VAR_I386_ARCH= intel
VAR_PLAT_sparc= sparc
VAR_PLAT_i386= intel/ia32
@@ -117,7 +59,6 @@
VAR_POUND_1=
VAR_POUND_2= $(POUND_SIGN)
-VAR_POUND_3= $(POUND_SIGN)
#
# VAR_AVLDIR - directory to find avl.c in.
@@ -169,18 +110,6 @@
VAR_LD_LLDFLAGS64 = '-R$$ORIGIN/../../../lib/$(MACH64)'
#
-# on 5.10 we no longer link against libdl - However we still
-# need to link against it when building the SUNWonld package (which
-# may run on 5.9 or 5.8 systems).
-#
-# Below are two macros - they should be toggled one way or the other
-# depending upon whether or not the base build provides '-ldl' or
-# the build of SUNWonld does.
-#
-VAR_PKG_DL_LIB = -ldl
-VAR_DL_LIB =
-
-#
# elfdump
#
VAR_ELFDUMP_LLDFLAGS= '-R$$ORIGIN/../../lib'
@@ -246,9 +175,6 @@
VAR_RTLD_V9_SONAME= /lib/sparcv9/ld.so.1
VAR_RTLD_ETCDYNLIB=
-VAR_RTLD_CPPFEATUREMACROS= \
- -DLD_BREADTH_DISABLED \
- -DEXPAND_RELATIVE \
- -DISSOLOAD_BASENAME_DISABLED
+VAR_RTLD_CPPFEATUREMACROS=
VAR_RTLD_CPPFLAGS= $(VAR_AVLINCDIR)
VAR_RTLD_EXTRASUBDIRS= mdbmod
--- a/usr/src/cmd/sgs/crle/Makefile.com Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/crle/Makefile.com Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
PROG= crle
@@ -40,13 +38,6 @@
MAPFILE= $(MAPFILE.NGB)
MAPOPT= $(MAPFILE:%=-M%)
-# Building SUNWonld results in a call to the `package' target. Requirements
-# needed to run this application on older releases are established:
-# dlopen/dlclose requires libdl.so.1 prior to 5.10
-#
-DLLIB= $(VAR_DL_LIB)
-package := DLLIB = $(VAR_PKG_DL_LIB)
-
CPPFLAGS += -I. -I../../include -I../../include/$(MACH) \
-I$(SRC)/common/sgsrtcid -I$(SRCBASE)/uts/$(ARCH)/sys \
$(CPPFLAGS.master) -D__EXTENSIONS__
--- a/usr/src/cmd/sgs/include/debug.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/include/debug.h Wed Jan 21 11:00:19 2009 -0800
@@ -89,10 +89,6 @@
#define DBG_DLCLOSE_IGNORE 1
#define DBG_DLCLOSE_RESCAN 2
-#define DBG_WAIT_INIT 1
-#define DBG_WAIT_FINI 2
-#define DBG_WAIT_SYMBOL 3
-
#define DBG_SYM_REDUCE_GLOBAL 1 /* reporting global symbols to local */
#define DBG_SYM_REDUCE_RETAIN 2 /* reporting non reduced local syms */
@@ -258,6 +254,7 @@
#define Dbg_file_hdl_title Dbg64_file_hdl_title
#define Dbg_file_lazyload Dbg64_file_lazyload
#define Dbg_file_ldso Dbg64_file_ldso
+#define Dbg_file_mmapobj Dbg64_file_mmapobj
#define Dbg_file_mode_promote Dbg64_file_mode_promote
#define Dbg_file_modified Dbg64_file_modified
#define Dbg_file_needed Dbg64_file_needed
@@ -298,6 +295,7 @@
#define Dbg_move_adjexpandreloc Dbg64_move_adjexpandreloc
#define Dbg_move_adjmovereloc Dbg64_move_adjmovereloc
+#define Dbg_move_bad Dbg64_move_bad
#define Dbg_move_data Dbg64_move_data
#define Dbg_move_entry1 Dbg64_move_entry1
#define Dbg_move_entry2 Dbg64_move_entry2
@@ -387,7 +385,6 @@
#define Dbg_syms_updated Dbg64_syms_updated
#define Dbg_syms_up_title Dbg64_syms_up_title
-#define Dbg_util_broadcast Dbg64_util_broadcast
#define Dbg_util_call_array Dbg64_util_call_array
#define Dbg_util_call_fini Dbg64_util_call_fini
#define Dbg_util_call_init Dbg64_util_call_init
@@ -403,7 +400,6 @@
#define Dbg_util_scc_entry Dbg64_util_scc_entry
#define Dbg_util_scc_title Dbg64_util_scc_title
#define Dbg_util_str Dbg64_util_str
-#define Dbg_util_wait Dbg64_util_wait
#define Dbg_unused_file Dbg64_unused_file
#define Dbg_unused_lcinterface Dbg64_unused_lcinterface
@@ -464,6 +460,7 @@
#define Dbg_file_hdl_title Dbg32_file_hdl_title
#define Dbg_file_lazyload Dbg32_file_lazyload
#define Dbg_file_ldso Dbg32_file_ldso
+#define Dbg_file_mmapobj Dbg32_file_mmapobj
#define Dbg_file_mode_promote Dbg32_file_mode_promote
#define Dbg_file_modified Dbg32_file_modified
#define Dbg_file_needed Dbg32_file_needed
@@ -504,6 +501,7 @@
#define Dbg_move_adjexpandreloc Dbg32_move_adjexpandreloc
#define Dbg_move_adjmovereloc Dbg32_move_adjmovereloc
+#define Dbg_move_bad Dbg32_move_bad
#define Dbg_move_data Dbg32_move_data
#define Dbg_move_entry1 Dbg32_move_entry1
#define Dbg_move_entry2 Dbg32_move_entry2
@@ -594,7 +592,6 @@
#define Dbg_syms_updated Dbg32_syms_updated
#define Dbg_syms_up_title Dbg32_syms_up_title
-#define Dbg_util_broadcast Dbg32_util_broadcast
#define Dbg_util_call_array Dbg32_util_call_array
#define Dbg_util_call_fini Dbg32_util_call_fini
#define Dbg_util_call_init Dbg32_util_call_init
@@ -610,7 +607,6 @@
#define Dbg_util_scc_entry Dbg32_util_scc_entry
#define Dbg_util_scc_title Dbg32_util_scc_title
#define Dbg_util_str Dbg32_util_str
-#define Dbg_util_wait Dbg32_util_wait
#define Dbg_unused_file Dbg32_unused_file
#define Dbg_unused_lcinterface Dbg32_unused_lcinterface
@@ -671,8 +667,8 @@
extern void Dbg_ent_print(Lm_list *, Half, List *, Boolean);
extern void Dbg_file_analyze(Rt_map *);
-extern void Dbg_file_aout(Lm_list *, const char *, ulong_t, ulong_t,
- ulong_t, const char *, Aliste);
+extern void Dbg_file_aout(Lm_list *, const char *, Addr, size_t,
+ const char *, Aliste);
extern void Dbg_file_ar(Lm_list *, const char *, int);
extern void Dbg_file_ar_rescan(Lm_list *, int, int);
extern void Dbg_file_bind_entry(Lm_list *, Bnd_desc *);
@@ -687,8 +683,8 @@
extern void Dbg_file_dlclose(Lm_list *, const char *, int);
extern void Dbg_file_dldump(Rt_map *, const char *, int);
extern void Dbg_file_dlopen(Rt_map *, const char *, int *, int);
-extern void Dbg_file_elf(Lm_list *, const char *, ulong_t, ulong_t,
- ulong_t, ulong_t, const char *, Aliste);
+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);
extern void Dbg_file_filter(Lm_list *, const char *, const char *, int);
extern void Dbg_file_fixname(Lm_list *, const char *, const char *);
@@ -699,6 +695,8 @@
extern void Dbg_file_lazyload(Rt_map *, const char *, const char *);
extern void Dbg_file_ldso(Rt_map *, char **, auxv_t *, const char *,
Aliste);
+extern void Dbg_file_mmapobj(Lm_list *, const char *, mmapobj_result_t *,
+ uint_t);
extern void Dbg_file_mode_promote(Rt_map *, int);
extern void Dbg_file_modified(Lm_list *, const char *, const char *,
const char *, int, int, Elf *, Elf *);
@@ -741,6 +739,7 @@
extern void Dbg_move_adjexpandreloc(Lm_list *, Xword, const char *);
extern void Dbg_move_adjmovereloc(Lm_list *, Xword, Xword, const char *);
+extern void Dbg_move_bad(Lm_list *, ulong_t, const char *, Addr);
extern void Dbg_move_data(Rt_map *);
extern void Dbg_move_entry1(Lm_list *, int, Move *, Sym_desc *);
extern void Dbg_move_entry2(Lm_list *, Move *, Word, const char *);
@@ -852,7 +851,6 @@
extern void Dbg_tls_static_block(Lm_list *, void *, ulong_t, ulong_t);
extern void Dbg_tls_static_resv(Rt_map *, ulong_t, ulong_t);
-extern void Dbg_util_broadcast(Rt_map *);
extern void Dbg_util_call_array(Rt_map *, void *, int, Word);
extern void Dbg_util_call_fini(Rt_map *);
extern void Dbg_util_call_init(Rt_map *, int);
@@ -869,7 +867,6 @@
extern void Dbg_util_str(Lm_list *, const char *);
extern void Dbg_util_scc_entry(Rt_map *, uint_t);
extern void Dbg_util_scc_title(Lm_list *, int);
-extern void Dbg_util_wait(Rt_map *, Rt_map *, int);
extern void Dbg_unused_file(Lm_list *, const char *, int, uint_t);
extern void Dbg_unused_lcinterface(Rt_map *, Rt_map *, int);
--- a/usr/src/cmd/sgs/include/i386/machdep_x86.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/include/i386/machdep_x86.h Wed Jan 21 11:00:19 2009 -0800
@@ -79,6 +79,15 @@
#define M_SROUND(X) (((X) + M_SEGSIZE - 1) & ~(M_SEGSIZE - 1))
/*
+ * Relocation type macros.
+ */
+#if defined(_ELF64)
+#define M_RELOC Rela
+#else
+#define M_RELOC Rel
+#endif
+
+/*
* TLS static segments must be rounded to the following requirements,
* due to libthread stack allocation.
*/
@@ -88,7 +97,6 @@
#define M_TLSSTATALIGN 0x08
#endif
-
/*
* Other machine dependent entities
*/
--- a/usr/src/cmd/sgs/include/libld.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/include/libld.h Wed Jan 21 11:00:19 2009 -0800
@@ -100,7 +100,6 @@
REF_NUM /* the number of symbol references */
} Symref;
-
/*
* GOT reference models
*/
@@ -128,7 +127,6 @@
Gotndx gt_gndx;
} Gottable;
-
/*
* Output file processing structure
*/
@@ -642,7 +640,6 @@
Elf_Scn *sg_fscn; /* the SCN of the first section. */
};
-
#define FLG_SG_VADDR 0x0001 /* vaddr segment attribute set */
#define FLG_SG_PADDR 0x0002 /* paddr segment attribute set */
#define FLG_SG_LENGTH 0x0004 /* length segment attribute set */
@@ -763,7 +760,6 @@
Half sa_dverndx; /* dependency versioning index */
};
-
/*
* Nodes used to track symbols in the global AVL symbol dictionary.
*/
@@ -1092,7 +1088,7 @@
#define ld_make_sections ld64_make_sections
#define ld_main ld64_main
#define ld_ofl_cleanup ld64_ofl_cleanup
-#define ld_process_open ld64_process_open
+#define ld_process_mem ld64_process_mem
#define ld_reloc_init ld64_reloc_init
#define ld_reloc_process ld64_reloc_process
#define ld_sym_validate ld64_sym_validate
@@ -1107,7 +1103,7 @@
#define ld_make_sections ld32_make_sections
#define ld_main ld32_main
#define ld_ofl_cleanup ld32_ofl_cleanup
-#define ld_process_open ld32_process_open
+#define ld_process_mem ld32_process_mem
#define ld_reloc_init ld32_reloc_init
#define ld_reloc_process ld32_reloc_process
#define ld_sym_validate ld32_sym_validate
@@ -1126,8 +1122,8 @@
extern int ld_init_target(Lm_list *, Half mach);
extern uintptr_t ld_make_sections(Ofl_desc *);
extern void ld_ofl_cleanup(Ofl_desc *);
-extern Ifl_desc *ld_process_open(const char *, const char *, int *,
- Ofl_desc *, Word, Rej_desc *);
+extern Ifl_desc *ld_process_mem(const char *, const char *, char *,
+ size_t, Ofl_desc *, Rej_desc *);
extern uintptr_t ld_reloc_init(Ofl_desc *);
extern uintptr_t ld_reloc_process(Ofl_desc *);
extern uintptr_t ld_sym_validate(Ofl_desc *);
--- a/usr/src/cmd/sgs/include/rtld.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/include/rtld.h Wed Jan 21 11:00:19 2009 -0800
@@ -20,16 +20,16 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
#ifndef _RTLD_H
#define _RTLD_H
/*
* Global include file for the runtime linker.
*/
+#include <sys/mman.h>
#include <time.h>
#include <sgs.h>
#include <thread.h>
@@ -47,7 +47,6 @@
extern "C" {
#endif
-
/*
* We use rtld_ino_t instead of ino_t so that we can get
* access to large inode values from 32-bit code.
@@ -58,20 +57,8 @@
typedef ino64_t rtld_ino_t;
#endif
-
-/*
- * Linked list of directories or filenames (built from colon separated string).
- */
-typedef struct pnode {
- const char *p_name;
- const char *p_oname;
- size_t p_len;
- uint_t p_orig;
- void *p_info;
- struct pnode *p_next;
-} Pnode;
-
typedef struct rt_map Rt_map;
+typedef struct slookup Slookup;
/*
* A binding descriptor. Establishes the binding relationship between two
@@ -98,8 +85,8 @@
* rtld_db implementations of the future to recognize core files produced on
* older systems and deal with these core files accordingly.
*
- * As of version 'RTLD_DB_VERSION <= 2' the following fields were valid for core
- * file examination (basically the public Link_map):
+ * As of version 'R_RTLDDB_VERSION <= 2' the following fields were valid for
+ * core file examination (basically the public Link_map):
*
* ADDR()
* NAME()
@@ -107,7 +94,7 @@
* NEXT()
* PREV()
*
- * Valid fields for RTLD_DB_VERSION3
+ * Valid fields for R_RTLDDB_VERSION3
*
* PATHNAME()
* PADSTART()
@@ -116,11 +103,11 @@
* FLAGS()
* FLAGS1()
*
- * Valid fields for RTLD_DB_VERSION4
+ * Valid fields for R_RTLDDB_VERSION4
*
* TLSMODID()
*
- * Valid fields for RTLD_DB_VERSION5
+ * Valid fields for R_RTLDDB_VERSION5
*
* Added rtld_flags & FLG_RT_RELOCED to stable flags range
*
@@ -138,7 +125,7 @@
struct r_debug rtd_rdebug; /* original r_debug structure */
Word rtd_version; /* version no. */
size_t rtd_objpad; /* padding around mmap()ed objects */
- List * rtd_dynlmlst; /* pointer to Dynlm_list */
+ List *rtd_dynlmlst; /* pointer to Dynlm_list */
} Rtld_db_priv;
#ifdef _SYSCALL32
@@ -381,22 +368,25 @@
#define LML_TFLG_LOADFLTR 0x00000008 /* trigger filtee loading */
-#define LML_TFLG_AUD_PREINIT 0x00100000 /* preinit (audit) exists */
-#define LML_TFLG_AUD_OBJSEARCH 0x00200000 /* objsearch (audit) exists */
-#define LML_TFLG_AUD_OBJOPEN 0x00400000 /* objopen (audit) exists */
-#define LML_TFLG_AUD_OBJFILTER 0x00800000 /* objfilter (audit) exists */
-#define LML_TFLG_AUD_OBJCLOSE 0x01000000 /* objclose (audit) exists */
-#define LML_TFLG_AUD_SYMBIND 0x02000000 /* symbind (audit) exists */
-#define LML_TFLG_AUD_PLTENTER 0x04000000 /* pltenter (audit) exists */
-#define LML_TFLG_AUD_PLTEXIT 0x08000000 /* pltexit (audit) exists */
-#define LML_TFLG_AUD_ACTIVITY 0x10000000 /* activity (audit) exists */
+#define LML_TFLG_AUD_PREINIT 0x00001000 /* preinit (audit) exists */
+#define LML_TFLG_AUD_OBJSEARCH 0x00002000 /* objsearch (audit) exists */
+#define LML_TFLG_AUD_OBJOPEN 0x00004000 /* objopen (audit) exists */
+#define LML_TFLG_AUD_OBJFILTER 0x00008000 /* objfilter (audit) exists */
+#define LML_TFLG_AUD_OBJCLOSE 0x00010000 /* objclose (audit) exists */
+#define LML_TFLG_AUD_SYMBIND 0x00020000 /* symbind (audit) exists */
+#define LML_TFLG_AUD_PLTENTER 0x00040000 /* pltenter (audit) exists */
+#define LML_TFLG_AUD_PLTEXIT 0x00080000 /* pltexit (audit) exists */
+#define LML_TFLG_AUD_ACTIVITY 0x00100000 /* activity (audit) exists */
/*
- * NOTE: Audit flags have duplicated FLAGS1() values. If more audit flags are
- * added, update the FLAGS1() reservation FL1_AUD_RS_STR to FL1_AUD_RS_END
- * defined later.
+ * NOTE: Each auditing module establishes a set of audit flags, AFLAGS(), that
+ * define the auditing interfaces the module offers. These auditing flags are
+ * the LML_TFLG_AUD_ flags defined above. Global auditors result in setting
+ * the lm_tflags too. Local auditors only use the AFLAGS(). All tests for
+ * auditing inspect the lm_tflags and AFLAGS() for a specific auditing
+ * interface, and thus use the same flag to test for both types of auditors.
*/
-#define LML_TFLG_AUD_MASK 0xfff00000 /* audit interfaces mask */
+#define LML_TFLG_AUD_MASK 0x0ffff000 /* audit interfaces mask */
/*
* Define a Group Handle.
@@ -466,7 +456,7 @@
* flags that indicate how the dependency can be used.
*/
typedef struct {
- Rt_map * gd_depend; /* dependency */
+ Rt_map *gd_depend; /* dependency */
uint_t gd_flags; /* dependency flags (GPD_ values) */
} Grp_desc;
@@ -544,17 +534,6 @@
} FullPathNode;
/*
- * Define a mapping structure, which is maintained to describe each mapping
- * of an object, ie. the text segment, data segment, bss segment, etc.
- */
-typedef struct {
- caddr_t m_vaddr; /* mapping address */
- size_t m_fsize; /* backing file size */
- size_t m_msize; /* mapping size */
- int m_perm; /* mapping permissions */
-} Mmap;
-
-/*
* A given link-map can hold either a supplier or receiver copy
* relocation list, but not both. This union is used to overlap
* the space used for the two lists.
@@ -573,10 +552,10 @@
* BEGIN: Exposed to rtld_db - don't move, don't delete
*/
Link_map rt_public; /* public data */
- char *rt_pathname; /* full pathname of loaded object */
+ const char *rt_pathname; /* full pathname of loaded object */
ulong_t rt_padstart; /* start of image (including padding) */
ulong_t rt_padimlen; /* size of image (including padding */
- ulong_t rt_msize; /* total memory mapped */
+ ulong_t rt_msize; /* total memory reservation range */
uint_t rt_flags; /* state flags, see FLG below */
uint_t rt_flags1; /* state flags1, see FL1 below */
ulong_t rt_tlsmodid; /* TLS module id */
@@ -585,17 +564,13 @@
*/
APlist *rt_alias; /* list of linked file names */
APlist *rt_fpnode; /* list of FullpathNode AVL nodes */
- void (*rt_init)(); /* address of _init */
- void (*rt_fini)(); /* address of _fini */
char *rt_runpath; /* LD_RUN_PATH and its equivalent */
- Pnode *rt_runlist; /* Pnode structures */
+ Alist *rt_runlist; /* Pdesc structures */
APlist *rt_depends; /* list of dependencies */
APlist *rt_callers; /* list of callers */
APlist *rt_handles; /* dlopen handles */
APlist *rt_groups; /* groups we're a member of */
- ulong_t rt_etext; /* etext address */
struct fct *rt_fct; /* file class table for this object */
- Sym *(*rt_symintp)(); /* link map symbol interpreter */
void *rt_priv; /* private data, object type specific */
Lm_list *rt_list; /* link map list we belong to */
uint_t rt_objfltrndx; /* object filtees .dynamic index */
@@ -606,8 +581,9 @@
uint_t rt_cycgroup; /* cyclic group */
dev_t rt_stdev; /* device id and inode number for .so */
rtld_ino_t rt_stino; /* multiple inclusion checks */
- char *rt_origname; /* original pathname of loaded object */
+ const char *rt_origname; /* original pathname of loaded object */
size_t rt_dirsz; /* and its size */
+ size_t rt_lmsize; /* size of the link-map allocation */
Rt_map_copy rt_copy; /* list of copy relocations */
Audit_desc *rt_auditors; /* audit descriptor array */
Audit_info *rt_audinfo; /* audit information descriptor */
@@ -617,7 +593,7 @@
Addr *rt_initarray; /* .initarray table */
Addr *rt_finiarray; /* .finiarray table */
Addr *rt_preinitarray; /* .preinitarray table */
- Mmap *rt_mmaps; /* array of mapping information */
+ mmapobj_result_t *rt_mmaps; /* array of mapping information */
uint_t rt_mmapcnt; /* and associated number */
uint_t rt_initarraysz; /* size of .initarray table */
uint_t rt_finiarraysz; /* size of .finiarray table */
@@ -627,15 +603,18 @@
uint_t rt_relacount; /* no. of RELATIVE relocations */
uint_t rt_idx; /* hold index within linkmap list */
uint_t rt_lazy; /* lazy dependencies pending */
- Rt_cond *rt_condvar; /* variables */
Xword rt_hwcap; /* hardware capabilities */
Xword rt_sfcap; /* software capabilities */
- thread_t rt_threadid; /* thread init/fini synchronization */
uint_t rt_cntl; /* link-map control list we belong to */
- uint_t rt_flags2; /* state flags2, see FL2 below */
+ uint_t rt_aflags; /* auditor flags, see LML_TFLG_AUD_ */
+ /* address of _init */
+ void (*rt_init)(void);
+ /* address of _fini */
+ void (*rt_fini)(void);
+ /* link map symbol interpreter */
+ Sym *(*rt_symintp)(Slookup *, Rt_map **, uint_t *, int *);
};
-
#ifdef _SYSCALL32
/*
* Structure to allow 64-bit rtld_db to read 32-bit processes out of procfs.
@@ -662,17 +641,13 @@
*/
uint32_t rt_alias;
uint32_t rt_fpnode;
- uint32_t rt_init;
- uint32_t rt_fini;
uint32_t rt_runpath;
uint32_t rt_runlist;
uint32_t rt_depends;
uint32_t rt_callers;
uint32_t rt_handles;
uint32_t rt_groups;
- uint32_t rt_etext;
uint32_t rt_fct;
- uint32_t rt_symintp;
uint32_t rt_priv;
uint32_t rt_list;
uint32_t rt_objfltrndx;
@@ -702,12 +677,13 @@
uint32_t rt_relacount;
uint32_t rt_idx;
uint32_t rt_lazy;
- uint32_t rt_condvar;
uint32_t rt_hwcap;
uint32_t rt_sfcap;
- uint32_t rt_threadid;
uint32_t rt_cntl;
- uint32_t rt_flags2;
+ uint32_t rt_aflags;
+ uint32_t rt_init;
+ uint32_t rt_fini;
+ uint32_t rt_symintp;
} Rt_map32;
#endif /* _SYSCALL32 */
@@ -721,7 +697,7 @@
#define FLG_RT_ISMAIN 0x00000001 /* object represents main executable */
#define FLG_RT_IMGALLOC 0x00000002 /* image is allocated (not mmap'ed) */
/*
- * Available for r_debug version >= RTLD_DB_VERSION5
+ * Available for r_debug version >= R_RTLDDB_VERSION5
*/
#define FLG_RT_RELOCED 0x00000004 /* object has been relocated */
/*
@@ -759,13 +735,13 @@
#define FLG_RT_RELOCING 0x40000000 /* object is being relocated */
#define FL1_RT_COPYTOOK 0x00000001 /* copy relocation taken */
-#define FL1_RT_RELATIVE 0x00000002 /* relative path expansion required */
+
#define FL1_RT_CONFSET 0x00000004 /* object was loaded by crle(1) */
#define FL1_RT_NODEFLIB 0x00000008 /* ignore default library search */
#define FL1_RT_ENDFILTE 0x00000010 /* filtee terminates filters search */
#define FL1_RT_DISPREL 0x00000020 /* object has *disp* relocation */
-#define FL1_RT_TEXTREL 0x00000040 /* DT_TEXTREL set in object */
-#define FL1_RT_INITWAIT 0x00000080 /* threads are waiting on .init */
+#define FL1_RT_DTFLAGS 0x00000040 /* DT_FLAGS element exists */
+
#define FL1_RT_LDDSTUB 0x00000100 /* identify lddstub */
#define FL1_RT_NOINIFIN 0x00000200 /* no .init or .fini exists */
#define FL1_RT_USED 0x00000400 /* symbol referenced from this object */
@@ -783,22 +759,13 @@
#define FL1_RT_GLOBAUD 0x00080000 /* establish global auditing */
/*
- * The following range of bits are reserved to hold LML_TFLG_AUD_ values
- * (although the definitions themselves aren't used anywhere).
- */
-#define FL1_AUD_RS_STR 0x00100000 /* RESERVATION start for AU flags */
-#define FL1_AUD_RS_END 0x80000000 /* RESERVATION end for AU flags */
-
-#define FL2_RT_DTFLAGS 0x00000001 /* DT_FLAGS element exists */
-
-/*
* Flags for the tls_modactivity() routine
*/
#define TM_FLG_MODADD 0x01 /* call tls_modadd() interface */
#define TM_FLG_MODREM 0x02 /* call tls_modrem() interface */
/*
- * Macros for getting to link_map data.
+ * Macros for getting to exposed, link_map data (R_RTLDDB_VERSION <= 2).
*/
#define ADDR(X) ((X)->rt_public.l_addr)
#define NAME(X) ((X)->rt_public.l_name)
@@ -833,7 +800,7 @@
#define PREV_RT_MAP(X) LINKMAP_TO_RTMAP(PREV(X))
/*
- * Macros for getting to linker private data.
+ * Macros for getting to exposed, link_map data (R_RTLDDB_VERSION3).
*/
#define PATHNAME(X) ((X)->rt_pathname)
#define PADSTART(X) ((X)->rt_padstart)
@@ -841,9 +808,17 @@
#define MSIZE(X) ((X)->rt_msize)
#define FLAGS(X) ((X)->rt_flags)
#define FLAGS1(X) ((X)->rt_flags1)
-#define FLAGS2(X) ((X)->rt_flags2)
+
+/*
+ * Macros for getting to exposed, link_map data (R_RTLDDB_VERSION4).
+ */
#define TLSMODID(X) ((X)->rt_tlsmodid)
+/*
+ * Macros for getting to unexposed, link-map data.
+ */
+#define LMSIZE(X) ((X)->rt_lmsize)
+#define AFLAGS(X) ((X)->rt_aflags)
#define ALIAS(X) ((X)->rt_alias)
#define FPNODE(X) ((X)->rt_fpnode)
#define INIT(X) ((X)->rt_init)
@@ -854,7 +829,6 @@
#define CALLERS(X) ((X)->rt_callers)
#define HANDLES(X) ((X)->rt_handles)
#define GROUPS(X) ((X)->rt_groups)
-#define ETEXT(X) ((X)->rt_etext)
#define FCT(X) ((X)->rt_fct)
#define SYMINTP(X) ((X)->rt_symintp)
#define LIST(X) ((X)->rt_list)
@@ -886,18 +860,16 @@
#define RELACOUNT(X) ((X)->rt_relacount)
#define IDX(X) ((X)->rt_idx)
#define LAZY(X) ((X)->rt_lazy)
-#define CONDVAR(X) ((X)->rt_condvar)
#define CNTL(X) ((X)->rt_cntl)
#define HWCAP(X) ((X)->rt_hwcap)
#define SFCAP(X) ((X)->rt_sfcap)
-#define THREADID(X) ((X)->rt_threadid)
/*
* Flags for tsorting.
*/
#define RT_SORT_FWD 0x01 /* topological sort (.fini) */
#define RT_SORT_REV 0x02 /* reverse topological sort (.init) */
-#define RT_SORT_DELETE 0x10 /* process FLG_RT_DELNEED objects */
+#define RT_SORT_DELETE 0x10 /* process FLG_RT_DELETE objects */
/* only (called via dlclose()) */
#define RT_SORT_INTPOSE 0x20 /* process interposer objects */
@@ -966,7 +938,7 @@
* interpretation of copy relocations, etc. Note, a number of flag settings
* are established in lookup_sym() from attributes of the symbol reference.
*/
-typedef struct {
+struct slookup {
const char *sl_name; /* symbol name */
Rt_map *sl_cmap; /* callers link-map */
Rt_map *sl_imap; /* initial link-map to search */
@@ -978,7 +950,7 @@
/* symbol */
uchar_t sl_bind; /* symbols binding (returned) */
uint_t sl_flags; /* lookup flags */
-} Slookup;
+};
#define SLOOKUP_INIT(sl, name, cmap, imap, id, hash, rsymndx, rsym, rtype, \
flags) \
--- a/usr/src/cmd/sgs/include/sgs.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/include/sgs.h Wed Jan 21 11:00:19 2009 -0800
@@ -24,7 +24,7 @@
* All Rights Reserved
*
*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Global include file for all sgs.
@@ -189,7 +189,7 @@
*/
typedef struct {
ushort_t rej_type; /* SGS_REJ_ value */
- ushort_t rej_flag; /* additional information */
+ ushort_t rej_flags; /* additional information */
uint_t rej_info; /* numeric and string information */
const char *rej_str; /* associated with error */
const char *rej_name; /* object name - expanded library */
@@ -212,6 +212,8 @@
#define SGS_REJ_HWCAP_1 12 /* hardware capabilities mismatch */
#define SGS_REJ_SFCAP_1 13 /* software capabilities mismatch */
+#define FLG_REJ_ALTER 0x01 /* object name is an alternative */
+
/*
* For those source files used both inside and outside of the
* libld source base (tools/common/string_table.c) we can
@@ -230,7 +232,6 @@
extern void *libld_realloc(void *, size_t);
#endif
-
/*
* Data structures (defined in libld.h).
*/
--- a/usr/src/cmd/sgs/include/sparc/machdep_sparc.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/include/sparc/machdep_sparc.h Wed Jan 21 11:00:19 2009 -0800
@@ -74,6 +74,10 @@
#define M_STRUNC(X) ((X) & ~(M_SEGSIZE - 1))
#define M_SROUND(X) (((X) + M_SEGSIZE - 1) & ~(M_SEGSIZE - 1))
+/*
+ * Relocation type macro.
+ */
+#define M_RELOC Rela
/*
* TLS static segments must be rounded to the following requirements,
@@ -85,7 +89,6 @@
#define M_TLSSTATALIGN 0x08
#endif
-
/*
* Instruction encodings.
*/
--- a/usr/src/cmd/sgs/ldd/Makefile.com Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/ldd/Makefile.com Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
PROG= ldd
@@ -39,13 +37,6 @@
MAPFILE= $(MAPFILE.NGB)
MAPOPTS= $(MAPFILE:%=-M%)
-# Building SUNWonld results in a call to the `package' target. Requirements
-# needed to run this application on older releases are established:
-# dlopen/dlclose requires libdl.so.1 prior to 5.10
-#
-DLLIB = $(VAR_DL_LIB)
-package := DLLIB = $(VAR_PKG_DL_LIB)
-
CPPFLAGS += -I. -I../../include -I../../include/$(MACH) \
-I$(SRCBASE)/uts/$(ARCH)/sys \
$(CPPFLAGS.master)
--- a/usr/src/cmd/sgs/ldprof/Makefile.com Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/ldprof/Makefile.com Wed Jan 21 11:00:19 2009 -0800
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
LIBRARY= ldprof.a
VERS= .1
@@ -40,13 +38,6 @@
MAPFILES = mapfile-vers
-# Building SUNWonld results in a call to the `package' target. Requirements
-# needed to run this application on older releases are established:
-# dlopen/dlclose requires libdl.so.1 prior to 5.10
-#
-DLLIB = $(VAR_DL_LIB)
-package := DLLIB = $(VAR_PKG_DL_LIB)
-
DYNFLAGS += $(USE_PROTO)
CPPFLAGS= -I. -I../common -I../../include \
-I../../rtld/common \
--- a/usr/src/cmd/sgs/libcrle/Makefile.com Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/libcrle/Makefile.com Wed Jan 21 11:00:19 2009 -0800
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
LIBRARY= libcrle.a
VERS= .1
@@ -39,13 +37,6 @@
SRCDIR = ../common
-# Building SUNWonld results in a call to the `package' target. Requirements
-# needed to run this application on older releases are established:
-# dlopen/dlclose requires libdl.so.1 prior to 5.10
-#
-DLLIB = $(VAR_DL_LIB)
-package := DLLIB = $(VAR_PKG_DL_LIB)
-
lint := ZRECORD =
LDLIBS += $(ZRECORD) -lmapmalloc $(DLLIB) -lc
--- a/usr/src/cmd/sgs/libld/Makefile.com Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/libld/Makefile.com Wed Jan 21 11:00:19 2009 -0800
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
LIBRARY = libld.a
VERS = .4
@@ -95,13 +93,6 @@
KRTLD_SPARC = $(SRCBASE)/uts/$(VAR_PLAT_sparc)/krtld
-# Building SUNWonld results in a call to the `package' target. Requirements
-# needed to run this application on older releases are established:
-# dlopen/dlclose requires libdl.so.1 prior to 5.10
-#
-DLLIB = $(VAR_DL_LIB)
-package := DLLIB = $(VAR_PKG_DL_LIB)
-
CPPFLAGS += -DUSE_LIBLD_MALLOC -I$(SRCBASE)/lib/libc/inc \
-I$(SRCBASE)/uts/common/krtld -I$(ELFCAP) \
-I$(SRCBASE)/uts/sparc \
@@ -114,7 +105,6 @@
DYNFLAGS += $(VERSREF) $(USE_PROTO) '-R$$ORIGIN'
-$(VAR_POUND_3)DEFS=
native:= DYNFLAGS += $(CONVLIBDIR)
BLTDEFS = msg.h
--- a/usr/src/cmd/sgs/libld/common/_libld.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/libld/common/_libld.h Wed Jan 21 11:00:19 2009 -0800
@@ -488,11 +488,6 @@
ld_swap_reloc_data(_ofl, _rel))
/*
- * For backward compatibility provide a /dev/zero file descriptor.
- */
-extern int dz_fd;
-
-/*
* Local functions.
*/
extern char *add_string(char *, char *);
@@ -548,6 +543,7 @@
#define ld_process_files ld64_process_files
#define ld_process_flags ld64_process_flags
#define ld_process_ifl ld64_process_ifl
+#define ld_process_open ld64_process_open
#define ld_process_ordered ld64_process_ordered
#define ld_process_sym_reloc ld64_process_sym_reloc
#define ld_recalc_shdrcnt ld64_recalc_shdrcnt
@@ -632,6 +628,7 @@
#define ld_process_files ld32_process_files
#define ld_process_flags ld32_process_flags
#define ld_process_ifl ld32_process_ifl
+#define ld_process_open ld32_process_open
#define ld_process_ordered ld32_process_ordered
#define ld_process_sym_reloc ld32_process_sym_reloc
#define ld_recalc_shdrcnt ld32_recalc_shdrcnt
@@ -734,6 +731,8 @@
extern uintptr_t ld_process_flags(Ofl_desc *, int, char **);
extern Ifl_desc *ld_process_ifl(const char *, const char *, int, Elf *,
Word, Ofl_desc *, Rej_desc *);
+extern Ifl_desc *ld_process_open(const char *, const char *, int *,
+ Ofl_desc *, Word, Rej_desc *);
extern uintptr_t ld_process_ordered(Ifl_desc *, Ofl_desc *, Word, Word);
extern uintptr_t ld_process_sym_reloc(Ofl_desc *, Rel_desc *, Rel *,
Is_desc *, const char *);
--- a/usr/src/cmd/sgs/libld/common/files.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/libld/common/files.c Wed Jan 21 11:00:19 2009 -0800
@@ -1993,7 +1993,7 @@
* been processed (rather than simply comparing filenames, the device
* information provides a quicker comparison and detects linked files).
*/
- if (!(flags & FLG_IF_EXTRACT))
+ if (fd && ((flags & FLG_IF_EXTRACT) == 0))
(void) fstat(fd, &status);
else {
status.st_dev = 0;
@@ -2295,6 +2295,26 @@
}
/*
+ * Having successfully mapped a file, set up the necessary elf structures to
+ * process it further. This routine is patterned after ld_process_open() and
+ * is only called by ld.so.1(1) to process a relocatable object.
+ */
+Ifl_desc *
+ld_process_mem(const char *path, const char *file, char *addr, size_t size,
+ Ofl_desc *ofl, Rej_desc *rej)
+{
+ Elf *elf;
+
+ if ((elf = elf_memory(addr, size)) == NULL) {
+ eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_MEMORY), path);
+ ofl->ofl_flags |= FLG_OF_FATAL;
+ return (0);
+ }
+
+ return (ld_process_ifl(path, file, 0, elf, 0, ofl, rej));
+}
+
+/*
* Process a required library (i.e. the dependency of a shared object).
* Combine the directory and filename, check the resultant path size, and try
* opening the pathname.
--- a/usr/src/cmd/sgs/libld/common/globals.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/libld/common/globals.c Wed Jan 21 11:00:19 2009 -0800
@@ -23,10 +23,9 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Global variables
@@ -59,11 +58,6 @@
char def32_Plibpath[] = "/usr/ccs/lib:/lib:/usr/lib";
/*
- * For backward compatibility provide a /dev/zero file descriptor.
- */
-int dz_fd = -1;
-
-/*
* Rejected file error messages (indexed to match FLG_RJC_ values).
*/
const Msg
--- a/usr/src/cmd/sgs/libld/common/libld.msg Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/libld/common/libld.msg Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -425,7 +425,6 @@
@ MSG_TARG_UNSUPPORTED "unsupported ELF machine type: %s"
-
# ELF processing messages
@ MSG_ELF_LIBELF "libelf: version not supported: %d"
@@ -609,6 +608,7 @@
@ MSG_ELF_GETPHDR "file %s: elf_getphdr"
@ MSG_ELF_GETSCN "file %s: elf_getscn: scnndx: %d"
@ MSG_ELF_GETSHDR "file %s: elf_getshdr"
+@ MSG_ELF_MEMORY "file %s: elf_memory"
@ MSG_ELF_NDXSCN "file %s: elf_ndxscn"
@ MSG_ELF_NEWDATA "file %s: elf_newdata"
@ MSG_ELF_NEWEHDR "file %s: elf_newehdr"
--- a/usr/src/cmd/sgs/libld/common/mapfile-vers Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/libld/common/mapfile-vers Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Generic interface definition for usr/src/cmd/sgs/libld.
@@ -35,7 +35,7 @@
# definitions see:
# Policy for Shared Library Version Names and Interface Definitions
-SUNWprivate_4.4 {
+SUNWprivate_4.5 {
global:
dbg_print = NODIRECT; # interposed - ld(1) and ld.so.1(1)
@@ -56,8 +56,8 @@
ld64_make_sections;
ld32_ofl_cleanup;
ld64_ofl_cleanup;
- ld32_process_open;
- ld64_process_open;
+ ld32_process_mem;
+ ld64_process_mem;
ld32_reloc_init;
ld64_reloc_init;
ld32_reloc_process;
--- a/usr/src/cmd/sgs/liblddbg/common/debug.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/debug.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -80,9 +80,7 @@
{MSG_ORIG(MSG_TOK_STRTAB), DBG_C_STRTAB, 0},
{MSG_ORIG(MSG_TOK_STATS), DBG_C_STATS, 0},
{MSG_ORIG(MSG_TOK_UNUSED), DBG_C_UNUSED, 0},
-#ifdef DEMANGLE
{MSG_ORIG(MSG_TOK_DEMANGLE), DBG_C_DEMANGLE, 0},
-#endif
{MSG_ORIG(MSG_TOK_CAP), DBG_C_CAP, 0},
{MSG_ORIG(MSG_TOK_INIT), DBG_C_INIT, 0},
{NULL, NULL},
@@ -284,7 +282,7 @@
* once this routine returns.
*/
if (aplist_append(&dbp->d_list, name,
- AL_CNT_DEBUG) == 0)
+ AL_CNT_DEBUG) == NULL)
return (S_ERROR);
found = TRUE;
--- a/usr/src/cmd/sgs/liblddbg/common/files.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/files.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,38 +51,69 @@
}
void
-Dbg_file_aout(Lm_list *lml, const char *name, ulong_t dynamic, ulong_t base,
- ulong_t size, const char *lmid, Aliste lmco)
+Dbg_file_mmapobj(Lm_list *lml, const char *name, mmapobj_result_t *ompp,
+ uint_t onum)
+{
+ mmapobj_result_t *mpp;
+ uint_t mnum;
+
+ if (DBG_NOTCLASS(DBG_C_FILES))
+ return;
+ if (DBG_NOTDETAIL())
+ return;
+
+ Dbg_util_nl(lml, DBG_NL_STD);
+ dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ), name, onum);
+
+ for (mnum = 0, mpp = ompp; mnum < onum; mnum++, mpp++) {
+ const char *str;
+ uint_t type = MR_GET_TYPE(mpp->mr_flags);
+
+ if (type == MR_PADDING)
+ str = MSG_ORIG(MSG_MR_PADDING);
+ else if (type == MR_HDR_ELF)
+ str = MSG_ORIG(MSG_MR_HDR_ELF);
+ else if (type == MR_HDR_AOUT)
+ str = MSG_ORIG(MSG_MR_HDR_AOUT);
+ else
+ str = MSG_ORIG(MSG_STR_EMPTY);
+
+ dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_1), mnum,
+ EC_NATPTR(mpp->mr_addr), EC_OFF(mpp->mr_fsize), str);
+ dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_2),
+ EC_OFF(mpp->mr_offset), EC_OFF(mpp->mr_msize));
+ }
+ Dbg_util_nl(lml, DBG_NL_STD);
+}
+
+void
+Dbg_file_aout(Lm_list *lml, const char *name, Addr addr, size_t size,
+ const char *lmid, Aliste lmco)
{
if (DBG_NOTCLASS(DBG_C_FILES))
return;
dbg_print(lml, MSG_INTL(MSG_FIL_AOUT), name);
- dbg_print(lml, MSG_INTL(MSG_FIL_DATA_DB), EC_XWORD(dynamic),
- EC_ADDR(base));
- dbg_print(lml, MSG_INTL(MSG_FIL_DATA_S), EC_XWORD(size));
+ dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(addr), EC_OFF(size));
dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
}
void
-Dbg_file_elf(Lm_list *lml, const char *name, ulong_t dynamic, ulong_t base,
- ulong_t size, ulong_t entry, const char *lmid, Aliste lmco)
+Dbg_file_elf(Lm_list *lml, const char *name, Addr addr, size_t size,
+ const char *lmid, Aliste lmco)
{
const char *str;
if (DBG_NOTCLASS(DBG_C_FILES))
return;
- if (base == 0)
+ if (addr == 0)
str = MSG_INTL(MSG_STR_TEMPORARY);
else
str = MSG_ORIG(MSG_STR_EMPTY);
dbg_print(lml, MSG_INTL(MSG_FIL_ELF), name, str);
- dbg_print(lml, MSG_INTL(MSG_FIL_DATA_DB), EC_XWORD(dynamic),
- EC_ADDR(base));
- dbg_print(lml, MSG_INTL(MSG_FIL_DATA_SE), EC_XWORD(size),
- EC_XWORD(entry));
+ dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(addr), EC_OFF(size));
dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
}
@@ -97,8 +128,8 @@
Dbg_util_nl(lml, DBG_NL_STD);
dbg_print(lml, MSG_INTL(MSG_FIL_LDSO), PATHNAME(lmp));
- dbg_print(lml, MSG_INTL(MSG_FIL_DATA_DB), EC_NATPTR(DYN(lmp)),
- EC_ADDR(ADDR(lmp)));
+ dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(ADDR(lmp)),
+ EC_OFF(MSIZE(lmp)));
dbg_print(lml, MSG_INTL(MSG_FIL_DATA_EA), EC_NATPTR(envp),
EC_NATPTR(auxv));
dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -406,12 +406,14 @@
@ MSG_FIL_CONFIG "file=%s [ ELF ]; configuration alternate found: %s"
-@ MSG_FIL_DATA_DB " dynamic: %#18llx base: %#18llx"
-@ MSG_FIL_DATA_SE " size: %#18llx entry: %#18llx"
-@ MSG_FIL_DATA_S " size: %#18llx"
+@ MSG_FIL_DATA_AS " addr: %#18llx size: %#18llx"
@ MSG_FIL_DATA_LL " lmid: %18.18s lmco: %#18llx"
@ MSG_FIL_DATA_EA " envp: %#18llx auxv: %#18llx"
+@ MSG_FIL_MMAPOBJ "file=%s mmapobj entries=%d"
+@ MSG_FIL_MMAPOBJ_1 " [%d]: addr: %#18llx fsize: %#18llx %s"
+@ MSG_FIL_MMAPOBJ_2 " offset: %#17llx msize: %#18llx"
+
@ MSG_FIL_BND_ADD "file=%s; add binding to:"
@ MSG_FIL_BND_FILE " file=%s %s"
@@ -544,6 +546,8 @@
@ MSG_MOVE_PAREXPN "expanding %s into .data: %s"
@ MSG_MOVE_OUTMOVE "copying move entries for %s into .SUNW_move"
@ MSG_MOVE_INPUT "collecting move entries: file=%s"
+@ MSG_MOVE_BAD "move %lld offset invalid: %s: offset=0x%llx \
+ lies outside memory image; move discarded"
# Section header messages
@@ -751,9 +755,6 @@
@ MSG_UTL_FINI "calling .fini: %s"
@ MSG_UTL_ARRAY "calling %s[%d]:0x%llx: %s"
@ MSG_UTL_TRANS "transferring control: %s"
-@ MSG_UTL_WAIT "suspending thread: %s from %s for completion of init \
- for %s"
-@ MSG_UTL_BROAD "signal suspended threads: %s init complete"
@ MSG_UTL_INTOOLATE "loading after relocation has started: interposition \
request (DF_1_INTERPOSE) ignored: %s"
@@ -793,7 +794,6 @@
@ MSG_STR_ADD "adding"
@ MSG_STR_UP_1 "updating"
@ MSG_STR_UP_2 "updated"
-@ MSG_STR_SYMBOL "symbol binding"
@ MSG_STR_UNKNOWN "<unknown>"
@ MSG_STR_ORPHAN "<orphan>"
@@ -1346,3 +1346,9 @@
# TLS information flags
@ MSG_TLS_FLAG_STATIC "STATIC-TLS"
+
+# mmapobj() mr_flags.
+
+@ MSG_MR_PADDING "[ PADDING ]"
+@ MSG_MR_HDR_ELF "[ HDR_ELF ]"
+@ MSG_MR_HDR_AOUT "[ HDR_AOUT ]"
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg Wed Jan 21 11:00:19 2009 -0800
@@ -26,6 +26,8 @@
* Use is subject to license terms.
*/
+#pragma ident "@(#)llib-llddbg 1.79 08/06/20 SMI"
+
#include <sys/types.h>
#include <sys/auxv.h>
#include <debug.h>
@@ -84,10 +86,10 @@
void Dbg32_file_analyze(Rt_map *);
void Dbg64_file_analyze64(Rt_map *);
-void Dbg32_file_aout(Lm_list *, const char *, ulong_t, ulong_t, ulong_t,
- const char *, Aliste);
-void Dbg64_file_aout(Lm_list *, const char *, ulong_t, ulong_t, ulong_t,
- const char *, Aliste);
+void Dbg32_file_aout(Lm_list *, const char *, Addr, size_t, const char *,
+ Aliste);
+void Dbg64_file_aout(Lm_list *, const char *, Addr, size_t, const char *,
+ Aliste);
void Dbg32_file_archive(Lm_list *, const char *, int);
void Dbg64_file_archive(Lm_list *, const char *, int);
void Dbg32_file_bind_entry(Lm_list *, Bnd_desc *);
@@ -114,10 +116,10 @@
void Dbg64_file_dldump(Rt_map *, const char *, int);
void Dbg32_file_dlopen(Rt_map *, const char *, int *, int);
void Dbg64_file_dlopen(Rt_map *, const char *, int *, int);
-void Dbg32_file_elf(Lm_list *, const char *, ulong_t, ulong_t, ulong_t,
- ulong_t, const char *, Aliste);
-void Dbg64_file_elf(Lm_list *, const char *, ulong_t, ulong_t, ulong_t,
- ulong_t, const char *, Aliste);
+void Dbg32_file_elf(Lm_list *, const char *, Addr, size_t, const char *,
+ Aliste);
+void Dbg64_file_elf(Lm_list *, const char *, Addr, size_t, const char *,
+ Aliste);
void Dbg32_file_filtee(Lm_list *, const char *, const char *, int);
void Dbg64_file_filtee(Lm_list *, const char *, const char *, int);
void Dbg32_file_filter(Lm_list *, const char *, const char *, int);
@@ -134,6 +136,8 @@
void Dbg32_file_lazyload(Rt_map *, const char *, const char *);
void Dbg32_file_ldso(Rt_map *, char **, auxv_t *, const char *, Aliste);
void Dbg64_file_ldso(Rt_map *, char **, auxv_t *, const char *, Aliste);
+void Dbg32_file_mmapobj(Lm_list *, const char *, mmapobj_result_t *, uint_t);
+void Dbg64_file_mmapobj(Lm_list *, const char *, mmapobj_result_t *, uint_t);
void Dbg32_file_mode_promote(Rt_map *, int);
void Dbg64_file_mode_promote(Rt_map *, int);
void Dbg32_file_modified(Lm_list *, const char *, const char *, const char *,
@@ -216,6 +220,8 @@
const char *);
void Dbg64_move_adjmovereloc(Lm_list *, Elf64_Xword, Elf64_Xword,
const char *);
+void Dbg32_move_bad(Lm_list *, ulong_t, const char *, Addr);
+void Dbg64_move_bad(Lm_list *, ulong_t, const char *, Addr);
void Dbg32_move_data(Rt_map *);
void Dbg64_move_data(Rt_map *);
void Dbg32_move_entry1(Lm_list *, int, Move *, Sym_desc *);
@@ -450,7 +456,7 @@
void Elf_syminfo_entry(Lm_list *, Word, Syminfo *, const char *, const char *);
void Elf_syminfo_title(Lm_list *);
void Elf_ver_def_title(Lm_list *);
-void Elf_ver_need_title(Lm_list *, int gnuver);
+void Elf_ver_need_title(Lm_list *, int);
void Elf_ver_line_1(Lm_list *, const char *, const char *, const char *,
const char *);
void Elf_ver_line_2(Lm_list *, const char *, const char *);
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -38,7 +38,7 @@
# Policy for Shared Library Version Names and Interface Definitions
-SUNWprivate_4.68 {
+SUNWprivate_4.69 {
global:
dbg_desc = NODIRECT; # interposed - ld.so.1(1)
dbg_print = NODIRECT; # interposed - ld(1) and ld.so.1(1)
@@ -138,6 +138,8 @@
Dbg64_file_lazyload;
Dbg32_file_ldso;
Dbg64_file_ldso;
+ Dbg32_file_mmapobj;
+ Dbg64_file_mmapobj;
Dbg32_file_mode_promote;
Dbg64_file_mode_promote;
Dbg32_file_modified;
@@ -214,6 +216,8 @@
Dbg64_move_adjexpandreloc;
Dbg32_move_adjmovereloc;
Dbg64_move_adjmovereloc;
+ Dbg32_move_bad;
+ Dbg64_move_bad;
Dbg32_move_data;
Dbg64_move_data;
Dbg32_move_entry1;
@@ -386,8 +390,6 @@
Dbg_tls_static_block;
Dbg_tls_static_resv;
- Dbg32_util_broadcast;
- Dbg64_util_broadcast;
Dbg32_util_call_array;
Dbg64_util_call_array;
Dbg32_util_call_fini;
@@ -418,8 +420,6 @@
Dbg64_util_scc_title;
Dbg32_util_str;
Dbg64_util_str;
- Dbg32_util_wait;
- Dbg64_util_wait;
Dbg32_unused_file;
Dbg64_unused_file;
--- a/usr/src/cmd/sgs/liblddbg/common/move.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/move.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,10 +20,9 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "msg.h"
#include "_debug.h"
@@ -168,3 +167,15 @@
dbg_print(lml, MSG_INTL(MSG_MOVE_ENTRYIN), EC_XWORD(mv->m_poffset),
EC_LWORD(mv->m_value), mv->m_repeat, mv->m_stride, sname);
}
+
+void
+Dbg_move_bad(Lm_list *lml, ulong_t num, const char *name, Addr addr)
+{
+ if (DBG_NOTCLASS(DBG_C_MOVE))
+ return;
+ if (DBG_NOTDETAIL())
+ return;
+
+ dbg_print(lml, MSG_INTL(MSG_MOVE_BAD), EC_XWORD(num), name,
+ EC_ADDR(addr));
+}
--- a/usr/src/cmd/sgs/liblddbg/common/util.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/util.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,10 +20,9 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include "msg.h"
#include "_debug.h"
@@ -210,44 +209,6 @@
dbg_print(LIST(lmp), MSG_ORIG(MSG_UTL_SCC_ENTRY), idx, NAME(lmp));
}
-void
-Dbg_util_broadcast(Rt_map *lmp)
-{
- Lm_list *lml = LIST(lmp);
-
- if (DBG_NOTCLASS(DBG_C_INIT))
- return;
- if (DBG_NOTDETAIL())
- return;
-
- Dbg_util_nl(lml, DBG_NL_STD);
- dbg_print(lml, MSG_INTL(MSG_UTL_BROAD), NAME(lmp));
- Dbg_util_nl(lml, DBG_NL_STD);
-}
-
-void
-Dbg_util_wait(Rt_map *clmp, Rt_map *dlmp, int what)
-{
- Lm_list *lml = LIST(clmp);
- const char *str;
-
- if (DBG_NOTCLASS(DBG_C_INIT))
- return;
- if (DBG_NOTDETAIL())
- return;
-
- if (what == DBG_WAIT_INIT)
- str = MSG_ORIG(MSG_SCN_INIT);
- else if (what == DBG_WAIT_FINI)
- str = MSG_ORIG(MSG_SCN_FINI);
- else
- str = MSG_INTL(MSG_STR_SYMBOL);
-
- Dbg_util_nl(lml, DBG_NL_STD);
- dbg_print(lml, MSG_INTL(MSG_UTL_WAIT), str, NAME(clmp), NAME(dlmp));
- Dbg_util_nl(lml, DBG_NL_STD);
-}
-
static int ectoggle = 0;
void
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/main.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/main.c Wed Jan 21 11:00:19 2009 -0800
@@ -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.
@@ -19,12 +18,11 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdlib.h>
@@ -49,8 +47,7 @@
#include "disasm.h"
#include "gram.h"
-
-void
+static void
init_proc()
{
int pfd;
@@ -59,8 +56,7 @@
sigset_t sigset;
fltset_t fltset;
sysset_t sysset;
- long oper;
- long pflags;
+ long oper, pflags;
struct iovec piov[2];
/*
@@ -69,8 +65,7 @@
pid = getpid();
(void) sprintf(procname, "/proc/%d/ctl", pid);
if ((pfd = open(procname, O_WRONLY)) < 0) {
- (void) fprintf(stderr, "can't open %s\n",
- procname);
+ (void) fprintf(stderr, "can't open %s\n", procname);
exit(1);
}
@@ -130,7 +125,6 @@
(void) close(pfd);
}
-
int
main(int argc, char *argv[])
{
@@ -138,7 +132,7 @@
int pstatusfd;
char procname[MAXPATHLEN];
char *command;
- char *rdb_commands = 0;
+ char *rdb_commands = NULL;
pid_t cpid;
pstatus_t pstatus;
sysset_t sysset;
@@ -160,9 +154,9 @@
}
if (error || (optind == argc)) {
- printf("usage: %s [-f file] executable "
- "[executable arguments ...]\n", command);
- printf("\t-f command file\n");
+ (void) printf("usage: %s [-f file] executable "
+ "[executable arguments ...]\n", command);
+ (void) printf("\t-f command file\n");
exit(1);
}
@@ -186,7 +180,8 @@
* initialize libelf
*/
if (elf_version(EV_CURRENT) == EV_NONE) {
- fprintf(stderr, "elf_version() failed: %s\n", elf_errmsg(0));
+ (void) fprintf(stderr, "elf_version() failed: %s\n",
+ elf_errmsg(0));
exit(1);
}
@@ -194,8 +189,8 @@
* initialize librtld_db
*/
if (rd_init(RD_VERSION) != RD_OK) {
- fprintf(stderr, "librtld_db::rd_init() failed: version "
- "submited: %d\n", RD_VERSION);
+ (void) fprintf(stderr, "librtld_db::rd_init() failed: version "
+ "submitted: %d\n", RD_VERSION);
exit(1);
}
@@ -206,12 +201,12 @@
* exec.
*/
(void) sprintf(procname, "/proc/%d/ctl", cpid);
- printf("parent: %d child: %d child procname: %s\n", getpid(),
- cpid, procname);
+ (void) printf("parent: %d child: %d child procname: %s\n", getpid(),
+ cpid, procname);
if ((pctlfd = open(procname, O_WRONLY)) < 0) {
perror(procname);
(void) fprintf(stderr, "%s: can't open child %s\n",
- command, procname);
+ command, procname);
exit(1);
}
@@ -242,7 +237,7 @@
(pstatus.pr_lwp.pr_what == SYS_execve))) {
long pflags = 0;
if (!(pstatus.pr_lwp.pr_reg[R_PS] & ERRBIT)) {
- /* sucessefull exec(2) */
+ /* successfull exec(2) */
break;
}
@@ -275,8 +270,9 @@
(pstatus.pr_lwp.pr_what != SYS_execve))) {
long pflags = 0;
- fprintf(stderr, "Didn't catch the exec, why: %d what: %d\n",
- pstatus.pr_lwp.pr_why, pstatus.pr_lwp.pr_what);
+ (void) fprintf(stderr, "Didn't catch the exec, why: %d "
+ "what: %d\n", pstatus.pr_lwp.pr_why,
+ pstatus.pr_lwp.pr_what);
oper = PCRUN;
piov[1].iov_base = (caddr_t)&pflags;
@@ -286,11 +282,12 @@
exit(1);
}
- ps_init(pctlfd, pstatusfd, cpid, &proch);
+ (void) ps_init(pctlfd, pstatusfd, cpid, &proch);
if (rdb_commands) {
if ((yyin = fopen(rdb_commands, "r")) == NULL) {
- printf("unable to open %s for input\n", rdb_commands);
+ (void) printf("unable to open %s for input\n",
+ rdb_commands);
perr("fopen");
}
} else {
@@ -301,7 +298,8 @@
if (proch.pp_flags & FLG_PP_PACT) {
long pflags = PRCFAULT;
- printf("\ncontinueing the hung process...\n");
+
+ (void) printf("\ncontinuing the hung process...\n");
pctlfd = proch.pp_ctlfd;
(void) ps_close(&proch);
@@ -311,7 +309,7 @@
piov[1].iov_len = sizeof (pflags);
if (writev(pctlfd, piov, 2) == -1)
perr("PCRUN2");
- close(pctlfd);
+ (void) close(pctlfd);
}
return (0);
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/maps.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/maps.c Wed Jan 21 11:00:19 2009 -0800
@@ -18,12 +18,11 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdlib.h>
@@ -46,11 +45,11 @@
#include "rdb.h"
-char *
+static char *
conv_lmid(Lmid_t ident, char *buf, size_t len)
{
if (len < 17)
- return ((char *)0);
+ return (NULL);
if (ident == LM_ID_BASE)
return (strncpy(buf, " BASE ", len));
@@ -82,7 +81,7 @@
addr_to_map(struct ps_prochandle *ph, ulong_t addr)
{
map_info_t *mip;
- if (ph->pp_lmaplist.ml_head == 0) {
+ if (ph->pp_lmaplist.ml_head == NULL) {
/*
* To early to have the full Link Map info available
* so we use the initial info obtained from procfs
@@ -95,7 +94,7 @@
(addr <= ph->pp_execmap.mi_end))
return ((map_info_t *)&(ph->pp_execmap));
- return ((map_info_t *)0);
+ return (NULL);
}
for (mip = ph->pp_lmaplist.ml_head; mip; mip = mip->mi_next)
@@ -103,51 +102,50 @@
(addr <= mip->mi_end))
return (mip);
- return ((map_info_t *)0);
+ return (NULL);
}
-
retc_t
display_linkmaps(struct ps_prochandle *ph)
{
char flagstr[1024];
map_info_t *mip;
- if (ph->pp_lmaplist.ml_head == 0) {
- printf("link-maps not yet available\n");
+ if (ph->pp_lmaplist.ml_head == NULL) {
+ (void) printf("link-maps not yet available\n");
return (RET_FAILED);
}
- printf("Link Maps\n");
- printf("---------\n");
+ (void) printf("Link Maps\n");
+ (void) printf("---------\n");
for (mip = ph->pp_lmaplist.ml_head; mip; mip = mip->mi_next) {
char sbuf[32];
rd_loadobj_t *lp = &mip->mi_loadobj;
- printf("link-map: id: %s name: ",
- conv_lmid(lp->rl_lmident, sbuf, 32));
+ (void) printf("link-map: id: %s name: ",
+ conv_lmid(lp->rl_lmident, sbuf, 32));
if (mip->mi_refname)
- printf("%s(%s)\n", mip->mi_name,
- mip->mi_refname);
+ (void) printf("%s(%s)\n", mip->mi_name,
+ mip->mi_refname);
else
- printf("%s\n", mip->mi_name);
+ (void) printf("%s\n", mip->mi_name);
- printf(" base: 0x%08lx padd_base: 0x%08lx\n",
- lp->rl_base, lp->rl_padstart);
- printf(" data_base: 0x%08llx\n",
- (unsigned long long)lp->rl_data_base);
- printf(" end: 0x%08lx padd_end: 0x%08lx\n",
- lp->rl_bend, lp->rl_padend);
+ (void) printf(" base: 0x%08lx padd_base: 0x%08lx\n",
+ lp->rl_base, lp->rl_padstart);
+ (void) printf(" data_base: 0x%08llx\n",
+ (unsigned long long)lp->rl_data_base);
+ (void) printf(" end: 0x%08lx padd_end: 0x%08lx\n",
+ lp->rl_bend, lp->rl_padend);
flagstr[0] = '\0';
+
if (lp->rl_flags & RD_FLG_MEM_OBJECT) {
- strcat(flagstr, " MEMOBJECT");
+ (void) strcat(flagstr, " MEMOBJECT");
}
- printf(" dynamic: 0x%08lx flags: 0x%08x:[%s ]\n",
- lp->rl_dynamic, lp->rl_flags, flagstr);
+ (void) printf(" dynamic: 0x%08lx flags: "
+ "0x%08x:[%s ]\n", lp->rl_dynamic, lp->rl_flags, flagstr);
}
return (RET_OK);
}
-
retc_t
display_maps(struct ps_prochandle *ph)
{
@@ -162,12 +160,12 @@
if (pread(ph->pp_mapfd, ptr, stbuf.st_size, 0) == -1)
perr("dm: reading map");
- puts("\nMappings");
- puts("--------");
+ (void) puts("\nMappings");
+ (void) puts("--------");
if (ph->pp_dmodel == PR_MODEL_LP64)
- puts("addr size prot ident name");
+ (void) puts("addr size prot ident name");
else
- puts("addr size prot ident name");
+ (void) puts("addr size prot ident name");
for (mapptr = (prmap_t *)ptr;
(uintptr_t)mapptr < ((uintptr_t)ptr + stbuf.st_size);
@@ -175,41 +173,38 @@
map_info_t *mip;
if (ph->pp_dmodel == PR_MODEL_LP64)
- printf("%#18lx %#08lx %#04x",
- mapptr->pr_vaddr, mapptr->pr_size,
- mapptr->pr_mflags);
+ (void) printf("%#18lx %#08lx %#04x", mapptr->pr_vaddr,
+ mapptr->pr_size, mapptr->pr_mflags);
else
- printf("0x%08lx 0x%06lx 0x%02x",
- mapptr->pr_vaddr, mapptr->pr_size,
- mapptr->pr_mflags);
+ (void) printf("0x%08lx 0x%06lx 0x%02x",
+ mapptr->pr_vaddr, mapptr->pr_size,
+ mapptr->pr_mflags);
if ((mip = addr_to_map(ph,
- (ulong_t)(mapptr->pr_vaddr))) != 0) {
+ (ulong_t)(mapptr->pr_vaddr))) != NULL) {
if (mip->mi_refname) {
- printf(" 0x%02lx %s(%s)",
- mip->mi_lmident, mip->mi_name,
- mip->mi_refname);
+ (void) printf(" 0x%02lx %s(%s)",
+ mip->mi_lmident, mip->mi_name,
+ mip->mi_refname);
} else
- printf(" 0x%02lx %s",
- mip->mi_lmident, mip->mi_name);
+ (void) printf(" 0x%02lx %s", mip->mi_lmident,
+ mip->mi_name);
}
- putchar('\n');
+ (void) putchar('\n');
}
- putchar('\n');
+ (void) putchar('\n');
free(ptr);
-
return (RET_OK);
}
-
retc_t
load_map(struct ps_prochandle *procp, caddr_t baddr, map_info_t *mp)
{
Elf *elf;
GElf_Ehdr ehdr;
GElf_Phdr phdr;
- Elf_Scn *scn = 0;
+ Elf_Scn *scn = NULL;
int cnt;
prmap_t *mapptr;
void *ptr;
@@ -226,12 +221,14 @@
for (mapptr = (prmap_t *)ptr;
(uintptr_t)mapptr < ((uintptr_t)ptr + stbuf.st_size);
mapptr++) {
+
if ((mapptr->pr_vaddr <= (uintptr_t)baddr) &&
- ((mapptr->pr_vaddr + mapptr->pr_size) >=
+ ((mapptr->pr_vaddr + mapptr->pr_size) >
(uintptr_t)baddr)) {
if (mapptr->pr_mapname[0]) {
char procname[MAXPATHLEN];
- snprintf(procname, MAXPATHLEN - 1,
+
+ (void) snprintf(procname, MAXPATHLEN - 1,
"/proc/%d/object/%s", procp->pp_pid,
mapptr->pr_mapname);
filefd = open(procname, O_RDONLY);
@@ -242,18 +239,19 @@
free(ptr);
if (filefd == -1) {
- fprintf(stderr, "unable to find good mmaping\n");
+ (void) fprintf(stderr, "unable to find file association to "
+ "maping address 0x%08lx\n", baddr);
return (RET_FAILED);
}
if ((elf = elf_begin(filefd, ELF_C_READ, 0)) == NULL) {
- fprintf(stderr, "elf_begin(): %s\n", elf_errmsg(-1));
+ (void) fprintf(stderr, "elf_begin(): %s\n", elf_errmsg(-1));
return (RET_FAILED);
}
if (elf_kind(elf) != ELF_K_ELF) {
- printf("non-elf file\n");
- elf_end(elf);
+ (void) printf("non-elf file\n");
+ (void) elf_end(elf);
return (RET_FAILED);
}
@@ -262,8 +260,8 @@
mp->mi_mapfd = filefd;
if (gelf_getehdr(mp->mi_elf, &ehdr) == NULL) {
- printf("gelf_getehdr(): %s\n", elf_errmsg(-1));
- elf_end(mp->mi_elf);
+ (void) printf("gelf_getehdr(): %s\n", elf_errmsg(-1));
+ (void) elf_end(mp->mi_elf);
return (RET_FAILED);
}
mp->mi_ehdr = ehdr;
@@ -278,8 +276,8 @@
#endif
for (cnt = 0; cnt < (int)(ehdr.e_phnum); cnt++) {
if (gelf_getphdr(mp->mi_elf, cnt, &phdr) == NULL) {
- printf("gelf_getphdr(): %s\n", elf_errmsg(-1));
- elf_end(mp->mi_elf);
+ (void) printf("gelf_getphdr(): %s\n", elf_errmsg(-1));
+ (void) elf_end(mp->mi_elf);
return (RET_FAILED);
}
@@ -287,7 +285,7 @@
if (mp->mi_end < (ulong_t)(phdr.p_vaddr +
phdr.p_memsz))
mp->mi_end = (ulong_t)(phdr.p_vaddr +
- phdr.p_memsz);
+ phdr.p_memsz);
if (mp->mi_addr > phdr.p_vaddr)
mp->mi_addr = phdr.p_vaddr;
}
@@ -297,14 +295,14 @@
mp->mi_pltsize = 0;
mp->mi_pltentsz = 0;
mp->mi_dynsym.st_symn = 0;
- while ((scn = elf_nextscn(mp->mi_elf, scn)) != 0) {
+ while ((scn = elf_nextscn(mp->mi_elf, scn)) != NULL) {
GElf_Shdr shdr;
- Elf_Data * dp;
- Elf_Scn * tscn = 0;
+ Elf_Data *dp;
+ Elf_Scn *tscn = NULL;
- if (gelf_getshdr(scn, &shdr) == 0) {
- printf("gelf_getshdr(): %s\n", elf_errmsg(-1));
- elf_end(mp->mi_elf);
+ if (gelf_getshdr(scn, &shdr) == NULL) {
+ (void) printf("gelf_getshdr(): %s\n", elf_errmsg(-1));
+ (void) elf_end(mp->mi_elf);
return (RET_FAILED);
}
@@ -314,7 +312,7 @@
mp->mi_dynsym.st_syms_pri = dp;
tscn = elf_getscn(mp->mi_elf, shdr.sh_link);
mp->mi_dynsym.st_symn +=
- shdr.sh_size / shdr.sh_entsize;
+ shdr.sh_size / shdr.sh_entsize;
dp = elf_getdata(tscn, 0);
mp->mi_dynsym.st_strs = (char *)dp->d_buf;
break;
@@ -322,7 +320,7 @@
dp = elf_getdata(scn, 0);
mp->mi_dynsym.st_syms_aux = dp;
mp->mi_dynsym.st_symn_aux =
- shdr.sh_size / shdr.sh_entsize;
+ shdr.sh_size / shdr.sh_entsize;
mp->mi_dynsym.st_symn += mp->mi_dynsym.st_symn_aux;
break;
case SHT_SYMTAB:
@@ -330,7 +328,7 @@
mp->mi_symtab.st_syms_pri = dp;
tscn = elf_getscn(mp->mi_elf, shdr.sh_link);
mp->mi_symtab.st_symn =
- shdr.sh_size / shdr.sh_entsize;
+ shdr.sh_size / shdr.sh_entsize;
dp = elf_getdata(tscn, 0);
mp->mi_symtab.st_strs = (char *)dp->d_buf;
break;
@@ -351,8 +349,6 @@
return (RET_OK);
}
-
-
static int
map_iter(const rd_loadobj_t *lop, void *cd)
{
@@ -361,7 +357,8 @@
char buf[MAXPATHLEN];
if ((mip = (map_info_t *)calloc(1, sizeof (map_info_t))) == NULL) {
- fprintf(stderr, "map_iter: memory error: allocation failed\n");
+ (void) fprintf(stderr, "map_iter: memory error: allocation "
+ "failed\n");
return (0);
}
@@ -369,9 +366,8 @@
if (proc_string_read(ph, lop->rl_nameaddr,
buf, MAXPATHLEN) == RET_FAILED) {
- fprintf(stderr,
- "mi: bad object name address passed: 0x%lx\n",
- lop->rl_nameaddr);
+ (void) fprintf(stderr, "mi: bad object name address "
+ "passed: 0x%lx\n", lop->rl_nameaddr);
free(mip);
return (0);
}
@@ -381,23 +377,28 @@
if (lop->rl_refnameaddr) {
if (proc_string_read(ph, lop->rl_refnameaddr, buf,
MAXPATHLEN) == RET_FAILED) {
- fprintf(stderr,
- "mi1: bad object name address passed: 0x%lx\n",
- lop->rl_refnameaddr);
+ (void) fprintf(stderr, "mi1: bad object name address "
+ "passed: 0x%lx\n", lop->rl_refnameaddr);
free(mip);
return (0);
}
mip->mi_refname = strdup(buf);
} else
- mip->mi_refname = 0;
+ mip->mi_refname = NULL;
- load_map(ph, (caddr_t)lop->rl_base, mip);
+ /*
+ * Relocatable objects are processed to create in-memory shared objects,
+ * and as such have no file associated with the allocated memory shared
+ * object.
+ */
+ if ((lop->rl_flags & RD_FLG_MEM_OBJECT) == 0)
+ (void) load_map(ph, (caddr_t)lop->rl_base, mip);
if ((mip->mi_flags & FLG_MI_EXEC) == 0) {
mip->mi_end += lop->rl_base;
mip->mi_addr += lop->rl_base;
}
mip->mi_lmident = lop->rl_lmident;
- mip->mi_next = 0;
+ mip->mi_next = NULL;
if (ph->pp_lmaplist.ml_head == 0) {
ph->pp_lmaplist.ml_head = ph->pp_lmaplist.ml_tail = mip;
@@ -414,11 +415,12 @@
free_linkmaps(struct ps_prochandle *ph)
{
map_info_t *cur, *prev;
- for (cur = ph->pp_lmaplist.ml_head, prev = 0; cur;
+
+ for (cur = ph->pp_lmaplist.ml_head, prev = NULL; cur;
prev = cur, cur = cur->mi_next) {
if (prev) {
- elf_end(prev->mi_elf);
- close(prev->mi_mapfd);
+ (void) elf_end(prev->mi_elf);
+ (void) close(prev->mi_mapfd);
free(prev->mi_name);
if (prev->mi_refname)
free(prev->mi_refname);
@@ -426,17 +428,16 @@
}
}
if (prev) {
- elf_end(prev->mi_elf);
- close(prev->mi_mapfd);
+ (void) elf_end(prev->mi_elf);
+ (void) close(prev->mi_mapfd);
free(prev->mi_name);
if (prev->mi_refname)
free(prev->mi_refname);
free(prev);
}
- ph->pp_lmaplist.ml_head = ph->pp_lmaplist.ml_tail = 0;
+ ph->pp_lmaplist.ml_head = ph->pp_lmaplist.ml_tail = NULL;
}
-
retc_t
get_linkmaps(struct ps_prochandle *ph)
{
@@ -449,7 +450,7 @@
set_objpad(struct ps_prochandle *ph, size_t padsize)
{
if (rd_objpad_enable(ph->pp_rap, padsize) != RD_OK) {
- printf("rdb: error setting object padding\n");
+ (void) printf("rdb: error setting object padding\n");
return (RET_FAILED);
}
return (RET_OK);
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/rdb.man Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/rdb.man Wed Jan 21 11:00:19 2009 -0800
@@ -1,13 +1,9 @@
-.\" ident "%Z%%M% %I% %E% SMI"
-.\" Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-.\" Use is subject to license terms.
.\"
.\" 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.
@@ -22,8 +18,12 @@
.\"
.\" CDDL HEADER END
.\"
+.\"
+.\" Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+.\" Use is subject to license terms.
+.\"
.if n .tr \--
-.TH rdb 1 "8 Aug 1996"
+.TH rdb 1 "24 April 2008"
.SH NAME
rdb \- run-time demo debugger
.SH SYNOPSIS
@@ -46,9 +46,9 @@
is distributed is source code format and is a sample
of how to use the
.I rtld_db
-interaface and is not meant to be used in a production environment.
+interface and is not meant to be used in a production environment.
.LP
-Each invokation of
+Each invocation of
.B rdb
will debug a single process. In order to start debugging the process
again from the beginning
--- a/usr/src/cmd/sgs/link_audit/Makefile.com Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/link_audit/Makefile.com Wed Jan 21 11:00:19 2009 -0800
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
include ../../../../lib/Makefile.lib
include ../../Makefile.com
@@ -67,13 +65,6 @@
LDLIBS += $(CONVLIBDIR) $(CONV_LIB)
-# Building SUNWonld results in a call to the `package' target. Requirements
-# needed to run this application on older releases are established:
-# dlopen/dlclose requires libdl.so.1 prior to 5.10
-#
-DLLIB = $(VAR_DL_LIB)
-package := DLLIB = $(VAR_PKG_DL_LIB)
-
$(TRUSSLIB):= PICS = $(TRUSSPICS)
$(PERFLIB):= PICS = $(PERFPICS)
$(WHOLIB):= PICS = $(WHOPICS)
--- a/usr/src/cmd/sgs/packages/Makefile Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/packages/Makefile Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
include $(SRC)/Makefile.master
include $(SRC)/cmd/sgs/Makefile.var
@@ -92,15 +90,6 @@
$(SUBDIRS1) $(SUBDIRS2) := TARGET = install
$(PKGDIRS) := TARGET = package
-
-M32:sh= if [ "$MACH" = "sparc" ]; \
- then echo sparc; \
- elif [ "$MACH" = "i386" ]; \
- then echo "$(VAR_I386_ARCH)"; \
- else \
- echo "unknown"; \
- fi
-
../%: FRC
@ cd $@; pwd; $(MAKE) $(TARGET)
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README Wed Jan 21 11:00:19 2009 -0800
@@ -1222,12 +1222,25 @@
================================================================================
6629404 ld with -z ignore doesn't scale
6606203 link editor ought to allow creation of >2gb sized objects (P)
+--------------------------------------------------------------------------------
+All the above changes are incorporated in the following patches:
+ Solaris/SunOS 5.10_sparc patch T139574-01
+ Solaris/SunOS 5.10_x86 patch T139575-01
+--------------------------------------------------------------------------------
6746674 setuid applications do not find libraries any more because trusted
directories behavior changed (D)
--------------------------------------------------------------------------------
All the above changes are incorporated in the following patches:
- Solaris/SunOS 5.10_sparc patch TXXXXXX-YY
- Solaris/SunOS 5.10_x86 patch TXXXXXX-YY
+ Solaris/SunOS 5.10_sparc patch T139574-02
+ Solaris/SunOS 5.10_x86 patch T139575-02
+--------------------------------------------------------------------------------
+6703683 Can't build VirtualBox on Build 88 or 89
+6737579 process_req_lib() in libld consumes file descriptors
+6685125 ld/elfdump do not handle ZERO terminator .eh_frame amd64 unwind entry
+--------------------------------------------------------------------------------
+All the above changes are incorporated in the following patches:
+ Solaris/SunOS 5.10_sparc patch T139574-03
+ Solaris/SunOS 5.10_x86 patch T139575-03
--------------------------------------------------------------------------------
--------------
@@ -1358,7 +1371,6 @@
6681761 lies, darn lies, and linker README files
6509323 Need to disable the Multiple Files loading - same name, different
directories (or its stat() use)
-6685125 ld/elfdump do not handle ZERO terminator .eh_frame amd64 unwind entry
6686889 ld.so.1 regression - bad pointer created with 6509323 integration
6695681 ldd(1) crashes when run from a chrooted environment
6516212 usr/src/cmd/sgs/libelf warlock targets should be fixed or abandoned
@@ -1367,7 +1379,6 @@
6699594 The ld command has a problem handling 'protected' mapfile keyword.
6699131 elfdump should display core file notes (D)
6702260 single threading .init/.fini sections breaks staroffice
-6703683 Can't build VirtualBox on Build 88 or 89
6703919 boot hangs intermittently on x86 with onnv daily.0430 and on
6701798 ld can enter infinite loop processing bad mapfile
6706401 direct binding copy relocation fallback is insufficient for ild
@@ -1419,3 +1430,5 @@
6789925 64-bit applications with SF1_SUNW_ADDR32 require non-default starting
address
6792906 ld -z nopartial fix breaks TLS
+6686372 ld.so.1 should use mmapobj(2)
+6726108 dlopen() performance could be improved.
--- a/usr/src/cmd/sgs/rtld/Makefile.targ Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/Makefile.targ Wed Jan 21 11:00:19 2009 -0800
@@ -19,14 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-
-# Get rid of new compiler warnings
-pics/getcwd.o := WARNFLAGS=-erroff=E_STATEMENT_NOT_REACHED
# Don't generate separate sections for this module
pics/debugdata.o := XFFLAG=
--- a/usr/src/cmd/sgs/rtld/amd64/Makefile Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/amd64/Makefile Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
BASEPLAT = amd64
@@ -35,15 +33,13 @@
analyze.o elf.o external.o globals.o \
malloc.o paths.o setup.o util.o \
dlfcns.o config_elf.o locale.o tsort.o \
- getcwd.o remove.o move.o tls.o \
- cap.o
+ remove.o move.o tls.o cap.o
S_COMOBJS= debug.o audit.o object.o
G_MACHOBJS= doreloc.o
-P_MACHOBJS= amd64_elf.o _setup.o zero.o \
- dlamd64getunwind.o
+P_MACHOBJS= amd64_elf.o _setup.o dlamd64getunwind.o
CP_MACHOBJS=
--- a/usr/src/cmd/sgs/rtld/amd64/_setup.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/amd64/_setup.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* amd64 specific setup routine - relocate ld.so's symbols, setup its
* environment, map in loadable sections of the executable.
@@ -44,33 +42,29 @@
#include <sys/stat.h>
#include <link.h>
#include <dlfcn.h>
-#include <debug.h>
#include "_rtld.h"
#include "_audit.h"
#include "msg.h"
-extern int _end;
-extern int _etext;
-
-
/* VARARGS */
unsigned long
-_setup(Boot * ebp, Dyn * ld_dyn)
+_setup(Boot *ebp, Dyn *ld_dyn)
{
- unsigned long reladdr, relacount, ld_base = 0;
- unsigned long relaent = 0, pltrelsz = 0;
- unsigned long strtab, soname, interp_base = 0;
+ ulong_t reladdr, relacount, ld_base = 0;
+ ulong_t relaent = 0, pltrelsz = 0;
+ ulong_t strtab, soname, interp_base = 0;
char *_rt_name, **_envp, **_argv;
- int _syspagsz = 0, fd = -1, dz_fd = FD_UNAVAIL;
+ int _syspagsz = 0, fd = -1;
uint_t _flags = 0, hwcap_1 = 0;
- Dyn * dyn_ptr;
- Phdr * phdr = 0;
- Rt_map * lmp;
+ Dyn *dyn_ptr;
+ Phdr *phdr = NULL;
+ Rt_map *lmp;
auxv_t *auxv, *_auxv;
uid_t uid = (uid_t)-1, euid = (uid_t)-1;
gid_t gid = (gid_t)-1, egid = (gid_t)-1;
- char *_platform = 0, *_execname = 0, *_emulator = 0;
+ char *_platform = NULL, *_execname = NULL, *_emulator = NULL;
int auxflags = -1;
+
/*
* Scan the bootstrap structure to pick up the basics.
*/
@@ -88,9 +82,6 @@
case EB_AUXV:
_auxv = (auxv_t *)ebp->eb_un.eb_ptr;
break;
- case EB_DEVZERO:
- dz_fd = (int)ebp->eb_un.eb_val;
- break;
case EB_PAGESIZE:
_syspagsz = (int)ebp->eb_un.eb_val;
break;
@@ -148,17 +139,17 @@
_execname = auxv->a_un.a_ptr;
break;
case AT_SUN_AUXFLAGS:
+ /* auxiliary flags */
auxflags = (int)auxv->a_un.a_val;
break;
case AT_SUN_HWCAP:
+ /* hardware capabilities */
hwcap_1 = (uint_t)auxv->a_un.a_val;
break;
-#ifdef AT_SUN_EMULATOR /* Emulation library name */
case AT_SUN_EMULATOR:
/* name of emulation library, if any */
_emulator = auxv->a_un.a_ptr;
break;
-#endif
}
}
@@ -192,17 +183,15 @@
_rt_name = (char *)strtab + soname;
/*
- * If we don't have a RELAENT, just assume
- * the size.
+ * If we don't have a RELAENT, just assume the size.
*/
if (relaent == 0)
relaent = sizeof (Rela);
+
/*
- * Relocate all symbols in ld.so.
- *
- * Because ld.so.1 is built with -Bsymbolic there should only be
- * RELATIVE and JMPSLOT relocations, both of which get relative
- * additions against them.
+ * As all global symbol references within ld.so.1 are protected
+ * (symbolic), only RELATIVE and JMPSLOT relocations should be left
+ * to process at runtime. Process all relocations now.
*/
relacount += (pltrelsz / relaent);
for (; relacount; relacount--) {
@@ -237,8 +226,8 @@
* Continue with generic startup processing.
*/
if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform,
- _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr,
- _execname, _argv, dz_fd, uid, euid, gid, egid, NULL, auxflags,
+ _syspagsz, _rt_name, ld_base, interp_base, fd, phdr,
+ _execname, _argv, uid, euid, gid, egid, NULL, auxflags,
hwcap_1)) == NULL) {
rtldexit(&lml_main, 1);
}
--- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,11 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma ident "@(#)amd64_elf.c 1.25 08/07/30 SMI"
/*
* amd64 machine dependent and ELF file class dependent functions.
@@ -44,9 +44,9 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_inline.h"
#include "msg.h"
-
extern void elf_rtbndr(Rt_map *, ulong_t, caddr_t);
int
@@ -64,7 +64,7 @@
}
void
-ldso_plt_init(Rt_map * lmp)
+ldso_plt_init(Rt_map *lmp)
{
/*
* There is no need to analyze ld.so because we don't map in any of
@@ -73,7 +73,7 @@
* permission information.
*/
if (PLTGOT(lmp))
- elf_plt_init((void *)(PLTGOT(lmp)), (caddr_t)lmp);
+ elf_plt_init((PLTGOT(lmp)), (caddr_t)lmp);
}
static const uchar_t dyn_plt_template[] = {
@@ -131,7 +131,6 @@
uchar_t *dyn_plt;
uintptr_t *dyndata;
-
/*
* We only need to add the glue code if there is an auditing
* library that is interested in this binding.
@@ -146,7 +145,7 @@
* we just set the plt to point to the new dyn_plt.
*/
if (*dyn_plt == 0) {
- Sym * symp;
+ Sym *symp;
Xword symvalue;
Lm_list *lml = LIST(rlmp);
@@ -196,7 +195,6 @@
return ((caddr_t)dyn_plt);
}
-
/*
* Function binding routine - invoked on the first call to a function through
* the procedure linkage table;
@@ -214,7 +212,7 @@
ulong_t
elf_bndr(Rt_map *lmp, ulong_t pltndx, caddr_t from)
{
- Rt_map *nlmp, * llmp;
+ Rt_map *nlmp, *llmp;
ulong_t addr, reloff, symval, rsymndx;
char *name;
Rela *rptr;
@@ -294,7 +292,7 @@
rtldexit(lml, 1);
}
- if ((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_SYMBIND) {
+ if ((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_SYMBIND) {
uint_t symndx = (((uintptr_t)nsym -
(uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp));
symval = audit_symbind(lmp, nlmp, nsym, symndx, symval,
@@ -305,7 +303,7 @@
addr = rptr->r_offset;
if (!(FLAGS(lmp) & FLG_RT_FIXED))
addr += ADDR(lmp);
- if (((lml->lm_tflags | FLAGS1(lmp)) &
+ if (((lml->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -331,8 +329,8 @@
* Print binding information and rebuild PLT entry.
*/
DBG_CALL(Dbg_bind_global(lmp, (Addr)from, (Off)(from - ADDR(lmp)),
- (Xword)(reloff / sizeof (Rela)), PLT_T_FULL, nlmp,
- (Addr)symval, nsym->st_value, name, binfo));
+ (Xword)(reloff / sizeof (Rela)), PLT_T_FULL, nlmp, (Addr)symval,
+ nsym->st_value, name, binfo));
/*
* Complete any processing for newly loaded objects. Note we don't
@@ -349,16 +347,10 @@
* result in objects being loaded on rtld's link-map, make sure these
* objects are initialized also.
*/
- if ((lml->lm_flags & LML_FLG_RTLDLM) && LIST(nlmp)->lm_init)
+ if ((LIST(nlmp)->lm_flags & LML_FLG_RTLDLM) && LIST(nlmp)->lm_init)
load_completion(nlmp);
/*
- * If the object we've bound to is in the process of being initialized
- * by another thread, determine whether we should block.
- */
- is_dep_ready(nlmp, lmp, DBG_WAIT_SYMBOL);
-
- /*
* Make sure the object to which we've bound has had it's .init fired.
* Cleanup before return to user code.
*/
@@ -373,95 +365,24 @@
return (symval);
}
-
-/*
- * When the relocation loop realizes that it's dealing with relative
- * relocations in a shared object, it breaks into this tighter loop
- * as an optimization.
- */
-ulong_t
-elf_reloc_relative(ulong_t relbgn, ulong_t relend, ulong_t relsiz,
- ulong_t basebgn, ulong_t etext, ulong_t emap)
-{
- ulong_t roffset = ((Rela *)relbgn)->r_offset;
- char rtype;
-
- do {
- roffset += basebgn;
-
- /*
- * If this relocation is against an address not mapped in,
- * then break out of the relative relocation loop, falling
- * back on the main relocation loop.
- */
- if (roffset < etext || roffset > emap)
- break;
-
- /*
- * Perform the actual relocation.
- */
- *((ulong_t *)roffset) = basebgn +
- ((Rela *)relbgn)->r_addend;
-
- relbgn += relsiz;
-
- if (relbgn >= relend)
- break;
-
- rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
- roffset = ((Rela *)relbgn)->r_offset;
-
- } while (rtype == R_AMD64_RELATIVE);
-
- return (relbgn);
-}
-
-/*
- * This is the tightest loop for RELATIVE relocations for those
- * objects built with the DT_RELACOUNT .dynamic entry.
- */
-ulong_t
-elf_reloc_relacount(ulong_t relbgn, ulong_t relacount, ulong_t relsiz,
- ulong_t basebgn)
-{
- ulong_t roffset = ((Rela *) relbgn)->r_offset;
-
- for (; relacount; relacount--) {
- roffset += basebgn;
-
- /*
- * Perform the actual relocation.
- */
- *((ulong_t *)roffset) = basebgn +
- ((Rela *)relbgn)->r_addend;
-
- relbgn += relsiz;
-
- roffset = ((Rela *)relbgn)->r_offset;
-
- }
-
- return (relbgn);
-}
-
/*
* Read and process the relocations for one link object, we assume all
* relocation sections for loadable segments are stored contiguously in
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
{
ulong_t relbgn, relend, relsiz, basebgn;
ulong_t pltbgn, pltend, _pltbgn, _pltend;
- ulong_t roffset, rsymndx, psymndx = 0, etext = ETEXT(lmp);
- ulong_t emap, dsymndx;
+ ulong_t roffset, rsymndx, psymndx = 0;
+ ulong_t dsymndx;
uchar_t rtype;
long reladd, value, pvalue;
Sym *symref, *psymref, *symdef, *psymdef;
char *name, *pname;
Rt_map *_lmp, *plmp;
- int textrel = 0, ret = 1, noplt = 0;
+ int ret = 1, noplt = 0;
int relacount = RELACOUNT(lmp), plthint = 0;
Rela *rel;
uint_t binfo, pbinfo;
@@ -473,12 +394,19 @@
* to find this useful.
*/
if ((plt == 0) && PLTGOT(lmp)) {
- if ((ulong_t)PLTGOT(lmp) < etext) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0)
- return (0);
- textrel = 1;
- }
- elf_plt_init((void *)PLTGOT(lmp), (caddr_t)lmp);
+ mmapobj_result_t *mpp;
+
+ /*
+ * Make sure the segment is writable.
+ */
+ if ((((mpp =
+ find_segment((caddr_t)PLTGOT(lmp), lmp)) != NULL) &&
+ ((mpp->mr_prot & PROT_WRITE) == 0)) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
+ return (0);
+
+ elf_plt_init(PLTGOT(lmp), (caddr_t)lmp);
}
/*
@@ -490,7 +418,6 @@
relsiz = (ulong_t)(RELENT(lmp));
basebgn = ADDR(lmp);
- emap = ADDR(lmp) + MSIZE(lmp);
if (PLTRELSZ(lmp))
plthint = PLTRELSZ(lmp) / relsiz;
@@ -516,8 +443,7 @@
SLOOKUP_INIT(sl, MSG_ORIG(MSG_SYM_PLT), lmp, lmp, ld_entry_cnt,
elf_hash(MSG_ORIG(MSG_SYM_PLT)), 0, 0, 0, LKUP_DEFT);
- if ((symdef = elf_find_sym(&sl, &_lmp,
- &binfo, in_nfavl)) == 0)
+ if ((symdef = elf_find_sym(&sl, &_lmp, &binfo, NULL)) == 0)
return (1);
_pltbgn = symdef->st_value;
@@ -578,42 +504,26 @@
* Loop through relocations.
*/
while (relbgn < relend) {
- uint_t sb_flags = 0;
+ mmapobj_result_t *mpp;
+ uint_t sb_flags = 0;
rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
/*
* If this is a RELATIVE relocation in a shared object (the
* common case), and if we are not debugging, then jump into a
- * tighter relocation loop (elf_reloc_relative). Only make the
- * jump if we've been given a hint on the number of relocations.
+ * tighter relocation loop (elf_reloc_relative).
*/
if ((rtype == R_AMD64_RELATIVE) &&
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
- /*
- * It's possible that the relative relocation block
- * has relocations against the text segment as well
- * as the data segment. Since our optimized relocation
- * engine does not check which segment the relocation
- * is against - just mprotect it now if it's been
- * marked as containing TEXTREL's.
- */
- if ((textrel == 0) && (FLAGS1(lmp) & FL1_RT_TEXTREL)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
- }
if (relacount) {
- relbgn = elf_reloc_relacount(relbgn, relacount,
- relsiz, basebgn);
+ relbgn = elf_reloc_relative_count(relbgn,
+ relacount, relsiz, basebgn, lmp, textrel);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, etext, emap);
+ relsiz, basebgn, lmp, textrel);
}
-
if (relbgn >= relend)
break;
rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
@@ -625,8 +535,6 @@
* If this is a shared object, add the base address to offset.
*/
if (!(FLAGS(lmp) & FLG_RT_FIXED)) {
-
-
/*
* If we're processing lazy bindings, we have to step
* through the plt entries and add the base address
@@ -677,26 +585,23 @@
}
/*
+ * If we're promoting plts, determine if this one has already
+ * been written.
+ */
+ if (plt && ((*(ulong_t *)roffset < _pltbgn) ||
+ (*(ulong_t *)roffset > _pltend)))
+ continue;
+
+ /*
* If this relocation is not against part of the image
* mapped into memory we skip it.
*/
- if ((roffset < ADDR(lmp)) || (roffset > (ADDR(lmp) +
- MSIZE(lmp)))) {
+ if ((mpp = find_segment((caddr_t)roffset, lmp)) == NULL) {
elf_reloc_bad(lmp, (void *)rel, rtype, roffset,
rsymndx);
continue;
}
- /*
- * If we're promoting plts determine if this one has already
- * been written.
- */
- if (plt) {
- if ((*(ulong_t *)roffset < _pltbgn) ||
- (*(ulong_t *)roffset > _pltend))
- continue;
- }
-
binfo = 0;
/*
* If a symbol index is specified then get the symbol table
@@ -770,7 +675,7 @@
binfo = pbinfo;
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
value = audit_symbind(lmp, _lmp,
/* LINTED */
@@ -808,8 +713,8 @@
rel, binfo))
continue;
- ret = 0;
- break;
+ ret = 0;
+ break;
} else {
psymndx = rsymndx;
@@ -869,7 +774,7 @@
pbinfo = binfo;
}
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
dsymndx = (((uintptr_t)symdef -
(uintptr_t)SYMTAB(_lmp)) /
@@ -924,15 +829,13 @@
M_REL_SHT_TYPE, rel, NULL, name));
/*
- * If this object has relocations in the text segment, turn
- * off the write protect.
+ * Make sure the segment is writable.
*/
- if ((roffset < etext) && (textrel == 0)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
+ if (((mpp->mr_prot & PROT_WRITE) == 0) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL))) {
+ ret = 0;
+ break;
}
/*
@@ -945,7 +848,7 @@
ret = 0;
break;
case R_AMD64_JUMP_SLOT:
- if (((LIST(lmp)->lm_tflags | FLAGS1(lmp)) &
+ if (((LIST(lmp)->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -994,7 +897,7 @@
}
}
- return (relocate_finish(lmp, bound, textrel, ret));
+ return (relocate_finish(lmp, bound, ret));
}
/*
@@ -1043,7 +946,7 @@
const char *
_conv_reloc_type(uint_t rel)
{
- static Conv_inv_buf_t inv_buf;
+ static Conv_inv_buf_t inv_buf;
return (conv_reloc_amd64_type(rel, 0, &inv_buf));
}
--- a/usr/src/cmd/sgs/rtld/amd64/dlamd64getunwind.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/amd64/dlamd64getunwind.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,24 +20,20 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Block comment which describes the contents of this file.
- */
+#pragma ident "@(#)dlamd64getunwind.c 1.10 08/07/30 SMI"
-#include <string.h>
-#include <dlfcn.h>
-#include <debug.h>
-#include <_rtld.h>
-#include <_elf.h>
-#include <msg.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <debug.h>
+#include "_rtld.h"
+#include "_elf.h"
+#include "_inline.h"
+#include "msg.h"
-#include <stdio.h>
static Dl_amd64_unwindinfo *
getunwind_core(Lm_list *lml, void *pc, Dl_amd64_unwindinfo *unwindinfo)
@@ -78,24 +74,19 @@
lmp = _caller(pc, CL_NONE);
if (lmp) {
- Mmap *immap;
-
- unwindinfo->dlui_objname = PATHNAME(lmp);
+ mmapobj_result_t *mpp;
/*
- * Scan through the mmaps of this object to get the specific
- * segment found.
+ * Determine the associated segment.
*/
- for (immap = MMAPS(lmp); immap->m_vaddr; immap++) {
- if (((caddr_t)pc >= immap->m_vaddr) &&
- ((caddr_t)pc < (immap->m_vaddr + immap->m_msize))) {
- break;
- }
- }
- unwindinfo->dlui_segstart = immap->m_vaddr;
- unwindinfo->dlui_segend = immap->m_vaddr + immap->m_msize;
+ if ((mpp = find_segment(pc, lmp)) == NULL)
+ return (0);
- if (PTUNWIND(lmp) && (immap->m_vaddr)) {
+ unwindinfo->dlui_objname = (char *)PATHNAME(lmp);
+ unwindinfo->dlui_segstart = mpp->mr_addr;
+ unwindinfo->dlui_segend = mpp->mr_addr + mpp->mr_msize;
+
+ if (PTUNWIND(lmp) && (mpp->mr_addr)) {
uintptr_t base;
if (FLAGS(lmp) & FLG_RT_FIXED)
@@ -109,7 +100,7 @@
(void *)(PTUNWIND(lmp)->p_vaddr +
PTUNWIND(lmp)->p_memsz + base);
- } else if (immap->m_vaddr)
+ } else if (mpp->mr_addr)
unwindinfo->dlui_flags |= DLUI_FLG_NOUNWIND;
else
unwindinfo->dlui_flags |=
--- a/usr/src/cmd/sgs/rtld/amd64/mapfile-amd64-vers Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/amd64/mapfile-amd64-vers Wed Jan 21 11:00:19 2009 -0800
@@ -1,5 +1,5 @@
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# CDDL HEADER START
@@ -21,10 +21,8 @@
#
# CDDL HEADER END
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-SUNWprivate_1.2 {
+SUNWprivate_1.3 {
protected:
_dlamd64getunwind;
dlamd64getunwind;
--- a/usr/src/cmd/sgs/rtld/amd64/zero.c Wed Jan 21 09:18:26 2009 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * 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.
- *
- * 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 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-
-void
-zero(caddr_t addr, size_t len)
-{
- int _len = (int)len;
-
- while (_len-- > 0) {
- /* Align and go faster */
- if (((intptr_t)addr & ((sizeof (int) - 1))) == 0) {
- /* LINTED */
- int *w = (int *)addr;
- /* LINTED */
- while (_len > 0) {
- *w++ = 0;
- _len -= sizeof (int);
- }
- return;
- }
- *addr++ = 0;
- }
-}
--- a/usr/src/cmd/sgs/rtld/common/_a.out.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/_a.out.h Wed Jan 21 11:00:19 2009 -0800
@@ -18,17 +18,16 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
#ifndef _A_DOT_OUT_DOT_H
#define _A_DOT_OUT_DOT_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
+#include <sys/mman.h>
#include <a.out.h>
#include <_rtld.h>
@@ -44,13 +43,15 @@
* Extern functions for a.out format file class.
*/
extern ulong_t aout_bndr(caddr_t);
+extern int aout_get_mmap(Lm_list *, mmapobj_result_t *);
extern Sym *aout_lookup_sym(Slookup *, Rt_map **, uint_t *, int *);
-extern Rt_map *aout_new_lm(Lm_list *, const char *, const char *,
- Link_dynamic *, caddr_t, size_t, Aliste);
+extern Rt_map *aout_new_lmp(Lm_list *, Aliste, Fdesc *, Addr, size_t, void *,
+ int *);
extern void aout_plt_write(caddr_t, ulong_t);
-extern int aout_reloc(Rt_map *, uint_t, int *);
+extern int aout_reloc(Rt_map *, uint_t, int *, APlist **);
extern void aout_rtbndr(caddr_t);
-extern int aout_set_prot(Rt_map *, int);
+extern Fct *aout_verify(caddr_t, size_t, Fdesc *, const char *,
+ Rej_desc *);
/*
* Private data for an a.out format file class.
@@ -265,6 +266,13 @@
#define TEXTBASE(X) (LM2LP(X)->lp_textbase)
/*
+ * Most of the above macros are used from AOUT specific routines, however there
+ * are a couple of instances where we need to ensure the file being processed
+ * is AOUT before dereferencing the macro.
+ */
+#define THIS_IS_AOUT(X) (FCT(X) == &aout_fct)
+
+/*
* Code collapsing macros.
*/
#define v2 ld_un.ld_2
--- a/usr/src/cmd/sgs/rtld/common/_elf.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/_elf.h Wed Jan 21 11:00:19 2009 -0800
@@ -18,19 +18,19 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
#ifndef __ELF_DOT_H
#define __ELF_DOT_H
#include <sys/types.h>
+#include <sys/mman.h>
#include <elf.h>
#include <_rtld.h>
@@ -41,12 +41,13 @@
/*
* Common extern functions for ELF file class.
*/
-extern int elf_reloc(Rt_map *, uint_t, int *);
-extern int elf_reloc_error(Rt_map *, const char *, void *, uint_t);
-extern void elf_plt_init(void *, caddr_t);
-extern int elf_set_prot(Rt_map *, int);
-extern Rt_map *elf_obj_file(Lm_list *, Aliste, const char *, int);
-extern Rt_map *elf_obj_fini(Lm_list *, Rt_map *, int *);
+extern int elf_config(Rt_map *, int);
+extern Rtc_obj *elf_config_ent(const char *, Word, int, const char **);
+extern void elf_config_flt(Lm_list *, const char *, const char *,
+ Alist **, Aliste);
+#if defined(__i386)
+extern int elf_copy_gen(Rt_map *);
+#endif
extern int elf_copy_reloc(char *, Sym *, Rt_map *, void *, Sym *,
Rt_map *, const void *);
extern Sym *elf_find_sym(Slookup *, Rt_map **, uint_t *, int *);
@@ -55,19 +56,29 @@
int *);
extern Sym *elf_lookup_filtee(Slookup *, Rt_map **, uint_t *, uint_t,
int *);
-extern Rt_map *elf_new_lm(Lm_list *, const char *, const char *, Dyn *,
- ulong_t, ulong_t, Aliste, ulong_t, ulong_t, ulong_t,
- ulong_t, Mmap *, uint_t, int *);
-extern int elf_rtld_load();
-
+extern int elf_mach_flags_check(Rej_desc *, Ehdr *);
+extern Rt_map *elf_new_lmp(Lm_list *, Aliste, Fdesc *, Addr, size_t, void *,
+ int *);
+extern Rt_map *elf_obj_file(Lm_list *, Aliste, const char *,
+ mmapobj_result_t *, mmapobj_result_t *, uint_t);
+extern Rt_map *elf_obj_fini(Lm_list *, Rt_map *, int *);
+extern void elf_plt_init(void *, caddr_t);
#if defined(__sparcv9)
extern void elf_plt2_init(uint_t *, Rt_map *);
#endif
-
-#if defined(__i386)
-extern ulong_t elf_reloc_relacount(ulong_t, ulong_t, ulong_t, ulong_t);
-extern int elf_copy_gen(Rt_map *);
-#endif
+extern int elf_reloc(Rt_map *, uint_t, int *, APlist **);
+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);
+extern Fct *elf_verify(caddr_t, size_t, Fdesc *, const char *, Rej_desc *);
+extern int elf_verify_vers(const char *, Rt_map *, Rt_map *);
/*
* Padinfo
@@ -92,7 +103,6 @@
char *e_strtab; /* string table */
void *e_reloc; /* relocation table */
uint_t *e_pltgot; /* addrs for procedure linkage table */
- void *e_dynplt; /* dynamic plt table - used by prof */
void *e_jmprel; /* plt relocations */
ulong_t e_sunwsortent; /* size of sunw[sym|tls]sort entry */
uint_t *e_sunwsymsort; /* sunwsymtab indices sorted by addr */
@@ -108,7 +118,6 @@
Phdr *e_pttls; /* PT_TLS */
Phdr *e_ptunwind; /* PT_SUNW_UNWIND (amd64 specific) */
ulong_t e_syment; /* size of symtab entry */
- ulong_t e_entry; /* entry point for file */
Verneed *e_verneed; /* versions needed by this image and */
int e_verneednum; /* their associated count */
Verdef *e_verdef; /* versions defined by this image and */
@@ -132,7 +141,6 @@
#define MOVESZ(X) (((Rt_elfp *)(X)->rt_priv)->e_movesz)
#define MOVEENT(X) (((Rt_elfp *)(X)->rt_priv)->e_moveent)
#define MOVETAB(X) (((Rt_elfp *)(X)->rt_priv)->e_movetab)
-#define DYNPLT(X) (((Rt_elfp *)(X)->rt_priv)->e_dynplt)
#define JMPREL(X) (((Rt_elfp *)(X)->rt_priv)->e_jmprel)
#define SUNWSYMSZ(X) (((Rt_elfp *)(X)->rt_priv)->e_sunwsymsz)
#define PTTLS(X) (((Rt_elfp *)(X)->rt_priv)->e_pttls)
@@ -142,7 +150,6 @@
#define RELSZ(X) (((Rt_elfp *)(X)->rt_priv)->e_relsz)
#define RELENT(X) (((Rt_elfp *)(X)->rt_priv)->e_relent)
#define SYMENT(X) (((Rt_elfp *)(X)->rt_priv)->e_syment)
-#define ENTRY(X) (((Rt_elfp *)(X)->rt_priv)->e_entry)
#define VERNEED(X) (((Rt_elfp *)(X)->rt_priv)->e_verneed)
#define VERNEEDNUM(X) (((Rt_elfp *)(X)->rt_priv)->e_verneednum)
#define VERDEF(X) (((Rt_elfp *)(X)->rt_priv)->e_verdef)
@@ -155,6 +162,14 @@
#define SUNWSYMSORT(X) (((Rt_elfp *)(X)->rt_priv)->e_sunwsymsort)
#define SUNWSYMSORTSZ(X) (((Rt_elfp *)(X)->rt_priv)->e_sunwsymsortsz)
+/*
+ * Most of the above macros are used from ELF specific routines, however there
+ * are a couple of instances where we need to ensure the file being processed
+ * is ELF before dereferencing the macro.
+ */
+#define THIS_IS_ELF(X) (FCT(X) == &elf_fct)
+#define THIS_IS_NOT_ELF(X) (FCT(X) != &elf_fct)
+
#ifdef __cplusplus
}
#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/sgs/rtld/common/_inline.h Wed Jan 21 11:00:19 2009 -0800
@@ -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 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 */
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h Wed Jan 21 11:00:19 2009 -0800
@@ -18,15 +18,14 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
#ifndef __RTLD_H
#define __RTLD_H
@@ -36,6 +35,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/avl.h>
+#include <sys/mman.h>
#include <stdarg.h>
#include <synch.h>
#include <signal.h>
@@ -62,88 +62,103 @@
#define RUNPATH 3 /* callers runpath */
#define DEFAULT 4 /* default library path */
+typedef struct fdesc Fdesc;
+typedef struct fct Fct;
+typedef struct pdesc Pdesc;
/*
* Data structure for file class specific functions and data.
*/
-typedef struct fct {
- int (*fct_are_u_this)(Rej_desc *); /* determine type of object */
- ulong_t (*fct_entry_pt)(void); /* get entry point */
- Rt_map *(*fct_map_so)(Lm_list *, Aliste, const char *, const char *,
- int, int *); /* map in a shared object */
- void (*fct_unmap_so)(Rt_map *); /* unmap a shared object */
+struct fct {
+ /* Verify that the object is of this class. */
+ Fct *(*fct_verify_file)(caddr_t, size_t, Fdesc *, const char *,
+ Rej_desc *);
+
+ /* Generate a link-map to describe the loaded object. */
+ Rt_map *(*fct_new_lmp)(Lm_list *, Aliste, Fdesc *, Addr, size_t,
+ void *, int *);
+
+ /* Retrieve the entry point of the object. */
+ Addr (*fct_entry_pt)(void);
+
+ /* Determine the objects dependencies (needed entries). */
int (*fct_needed)(Lm_list *, Aliste, Rt_map *, int *);
- /* determine needed objects */
+
+ /* Look up a symbol for the object. */
Sym *(*fct_lookup_sym)(Slookup *, Rt_map **, uint_t *, int *);
- /* initialize symbol lookup */
- int (*fct_reloc)(Rt_map *, uint_t, int *);
- /* relocate shared object */
- Pnode *fct_dflt_dirs; /* list of default dirs to */
- /* search */
- Pnode *fct_secure_dirs; /* list of secure dirs to */
- /* search (set[ug]id) */
- Pnode *(*fct_fix_name)(const char *, Rt_map *, uint_t);
- /* transpose name */
- char *(*fct_get_so)(const char *, const char *);
- /* get shared object */
+
+ /* Relocate the object. */
+ int (*fct_reloc)(Rt_map *, uint_t, int *, APlist **);
+
+ /* List of default directories to search for dependencies. */
+ Alist **(*fct_get_def_dirs)(void);
+
+ /* List of secure directories to search for dependencies. */
+ Alist **(*fct_get_sec_dirs)(void);
+
+ /* Transpose the name of the object. */
+ int (*fct_fix_name)(const char *, Rt_map *, Alist **, Aliste,
+ uint_t);
+
+ /* Get a shared object name */
+ char *(*fct_get_so)(const char *, const char *, size_t, size_t);
+
+ /* Retrieve a symbolic address from the object. */
void (*fct_dladdr)(ulong_t, Rt_map *, Dl_info *, void **, int);
- /* get symbolic address */
+
+ /* Process a dlsym(3c) request within the object. */
Sym *(*fct_dlsym)(Grp_hdl *, Slookup *, Rt_map **, uint_t *,
- int *); /* process dlsym request */
- int (*fct_verify_vers)(const char *, Rt_map *, Rt_map *);
- /* verify versioning (ELF) */
- int (*fct_set_prot)(Rt_map *, int);
- /* set protection */
-} Fct;
-
-
-/*
- * Return codes for util::anon_map().
- */
-typedef enum {
- AM_OK, /* mmap(MAP_ANON) succeeded */
- AM_NOSUP, /* mmap(MAP_ANON) not supported (old OS) */
- AM_ERROR /* mmap(MAP_ANON) failed */
-} Am_ret;
-
+ int *);
+};
/*
* Macros for getting to the file class table.
*/
#define LM_ENTRY_PT(X) ((X)->rt_fct->fct_entry_pt)
-#define LM_UNMAP_SO(X) ((X)->rt_fct->fct_unmap_so)
#define LM_NEEDED(X) ((X)->rt_fct->fct_needed)
#define LM_LOOKUP_SYM(X) ((X)->rt_fct->fct_lookup_sym)
#define LM_RELOC(X) ((X)->rt_fct->fct_reloc)
-#define LM_DFLT_DIRS(X) ((X)->rt_fct->fct_dflt_dirs)
-#define LM_SECURE_DIRS(X) ((X)->rt_fct->fct_secure_dirs)
+#define LM_DEFAULT_DIRS(X) ((X)->rt_fct->fct_get_def_dirs)
+#define LM_SECURE_DIRS(X) ((X)->rt_fct->fct_get_sec_dirs)
#define LM_FIX_NAME(X) ((X)->rt_fct->fct_fix_name)
#define LM_GET_SO(X) ((X)->rt_fct->fct_get_so)
#define LM_DLADDR(X) ((X)->rt_fct->fct_dladdr)
#define LM_DLSYM(X) ((X)->rt_fct->fct_dlsym)
-#define LM_VERIFY_VERS(X) ((X)->rt_fct->fct_verify_vers)
-#define LM_SET_PROT(X) ((X)->rt_fct->fct_set_prot)
+/*
+ * Initial memory map allocation. Typical ELF objects contain a text and data
+ * segment, which can be augmented with a bss mapping. Add a bunch more for
+ * luck.
+ */
+#define MMAPFD_NUM 10
/*
- * Define Alist initialization sizes.
+ * Define Alist initialization counts.
*/
-#define AL_CNT_ALIAS 2 /* ALIAS() initial alist count */
-#define AL_CNT_DEPENDS 10 /* DEPENDS() initial alist count */
-#define AL_CNT_CALLERS 10 /* CALLERS() initial alist count */
-#define AL_CNT_GROUPS 4 /* GROUPS() initial alist count */
-#define AL_CNT_COPYREL 10 /* COPY() initial alist count */
-#define AL_CNT_LAZYFIND 10 /* elf_lazy_find_sym() initial alist */
- /* count */
-#define AL_CNT_GRPCLCT 10 /* gdp_collect() initial alist count */
-#define AL_CNT_DEPCLCT 10 /* load_so() initial alist count */
-#define AL_CNT_RTLDINFO 1 /* RTLDINFO() initial alist count */
-#define AL_CNT_FPNODE 2 /* FPNODE() initial alist count */
-#define AL_CNT_LMLISTS 8 /* lm_lists initial alist count */
-#define AL_CNT_LMNOW 8 /* lm_now initial alist count */
-#define AL_CNT_RELBIND 20 /* relocation binding alist count */
-#define AL_CNT_ACTAUDIT 2 /* lm_actaudit alist count */
-#define AL_CNT_MOVES 10 /* move_data alist count */
+#define AL_CNT_ALIAS 2 /* ALIAS() */
+#define AL_CNT_DEPENDS 10 /* DEPENDS() */
+#define AL_CNT_CALLERS 10 /* CALLERS() */
+#define AL_CNT_GROUPS 4 /* GROUPS() */
+#define AL_CNT_COPYREL 10 /* COPY() */
+#define AL_CNT_LAZYFIND 10 /* elf_lazy_find_sym() */
+#define AL_CNT_GRPCLCT 10 /* gdp_collect() */
+#define AL_CNT_DEPCLCT 10 /* load_finish() */
+#define AL_CNT_RTLDINFO 1 /* RTLDINFO() */
+#define AL_CNT_FPNODE 4 /* FPNODE() */
+#define AL_CNT_LMLISTS 8 /* lm_lists */
+#define AL_CNT_LMNOW 8 /* lm_now */
+#define AL_CNT_RELBIND 20 /* relocation binding */
+#define AL_CNT_ACTAUDIT 2 /* lm_actaudit */
+#define AL_CNT_MOVES 10 /* move_data */
+#define AL_CNT_MPOBJS 4 /* elf_obj_file() */
+#define AL_CNT_TEXTREL 2 /* text relocation segment */
+#define AL_CNT_NEEDED 1 /* dependency path */
+#define AL_CNT_SEARCH 4 /* search path */
+#define AL_CNT_FILTEES 2 /* filtee path */
+#define AL_CNT_HANDLES 1 /* hdl_list[] */
+#define AL_CNT_FREELIST 40 /* free_alp */
+#define AL_CNT_HWCAP 10 /* hwcap candidate */
+#define AL_CNT_SPATH 4 /* search path */
/*
@@ -151,7 +166,6 @@
*/
#define ERRSIZE 2048 /* MAXPATHLEN * 2 */
-
/*
* Configuration file information.
*/
@@ -206,26 +220,10 @@
} Rel_copy;
/*
- * Data structure to hold initial file mapping information. Used to
- * communicate during initial object mapping and provide for error recovery.
- */
-typedef struct {
- char *fm_maddr; /* address of initial mapping */
- size_t fm_msize; /* size of initial mapping */
- size_t fm_fsize; /* actual file size */
- ulong_t fm_etext; /* end of text segment */
- int fm_mflags; /* mapping flags */
- ulong_t fm_hwptr; /* hardware capabilities pointer */
-} Fmap;
-
-#define FMAP_SIZE 0x8000 /* initial size to map from a file */
- /* big enough to capture standard */
- /* filters */
-/*
* Define a file descriptor, which maintains information regarding a pathname
* that has been opened and minimally inspected.
*/
-typedef struct {
+struct fdesc {
Rt_map *fd_lmp; /* existing link-map pointer */
Fct *fd_ftp; /* file functions pointer */
const char *fd_oname; /* original file name */
@@ -234,14 +232,16 @@
const char *fd_pname; /* new path (resolved) name */
dev_t fd_dev; /* file device 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 */
- Fmap fd_fmap; /* file mapping information */
-} Fdesc;
+ Xword fd_hwcap; /* hardware capabilities value */
+ mmapobj_result_t *fd_mapp; /* mapping pointer */
+ uint_t fd_mapn; /* mapping number */
+};
-#define FLG_FD_ALTER 0x01 /* file is an alternate */
-#define FLG_FD_SLASH 0x02 /* file contains a "/" */
+#define FLG_FD_ALTER 0x0001 /* file is an alternate */
+#define FLG_FD_SLASH 0x0002 /* file contains a "/" */
+#define FLG_FD_RESOLVED 0x0004 /* fd_nname has been resolved */
/*
* File descriptor availability flag.
@@ -265,15 +265,11 @@
#define RT_FL_WARNFLTR 0x00000002 /* warn of missing filtees (ldd) */
#define RT_FL_DBNOTIF 0x00000004 /* binding activity going on */
-#ifdef SIEBEL_DISABLE
-#define RT_FL_DISFIX_1 0x00000008 /* disable fix number 1 */
-#endif
-
#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 */
#define RT_FL_APPLIC 0x00000080 /* are we executing user code */
-#define RT_FL_CONCUR 0x00000100 /* thread concurrency checks required */
+
#define RT_FL_CONFGEN 0x00000200 /* don't relocate initiating object */
/* set by crle(1). */
#define RT_FL_CONFAPP 0x00000400 /* application specific configuration */
@@ -283,14 +279,13 @@
#define RT_FL_NEWLOCALE 0x00002000 /* message locale has changed */
#define RT_FL_NOBAPLT 0x00004000 /* sparc: don't use ba plt's */
#define RT_FL_NOAUXFLTR 0x00008000 /* disable auxiliary filters */
-#define RT_FL_NOCONCUR 0x00010000 /* disable thread concurrency checks */
+
#define RT_FL_NOAUDIT 0x00020000 /* disable auditing */
#define RT_FL_ATEXIT 0x00040000 /* we're shutting down */
#define RT_FL_SILENCERR 0x00080000 /* silence error messages */
-#define RT_FL_BREADTH 0x00100000 /* use breadth-first for .init/.fini */
+
#define RT_FL_INITFIRST 0x00200000 /* processing a DT_INITFIRST object */
-#define RT_FL_RELATIVE 0x00400000 /* relative path expansion required */
-#define RT_FL_EXECNAME 0x00800000 /* AT_SUN_EXECNAME vector is avail */
+
#define RT_FL_DEMANGLE 0x01000000 /* demangle C++ symbol names */
#define RT_FL_NOCFG 0x02000000 /* disable config file use */
#define RT_FL_NODIRCFG 0x04000000 /* disable directory config use */
@@ -306,7 +301,7 @@
#define RT_FL2_HASAUDIT 0x00000001 /* auditing lm_list is present */
#define RT_FL2_RTLDSEEN 0x00000002 /* rtldinfo has been set */
#define RT_FL2_UNIFPROC 0x00000004 /* libc/libthread unified environment */
-#define RT_FL2_NOMALIGN 0x00000008 /* mmap MAP_ALIGN isn't available */
+
#define RT_FL2_NOFLTCFG 0x00000010 /* disable config filter use */
#define RT_FL2_FLTCFG 0x00000020 /* filter config info available */
#define RT_FL2_HWCAP 0x00000040 /* hardware capabilities available */
@@ -337,12 +332,12 @@
} Rti_desc;
/*
- * Binding flags for the bindguard routines.
+ * Binding flags for the rt_bind_guard()/rt_bind_clear() routines.
* These are defined in usr/src/lib/libc/inc/libc_int.h in the
* latest version of the libc/rtld runtime interface (CI_V_FIVE).
*/
#if !defined(CI_V_FIVE)
-#define THR_FLG_RTLD 0x00000001 /* rtldlock bind_guard() flag */
+#define THR_FLG_RTLD 0x00000001 /* rtldlock bind guard flag */
#define THR_FLG_NOLOCK 0x00000000 /* no-op before CI_V_FIVE */
#define THR_FLG_REENTER 0x00000000 /* no-op before CI_V_FIVE */
#endif
@@ -360,48 +355,93 @@
} Prfbuf;
/*
+ * Path name descriptor. Used to construct various path names such as search
+ * paths, dependency paths, filter paths etc. The pd_info element can be used
+ * to hold various pointers, like Grp_hdl, Rtc_obj, etc.
+ */
+struct pdesc {
+ const char *pd_pname; /* path name - may be expanded */
+ const char *pd_oname; /* original name - unexpanded */
+ void *pd_info; /* possible auxiliary information */
+ size_t pd_plen; /* path name length */
+ uint_t pd_flags; /* descriptor specific flags */
+};
+
+/*
+ * Path name descriptors are passed to expand_path() and expand(). These
+ * routines break down possible multiple path strings (separated with ":"),
+ * and perform any reserved token expansion. These routines are passed
+ * information that indicates the use of the path, for example, search paths,
+ * i.e., LD_LIBRARY_PATH, RPATHS, etc. are defined using la_objsearch()
+ * information (see LA_SER flags in link.h). This information is recorded in
+ * the pd_flags field for later use.
+ *
+ * Define expansion path tokens. These are used to prevent various expansions
+ * from occurring, and record those expansions that do. Any expansion
+ * information is also recorded in the pd_flags field, and thus is or'd
+ * together with any LA_SER flags.
+ */
+#define PD_TKN_ORIGIN 0x00001000 /* $ORIGIN expansion has occurred */
+#define PD_TKN_PLATFORM 0x00002000 /* $PLATFORM expansion has occurred */
+#define PD_TKN_OSNAME 0x00004000 /* $OSNAME expansion has occurred */
+#define PD_TKN_OSREL 0x00008000 /* $OSREL expansion has occurred */
+#define PD_TKN_ISALIST 0x00010000 /* $ISALIST expansion has occurred */
+#define PD_TKN_HWCAP 0x00020000 /* $HWCAP expansion has occurred */
+#define PD_TKN_RESOLVED 0x00040000 /* resolvepath() expansion has */
+ /* occurred */
+#define PD_MSK_EXPAND 0x000ff000 /* mask for all expansions */
+
+/*
+ * Define additional path information. These definitions extend the path
+ * information, and may be passed into expand_path(), or set internally, or
+ * inherited from expand(). These definitions are or'd together with any
+ * LA_SER_ flags and PD_TKN_ flags.
+ */
+#define PD_FLG_PNSLASH 0x00100000 /* pd_pname contains a slash */
+#define PD_FLG_DUPLICAT 0x00200000 /* path is a duplicate */
+#define PD_FLG_EXTLOAD 0x00400000 /* path defines extra loaded objects */
+ /* (preload, audit etc.) */
+#define PD_FLG_UNIQUE 0x00800000 /* ensure path is unique */
+#define PD_FLG_USED 0x01000000 /* indicate that path is used */
+#define PD_FLG_FULLPATH 0x02000000 /* ensure path is a full path */
+
+#define PD_MSK_INHERIT 0x0ffff000 /* mask for pd_flags incorporation */
+
+/*
+ * Additional token expansion information. Although these flags may be set
+ * within a token data item return from expand(), they are masked off with
+ * PD_MSK_INHERIT prior to any expansion information being recorded in a path
+ * name descriptor for later diagnostics.
+ */
+#define TKN_NONE 0x00000001 /* no token expansion has occurred */
+#define TKN_DOTSLASH 0x00000002 /* path contains a "./" */
+
+/*
* dlopen() handle list size.
*/
#define HDLIST_SZ 101 /* prime no. for hashing */
#define HDLIST_ORP 102 /* orphan handle list */
/*
- * Define expansion path information. Search paths, i.e., LD_LIBRARY_PATH,
- * RPATHS, etc. are defined using la_objsearch() information (see LA_SER flags
- * in link.h). Definitions here extend the path information to other uses of
- * pathname expansion, and are or'd together with any LA_SER_* flags.
+ * Define a path name search descriptor. This "cookie" maintains state as
+ * search paths are processed with get_next_dir(). Note, the path list is an
+ * indirect pointer, as search paths can be reevaluated for secure applications
+ * to provide better error diagnostics.
*/
-#define PN_FLG_EXTLOAD 0x00001000 /* path defines extra loaded objects */
- /* (preload, audit etc.) */
-#define PN_FLG_UNIQUE 0x00002000 /* ensure path is unique */
-#define PN_FLG_USED 0x00004000 /* indicate that path is used */
-#define PN_FLG_DUPLICAT 0x00008000 /* path is a duplicate */
-#define PN_FLG_FULLPATH 0x00010000 /* ensure path is a full path */
-
-#define PN_FLG_MASK 0x000ff000 /* mask for p_orig incorporation */
+typedef struct {
+ uchar_t *sp_rule; /* present search rule */
+ Alist **sp_dalpp; /* present path list within rule */
+ Aliste sp_idx; /* present index within path list */
+} Spath_desc;
/*
- * Define reserved path tokens. These are used to prevent various expansions
- * from occurring, and record those expansions that do. Note that any expansion
- * information is also recorded in the p_orig field of a Pnode, and thus is
- * or'd together with any LA_SER, and PN_FLG flags.
+ * Define a path name definition descriptor. Used to maintain initial ELF and
+ * AOUT path name definitions.
*/
-#define PN_TKN_ORIGIN 0x00100000 /* $ORIGIN expansion has occurred */
-#define PN_TKN_PLATFORM 0x00200000 /* $PLATFORM expansion has occurred */
-#define PN_TKN_OSNAME 0x00400000 /* $OSNAME expansion has occurred */
-#define PN_TKN_OSREL 0x00800000 /* $OSREL expansion has occurred */
-#define PN_TKN_ISALIST 0x01000000 /* $ISALIST expansion has occurred */
-#define PN_TKN_HWCAP 0x02000000 /* $HWCAP expansion has occurred */
-
-#define PN_TKN_MASK 0xfff00000 /* mask for p_orig incorporation */
-
-/*
- * Additional token expansion information. Although these flags may be set
- * within a token data item they are masked off with PN_TKN_MASK prior to any
- * expansion information being recorded in a Pnode for later diagnostics.
- */
-#define TKN_NONE 0x00000001 /* no token expansion has occurred */
-#define TKN_DOTSLASH 0x00000002 /* path contains a "./" */
+typedef struct {
+ const char *sd_name; /* path name */
+ size_t sd_len; /* path name size */
+} Spath_defn;
/*
* Define _caller flags.
@@ -469,7 +509,7 @@
extern char *lasterr; /* string describing last error */
extern Interp *interp; /* ELF executable interpreter info */
extern const char *rtldname; /* name of the dynamic linker */
-extern List hdl_list[]; /* dlopen() handle list */
+extern APlist *hdl_alp[]; /* dlopen() handle list */
extern size_t syspagsz; /* system page size */
extern char *platform; /* platform name */
extern size_t platform_sz; /* platform name string size */
@@ -477,7 +517,6 @@
extern Uts_desc *uts; /* utsname descriptor */
extern uint_t rtld_flags; /* status flags for RTLD */
extern uint_t rtld_flags2; /* additional status flags for RTLD */
-extern Fmap *fmap; /* Initial file mapping info */
extern uint32_t pltcnt21d; /* cnt of 21d PLTs */
extern uint32_t pltcnt24d; /* cnt of 24d PLTs */
extern uint32_t pltcntu32; /* cnt of u32 PLTs */
@@ -502,19 +541,25 @@
extern const char *rpl_debug; /* replaceable LD_DEBUG string */
extern const char *rpl_ldflags; /* replaceable LD_FLAGS string */
extern const char *rpl_libpath; /* replaceable LD_LIBRARY string */
-extern Pnode *rpl_libdirs; /* and its associated Pnode list */
+extern Alist *rpl_libdirs; /* and its associated Pdesc list */
extern const char *rpl_preload; /* replaceable LD_PRELOAD string */
extern const char *prm_audit; /* permanent LD_AUDIT string */
extern const char *prm_debug; /* permanent LD_DEBUG string */
extern const char *prm_ldflags; /* permanent LD_FLAGS string */
extern const char *prm_libpath; /* permanent LD_LIBRARY string */
-extern Pnode *prm_libdirs; /* and its associated Pnode list */
+extern Alist *prm_libdirs; /* and its associated Pdesc list */
extern const char *prm_preload; /* permanent LD_PRELOAD string */
+extern Alist *elf_def_dirs; /* ELF default directory seach paths */
+extern Alist *elf_sec_dirs; /* ELF secure directory seach paths */
+extern Alist *aout_def_dirs; /* AOUT default directory seach paths */
+extern Alist *aout_sec_dirs; /* AOUT secure directory seach paths */
+
extern uint_t env_info; /* information regarding environment */
/* variables */
extern int killsig; /* signal sent on fatal exit */
+extern APlist *free_alp; /* defragmentation list */
extern uint_t audit_argcnt; /* no. of stack args to copy */
extern Audit_desc *auditors; /* global auditors */
@@ -548,10 +593,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, rtld_stat_t *,
- const char *);
+extern Rt_map *analyze_lmc(Lm_list *, Aliste, Rt_map *, int *);
extern void atexit_fini(void);
extern int bind_one(Rt_map *, Rt_map *, uint_t);
extern int bufprint(Prfbuf *, const char *, ...);
@@ -563,8 +605,8 @@
extern caddr_t caller(void);
extern void *calloc(size_t, size_t);
extern void cap_assign(Cap *, Rt_map *);
-extern int cap_check(Rej_desc *, Ehdr *);
extern const char *_conv_reloc_type(uint_t rel);
+extern void defrag(void);
extern uintptr_t dbg_setup(const char *, Dbg_desc *);
extern const char *demangle(const char *);
extern int dlclose_intn(Grp_hdl *, Rt_map *);
@@ -576,46 +618,34 @@
uint_t, uint_t);
extern size_t doprf(const char *, va_list, Prfbuf *);
extern int dowrite(Prfbuf *);
-extern void dz_init(int);
-extern caddr_t dz_map(Lm_list *, caddr_t, size_t, int, int);
-extern int elf_config(Rt_map *, int);
-extern int elf_mach_flags_check(Rej_desc *, Ehdr *);
-extern Rtc_obj *elf_config_ent(const char *, Word, int, const char **);
-extern Pnode *elf_config_flt(Lm_list *, const char *, const char *);
-extern ulong_t elf_hash(const char *);
-extern void elf_reloc_bad(Rt_map *, void *, uchar_t, ulong_t,
- ulong_t);
-extern ulong_t elf_reloc_relative(ulong_t, ulong_t, ulong_t,
- ulong_t, ulong_t, ulong_t);
-extern ulong_t elf_reloc_relacount(ulong_t, ulong_t,
- ulong_t, ulong_t);
-extern long elf_static_tls(Rt_map *, Sym *, void *, uchar_t, char *,
- ulong_t, long);
+extern void *dz_map(Lm_list *, caddr_t, size_t, int, int);
extern int enter(int);
extern uint_t expand(char **, size_t *, char **, uint_t, uint_t,
Rt_map *);
-extern Pnode *expand_paths(Rt_map *, const char *, uint_t, uint_t);
+extern int expand_paths(Rt_map *, const char *, Alist **, Aliste,
+ uint_t, uint_t);
extern void free_hdl(Grp_hdl *, Rt_map *, uint_t);
extern void file_notfound(Lm_list *, const char *, Rt_map *,
uint_t, Rej_desc *);
-extern int find_path(Lm_list *, const char *, Rt_map *, uint_t,
- Fdesc *, Rej_desc *, int *);
+extern int find_path(Lm_list *, Rt_map *, uint_t, Fdesc *,
+ Rej_desc *, int *);
extern int fpavl_insert(Lm_list *, Rt_map *, const char *,
avl_index_t);
-extern Rt_map *fpavl_recorded(Lm_list *, const char *, avl_index_t *);
+extern Rt_map *fpavl_recorded(Lm_list *, const char *, uint_t,
+ avl_index_t *);
extern void fpavl_remove(Rt_map *);
-extern size_t fullpath(Rt_map *, const char *);
-extern void fmap_setup();
+extern size_t fullpath(Rt_map *, Fdesc *);
extern void get_lcinterface(Rt_map *, Lc_interface *);
extern Lmid_t get_linkmap_id(Lm_list *);
-extern Pnode *get_next_dir(Pnode **, Rt_map *, uint_t);
+extern Pdesc *get_next_dir(Spath_desc *, Rt_map *, uint_t);
extern int hdl_add(Grp_hdl *, Rt_map *, uint_t);
extern Grp_hdl *hdl_create(Lm_list *, Rt_map *, Rt_map *, uint_t,
uint_t, uint_t);
extern int hdl_initialize(Grp_hdl *, Rt_map *, int, int);
-extern Pnode *hwcap_filtees(Pnode **, Aliste, Lm_cntl *, Dyninfo *,
- Rt_map *, const char *, int, uint_t, int *);
-extern void is_dep_ready(Rt_map *, Rt_map *, int);
+extern int hwcap_check(Xword, Rej_desc *);
+extern int hwcap_filtees(Alist **, Aliste, const char *, Aliste,
+ Lm_cntl *, Rt_map *, const char *, int, uint_t,
+ int *);
extern void is_dep_init(Rt_map *, Rt_map *);
extern int is_move_data(caddr_t);
extern int is_path_secure(char *, Rt_map *, uint_t, uint_t);
@@ -632,39 +662,35 @@
extern void lm_move(Lm_list *, Aliste, Aliste, Lm_cntl *,
Lm_cntl *);
extern void load_completion(Rt_map *);
+extern Rt_map *load_file(Lm_list *, Aliste, Fdesc *, int *);
extern Rt_map *load_hwcap(Lm_list *, Aliste, const char *, Rt_map *,
uint_t, uint_t, Grp_hdl **, Rej_desc *, int *);
-extern Rt_map *load_path(Lm_list *, Aliste, const char **, Rt_map *,
- int, uint_t, Grp_hdl **, Fdesc *, Rej_desc *,
- int *);
-extern Rt_map *load_one(Lm_list *, Aliste, Pnode *, Rt_map *, int,
+extern Rt_map *load_path(Lm_list *, Aliste, Rt_map *, int, uint_t,
+ Grp_hdl **, Fdesc *, Rej_desc *, int *);
+extern Rt_map *load_one(Lm_list *, Aliste, Alist *, Rt_map *, int,
uint_t, Grp_hdl **, int *);
-extern int load_trace(Lm_list *, const char **, Rt_map *);
+extern const char *load_trace(Lm_list *, Pdesc *, Rt_map *, Fdesc *);
extern void nfavl_insert(const char *, avl_index_t);
-extern int nfavl_recorded(const char *, avl_index_t *);
-extern caddr_t nu_map(Lm_list *, caddr_t, size_t, int, int);
+extern int nfavl_recorded(const char *, uint_t, avl_index_t *);
+extern void *nu_map(Lm_list *, caddr_t, size_t, int, int);
+extern Fct *map_obj(Lm_list *, Fdesc *, size_t, const char *, int,
+ Rej_desc *);
extern void *malloc(size_t);
-extern int move_data(Rt_map *);
-extern int pr_open(Lm_list *);
+extern int move_data(Rt_map *, APlist **);
extern void rd_event(Lm_list *, rd_event_e, r_state_e);
extern int readenv_user(const char **, Word *, Word *, int);
extern int readenv_config(Rtc_env *, Addr, int);
extern void rejection_inherit(Rej_desc *, Rej_desc *);
extern int relocate_lmc(Lm_list *, Aliste, Rt_map *, Rt_map *,
int *);
-extern int relocate_finish(Rt_map *, APlist *, int, int);
+extern int relocate_finish(Rt_map *, APlist *, int);
extern void remove_cntl(Lm_list *, Aliste);
extern int remove_hdl(Grp_hdl *, Rt_map *, int *);
extern void remove_lmc(Lm_list *, Rt_map *, Lm_cntl *, Aliste,
const char *);
-extern void remove_incomplete(Lm_list *, Aliste);
-extern void remove_lists(Rt_map *, int);
extern void remove_lml(Lm_list *);
-extern void remove_pnode(Pnode *);
-extern void remove_rej(Rej_desc *);
+extern void remove_plist(Alist **, int);
extern void remove_so(Lm_list *, Rt_map *);
-extern int rt_cond_broadcast(Rt_cond *);
-extern Rt_cond *rt_cond_create(void);
extern int rt_cond_wait(Rt_cond *, Rt_lock *);
extern int rt_bind_guard(int);
extern int rt_bind_clear(int);
@@ -685,17 +711,21 @@
Word *, int);
extern void security(uid_t, uid_t, gid_t, gid_t, int);
extern void set_environ(Lm_list *);
+extern void set_dirs(Alist **, Spath_defn *, uint_t);
+extern int set_prot(Rt_map *, mmapobj_result_t *, int);
extern Rt_map *setup(char **, auxv_t *, Word, char *, int, char *,
- Dyn *, ulong_t, ulong_t, int fd, Phdr *, char *,
- char **, int, uid_t, uid_t, gid_t, gid_t, void *,
- int, uint_t);
+ ulong_t, ulong_t, int fd, Phdr *, char *, char **,
+ uid_t, uid_t, gid_t, gid_t, void *, int, uint_t);
+extern const char *stravl_insert(const char *, uint_t, size_t, int);
extern void spavl_insert(const char *);
extern int spavl_recorded(const char *, avl_index_t *);
+extern int sfcap_check(Xword, Rej_desc *);
extern int tls_assign(Lm_list *, Rt_map *, Phdr *);
extern void tls_modaddrem(Rt_map *, uint_t);
extern int tls_statmod(Lm_list *, Rt_map *);
extern Rt_map **tsort(Rt_map *, int, int);
extern void unused(Lm_list *);
+extern void unmap_obj(mmapobj_result_t *, uint_t);
extern int update_mode(Rt_map *, int, int);
extern void zero(caddr_t, size_t);
--- a/usr/src/cmd/sgs/rtld/common/a.out.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/a.out.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,7 +31,10 @@
#include <a.out.h> /* Explicitly override M_SEGSIZE */
#include <machdep.h> /* used in M_SROUND */
+#include <sys/types.h>
+#include <sys/procfs.h>
#include <sys/mman.h>
+#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
@@ -47,148 +50,146 @@
/*
* Default and secure dependency search paths.
*/
-static Pnode aout_dflt_dirs[] = {
- { MSG_ORIG(MSG_PTH_USR4LIB), 0, MSG_PTH_USR4LIB_SIZE,
- LA_SER_DEFAULT, 0, &aout_dflt_dirs[1] },
- { MSG_ORIG(MSG_PTH_USRLIB), 0, MSG_PTH_USRLIB_SIZE,
- LA_SER_DEFAULT, 0, &aout_dflt_dirs[2] },
- { MSG_ORIG(MSG_PTH_USRLCLIB), 0, MSG_PTH_USRLCLIB_SIZE,
- LA_SER_DEFAULT, 0, 0 }
+static Spath_defn _aout_def_dirs[] = {
+ { MSG_ORIG(MSG_PTH_USR4LIB), MSG_PTH_USR4LIB_SIZE },
+ { MSG_ORIG(MSG_PTH_USRLIB), MSG_PTH_USRLIB_SIZE },
+ { MSG_ORIG(MSG_PTH_USRLCLIB), MSG_PTH_USRLCLIB_SIZE },
+ { 0, 0 }
};
-static Pnode aout_secure_dirs[] = {
-#ifndef SGS_PRE_UNIFIED_PROCESS
- { MSG_ORIG(MSG_PTH_LIBSE), 0, MSG_PTH_LIBSE_SIZE,
- LA_SER_SECURE, 0, &aout_secure_dirs[1] },
-#endif
- { MSG_ORIG(MSG_PTH_USRLIBSE), 0, MSG_PTH_USRLIBSE_SIZE,
- LA_SER_SECURE, 0, 0 }
+static Spath_defn _aout_sec_dirs[] = {
+ { MSG_ORIG(MSG_PTH_LIBSE), MSG_PTH_LIBSE_SIZE },
+ { 0, 0 }
};
+Alist *aout_def_dirs = NULL;
+Alist *aout_sec_dirs = NULL;
+
/*
* Defines for local functions.
*/
-static int aout_are_u();
-static ulong_t aout_entry_pt();
-static Rt_map *aout_map_so();
-static void aout_unmap_so();
-static int aout_needed();
-extern Sym *aout_lookup_sym();
-static Sym *aout_find_sym();
-static char *aout_get_so();
-static Pnode *aout_fix_name();
-static void aout_dladdr();
-static Sym *aout_dlsym_handle();
-static int aout_verify_vers();
+static void aout_dladdr(ulong_t, Rt_map *, Dl_info *, void **, int);
+static Sym *aout_dlsym_handle(Grp_hdl *, Slookup *, Rt_map **, uint_t *,
+ int *l);
+static Addr aout_entry_point(void);
+static Sym *aout_find_sym(Slookup *, Rt_map **, uint_t *, int *);
+static int aout_fix_name(const char *, Rt_map *, Alist **, Aliste, uint_t);
+static Alist **aout_get_def_dirs(void);
+static Alist **aout_get_sec_dirs(void);
+static char *aout_get_so(const char *, const char *, size_t, size_t);
+extern Sym *aout_lookup_sym(Slookup *, Rt_map **, uint_t *, int *);
+static int aout_needed(Lm_list *, Aliste, Rt_map *, int *);
/*
* Functions and data accessed through indirect pointers.
*/
Fct aout_fct = {
- aout_are_u,
- aout_entry_pt,
- aout_map_so,
- aout_unmap_so,
+ aout_verify,
+ aout_new_lmp,
+ aout_entry_point,
aout_needed,
aout_lookup_sym,
aout_reloc,
- aout_dflt_dirs,
- aout_secure_dirs,
+ aout_get_def_dirs,
+ aout_get_sec_dirs,
aout_fix_name,
aout_get_so,
aout_dladdr,
- aout_dlsym_handle,
- aout_verify_vers,
- aout_set_prot
+ aout_dlsym_handle
};
+/*
+ * Default and secure dependency search paths.
+ */
+static Alist **
+aout_get_def_dirs()
+{
+ if (aout_def_dirs == NULL)
+ set_dirs(&aout_def_dirs, _aout_def_dirs, LA_SER_DEFAULT);
+ return (&aout_def_dirs);
+}
+
+static Alist **
+aout_get_sec_dirs()
+{
+ if (aout_sec_dirs == NULL)
+ set_dirs(&aout_sec_dirs, _aout_sec_dirs, LA_SER_SECURE);
+ return (&aout_sec_dirs);
+}
/*
* In 4.x, a needed file or a dlopened file that was a simple file name implied
* that the file be found in the present working directory. To simulate this
- * lookup within the elf rules it is necessary to add a proceeding `./' to the
+ * lookup within the ELF rules it is necessary to add a preceding `./' to the
* filename.
*/
-static Pnode *
-aout_fix_name(const char *name, Rt_map *clmp)
+/* ARGSUSED4 */
+static int
+aout_fix_name(const char *oname, Rt_map *clmp, Alist **alpp, Aliste alni,
+ uint_t orig)
{
- size_t len;
- Pnode *pnp;
-
- if ((pnp = calloc(1, sizeof (Pnode))) == 0)
- return (0);
+ size_t len;
+ Pdesc *pdp;
+ const char *nname;
/*
* Check for slash in name, if none, prepend "./", otherwise just
* return name given.
*/
- if (strchr(name, '/')) {
- len = strlen(name) + 1;
- if ((pnp->p_name = malloc(len)) != 0)
- (void) strcpy((char *)pnp->p_name, name);
+ if (strchr(oname, '/')) {
+ len = strlen(oname) + 1;
+ if ((nname = stravl_insert(oname, 0, len, 0)) == NULL)
+ return (0);
} else {
- len = strlen(name) + 3;
- if ((pnp->p_name = malloc(len)) != 0)
- (void) snprintf((char *)pnp->p_name, len,
- MSG_ORIG(MSG_FMT_4XPATH), name);
+ char buffer[PATH_MAX];
+
+ len = strlen(oname) + 3;
+ (void) snprintf(buffer, len, MSG_ORIG(MSG_FMT_4XPATH), oname);
+ if ((nname = stravl_insert(buffer, 0, len, 0)) == NULL)
+ return (0);
}
- if (pnp->p_name) {
- pnp->p_len = len;
- DBG_CALL(Dbg_file_fixname(LIST(clmp), pnp->p_name, name));
- return (pnp);
- }
- free(pnp);
- return (0);
+ if ((pdp = alist_append(alpp, 0, sizeof (Pdesc), alni)) == NULL)
+ return (0);
+
+ pdp->pd_pname = nname;
+ pdp->pd_plen = len;
+ pdp->pd_flags = PD_FLG_PNSLASH;
+
+ DBG_CALL(Dbg_file_fixname(LIST(clmp), nname, oname));
+ return (1);
}
/*
* Determine if we have been given an A_OUT file. Returns 1 if true.
*/
-static int
-aout_are_u()
+Fct *
+/* ARGSUSED1 */
+aout_verify(caddr_t addr, size_t size, Fdesc *fdp, const char *name,
+ Rej_desc *rej)
{
- struct exec *exec;
-
/* LINTED */
- exec = (struct exec *)fmap->fm_maddr;
- if (fmap->fm_fsize < sizeof (exec) || (exec->a_machtype != M_SPARC) ||
+ struct exec *exec = (struct exec *)addr;
+
+ if (size < sizeof (exec) || (exec->a_machtype != M_SPARC) ||
(N_BADMAG(*exec))) {
- return (0);
+ return (NULL);
}
- return (1);
+ return (&aout_fct);
}
/*
- * Return the entry point the A_OUT executable. This is always zero.
+ * Return the entry point of the A_OUT executable. Although the entry point
+ * within an ELF file is flexible, the entry point of an A_OUT executable is
+ * always zero.
*/
-static ulong_t
-aout_entry_pt()
+static Addr
+aout_entry_point()
{
return (0);
}
/*
- * Unmap a given A_OUT shared object from the address space.
- */
-static void
-aout_unmap_so(Rt_map *lmp)
-{
- Mmap *immap = MMAPS(lmp);
-
- (void) munmap(immap->m_vaddr, immap->m_msize);
-}
-
-/*
- * Dummy versioning interface - real functionality is only applicable to elf.
- */
-static int
-aout_verify_vers()
-{
- return (1);
-}
-
-/*
* Search through the dynamic section for DT_NEEDED entries and perform one
* of two functions. If only the first argument is specified then load the
* defined shared object, otherwise add the link map representing the
@@ -197,6 +198,7 @@
static int
aout_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp, int *in_nfavl)
{
+ Alist *palp = NULL;
void *need;
for (need = &TEXTBASE(clmp)[AOUTDYN(clmp)->v2->ld_need];
@@ -204,7 +206,6 @@
need = &TEXTBASE(clmp)[((Lnk_obj *)(need))->lo_next]) {
Rt_map *nlmp;
char *name;
- Pnode *pnp;
name = &TEXTBASE(clmp)[((Lnk_obj *)(need))->lo_name];
@@ -215,7 +216,6 @@
* Thus we need to rebuild the library name before
* trying to load it.
*/
- Pnode *dir, *dirlist = (Pnode *)0;
char *file;
size_t len;
@@ -224,7 +224,7 @@
* lib.so.. = 7 + (2 * short) + NULL = 7 + 12 + 1 = 20
*/
len = strlen(name) + 20;
- if ((file = malloc(len)) == 0)
+ if ((file = malloc(len)) == NULL)
return (0);
(void) snprintf(file, len, MSG_ORIG(MSG_FMT_4XLIB),
name, ((Lnk_obj *)(need))->lo_major,
@@ -244,18 +244,20 @@
if (lml->lm_flags & LML_FLG_TRC_ENABLE)
name = file;
else {
- char *path = (char *)0;
+ Spath_desc sd = { search_rules, NULL, 0 };
+ Pdesc *pdp;
+ char *path = NULL;
- for (dir = get_next_dir(&dirlist, clmp, 0); dir;
- dir = get_next_dir(&dirlist, clmp, 0)) {
- if (dir->p_name == 0)
+ for (pdp = get_next_dir(&sd, clmp, 0); pdp;
+ pdp = get_next_dir(&sd, clmp, 0)) {
+ if (pdp->pd_pname == 0)
continue;
- if (path =
- aout_get_so(dir->p_name, file))
+ if (path = aout_get_so(pdp->pd_pname,
+ file, 0, 0))
break;
}
- if (!path) {
+ if (path == NULL) {
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_SYS_OPEN), file,
strerror(ENOENT));
@@ -263,7 +265,8 @@
}
name = path;
}
- if ((pnp = expand_paths(clmp, name, 0, 0)) == 0)
+ if (expand_paths(clmp, name, &palp,
+ AL_CNT_NEEDED, 0, 0) == 0)
return (0);
} else {
/*
@@ -271,15 +274,16 @@
* it must be fixed to specify the current working
* directory (ie. libc.so.1.2 -> ./libc.so.1.2).
*/
- if ((pnp = aout_fix_name(name, clmp)) == 0)
+ if (aout_fix_name(name, clmp, &palp,
+ AL_CNT_NEEDED, 0) == 0)
return (0);
}
DBG_CALL(Dbg_file_needed(clmp, name));
- nlmp = load_one(lml, lmco, pnp, clmp, MODE(clmp), 0, 0,
+ nlmp = load_one(lml, lmco, palp, clmp, MODE(clmp), 0, 0,
in_nfavl);
- remove_pnode(pnp);
+ remove_plist(&palp, 1);
if (((nlmp == 0) || (bind_one(clmp, nlmp, BND_NEEDED) == 0)) &&
((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
return (0);
@@ -321,7 +325,7 @@
aout_find_com(struct nlist *sp, const char *name)
{
static struct rtc_symb *rtcp = 0;
- struct rtc_symb *rs, * trs;
+ struct rtc_symb *rs, *trs;
const char *sl;
char *cp;
@@ -341,20 +345,21 @@
/*
* If we got here, common is not already allocated so allocate it.
*/
- if ((rs = malloc(sizeof (struct rtc_symb))) == 0)
- return (0);
- if ((rs->rtc_sp = malloc(sizeof (struct nlist))) == 0)
- return (0);
+ if ((rs = malloc(sizeof (struct rtc_symb))) == NULL)
+ return (NULL);
+ if ((rs->rtc_sp = malloc(sizeof (struct nlist))) == NULL)
+ return (NULL);
trs = rtcp;
rtcp = rs;
rs->rtc_next = trs;
*(rs->rtc_sp) = *sp;
- if ((rs->rtc_sp->n_un.n_name = malloc(strlen(name) + 1)) == 0)
- return (0);
+ if ((rs->rtc_sp->n_un.n_name = malloc(strlen(name) + 1)) == NULL)
+ return (NULL);
(void) strcpy(rs->rtc_sp->n_un.n_name, name);
rs->rtc_sp->n_type = N_COMM;
- if ((rs->rtc_sp->n_value = (long)calloc(rs->rtc_sp->n_value, 1)) == 0)
- return (0);
+ if ((rs->rtc_sp->n_value =
+ (long)calloc(rs->rtc_sp->n_value, 1)) == NULL)
+ return (NULL);
return (rs->rtc_sp);
}
@@ -401,7 +406,7 @@
AOUTDYN(lmp)->v2->ld_buckets);
p = LM2LP(lmp)->lp_hash + i;
- if (p->fssymbno != -1)
+ if (p->fssymbno != -1) {
do {
sp = &LM2LP(lmp)->lp_symtab[p->fssymbno];
cp = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx];
@@ -417,11 +422,12 @@
return (sp); /* found */
}
if (p->next == 0)
- return (0); /* not found */
+ return (NULL); /* not found */
else
continue;
} while ((p = &LM2LP(lmp)->lp_hash[p->next]) != 0);
- return (0);
+ }
+ return (NULL);
}
/*
@@ -441,7 +447,7 @@
char name[PATH_MAX];
Slookup sl = *slp;
- DBG_CALL(Dbg_syms_lookup_aout(LIST(slp->sl_imap), slp->sl_name));
+ DBG_CALL(Dbg_syms_lookup_aout(LIST(slp->sl_cmap), slp->sl_name));
if (*sl.sl_name == '_')
++sl.sl_name;
@@ -480,149 +486,57 @@
*/
if (sp->n_type == (N_EXT + N_UNDF)) {
if ((sp = aout_find_com(sp, name)) == 0)
- return ((Sym *)0);
+ return (NULL);
}
*dlmp = ilmp;
*binfo |= DBG_BINFO_FOUND;
return (aout_symconvert(sp));
}
}
- return ((Sym *)0);
-}
-
-/*
- * Map in an a.out format object.
- * Takes an open file descriptor for the object to map and
- * its pathname; returns a pointer to a Rt_map structure
- * for this object, or 0 on error.
- */
-static Rt_map *
-aout_map_so(Lm_list *lml, Aliste lmco, const char *pname, const char *oname,
- int fd)
-{
- struct exec *exec; /* working area for object headers */
- caddr_t addr; /* mmap result temporary */
- struct link_dynamic *ld; /* dynamic pointer of object mapped */
- size_t size; /* size of object */
- Rt_map *lmp; /* link map created */
- int err;
- struct nlist *nl;
-
- /*
- * Map text and allocate enough address space to fit the whole
- * library. Note that we map enough to catch the first symbol
- * in the symbol table and thereby avoid an "lseek" & "read"
- * pair to pick it up.
- */
- /* LINTED */
- exec = (struct exec *)fmap->fm_maddr;
- size = max(SIZE(*exec), N_SYMOFF(*exec) + sizeof (struct nlist));
- if ((addr = mmap(0, size, (PROT_READ | PROT_EXEC), MAP_PRIVATE,
- fd, 0)) == MAP_FAILED) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), pname,
- strerror(err));
- return (0);
- }
-
- /*
- * Grab the first symbol entry while we've got it mapped aligned
- * to file addresses. We assume that this symbol describes the
- * object's link_dynamic.
- */
- /* LINTED */
- nl = (struct nlist *)&addr[N_SYMOFF(*exec)];
- /* LINTED */
- ld = (struct link_dynamic *)&addr[nl->n_value];
-
- /*
- * Map the initialized data portion of the file to the correct
- * point in the range of allocated addresses. This will leave
- * some portion of the data segment "doubly mapped" on machines
- * where the text/data relocation alignment is not on a page
- * boundaries. However, leaving the file mapped has the double
- * advantage of both saving the munmap system call and of leaving
- * us a contiguous chunk of address space devoted to the object --
- * in case we need to unmap it all later.
- */
- if (mmap((caddr_t)(addr + M_SROUND(exec->a_text)),
- (int)exec->a_data, (PROT_READ | PROT_WRITE | PROT_EXEC),
- (MAP_FIXED | MAP_PRIVATE), fd, (off_t)exec->a_text) == MAP_FAILED) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), pname,
- strerror(err));
- return (0);
- }
-
- /*
- * Allocate pages for the object's bss, if necessary.
- */
- if (exec->a_bss != 0) {
- if (dz_map(lml, addr + M_SROUND(exec->a_text) + exec->a_data,
- (int)exec->a_bss, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE) == MAP_FAILED)
- goto error;
- }
-
- /*
- * Create link map structure for newly mapped shared object.
- */
- ld->v2 = (struct link_dynamic_2 *)((int)ld->v2 + (int)addr);
- if (!(lmp = aout_new_lm(lml, pname, oname, ld, addr, size, lmco)))
- goto error;
-
- return (lmp);
-
- /*
- * Error returns: close off file and free address space.
- */
-error:
- (void) munmap((caddr_t)addr, size);
- return (0);
+ return (NULL);
}
/*
* Create a new Rt_map structure for an a.out format object and
* initializes all values.
*/
+/* ARGSUSED6 */
Rt_map *
-aout_new_lm(Lm_list *lml, const char *pname, const char *oname,
- struct link_dynamic *ld, caddr_t addr, size_t size, Aliste lmco)
+aout_new_lmp(Lm_list *lml, Aliste lmco, Fdesc *fdp, Addr addr, size_t msize,
+ void *odyn, int *in_nfavl)
{
- Rt_map *lmp;
- caddr_t offset;
+ const char *name = fdp->fd_nname;
+ Rt_map *lmp;
+ caddr_t base, caddr = (caddr_t)addr;
+ Link_dynamic *ld = (Link_dynamic *)odyn;
+ size_t lmsz, rtsz, prsz;
- DBG_CALL(Dbg_file_aout(lml, pname, (ulong_t)ld, (ulong_t)addr,
- (ulong_t)size, lml->lm_lmidstr, lmco));
+ DBG_CALL(Dbg_file_aout(lml, name, addr, msize, lml->lm_lmidstr, lmco));
/*
* Allocate space for the link-map and private a.out information. Once
* these are allocated and initialized, we can use remove_so(0, lmp) to
* tear down the link-map should any failures occur.
*/
- if ((lmp = calloc(sizeof (Rt_map), 1)) == 0)
- return (0);
- if ((AOUTPRV(lmp) = calloc(sizeof (Rt_aoutp), 1)) == 0) {
- free(lmp);
- return (0);
- }
- if ((((Rt_aoutp *)AOUTPRV(lmp))->lm_lpd =
- calloc(sizeof (struct ld_private), 1)) == 0) {
- free(AOUTPRV(lmp));
- free(lmp);
- return (0);
- }
+ rtsz = S_DROUND(sizeof (Rt_map));
+ prsz = S_DROUND(sizeof (Rt_aoutp));
+ lmsz = rtsz + prsz + sizeof (struct ld_private);
+ if ((lmp = calloc(lmsz, 1)) == NULL)
+ return (NULL);
+ AOUTPRV(lmp) = (void *)((uintptr_t)lmp + rtsz);
+ ((Rt_aoutp *)AOUTPRV(lmp))->lm_lpd =
+ (void *)((uintptr_t)lmp + rtsz + prsz);
+ LMSIZE(lmp) = lmsz;
/*
* All fields not filled in were set to 0 by calloc.
*/
- ORIGNAME(lmp) = PATHNAME(lmp) = NAME(lmp) = (char *)pname;
- ADDR(lmp) = (ulong_t)addr;
- MSIZE(lmp) = (ulong_t)size;
+ NAME(lmp) = (char *)name;
+ ADDR(lmp) = addr;
+ MSIZE(lmp) = msize;
SYMINTP(lmp) = aout_find_sym;
FCT(lmp) = &aout_fct;
LIST(lmp) = lml;
- THREADID(lmp) = rt_thr_self();
OBJFLTRNDX(lmp) = FLTR_DISABLED;
SORTVAL(lmp) = -1;
@@ -630,59 +544,48 @@
* Specific settings for a.out format.
*/
if (lml->lm_head == 0) {
- offset = (caddr_t)MAIN_BASE;
+ base = (caddr_t)MAIN_BASE;
FLAGS(lmp) |= FLG_RT_FIXED;
} else
- offset = addr;
-
- ETEXT(lmp) = (ulong_t)&offset[ld->v2->ld_text];
-
- /*
- * Create a mapping descriptor to describe the whole object as a single
- * mapping.
- */
- if ((MMAPS(lmp) = calloc(2, sizeof (Mmap))) == 0)
- return (0);
- MMAPS(lmp)->m_vaddr = offset;
- /* LINTED */
- MMAPS(lmp)->m_msize = max(SIZE(*(struct exec *)offset),
- N_SYMOFF((*(struct exec *)offset)) + sizeof (struct nlist));
- MMAPS(lmp)->m_fsize = MMAPS(lmp)->m_msize;
- MMAPCNT(lmp) = 1;
+ base = caddr;
/*
- * Fill in all AOUT information.
+ * Fill in all AOUT information. Applications provide the Link_dynamic
+ * offset via the boot block, but if this is a shared object that
+ * ld.so.1 has mapped, then determine the Link_dynamic offset from the
+ * mapped image.
*/
+ if (ld == NULL) {
+ /* LINTED */
+ struct exec *exec = (struct exec *)caddr;
+ struct nlist *nl;
+
+ /* LINTED */
+ nl = (struct nlist *)&caddr[N_SYMOFF(*exec)];
+ /* LINTED */
+ ld = (Link_dynamic *)&caddr[nl->n_value];
+
+ ld->v2 = (struct link_dynamic_2 *)((int)ld->v2 + (int)caddr);
+ }
AOUTDYN(lmp) = ld;
- if ((RPATH(lmp) = (char *)&offset[ld->v2->ld_rules]) == offset)
+
+ if ((RPATH(lmp) = (char *)&base[ld->v2->ld_rules]) == base)
RPATH(lmp) = 0;
- LM2LP(lmp)->lp_symbol_base = addr;
+ LM2LP(lmp)->lp_symbol_base = caddr;
/* LINTED */
- LM2LP(lmp)->lp_plt = (struct jbind *)(&addr[JMPOFF(ld)]);
+ LM2LP(lmp)->lp_plt = (struct jbind *)(&caddr[JMPOFF(ld)]);
LM2LP(lmp)->lp_rp =
/* LINTED */
- (struct relocation_info *)(&offset[RELOCOFF(ld)]);
+ (struct relocation_info *)(&base[RELOCOFF(ld)]);
/* LINTED */
- LM2LP(lmp)->lp_hash = (struct fshash *)(&offset[HASHOFF(ld)]);
+ LM2LP(lmp)->lp_hash = (struct fshash *)(&base[HASHOFF(ld)]);
/* LINTED */
- LM2LP(lmp)->lp_symtab = (struct nlist *)(&offset[SYMOFF(ld)]);
- LM2LP(lmp)->lp_symstr = &offset[STROFF(ld)];
- LM2LP(lmp)->lp_textbase = offset;
+ LM2LP(lmp)->lp_symtab = (struct nlist *)(&base[SYMOFF(ld)]);
+ LM2LP(lmp)->lp_symstr = &base[STROFF(ld)];
+ LM2LP(lmp)->lp_textbase = base;
LM2LP(lmp)->lp_refcnt++;
LM2LP(lmp)->lp_dlp = NULL;
- if (rtld_flags & RT_FL_RELATIVE)
- FLAGS1(lmp) |= FL1_RT_RELATIVE;
-
- if ((CONDVAR(lmp) = rt_cond_create()) == 0) {
- remove_so(0, lmp);
- return (0);
- }
- if (oname && ((append_alias((lmp), oname, 0)) == 0)) {
- remove_so(0, lmp);
- return (0);
- }
-
/*
* Add the mapped object to the end of the link map list.
*/
@@ -691,42 +594,12 @@
}
/*
- * Function to correct protection settings.
- * Segments are all mapped initially with permissions as given in
- * the segment header, but we need to turn on write permissions
- * on a text segment if there are any relocations against that segment,
- * and them turn write permission back off again before returning control
- * to the program. This function turns the permission on or off depending
- * on the value of the argument.
- */
-int
-aout_set_prot(Rt_map *lmp, int permission)
-{
- int prot; /* protection setting */
- caddr_t et; /* cached _etext of object */
- size_t size; /* size of text segment */
-
- DBG_CALL(Dbg_file_prot(lmp, permission));
-
- et = (caddr_t)ETEXT(lmp);
- size = M_PROUND((ulong_t)(et - TEXTBASE(lmp)));
- prot = PROT_READ | PROT_EXEC | permission;
- if (mprotect((caddr_t)TEXTBASE(lmp), size, prot) == -1) {
- int err = errno;
-
- eprintf(LIST(lmp), ERR_FATAL, MSG_INTL(MSG_SYS_MPROT),
- NAME(lmp), strerror(err));
- return (0);
- }
- return (1);
-}
-
-/*
* Build full pathname of shared object from the given directory name and
* filename.
*/
static char *
-aout_get_so(const char *dir, const char *file)
+/* ARGSUSED2 */
+aout_get_so(const char *dir, const char *file, size_t dlen, size_t flen)
{
struct db *dbp;
char *path = NULL;
@@ -804,8 +677,8 @@
* individual link-maps we don't need to supply a starting link-map to the
* lookup routine (see lookup_sym():analyze.c).
*/
-Sym *
-aout_dlsym_handle(Grp_hdl * ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo,
+static Sym *
+aout_dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo,
int *in_nfavl)
{
Sym *sym;
@@ -829,3 +702,66 @@
return (dlsym_handle(ghp, &sl, _lmp, binfo, in_nfavl));
}
+
+/*
+ * The initial mapping of the a.out occurs through exec(2), and presently this
+ * implementation doesn't provide a mmapobj_result_t array to ld.so.1. Thus,
+ * aout_get_mmap() is called to create the mapping information. Unlike ELF,
+ * the information that can be gathered from a mapped AOUT file, can be limited.
+ * In some cases the AOUT header isn't available in the mapped image, and thus
+ * this can't be inspected to determine the files size (the kernel always
+ * returns a pointer to the AOUT dynamic structure, but this is only sufficient
+ * to determine the size of the text segment).
+ *
+ * Therefore, the only generic mechanism of determining the AOUT's mapping is
+ * to use /proc. Only two mappings are required, the text (to determine any
+ * read-only region), and the data. The two mapping validate the range in
+ * which any relocations will occur. Should there be an additional bss segment,
+ * we don't care, as this can't be relocated, and we're never going to try
+ * unmapping the a.out.
+ */
+int
+aout_get_mmap(Lm_list *lml, mmapobj_result_t *mpp)
+{
+ prmap_t *maps;
+ char proc[16];
+ int num, err, fd;
+
+ (void) snprintf(proc, 16, MSG_ORIG(MSG_FMT_PROC), (int)getpid());
+ if ((fd = open(proc, O_RDONLY)) == -1) {
+ err = errno;
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc,
+ strerror(err));
+ return (1);
+ }
+
+ if (ioctl(fd, PIOCNMAP, (void *)&num) == -1) {
+ err = errno;
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), strerror(err));
+ return (1);
+ }
+
+ if ((maps = malloc((num + 1) * sizeof (prmap_t))) == NULL)
+ return (1);
+
+ if (ioctl(fd, PIOCMAP, (void *)maps) == -1) {
+ err = errno;
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), strerror(err));
+ free(maps);
+ return (1);
+ }
+
+ mpp->mr_addr = maps->pr_vaddr;
+ mpp->mr_fsize = mpp->mr_msize = maps->pr_size;
+ mpp->mr_prot = (PROT_READ | PROT_EXEC);
+
+ mpp++, maps++;
+
+ mpp->mr_addr = maps->pr_vaddr;
+ mpp->mr_fsize = mpp->mr_msize = maps->pr_size;
+ mpp->mr_prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
+
+ maps--;
+ free(maps);
+ return (0);
+}
--- a/usr/src/cmd/sgs/rtld/common/analyze.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/analyze.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <sys/debug.h>
#include <fcntl.h>
#include <limits.h>
#include <dlfcn.h>
@@ -44,16 +45,10 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_a.out.h"
+#include "_inline.h"
#include "msg.h"
-static Fct *vector[] = {
- &elf_fct,
-#ifdef A_OUT
- &aout_fct,
-#endif
- 0
-};
-
/*
* If a load filter flag is in effect, and this object is a filter, trigger the
* loading of all its filtees. The load filter flag is in effect when creating
@@ -96,13 +91,14 @@
* initial object. As dependencies are analyzed they are added to the link-map
* control list. Thus the list grows as we traverse it - this results in the
* breadth first ordering of all needed objects.
+ *
+ * Return the initial link-map from which analysis starts for relocate_lmc().
*/
-int
+Rt_map *
analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, int *in_nfavl)
{
- Rt_map *lmp = nlmp;
+ Rt_map *lmp;
Lm_cntl *nlmc;
- int ret = 1;
/*
* If this link-map control list is being analyzed, return. The object
@@ -115,7 +111,7 @@
/* LINTED */
nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
if (nlmc->lc_flags & LMC_FLG_ANALYZING)
- return (1);
+ return (nlmp);
/*
* If this object doesn't belong to the present link-map control list
@@ -124,11 +120,11 @@
* case, ignore the object as it's already being taken care of.
*/
if (nlmco != CNTL(nlmp))
- return (1);
+ return (nlmp);
nlmc->lc_flags |= LMC_FLG_ANALYZING;
- for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
+ for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
if (FLAGS(lmp) &
(FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE))
continue;
@@ -143,12 +139,31 @@
* need to finish the link-editing of the object at this point.
*/
if (FLAGS(lmp) & FLG_RT_OBJECT) {
- if (elf_obj_fini(lml, lmp, in_nfavl) == 0) {
+ Rt_map *olmp;
+
+ if ((olmp = elf_obj_fini(lml, lmp, in_nfavl)) == NULL) {
if (lml->lm_flags & LML_FLG_TRC_ENABLE)
continue;
- ret = 0;
+ nlmp = NULL;
break;
}
+
+ /*
+ * The original link-map that captured a relocatable
+ * object is a temporary link-map, that basically acts
+ * as a place holder in the link-map list. On
+ * completion of relocatable object processing, a new
+ * link-map is created, and switched with the place
+ * holder. Therefore, reassign both the present
+ * link-map pointer and the return link-map pointer.
+ * The former resets this routines link-map processing,
+ * while the latter provides for later functions, like
+ * relocate_lmc(), to start processing from this new
+ * link-map.
+ */
+ if (nlmp == lmp)
+ nlmp = olmp;
+ lmp = olmp;
}
DBG_CALL(Dbg_file_analyze(lmp));
@@ -159,7 +174,7 @@
if (LM_NEEDED(lmp)(lml, nlmco, lmp, in_nfavl) == 0) {
if (lml->lm_flags & LML_FLG_TRC_ENABLE)
continue;
- ret = 0;
+ nlmp = NULL;
break;
}
@@ -195,7 +210,7 @@
nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
nlmc->lc_flags &= ~LMC_FLG_ANALYZING;
- return (ret);
+ return (nlmp);
}
/*
@@ -214,8 +229,8 @@
static int
are_bits_zero(Rt_map *dlmp, Sym *dsym, int dest)
{
- Mmap *mmap = NULL, *mmaps;
- caddr_t daddr = (caddr_t)dsym->st_value;
+ mmapobj_result_t *mpp;
+ caddr_t daddr = (caddr_t)dsym->st_value;
if ((FLAGS(dlmp) & FLG_RT_FIXED) == 0)
daddr += ADDR(dlmp);
@@ -225,20 +240,13 @@
* the copy relocation records have already been captured and verified,
* a segment must be found (but we add an escape clause never the less).
*/
- for (mmaps = MMAPS(dlmp); mmaps->m_vaddr; mmaps++) {
- if ((daddr >= mmaps->m_vaddr) &&
- (daddr < (mmaps->m_vaddr + mmaps->m_msize))) {
- mmap = mmaps;
- break;
- }
- }
- if (mmap == NULL)
+ if ((mpp = find_segment(daddr, dlmp)) == NULL)
return (1);
/*
* If the definition is not within .bss, indicate this is not zero data.
*/
- if (daddr < (mmap->m_vaddr + mmaps->m_fsize))
+ if (daddr < (mpp->mr_addr + mpp->mr_offset + mpp->mr_fsize))
return (0);
/*
@@ -269,6 +277,9 @@
static int
relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now, int *in_nfavl)
{
+ APlist *textrel = NULL;
+ int ret = 1;
+
/*
* If we're running under ldd(1), and haven't been asked to trace any
* warnings, skip any actual relocation processing.
@@ -279,18 +290,44 @@
if (relocated)
(*relocated)++;
- if ((LM_RELOC(lmp)(lmp, now, in_nfavl) == 0) &&
+ if ((LM_RELOC(lmp)(lmp, now, in_nfavl, &textrel) == 0) &&
+ ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
+ ret = 0;
+
+ /*
+ * Finally process any move data. Note, this is carried out
+ * with ldd(1) under relocation processing too, as it can flush
+ * out move errors, and enables lari(1) to provide a true
+ * representation of the runtime bindings.
+ */
+ if ((FLAGS(lmp) & FLG_RT_MOVE) &&
+ (move_data(lmp, &textrel) == 0) &&
((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
- return (0);
+ ret = 0;
}
- return (1);
+
+ /*
+ * If a text segment was write enabled to perform any relocations or
+ * move records, then re-protect the segment by disabling writes.
+ */
+ if (textrel) {
+ mmapobj_result_t *mpp;
+ Aliste idx;
+
+ for (APLIST_TRAVERSE(textrel, idx, mpp))
+ (void) set_prot(lmp, mpp, 0);
+ free(textrel);
+ }
+
+ return (ret);
}
/*
* Relocate the objects on a link-map control list.
*/
static int
-_relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated, int *in_nfavl)
+_relocate_lmc(Lm_list *lml, Aliste lmco, Rt_map *nlmp, int *relocated,
+ int *in_nfavl)
{
Rt_map *lmp;
@@ -322,23 +359,20 @@
FLAGS(lmp) |= FLG_RT_RELOCED;
/*
- * Mark this object's init is available for harvesting. Under
- * ldd(1) this marking is necessary for -i (tsort) gathering.
+ * If this object is being relocated on the main link-map list
+ * indicate that this object's init is available for harvesting.
+ * Objects that are being collected on other link-map lists
+ * will have there init availability tagged when the objects
+ * are move to the main link-map list (ie, after we know they,
+ * and their dependencies, are fully relocated and ready for
+ * use).
+ *
+ * Note, even under ldd(1) this init identification is necessary
+ * for -i (tsort) gathering.
*/
- lml->lm_init++;
- lml->lm_flags |= LML_FLG_OBJADDED;
-
- /*
- * Process any move data. Note, this is carried out under ldd
- * under relocation processing too, as it can flush out move
- * errors, and enables lari(1) to provide a true representation
- * of the runtime bindings.
- */
- if ((FLAGS(lmp) & FLG_RT_MOVE) &&
- (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||
- (lml->lm_flags & LML_FLG_TRC_WARN))) {
- if (move_data(lmp) == 0)
- return (0);
+ if (lmco == ALIST_OFF_DATA) {
+ lml->lm_init++;
+ lml->lm_flags |= LML_FLG_OBJADDED;
}
/*
@@ -486,7 +520,7 @@
* to the present link-map control list, try and clean up any
* failed objects now.
*/
- lret = _relocate_lmc(lml, nlmp, &relocated, in_nfavl);
+ lret = _relocate_lmc(lml, nlmco, nlmp, &relocated, in_nfavl);
if ((lret == 0) && (nlmco != ALIST_OFF_DATA))
remove_lmc(lml, clmp, nlmc, nlmco, NAME(nlmp));
}
@@ -625,129 +659,20 @@
if (rej2->rej_type && (rej1->rej_type == 0)) {
rej1->rej_type = rej2->rej_type;
rej1->rej_info = rej2->rej_info;
- rej1->rej_flag = rej2->rej_flag;
+ rej1->rej_flags = rej2->rej_flags;
if (rej2->rej_name)
- rej1->rej_name = strdup(rej2->rej_name);
- if (rej2->rej_str) {
- if ((rej1->rej_str = strdup(rej2->rej_str)) == NULL)
- rej1->rej_str = MSG_ORIG(MSG_EMG_ENOMEM);
- }
- }
-}
-
-/*
- * Determine the object type of a file.
- */
-Fct *
-are_u_this(Rej_desc *rej, int fd, rtld_stat_t *status, const char *name)
-{
- int i;
- char *maddr = 0;
-
- fmap->fm_fsize = status->st_size;
-
- /*
- * If this is a directory (which can't be mmap()'ed) generate a precise
- * error message.
- */
- if ((status->st_mode & S_IFMT) == S_IFDIR) {
- rej->rej_type = SGS_REJ_STR;
- rej->rej_str = strerror(EISDIR);
- return (NULL);
- }
-
- /*
- * Map in the first page of the file. When this buffer is first used,
- * the mapping is a single system page. This is typically enough to
- * inspect the ehdr and phdrs of the file, and can be reused for each
- * file that get loaded. If a larger mapping is required to read the
- * ehdr and phdrs, a new mapping is created (see elf_map_it()). This
- * new mapping is again used for each new file loaded. Some objects,
- * such as filters, only take up one page, and in this case this mapping
- * will suffice for the file.
- */
- maddr = mmap(fmap->fm_maddr, fmap->fm_msize, (PROT_READ | PROT_EXEC),
- fmap->fm_mflags, fd, 0);
-#if defined(MAP_ALIGN)
- if ((maddr == MAP_FAILED) && (errno == EINVAL)) {
- /*
- * If the mapping failed, and we used MAP_ALIGN, assume we're
- * on a system that doesn't support this option. Try again
- * without MAP_ALIGN.
- */
- if (fmap->fm_mflags & MAP_ALIGN) {
- rtld_flags2 |= RT_FL2_NOMALIGN;
- fmap_setup();
-
- maddr = (char *)mmap(fmap->fm_maddr, fmap->fm_msize,
- (PROT_READ | PROT_EXEC), fmap->fm_mflags, fd, 0);
- }
+ rej1->rej_name = stravl_insert(rej2->rej_name, 0, 0, 0);
+ if ((rej2->rej_str) && ((rej1->rej_str =
+ stravl_insert(rej2->rej_str, 0, 0, 0)) == NULL))
+ rej1->rej_str = MSG_ORIG(MSG_EMG_ENOMEM);
}
-#endif
- if (maddr == MAP_FAILED) {
- rej->rej_type = SGS_REJ_STR;
- rej->rej_str = strerror(errno);
- return (NULL);
- }
-
- /*
- * From now on we will re-use fmap->fm_maddr as the mapping address
- * so we augment the flags with MAP_FIXED and drop any MAP_ALIGN.
- */
- fmap->fm_maddr = maddr;
- fmap->fm_mflags |= MAP_FIXED;
-#if defined(MAP_ALIGN)
- fmap->fm_mflags &= ~MAP_ALIGN;
-#endif
-
- /*
- * Search through the object vectors to determine what kind of
- * object we have.
- */
- for (i = 0; vector[i]; i++) {
- if ((vector[i]->fct_are_u_this)(rej))
- return (vector[i]);
- else if (rej->rej_type) {
- Rt_map *lmp;
-
- /*
- * If this object is an explicitly defined shared
- * object under inspection by ldd, and contains a
- * incompatible capabilities requirement, then
- * inform the user, but continue processing.
- *
- * XXXX - ldd -v for any rej failure.
- */
- if (((rej->rej_type == SGS_REJ_HWCAP_1) ||
- (rej->rej_type == SGS_REJ_SFCAP_1)) &&
- (lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) &&
- ((lmp = lml_main.lm_head) != 0) &&
- (FLAGS1(lmp) & FL1_RT_LDDSTUB) &&
- (NEXT(lmp) == 0)) {
- const char *fmt;
- if (rej->rej_type == SGS_REJ_HWCAP_1)
- fmt = MSG_INTL(MSG_LDD_GEN_HWCAP_1);
- else
- fmt = MSG_INTL(MSG_LDD_GEN_SFCAP_1);
- (void) printf(fmt, name, rej->rej_str);
- return (vector[i]);
- }
- return (NULL);
- }
- }
-
- /*
- * Unknown file type.
- */
- rej->rej_type = SGS_REJ_UNKFILE;
- return (NULL);
}
/*
* Helper routine for is_so_matched() that consolidates matching a path name,
* or file name component of a link-map name.
*/
-static int
+inline static int
_is_so_matched(const char *name, const char *str, int path)
{
const char *_str;
@@ -766,81 +691,45 @@
*
* . a NAME() - typically the full pathname of an object that has been
* loaded. For example, when looking for the dependency "libc.so.1", a
- * search path is applied, with the eventual NAME() being "/lib/ld.so.1".
- * The name of the executable is typically a simple filename, such as
- * "main", as this is the name passed to exec() to start the process.
+ * search path is applied, with the eventual NAME() being "/lib/libc.so.1".
+ * The name of a dynamic executable can be a simple filename, such as
+ * "main", as this can be the name passed to exec() to start the process.
*
* . a PATHNAME() - this is maintained if the resolved NAME() is different
- * to NAME(), ie. the original name is a symbolic link. This is also
- * the resolved full pathname for a dynamic executable.
+ * than NAME(), ie. a component of the original name is a symbolic link.
+ * This is also the resolved full pathname for a simple dynamic executable.
*
- * . a list of ALIAS() names - these are alternative names by which the
- * object has been found, ie. when dependencies are loaded through a
- * variety of different symbolic links.
+ * . an ALIAS() name - these are alternative names by which the object has
+ * been found, ie. when dependencies are loaded through a variety of
+ * different symbolic links.
*
* The name pattern matching can differ depending on whether we are looking
* for a full path name (path != 0), or a simple file name (path == 0). Full
- * path names typically match NAME() or PATHNAME() entries, so these link-map
- * names are inspected first when a full path name is being searched for.
- * Simple file names typically match ALIAS() names, so these link-map names are
- * inspected first when a simple file name is being searched for.
+ * path names typically match NAME() or PATHNAME() entries.
*
* For all full path name searches, the link-map names are taken as is. For
* simple file name searches, only the file name component of any link-map
* names are used for comparison.
*/
-static Rt_map *
+inline static Rt_map *
is_so_matched(Rt_map *lmp, const char *name, int path)
{
Aliste idx;
const char *cp;
- /*
- * A pathname is typically going to match a NAME() or PATHNAME(), so
- * check these first.
- */
- if (path) {
- if (strcmp(name, NAME(lmp)) == 0)
+ if (_is_so_matched(name, NAME(lmp), path) == 0)
+ return (lmp);
+
+ if (PATHNAME(lmp) != NAME(lmp)) {
+ if (_is_so_matched(name, PATHNAME(lmp), path) == 0)
return (lmp);
-
- if (PATHNAME(lmp) != NAME(lmp)) {
- if (strcmp(name, PATHNAME(lmp)) == 0)
- return (lmp);
- }
}
- /*
- * Typically, dependencies are specified as simple file names
- * (DT_NEEDED == libc.so.1), which are expanded to full pathnames to
- * open the file. The full pathname is NAME(), and the original name
- * is maintained on the ALIAS() list.
- *
- * If this is a simple filename, or a pathname has failed to match the
- * NAME() and PATHNAME() check above, look through the ALIAS() list.
- */
for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) {
- /*
- * If we're looking for a simple filename, _is_so_matched()
- * will reduce the ALIAS name to its simple name.
- */
if (_is_so_matched(name, cp, path) == 0)
return (lmp);
}
- /*
- * Finally, if this is a simple file name, and any ALIAS() search has
- * been completed, match the simple file name of NAME() and PATHNAME().
- */
- if (path == 0) {
- if (_is_so_matched(name, NAME(lmp), 0) == 0)
- return (lmp);
-
- if (PATHNAME(lmp) != NAME(lmp)) {
- if (_is_so_matched(name, PATHNAME(lmp), 0) == 0)
- return (lmp);
- }
- }
-
return (NULL);
}
@@ -871,7 +760,7 @@
*
* A full path name, which is a fully resolved path name that starts with a "/"
* character, or a relative path name that includes a "/" character, must match
- * the link-map names explicitly. A simple file name, which is any name *not*
+ * the link-map names exactly. A simple file name, which is any name *not*
* containing a "/" character, are matched against the file name component of
* any link-map names.
*/
@@ -889,10 +778,13 @@
* registered on the FullPathNode AVL, or not-found AVL trees.
*/
if (name[0] == '/') {
- if (((lmp = fpavl_recorded(lml, name, &where)) != NULL) &&
+ uint_t hash = sgs_str_hash(name);
+
+ if (((lmp = fpavl_recorded(lml, name, hash, &where)) != NULL) &&
((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0))
return (lmp);
- if (nfavl_recorded(name, 0)) {
+
+ if (nfavl_recorded(name, hash, 0)) {
/*
* For dlopen() and dlsym() fall backs, indicate that
* a registered not-found path has indicated that this
@@ -975,7 +867,7 @@
* Was an alternative pathname defined (from a configuration
* file).
*/
- if (rej->rej_flag & FLG_FD_ALTER)
+ if (rej->rej_flags & FLG_REJ_ALTER)
str = MSG_INTL(MSG_LDD_FIL_ALTER);
} else {
if (alter)
@@ -1052,15 +944,6 @@
(void) aplist_append(&lmc->lc_now, lmp, AL_CNT_LMNOW);
}
-#ifdef SIEBEL_DISABLE
- /*
- * For patch backward compatibility the following .init collection
- * is disabled.
- */
- if (rtld_flags & RT_FL_DISFIX_1)
- return (pmode);
-#endif
-
/*
* If this objects .init has been collected but has not yet been called,
* it may be necessary to reevaluate the object using tsort(). For
@@ -1090,15 +973,15 @@
* Determine whether an alias name already exists, and if not create one. This
* is typically used to retain dependency names, such as "libc.so.1", which
* would have been expanded to full path names when they were loaded. The
- * full path names (NAME() and possibly PATHNAME()) are maintained as Fullpath
- * AVL nodes, and thus would have been matched by fpavl_loaded() during
- * file_open().
+ * full path names (NAME() and possibly PATHNAME()) are maintained on the
+ * FullPathNode AVL tree, and thus would have been matched by fpavl_loaded()
+ * during file_open().
*/
int
append_alias(Rt_map *lmp, const char *str, int *added)
{
- Aliste idx;
- char *cp;
+ const char *cp;
+ Aliste idx;
/*
* Determine if this filename is already on the alias list.
@@ -1111,13 +994,10 @@
/*
* This is a new alias, append it to the alias list.
*/
- if ((cp = strdup(str)) == NULL)
+ if (((cp = stravl_insert(str, 0, 0, 0)) == NULL) ||
+ (aplist_append(&ALIAS(lmp), cp, AL_CNT_ALIAS) == NULL))
return (0);
- if (aplist_append(&ALIAS(lmp), cp, AL_CNT_ALIAS) == NULL) {
- free(cp);
- return (0);
- }
if (added)
*added = 1;
return (1);
@@ -1200,7 +1080,7 @@
*/
void
file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags,
- Rej_desc * rej)
+ Rej_desc *rej)
{
int secure = 0;
@@ -1243,18 +1123,21 @@
}
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)
+file_open(int err, Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp,
+ Rej_desc *rej, int *in_nfavl)
{
rtld_stat_t status;
Rt_map *nlmp;
- int resolved = 0;
- char *name;
avl_index_t nfavlwhere = 0;
-
- fdesc->fd_oname = oname;
-
- if ((err == 0) && (fdesc->fd_flags & FLG_FD_ALTER))
+ const char *oname = fdp->fd_oname, *nname = fdp->fd_nname;
+ uint_t hash = sgs_str_hash(nname);
+
+
+ if ((nname = stravl_insert(fdp->fd_nname, hash, 0, 0)) == NULL)
+ return (0);
+ fdp->fd_nname = nname;
+
+ if ((err == 0) && (fdp->fd_flags & FLG_FD_ALTER))
DBG_CALL(Dbg_file_config_obj(lml, oname, 0, nname));
/*
@@ -1264,26 +1147,22 @@
* one previously used, the process may have changed directory.
*/
if ((err == 0) && (nname[0] == '/')) {
- if ((nlmp = fpavl_recorded(lml, nname,
- &(fdesc->fd_avlwhere))) != NULL) {
- fdesc->fd_nname = nname;
- fdesc->fd_lmp = nlmp;
+ if ((nlmp = fpavl_recorded(lml, nname, hash,
+ &(fdp->fd_avlwhere))) != NULL) {
+ fdp->fd_lmp = nlmp;
return (1);
}
- if (nfavl_recorded(nname, &nfavlwhere)) {
+ if (nfavl_recorded(nname, hash, &nfavlwhere)) {
/*
* For dlopen() and dlsym() fall backs, indicate that
* a registered not-found path has indicated that this
* object does not exist. If this path has been
* constructed as part of expanding a HWCAP directory,
- * and as this is a silent failure, where no rejection
- * message is created, free the original name to
- * simplify the life of the caller.
+ * this is a silent failure, where no rejection message
+ * is created.
*/
if (in_nfavl)
(*in_nfavl)++;
- if (flags & FLG_RT_HWCAP)
- free((void *)nname);
return (0);
}
}
@@ -1295,14 +1174,25 @@
/*
* If this path has been constructed as part of expanding a
* HWCAP directory, ignore any subdirectories. As this is a
- * silent failure, where no rejection message is created, free
- * the original name to simplify the life of the caller. For
- * any other reference that expands to a directory, fall through
+ * silent failure, no rejection message is created. For any
+ * other reference that expands to a directory, fall through
* to construct a meaningful rejection message.
*/
if ((flags & FLG_RT_HWCAP) &&
- ((status.st_mode & S_IFMT) == S_IFDIR)) {
- free((void *)nname);
+ ((status.st_mode & S_IFMT) == S_IFDIR))
+ return (0);
+
+ /*
+ * If this is a directory (which can't be mmap()'ed) generate a
+ * precise error message.
+ */
+ if ((status.st_mode & S_IFMT) == S_IFDIR) {
+ rej->rej_name = nname;
+ if (fdp->fd_flags & FLG_FD_ALTER)
+ rej->rej_flags = FLG_REJ_ALTER;
+ rej->rej_type = SGS_REJ_STR;
+ rej->rej_str = strerror(EISDIR);
+ DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH));
return (0);
}
@@ -1310,20 +1200,22 @@
* Resolve the filename and determine whether the resolved name
* is already known. Typically, the previous fpavl_loaded()
* will have caught this, as both NAME() and PATHNAME() for a
- * link-map are recorded in the FullNode AVL tree. However,
+ * link-map are recorded in the FullPathNode AVL tree. However,
* instances exist where a file can be replaced (loop-back
* mounts, bfu, etc.), and reference is made to the original
* file through a symbolic link. By checking the pathname here,
* we don't fall through to the dev/inode check and conclude
* that a new file should be loaded.
*/
- if ((nname[0] == '/') && (rtld_flags & RT_FL_EXECNAME) &&
+ if ((nname[0] == '/') &&
((size = resolvepath(nname, path, (PATH_MAX - 1))) > 0)) {
path[size] = '\0';
+ fdp->fd_flags |= FLG_FD_RESOLVED;
+
if (strcmp(nname, path)) {
if ((nlmp =
- fpavl_recorded(lml, path, 0)) != NULL) {
+ fpavl_recorded(lml, path, 0, 0)) != NULL) {
added = 0;
if (append_alias(nlmp, nname,
@@ -1334,8 +1226,7 @@
DBG_CALL(Dbg_file_skip(LIST(clmp),
NAME(nlmp), nname));
/* END CSTYLED */
- fdesc->fd_nname = nname;
- fdesc->fd_lmp = nlmp;
+ fdp->fd_lmp = nlmp;
return (1);
}
@@ -1345,17 +1236,9 @@
* have to be recomputed as part of fullpath()
* processing.
*/
- if ((fdesc->fd_pname = strdup(path)) == NULL)
+ if ((fdp->fd_pname = stravl_insert(path, 0,
+ (size + 1), 0)) == NULL)
return (0);
- resolved = 1;
- } else {
- /*
- * If the resolved name doesn't differ from the
- * original, save it without duplication.
- * Having fd_pname set indicates that no further
- * resolvepath processing is necessary.
- */
- fdesc->fd_pname = nname;
}
}
@@ -1372,8 +1255,8 @@
/*
* Otherwise, if an alternatively named file
* has been found for the same dev/inode, add
- * a new name alias, and insert any alias full
- * pathname in the link-map lists AVL tree.
+ * a new name alias. Insert any alias full path
+ * name in the FullPathNode AVL tree.
*/
added = 0;
@@ -1393,8 +1276,7 @@
* Record in the file descriptor the existing object
* that satisfies this open request.
*/
- fdesc->fd_nname = nname;
- fdesc->fd_lmp = nlmp;
+ fdp->fd_lmp = nlmp;
return (1);
}
@@ -1406,26 +1288,27 @@
rej->rej_type = SGS_REJ_STR;
rej->rej_str = strerror(errno);
} else {
- Fct *ftp;
-
- if ((ftp = are_u_this(rej, fd, &status, nname)) != 0) {
- fdesc->fd_nname = nname;
- fdesc->fd_ftp = ftp;
- fdesc->fd_dev = status.st_dev;
- fdesc->fd_ino = status.st_ino;
- fdesc->fd_fd = fd;
+ /*
+ * Map the object. A successful return indicates that
+ * the object is appropriate for ld.so.1 processing.
+ */
+ fdp->fd_ftp = map_obj(lml, fdp, status.st_size, nname,
+ fd, rej);
+ (void) close(fd);
+
+ if (fdp->fd_ftp != NULL) {
+ fdp->fd_dev = status.st_dev;
+ fdp->fd_ino = status.st_ino;
/*
* Trace that this open has succeeded.
*/
if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
trace_so(clmp, 0, oname, nname,
- (fdesc->fd_flags & FLG_FD_ALTER),
- 0);
+ (fdp->fd_flags & FLG_FD_ALTER), 0);
}
return (1);
}
- (void) close(fd);
}
} else if (errno != ENOENT) {
@@ -1441,23 +1324,16 @@
* Regardless of error, duplicate and record any full path names that
* can't be used on the "not-found" AVL tree.
*/
- if ((nname[0] == '/') && ((name = strdup(nname)) != NULL))
- nfavl_insert(name, nfavlwhere);
+ if (nname[0] == '/')
+ nfavl_insert(nname, nfavlwhere);
/*
* Indicate any rejection.
*/
if (rej->rej_type) {
- /*
- * If this pathname was resolved and duplicated, remove the
- * allocated name to simplify the cleanup of the callers.
- */
- if (resolved) {
- free((void *)fdesc->fd_pname);
- fdesc->fd_pname = NULL;
- }
rej->rej_name = nname;
- rej->rej_flag = (fdesc->fd_flags & FLG_FD_ALTER);
+ if (fdp->fd_flags & FLG_FD_ALTER)
+ rej->rej_flags = FLG_REJ_ALTER;
DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH));
}
return (0);
@@ -1467,10 +1343,11 @@
* Find a full pathname (it contains a "/").
*/
int
-find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
- Fdesc *fdesc, Rej_desc *rej, int *in_nfavl)
+find_path(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
+ int *in_nfavl)
{
- int err = 0;
+ const char *oname = fdp->fd_oname;
+ int err = 0;
/*
* If directory configuration exists determine if this path is known.
@@ -1497,7 +1374,9 @@
(rtld_flags & RT_FL_OBJALT) && (lml == &lml_main)) {
int ret;
- fdesc->fd_flags |= FLG_FD_ALTER;
+ fdp->fd_flags |= FLG_FD_ALTER;
+ fdp->fd_nname = aname;
+
/*
* Attempt to open the alternative path. If
* this fails, and the alternative is flagged
@@ -1506,28 +1385,30 @@
*/
DBG_CALL(Dbg_libs_found(lml, aname,
FLG_FD_ALTER));
- if (((ret = file_open(0, lml, oname, aname,
- clmp, flags, fdesc, rej, in_nfavl)) != 0) ||
- ((obj->co_flags & RTC_OBJ_OPTINAL) == 0))
+ ret = file_open(0, lml, clmp, flags, fdp,
+ rej, in_nfavl);
+ if (ret || ((obj->co_flags &
+ RTC_OBJ_OPTINAL) == 0))
return (ret);
- fdesc->fd_flags &= ~FLG_FD_ALTER;
+ fdp->fd_flags &= ~FLG_FD_ALTER;
}
}
}
DBG_CALL(Dbg_libs_found(lml, oname, 0));
- return (file_open(err, lml, oname, oname, clmp, flags, fdesc,
- rej, in_nfavl));
+ fdp->fd_nname = oname;
+ return (file_open(err, lml, clmp, flags, fdp, rej, in_nfavl));
}
/*
* Find a simple filename (it doesn't contain a "/").
*/
static int
-_find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp,
- uint_t flags, Fdesc *fdesc, Rej_desc *rej, Pnode *dir, int aflag,
- int *in_nfavl)
+_find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
+ Pdesc *pdp, int aflag, int *in_nfavl)
{
+ const char *nname = fdp->fd_nname;
+
DBG_CALL(Dbg_libs_found(lml, nname, aflag));
if ((lml->lm_flags & LML_FLG_TRC_SEARCH) &&
((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
@@ -1540,65 +1421,61 @@
* to go search for. The audit library may offer an alternative
* dependency, or indicate that this dependency should be ignored.
*/
- if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
+ if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
char *aname;
if ((aname = audit_objsearch(clmp, nname,
- (dir->p_orig & LA_SER_MASK))) == 0) {
+ (pdp->pd_flags & LA_SER_MASK))) == NULL) {
DBG_CALL(Dbg_audit_terminate(lml, nname));
return (0);
}
- /*
- * Protect ourselves from auditor mischief, by copying any
- * alternative name over the present name (the present name is
- * maintained in a static buffer - see elf_get_so());
- */
- if (nname != aname)
- (void) strncpy((char *)nname, aname, PATH_MAX);
+ if (aname != nname) {
+ fdp->fd_flags &= ~FLG_FD_SLASH;
+ fdp->fd_nname = aname;
+ }
}
- return (file_open(0, lml, oname, nname, clmp, flags, fdesc,
- rej, in_nfavl));
+ return (file_open(0, lml, clmp, flags, fdp, rej, in_nfavl));
}
static int
-find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
- Fdesc *fdesc, Rej_desc *rej, Pnode *dir, Word * strhash, size_t olen,
- int *in_nfavl)
+find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
+ Pdesc *pdp, Word *strhash, int *in_nfavl)
{
static Rtc_obj Obj = { 0 };
Rtc_obj *dobj;
- const char *nname = oname;
-
- if (dir->p_name == 0)
+ const char *oname = fdp->fd_oname;
+ size_t olen = strlen(oname);
+
+ if (pdp->pd_pname == NULL)
return (0);
- if (dir->p_info) {
- dobj = (Rtc_obj *)dir->p_info;
+ if (pdp->pd_info) {
+ dobj = (Rtc_obj *)pdp->pd_info;
if ((dobj->co_flags &
(RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
return (0);
} else
- dobj = 0;
+ dobj = NULL;
/*
* If configuration information exists see if this directory/file
* combination exists.
*/
if ((rtld_flags & RT_FL_DIRCFG) &&
- ((dobj == 0) || (dobj->co_id != 0))) {
+ ((dobj == NULL) || (dobj->co_id != 0))) {
Rtc_obj *fobj;
- const char *alt = 0;
+ const char *aname = NULL;
/*
- * If this pnode has not yet been searched for in the
- * configuration file go find it.
+ * If this object descriptor has not yet been searched for in
+ * the configuration file go find it.
*/
- if (dobj == 0) {
- dobj = elf_config_ent(dir->p_name,
- (Word)elf_hash(dir->p_name), 0, 0);
- if (dobj == 0)
+ if (dobj == NULL) {
+ dobj = elf_config_ent(pdp->pd_pname,
+ (Word)elf_hash(pdp->pd_pname), 0, 0);
+ if (dobj == NULL)
dobj = &Obj;
- dir->p_info = (void *)dobj;
+ pdp->pd_info = (void *)dobj;
if ((dobj->co_flags & (RTC_OBJ_NOEXIST |
RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
@@ -1609,10 +1486,10 @@
* If we found a directory search for the file.
*/
if (dobj->co_id != 0) {
- if (*strhash == 0)
- *strhash = (Word)elf_hash(nname);
- fobj = elf_config_ent(nname, *strhash,
- dobj->co_id, &alt);
+ if (*strhash == NULL)
+ *strhash = (Word)elf_hash(oname);
+ fobj = elf_config_ent(oname, *strhash,
+ dobj->co_id, &aname);
/*
* If this object specifically does not exist, or the
@@ -1620,7 +1497,7 @@
* directory, continue looking. If the object does
* exist determine if an alternative object exists.
*/
- if (fobj == 0) {
+ if (fobj == NULL) {
if (dobj->co_flags & RTC_OBJ_ALLENTS)
return (0);
} else {
@@ -1633,21 +1510,22 @@
(lml == &lml_main)) {
int ret;
- fdesc->fd_flags |= FLG_FD_ALTER;
+ fdp->fd_flags |= FLG_FD_ALTER;
+ fdp->fd_nname = aname;
+
/*
* Attempt to open the alternative path.
* If this fails, and the alternative is
* flagged as optional, fall through to
* open the original path.
*/
- ret = _find_file(lml, oname, alt, clmp,
- flags, fdesc, rej, dir, 1,
- in_nfavl);
+ ret = _find_file(lml, clmp, flags, fdp,
+ rej, pdp, 1, in_nfavl);
if (ret || ((fobj->co_flags &
RTC_OBJ_OPTINAL) == 0))
return (ret);
- fdesc->fd_flags &= ~FLG_FD_ALTER;
+ fdp->fd_flags &= ~FLG_FD_ALTER;
}
}
}
@@ -1656,120 +1534,361 @@
/*
* Protect ourselves from building an invalid pathname.
*/
- if ((olen + dir->p_len + 1) >= PATH_MAX) {
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), nname,
+ if ((olen + pdp->pd_plen + 1) >= PATH_MAX) {
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), oname,
strerror(ENAMETOOLONG));
return (0);
}
- if ((nname = (LM_GET_SO(clmp)(dir->p_name, nname))) == 0)
+ if ((fdp->fd_nname = (LM_GET_SO(clmp)(pdp->pd_pname, oname,
+ pdp->pd_plen, olen))) == NULL)
+ return (0);
+
+ return (_find_file(lml, clmp, flags, fdp, rej, pdp, 0, in_nfavl));
+}
+
+static Fct *Vector[] = {
+ &elf_fct,
+#ifdef A_OUT
+ &aout_fct,
+#endif
+ 0
+};
+
+/*
+ * Remap the first page of a file to provide a better diagnostic as to why
+ * an mmapobj(2) operation on this file failed. Sadly, mmapobj(), and all
+ * system calls for that matter, only pass back a generic failure in errno.
+ * Hopefully one day this will be improved, but in the mean time we repeat
+ * the kernels ELF verification to try and provide more detailed information.
+ */
+static int
+map_fail(Fdesc *fdp, size_t fsize, const char *name, int fd, Rej_desc *rej)
+{
+ caddr_t addr;
+ int vnum;
+ size_t size;
+
+ /*
+ * Use the original file size to determine what to map, and catch the
+ * obvious error of a zero sized file.
+ */
+ if (fsize == 0) {
+ rej->rej_type = SGS_REJ_UNKFILE;
+ return (1);
+ } else if (fsize < syspagsz)
+ size = fsize;
+ else
+ size = syspagsz;
+
+ if ((addr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
return (0);
- return (_find_file(lml, oname, nname, clmp, flags, fdesc, rej,
- dir, 0, in_nfavl));
+ rej->rej_type = 0;
+
+ /*
+ * Validate the file against each supported file type. Should a
+ * characteristic of the file be found invalid for this platform, a
+ * rejection message will have been recorded.
+ */
+ for (vnum = 0; Vector[vnum]; vnum++) {
+ if (((Vector[vnum]->fct_verify_file)(addr, size,
+ fdp, name, rej) == 0) && rej->rej_type)
+ break;
+ }
+
+ /*
+ * If no rejection message has been recorded, then this is simply an
+ * unknown file type.
+ */
+ if (rej->rej_type == 0)
+ rej->rej_type = SGS_REJ_UNKFILE;
+
+ (void) munmap(addr, size);
+ return (1);
+}
+
+/*
+ * Unmap a file.
+ */
+void
+unmap_obj(mmapobj_result_t *mpp, uint_t mapnum)
+{
+ uint_t num;
+
+ for (num = 0; num < mapnum; num++) {
+ /* LINTED */
+ (void) munmap((void *)(uintptr_t)mpp[num].mr_addr,
+ mpp[num].mr_msize);
+ }
+}
+
+/*
+ * Map a file.
+ */
+Fct *
+map_obj(Lm_list *lml, Fdesc *fdp, size_t fsize, const char *name, int fd,
+ Rej_desc *rej)
+{
+ static mmapobj_result_t *smpp = NULL;
+ static uint_t smapnum;
+ mmapobj_result_t *mpp;
+ uint_t mnum, mapnum, mflags;
+ void *padding;
+
+ /*
+ * Allocate an initial mapping array. The initial size should be large
+ * enough to handle the normal ELF objects we come across.
+ */
+ if (smpp == NULL) {
+ smpp = malloc(sizeof (mmapobj_result_t) * MMAPFD_NUM);
+ if (smpp == NULL)
+ return (NULL);
+ smapnum = MMAPFD_NUM;
+ }
+
+ /*
+ * If object padding is required, set the necessary flags.
+ */
+ if (r_debug.rtd_objpad) {
+ mflags = MMOBJ_INTERPRET | MMOBJ_PADDING;
+ padding = &r_debug.rtd_objpad;
+ } else {
+ mflags = MMOBJ_INTERPRET;
+ padding = NULL;
+ }
+
+ /*
+ * Map the file. If the number of mappings required by this file
+ * exceeds the present mapping structure, an error indicating the
+ * return data is too big is returned. Bail on any other error.
+ */
+ mapnum = smapnum;
+ if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) {
+ if (errno != E2BIG) {
+ int err = errno;
+
+ /*
+ * An unsupported error indicates that there's something
+ * incompatible with this ELF file, and the process that
+ * is already running. Map the first page of the file
+ * and see if we can generate a better error message.
+ */
+ if ((errno == ENOTSUP) && map_fail(fdp, fsize, name,
+ fd, rej))
+ return (NULL);
+
+ rej->rej_type = SGS_REJ_STR;
+ rej->rej_str = strerror(err);
+ return (NULL);
+ }
+
+ /*
+ * The mapping requirement exceeds the present mapping
+ * structure, however the number of mapping required is
+ * available in the mapping number.
+ */
+ free((void *)smpp);
+ if ((smpp = malloc(sizeof (mmapobj_result_t) * mapnum)) == NULL)
+ return (NULL);
+ smapnum = mapnum;
+
+ /*
+ * With the appropriate mapping structure, try the mapping
+ * request again.
+ */
+ if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) {
+ rej->rej_type = SGS_REJ_STR;
+ rej->rej_str = strerror(errno);
+ return (NULL);
+ }
+ }
+ ASSERT(mapnum != 0);
+
+ /*
+ * Traverse the mappings in search of a file type ld.so.1 can process.
+ * If the file type is verified as one ld.so.1 can process, retain the
+ * mapping information, and the number of mappings this object uses,
+ * and clear the static mapping pointer for the next map_obj() use of
+ * mmapobj().
+ */
+ DBG_CALL(Dbg_file_mmapobj(lml, name, smpp, mapnum));
+
+ for (mnum = 0, mpp = smpp; mnum < mapnum; mnum++, mpp++) {
+ uint_t flags = (mpp->mr_flags & MR_TYPE_MASK);
+ Fct *fptr = NULL;
+
+ if (flags == MR_HDR_ELF) {
+ fptr = elf_verify((mpp->mr_addr + mpp->mr_offset),
+ mpp->mr_fsize, fdp, name, rej);
+ }
+#ifdef A_OUT
+ if (flags == MR_HDR_AOUT) {
+ fptr = aout_verify((mpp->mr_addr + mpp->mr_offset),
+ mpp->mr_fsize, fdp, name, rej);
+ }
+#endif
+ if (fptr) {
+ fdp->fd_mapn = mapnum;
+ fdp->fd_mapp = smpp;
+
+ smpp = NULL;
+
+ return (fptr);
+ }
+ }
+
+ /*
+ * If the mapped file is inappropriate, indicate that the file type is
+ * unknown, and free the mapping.
+ */
+ if (rej->rej_type == 0)
+ rej->rej_type = SGS_REJ_UNKFILE;
+ unmap_obj(smpp, mapnum);
+
+ return (NULL);
}
/*
* A unique file has been opened. Create a link-map to represent it, and
* process the various names by which it can be referenced.
*/
-static Rt_map *
-load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc, int *in_nfavl)
+Rt_map *
+load_file(Lm_list *lml, Aliste lmco, Fdesc *fdp, int *in_nfavl)
{
- const char *oname = fdesc->fd_oname;
- const char *nname = fdesc->fd_nname;
- Rt_map *nlmp;
+ mmapobj_result_t *fpmpp = NULL, *fmpp = NULL, *lpmpp, *lmpp;
+ mmapobj_result_t *hmpp, *mpp, *ompp = fdp->fd_mapp;
+ uint_t mnum, omapnum = fdp->fd_mapn;
+ const char *nname = fdp->fd_nname;
+ Rt_map *nlmp;
+ Ehdr *ehdr = NULL;
/*
- * Typically we call fct_map_so() with the full pathname of the opened
- * file (nname) and the name that started the search (oname), thus for
- * a typical dependency on libc this would be /usr/lib/libc.so.1 and
- * libc.so.1 (DT_NEEDED). The original name is maintained on an ALIAS
- * list for comparison when bringing in new dependencies. If the user
- * specified name as a full path (from a dlopen() for example) then
- * there's no need to create an ALIAS.
+ * Traverse the mappings for the input file to capture generic mapping
+ * information, and create a link-map to represent the file.
*/
- if (strcmp(oname, nname) == 0)
- oname = 0;
-
- /*
- * A new file has been opened, now map it into the process. Close the
- * original file so as not to accumulate file descriptors.
- */
- nlmp = ((fdesc->fd_ftp)->fct_map_so)(lml, lmco, nname, oname,
- fdesc->fd_fd, in_nfavl);
- (void) close(fdesc->fd_fd);
- fdesc->fd_fd = 0;
-
- if (nlmp == 0)
- return (NULL);
-
- /*
- * Save the dev/inode information for later comparisons.
- */
- STDEV(nlmp) = fdesc->fd_dev;
- STINO(nlmp) = fdesc->fd_ino;
+ for (mnum = 0, mpp = ompp; mnum < omapnum; mnum++, mpp++) {
+ uint_t flags = (mpp->mr_flags & MR_TYPE_MASK);
+
+ /*
+ * Keep track of the first and last mappings that may include
+ * padding.
+ */
+ if (fpmpp == NULL)
+ fpmpp = mpp;
+ lpmpp = mpp;
+
+ /*
+ * Keep track of the first and last mappings that do not include
+ * padding.
+ */
+ if (flags != MR_PADDING) {
+ if (fmpp == NULL)
+ fmpp = mpp;
+ lmpp = mpp;
+ }
+ if (flags == MR_HDR_ELF) {
+ /* LINTED */
+ ehdr = (Ehdr *)(mpp->mr_addr + mpp->mr_offset);
+ hmpp = mpp;
+ } else if (flags == MR_HDR_AOUT)
+ hmpp = mpp;
+ }
/*
- * Insert the names of this link-map into the FullpathNode AVL tree.
- * Save both the NAME() and PATHNAME() is they differ.
+ * The only ELF files we can handle are ET_EXEC, ET_DYN, and ET_REL.
*
- * If this is an OBJECT file, don't insert it yet as this is only a
- * temporary link-map. During elf_obj_fini() the final link-map is
- * created, and its names will be inserted in the FullpathNode AVL
- * tree at that time.
+ * ET_REL must be processed by ld(1) to create an in-memory ET_DYN.
+ * The initial processing carried out by elf_obj_file() creates a
+ * temporary link-map, that acts as a place holder, until the objects
+ * processing is finished with elf_obj_fini().
*/
- if ((FLAGS(nlmp) & FLG_RT_OBJECT) == 0) {
+ if (ehdr && (ehdr->e_type == ET_REL)) {
+ if ((nlmp = elf_obj_file(lml, lmco, nname, hmpp, ompp,
+ omapnum)) == NULL)
+ return (nlmp);
+ } else {
+ Addr addr;
+ size_t msize;
+
/*
- * Update the objects full path information if necessary.
- * Note, with pathname expansion in effect, the fd_pname will
- * be used as PATHNAME(). This allocated string will be freed
- * should this object be deleted. However, without pathname
- * expansion, the fd_name should be freed now, as it is no
- * longer referenced.
+ * The size of the total reservation, and the padding range,
+ * are a historic artifact required by debuggers. Although
+ * these values express the range of the associated mappings,
+ * there can be holes between segments (in which small objects
+ * could be mapped). Anyone who needs to verify offsets
+ * against segments should analyze all the object mappings,
+ * rather than relying on these address ranges.
*/
- if (FLAGS1(nlmp) & FL1_RT_RELATIVE)
- (void) fullpath(nlmp, fdesc->fd_pname);
- else if (fdesc->fd_pname != fdesc->fd_nname)
- free((void *)fdesc->fd_pname);
- fdesc->fd_pname = 0;
-
- if ((NAME(nlmp)[0] == '/') && (fpavl_insert(lml, nlmp,
- NAME(nlmp), fdesc->fd_avlwhere) == 0)) {
- remove_so(lml, nlmp);
+ addr = (Addr)(hmpp->mr_addr + hmpp->mr_offset);
+ msize = lmpp->mr_addr + lmpp->mr_msize - fmpp->mr_addr;
+
+ if ((nlmp = ((fdp->fd_ftp)->fct_new_lmp)(lml, lmco, fdp, addr,
+ msize, NULL, in_nfavl)) == NULL)
return (NULL);
- }
- if (((NAME(nlmp)[0] != '/') ||
- (NAME(nlmp) != PATHNAME(nlmp))) &&
- (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)) {
- remove_so(lml, nlmp);
- return (NULL);
- }
/*
- * If this is a secure application, record any full path name
- * directory in which this dependency has been found. This
- * directory can be deemed safe (as we've already found a
- * dependency here). This recording provides a fall-back
- * should another objects $ORIGIN definition expands to this
- * directory, an expansion that would ordinarily be deemed
- * insecure.
+ * Save generic mapping information.
*/
- if (rtld_flags & RT_FL_SECURE) {
- if (NAME(nlmp)[0] == '/')
- spavl_insert(NAME(nlmp));
- if ((NAME(nlmp) != PATHNAME(nlmp)) &&
- (PATHNAME(nlmp)[0] == '/'))
- spavl_insert(PATHNAME(nlmp));
- }
+ MMAPS(nlmp) = ompp;
+ MMAPCNT(nlmp) = omapnum;
+ PADSTART(nlmp) = (ulong_t)fpmpp->mr_addr;
+ PADIMLEN(nlmp) = lpmpp->mr_addr + lpmpp->mr_msize -
+ fpmpp->mr_addr;
+ }
+
+ /*
+ * Save the dev/inode information for later comparisons, and identify
+ * this as a new object.
+ */
+ STDEV(nlmp) = fdp->fd_dev;
+ STINO(nlmp) = fdp->fd_ino;
+ FLAGS(nlmp) |= FLG_RT_NEWLOAD;
+
+ /*
+ * If this is ELF relocatable object, we're done for now.
+ */
+ if (ehdr && (ehdr->e_type == ET_REL))
+ return (nlmp);
+
+ /*
+ * Insert the names of this link-map into the FullPathNode AVL tree.
+ * Save both the NAME() and PATHNAME() if the names differ.
+ */
+ (void) fullpath(nlmp, fdp);
+
+ if ((NAME(nlmp)[0] == '/') && (fpavl_insert(lml, nlmp, NAME(nlmp),
+ fdp->fd_avlwhere) == 0)) {
+ remove_so(lml, nlmp);
+ return (NULL);
+ }
+ if (((NAME(nlmp)[0] != '/') || (NAME(nlmp) != PATHNAME(nlmp))) &&
+ (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)) {
+ remove_so(lml, nlmp);
+ return (NULL);
+ }
+
+ /*
+ * If this is a secure application, record any full path name directory
+ * in which this dependency has been found. This directory can be
+ * deemed safe (as we've already found a dependency here). This
+ * recording provides a fall-back should another objects $ORIGIN
+ * definition expands to this directory, an expansion that would
+ * ordinarily be deemed insecure.
+ */
+ if (rtld_flags & RT_FL_SECURE) {
+ if (NAME(nlmp)[0] == '/')
+ spavl_insert(NAME(nlmp));
+ if ((NAME(nlmp) != PATHNAME(nlmp)) &&
+ (PATHNAME(nlmp)[0] == '/'))
+ spavl_insert(PATHNAME(nlmp));
}
/*
* If we're processing an alternative object reset the original name
* for possible $ORIGIN processing.
*/
- if (fdesc->fd_flags & FLG_FD_ALTER) {
- const char *odir;
- char *ndir;
+ if (fdp->fd_flags & FLG_FD_ALTER) {
+ const char *odir, *ndir;
size_t olen;
FLAGS(nlmp) |= FLG_RT_ALTER;
@@ -1780,33 +1899,24 @@
* directory is in dir->p_name (which is all we need for
* $ORIGIN).
*/
- if (fdesc->fd_flags & FLG_FD_SLASH) {
+ if (fdp->fd_flags & FLG_FD_SLASH) {
char *ofil;
- odir = oname;
- ofil = strrchr(oname, '/');
+ odir = fdp->fd_oname;
+ ofil = strrchr(fdp->fd_oname, '/');
olen = ofil - odir + 1;
} else {
- odir = fdesc->fd_odir;
+ odir = fdp->fd_odir;
olen = strlen(odir) + 1;
}
-
- if ((ndir = (char *)malloc(olen)) == 0) {
+ if ((ndir = stravl_insert(odir, 0, olen, 1)) == NULL) {
remove_so(lml, nlmp);
return (NULL);
}
- (void) strncpy(ndir, odir, olen);
- ndir[--olen] = '\0';
-
ORIGNAME(nlmp) = ndir;
- DIRSZ(nlmp) = olen;
+ DIRSZ(nlmp) = --olen;
}
- /*
- * Identify this as a new object.
- */
- FLAGS(nlmp) |= FLG_RT_NEWLOAD;
-
return (nlmp);
}
@@ -1818,38 +1928,29 @@
* of link maps and return a pointer to the new link map. Return 0 on error.
*/
static Rt_map *
-load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
- uint_t flags, Fdesc *nfdp, Rej_desc *rej, int *in_nfavl)
+load_so(Lm_list *lml, Aliste lmco, Rt_map *clmp, uint_t flags,
+ Fdesc *fdp, Rej_desc *rej, int *in_nfavl)
{
- char *name;
- uint_t slash = 0;
- size_t olen;
- Fdesc fdesc = { 0 };
- Pnode *dir;
+ const char *oname = fdp->fd_oname;
+ Pdesc *pdp;
/*
- * If the file is the run time linker then it's already loaded.
+ * If this path name hasn't already been identified as containing a
+ * slash, check the path name. Most paths have been constructed
+ * through appending a file name to a search path, and/or have been
+ * inspected by expand(), and thus have a slash. However, we can
+ * receive path names via auditors or configuration files, and thus
+ * an evaluation here catches these instances.
*/
- if (interp && (strcmp(oname, NAME(lml_rtld.lm_head)) == 0))
- return (lml_rtld.lm_head);
-
- /*
- * If this isn't a hardware capabilities pathname, which is already a
- * full, duplicated pathname, determine whether the pathname contains
- * a slash, and if not determine the input filename (for max path
- * length verification).
- */
- if ((flags & FLG_RT_HWCAP) == 0) {
+ if ((fdp->fd_flags & FLG_FD_SLASH) == 0) {
const char *str;
for (str = oname; *str; str++) {
if (*str == '/') {
- slash++;
+ fdp->fd_flags |= FLG_FD_SLASH;
break;
}
}
- if (slash == 0)
- olen = (str - oname) + 1;
}
/*
@@ -1877,37 +1978,19 @@
/*
* If this object is already loaded, we're done.
*/
- if (nfdp->fd_lmp)
- return (nfdp->fd_lmp);
+ if (fdp->fd_lmp)
+ return (fdp->fd_lmp);
/*
* Obtain the avl index for this object.
*/
- (void) fpavl_recorded(lml, nfdp->fd_nname,
- &(nfdp->fd_avlwhere));
-
- /*
- * If the name and resolved pathname differ, duplicate the path
- * name once more to provide for generic cleanup by the caller.
- */
- if (nfdp->fd_pname && (nfdp->fd_nname != nfdp->fd_pname)) {
- char *pname;
-
- if ((pname = strdup(nfdp->fd_pname)) == NULL)
- return (NULL);
- nfdp->fd_pname = pname;
- }
-
- nfdp->fd_flags |= FLG_FD_SLASH;
-
- } else if (slash) {
+ (void) fpavl_recorded(lml, fdp->fd_nname, 0,
+ &(fdp->fd_avlwhere));
+
+ } else if (fdp->fd_flags & FLG_FD_SLASH) {
Rej_desc _rej = { 0 };
- *nfdp = fdesc;
- nfdp->fd_flags = FLG_FD_SLASH;
-
- if (find_path(lml, oname, clmp, flags, nfdp,
- &_rej, in_nfavl) == 0) {
+ if (find_path(lml, clmp, flags, fdp, &_rej, in_nfavl) == 0) {
rejection_inherit(rej, &_rej);
return (NULL);
}
@@ -1915,36 +1998,28 @@
/*
* If this object is already loaded, we're done.
*/
- if (nfdp->fd_lmp)
- return (nfdp->fd_lmp);
+ if (fdp->fd_lmp)
+ return (fdp->fd_lmp);
} else {
/*
* No '/' - for each directory on list, make a pathname using
* that directory and filename and try to open that file.
*/
- Pnode *dirlist = (Pnode *)0;
+ Spath_desc sd = { search_rules, NULL, 0 };
Word strhash = 0;
-#if !defined(ISSOLOAD_BASENAME_DISABLED)
- Rt_map *nlmp;
-#endif
+ int found = 0;
+
DBG_CALL(Dbg_libs_find(lml, oname));
-#if !defined(ISSOLOAD_BASENAME_DISABLED)
- if ((nlmp = is_so_loaded(lml, oname, in_nfavl)))
- return (nlmp);
-#endif
/*
- * Make sure we clear the file descriptor new name in case the
- * following directory search doesn't provide any directories
- * (odd, but this can be forced with a -znodefaultlib test).
+ * Traverse the search path lists, creating full pathnames and
+ * attempt to load each path.
*/
- *nfdp = fdesc;
- for (dir = get_next_dir(&dirlist, clmp, flags); dir;
- dir = get_next_dir(&dirlist, clmp, flags)) {
+ for (pdp = get_next_dir(&sd, clmp, flags); pdp;
+ pdp = get_next_dir(&sd, clmp, flags)) {
Rej_desc _rej = { 0 };
-
- *nfdp = fdesc;
+ Fdesc fd = { 0 };
/*
* Under debugging, duplicate path name entries are
@@ -1953,16 +2028,18 @@
* Skip these entries, as this path would have already
* been attempted.
*/
- if (dir->p_orig & PN_FLG_DUPLICAT)
+ if (pdp->pd_flags & PD_FLG_DUPLICAT)
continue;
+ fd = *fdp;
+
/*
* Try and locate this file. Make sure to clean up
* any rejection information should the file have
* been found, but not appropriate.
*/
- if (find_file(lml, oname, clmp, flags, nfdp, &_rej,
- dir, &strhash, olen, in_nfavl) == 0) {
+ if (find_file(lml, clmp, flags, &fd, &_rej, pdp,
+ &strhash, in_nfavl) == 0) {
rejection_inherit(rej, &_rej);
continue;
}
@@ -1972,17 +2049,19 @@
* this is an LD_LIBRARY_PATH setting, ignore any use
* by ld.so.1 itself.
*/
- if (((dir->p_orig & LA_SER_LIBPATH) == 0) ||
+ if (((pdp->pd_flags & LA_SER_LIBPATH) == 0) ||
((lml->lm_flags & LML_FLG_RTLDLM) == 0))
- dir->p_orig |= PN_FLG_USED;
+ pdp->pd_flags |= PD_FLG_USED;
/*
* If this object is already loaded, we're done.
*/
- if (nfdp->fd_lmp)
- return (nfdp->fd_lmp);
-
- nfdp->fd_odir = dir->p_name;
+ *fdp = fd;
+ if (fdp->fd_lmp)
+ return (fdp->fd_lmp);
+
+ fdp->fd_odir = pdp->pd_pname;
+ found = 1;
break;
}
@@ -1994,25 +2073,11 @@
* (i.e., a file might have a dependency on foo.so.1 which has
* already been opened using its full pathname).
*/
- if (nfdp->fd_nname == NULL)
+ if (found == 0)
return (is_so_loaded(lml, oname, in_nfavl));
}
/*
- * Duplicate the file name so that NAME() is available in core files.
- * Note, that hardware capability names are already duplicated, but
- * they get duplicated once more to insure consistent cleanup in the
- * event of an error condition.
- */
- if ((name = strdup(nfdp->fd_nname)) == NULL)
- return (NULL);
-
- if (nfdp->fd_nname == nfdp->fd_pname)
- nfdp->fd_nname = nfdp->fd_pname = name;
- else
- nfdp->fd_nname = name;
-
- /*
* Finish mapping the file and return the link-map descriptor. Note,
* if this request originated from a HWCAP request, re-establish the
* fdesc information. For single paged objects, such as filters, the
@@ -2020,16 +2085,16 @@
* this mapping needs to be reset to insure it doesn't mistakenly get
* unmapped as part of HWCAP cleanup.
*/
- return (load_file(lml, lmco, nfdp, in_nfavl));
+ return (load_file(lml, lmco, fdp, in_nfavl));
}
/*
- * Trace an attempt to load an object.
+ * Trace an attempt to load an object, and seed the originating name.
*/
-int
-load_trace(Lm_list *lml, const char **oname, Rt_map *clmp)
+const char *
+load_trace(Lm_list *lml, Pdesc *pdp, Rt_map *clmp, Fdesc *fdp)
{
- const char *name = *oname;
+ const char *name = pdp->pd_pname;
/*
* First generate any ldd(1) diagnostics.
@@ -2039,41 +2104,38 @@
(void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, NAME(clmp));
/*
+ * Propagate any knowledge of a slash within the path name.
+ */
+ if (pdp->pd_flags & PD_FLG_PNSLASH)
+ fdp->fd_flags |= FLG_FD_SLASH;
+
+ /*
* If we're being audited tell the audit library of the file we're
* about to go search for.
*/
- if (((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_ACTIVITY) &&
+ if (((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_ACTIVITY) &&
(lml == LIST(clmp)))
audit_activity(clmp, LA_ACT_ADD);
- if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
- char *aname = audit_objsearch(clmp, name, LA_SER_ORIG);
+ if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
+ char *aname;
/*
* The auditor can indicate that this object should be ignored.
*/
- if (aname == NULL) {
+ if ((aname =
+ audit_objsearch(clmp, name, LA_SER_ORIG)) == NULL) {
DBG_CALL(Dbg_audit_terminate(lml, name));
- return (0);
+ return (NULL);
}
- /*
- * Protect ourselves from auditor mischief, by duplicating any
- * alternative name. The original name has been allocated from
- * expand(), so free this allocation before using the audit
- * alternative.
- */
if (name != aname) {
- if ((aname = strdup(aname)) == NULL) {
- eprintf(lml, ERR_FATAL,
- MSG_INTL(MSG_GEN_AUDITERM), name);
- return (0);
- }
- free((void *)*oname);
- *oname = aname;
+ fdp->fd_flags &= ~FLG_FD_SLASH;
+ name = aname;
}
}
- return (1);
+ fdp->fd_oname = name;
+ return (name);
}
/*
@@ -2094,9 +2156,8 @@
* If this dependency is associated with a required version insure that
* the version is present in the loaded file.
*/
- if (((rtld_flags & RT_FL_NOVERSION) == 0) &&
- (FCT(clmp) == &elf_fct) && VERNEED(clmp) &&
- (LM_VERIFY_VERS(clmp)(name, clmp, nlmp) == 0))
+ if (((rtld_flags & RT_FL_NOVERSION) == 0) && THIS_IS_ELF(clmp) &&
+ VERNEED(clmp) && (elf_verify_vers(name, clmp, nlmp) == 0))
return (0);
/*
@@ -2127,18 +2188,8 @@
/*
* Establish new mode and flags.
- *
- * For patch backward compatibility, the following use of update_mode()
- * is disabled.
*/
-#ifdef SIEBEL_DISABLE
- if (rtld_flags & RT_FL_DISFIX_1)
- promote = MODE(nlmp) |=
- (nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST));
- else
-#endif
- promote = update_mode(nlmp, MODE(nlmp), nmode);
-
+ promote = update_mode(nlmp, MODE(nlmp), nmode);
FLAGS(nlmp) |= flags;
/*
@@ -2291,7 +2342,7 @@
* Otherwise, this object exists and has dependencies, so add
* all of its dependencies to the handle were operating on.
*/
- if (aplist_append(&lmalp, nlmp, AL_CNT_DEPCLCT) == 0)
+ if (aplist_append(&lmalp, nlmp, AL_CNT_DEPCLCT) == NULL)
return (0);
for (APLIST_TRAVERSE(lmalp, idx1, dlmp1)) {
@@ -2320,15 +2371,13 @@
continue;
if ((exist = hdl_add(ghp, dlmp1,
- (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS))) != 0) {
- if (exist == ALE_CREATE) {
- (void) update_mode(dlmp1, MODE(dlmp1),
- nmode);
- }
- continue;
+ (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS))) == 0) {
+ free(lmalp);
+ return (0);
}
- free(lmalp);
- return (0);
+
+ if (exist == ALE_CREATE)
+ (void) update_mode(dlmp1, MODE(dlmp1), nmode);
}
free(lmalp);
}
@@ -2339,26 +2388,19 @@
* The central routine for loading shared objects. Insures ldd() diagnostics,
* handles and any other related additions are all done in one place.
*/
-static Rt_map *
-_load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp,
- int nmode, uint_t flags, Grp_hdl ** hdl, Fdesc *nfdp, Rej_desc *rej,
- int *in_nfavl)
+Rt_map *
+load_path(Lm_list *lml, Aliste lmco, Rt_map *clmp, int nmode, uint_t flags,
+ Grp_hdl **hdl, Fdesc *fdp, Rej_desc *rej, int *in_nfavl)
{
+ const char *name = fdp->fd_oname;
Rt_map *nlmp;
- const char *name = *oname;
if ((nmode & RTLD_NOLOAD) == 0) {
/*
* If this isn't a noload request attempt to load the file.
- * Note, the name of the file may be changed by an auditor.
*/
- if ((load_trace(lml, oname, clmp)) == 0)
- return (NULL);
-
- name = *oname;
-
- if ((nlmp = load_so(lml, lmco, name, clmp, flags,
- nfdp, rej, in_nfavl)) == 0)
+ if ((nlmp = load_so(lml, lmco, clmp, flags, fdp, rej,
+ in_nfavl)) == NULL)
return (NULL);
/*
@@ -2440,7 +2482,7 @@
if (FLAGS(nlmp) & FLG_RT_NEWLOAD) {
FLAGS(nlmp) &= ~FLG_RT_NEWLOAD;
- if (((lml->lm_tflags | FLAGS1(clmp) | FLAGS1(nlmp)) &
+ if (((lml->lm_tflags | AFLAGS(clmp) | AFLAGS(nlmp)) &
LML_TFLG_AUD_MASK) && (((lml->lm_flags |
LIST(clmp)->lm_flags) & LML_FLG_NOAUDIT) == 0)) {
if (audit_objopen(clmp, nlmp) == 0) {
@@ -2452,59 +2494,6 @@
return (nlmp);
}
-Rt_map *
-load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp, int nmode,
- uint_t flags, Grp_hdl **hdl, Fdesc *cfdp, Rej_desc *rej, int *in_nfavl)
-{
- Rt_map *lmp;
- Fdesc nfdp = { 0 };
-
- /*
- * If this path resulted from a $HWCAP specification, then the best
- * hardware capability object has already been establish, and is
- * available in the calling file descriptor.
- */
- if (flags & FLG_RT_HWCAP) {
- if (cfdp->fd_lmp == 0) {
- /*
- * If this object hasn't yet been mapped, re-establish
- * the file descriptor structure to reflect this objects
- * original initial page mapping. Make sure any present
- * file descriptor mapping is removed before overwriting
- * the structure.
- */
-#if defined(MAP_ALIGN)
- if (fmap->fm_maddr &&
- ((fmap->fm_mflags & MAP_ALIGN) == 0))
-#else
- if (fmap->fm_maddr)
-#endif
- (void) munmap(fmap->fm_maddr, fmap->fm_msize);
-
- *fmap = cfdp->fd_fmap;
- }
- nfdp = *cfdp;
- }
-
- lmp = _load_path(lml, lmco, name, clmp, nmode, flags, hdl, &nfdp,
- rej, in_nfavl);
-
- /*
- * If this path originated from a $HWCAP specification, re-establish the
- * fdesc information. For single paged objects, such as filters, the
- * original mapping may have been sufficient to capture the file, thus
- * this mapping needs to be reset to insure it doesn't mistakenly get
- * unmapped as part of HWCAP cleanup.
- */
- if ((flags & FLG_RT_HWCAP) && (cfdp->fd_lmp == 0)) {
- cfdp->fd_fmap.fm_maddr = fmap->fm_maddr;
- cfdp->fd_fmap.fm_mflags = fmap->fm_mflags;
- cfdp->fd_fd = nfdp.fd_fd;
- }
-
- return (lmp);
-}
-
/*
* Load one object from a possible list of objects. Typically, for requests
* such as NEEDED's, only one object is specified. However, this object could
@@ -2512,45 +2501,56 @@
* that can be loaded is used (ie. the best).
*/
Rt_map *
-load_one(Lm_list *lml, Aliste lmco, Pnode *pnp, Rt_map *clmp, int mode,
+load_one(Lm_list *lml, Aliste lmco, Alist *palp, Rt_map *clmp, int mode,
uint_t flags, Grp_hdl **hdl, int *in_nfavl)
{
Rej_desc rej = { 0 };
- Pnode *tpnp;
+ Aliste idx;
+ Pdesc *pdp;
const char *name;
- for (tpnp = pnp; tpnp && tpnp->p_name; tpnp = tpnp->p_next) {
- Rt_map *tlmp;
+ for (ALIST_TRAVERSE(palp, idx, pdp)) {
+ Rt_map *lmp = NULL;
/*
* A Hardware capabilities requirement can itself expand into
* a number of candidates.
*/
- if (tpnp->p_orig & PN_TKN_HWCAP) {
- if ((tlmp = load_hwcap(lml, lmco, tpnp->p_name, clmp,
- mode, (flags | FLG_RT_HWCAP), hdl, &rej,
- in_nfavl)) != 0) {
- remove_rej(&rej);
- return (tlmp);
- }
+ if (pdp->pd_flags & PD_TKN_HWCAP) {
+ lmp = load_hwcap(lml, lmco, pdp->pd_pname, clmp,
+ mode, (flags | FLG_RT_HWCAP), hdl, &rej, in_nfavl);
} else {
- if ((tlmp = load_path(lml, lmco, &tpnp->p_name, clmp,
- mode, flags, hdl, 0, &rej, in_nfavl)) != 0) {
- remove_rej(&rej);
- return (tlmp);
- }
+ Fdesc fd = { 0 };
+
+ /*
+ * Trace the inspection of this file, determine any
+ * auditor substitution, and seed the file descriptor
+ * with the originating name.
+ */
+ if (load_trace(lml, pdp, clmp, &fd) == NULL)
+ continue;
+
+ /*
+ * Locate and load the file.
+ */
+ lmp = load_path(lml, lmco, clmp, mode, flags, hdl, &fd,
+ &rej, in_nfavl);
}
+ if (lmp)
+ return (lmp);
}
/*
- * If this pathname originated from an expanded token, use the original
- * for any diagnostic output.
+ * If no objects can be found, use the first path name from the Alist
+ * to provide a diagnostic. If this pathname originated from an
+ * expanded token, use the original name for any diagnostic output.
*/
- if ((name = pnp->p_oname) == 0)
- name = pnp->p_name;
+ pdp = alist_item(palp, 0);
+
+ if ((name = pdp->pd_oname) == 0)
+ name = pdp->pd_pname;
file_notfound(lml, name, clmp, flags, &rej);
- remove_rej(&rej);
return (NULL);
}
@@ -2640,7 +2640,7 @@
* .bss symbol definition as has been directly bound to, redirect the
* binding to the executables data definition.
*/
- if (osym && ((FLAGS2(lmp) & FL2_RT_DTFLAGS) == 0) &&
+ if (osym && ((FLAGS1(lmp) & FL1_RT_DTFLAGS) == 0) &&
(FCT(lmp) == &elf_fct) &&
(ELF_ST_TYPE(osym->st_info) != STT_FUNC) &&
are_bits_zero(*dlmp, osym, 0)) {
@@ -3236,10 +3236,10 @@
* Append the binding descriptor to the caller and the
* dependency.
*/
- if (aplist_append(&DEPENDS(clmp), bdp, AL_CNT_DEPENDS) == 0)
+ if (aplist_append(&DEPENDS(clmp), bdp, AL_CNT_DEPENDS) == NULL)
return (0);
- if (aplist_append(&CALLERS(dlmp), bdp, AL_CNT_CALLERS) == 0)
+ if (aplist_append(&CALLERS(dlmp), bdp, AL_CNT_CALLERS) == NULL)
return (0);
}
@@ -3258,7 +3258,7 @@
* Cleanup after relocation processing.
*/
int
-relocate_finish(Rt_map *lmp, APlist *bound, int textrel, int ret)
+relocate_finish(Rt_map *lmp, APlist *bound, int ret)
{
DBG_CALL(Dbg_reloc_run(lmp, 0, ret, DBG_REL_FINISH));
@@ -3266,7 +3266,6 @@
* Establish bindings to all objects that have been bound to.
*/
if (bound) {
- Aliste idx;
Rt_map *_lmp;
Word used;
@@ -3282,6 +3281,8 @@
(LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED);
if (ret || used) {
+ Aliste idx;
+
for (APLIST_TRAVERSE(bound, idx, _lmp)) {
if (bind_one(lmp, _lmp, BND_REFER) || used)
continue;
@@ -3293,12 +3294,43 @@
free(bound);
}
- /*
- * If we write enabled the text segment to perform these relocations
- * re-protect by disabling writes.
- */
- if (textrel)
- (void) LM_SET_PROT(lmp)(lmp, 0);
-
return (ret);
}
+
+/*
+ * Function to correct protection settings. Segments are all mapped initially
+ * with permissions as given in the segment header. We need to turn on write
+ * permissions on a text segment if there are any relocations against that
+ * segment, and then turn write permission back off again before returning
+ * control to the caller. This function turns the permission on or off
+ * depending on the value of the permission argument.
+ */
+int
+set_prot(Rt_map *lmp, mmapobj_result_t *mpp, int perm)
+{
+ int prot;
+
+ /*
+ * If this is an allocated image (ie. a relocatable object) we can't
+ * mprotect() anything.
+ */
+ if (FLAGS(lmp) & FLG_RT_IMGALLOC)
+ return (1);
+
+ DBG_CALL(Dbg_file_prot(lmp, perm));
+
+ if (perm)
+ prot = mpp->mr_prot | PROT_WRITE;
+ else
+ prot = mpp->mr_prot & ~PROT_WRITE;
+
+ if (mprotect((void *)(uintptr_t)mpp->mr_addr,
+ mpp->mr_msize, prot) == -1) {
+ int err = errno;
+ eprintf(LIST(lmp), ERR_FATAL, MSG_INTL(MSG_SYS_MPROT),
+ NAME(lmp), strerror(err));
+ return (0);
+ }
+ mpp->mr_prot = prot;
+ return (1);
+}
--- a/usr/src/cmd/sgs/rtld/common/audit.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/audit.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Audit interfaces. Auditing can be enabled in two ways:
@@ -40,13 +40,12 @@
* flags can occur in different data items they are defined as one to simplify
* audit interface requirements. The basic test for all audit interfaces is:
*
- * if (((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_MASK) &&
+ * if (((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_MASK) &&
* (lml == LIST(lmp)))
*
* The latter link-map list equivalence test insures that auditors themselves
* (invoked through DT_DEPAUDIT) are not audited.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <sys/types.h>
@@ -303,6 +302,7 @@
ulong_t pltcnt;
acp->ac_flags |= FLG_AC_BINDFROM;
+
/*
* We only need dynamic plt's if a pltenter and/or a
* pltexit() entry point exist in one of our auditing
@@ -318,7 +318,7 @@
*/
pltcnt = PLTRELSZ(nlmp) / RELENT(nlmp);
if ((aip->ai_dynplts = calloc(pltcnt,
- dyn_plt_ent_size)) == 0)
+ dyn_plt_ent_size)) == NULL)
return (0);
}
}
@@ -359,7 +359,7 @@
* .........
*/
if ((AUDINFO(nlmp) = aip = calloc(1, sizeof (Audit_info) +
- (sizeof (Audit_client) * clients))) == 0)
+ (sizeof (Audit_client) * clients))) == NULL)
return (0);
aip->ai_cnt = clients;
@@ -509,7 +509,6 @@
return (_sym.st_value);
}
-
/*
* la_pltexit() caller. Traverse through all audit library and call any
* la_pltexit() entry points found. See notes above (_audit_pltenter) for
@@ -693,7 +692,6 @@
return (_sym.st_value);
}
-
/*
* la_preinit() caller. Traverse through all audit libraries and call any
* la_preinit() entry points found.
@@ -735,7 +733,6 @@
rtld_flags &= ~RT_FL_APPLIC;
}
-
/*
* Clean up (free) an audit descriptor. First, gather a list of all handles,
* and then close each one down. This is done rather than using the handles
@@ -982,7 +979,7 @@
* Allocate an audit list descriptor for this object and
* search for all known entry points.
*/
- if ((alp = calloc(1, sizeof (Audit_list))) == 0)
+ if ((alp = calloc(1, sizeof (Audit_list))) == NULL)
return (audit_disable(ptr, clmp, ghp, 0));
alp->al_libname = NAME(lmp);
--- a/usr/src/cmd/sgs/rtld/common/cap.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/cap.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,8 +43,8 @@
static int
compare(const void *fdesc1, const void *fdesc2)
{
- ulong_t hwcap1 = ((Fdesc *)fdesc1)->fd_fmap.fm_hwptr;
- ulong_t hwcap2 = ((Fdesc *)fdesc2)->fd_fmap.fm_hwptr;
+ Xword hwcap1 = ((Fdesc *)fdesc1)->fd_hwcap;
+ Xword hwcap2 = ((Fdesc *)fdesc2)->fd_hwcap;
if (hwcap1 && (hwcap2 == 0))
return (-1);
@@ -61,109 +61,50 @@
}
/*
- * Process any hardware and software capabilities.
+ * Process any hardware capabilities.
*/
int
-cap_check(Rej_desc *rej, Ehdr *ehdr)
+hwcap_check(Xword val, Rej_desc *rej)
{
- Cap *cptr;
- Phdr *phdr;
- int cnt;
-
- /* LINTED */
- phdr = (Phdr *)((char *)ehdr + ehdr->e_phoff);
- for (cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
- Lword val;
-
- if (phdr->p_type != PT_SUNWCAP)
- continue;
-
- /* LINTED */
- for (cptr = (Cap *)((char *)ehdr + phdr->p_offset);
- (cptr->c_tag != CA_SUNW_NULL); cptr++) {
-
- if ((cptr->c_tag == CA_SUNW_HW_1) &&
- (rtld_flags2 & RT_FL2_HWCAP)) {
- /*
- * If this object defines a set of hardware
- * capability requirements, ensure the kernel
- * can cope with them.
- */
- if ((val = (cptr->c_un.c_val & ~hwcap)) != 0) {
- static Conv_cap_val_hw1_buf_t cap_buf;
+ Xword mval;
- rej->rej_type = SGS_REJ_HWCAP_1;
- rej->rej_str =
- conv_cap_val_hw1(val, M_MACH, 0,
- &cap_buf);
- return (0);
- }
-
- /*
- * Retain this hardware capabilities value for
- * possible later inspection should this object
- * be processed as a filtee.
- */
- fmap->fm_hwptr = cptr->c_un.c_val;
+ /*
+ * Ensure that the kernel can cope with the required capabilities.
+ */
+ if ((rtld_flags2 & RT_FL2_HWCAP) && ((mval = (val & ~hwcap)) != 0)) {
+ static Conv_cap_val_hw1_buf_t cap_buf;
- }
-#if defined(_ELF64)
- if (cptr->c_tag == CA_SUNW_SF_1) {
- /*
- * A 64-bit executable that started the process
- * can be restricted to a 32-bit address space.
- * A 64-bit dependency that is restricted to a
- * 32-bit address space can not be loaded unless
- * the executable has established this
- * requirement.
- */
- if ((cptr->c_un.c_val & SF1_SUNW_ADDR32) &&
- ((rtld_flags2 & RT_FL2_ADDR32) == 0)) {
- static Conv_cap_val_sf1_buf_t cap_buf;
-
- rej->rej_type = SGS_REJ_SFCAP_1;
- rej->rej_str =
- conv_cap_val_sf1(SF1_SUNW_ADDR32,
- M_MACH, 0, &cap_buf);
- return (0);
- }
- }
-#endif
- }
+ rej->rej_type = SGS_REJ_HWCAP_1;
+ rej->rej_str = conv_cap_val_hw1(mval, M_MACH, 0, &cap_buf);
+ return (0);
}
return (1);
}
-static void
-remove_fdesc(Fdesc *fdp)
+/*
+ * Process any software capabilities.
+ */
+/* ARGSUSED0 */
+int
+sfcap_check(Xword val, Rej_desc *rej)
{
-#if defined(MAP_ALIGN)
- if (fdp->fd_fmap.fm_maddr &&
- ((fdp->fd_fmap.fm_mflags & MAP_ALIGN) == 0)) {
-#else
- if (fdp->fd_fmap.fm_maddr) {
-#endif
- (void) munmap(fdp->fd_fmap.fm_maddr, fdp->fd_fmap.fm_msize);
+#if defined(_ELF64)
+ /*
+ * A 64-bit executable that started the process can be restricted to a
+ * 32-bit address space. A 64-bit dependency that is restricted to a
+ * 32-bit address space can not be loaded unless the executable has
+ * established this requirement.
+ */
+ if ((val & SF1_SUNW_ADDR32) && ((rtld_flags2 & RT_FL2_ADDR32) == 0)) {
+ static Conv_cap_val_sf1_buf_t cap_buf;
- /*
- * Note, this file descriptor might be duplicating information
- * from the global fmap descriptor. If so, clean up the global
- * descriptor to prevent a duplicate (unnecessary) unmap.
- */
- if (fmap->fm_maddr == fdp->fd_fmap.fm_maddr) {
- fmap->fm_maddr = 0;
- fmap_setup();
- }
+ rej->rej_type = SGS_REJ_SFCAP_1;
+ rej->rej_str =
+ conv_cap_val_sf1(SF1_SUNW_ADDR32, M_MACH, 0, &cap_buf);
+ return (0);
}
- if (fdp->fd_fd)
- (void) close(fdp->fd_fd);
-
- if ((fdp->fd_flags & FLG_FD_ALTER) == 0) {
- if (fdp->fd_pname && (fdp->fd_pname != fdp->fd_nname))
- free((void *)fdp->fd_pname);
- if (fdp->fd_nname)
- free((void *)fdp->fd_nname);
- }
+#endif
+ return (1);
}
/*
@@ -171,34 +112,32 @@
* and analyze all the files it contains.
*/
static int
-hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,
+hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *dname, Rt_map *clmp,
uint_t flags, Rej_desc *rej, int *in_nfavl)
{
char path[PATH_MAX], *dst;
const char *src;
DIR *dir;
struct dirent *dirent;
- Aliste idx;
Alist *fdalp = NULL;
- Fdesc *fdp;
int error = 0;
/*
* Access the directory in preparation for reading its entries. If
* successful, establish the initial pathname.
*/
- if ((dir = opendir(name)) == 0) {
+ if ((dir = opendir(dname)) == NULL) {
Rej_desc _rej = { 0 };
_rej.rej_type = SGS_REJ_STR;
- _rej.rej_name = name;
+ _rej.rej_name = dname;
_rej.rej_str = strerror(errno);
DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH));
rejection_inherit(rej, &_rej);
return (0);
}
- for (dst = path, src = name; *src; dst++, src++)
+ for (dst = path, src = dname; *src; dst++, src++)
*dst = *src;
*dst++ = '/';
@@ -207,10 +146,11 @@
* valid ELF file.
*/
while ((dirent = readdir(dir)) != NULL) {
- const char *file = dirent->d_name, *oname;
+ const char *file = dirent->d_name;
char *_dst;
- Fdesc fdesc = { 0 };
+ Fdesc fd = { 0 };
Rej_desc _rej = { 0 };
+ Pdesc pd = { 0 };
/*
* Ignore "." and ".." entries.
@@ -220,23 +160,21 @@
continue;
/*
- * Complete the full pathname, and verify its usability. Note,
- * an auditor can supply an alternative name.
+ * Complete the full pathname.
*/
for (_dst = dst, src = file, file = dst; *src; _dst++, src++)
*_dst = *src;
*_dst = '\0';
- if ((oname = strdup(path)) == NULL) {
- error = 1;
- break;
- }
+ /*
+ * Trace the inspection of this file, and determine any
+ * auditor substitution.
+ */
+ pd.pd_pname = path;
+ pd.pd_flags = PD_FLG_PNSLASH;
- if (load_trace(lml, &oname, clmp) == 0) {
- free((void *)oname);
+ if (load_trace(lml, &pd, clmp, &fd) == NULL)
continue;
- }
- name = oname;
/*
* Note, all directory entries are processed by find_path(),
@@ -244,41 +182,26 @@
* point for control keeps the number of stat()'s down, and
* provides a single point for error diagnostics.
*/
- if (find_path(lml, name, clmp, flags, &fdesc,
- &_rej, in_nfavl) == 0) {
+ if (find_path(lml, clmp, flags, &fd, &_rej, in_nfavl) == 0) {
rejection_inherit(rej, &_rej);
- if ((rej->rej_name != _rej.rej_name) &&
- (_rej.rej_name == name))
- free((void *)name);
continue;
}
- DBG_CALL(Dbg_cap_hw_candidate(lml, name));
+ DBG_CALL(Dbg_cap_hw_candidate(lml, fd.fd_nname));
/*
* If this object has already been loaded, obtain the hardware
* capabilities for later sorting. Otherwise we have a new
* candidate.
*/
- if (fdesc.fd_lmp)
- fdesc.fd_fmap.fm_hwptr = HWCAP(fdesc.fd_lmp);
- else
- fdesc.fd_fmap = *fmap;
+ if (fd.fd_lmp)
+ fd.fd_hwcap = HWCAP(fd.fd_lmp);
- if (alist_append(&fdalp, &fdesc, sizeof (Fdesc), 10) == 0) {
- remove_fdesc(&fdesc);
+ if (alist_append(&fdalp, &fd, sizeof (Fdesc),
+ AL_CNT_HWCAP) == NULL) {
error = 1;
break;
}
-
- /*
- * Clear the global file mapping structure so that the mapping
- * for this file won't be overriden.
- */
- fmap->fm_mflags = MAP_PRIVATE;
- fmap->fm_maddr = 0;
- fmap->fm_msize = FMAP_SIZE;
- fmap->fm_hwptr = 0;
}
(void) closedir(dir);
@@ -288,11 +211,8 @@
* had already been added to the list and return.
*/
if ((fdalp == NULL) || error) {
- if (fdalp) {
- for (ALIST_TRAVERSE(fdalp, idx, fdp))
- remove_fdesc(fdp);
+ if (fdalp)
free(fdalp);
- }
return (0);
}
@@ -306,40 +226,33 @@
return (1);
}
-static Pnode *
-_hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,
- const char *ref, const char *dir, int mode, uint_t flags, int *in_nfavl)
+int
+hwcap_filtees(Alist **alpp, Aliste oidx, const char *dir, Aliste nlmco,
+ Lm_cntl *nlmc, Rt_map *flmp, const char *ref, int mode, uint_t flags,
+ int *in_nfavl)
{
Alist *fdalp = NULL;
Aliste idx;
- Pnode *fpnp = 0, *lpnp, *npnp = (*pnpp)->p_next;
Fdesc *fdp;
Lm_list *lml = LIST(flmp);
int unused = 0;
Rej_desc rej = { 0 };
- if (hwcap_dir(&fdalp, lml, dir, flmp, flags, &rej, in_nfavl) == 0) {
- remove_rej(&rej);
+ if (hwcap_dir(&fdalp, lml, dir, flmp, flags, &rej, in_nfavl) == 0)
return (0);
- }
/*
* Now complete the mapping of each of the ordered objects, adding
- * each object to a new Pnode.
+ * each object to a new pathname descriptor.
*/
for (ALIST_TRAVERSE(fdalp, idx, fdp)) {
Rt_map *nlmp;
Grp_hdl *ghp = 0;
- Pnode *pnp;
+ Pdesc *pdp;
int audit = 0;
- if (unused) {
- /*
- * Flush out objects remaining.
- */
- remove_fdesc(fdp);
+ if (unused)
continue;
- }
/*
* Complete mapping the file, obtaining a handle, and continue
@@ -349,61 +262,33 @@
*/
DBG_CALL(Dbg_file_filtee(lml, NAME(flmp), fdp->fd_nname, 0));
- nlmp = load_path(lml, nlmco, &fdp->fd_nname, flmp, mode,
+ nlmp = load_path(lml, nlmco, flmp, mode,
(flags | FLG_RT_HANDLE), &ghp, fdp, &rej, in_nfavl);
- remove_fdesc(fdp);
if (nlmp == 0)
continue;
/*
- * Create a new Pnode to represent this filtee, and substitute
- * the calling Pnode (which was used to represent the hardware
+ * Create a new pathname descriptor to represent this filtee,
+ * and insert this descriptor in the Alist following the
+ * hardware descriptor that seeded this processing.
* capability directory).
*/
- if ((pnp = calloc(1, sizeof (Pnode))) == 0) {
- if (ghp) {
- remove_lmc(lml, flmp, nlmc, nlmco,
- fdp->fd_nname);
- }
- return (0);
- }
- if ((pnp->p_name = strdup(NAME(nlmp))) == NULL) {
- if (ghp) {
- remove_lmc(lml, flmp, nlmc, nlmco,
- fdp->fd_nname);
- }
- free(pnp);
+ if ((pdp = alist_insert(alpp, 0, sizeof (Pdesc),
+ AL_CNT_FILTEES, ++oidx)) == NULL) {
+ if (ghp)
+ remove_lmc(lml, flmp, nlmc, nlmco, NAME(nlmp));
return (0);
}
- pnp->p_len = strlen(NAME(nlmp));
- pnp->p_info = (void *)ghp;
- pnp->p_next = npnp;
- if (fpnp == 0) {
- Pnode *opnp = (*pnpp);
-
- /*
- * If this is the first pnode, reuse the original after
- * freeing any of its pathnames.
- */
- if (opnp->p_name)
- free((void *)opnp->p_name);
- if (opnp->p_oname)
- free((void *)opnp->p_oname);
- *opnp = *pnp;
- free((void *)pnp);
- fpnp = lpnp = pnp = opnp;
- } else {
- lpnp->p_next = pnp;
- lpnp = pnp;
- }
+ pdp->pd_pname = NAME(nlmp);
+ pdp->pd_plen = strlen(NAME(nlmp));
/*
* Establish the filter handle to prevent any recursion.
*/
if (nlmp && ghp) {
ghp->gh_flags |= GPH_FILTEE;
- pnp->p_info = (void *)ghp;
+ pdp->pd_info = (void *)ghp;
}
/*
@@ -421,10 +306,10 @@
/*
* Finish processing the objects associated with this request.
*/
- if (nlmp && ghp &&
- ((analyze_lmc(lml, nlmco, nlmp, in_nfavl) == 0) ||
+ if (nlmp && ghp && (((nlmp = analyze_lmc(lml, nlmco, nlmp,
+ in_nfavl)) == NULL) ||
(relocate_lmc(lml, nlmco, flmp, nlmp, in_nfavl) == 0)))
- nlmp = 0;
+ nlmp = NULL;
/*
* If the filtee has been successfully processed, then create
@@ -434,7 +319,7 @@
*/
DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD));
if (nlmp && ghp && (hdl_add(ghp, flmp, GPD_FILTER) == 0))
- nlmp = 0;
+ nlmp = NULL;
/*
* If this object is marked an end-filtee, we're done.
@@ -444,9 +329,12 @@
/*
* If this filtee loading has failed, generate a diagnostic.
- * Null out the pnode entry, and continue the search.
+ * Null out the path name descriptor entry, and continue the
+ * search.
*/
- if (nlmp == 0) {
+ if (nlmp == NULL) {
+ DBG_CALL(Dbg_file_filtee(lml, 0, pdp->pd_pname, audit));
+
/*
* If attempting to load this filtee required a new
* link-map control list to which this request has
@@ -454,46 +342,16 @@
* have been associated to this request.
*/
if (nlmc && nlmc->lc_head)
- remove_lmc(lml, flmp, nlmc, nlmco, pnp->p_name);
+ remove_lmc(lml, flmp, nlmc, nlmco,
+ pdp->pd_pname);
- DBG_CALL(Dbg_file_filtee(lml, 0, pnp->p_name, audit));
-
- pnp->p_len = 0;
- pnp->p_info = 0;
+ pdp->pd_plen = 0;
+ pdp->pd_info = 0;
}
}
free(fdalp);
- return (fpnp);
-}
-
-Pnode *
-hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Dyninfo *dip,
- Rt_map *flmp, const char *ref, int mode, uint_t flags, int *in_nfavl)
-{
- Pnode *pnp = *pnpp;
- const char *dir = pnp->p_name;
- Lm_list *flml = LIST(flmp);
-
- DBG_CALL(Dbg_cap_hw_filter(flml, dir, flmp));
-
- if ((pnp = _hwcap_filtees(pnpp, nlmco, nlmc, flmp, ref, dir, mode,
- flags, in_nfavl)) != 0)
- return (pnp);
-
- /*
- * If no hardware capability filtees have been found, provide suitable
- * diagnostics and mark the incoming Pnode as unused.
- */
- if ((flml->lm_flags & LML_FLG_TRC_ENABLE) &&
- (dip->di_flags & FLG_DI_AUXFLTR) && (rtld_flags & RT_FL_WARNFLTR))
- (void) printf(MSG_INTL(MSG_LDD_HWCAP_NFOUND), dir);
-
- DBG_CALL(Dbg_cap_hw_filter(flml, dir, 0));
-
- pnp = *pnpp;
- pnp->p_len = 0;
- return (pnp);
+ return (1);
}
/*
@@ -503,31 +361,28 @@
load_hwcap(Lm_list *lml, Aliste lmco, const char *dir, Rt_map *clmp,
uint_t mode, uint_t flags, Grp_hdl **hdl, Rej_desc *rej, int *in_nfavl)
{
- Alist *fdalp = NULL;
- Aliste idx;
- Fdesc *fdp;
- int found = 0;
- Rt_map *lmp = 0;
+ Alist *fdalp = NULL;
+ Aliste idx;
+ Fdesc *fdp;
+ int found = 0;
+ Rt_map *lmp = 0;
/*
- * Obtain the sorted list of hardware capabilites objects available.
+ * Obtain the sorted list of hardware capabilities objects available.
*/
if (hwcap_dir(&fdalp, lml, dir, clmp, flags, rej, in_nfavl) == 0)
- return (0);
+ return (NULL);
/*
* From the list of hardware capability objects, use the first and
* discard the rest.
*/
for (ALIST_TRAVERSE(fdalp, idx, fdp)) {
- if ((found == 0) && ((lmp = load_path(lml, lmco, &fdp->fd_nname,
- clmp, mode, flags, hdl, fdp, rej, in_nfavl)) != 0))
- found++;
+ Fdesc fd = *fdp;
- /*
- * Remove the used file descriptor and any objects remaining.
- */
- remove_fdesc(fdp);
+ if ((found == 0) && ((lmp = load_path(lml, lmco, clmp, mode,
+ flags, hdl, &fd, rej, in_nfavl)) != 0))
+ found++;
}
free(fdalp);
--- a/usr/src/cmd/sgs/rtld/common/config_elf.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/config_elf.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -63,7 +63,8 @@
* that exec shells using execv(/usr/bin/ksh, sh ...).
*/
if (head->ch_app) {
- char *_str, *_cname, *cname, *aname = PATHNAME(lmp);
+ char *_str, *_cname, *cname;
+ const char *aname = PATHNAME(lmp);
obj = (Rtc_obj *)(head->ch_app + addr);
cname = _cname = (char *)(strtbl + obj->co_name);
@@ -199,7 +200,6 @@
int fd, features = 0;
rtld_stat_t status;
Addr addr;
- Pnode *pnp;
const char *str;
char path[PATH_MAX];
@@ -230,7 +230,7 @@
* Expand any configuration string.
*/
if ((tkns = expand(&estr, &size, 0, 0,
- (PN_TKN_ISALIST | PN_TKN_HWCAP), lmp)) == 0)
+ (PD_TKN_ISALIST | PD_TKN_HWCAP), lmp)) == 0)
return (0);
/*
@@ -239,7 +239,7 @@
* fall through to pick up the defaults.
*/
if ((rtld_flags & RT_FL_SECURE) &&
- (is_path_secure(estr, lmp, PN_FLG_FULLPATH, tkns) == 0))
+ (is_path_secure(estr, lmp, PD_FLG_FULLPATH, tkns) == 0))
str = NULL;
else
str = (const char *)estr;
@@ -331,10 +331,9 @@
#endif
}
#endif
- if ((pnp = expand_paths(lmp, str,
- (LA_SER_DEFAULT | LA_SER_CONFIG), PN_TKN_HWCAP)) != 0)
- elf_fct.fct_dflt_dirs = pnp;
- features |= CONF_EDLIBPATH;
+ if (expand_paths(lmp, str, &elf_def_dirs, AL_CNT_SEARCH,
+ (LA_SER_DEFAULT | LA_SER_CONFIG), PD_TKN_HWCAP) != NULL)
+ features |= CONF_EDLIBPATH;
}
if (head->ch_eslibpath) {
str = (const char *)(head->ch_eslibpath + addr);
@@ -350,25 +349,22 @@
#endif
}
#endif
- if ((pnp = expand_paths(lmp, str,
- (LA_SER_SECURE | LA_SER_CONFIG), PN_TKN_HWCAP)) != 0)
- elf_fct.fct_secure_dirs = pnp;
- features |= CONF_ESLIBPATH;
+ if (expand_paths(lmp, str, &elf_sec_dirs, AL_CNT_SEARCH,
+ (LA_SER_SECURE | LA_SER_CONFIG), PD_TKN_HWCAP) != NULL)
+ features |= CONF_ESLIBPATH;
}
#if defined(__sparc) && !defined(_ELF64)
if (head->ch_adlibpath) {
str = (const char *)(head->ch_adlibpath + addr);
- if ((pnp = expand_paths(lmp, str,
- (LA_SER_DEFAULT | LA_SER_CONFIG), PN_TKN_HWCAP)) != 0)
- aout_fct.fct_dflt_dirs = pnp;
- features |= CONF_ADLIBPATH;
+ if (expand_paths(lmp, str, &aout_def_dirs, AL_CNT_SEARCH,
+ (LA_SER_DEFAULT | LA_SER_CONFIG), PD_TKN_HWCAP) != NULL)
+ features |= CONF_ADLIBPATH;
}
if (head->ch_aslibpath) {
str = (const char *)(head->ch_aslibpath + addr);
- if ((pnp = expand_paths(lmp, str,
- (LA_SER_SECURE | LA_SER_CONFIG), PN_TKN_HWCAP)) != 0)
- aout_fct.fct_secure_dirs = pnp;
- features |= CONF_ASLIBPATH;
+ if (expand_paths(lmp, str, &aout_sec_dirs, AL_CNT_SEARCH,
+ (LA_SER_SECURE | LA_SER_CONFIG), PD_TKN_HWCAP) != NULL)
+ features |= CONF_ASLIBPATH;
}
#endif
/*
@@ -474,13 +470,13 @@
/*
* Determine whether a filter and filtee string pair exists in the configuration
* file. If so, return the cached filtees that are associated with this pair as
- * a Pnode list.
+ * an Alist.
*/
-Pnode *
-elf_config_flt(Lm_list *lml, const char *filter, const char *string)
+void
+elf_config_flt(Lm_list *lml, const char *filter, const char *string,
+ Alist **alpp, Aliste alni)
{
Rtc_fltr *fltrtbl;
- Pnode *pnp = NULL, *npnp, *opnp = NULL;
for (fltrtbl = (Rtc_fltr *)config->c_fltr; fltrtbl->fr_filter;
fltrtbl++) {
@@ -493,7 +489,7 @@
continue;
/*
- * Create a pnode list for each filtee associated with this
+ * Create a path descriptor for each filtee associated with this
* filter/filtee string pair. Note, no expansion of filtee
* entries is called for, as any original expansion would have
* been carried out before they were recorded in the
@@ -503,26 +499,19 @@
for (fltetbl = (Rtc_flte *)((char *)config->c_flte +
fltrtbl->fr_filtee); fltetbl->fe_filtee; fltetbl++) {
const char *flte;
+ Pdesc *pdp;
flte = config->c_strtbl + fltetbl->fe_filtee;
- if (((npnp = calloc(1, sizeof (Pnode))) == NULL) ||
- ((npnp->p_name = strdup(flte)) == NULL))
- return (0);
+ if ((pdp = alist_append(alpp, 0, sizeof (Pdesc),
+ alni)) == NULL)
+ return;
+
+ pdp->pd_pname = (char *)flte;
+ pdp->pd_plen = strlen(flte) + 1;
+ pdp->pd_flags = LA_SER_CONFIG;
DBG_CALL(Dbg_file_filter(lml, fltr, flte, 1));
-
- if (opnp == NULL)
- pnp = npnp;
- else
- opnp->p_next = npnp;
-
- npnp->p_len = strlen(flte) + 1;
- npnp->p_orig = LA_SER_CONFIG;
-
- opnp = npnp;
}
- return (pnp);
}
- return (0);
}
--- a/usr/src/cmd/sgs/rtld/common/dlfcns.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,6 +43,7 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_inline.h"
#include "msg.h"
/*
@@ -62,8 +63,8 @@
Rt_map *
_caller(caddr_t cpc, int flags)
{
- Lm_list * lml;
- Listnode * lnp;
+ Lm_list *lml;
+ Listnode *lnp;
for (LIST_TRAVERSE(&dynlm_list, lnp, lml)) {
Aliste idx;
@@ -74,17 +75,9 @@
for (lmp = lmc->lc_head; lmp;
lmp = NEXT_RT_MAP(lmp)) {
- Mmap *mmap;
- /*
- * Traverse this objects mappings testing
- * whether the pc falls within its range.
- */
- for (mmap = MMAPS(lmp); mmap->m_vaddr; mmap++) {
- if ((cpc >= mmap->m_vaddr) && (cpc <
- (mmap->m_vaddr + mmap->m_msize)))
- return (lmp);
- }
+ if (find_segment(cpc, lmp))
+ return (lmp);
}
}
}
@@ -117,7 +110,7 @@
clmp = _caller(caller(), CL_EXECDEF);
error = lasterr;
- lasterr = (char *)0;
+ lasterr = NULL;
if (entry)
leave(LIST(clmp), 0);
@@ -159,15 +152,14 @@
/*
* Indicate this object is a part of this handles group.
*/
- if (aplist_append(&GROUPS(lmp), ghp,
- AL_CNT_GROUPS) == 0)
+ if (aplist_append(&GROUPS(lmp), ghp, AL_CNT_GROUPS) == NULL)
return (0);
/*
* Append the new dependency to this handle.
*/
if ((gdp = alist_append(&ghp->gh_depends, &gd,
- sizeof (Grp_desc), AL_CNT_DEPENDS)) == 0)
+ sizeof (Grp_desc), AL_CNT_DEPENDS)) == NULL)
return (0);
}
@@ -186,29 +178,6 @@
}
/*
- * Allocate a handle and record its existence on the handle list for future
- * verification.
- */
-Grp_hdl *
-hdl_alloc()
-{
- Grp_hdl *ghp;
- uint_t ndx;
-
- if ((ghp = calloc(sizeof (Grp_hdl), 1)) == 0)
- return (0);
-
- /* LINTED */
- ndx = (uintptr_t)ghp % HDLIST_SZ;
-
- if (list_append(&hdl_list[ndx], ghp) == 0) {
- free(ghp);
- return (0);
- }
- return (ghp);
-}
-
-/*
* Create a handle.
*/
Grp_hdl *
@@ -245,18 +214,39 @@
}
if (ghp == 0) {
+ uint_t ndx;
+
DBG_CALL(Dbg_file_hdl_title(DBG_HDL_CREATE));
/*
* If this is the first dlopen() request for this handle
* allocate and initialize a new handle.
*/
- if ((ghp = hdl_alloc()) == 0)
- return (0);
+ if ((ghp = malloc(sizeof (Grp_hdl))) == NULL)
+ return (NULL);
+
+ /*
+ * Associate the handle with the link-map list or the reference
+ * link-map as appropriate.
+ */
+ if (aplist_append(alpp, ghp, AL_CNT_GROUPS) == NULL) {
+ free(ghp);
+ return (NULL);
+ }
- if (aplist_append(alpp, ghp, AL_CNT_GROUPS) == 0)
- return (0);
+ /*
+ * Record the existence of this handle for future verification.
+ */
+ /* LINTED */
+ ndx = (uintptr_t)ghp % HDLIST_SZ;
+ if (aplist_append(&hdl_alp[ndx], ghp, AL_CNT_HANDLES) == NULL) {
+ (void) aplist_delete_value(*alpp, ghp);
+ free(ghp);
+ return (NULL);
+ }
+
+ ghp->gh_depends = NULL;
ghp->gh_refcnt = 1;
ghp->gh_flags = hflags;
@@ -276,7 +266,7 @@
ghp->gh_ownlml = LIST(nlmp);
if (hdl_add(ghp, nlmp, ndflags) == 0)
- return (0);
+ return (NULL);
/*
* Indicate that a local group now exists. This state
@@ -306,8 +296,9 @@
/* LINTED */
ndx = (uintptr_t)ghp % HDLIST_SZ;
- list_delete(&hdl_list[HDLIST_ORP], ghp);
- (void) list_append(&hdl_list[ndx], ghp);
+ (void) aplist_delete_value(hdl_alp[HDLIST_ORP], ghp);
+ (void) aplist_append(&hdl_alp[ndx], ghp,
+ AL_CNT_HANDLES);
if (DBG_ENABLED) {
Aliste idx;
@@ -327,7 +318,7 @@
* handle is requested.
*/
if (clmp && (hdl_add(ghp, clmp, cdflags) == 0))
- return (0);
+ return (NULL);
return (ghp);
}
@@ -397,14 +388,14 @@
static int
hdl_validate(Grp_hdl *ghp)
{
- Listnode *lnp;
+ Aliste idx;
Grp_hdl *lghp;
uint_t ndx;
/* LINTED */
ndx = (uintptr_t)ghp % HDLIST_SZ;
- for (LIST_TRAVERSE(&hdl_list[ndx], lnp, lghp)) {
+ for (APLIST_TRAVERSE(hdl_alp[ndx], idx, lghp)) {
if ((lghp == ghp) && (ghp->gh_refcnt != 0))
return (1);
}
@@ -578,11 +569,11 @@
dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
uint_t flags, uint_t orig, int *in_nfavl)
{
- Rt_map *nlmp;
- Grp_hdl *ghp;
- Pnode *pnp;
- Aliste olmco, nlmco;
- Lm_cntl *lmc;
+ Alist *palp = NULL;
+ Rt_map *nlmp;
+ Grp_hdl *ghp;
+ Aliste olmco, nlmco;
+ Lm_cntl *lmc;
DBG_CALL(Dbg_file_dlopen(clmp,
(path ? path : MSG_ORIG(MSG_STR_ZERO)), in_nfavl, mode));
@@ -673,12 +664,11 @@
* provides flexibility should we be able to support dlopening more
* than one object in the future.
*/
- if ((pnp = LM_FIX_NAME(clmp)(path, clmp, orig)) == 0)
+ if (LM_FIX_NAME(clmp)(path, clmp, &palp, AL_CNT_NEEDED, orig) == 0)
return (0);
- if (((pnp->p_orig & (PN_TKN_ISALIST | PN_TKN_HWCAP)) || pnp->p_next) &&
- ((mode & RTLD_FIRST) == 0)) {
- remove_pnode(pnp);
+ if ((palp->al_arritems > 1) && ((mode & RTLD_FIRST) == 0)) {
+ remove_plist(&palp, 1);
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_ARG_ILLMODE_5));
return (0);
}
@@ -689,19 +679,19 @@
*/
if ((lmc = alist_append(&lml->lm_lists, 0, sizeof (Lm_cntl),
AL_CNT_LMLISTS)) == 0) {
- remove_pnode(pnp);
+ remove_plist(&palp, 1);
return (0);
}
olmco = nlmco = (Aliste)((char *)lmc - (char *)lml->lm_lists);
- nlmp = load_one(lml, nlmco, pnp, clmp, mode,
- (flags | FLG_RT_HANDLE), &ghp, in_nfavl);
+ nlmp = load_one(lml, nlmco, palp, clmp, mode, (flags | FLG_RT_HANDLE),
+ &ghp, in_nfavl);
/*
* Remove any expanded pathname infrastructure, and if the dependency
* couldn't be loaded, cleanup.
*/
- remove_pnode(pnp);
+ remove_plist(&palp, 1);
if (nlmp == 0) {
remove_cntl(lml, olmco);
return (0);
@@ -725,10 +715,10 @@
/*
* Finish processing the objects associated with this request.
*/
- if ((analyze_lmc(lml, nlmco, nlmp, in_nfavl) == 0) ||
+ if (((nlmp = analyze_lmc(lml, nlmco, nlmp, in_nfavl)) == NULL) ||
(relocate_lmc(lml, nlmco, clmp, nlmp, in_nfavl) == 0)) {
ghp = 0;
- nlmp = 0;
+ nlmp = NULL;
}
/*
@@ -736,7 +726,7 @@
* control list to which this request has added objects, then remove
* all the objects that have been associated to this request.
*/
- if ((nlmp == 0) && olmco && lmc->lc_head)
+ if ((nlmp == NULL) && olmco && lmc->lc_head)
remove_lmc(lml, clmp, lmc, olmco, path);
/*
@@ -769,10 +759,9 @@
void *cookie = NULL;
if (avlt) {
- while ((pnp = avl_destroy_nodes(avlt, &cookie)) != NULL) {
- free((void *)pnp->pn_name);
+ while ((pnp = avl_destroy_nodes(avlt, &cookie)) != NULL)
free(pnp);
- }
+
avl_destroy(avlt);
free(avlt);
}
@@ -798,8 +787,8 @@
* LM_ID_NEWLM: Create a new link-map.
*/
if (lml == (Lm_list *)LM_ID_NEWLM) {
- if ((lml = calloc(sizeof (Lm_list), 1)) == 0)
- return (0);
+ if ((lml = calloc(sizeof (Lm_list), 1)) == NULL)
+ return (NULL);
/*
* Establish the new link-map flags from the callers and those
@@ -819,12 +808,12 @@
if (list_append(&dynlm_list, lml) == 0) {
free(lml);
- return (0);
+ return (NULL);
}
if (newlmid(lml) == 0) {
list_delete(&dynlm_list, lml);
free(lml);
- return (0);
+ return (NULL);
}
} else if ((uintptr_t)lml < LM_ID_NUM) {
if ((uintptr_t)lml == LM_ID_BASE)
@@ -841,7 +830,7 @@
/*
* If the object could not be found it is possible that the "not-found"
* AVL tree had indicated that the file does not exist. In case the
- * file system has changes since this "not-found" recording was made,
+ * file system has changed since this "not-found" recording was made,
* retry the dlopen() with a clean "not-found" AVL tree.
*/
if ((ghp == 0) && in_nfavl) {
@@ -1029,7 +1018,7 @@
* first object check whether we're done.
*/
if ((nlmp != lmp) && (ghp->gh_flags & GPH_FIRST))
- return ((Sym *)0);
+ return (NULL);
if (!(MODE(nlmp) & RTLD_GLOBAL))
continue;
@@ -1104,7 +1093,7 @@
return (sym);
if (ghp->gh_flags & GPH_FIRST)
- return ((Sym *)0);
+ return (NULL);
}
/*
@@ -1144,7 +1133,7 @@
ghp->gh_flags |= GPH_NOPENDLAZY;
}
}
- return ((Sym *)0);
+ return (NULL);
}
/*
@@ -1177,7 +1166,7 @@
SLOOKUP_INIT(sl, name, clmp, clmp, ld_entry_cnt, elf_hash(name),
0, 0, 0, LKUP_SYMNDX);
- if ((FCT(clmp) == &elf_fct) &&
+ if (THIS_IS_ELF(clmp) &&
((sym = SYMINTP(clmp)(&sl, 0, 0, NULL)) != NULL)) {
sl.sl_rsymndx = (((ulong_t)sym -
(ulong_t)SYMTAB(clmp)) / SYMENT(clmp));
@@ -1321,7 +1310,7 @@
DBG_CALL(Dbg_bind_global(clmp, 0, 0, (Xword)-1, PLT_T_NONE,
*dlmp, addr, sym->st_value, name, binfo));
- if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_SYMBIND) {
+ if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_SYMBIND) {
uint_t sb_flags = LA_SYMB_DLSYM;
/* LINTED */
uint_t symndx = (uint_t)(((Xword)sym -
@@ -1449,14 +1438,11 @@
addr = dlsym_check(handle, name, clmp, &dlmp);
- if (dlmp)
- is_dep_ready(dlmp, clmp, DBG_WAIT_SYMBOL);
-
- if (entry && dlmp)
- is_dep_init(dlmp, clmp);
-
- if (entry)
+ if (entry) {
+ if (dlmp)
+ is_dep_init(dlmp, clmp);
leave(LIST(clmp), 0);
+ }
return (addr);
}
@@ -1500,7 +1486,7 @@
* with the supplied address. If a caller can't be determined,
* indicate the failure.
*/
- if ((clmp = _caller((caddr_t)addr, CL_NONE)) == 0) {
+ if ((clmp = _caller(addr, CL_NONE)) == 0) {
eprintf(0, ERR_FATAL, MSG_INTL(MSG_ARG_INVADDR),
EC_NATPTR(addr));
error = 0;
@@ -1547,7 +1533,7 @@
* with the supplied address. If a caller can't be determined,
* indicate the failure.
*/
- if ((clmp = _caller((caddr_t)addr, CL_NONE)) == 0) {
+ if ((clmp = _caller(addr, CL_NONE)) == 0) {
eprintf(0, ERR_FATAL, MSG_INTL(MSG_ARG_INVADDR),
EC_NATPTR(addr));
error = 0;
@@ -1703,7 +1689,7 @@
* Return profiled object name (used by ldprof audit library).
*/
if (request == RTLD_DI_PROFILENAME) {
- if (profile_name == 0) {
+ if (profile_name == NULL) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_ARG_NOPROFNAME));
return (-1);
}
@@ -1716,7 +1702,7 @@
* If a profile destination directory hasn't been specified
* provide a default.
*/
- if (profile_out == 0)
+ if (profile_out == NULL)
profile_out = MSG_ORIG(MSG_PTH_VARTMP);
*(const char **)p = profile_out;
@@ -1802,7 +1788,8 @@
* to store the information.
*/
if ((request == RTLD_DI_SERINFO) || (request == RTLD_DI_SERINFOSIZE)) {
- Pnode *dir, *dirlist = (Pnode *)0;
+ Spath_desc sd = { search_rules, NULL, 0 };
+ Pdesc *pdp;
Dl_serinfo *info;
Dl_serpath *path;
char *strs;
@@ -1816,10 +1803,10 @@
/*
* Traverse search path entries for this object.
*/
- while ((dir = get_next_dir(&dirlist, lmp, 0)) != 0) {
+ while ((pdp = get_next_dir(&sd, lmp, 0)) != 0) {
size_t _size;
- if (dir->p_name == 0)
+ if (pdp->pd_pname == 0)
continue;
/*
@@ -1827,8 +1814,8 @@
* this path has been identified as non-existent, if so
* ignore it.
*/
- if (dir->p_info) {
- Rtc_obj *dobj = (Rtc_obj *)dir->p_info;
+ if (pdp->pd_info) {
+ Rtc_obj *dobj = (Rtc_obj *)pdp->pd_info;
if (dobj->co_flags & RTC_OBJ_NOEXIST)
continue;
}
@@ -1838,7 +1825,7 @@
*/
if (cnt++)
size += sizeof (Dl_serpath);
- _size = strlen(dir->p_name) + 1;
+ _size = pdp->pd_plen + 1;
size += _size;
if (request == RTLD_DI_SERINFOSIZE)
@@ -1863,9 +1850,9 @@
/*
* Append the path to the information buffer.
*/
- (void) strcpy(strs, dir->p_name);
+ (void) strcpy(strs, pdp->pd_pname);
path->dls_name = strs;
- path->dls_flags = dir->p_orig;
+ path->dls_flags = pdp->pd_flags;
strs = strs + _size;
path++;
@@ -1887,9 +1874,6 @@
if (request == RTLD_DI_ORIGIN) {
char *str = (char *)p;
- if (DIRSZ(lmp) == 0)
- (void) fullpath(lmp, 0);
-
(void) strncpy(str, ORIGNAME(lmp), DIRSZ(lmp));
str += DIRSZ(lmp);
*str = '\0';
--- a/usr/src/cmd/sgs/rtld/common/elf.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/elf.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,89 +45,91 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_inline.h"
#include "msg.h"
/*
* Default and secure dependency search paths.
*/
-static Pnode elf_dflt_dirs[] = {
+static Spath_defn _elf_def_dirs[] = {
#if defined(_ELF64)
-#ifndef SGS_PRE_UNIFIED_PROCESS
- { MSG_ORIG(MSG_PTH_LIB_64), 0, MSG_PTH_LIB_64_SIZE,
- LA_SER_DEFAULT, 0, &elf_dflt_dirs[1] },
+ { MSG_ORIG(MSG_PTH_LIB_64), MSG_PTH_LIB_64_SIZE },
+ { MSG_ORIG(MSG_PTH_USRLIB_64), MSG_PTH_USRLIB_64_SIZE },
+#else
+ { MSG_ORIG(MSG_PTH_LIB), MSG_PTH_LIB_SIZE },
+ { MSG_ORIG(MSG_PTH_USRLIB), MSG_PTH_USRLIB_SIZE },
#endif
- { MSG_ORIG(MSG_PTH_USRLIB_64), 0, MSG_PTH_USRLIB_64_SIZE,
- LA_SER_DEFAULT, 0, 0 }
-#else
-#ifndef SGS_PRE_UNIFIED_PROCESS
- { MSG_ORIG(MSG_PTH_LIB), 0, MSG_PTH_LIB_SIZE,
- LA_SER_DEFAULT, 0, &elf_dflt_dirs[1] },
-#endif
- { MSG_ORIG(MSG_PTH_USRLIB), 0, MSG_PTH_USRLIB_SIZE,
- LA_SER_DEFAULT, 0, 0 }
-#endif
+ { 0, 0 }
};
-static Pnode elf_secure_dirs[] = {
+static Spath_defn _elf_sec_dirs[] = {
#if defined(_ELF64)
-#ifndef SGS_PRE_UNIFIED_PROCESS
- { MSG_ORIG(MSG_PTH_LIBSE_64), 0, MSG_PTH_LIBSE_64_SIZE,
- LA_SER_SECURE, 0, &elf_secure_dirs[1] },
+ { MSG_ORIG(MSG_PTH_LIBSE_64), MSG_PTH_LIBSE_64_SIZE },
+ { MSG_ORIG(MSG_PTH_USRLIBSE_64), MSG_PTH_USRLIBSE_64_SIZE },
+#else
+ { MSG_ORIG(MSG_PTH_LIBSE), MSG_PTH_LIBSE_SIZE },
+ { MSG_ORIG(MSG_PTH_USRLIBSE), MSG_PTH_USRLIBSE_SIZE },
#endif
- { MSG_ORIG(MSG_PTH_USRLIBSE_64), 0,
- MSG_PTH_USRLIBSE_64_SIZE,
- LA_SER_SECURE, 0, 0 }
-#else
-#ifndef SGS_PRE_UNIFIED_PROCESS
- { MSG_ORIG(MSG_PTH_LIBSE), 0, MSG_PTH_LIBSE_SIZE,
- LA_SER_SECURE, 0, &elf_secure_dirs[1] },
-#endif
- { MSG_ORIG(MSG_PTH_USRLIBSE), 0, MSG_PTH_USRLIBSE_SIZE,
- LA_SER_SECURE, 0, 0 }
-#endif
+ { 0, 0 }
};
+Alist *elf_def_dirs = NULL;
+Alist *elf_sec_dirs = NULL;
+
/*
* Defines for local functions.
*/
-static Pnode *elf_fix_name(const char *, Rt_map *, uint_t);
-static int elf_are_u(Rej_desc *);
static void elf_dladdr(ulong_t, Rt_map *, Dl_info *, void **, int);
-static ulong_t elf_entry_pt(void);
-static char *elf_get_so(const char *, const char *);
-static Rt_map *elf_map_so(Lm_list *, Aliste, const char *, const char *,
- int, int *);
+static Addr elf_entry_point(void);
+static int elf_fix_name(const char *, Rt_map *, Alist **, Aliste, uint_t);
+static Alist **elf_get_def_dirs(void);
+static Alist **elf_get_sec_dirs(void);
+static char *elf_get_so(const char *, const char *, size_t, size_t);
static int elf_needed(Lm_list *, Aliste, Rt_map *, int *);
-static void elf_unmap_so(Rt_map *);
-static int elf_verify_vers(const char *, Rt_map *, Rt_map *);
/*
* Functions and data accessed through indirect pointers.
*/
Fct elf_fct = {
- elf_are_u,
- elf_entry_pt,
- elf_map_so,
- elf_unmap_so,
+ elf_verify,
+ elf_new_lmp,
+ elf_entry_point,
elf_needed,
lookup_sym,
elf_reloc,
- elf_dflt_dirs,
- elf_secure_dirs,
+ elf_get_def_dirs,
+ elf_get_sec_dirs,
elf_fix_name,
elf_get_so,
elf_dladdr,
- dlsym_handle,
- elf_verify_vers,
- elf_set_prot
+ dlsym_handle
};
+/*
+ * Default and secure dependency search paths.
+ */
+static Alist **
+elf_get_def_dirs()
+{
+ if (elf_def_dirs == NULL)
+ set_dirs(&elf_def_dirs, _elf_def_dirs, LA_SER_DEFAULT);
+ return (&elf_def_dirs);
+}
+
+static Alist **
+elf_get_sec_dirs()
+{
+ if (elf_sec_dirs == NULL)
+ set_dirs(&elf_sec_dirs, _elf_sec_dirs, LA_SER_SECURE);
+ return (&elf_sec_dirs);
+}
/*
* Redefine NEEDED name if necessary.
*/
-static Pnode *
-elf_fix_name(const char *name, Rt_map *clmp, uint_t orig)
+static int
+elf_fix_name(const char *name, Rt_map *clmp, Alist **alpp, Aliste alni,
+ uint_t orig)
{
/*
* For ABI compliance, if we are asked for ld.so.1, then really give
@@ -142,21 +144,68 @@
#endif
(strcmp(name, MSG_ORIG(MSG_FIL_RTLD)) == 0)) {
/* END CSTYLED */
- Pnode *pnp;
+ Pdesc *pdp;
DBG_CALL(Dbg_file_fixname(LIST(clmp), name,
MSG_ORIG(MSG_PTH_LIBSYS)));
- if (((pnp = calloc(sizeof (Pnode), 1)) == 0) ||
- ((pnp->p_name = strdup(MSG_ORIG(MSG_PTH_LIBSYS))) == 0)) {
- if (pnp)
- free(pnp);
+ if ((pdp = alist_append(alpp, 0, sizeof (Pdesc), alni)) == NULL)
return (0);
- }
- pnp->p_len = MSG_PTH_LIBSYS_SIZE;
- return (pnp);
+
+ pdp->pd_pname = (char *)MSG_ORIG(MSG_PTH_LIBSYS);
+ pdp->pd_plen = MSG_PTH_LIBSYS_SIZE;
+ pdp->pd_flags = PD_FLG_PNSLASH;
+
+ return (1);
}
- return (expand_paths(clmp, name, orig, 0));
+ return (expand_paths(clmp, name, alpp, alni, orig, 0));
+}
+
+/*
+ * Determine whether this object requires any hardware or software capabilities.
+ */
+static int
+elf_cap_check(Fdesc *fdp, Ehdr *ehdr, Rej_desc *rej)
+{
+ Phdr *phdr;
+ int cnt;
+
+ /* LINTED */
+ phdr = (Phdr *)((char *)ehdr + ehdr->e_phoff);
+ for (cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
+ Cap *cptr;
+
+ if (phdr->p_type != PT_SUNWCAP)
+ continue;
+
+ /* LINTED */
+ cptr = (Cap *)((char *)ehdr + phdr->p_offset);
+ while (cptr->c_tag != CA_SUNW_NULL) {
+ if (cptr->c_tag == CA_SUNW_HW_1) {
+ /*
+ * Verify the hardware capabilities.
+ */
+ if (hwcap_check(cptr->c_un.c_val, rej) == 0)
+ return (0);
+
+ /*
+ * Retain this hardware capabilities value for
+ * possible later inspection should this object
+ * be processed as a filtee.
+ */
+ fdp->fd_hwcap = cptr->c_un.c_val;
+ }
+ if (cptr->c_tag == CA_SUNW_SF_1) {
+ /*
+ * Verify the software capabilities.
+ */
+ if (sfcap_check(cptr->c_un.c_val, rej) == 0)
+ return (0);
+ }
+ cptr++;
+ }
+ }
+ return (1);
}
/*
@@ -164,62 +213,87 @@
* is compatible. Returns 1 if true, else 0 and sets the reject descriptor
* with associated error information.
*/
-static int
-elf_are_u(Rej_desc *rej)
+Fct *
+elf_verify(caddr_t addr, size_t size, Fdesc *fdp, const char *name,
+ Rej_desc *rej)
{
Ehdr *ehdr;
+ char *caddr = (char *)addr;
/*
* Determine if we're an elf file. If not simply return, we don't set
* any rejection information as this test allows use to scroll through
* the objects we support (ELF, AOUT).
*/
- if (fmap->fm_fsize < sizeof (Ehdr) ||
- fmap->fm_maddr[EI_MAG0] != ELFMAG0 ||
- fmap->fm_maddr[EI_MAG1] != ELFMAG1 ||
- fmap->fm_maddr[EI_MAG2] != ELFMAG2 ||
- fmap->fm_maddr[EI_MAG3] != ELFMAG3) {
- return (0);
+ if (size < sizeof (Ehdr) ||
+ caddr[EI_MAG0] != ELFMAG0 ||
+ caddr[EI_MAG1] != ELFMAG1 ||
+ caddr[EI_MAG2] != ELFMAG2 ||
+ caddr[EI_MAG3] != ELFMAG3) {
+ return (NULL);
}
/*
* Check class and encoding.
*/
/* LINTED */
- ehdr = (Ehdr *)fmap->fm_maddr;
+ ehdr = (Ehdr *)addr;
if (ehdr->e_ident[EI_CLASS] != M_CLASS) {
rej->rej_type = SGS_REJ_CLASS;
rej->rej_info = (uint_t)ehdr->e_ident[EI_CLASS];
- return (0);
+ return (NULL);
}
if (ehdr->e_ident[EI_DATA] != M_DATA) {
rej->rej_type = SGS_REJ_DATA;
rej->rej_info = (uint_t)ehdr->e_ident[EI_DATA];
- return (0);
+ return (NULL);
}
if ((ehdr->e_type != ET_REL) && (ehdr->e_type != ET_EXEC) &&
(ehdr->e_type != ET_DYN)) {
rej->rej_type = SGS_REJ_TYPE;
rej->rej_info = (uint_t)ehdr->e_type;
- return (0);
+ return (NULL);
}
/*
- * Verify machine specific flags, and hardware capability requirements.
- */
- if ((elf_mach_flags_check(rej, ehdr) == 0) ||
- (cap_check(rej, ehdr) == 0))
- return (0);
-
- /*
- * Verify ELF version. ??? is this too restrictive ???
+ * Verify ELF version.
*/
if (ehdr->e_version > EV_CURRENT) {
rej->rej_type = SGS_REJ_VERSION;
rej->rej_info = (uint_t)ehdr->e_version;
- return (0);
+ return (NULL);
}
- return (1);
+
+ /*
+ * Verify machine specific flags.
+ */
+ if (elf_mach_flags_check(rej, ehdr) == 0)
+ return (NULL);
+
+ /*
+ * Verify any hardware/software capability requirements. Note, if this
+ * object is an explicitly defined shared object under inspection by
+ * ldd(1), and contains an incompatible hardware capabilities
+ * requirement, then inform the user, but continue processing.
+ */
+ if (elf_cap_check(fdp, ehdr, rej) == 0) {
+ Rt_map *lmp = lml_main.lm_head;
+
+ if ((lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) &&
+ (lmp != NULL) && (FLAGS1(lmp) & FL1_RT_LDDSTUB) &&
+ (NEXT(lmp) == NULL)) {
+ const char *fmt;
+
+ if (rej->rej_type == SGS_REJ_HWCAP_1)
+ fmt = MSG_INTL(MSG_LDD_GEN_HWCAP_1);
+ else
+ fmt = MSG_INTL(MSG_LDD_GEN_SFCAP_1);
+ (void) printf(fmt, name, rej->rej_str);
+ return (&elf_fct);
+ }
+ return (NULL);
+ }
+ return (&elf_fct);
}
/*
@@ -265,9 +339,9 @@
* to elf_lazy_load(). This is because all dynamic dependencies
* are recorded as lazy dependencies.
*/
- (void) elf_reloc_relacount((ulong_t)JMPREL(lmp),
+ (void) elf_reloc_relative_count((ulong_t)JMPREL(lmp),
(ulong_t)(PLTRELSZ(lmp) / RELENT(lmp)), (ulong_t)RELENT(lmp),
- (ulong_t)ADDR(lmp));
+ (ulong_t)ADDR(lmp), lmp, NULL);
#endif
lml->lm_flags |= LML_FLG_PLTREL;
@@ -281,10 +355,10 @@
elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym,
int *in_nfavl)
{
+ Alist *palp = NULL;
Rt_map *nlmp, *hlmp;
Dyninfo *dip = &DYNINFO(clmp)[ndx], *pdip;
uint_t flags = 0;
- Pnode *pnp;
const char *name;
Lm_list *lml = LIST(clmp);
Lm_cntl *lmc;
@@ -293,7 +367,7 @@
/*
* If this dependency has already been processed, we're done.
*/
- if (((nlmp = (Rt_map *)dip->di_info) != 0) ||
+ if (((nlmp = (Rt_map *)dip->di_info) != NULL) ||
(dip->di_flags & FLG_DI_LDD_DONE))
return (nlmp);
@@ -337,8 +411,8 @@
/*
* Expand the requested name if necessary.
*/
- if ((pnp = elf_fix_name(name, clmp, 0)) == 0)
- return (0);
+ if (elf_fix_name(name, clmp, &palp, AL_CNT_NEEDED, 0) == 0)
+ return (NULL);
/*
* Provided the object on the head of the link-map has completed its
@@ -347,9 +421,9 @@
hlmp = lml->lm_head;
if (FLAGS(hlmp) & FLG_RT_RELOCED) {
if ((lmc = alist_append(&lml->lm_lists, 0, sizeof (Lm_cntl),
- AL_CNT_LMLISTS)) == 0) {
- remove_pnode(pnp);
- return (0);
+ AL_CNT_LMLISTS)) == NULL) {
+ remove_plist(&palp, 1);
+ return (NULL);
}
lmco = (Aliste)((char *)lmc - (char *)lml->lm_lists);
} else {
@@ -361,14 +435,14 @@
* Load the associated object.
*/
dip->di_info = nlmp =
- load_one(lml, lmco, pnp, clmp, MODE(clmp), flags, 0, in_nfavl);
+ load_one(lml, lmco, palp, clmp, MODE(clmp), flags, 0, in_nfavl);
/*
* Remove any expanded pathname infrastructure. Reduce the pending lazy
* dependency count of the caller, together with the link-map lists
* count of objects that still have lazy dependencies pending.
*/
- remove_pnode(pnp);
+ remove_plist(&palp, 1);
if (--LAZY(clmp) == 0)
LIST(clmp)->lm_lazy--;
@@ -377,16 +451,16 @@
* create an association between the caller and this dependency.
*/
if (nlmp && ((bind_one(clmp, nlmp, BND_NEEDED) == 0) ||
- (analyze_lmc(lml, lmco, nlmp, in_nfavl) == 0) ||
+ ((nlmp = analyze_lmc(lml, lmco, nlmp, in_nfavl)) == NULL) ||
(relocate_lmc(lml, lmco, clmp, nlmp, in_nfavl) == 0)))
- dip->di_info = nlmp = 0;
+ dip->di_info = nlmp = NULL;
/*
* If this lazyload has failed, and we've created a new link-map
* control list to which this request has added objects, then remove
* all the objects that have been associated to this request.
*/
- if ((nlmp == 0) && lmc && lmc->lc_head)
+ if ((nlmp == NULL) && lmc && lmc->lc_head)
remove_lmc(lml, clmp, lmc, lmco, name);
/*
@@ -399,7 +473,7 @@
* If this lazy loading failed, record the fact, and bump the lazy
* counts.
*/
- if (nlmp == 0) {
+ if (nlmp == NULL) {
dip->di_flags |= FLG_DI_LAZYFAIL;
if (LAZY(clmp)++ == 0)
LIST(clmp)->lm_lazy++;
@@ -411,69 +485,24 @@
/*
* Return the entry point of the ELF executable.
*/
-static ulong_t
-elf_entry_pt(void)
+static Addr
+elf_entry_point(void)
{
- return (ENTRY(lml_main.lm_head));
-}
-
-/*
- * Unmap a given ELF shared object from the address space.
- */
-static void
-elf_unmap_so(Rt_map *lmp)
-{
- caddr_t addr;
- size_t size;
- Mmap *mmaps;
+ Rt_map *lmp = lml_main.lm_head;
+ Ehdr *ehdr = (Ehdr *)ADDR(lmp);
+ Addr addr = (Addr)(ehdr->e_entry);
- /*
- * If this link map represents a relocatable object concatenation, then
- * the image was simply generated in allocated memory. Free the memory.
- *
- * Note: the memory was originally allocated in the libelf:_elf_outmap
- * routine and would normally have been free'd in elf_outsync(), but
- * because we 'interpose' on that routine the memory wasn't free'd at
- * that time.
- */
- if (FLAGS(lmp) & FLG_RT_IMGALLOC) {
- free((void *)ADDR(lmp));
- return;
- }
+ if ((FLAGS(lmp) & FLG_RT_FIXED) == 0)
+ addr += ADDR(lmp);
- /*
- * If padding was enabled via rtld_db, then we have at least one page
- * in front of the image - and possibly a trailing page.
- * Unmap the front page first:
- */
- if (PADSTART(lmp) != ADDR(lmp)) {
- addr = (caddr_t)M_PTRUNC(PADSTART(lmp));
- size = ADDR(lmp) - (ulong_t)addr;
- (void) munmap(addr, size);
- }
-
- /*
- * Unmap any trailing padding.
- */
- if (M_PROUND((PADSTART(lmp) + PADIMLEN(lmp))) >
- M_PROUND(ADDR(lmp) + MSIZE(lmp))) {
- addr = (caddr_t)M_PROUND(ADDR(lmp) + MSIZE(lmp));
- size = M_PROUND(PADSTART(lmp) + PADIMLEN(lmp)) - (ulong_t)addr;
- (void) munmap(addr, size);
- }
-
- /*
- * Unmmap all mapped segments.
- */
- for (mmaps = MMAPS(lmp); mmaps->m_vaddr; mmaps++)
- (void) munmap(mmaps->m_vaddr, mmaps->m_msize);
+ return (addr);
}
/*
* Determine if a dependency requires a particular version and if so verify
* that the version exists in the dependency.
*/
-static int
+int
elf_verify_vers(const char *name, Rt_map *clmp, Rt_map *nlmp)
{
Verneed *vnd = VERNEED(clmp);
@@ -605,6 +634,7 @@
static int
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;
@@ -623,7 +653,6 @@
Rt_map *nlmp = 0;
char *name;
int silent = 0;
- Pnode *pnp;
switch (dyn->d_tag) {
case DT_POSFLAG_1:
@@ -723,9 +752,10 @@
* Establish the objects name, load it and establish a binding
* with the caller.
*/
- if (((pnp = elf_fix_name(name, clmp, 0)) == 0) || ((nlmp =
- load_one(lml, lmco, pnp, clmp, MODE(clmp), flags, 0,
- in_nfavl)) == 0) || (bind_one(clmp, nlmp, BND_NEEDED) == 0))
+ if ((elf_fix_name(name, clmp, &palp, AL_CNT_NEEDED, 0) == 0) ||
+ ((nlmp = load_one(lml, lmco, palp, clmp, MODE(clmp),
+ flags, 0, in_nfavl)) == NULL) ||
+ (bind_one(clmp, nlmp, BND_NEEDED) == 0))
nlmp = 0;
/*
@@ -733,8 +763,8 @@
* error suppression state, if it had been previously set in
* this routine.
*/
- if (pnp)
- remove_pnode(pnp);
+ remove_plist(&palp, 0);
+
if (silent)
rtld_flags &= ~RT_FL_SILENCERR;
@@ -746,578 +776,20 @@
if ((MODE(clmp) & RTLD_CONFGEN) || (lmflags &
(LML_FLG_LOADAVAIL | LML_FLG_TRC_ENABLE)))
continue;
- else
+ else {
+ remove_plist(&palp, 1);
return (0);
+ }
}
}
if (LAZY(clmp))
lml->lm_lazy++;
+ remove_plist(&palp, 1);
return (1);
}
-static int
-elf_map_check(Lm_list *lml, const char *name, caddr_t vaddr, Off size)
-{
- prmap_t *maps, *_maps;
- int pfd, num, _num;
- caddr_t eaddr = vaddr + size;
- int err;
-
- /*
- * If memory reservations have been established for alternative objects
- * determine if this object falls within the reservation, if it does no
- * further checking is required.
- */
- if (rtld_flags & RT_FL_MEMRESV) {
- Rtc_head *head = (Rtc_head *)config->c_bgn;
-
- if ((vaddr >= (caddr_t)(uintptr_t)head->ch_resbgn) &&
- (eaddr <= (caddr_t)(uintptr_t)head->ch_resend))
- return (0);
- }
-
- /*
- * Determine the mappings presently in use by this process.
- */
- if ((pfd = pr_open(lml)) == FD_UNAVAIL)
- return (1);
-
- if (ioctl(pfd, PIOCNMAP, (void *)&num) == -1) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), name,
- strerror(err));
- return (1);
- }
-
- if ((maps = malloc((num + 1) * sizeof (prmap_t))) == 0)
- return (1);
-
- if (ioctl(pfd, PIOCMAP, (void *)maps) == -1) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), name,
- strerror(err));
- free(maps);
- return (1);
- }
-
- /*
- * Determine if the supplied address clashes with any of the present
- * process mappings.
- */
- for (_num = 0, _maps = maps; _num < num; _num++, _maps++) {
- caddr_t _eaddr = _maps->pr_vaddr + _maps->pr_size;
- Rt_map *lmp;
- const char *str;
-
- if ((eaddr < _maps->pr_vaddr) || (vaddr >= _eaddr))
- continue;
-
- /*
- * We have a memory clash. See if one of the known dynamic
- * dependency mappings represents this space so as to provide
- * the user a more meaningful message.
- */
- if ((lmp = _caller(vaddr, 0)) != 0)
- str = NAME(lmp);
- else
- str = MSG_INTL(MSG_STR_UNKNOWN);
-
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_GEN_MAPINUSE), name,
- EC_NATPTR(vaddr), EC_OFF(size), str);
- return (1);
- }
- free(maps);
- return (0);
-}
-
-/*
- * Obtain a memory reservation. On newer systems, both MAP_ANON and MAP_ALIGN
- * are used to obtained an aligned reservation from anonymous memory. If
- * MAP_ANON isn't available, then MAP_ALIGN isn't either, so obtain a standard
- * reservation using the file as backing.
- */
-static Am_ret
-elf_map_reserve(Lm_list *lml, const char *name, caddr_t *maddr, Off msize,
- int mperm, int fd, Xword align)
-{
- Am_ret amret;
- int mflag = MAP_PRIVATE | MAP_NORESERVE;
-
-#if defined(MAP_ALIGN)
- if ((rtld_flags2 & RT_FL2_NOMALIGN) == 0) {
- mflag |= MAP_ALIGN;
- *maddr = (caddr_t)align;
- }
-#endif
- if ((amret = anon_map(lml, maddr, msize, PROT_NONE, mflag)) == AM_ERROR)
- return (amret);
-
- if (amret == AM_OK)
- return (AM_OK);
-
- /*
- * If an anonymous memory request failed (which should only be the
- * case if it is unsupported on the system we're running on), establish
- * the initial mapping directly from the file.
- */
- *maddr = 0;
- if ((*maddr = mmap(*maddr, msize, mperm, MAP_PRIVATE,
- fd, 0)) == MAP_FAILED) {
- int err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), name,
- strerror(err));
- return (AM_ERROR);
- }
- return (AM_NOSUP);
-}
-
-static void *
-elf_map_textdata(caddr_t addr, Off flen, int mperm, int phdr_mperm, int mflag,
- int fd, Off foff)
-{
-#if defined(MAP_TEXT) && defined(MAP_INITDATA)
- static int notd = 0;
-
- /*
- * If MAP_TEXT and MAP_INITDATA are available, select the appropriate
- * flag.
- */
- if (notd == 0) {
- if ((phdr_mperm & (PROT_WRITE | PROT_EXEC)) == PROT_EXEC)
- mflag |= MAP_TEXT;
- else
- mflag |= MAP_INITDATA;
- }
-#endif
- if (mmap((caddr_t)addr, flen, mperm, mflag, fd, foff) != MAP_FAILED)
- return (0);
-
-#if defined(MAP_TEXT) && defined(MAP_INITDATA)
- if ((notd == 0) && (errno == EINVAL)) {
- /*
- * MAP_TEXT and MAP_INITDATA may not be supported on this
- * platform, try again without.
- */
- notd = 1;
- mflag &= ~(MAP_TEXT | MAP_INITDATA);
-
- return (mmap((caddr_t)addr, flen, mperm, mflag, fd, foff));
- }
-#endif
- return (MAP_FAILED);
-}
-
-/*
- * Map in a file.
- */
-static caddr_t
-elf_map_it(
- Lm_list *lml, /* link-map list */
- const char *name, /* actual name stored for pathname */
- Off fsize, /* total mapping claim of the file */
- Ehdr *ehdr, /* ELF header of file */
- Phdr *fphdr, /* first loadable Phdr */
- Phdr *lphdr, /* last loadable Phdr */
- Phdr **rrphdr, /* return first Phdr in reservation */
- caddr_t *rraddr, /* return start of reservation */
- Off *rrsize, /* return total size of reservation */
- int fixed, /* image is resolved to a fixed addr */
- int fd, /* images file descriptor */
- Xword align, /* image segments maximum alignment */
- Mmap *mmaps, /* mmap information array and */
- uint_t *mmapcnt) /* mapping count */
-{
- caddr_t raddr; /* reservation address */
- Off rsize; /* reservation size */
- Phdr *phdr; /* working program header poiner */
- caddr_t maddr; /* working mmap address */
- caddr_t faddr; /* working file address */
- size_t padsize; /* object padding requirement */
- size_t padpsize = 0; /* padding size rounded to next page */
- size_t padmsize = 0; /* padding size rounded for alignment */
- int skipfseg; /* skip mapping first segment */
- int mperm; /* segment permissions */
- Am_ret amret = AM_NOSUP;
-
- /*
- * If padding is required extend both the front and rear of the image.
- * To insure the image itself is mapped at the correct alignment the
- * initial padding is rounded up to the nearest page. Once the image is
- * mapped the excess can be pruned to the nearest page required for the
- * actual padding itself.
- */
- if ((padsize = r_debug.rtd_objpad) != 0) {
- padpsize = M_PROUND(padsize);
- if (fixed)
- padmsize = padpsize;
- else
- padmsize = S_ROUND(padsize, align);
- }
-
- /*
- * Determine the initial permissions used to map in the first segment.
- * If this segments memsz is greater that its filesz then the difference
- * must be zeroed. Make sure this segment is writable.
- */
- mperm = 0;
- if (fphdr->p_flags & PF_R)
- mperm |= PROT_READ;
- if (fphdr->p_flags & PF_X)
- mperm |= PROT_EXEC;
- if ((fphdr->p_flags & PF_W) || (fphdr->p_memsz > fphdr->p_filesz))
- mperm |= PROT_WRITE;
-
- /*
- * Determine whether or not to let system reserve address space based on
- * whether this is a dynamic executable (addresses in object are fixed)
- * or a shared object (addresses in object are relative to the objects'
- * base).
- */
- if (fixed) {
- /*
- * Determine the reservation address and size, and insure that
- * this reservation isn't already in use.
- */
- faddr = maddr = (caddr_t)M_PTRUNC((ulong_t)fphdr->p_vaddr);
- raddr = maddr - padpsize;
- rsize = fsize + padpsize + padsize;
-
- if (lml_main.lm_head) {
- if (elf_map_check(lml, name, raddr, rsize) != 0)
- return (0);
- }
-
- /*
- * As this is a fixed image, all segments must be individually
- * mapped.
- */
- skipfseg = 0;
-
- } else {
- size_t esize;
-
- /*
- * If this isn't a fixed image, reserve enough address space for
- * the entire image to be mapped. The amount of reservation is
- * the range between the beginning of the first, and end of the
- * last loadable segment, together with any padding, plus the
- * alignment of the first segment.
- *
- * The optimal reservation is made as a no-reserve mapping from
- * anonymous memory. Each segment is then mapped into this
- * reservation. If the anonymous mapping capability isn't
- * available, the reservation is obtained from the file itself.
- * In this case the first segment of the image is mapped as part
- * of the reservation, thus only the following segments need to
- * be remapped.
- */
- rsize = fsize + padmsize + padsize;
- if ((amret = elf_map_reserve(lml, name, &raddr, rsize, mperm,
- fd, align)) == AM_ERROR)
- return (0);
- maddr = raddr + padmsize;
- faddr = (caddr_t)S_ROUND((Off)maddr, align);
-
- /*
- * If this reservation has been obtained from anonymous memory,
- * then all segments must be individually mapped. Otherwise,
- * the first segment heads the reservation.
- */
- if (amret == AM_OK)
- skipfseg = 0;
- else
- skipfseg = 1;
-
- /*
- * For backward compatibility (where MAP_ALIGN isn't available),
- * insure the alignment of the reservation is adequate for this
- * object, and if not remap the object to obtain the correct
- * alignment.
- */
- if (faddr != maddr) {
- (void) munmap(raddr, rsize);
-
- rsize += align;
- if ((amret = elf_map_reserve(lml, name, &raddr, rsize,
- mperm, fd, align)) == AM_ERROR)
- return (0);
-
- maddr = faddr = (caddr_t)S_ROUND((Off)(raddr +
- padpsize), align);
-
- esize = maddr - raddr + padpsize;
-
- /*
- * As ths image has been realigned, the first segment
- * of the file needs to be remapped to its correct
- * location.
- */
- skipfseg = 0;
- } else
- esize = padmsize - padpsize;
-
- /*
- * If this reservation included padding, remove any excess for
- * the start of the image (the padding was adjusted to insure
- * the image was aligned appropriately).
- */
- if (esize) {
- (void) munmap(raddr, esize);
- raddr += esize;
- rsize -= esize;
- }
- }
-
- /*
- * At this point we know the initial location of the image, and its
- * size. Pass these back to the caller for inclusion in the link-map
- * that will eventually be created.
- */
- *rraddr = raddr;
- *rrsize = rsize;
-
- /*
- * The first loadable segment is now pointed to by maddr. This segment
- * will eventually contain the elf header and program headers, so reset
- * the program header. Pass this back to the caller for inclusion in
- * the link-map so it can be used for later unmapping operations.
- */
- /* LINTED */
- *rrphdr = (Phdr *)((char *)maddr + ehdr->e_phoff);
-
- /*
- * If padding is required at the front of the image, obtain that now.
- * Note, if we've already obtained a reservation from anonymous memory
- * then this reservation will already include suitable padding.
- * Otherwise this reservation is backed by the file, or in the case of
- * a fixed image, doesn't yet exist. Map the padding so that it is
- * suitably protected (PROT_NONE), and insure the first segment of the
- * file is mapped to its correct location.
- */
- if (padsize) {
- if (amret == AM_NOSUP) {
- if (dz_map(lml, raddr, padpsize, PROT_NONE,
- (MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE)) ==
- MAP_FAILED)
- return (0);
-
- skipfseg = 0;
- }
- rsize -= padpsize;
- }
-
- /*
- * Map individual segments. For a fixed image, these will each be
- * unique mappings. For a reservation these will fill in the
- * reservation.
- */
- for (phdr = fphdr; phdr <= lphdr;
- phdr = (Phdr *)((Off)phdr + ehdr->e_phentsize)) {
- caddr_t addr;
- Off mlen, flen;
- size_t size;
-
- /*
- * Skip non-loadable segments or segments that don't occupy
- * any memory.
- */
- if ((phdr->p_type != PT_LOAD) || (phdr->p_memsz == 0))
- continue;
-
- /*
- * Establish this segments address relative to our base.
- */
- addr = (caddr_t)M_PTRUNC((ulong_t)(phdr->p_vaddr +
- (fixed ? 0 : faddr)));
-
- /*
- * Determine the mapping protection from the segment attributes.
- * Also determine the etext address from the last loadable
- * segment which has permissions but no write access.
- */
- mperm = 0;
- if (phdr->p_flags) {
- if (phdr->p_flags & PF_R)
- mperm |= PROT_READ;
- if (phdr->p_flags & PF_X)
- mperm |= PROT_EXEC;
- if (phdr->p_flags & PF_W)
- mperm |= PROT_WRITE;
- else
- fmap->fm_etext = phdr->p_vaddr + phdr->p_memsz +
- (ulong_t)(fixed ? 0 : faddr);
- }
-
- /*
- * Determine the type of mapping required.
- */
- if ((phdr->p_filesz == 0) && (phdr->p_flags == 0)) {
- /*
- * If this segment has no backing file and no flags
- * specified, then it defines a reservation. At this
- * point all standard loadable segments will have been
- * processed. The segment reservation is mapped
- * directly from /dev/null.
- */
- if (nu_map(lml, (caddr_t)addr, phdr->p_memsz, PROT_NONE,
- MAP_FIXED | MAP_PRIVATE) == MAP_FAILED)
- return (0);
-
- mlen = phdr->p_memsz;
- flen = 0;
-
- } else if (phdr->p_filesz == 0) {
- /*
- * If this segment has no backing file then it defines a
- * nobits segment and is mapped directly from /dev/zero.
- */
- if (dz_map(lml, (caddr_t)addr, phdr->p_memsz, mperm,
- MAP_FIXED | MAP_PRIVATE) == MAP_FAILED)
- return (0);
-
- mlen = phdr->p_memsz;
- flen = 0;
-
- } else {
- Off foff;
-
- /*
- * This mapping originates from the file. Determine the
- * file offset to which the mapping will be directed
- * (must be aligned) and how much to map (might be more
- * than the file in the case of .bss).
- */
- foff = M_PTRUNC((ulong_t)phdr->p_offset);
- mlen = phdr->p_memsz + (phdr->p_offset - foff);
- flen = phdr->p_filesz + (phdr->p_offset - foff);
-
- /*
- * If this is a non-fixed, non-anonymous mapping, and no
- * padding is involved, then the first loadable segment
- * is already part of the initial reservation. In this
- * case there is no need to remap this segment.
- */
- if ((skipfseg == 0) || (phdr != fphdr)) {
- int phdr_mperm = mperm;
- /*
- * If this segments memsz is greater that its
- * filesz then the difference must be zeroed.
- * Make sure this segment is writable.
- */
- if (phdr->p_memsz > phdr->p_filesz)
- mperm |= PROT_WRITE;
-
- if (elf_map_textdata((caddr_t)addr, flen,
- mperm, phdr_mperm,
- (MAP_FIXED | MAP_PRIVATE), fd, foff) ==
- MAP_FAILED) {
- int err = errno;
- eprintf(lml, ERR_FATAL,
- MSG_INTL(MSG_SYS_MMAP), name,
- strerror(err));
- return (0);
- }
- }
-
- /*
- * If the memory occupancy of the segment overflows the
- * definition in the file, we need to "zero out" the end
- * of the mapping we've established, and if necessary,
- * map some more space from /dev/zero. Note, zero'ed
- * memory must end on a double word boundary to satisfy
- * zero().
- */
- if (phdr->p_memsz > phdr->p_filesz) {
- caddr_t zaddr;
- size_t zlen, zplen;
- Off fend;
-
- foff = (Off)(phdr->p_vaddr + phdr->p_filesz +
- (fixed ? 0 : faddr));
- zaddr = (caddr_t)M_PROUND(foff);
- zplen = (size_t)(zaddr - foff);
-
- fend = (Off)S_DROUND((size_t)(phdr->p_vaddr +
- phdr->p_memsz + (fixed ? 0 : faddr)));
- zlen = (size_t)(fend - foff);
-
- /*
- * Determine whether the number of bytes that
- * must be zero'ed overflow to the next page.
- * If not, simply clear the exact bytes
- * (filesz to memsz) from this page. Otherwise,
- * clear the remaining bytes of this page, and
- * map an following pages from /dev/zero.
- */
- if (zlen < zplen)
- zero((caddr_t)foff, (long)zlen);
- else {
- zero((caddr_t)foff, (long)zplen);
-
- if ((zlen = (fend - (Off)zaddr)) > 0) {
- if (dz_map(lml, zaddr, zlen,
- mperm,
- MAP_FIXED | MAP_PRIVATE) ==
- MAP_FAILED)
- return (0);
- }
- }
- }
- }
-
- /*
- * Unmap anything from the last mapping address to this one and
- * update the mapping claim pointer.
- */
- if ((fixed == 0) && ((size = addr - maddr) != 0)) {
- (void) munmap(maddr, size);
- rsize -= size;
- }
-
- /*
- * Retain this segments mapping information.
- */
- mmaps[*mmapcnt].m_vaddr = addr;
- mmaps[*mmapcnt].m_msize = mlen;
- mmaps[*mmapcnt].m_fsize = flen;
- mmaps[*mmapcnt].m_perm = mperm;
- (*mmapcnt)++;
-
- maddr = addr + M_PROUND(mlen);
- rsize -= M_PROUND(mlen);
- }
-
- /*
- * If padding is required at the end of the image, obtain that now.
- * Note, if we've already obtained a reservation from anonymous memory
- * then this reservation will already include suitable padding.
- */
- if (padsize) {
- if (amret == AM_NOSUP) {
- /*
- * maddr is currently page aligned from the last segment
- * mapping.
- */
- if (dz_map(lml, maddr, padsize, PROT_NONE,
- (MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE)) ==
- MAP_FAILED)
- return (0);
- }
- maddr += padsize;
- rsize -= padsize;
- }
-
- /*
- * Unmap any final reservation.
- */
- if ((fixed == 0) && (rsize != 0))
- (void) munmap(maddr, rsize);
-
- return (faddr);
-}
-
/*
* A null symbol interpretor. Used if a filter has no associated filtees.
*/
@@ -1334,14 +806,11 @@
static void
elf_disable_filtee(Rt_map *lmp, Dyninfo *dip)
{
- dip->di_info = 0;
-
if ((dip->di_flags & FLG_DI_SYMFLTR) == 0) {
/*
- * If this is an object filter, free the filtee's duplication.
+ * If this is an object filter, null out the reference name.
*/
if (OBJFLTRNDX(lmp) != FLTR_DISABLED) {
- free(REFNAME(lmp));
REFNAME(lmp) = NULL;
OBJFLTRNDX(lmp) = FLTR_DISABLED;
@@ -1382,10 +851,11 @@
const char *name = slp->sl_name, *filtees;
Rt_map *clmp = slp->sl_cmap;
Rt_map *ilmp = slp->sl_imap;
- Pnode *pnp, **pnpp;
+ Pdesc *pdp;
int any;
Dyninfo *dip = &DYNINFO(ilmp)[ndx];
Lm_list *lml = LIST(ilmp);
+ Aliste idx;
/*
* Indicate that the filter has been used. If a binding already exists
@@ -1425,8 +895,8 @@
filtees = (char *)STRTAB(ilmp) + DYN(ilmp)[ndx].d_un.d_val;
if (dip->di_info == 0) {
if (rtld_flags2 & RT_FL2_FLTCFG)
- dip->di_info = elf_config_flt(lml, PATHNAME(ilmp),
- filtees);
+ elf_config_flt(lml, PATHNAME(ilmp), filtees,
+ (Alist **)&dip->di_info, AL_CNT_FILTEES);
if (dip->di_info == 0) {
DBG_CALL(Dbg_file_filter(lml, NAME(ilmp), filtees, 0));
@@ -1436,8 +906,8 @@
(void) printf(MSG_INTL(MSG_LDD_FIL_FILTER),
NAME(ilmp), filtees);
- if ((dip->di_info = (void *)expand_paths(ilmp,
- filtees, 0, 0)) == 0) {
+ if (expand_paths(ilmp, filtees, (Alist **)&dip->di_info,
+ AL_CNT_FILTEES, 0, 0) == 0) {
elf_disable_filtee(ilmp, dip);
return (NULL);
}
@@ -1448,13 +918,13 @@
* Traverse the filtee list, dlopen()'ing any objects specified and
* using their group handle to lookup the symbol.
*/
- for (any = 0, pnpp = (Pnode **)&(dip->di_info), pnp = *pnpp; pnp;
- pnpp = &pnp->p_next, pnp = *pnpp) {
+ any = 0;
+ for (ALIST_TRAVERSE((Alist *)dip->di_info, idx, pdp)) {
int mode;
Grp_hdl *ghp;
Rt_map *nlmp = 0;
- if (pnp->p_len == 0)
+ if (pdp->pd_plen == 0)
continue;
/*
@@ -1479,13 +949,14 @@
* link-map control list from which to analyze any newly added
* objects.
*/
- if ((pnp->p_info == 0) && (pnp->p_orig & PN_TKN_HWCAP)) {
- Lm_cntl *lmc;
- Aliste lmco;
+ if ((pdp->pd_info == 0) && (pdp->pd_flags & PD_TKN_HWCAP)) {
+ const char *dir = pdp->pd_pname;
+ Lm_cntl *lmc;
+ Aliste lmco;
if (FLAGS(lml->lm_head) & FLG_RT_RELOCED) {
if ((lmc = alist_append(&lml->lm_lists, 0,
- sizeof (Lm_cntl), AL_CNT_LMLISTS)) == 0)
+ sizeof (Lm_cntl), AL_CNT_LMLISTS)) == NULL)
return (NULL);
lmco = (Aliste)((char *)lmc -
(char *)lml->lm_lists);
@@ -1494,8 +965,36 @@
lmco = ALIST_OFF_DATA;
}
- pnp = hwcap_filtees(pnpp, lmco, lmc, dip, ilmp, filtees,
- mode, (FLG_RT_HANDLE | FLG_RT_HWCAP), in_nfavl);
+ /*
+ * Determine the hardware capability filtees. If none
+ * can be found, provide suitable diagnostics.
+ */
+ DBG_CALL(Dbg_cap_hw_filter(lml, dir, ilmp));
+ if (hwcap_filtees((Alist **)&dip->di_info, idx, dir,
+ lmco, lmc, ilmp, filtees, mode,
+ (FLG_RT_HANDLE | FLG_RT_HWCAP), in_nfavl) == 0) {
+ if ((lml->lm_flags & LML_FLG_TRC_ENABLE) &&
+ (dip->di_flags & FLG_DI_AUXFLTR) &&
+ (rtld_flags & RT_FL_WARNFLTR)) {
+ (void) printf(
+ MSG_INTL(MSG_LDD_HWCAP_NFOUND),
+ dir);
+ }
+ DBG_CALL(Dbg_cap_hw_filter(lml, dir, 0));
+ }
+
+ /*
+ * Re-establish the originating path name descriptor, as
+ * the expansion of hardware capabilities filtees may
+ * have re-allocated the controlling Alist. Mark this
+ * original pathname descriptor as unused so that the
+ * descriptor isn't revisited for processing. Any real
+ * hardware capabilities filtees have been added as new
+ * pathname descriptors following this descriptor.
+ */
+ pdp = alist_item((Alist *)dip->di_info, idx);
+ pdp->pd_flags &= ~PD_TKN_HWCAP;
+ pdp->pd_plen = 0;
/*
* Now that any hardware capability objects have been
@@ -1505,14 +1004,14 @@
remove_cntl(lml, lmco);
}
- if (pnp->p_len == 0)
+ if (pdp->pd_plen == 0)
continue;
/*
* Process an individual filtee.
*/
- if (pnp->p_info == 0) {
- const char *filtee = pnp->p_name;
+ if (pdp->pd_info == 0) {
+ const char *filtee = pdp->pd_pname;
int audit = 0;
DBG_CALL(Dbg_file_filtee(lml, NAME(ilmp), filtee, 0));
@@ -1550,7 +1049,7 @@
* recursion.
*/
if (nlmp && ghp)
- pnp->p_info = (void *)ghp;
+ pdp->pd_info = (void *)ghp;
/*
* Audit the filter/filtee established. Ignore
@@ -1558,17 +1057,26 @@
* allow ignore filtering to ld.so.1, otherwise
* nothing is going to work.
*/
- if (nlmp && ((lml->lm_tflags | FLAGS1(ilmp)) &
+ if (nlmp && ((lml->lm_tflags | AFLAGS(ilmp)) &
LML_TFLG_AUD_OBJFILTER))
(void) audit_objfilter(ilmp, filtees,
nlmp, 0);
} else {
Rej_desc rej = { 0 };
+ Fdesc fd = { 0 };
Lm_cntl *lmc;
Aliste lmco;
/*
+ * Trace the inspection of this file, determine
+ * any auditor substitution, and seed the file
+ * descriptor with the originating name.
+ */
+ if (load_trace(lml, pdp, clmp, &fd) == NULL)
+ continue;
+
+ /*
* Establish a new link-map control list from
* which to analyze any newly added objects.
*/
@@ -1576,7 +1084,7 @@
if ((lmc =
alist_append(&lml->lm_lists, 0,
sizeof (Lm_cntl),
- AL_CNT_LMLISTS)) == 0)
+ AL_CNT_LMLISTS)) == NULL)
return (NULL);
lmco = (Aliste)((char *)lmc -
(char *)lml->lm_lists);
@@ -1586,17 +1094,15 @@
}
/*
- * Load the filtee. Note, an auditor can
- * provide an alternative name.
+ * Locate and load the filtee.
*/
- if ((nlmp = load_path(lml, lmco, &(pnp->p_name),
- ilmp, mode, FLG_RT_HANDLE, &ghp, 0,
- &rej, in_nfavl)) == 0) {
+ if ((nlmp = load_path(lml, lmco, ilmp, mode,
+ FLG_RT_HANDLE, &ghp, &fd, &rej,
+ in_nfavl)) == NULL)
file_notfound(LIST(ilmp), filtee, ilmp,
FLG_RT_HANDLE, &rej);
- remove_rej(&rej);
- }
- filtee = pnp->p_name;
+
+ filtee = pdp->pd_pname;
/*
* Establish the filter handle to prevent any
@@ -1604,7 +1110,7 @@
*/
if (nlmp && ghp) {
ghp->gh_flags |= GPH_FILTEE;
- pnp->p_info = (void *)ghp;
+ pdp->pd_info = (void *)ghp;
FLAGS1(nlmp) |= FL1_RT_USED;
}
@@ -1630,9 +1136,10 @@
* provide sufficient information to tear down
* this filtee if necessary.
*/
- if (nlmp && ghp && ((analyze_lmc(lml, lmco,
- nlmp, in_nfavl) == 0) || (relocate_lmc(lml,
- lmco, ilmp, nlmp, in_nfavl) == 0)))
+ if (nlmp && ghp && (((nlmp = analyze_lmc(lml,
+ lmco, nlmp, in_nfavl)) == NULL) ||
+ (relocate_lmc(lml, lmco, ilmp, nlmp,
+ in_nfavl) == 0)))
nlmp = 0;
/*
@@ -1649,6 +1156,14 @@
nlmp = 0;
/*
+ * Generate a diagnostic if the filtee couldn't
+ * be loaded.
+ */
+ if (nlmp == 0)
+ DBG_CALL(Dbg_file_filtee(lml, 0, filtee,
+ audit));
+
+ /*
* If this filtee loading has failed, and we've
* created a new link-map control list to which
* this request has added objects, then remove
@@ -1667,22 +1182,19 @@
}
/*
- * Generate a diagnostic if the filtee couldn't be
- * loaded, null out the pnode entry, and continue
- * the search. Otherwise, retain this group handle
- * for future symbol searches.
+ * If the filtee couldn't be loaded, null out the
+ * path name descriptor entry, and continue the search.
+ * Otherwise, the group handle is retained for future
+ * symbol searches.
*/
if (nlmp == 0) {
- DBG_CALL(Dbg_file_filtee(lml, 0, filtee,
- audit));
-
- pnp->p_info = 0;
- pnp->p_len = 0;
+ pdp->pd_info = NULL;
+ pdp->pd_plen = 0;
continue;
}
}
- ghp = (Grp_hdl *)pnp->p_info;
+ ghp = (Grp_hdl *)pdp->pd_info;
/*
* If we're just here to trigger filtee loading skip the symbol
@@ -1748,14 +1260,14 @@
return (NULL);
/*
- * If no filtees have been found for a filter, clean up any Pnode
- * structures and disable their search completely. For auxiliary
+ * If no filtees have been found for a filter, clean up any path name
+ * descriptors and disable their search completely. For auxiliary
* filters we can reselect the symbol search function so that we never
* enter this routine again for this object. For standard filters we
* use the null symbol routine.
*/
if (any == 0) {
- remove_pnode((Pnode *)dip->di_info);
+ remove_plist((Alist **)&(dip->di_info), 1);
elf_disable_filtee(ilmp, dip);
return (NULL);
}
@@ -2117,105 +1629,145 @@
* all values.
*/
Rt_map *
-elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
- ulong_t addr, ulong_t etext, Aliste lmco, ulong_t msize, ulong_t entry,
- ulong_t paddr, ulong_t padimsize, Mmap *mmaps, uint_t mmapcnt,
- int *in_nfavl)
+elf_new_lmp(Lm_list *lml, Aliste lmco, Fdesc *fdp, Addr addr, size_t msize,
+ void *odyn, int *in_nfavl)
{
+ const char *name = fdp->fd_nname;
Rt_map *lmp;
- ulong_t base, fltr = 0, audit = 0, cfile = 0, crle = 0;
+ Ehdr *ehdr = (Ehdr *)addr;
+ Phdr *phdr, *tphdr = NULL, *dphdr = NULL, *uphdr = NULL;
+ Dyn *dyn = (Dyn *)odyn;
+ Cap *cap = NULL;
+ int ndx;
+ Addr base, fltr = 0, audit = 0, cfile = 0, crle = 0;
Xword rpath = 0;
- Ehdr *ehdr = (Ehdr *)addr;
+ size_t lmsz, rtsz, epsz, dynsz = 0;
+ uint_t dyncnt = 0;
+
+ DBG_CALL(Dbg_file_elf(lml, name, addr, msize, lml->lm_lmidstr, lmco));
- DBG_CALL(Dbg_file_elf(lml, pname, (ulong_t)ld, addr, msize, entry,
- lml->lm_lmidstr, lmco));
+ /*
+ * If this is a shared object, the base address of the shared object is
+ * added to all address values defined within the object. Otherwise, if
+ * this is an executable, all object addresses are used as is.
+ */
+ if (ehdr->e_type == ET_EXEC)
+ base = 0;
+ else
+ base = addr;
/*
- * Allocate space for the link-map and private elf information. Once
- * these are allocated and initialized, we can use remove_so(0, lmp) to
- * tear down the link-map should any failures occur.
+ * Traverse the program header table, picking off required items. This
+ * traversal also provides for the sizing of the PT_DYNAMIC section.
*/
- if ((lmp = calloc(sizeof (Rt_map), 1)) == 0)
- return (0);
- if ((ELFPRV(lmp) = calloc(sizeof (Rt_elfp), 1)) == 0) {
- free(lmp);
- return (0);
+ phdr = (Phdr *)((uintptr_t)ehdr + ehdr->e_phoff);
+ for (ndx = 0; ndx < (int)ehdr->e_phnum; ndx++,
+ phdr = (Phdr *)((uintptr_t)phdr + ehdr->e_phentsize)) {
+ switch (phdr->p_type) {
+ case PT_DYNAMIC:
+ dphdr = phdr;
+ dyn = (Dyn *)((uintptr_t)phdr->p_vaddr + base);
+ break;
+ case PT_TLS:
+ tphdr = phdr;
+ break;
+ case PT_SUNWCAP:
+ cap = (Cap *)((uintptr_t)phdr->p_vaddr + base);
+ break;
+ case PT_SUNW_UNWIND:
+ uphdr = phdr;
+ break;
+ default:
+ break;
+ }
}
/*
+ * Determine the number of PT_DYNAMIC entries for the DYNINFO()
+ * allocation. Sadly, this is a little larger than we really need,
+ * as there are typically padding DT_NULL entries. However, adding
+ * this data to the initial link-map allocation is a win.
+ */
+ if (dyn) {
+ dyncnt = dphdr->p_filesz / sizeof (Dyn);
+ dynsz = dyncnt * sizeof (Dyninfo);
+ }
+
+ /*
+ * Allocate space for the link-map, private elf information, and
+ * DYNINFO() data. Once these are allocated and initialized,
+ * remove_so(0, lmp) can be used to tear down the link-map allocation
+ * should any failures occur.
+ */
+ rtsz = S_DROUND(sizeof (Rt_map));
+ epsz = S_DROUND(sizeof (Rt_elfp));
+ lmsz = rtsz + epsz + dynsz;
+ if ((lmp = calloc(lmsz, 1)) == NULL)
+ return (NULL);
+ ELFPRV(lmp) = (void *)((uintptr_t)lmp + rtsz);
+ DYNINFO(lmp) = (Dyninfo *)((uintptr_t)lmp + rtsz + epsz);
+ LMSIZE(lmp) = lmsz;
+
+ /*
* All fields not filled in were set to 0 by calloc.
*/
- ORIGNAME(lmp) = PATHNAME(lmp) = NAME(lmp) = (char *)pname;
- DYN(lmp) = ld;
+ NAME(lmp) = (char *)name;
ADDR(lmp) = addr;
MSIZE(lmp) = msize;
- ENTRY(lmp) = (Addr)entry;
SYMINTP(lmp) = elf_find_sym;
- ETEXT(lmp) = etext;
FCT(lmp) = &elf_fct;
LIST(lmp) = lml;
- PADSTART(lmp) = paddr;
- PADIMLEN(lmp) = padimsize;
- THREADID(lmp) = rt_thr_self();
OBJFLTRNDX(lmp) = FLTR_DISABLED;
SORTVAL(lmp) = -1;
-
- MMAPS(lmp) = mmaps;
- MMAPCNT(lmp) = mmapcnt;
- ASSERT(mmapcnt != 0);
+ DYN(lmp) = dyn;
+ DYNINFOCNT(lmp) = dyncnt;
+ PTUNWIND(lmp) = uphdr;
- /*
- * If this is a shared object, add the base address to each address.
- * if this is an executable, use address as is.
- */
- if (ehdr->e_type == ET_EXEC) {
- base = 0;
+ if (ehdr->e_type == ET_EXEC)
FLAGS(lmp) |= FLG_RT_FIXED;
- } else
- base = addr;
/*
* Fill in rest of the link map entries with information from the file's
* dynamic structure.
*/
- if (ld) {
+ if (dyn) {
uint_t dynndx = 0;
Xword pltpadsz = 0;
Rti_desc *rti;
/* CSTYLED */
- for ( ; ld->d_tag != DT_NULL; ++ld, dynndx++) {
- switch ((Xword)ld->d_tag) {
+ for ( ; dyn->d_tag != DT_NULL; ++dyn, dynndx++) {
+ switch ((Xword)dyn->d_tag) {
case DT_SYMTAB:
- SYMTAB(lmp) = (void *)(ld->d_un.d_ptr + base);
+ SYMTAB(lmp) = (void *)(dyn->d_un.d_ptr + base);
break;
case DT_SUNW_SYMTAB:
SUNWSYMTAB(lmp) =
- (void *)(ld->d_un.d_ptr + base);
+ (void *)(dyn->d_un.d_ptr + base);
break;
case DT_SUNW_SYMSZ:
- SUNWSYMSZ(lmp) = ld->d_un.d_val;
+ SUNWSYMSZ(lmp) = dyn->d_un.d_val;
break;
case DT_STRTAB:
- STRTAB(lmp) = (void *)(ld->d_un.d_ptr + base);
+ STRTAB(lmp) = (void *)(dyn->d_un.d_ptr + base);
break;
case DT_SYMENT:
- SYMENT(lmp) = ld->d_un.d_val;
+ SYMENT(lmp) = dyn->d_un.d_val;
break;
case DT_FEATURE_1:
- ld->d_un.d_val |= DTF_1_PARINIT;
- if (ld->d_un.d_val & DTF_1_CONFEXP)
+ dyn->d_un.d_val |= DTF_1_PARINIT;
+ if (dyn->d_un.d_val & DTF_1_CONFEXP)
crle = 1;
break;
case DT_MOVESZ:
- MOVESZ(lmp) = ld->d_un.d_val;
+ MOVESZ(lmp) = dyn->d_un.d_val;
FLAGS(lmp) |= FLG_RT_MOVE;
break;
case DT_MOVEENT:
- MOVEENT(lmp) = ld->d_un.d_val;
+ MOVEENT(lmp) = dyn->d_un.d_val;
break;
case DT_MOVETAB:
- MOVETAB(lmp) = (void *)(ld->d_un.d_ptr + base);
+ MOVETAB(lmp) = (void *)(dyn->d_un.d_ptr + base);
break;
case DT_REL:
case DT_RELA:
@@ -2223,78 +1775,78 @@
* At this time, ld.so. can only handle one
* type of relocation per object.
*/
- REL(lmp) = (void *)(ld->d_un.d_ptr + base);
+ REL(lmp) = (void *)(dyn->d_un.d_ptr + base);
break;
case DT_RELSZ:
case DT_RELASZ:
- RELSZ(lmp) = ld->d_un.d_val;
+ RELSZ(lmp) = dyn->d_un.d_val;
break;
case DT_RELENT:
case DT_RELAENT:
- RELENT(lmp) = ld->d_un.d_val;
+ RELENT(lmp) = dyn->d_un.d_val;
break;
case DT_RELCOUNT:
case DT_RELACOUNT:
- RELACOUNT(lmp) = (uint_t)ld->d_un.d_val;
- break;
- case DT_TEXTREL:
- FLAGS1(lmp) |= FL1_RT_TEXTREL;
+ RELACOUNT(lmp) = (uint_t)dyn->d_un.d_val;
break;
case DT_HASH:
- HASH(lmp) = (uint_t *)(ld->d_un.d_ptr + base);
+ HASH(lmp) = (uint_t *)(dyn->d_un.d_ptr + base);
break;
case DT_PLTGOT:
- PLTGOT(lmp) = (uint_t *)(ld->d_un.d_ptr + base);
+ PLTGOT(lmp) =
+ (uint_t *)(dyn->d_un.d_ptr + base);
break;
case DT_PLTRELSZ:
- PLTRELSZ(lmp) = ld->d_un.d_val;
+ PLTRELSZ(lmp) = dyn->d_un.d_val;
break;
case DT_JMPREL:
- JMPREL(lmp) = (void *)(ld->d_un.d_ptr + base);
+ JMPREL(lmp) = (void *)(dyn->d_un.d_ptr + base);
break;
case DT_INIT:
- if (ld->d_un.d_ptr != NULL)
+ if (dyn->d_un.d_ptr != NULL)
INIT(lmp) =
- (void (*)())(ld->d_un.d_ptr + base);
+ (void (*)())(dyn->d_un.d_ptr +
+ base);
break;
case DT_FINI:
- if (ld->d_un.d_ptr != NULL)
+ if (dyn->d_un.d_ptr != NULL)
FINI(lmp) =
- (void (*)())(ld->d_un.d_ptr + base);
+ (void (*)())(dyn->d_un.d_ptr +
+ base);
break;
case DT_INIT_ARRAY:
- INITARRAY(lmp) = (Addr *)(ld->d_un.d_ptr +
+ INITARRAY(lmp) = (Addr *)(dyn->d_un.d_ptr +
base);
break;
case DT_INIT_ARRAYSZ:
- INITARRAYSZ(lmp) = (uint_t)ld->d_un.d_val;
+ INITARRAYSZ(lmp) = (uint_t)dyn->d_un.d_val;
break;
case DT_FINI_ARRAY:
- FINIARRAY(lmp) = (Addr *)(ld->d_un.d_ptr +
+ FINIARRAY(lmp) = (Addr *)(dyn->d_un.d_ptr +
base);
break;
case DT_FINI_ARRAYSZ:
- FINIARRAYSZ(lmp) = (uint_t)ld->d_un.d_val;
+ FINIARRAYSZ(lmp) = (uint_t)dyn->d_un.d_val;
break;
case DT_PREINIT_ARRAY:
- PREINITARRAY(lmp) = (Addr *)(ld->d_un.d_ptr +
+ PREINITARRAY(lmp) = (Addr *)(dyn->d_un.d_ptr +
base);
break;
case DT_PREINIT_ARRAYSZ:
- PREINITARRAYSZ(lmp) = (uint_t)ld->d_un.d_val;
+ PREINITARRAYSZ(lmp) = (uint_t)dyn->d_un.d_val;
break;
case DT_RPATH:
case DT_RUNPATH:
- rpath = ld->d_un.d_val;
+ rpath = dyn->d_un.d_val;
break;
case DT_FILTER:
- fltr = ld->d_un.d_val;
+ fltr = dyn->d_un.d_val;
OBJFLTRNDX(lmp) = dynndx;
FLAGS1(lmp) |= FL1_RT_OBJSFLTR;
break;
case DT_AUXILIARY:
if (!(rtld_flags & RT_FL_NOAUXFLTR)) {
- fltr = ld->d_un.d_val;
+ fltr = dyn->d_un.d_val;
OBJFLTRNDX(lmp) = dynndx;
}
FLAGS1(lmp) |= FL1_RT_OBJAFLTR;
@@ -2311,10 +1863,10 @@
break;
case DT_DEPAUDIT:
if (!(rtld_flags & RT_FL_NOAUDIT))
- audit = ld->d_un.d_val;
+ audit = dyn->d_un.d_val;
break;
case DT_CONFIG:
- cfile = ld->d_un.d_val;
+ cfile = dyn->d_un.d_val;
break;
case DT_DEBUG:
/*
@@ -2332,25 +1884,26 @@
* dependencies, and we can't handle requests
* like object padding for alternative objects.
*/
- if (ld->d_un.d_ptr)
+ if (dyn->d_un.d_ptr)
rtld_flags |=
(RT_FL_DEBUGGER | RT_FL_NOOBJALT);
- ld->d_un.d_ptr = (Addr)&r_debug;
+ dyn->d_un.d_ptr = (Addr)&r_debug;
break;
case DT_VERNEED:
- VERNEED(lmp) = (Verneed *)(ld->d_un.d_ptr +
+ VERNEED(lmp) = (Verneed *)(dyn->d_un.d_ptr +
base);
break;
case DT_VERNEEDNUM:
/* LINTED */
- VERNEEDNUM(lmp) = (int)ld->d_un.d_val;
+ VERNEEDNUM(lmp) = (int)dyn->d_un.d_val;
break;
case DT_VERDEF:
- VERDEF(lmp) = (Verdef *)(ld->d_un.d_ptr + base);
+ VERDEF(lmp) = (Verdef *)(dyn->d_un.d_ptr +
+ base);
break;
case DT_VERDEFNUM:
/* LINTED */
- VERDEFNUM(lmp) = (int)ld->d_un.d_val;
+ VERDEFNUM(lmp) = (int)dyn->d_un.d_val;
break;
case DT_VERSYM:
/*
@@ -2364,21 +1917,21 @@
* If DT_VERSYM is not present, then Solaris
* versioning rules apply.
*/
- VERSYM(lmp) = (Versym *)(ld->d_un.d_ptr + base);
+ VERSYM(lmp) = (Versym *)(dyn->d_un.d_ptr +
+ base);
break;
case DT_BIND_NOW:
- if ((rtld_flags2 & RT_FL2_BINDLAZY) == 0) {
+ if ((dyn->d_un.d_val & DF_BIND_NOW) &&
+ ((rtld_flags2 & RT_FL2_BINDLAZY) == 0)) {
MODE(lmp) |= RTLD_NOW;
MODE(lmp) &= ~RTLD_LAZY;
}
break;
case DT_FLAGS:
- FLAGS2(lmp) |= FL2_RT_DTFLAGS;
- if (ld->d_un.d_val & DF_SYMBOLIC)
+ FLAGS1(lmp) |= FL1_RT_DTFLAGS;
+ if (dyn->d_un.d_val & DF_SYMBOLIC)
FLAGS1(lmp) |= FL1_RT_SYMBOLIC;
- if (ld->d_un.d_val & DF_TEXTREL)
- FLAGS1(lmp) |= FL1_RT_TEXTREL;
- if ((ld->d_un.d_val & DF_BIND_NOW) &&
+ if ((dyn->d_un.d_val & DF_BIND_NOW) &&
((rtld_flags2 & RT_FL2_BINDLAZY) == 0)) {
MODE(lmp) |= RTLD_NOW;
MODE(lmp) &= ~RTLD_LAZY;
@@ -2387,46 +1940,43 @@
* Capture any static TLS use, and enforce that
* this object be non-deletable.
*/
- if (ld->d_un.d_val & DF_STATIC_TLS) {
+ if (dyn->d_un.d_val & DF_STATIC_TLS) {
FLAGS1(lmp) |= FL1_RT_TLSSTAT;
MODE(lmp) |= RTLD_NODELETE;
}
break;
case DT_FLAGS_1:
- if (ld->d_un.d_val & DF_1_DISPRELPND)
+ if (dyn->d_un.d_val & DF_1_DISPRELPND)
FLAGS1(lmp) |= FL1_RT_DISPREL;
- if (ld->d_un.d_val & DF_1_GROUP)
+ if (dyn->d_un.d_val & DF_1_GROUP)
FLAGS(lmp) |=
(FLG_RT_SETGROUP | FLG_RT_HANDLE);
- if ((ld->d_un.d_val & DF_1_NOW) &&
+ if ((dyn->d_un.d_val & DF_1_NOW) &&
((rtld_flags2 & RT_FL2_BINDLAZY) == 0)) {
MODE(lmp) |= RTLD_NOW;
MODE(lmp) &= ~RTLD_LAZY;
}
- if (ld->d_un.d_val & DF_1_NODELETE)
+ if (dyn->d_un.d_val & DF_1_NODELETE)
MODE(lmp) |= RTLD_NODELETE;
- if (ld->d_un.d_val & DF_1_INITFIRST)
+ if (dyn->d_un.d_val & DF_1_INITFIRST)
FLAGS(lmp) |= FLG_RT_INITFRST;
- if (ld->d_un.d_val & DF_1_NOOPEN)
+ if (dyn->d_un.d_val & DF_1_NOOPEN)
FLAGS(lmp) |= FLG_RT_NOOPEN;
- if (ld->d_un.d_val & DF_1_LOADFLTR)
+ if (dyn->d_un.d_val & DF_1_LOADFLTR)
FLAGS(lmp) |= FLG_RT_LOADFLTR;
- if (ld->d_un.d_val & DF_1_NODUMP)
+ if (dyn->d_un.d_val & DF_1_NODUMP)
FLAGS(lmp) |= FLG_RT_NODUMP;
- if (ld->d_un.d_val & DF_1_CONFALT)
+ if (dyn->d_un.d_val & DF_1_CONFALT)
crle = 1;
- if (ld->d_un.d_val & DF_1_DIRECT)
+ if (dyn->d_un.d_val & DF_1_DIRECT)
FLAGS1(lmp) |= FL1_RT_DIRECT;
- if (ld->d_un.d_val & DF_1_NODEFLIB)
+ if (dyn->d_un.d_val & DF_1_NODEFLIB)
FLAGS1(lmp) |= FL1_RT_NODEFLIB;
- if (ld->d_un.d_val & DF_1_ENDFILTEE)
+ if (dyn->d_un.d_val & DF_1_ENDFILTEE)
FLAGS1(lmp) |= FL1_RT_ENDFILTE;
- if (ld->d_un.d_val & DF_1_TRANS)
+ if (dyn->d_un.d_val & DF_1_TRANS)
FLAGS(lmp) |= FLG_RT_TRANS;
-#ifndef EXPAND_RELATIVE
- if (ld->d_un.d_val & DF_1_ORIGIN)
- FLAGS1(lmp) |= FL1_RT_RELATIVE;
-#endif
+
/*
* Global auditing is only meaningful when
* specified by the initiating object of the
@@ -2436,7 +1986,7 @@
* link-map list, and consequently the link-map
* list is empty. (see setup()).
*/
- if (ld->d_un.d_val & DF_1_GLOBAUDIT) {
+ if (dyn->d_un.d_val & DF_1_GLOBAUDIT) {
if (lml_main.lm_head == 0)
FLAGS1(lmp) |= FL1_RT_GLOBAUD;
else
@@ -2450,7 +2000,7 @@
* late to guarantee complete interposition.
*/
/* BEGIN CSTYLED */
- if (ld->d_un.d_val &
+ if (dyn->d_un.d_val &
(DF_1_INTERPOSE | DF_1_SYMINTPOSE)) {
if (lml->lm_flags & LML_FLG_STARTREL) {
DBG_CALL(Dbg_util_intoolate(lmp));
@@ -2458,7 +2008,7 @@
(void) printf(
MSG_INTL(MSG_LDD_REL_ERR2),
NAME(lmp));
- } else if (ld->d_un.d_val & DF_1_INTERPOSE)
+ } else if (dyn->d_un.d_val & DF_1_INTERPOSE)
FLAGS(lmp) |= FLG_RT_OBJINTPO;
else
FLAGS(lmp) |= FLG_RT_SYMINTPO;
@@ -2466,17 +2016,17 @@
/* END CSTYLED */
break;
case DT_SYMINFO:
- SYMINFO(lmp) = (Syminfo *)(ld->d_un.d_ptr +
+ SYMINFO(lmp) = (Syminfo *)(dyn->d_un.d_ptr +
base);
break;
case DT_SYMINENT:
- SYMINENT(lmp) = ld->d_un.d_val;
+ SYMINENT(lmp) = dyn->d_un.d_val;
break;
case DT_PLTPAD:
- PLTPAD(lmp) = (void *)(ld->d_un.d_ptr + base);
+ PLTPAD(lmp) = (void *)(dyn->d_un.d_ptr + base);
break;
case DT_PLTPADSZ:
- pltpadsz = ld->d_un.d_val;
+ pltpadsz = dyn->d_un.d_val;
break;
case DT_SUNW_RTLDINF:
/*
@@ -2489,22 +2039,24 @@
* structure may provide atexit reservations.
*/
if ((rti = alist_append(&lml->lm_rti, 0,
- sizeof (Rti_desc), AL_CNT_RTLDINFO)) == 0) {
+ sizeof (Rti_desc),
+ AL_CNT_RTLDINFO)) == NULL) {
remove_so(0, lmp);
- return (0);
+ return (NULL);
}
rti->rti_lmp = lmp;
- rti->rti_info = (void *)(ld->d_un.d_ptr + base);
+ rti->rti_info = (void *)(dyn->d_un.d_ptr +
+ base);
break;
case DT_SUNW_SORTENT:
- SUNWSORTENT(lmp) = ld->d_un.d_val;
+ SUNWSORTENT(lmp) = dyn->d_un.d_val;
break;
case DT_SUNW_SYMSORT:
SUNWSYMSORT(lmp) =
- (void *)(ld->d_un.d_ptr + base);
+ (void *)(dyn->d_un.d_ptr + base);
break;
case DT_SUNW_SYMSORTSZ:
- SUNWSYMSORTSZ(lmp) = ld->d_un.d_val;
+ SUNWSYMSORTSZ(lmp) = dyn->d_un.d_val;
break;
case DT_DEPRECATED_SPARC_REGISTER:
case M_DT_REGISTER:
@@ -2520,16 +2072,6 @@
PLTPADEND(lmp) = (void *)((Addr)PLTPAD(lmp) +
pltpadsz);
}
-
- /*
- * Allocate a Dynamic Info structure.
- */
- if ((DYNINFO(lmp) = calloc((size_t)dynndx,
- sizeof (Dyninfo))) == 0) {
- remove_so(0, lmp);
- return (0);
- }
- DYNINFOCNT(lmp) = dynndx;
}
/*
@@ -2574,31 +2116,14 @@
if (cfile)
config->c_name = (const char *)(cfile +
(char *)STRTAB(lmp));
- else if (crle) {
+ else if (crle)
rtld_flags |= RT_FL_CONFAPP;
-#ifndef EXPAND_RELATIVE
- FLAGS1(lmp) |= FL1_RT_RELATIVE;
-#endif
- }
}
if (rpath)
RPATH(lmp) = (char *)(rpath + (char *)STRTAB(lmp));
- if (fltr) {
- /*
- * If this object is a global filter, duplicate the filtee
- * string name(s) so that REFNAME() is available in core files.
- * This cludge was useful for debuggers at one point, but only
- * when the filtee name was an individual full path.
- */
- if ((REFNAME(lmp) = strdup(fltr + (char *)STRTAB(lmp))) == 0) {
- remove_so(0, lmp);
- return (0);
- }
- }
-
- if (rtld_flags & RT_FL_RELATIVE)
- FLAGS1(lmp) |= FL1_RT_RELATIVE;
+ if (fltr)
+ REFNAME(lmp) = (char *)(fltr + (char *)STRTAB(lmp));
/*
* For Intel ABI compatibility. It's possible that a JMPREL can be
@@ -2610,7 +2135,7 @@
* details.
*/
if (!RELENT(lmp) && JMPREL(lmp))
- RELENT(lmp) = sizeof (Rel);
+ RELENT(lmp) = sizeof (M_RELOC);
/*
* Establish any per-object auditing. If we're establishing `main's
@@ -2622,36 +2147,44 @@
if (*cp) {
if (((AUDITORS(lmp) =
- calloc(1, sizeof (Audit_desc))) == 0) ||
- ((AUDITORS(lmp)->ad_name = strdup(cp)) == 0)) {
+ calloc(1, sizeof (Audit_desc))) == NULL) ||
+ ((AUDITORS(lmp)->ad_name = strdup(cp)) == NULL)) {
remove_so(0, lmp);
- return (0);
+ return (NULL);
}
if (lml_main.lm_head) {
if (audit_setup(lmp, AUDITORS(lmp), 0,
in_nfavl) == 0) {
remove_so(0, lmp);
- return (0);
+ return (NULL);
}
- FLAGS1(lmp) |= AUDITORS(lmp)->ad_flags;
+ AFLAGS(lmp) |= AUDITORS(lmp)->ad_flags;
lml->lm_flags |= LML_FLG_LOCAUDIT;
}
}
}
- if ((CONDVAR(lmp) = rt_cond_create()) == 0) {
+ if (tphdr && (tls_assign(lml, lmp, tphdr) == 0)) {
remove_so(0, lmp);
- return (0);
+ return (NULL);
}
- if (oname && ((append_alias(lmp, oname, 0)) == 0)) {
- remove_so(0, lmp);
- return (0);
- }
+
+ if (cap)
+ cap_assign(cap, lmp);
/*
* Add the mapped object to the end of the link map list.
*/
lm_append(lml, lmco, lmp);
+
+ /*
+ * Start the system loading in the ELF information we'll be processing.
+ */
+ if (REL(lmp)) {
+ (void) madvise((void *)ADDR(lmp), (uintptr_t)REL(lmp) +
+ (uintptr_t)RELSZ(lmp) - (uintptr_t)ADDR(lmp),
+ MADV_WILLNEED);
+ }
return (lmp);
}
@@ -2674,353 +2207,16 @@
}
/*
- * Map in an ELF object.
- * Takes an open file descriptor for the object to map and its pathname; returns
- * a pointer to a Rt_map structure for this object, or 0 on error.
- */
-static Rt_map *
-elf_map_so(Lm_list *lml, Aliste lmco, const char *pname, const char *oname,
- int fd, int *in_nfavl)
-{
- int i; /* general temporary */
- Off memsize = 0; /* total memory size of pathname */
- Off mentry; /* entry point */
- Ehdr *ehdr; /* ELF header of ld.so */
- Phdr *phdr; /* first Phdr in file */
- Phdr *phdr0; /* Saved first Phdr in file */
- Phdr *pptr; /* working Phdr */
- Phdr *fph = 0; /* first loadable Phdr */
- Phdr *lph; /* last loadable Phdr */
- Phdr *lfph = 0; /* last loadable (filesz != 0) Phdr */
- Phdr *lmph = 0; /* last loadable (memsz != 0) Phdr */
- Phdr *tlph = 0; /* program header for PT_TLS */
- Phdr *unwindph = 0; /* program header for PT_SUNW_UNWIND */
- Cap *cap = 0; /* program header for SUNWCAP */
- Dyn *mld = 0; /* DYNAMIC structure for pathname */
- size_t size; /* size of elf and program headers */
- caddr_t faddr = 0; /* mapping address of pathname */
- Rt_map *lmp; /* link map created */
- caddr_t paddr; /* start of padded image */
- Off plen; /* size of image including padding */
- Half etype;
- int fixed;
- Mmap *mmaps;
- uint_t mmapcnt = 0;
- Xword align = 0;
-
- /* LINTED */
- ehdr = (Ehdr *)fmap->fm_maddr;
-
- /*
- * If this a relocatable object then special processing is required.
- */
- if ((etype = ehdr->e_type) == ET_REL)
- return (elf_obj_file(lml, lmco, pname, fd));
-
- /*
- * If this isn't a dynamic executable or shared object we can't process
- * it. If this is a dynamic executable then all addresses are fixed.
- */
- if (etype == ET_EXEC) {
- fixed = 1;
- } else if (etype == ET_DYN) {
- fixed = 0;
- } else {
- Conv_inv_buf_t inv_buf;
-
- eprintf(lml, ERR_ELF, MSG_INTL(MSG_GEN_BADTYPE), pname,
- conv_ehdr_type(etype, 0, &inv_buf));
- return (0);
- }
-
- /*
- * If our original mapped page was not large enough to hold all the
- * program headers remap them.
- */
- size = (size_t)((char *)ehdr->e_phoff +
- (ehdr->e_phnum * ehdr->e_phentsize));
- if (size > fmap->fm_fsize) {
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_GEN_CORTRUNC), pname);
- return (0);
- }
- if (size > fmap->fm_msize) {
- fmap_setup();
- if ((fmap->fm_maddr = mmap(fmap->fm_maddr, size, PROT_READ,
- fmap->fm_mflags, fd, 0)) == MAP_FAILED) {
- int err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), pname,
- strerror(err));
- return (0);
- }
- fmap->fm_msize = size;
- /* LINTED */
- ehdr = (Ehdr *)fmap->fm_maddr;
- }
- /* LINTED */
- phdr0 = phdr = (Phdr *)((char *)ehdr + ehdr->e_ehsize);
-
- /*
- * Get entry point.
- */
- mentry = ehdr->e_entry;
-
- /*
- * Point at program headers and perform some basic validation.
- */
- for (i = 0, pptr = phdr; i < (int)ehdr->e_phnum; i++,
- pptr = (Phdr *)((Off)pptr + ehdr->e_phentsize)) {
- if (pptr->p_type == PT_LOAD) {
-
- if (fph == 0) {
- fph = pptr;
- /* LINTED argument lph is initialized in first pass */
- } else if (pptr->p_vaddr <= lph->p_vaddr) {
- eprintf(lml, ERR_ELF,
- MSG_INTL(MSG_GEN_INVPRGHDR), pname);
- return (0);
- }
-
- lph = pptr;
-
- if (pptr->p_memsz)
- lmph = pptr;
- if (pptr->p_filesz)
- lfph = pptr;
- if (pptr->p_align > align)
- align = pptr->p_align;
-
- } else if (pptr->p_type == PT_DYNAMIC) {
- mld = (Dyn *)(pptr->p_vaddr);
- } else if ((pptr->p_type == PT_TLS) && pptr->p_memsz) {
- tlph = pptr;
- } else if (pptr->p_type == PT_SUNWCAP) {
- cap = (Cap *)(pptr->p_vaddr);
- } else if (pptr->p_type == PT_SUNW_UNWIND) {
- unwindph = pptr;
- }
- }
-
-#if defined(MAP_ALIGN)
- /*
- * Make sure the maximum page alignment is a power of 2 >= the default
- * segment alignment, for use with MAP_ALIGN.
- */
- align = S_ROUND(align, M_SEGM_ALIGN);
-#endif
-
- /*
- * We'd better have at least one loadable segment, together with some
- * specified file and memory size.
- */
- if ((fph == 0) || (lmph == 0) || (lfph == 0)) {
- eprintf(lml, ERR_ELF, MSG_INTL(MSG_GEN_NOLOADSEG), pname);
- return (0);
- }
-
- /*
- * Check that the files size accounts for the loadable sections
- * we're going to map in (failure to do this may cause spurious
- * bus errors if we're given a truncated file).
- */
- if (fmap->fm_fsize < ((size_t)lfph->p_offset + lfph->p_filesz)) {
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_GEN_CORTRUNC), pname);
- return (0);
- }
-
- /*
- * Memsize must be page rounded so that if we add object padding
- * at the end it will start at the beginning of a page.
- */
- plen = memsize = M_PROUND((lmph->p_vaddr + lmph->p_memsz) -
- M_PTRUNC((ulong_t)fph->p_vaddr));
-
- /*
- * Determine if an existing mapping is acceptable.
- */
- if (interp && (lml->lm_flags & LML_FLG_BASELM) &&
- (strcmp(pname, interp->i_name) == 0)) {
- /*
- * If this is the interpreter then it has already been mapped
- * and we have the address so don't map it again. Note that
- * the common occurrence of a reference to the interpretor
- * (libdl -> ld.so.1) will have been caught during filter
- * initialization (see elf_lookup_filtee()). However, some
- * ELF implementations are known to record libc.so.1 as the
- * interpretor, and thus this test catches this behavior.
- */
- paddr = faddr = interp->i_faddr;
-
- } else if ((fixed == 0) && (r_debug.rtd_objpad == 0) &&
- (memsize <= fmap->fm_msize) && ((fph->p_flags & PF_W) == 0) &&
- (fph == lph) && (fph->p_filesz == fph->p_memsz) &&
- (((Xword)fmap->fm_maddr % align) == 0)) {
- size_t rsize;
-
- /*
- * If the file contains a single segment, and the mapping
- * required has already been established from the initial fmap
- * mapping, then we don't need to do anything more. Reset the
- * fmap address so that any later files start a new fmap. This
- * is really an optimization for filters, such as libdl.so,
- * libthread, etc. that are constructed to be a single text
- * segment.
- */
- paddr = faddr = fmap->fm_maddr;
-
- /*
- * Free any unused mapping by assigning the fmap buffer to the
- * unused region. fmap_setup() will unmap this area and
- * establish defaults for future mappings.
- */
- rsize = M_PROUND(fph->p_filesz);
- fmap->fm_maddr += rsize;
- fmap->fm_msize -= rsize;
- fmap_setup();
- }
-
- /*
- * Allocate a mapping array to retain mapped segment information.
- */
- if ((mmaps = calloc(ehdr->e_phnum, sizeof (Mmap))) == 0)
- return (0);
-
- /*
- * If we're reusing an existing mapping determine the objects etext
- * address. Otherwise map the file (which will calculate the etext
- * address as part of the mapping process).
- */
- if (faddr) {
- caddr_t base;
-
- if (fixed)
- base = 0;
- else
- base = faddr;
-
- /* LINTED */
- phdr0 = phdr = (Phdr *)((char *)faddr + ehdr->e_ehsize);
-
- for (i = 0, pptr = phdr; i < (int)ehdr->e_phnum; i++,
- pptr = (Phdr *)((Off)pptr + ehdr->e_phentsize)) {
- if (pptr->p_type != PT_LOAD)
- continue;
-
- mmaps[mmapcnt].m_vaddr = (pptr->p_vaddr + base);
- mmaps[mmapcnt].m_msize = pptr->p_memsz;
- mmaps[mmapcnt].m_fsize = pptr->p_filesz;
- mmaps[mmapcnt].m_perm = (PROT_READ | PROT_EXEC);
- mmapcnt++;
-
- if (!(pptr->p_flags & PF_W)) {
- fmap->fm_etext = (ulong_t)pptr->p_vaddr +
- (ulong_t)pptr->p_memsz +
- (ulong_t)(fixed ? 0 : faddr);
- }
- }
- } else {
- /*
- * Map the file.
- */
- if (!(faddr = elf_map_it(lml, pname, memsize, ehdr, fph, lph,
- &phdr, &paddr, &plen, fixed, fd, align, mmaps, &mmapcnt)))
- return (0);
- }
-
- /*
- * Calculate absolute base addresses and entry points.
- */
- if (!fixed) {
- if (mld)
- /* LINTED */
- mld = (Dyn *)((Off)mld + faddr);
- if (cap)
- /* LINTED */
- cap = (Cap *)((Off)cap + faddr);
- mentry += (Off)faddr;
- }
-
- /*
- * Create new link map structure for newly mapped shared object.
- */
- if (!(lmp = elf_new_lm(lml, pname, oname, mld, (ulong_t)faddr,
- fmap->fm_etext, lmco, memsize, mentry, (ulong_t)paddr, plen, mmaps,
- mmapcnt, in_nfavl))) {
- (void) munmap((caddr_t)faddr, memsize);
- return (0);
- }
-
- /*
- * Start the system loading in the ELF information we'll be processing.
- */
- if (REL(lmp)) {
- (void) madvise((void *)ADDR(lmp), (uintptr_t)REL(lmp) +
- (uintptr_t)RELSZ(lmp) - (uintptr_t)ADDR(lmp),
- MADV_WILLNEED);
- }
-
- /*
- * If this shared object contains any special segments, record them.
- */
- if (tlph && (tls_assign(lml, lmp, (phdr + (tlph - phdr0))) == 0)) {
- remove_so(lml, lmp);
- return (0);
- }
-
- if (unwindph)
- PTUNWIND(lmp) = phdr + (unwindph - phdr0);
-
- if (cap)
- cap_assign(cap, lmp);
-
- return (lmp);
-}
-
-/*
- * Function to correct protection settings. Segments are all mapped initially
- * with permissions as given in the segment header. We need to turn on write
- * permissions on a text segment if there are any relocations against that
- * segment, and them turn write permission back off again before returning
- * control to the user. This function turns the permission on or off depending
- * on the value of the argument.
- */
-int
-elf_set_prot(Rt_map *lmp, int permission)
-{
- Mmap *mmaps;
-
- /*
- * If this is an allocated image (ie. a relocatable object) we can't
- * mprotect() anything.
- */
- if (FLAGS(lmp) & FLG_RT_IMGALLOC)
- return (1);
-
- DBG_CALL(Dbg_file_prot(lmp, permission));
-
- for (mmaps = MMAPS(lmp); mmaps->m_vaddr; mmaps++) {
- if (mmaps->m_perm & PROT_WRITE)
- continue;
-
- if (mprotect(mmaps->m_vaddr, mmaps->m_msize,
- (mmaps->m_perm | permission)) == -1) {
- int err = errno;
- eprintf(LIST(lmp), ERR_FATAL, MSG_INTL(MSG_SYS_MPROT),
- NAME(lmp), strerror(err));
- return (0);
- }
- }
- return (1);
-}
-
-/*
* Build full pathname of shared object from given directory name and filename.
*/
static char *
-elf_get_so(const char *dir, const char *file)
+elf_get_so(const char *dir, const char *file, size_t dlen, size_t flen)
{
static char pname[PATH_MAX];
- (void) snprintf(pname, PATH_MAX, MSG_ORIG(MSG_FMT_PATH), dir, file);
+ (void) strncpy(pname, dir, dlen);
+ pname[dlen++] = '/';
+ (void) strncpy(&pname[dlen], file, flen + 1);
return (pname);
}
@@ -3057,7 +2253,7 @@
rc.r_size = (size_t)rsym->st_size;
if (alist_append(©_R(dlmp), &rc, sizeof (Rel_copy),
- AL_CNT_COPYREL) == 0) {
+ AL_CNT_COPYREL) == NULL) {
if (!(lml->lm_flags & LML_FLG_TRC_WARN))
return (0);
else
@@ -3435,9 +2631,9 @@
*/
if ((sl.sl_flags & LKUP_NODESCENT) == 0) {
if (aplist_append(&alist, nlmp,
- AL_CNT_LAZYFIND) == 0) {
+ AL_CNT_LAZYFIND) == NULL) {
elf_lazy_cleanup(alist);
- return (0);
+ return (NULL);
}
FLAGS(nlmp) |= FLG_RT_TMPLIST;
}
@@ -3480,7 +2676,7 @@
}
if (name == 0)
- name = MSG_ORIG(MSG_STR_EMPTY);
+ name = MSG_INTL(MSG_STR_UNKNOWN);
if (trace) {
const char *rstr;
@@ -3595,3 +2791,94 @@
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/external.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/external.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Implementation of all external interfaces between ld.so.1 and libc.
*
@@ -357,11 +355,8 @@
}
/*
- * Indicate that we're now thread capable, and enable concurrency if
- * requested.
+ * Indicate that we're now thread capable.
*/
- if ((rtld_flags & RT_FL_NOCONCUR) == 0)
- rtld_flags |= RT_FL_CONCUR;
if ((lml->lm_flags & LML_FLG_RTLDLM) == 0)
rtld_flags |= RT_FL_THREADS;
}
@@ -447,7 +442,7 @@
if ((fptr = (void (*)())lml->lm_lcs[CI_THRINIT].lc_un.lc_func) != 0) {
lml->lm_lcs[CI_THRINIT].lc_un.lc_func = 0;
- leave((Lm_list *)0, thr_flg_reenter);
+ leave(NULL, thr_flg_reenter);
(*fptr)();
(void) enter(thr_flg_reenter);
}
@@ -476,26 +471,6 @@
return (_lwp_mutex_unlock((lwp_mutex_t *)mp));
}
-Rt_cond *
-rt_cond_create()
-{
- return (calloc(1, sizeof (Rt_cond)));
-}
-
-int
-rt_cond_wait(Rt_cond * cvp, Rt_lock * mp)
-{
- return (_lwp_cond_wait(cvp, (lwp_mutex_t *)mp));
-}
-
-int
-rt_cond_broadcast(Rt_cond * cvp)
-{
- return (_lwp_cond_broadcast(cvp));
-}
-
-#ifdef EXPAND_RELATIVE
-
/*
* Mutex interfaces to resolve references from any objects extracted from
* libc_pic.a. Note, as ld.so.1 is essentially single threaded these can be
@@ -612,5 +587,3 @@
extern ssize_t __write(int, const void *, size_t);
return (__write(fd, buf, size));
}
-
-#endif /* EXPAND_RELATIVE */
--- a/usr/src/cmd/sgs/rtld/common/getcwd.c Wed Jan 21 09:18:26 2009 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,295 +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 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <strings.h>
-#include "_rtld.h"
-#include "msg.h"
-
-
-#ifndef EXPAND_RELATIVE
-
-static rtld_stat_t status;
-
-/*
- * Included here (instead of using libc's) to reduce the number of stat calls.
- */
-static DIR *
-_opendir(const char *file)
-{
- DIR *dirp;
- int fd;
-
- if ((fd = open(file, (O_RDONLY | O_NDELAY), 0)) < 0)
- return (0);
-
- if ((rtld_fstat(fd, &status) < 0) ||
- ((status.st_mode & S_IFMT) != S_IFDIR) ||
- ((dirp = (DIR *)malloc(sizeof (DIR) + DIRBUF)) == NULL)) {
- (void) close(fd);
- return (0);
- }
-
- dirp->dd_buf = (char *)dirp + sizeof (DIR);
- dirp->dd_fd = fd;
- dirp->dd_loc = dirp->dd_size = 0;
-
- return (dirp);
-}
-
-static struct dirent *
-_readdir(DIR *dirp)
-{
- struct dirent *denp;
- int saveloc = 0;
-
- if (dirp->dd_size != 0) {
- /* LINTED */
- denp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc];
- saveloc = dirp->dd_loc;
- dirp->dd_loc += denp->d_reclen;
- }
- if (dirp->dd_loc >= dirp->dd_size)
- dirp->dd_loc = dirp->dd_size = 0;
-
- if ((dirp->dd_size == 0) &&
- ((dirp->dd_size = getdents(dirp->dd_fd,
- /* LINTED */
- (struct dirent *)dirp->dd_buf, DIRBUF)) <= 0)) {
- if (dirp->dd_size == 0)
- dirp->dd_loc = saveloc;
- return (0);
- }
-
- /* LINTED */
- denp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc];
-
- return (denp);
-}
-
-static int
-_closedir(DIR * dirp)
-{
- int fd = dirp->dd_fd;
-
- free((char *)dirp);
- return (close(fd));
-}
-
-/*
- * Simplified getcwd(3C), stolen from raf's proc(1) pwdx.
- */
-char *
-getcwd(char *path, size_t pathsz)
-{
- char _path[PATH_MAX], cwd[PATH_MAX];
- size_t cwdsz;
- rtld_ino_t cino;
- dev_t cdev;
-
- _path[--pathsz] = '\0';
-
- /*
- * Stat the present working directory to establish the initial device
- * and inode pair.
- */
- (void) strcpy(cwd, MSG_ORIG(MSG_FMT_CWD));
- cwdsz = MSG_FMT_CWD_SIZE;
-
- if (rtld_stat(cwd, &status) == -1)
- return (NULL);
-
- /* LINTED */
- while (1) {
- DIR *dirp;
- struct dirent *denp;
- size_t len;
-
- cino = status.st_ino;
- cdev = status.st_dev;
-
- /*
- * Open parent directory
- */
- (void) strcpy(&cwd[cwdsz], MSG_ORIG(MSG_FMT_PARENT));
- cwdsz += MSG_FMT_PARENT_SIZE;
-
- if ((dirp = _opendir(cwd)) == 0)
- return (NULL);
-
- /*
- * Find subdirectory of parent that matches current directory.
- */
- if (cdev == status.st_dev) {
- if (cino == status.st_ino) {
- /*
- * At root, return the pathname we've
- * established.
- */
- (void) _closedir(dirp);
- (void) strcpy(path, &_path[pathsz]);
- return (path);
- }
-
- do {
- if ((denp = _readdir(dirp)) == NULL) {
- (void) _closedir(dirp);
- return (NULL);
- }
- } while (denp->d_ino != cino);
-
- } else {
- /*
- * The parent director is a different filesystem, so
- * determine filenames of subdirectories and stat.
- */
- rtld_stat_t _status;
-
- cwd[cwdsz] = '/';
-
- /* LINTED */
- while (1) {
- if ((denp = _readdir(dirp)) == NULL) {
- (void) _closedir(dirp);
- return (NULL);
- }
- if (denp->d_name[0] == '.') {
- if (denp->d_name[1] == '\0')
- continue;
- if (denp->d_name[1] == '.' &&
- denp->d_name[2] == '\0')
- continue;
- }
- (void) strcpy(&cwd[cwdsz + 1], denp->d_name);
-
- /*
- * Silently ignore non-stat'able entries.
- */
- if (rtld_stat(cwd, &_status) == -1)
- continue;
-
- if ((_status.st_ino == cino) &&
- (_status.st_dev == cdev))
- break;
- }
- }
-
- /*
- * Copy name of current directory into pathname.
- */
- if ((len = strlen(denp->d_name)) < pathsz) {
- pathsz -= len;
- (void) strncpy(&_path[pathsz], denp->d_name, len);
- _path[--pathsz] = '/';
- }
- (void) _closedir(dirp);
- }
-
- return (NULL);
-}
-
-#endif
-
-/*
- * Take the given link-map file/pathname and prepend the current working
- * directory.
- *
- * When $ORIGIN was first introduced, the expansion of a relative pathname was
- * deferred until it was required. However now we insure a full pathname is
- * always created - things like the analyzer wish to rely on librtld_db
- * returning a full path. The overhead of this is perceived to be low,
- * providing the associated libc version of getcwd is available (see 4336878).
- * This getcwd() was ported back to Solaris 8.1.
- */
-size_t
-fullpath(Rt_map *lmp, const char *rpath)
-{
- char *name, _path[PATH_MAX];
-
- /*
- * If a resolved path isn't provided, establish one from the PATHNAME().
- */
- if (rpath)
- PATHNAME(lmp) = (char *)rpath;
- else {
- char *path;
-
- name = path = (char *)PATHNAME(lmp);
-
- if (path[0] != '/') {
- /*
- * If we can't determine the current directory (possible
- * if too many files are open - EMFILE), or if the
- * created path is too big, simply revert back to the
- * initial pathname.
- */
- if (getcwd(_path, (PATH_MAX - 2 - strlen(name))) !=
- NULL) {
- (void) strcat(_path, MSG_ORIG(MSG_STR_SLASH));
- (void) strcat(_path, name);
- path = _path;
- }
- }
-
- /*
- * See if the pathname can be reduced further.
- */
- if (rtld_flags & RT_FL_EXECNAME) {
- int size = PATH_MAX - 1;
-
- if ((size = resolvepath(path, _path, size)) > 0) {
- _path[size] = '\0';
- path = _path;
- }
- }
-
- /*
- * If the pathname is different from the original, duplicate it
- * so that it is available in a core file. If the duplication
- * fails simply leave the original pathname alone.
- */
- if ((name != path) && strcmp(name, path)) {
- if ((PATHNAME(lmp) = strdup(path)) == 0)
- PATHNAME(lmp) = name;
- }
- }
-
- name = ORIGNAME(lmp) = PATHNAME(lmp);
-
- /*
- * Establish the directory name size - this also acts as a flag that the
- * directory name has been computed.
- */
- DIRSZ(lmp) = strrchr(name, '/') - name;
-
- return (DIRSZ(lmp));
-}
--- a/usr/src/cmd/sgs/rtld/common/globals.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/globals.c Wed Jan 21 11:00:19 2009 -0800
@@ -23,8 +23,7 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -82,18 +81,12 @@
* END: Exposed to rtld_db
*/
-Reglist * reglist = 0; /* list of register symbols */
+Reglist *reglist = NULL; /* list of register symbols */
ulong_t hwcap = 0; /* hardware capabilities */
ulong_t sfcap = 0; /* software capabilities */
/*
- * Initialized fmap structure.
- */
-static Fmap _fmap = { 0, 0, 0, 0, 0 };
-Fmap * fmap = &_fmap; /* initial file mapping info */
-
-/*
* Set of integers to track how many of what type of PLT's have been bound.
* This is only really interesting for SPARC since ia32 has only one PLT.
*/
@@ -110,59 +103,49 @@
avl_tree_t *nfavl = NULL;
/*
- * Enable technology (via status flags for RTLD) dependent upon whether we're
- * in a patch or major release build environment.
- */
-uint_t rtld_flags =
-#ifdef EXPAND_RELATIVE
- RT_FL_RELATIVE |
-#endif
-#ifdef SIEBEL_DISABLE
- RT_FL_DISFIX_1 |
-#endif
- RT_FL_NOCONCUR;
-uint_t rtld_flags2 = 0;
-
-/*
* Various other global data.
*/
+uint_t rtld_flags = 0;
+uint_t rtld_flags2 = 0;
+
Lc_desc glcs[CI_MAX]; /* global external interfaces */
-const char *procname = (const char *)0;
+const char *procname = NULL;
const char *rtldname = MSG_ORIG(MSG_FIL_RTLD);
-char *lasterr = (char *)0; /* string describing last error */
+char *lasterr = NULL; /* string describing last error */
/* cleared by each dlerror() */
-Interp *interp = 0; /* ELF interpreter info */
-List hdl_list[HDLIST_SZ+2]; /* dlopen() handle list */
+Interp *interp = NULL; /* ELF interpreter info */
+APlist *hdl_alp[HDLIST_SZ+2]; /* dlopen() handle list */
size_t syspagsz = 0; /* system page size */
-unsigned long at_flags = 0; /* machine specific file flags */
-char *platform = 0; /* platform name from AT_SUN_PLATFORM */
+ulong_t at_flags = 0; /* machine specific file flags */
+char *platform = NULL; /* platform name from AT_SUN_PLATFORM */
size_t platform_sz = 0; /* platform string length */
-Uts_desc *uts; /* utsname descriptor */
-Isa_desc *isa; /* isalist descriptor */
+Uts_desc *uts = NULL; /* utsname descriptor */
+Isa_desc *isa = NULL; /* isalist descriptor */
uint_t audit_argcnt = 64; /* no. of stack args to copy (default */
/* is all) */
-Audit_desc *auditors = 0; /* global auditors (LD_AUDIT) */
+Audit_desc *auditors = NULL; /* global auditors (LD_AUDIT) */
-const char *rpl_audit = 0; /* replaceable LD_AUDIT string */
-const char *rpl_debug = 0; /* replaceable LD_DEBUG string */
-const char *rpl_ldflags = 0; /* replaceable LD_FLAGS string */
-const char *rpl_libpath = 0; /* replaceable LD_LIBRARY_PATH string */
-Pnode *rpl_libdirs = 0; /* and associated Pnode list */
-const char *rpl_preload = 0; /* replaceable LD_PRELOAD string */
+const char *rpl_audit = NULL; /* replaceable LD_AUDIT string */
+const char *rpl_debug = NULL; /* replaceable LD_DEBUG string */
+const char *rpl_ldflags = NULL; /* replaceable LD_FLAGS string */
+const char *rpl_libpath = NULL; /* replaceable LD_LIBRARY_PATH string */
+Alist *rpl_libdirs = NULL; /* and associated Pdesc list */
+const char *rpl_preload = NULL; /* replaceable LD_PRELOAD string */
-const char *prm_audit = 0; /* permanent LD_AUDIT string */
-const char *prm_debug = 0; /* permanent LD_DEBUG string */
-const char *prm_ldflags = 0; /* permanent LD_FLAGS string */
-const char *prm_libpath = 0; /* permanent LD_LIBRARY_PATH string */
-Pnode *prm_libdirs = 0; /* and associated Pnode list */
-const char *prm_preload = 0; /* permanent LD_PRELOAD string */
+const char *prm_audit = NULL; /* permanent LD_AUDIT string */
+const char *prm_debug = NULL; /* permanent LD_DEBUG string */
+const char *prm_ldflags = NULL; /* permanent LD_FLAGS string */
+const char *prm_libpath = NULL; /* permanent LD_LIBRARY_PATH string */
+Alist *prm_libdirs = NULL; /* and associated Pdesc list */
+const char *prm_preload = NULL; /* permanent LD_PRELOAD string */
uint_t env_info = 0; /* information regarding environment */
/* variables */
int killsig = SIGKILL; /* signal sent on fatal exit */
+APlist *free_alp = NULL; /* defragmentation list */
/*
* Note, the debugging descriptor interposes on the default definition provided
@@ -171,17 +154,17 @@
*/
static Dbg_desc _dbg_desc = {0, 0, 0};
Dbg_desc *dbg_desc = &_dbg_desc; /* debugging descriptor */
-const char *dbg_file = 0; /* debugging directed to file */
+const char *dbg_file = NULL; /* debugging directed to file */
#pragma weak environ = _environ /* environ for PLT tracing - we */
-char **_environ = 0; /* supply the pair to satisfy any */
+char **_environ = NULL; /* supply the pair to satisfy any */
/* libc requirements (hwmuldiv) */
-const char *profile_name; /* object being profiled */
-const char *profile_out; /* profile output file */
-const char *profile_lib; /* audit library to perform profile */
+const char *profile_name = NULL; /* object being profiled */
+const char *profile_out = NULL; /* profile output file */
+const char *profile_lib = NULL; /* audit library to perform profile */
-unsigned char search_rules[] = { /* dependency search rules */
+uchar_t search_rules[] = { /* dependency search rules */
RPLENV, /* replaceable LD_LIBRARY_PATH */
PRMENV, /* permanent LD_LIBRARY_PATH */
RUNPATH, /* callers runpath */
@@ -197,7 +180,7 @@
* also provide for resetting should the locale change (see _ld_libc()).
*/
const char *err_strs[ERR_NUM] = { 0 };
-const char *nosym_str = 0;
+const char *nosym_str = NULL;
/*
@@ -221,7 +204,6 @@
MSG_LDD_REJ_SFCAP_1, /* MSG_INTL(MSG_LDD_REJ_SFCAP_1) */
};
-
const Msg
err_reject[] = {
MSG_STR_EMPTY,
--- a/usr/src/cmd/sgs/rtld/common/locale.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/locale.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -228,7 +228,7 @@
* Determine if we've initialized any domains yet.
*/
if (domaincnt == 0) {
- if ((domains = (Domain *)calloc(sizeof (Domain), 2)) == 0)
+ if ((domains = calloc(sizeof (Domain), 2)) == NULL)
return ((char *)msgid);
domains[0].dom_name = MSG_ORIG(MSG_SUNW_OST_SGS);
domains[1].dom_name = MSG_ORIG(MSG_SUNW_OST_OSLIB);
--- a/usr/src/cmd/sgs/rtld/common/malloc.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/malloc.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,8 +29,6 @@
* All Rights Reserved
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Simplified version of malloc(), calloc() and free(), to be linked with
* utilities that use [s]brk() and do not define their own version of the
@@ -69,7 +67,6 @@
#define HDR_BLOCK (sizeof (struct block) - sizeof (void *))
#define HDR_PAGE (sizeof (struct page) - sizeof (void *))
-#define MINSZ 8
static struct page *memstart;
@@ -102,40 +99,35 @@
/*
* Defragmentation
*/
-static void
-defrag(struct page *page)
+void
+defrag()
{
- struct block *block;
+ struct page *page;
+ Aliste idx;
- for (block = page->block; block; block = block->next) {
- struct block *block2;
+ for (APLIST_TRAVERSE(free_alp, idx, page)) {
+ struct block *block;
- if (block->status == BUSY)
- continue;
- for (block2 = block->next; block2 && block2->status == FREE;
- block2 = block2->next) {
- block->next = block2->next;
- block->size += block2->size + HDR_BLOCK;
- }
- }
+ for (block = page->block; block; block = block->next) {
+ struct block *block2;
- /*
- * Free page
- */
- if (page->block->size == page->size - HDR_PAGE) {
- if (page == memstart)
- memstart = page->next;
- else {
- struct page *page2;
- for (page2 = memstart; page2->next;
- page2 = page2->next) {
- if (page2->next == page) {
- page2->next = page->next;
- break;
- }
+ if (block->status == BUSY)
+ continue;
+ for (block2 = block->next; block2 &&
+ block2->status == FREE; block2 = block2->next) {
+ block->next = block2->next;
+ block->size += block2->size + HDR_BLOCK;
}
}
- (void) munmap((caddr_t)page, (size_t)page->size);
+
+ /*
+ * If a page becomes free, leave it, and save the unmapping
+ * expense, as we'll probably come back and reclaim the page
+ * for later malloc activity.
+ *
+ * Free the defrag index.
+ */
+ aplist_delete(free_alp, &idx);
}
}
@@ -156,18 +148,7 @@
}
}
-
-/*
- * Align size on an appropriate boundary
- */
-static size_t
-align(size_t size, size_t bound)
-{
- if (size < bound)
- return (bound);
- else
- return (size + bound - 1 - (size + bound - 1) % bound);
-}
+#include <stdio.h>
/*
* Replace both malloc() and lmalloc() (libc's private memory allocator).
@@ -180,7 +161,7 @@
struct block *block;
struct page *page;
- size = align(size, MINSZ);
+ size = S_DROUND(size);
/*
* Try to locate necessary space
@@ -192,18 +173,16 @@
}
}
found:
-
/*
* Need to allocate a new page
*/
if (!page) {
- size_t totsize = size + HDR_PAGE;
- size_t totpage = align(totsize, syspagsz);
+ size_t totsize = size + HDR_PAGE;
+ size_t totpage = S_ROUND(totsize, syspagsz);
- /* LINTED */
- if ((page = (struct page *)dz_map(0, 0, totpage,
+ if ((page = dz_map(0, 0, totpage,
PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE)) == (struct page *)-1)
+ MAP_PRIVATE)) == MAP_FAILED)
return (0);
page->next = memstart;
@@ -237,7 +216,7 @@
}
void *
-realloc(void * ptr, size_t size)
+realloc(void *ptr, size_t size)
{
struct block *block;
size_t osize;
@@ -248,7 +227,7 @@
/* LINTED */
block = (struct block *)((char *)ptr - HDR_BLOCK);
- size = align(size, MINSZ);
+ size = S_DROUND(size);
osize = block->size;
/*
@@ -273,7 +252,7 @@
return (NULL);
(void) memcpy(newptr, ptr, osize);
block->status = FREE;
- defrag(block->page);
+ (void) aplist_test(&free_alp, block->page, AL_CNT_FREELIST);
return (newptr);
}
@@ -282,7 +261,7 @@
* They are both private here.
*/
void
-free(void * ptr)
+free(void *ptr)
{
struct block *block;
@@ -295,23 +274,22 @@
#if DEBUG
scribble((ulong_t *)&block->memstart, FREMEM, block->size);
#endif
- defrag(block->page);
+ (void) aplist_test(&free_alp, block->page, AL_CNT_FREELIST);
}
/* ARGSUSED1 */
void
-lfree(void * ptr, size_t size)
+lfree(void *ptr, size_t size)
{
free(ptr);
}
-
/*
* We can use any memory after ld.so.1's .bss up until the next page boundary
* as allocatable memory.
*/
void
-addfree(void * ptr, size_t bytes)
+addfree(void *ptr, size_t bytes)
{
struct block *block;
struct page *page;
--- a/usr/src/cmd/sgs/rtld/common/mapfile-32-vers Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-32-vers Wed Jan 21 11:00:19 2009 -0800
@@ -20,13 +20,11 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-SUNWprivate_1.2 {
+SUNWprivate_1.3 {
protected:
do32_reloc_rtld; # Required to support librtld.so
reloc32_table;
--- a/usr/src/cmd/sgs/rtld/common/mapfile-64-vers Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-64-vers Wed Jan 21 11:00:19 2009 -0800
@@ -20,13 +20,11 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-SUNWprivate_1.2 {
+SUNWprivate_1.3 {
protected:
do64_reloc_rtld; # Required to support librtld.so
reloc64_table;
--- a/usr/src/cmd/sgs/rtld/common/mapfile-vers Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-vers Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# Generic interface definition for usr/src/cmd/sgs/rtld.
#
# For information regarding the establishment of versioned definitions see:
@@ -39,7 +37,7 @@
#
# All symbols in ld.so.1 are private as no-one should bind to these directly.
-SUNWprivate_1.2 {
+SUNWprivate_1.3 {
protected:
dladdr; # Standard dlopen(3x) family
dladdr1;
@@ -87,7 +85,6 @@
strerror;
calloc; # Memory management (mapmalloc).
- dz_fd;
free;
malloc;
realloc;
--- a/usr/src/cmd/sgs/rtld/common/move.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/move.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +37,7 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_inline.h"
#include "msg.h"
/*
@@ -47,15 +48,43 @@
static APlist *alp = NULL;
/*
- * Move data
+ * Warning message for bad move target.
+ */
+void
+elf_move_bad(Lm_list *lml, Rt_map *lmp, Sym *sym, ulong_t num, Addr addr)
+{
+ const char *name;
+ int trace;
+
+ trace = (lml->lm_flags & LML_FLG_TRC_ENABLE) &&
+ (((rtld_flags & RT_FL_SILENCERR) == 0) ||
+ (lml->lm_flags & (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_WARN)));
+
+ if ((trace == 0) && (DBG_ENABLED == 0))
+ return;
+
+ if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
+ name = (const char *)(STRTAB(lmp) + sym->st_name);
+ else
+ name = MSG_INTL(MSG_STR_UNKNOWN);
+
+ if (trace)
+ (void) printf(MSG_INTL(MSG_LDD_MOVE_ERR), EC_XWORD(num), name,
+ EC_ADDR(addr));
+ else
+ DBG_CALL(Dbg_move_bad(lml, num, name, addr));
+}
+
+/*
+ * Move data. Apply sparse initialization to data in zeroed bss.
*/
int
-move_data(Rt_map *lmp)
+move_data(Rt_map *lmp, APlist **textrel)
{
- Lm_list *lml = LIST(lmp);
- Move *mv = MOVETAB(lmp);
- ulong_t num, mvnum = MOVESZ(lmp) / MOVEENT(lmp);
- int moves;
+ Lm_list *lml = LIST(lmp);
+ Move *mv = MOVETAB(lmp);
+ ulong_t num, mvnum = MOVESZ(lmp) / MOVEENT(lmp);
+ int moves;
/*
* If these records are against the executable, and the executable was
@@ -63,23 +92,38 @@
* comment in analyze.c:lookup_sym_interpose() in regards Solaris 8
* objects and DT_FLAGS.
*/
- moves = (lmp == lml->lm_head) && ((FLAGS2(lmp) & FL2_RT_DTFLAGS) == 0);
+ moves = (lmp == lml->lm_head) && ((FLAGS1(lmp) & FL1_RT_DTFLAGS) == 0);
DBG_CALL(Dbg_move_data(lmp));
for (num = 0; num < mvnum; num++, mv++) {
- Addr addr, taddr;
- Half rep, repno, stride;
- Sym *sym;
+ mmapobj_result_t *mpp;
+ Addr addr, taddr;
+ Half rep, repno, stride;
+ Sym *sym;
if ((sym = (Sym *)SYMTAB(lmp) + ELF_M_SYM(mv->m_info)) == 0)
continue;
stride = mv->m_stride + 1;
addr = sym->st_value;
+
+ /*
+ * Determine the move data target, and verify the address is
+ * writable.
+ */
if ((FLAGS(lmp) & FLG_RT_FIXED) == 0)
addr += ADDR(lmp);
taddr = addr + mv->m_poffset;
+ if ((mpp = find_segment((caddr_t)taddr, lmp)) == NULL) {
+ elf_move_bad(lml, lmp, sym, num, taddr);
+ continue;
+ }
+ if (((mpp->mr_prot & PROT_WRITE) == 0) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
+ return (0);
+
DBG_CALL(Dbg_move_entry2(lml, mv, sym->st_name,
(const char *)(sym->st_name + STRTAB(lmp))));
@@ -122,7 +166,7 @@
* copy relocation processing.
*/
if (moves && repno &&
- (aplist_append(&alp, (void *)addr, AL_CNT_MOVES) == 0))
+ (aplist_append(&alp, (void *)addr, AL_CNT_MOVES) == NULL))
return (0);
}
--- a/usr/src/cmd/sgs/rtld/common/object.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/object.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,7 +40,8 @@
#include "_audit.h"
#include "_elf.h"
-static Rt_map *olmp = 0;
+static Rt_map *olmp = NULL;
+static Alist *mpalp = NULL;
static Ehdr dehdr = { { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
M_CLASS, M_DATA }, 0, M_MACH, EV_CURRENT };
@@ -53,15 +54,25 @@
* elf_obj_fini() to complete the concatenation.
*/
static Rt_map *
-elf_obj_init(Lm_list *lml, Aliste lmco, const char *name)
+elf_obj_init(Lm_list *lml, Aliste lmco, const char *oname)
{
- Ofl_desc * ofl;
+ Ofl_desc *ofl;
+ const char *name;
+ size_t lmsz;
+
+ /*
+ * Allocate the name of this object, as the original name may be
+ * associated with a data buffer that can be reused to load the
+ * dependencies needed to processes this object.
+ */
+ if ((name = stravl_insert(oname, 0, 0, 0)) == NULL)
+ return (NULL);
/*
* Initialize an output file descriptor and the entrance criteria.
*/
- if ((ofl = (Ofl_desc *)calloc(sizeof (Ofl_desc), 1)) == 0)
- return (0);
+ if ((ofl = calloc(sizeof (Ofl_desc), 1)) == NULL)
+ return (NULL);
ofl->ofl_dehdr = &dehdr;
@@ -72,40 +83,40 @@
/*
* As ent_setup() will effectively lazy load the necessary support
* libraries, make sure ld.so.1 is initialized for plt relocations.
- */
- if (elf_rtld_load() == 0)
- return (0);
-
- /*
- * Configure libld.so to process objects of the desired target
+ * Then configure libld.so to process objects of the desired target
* type (this is the first call to libld.so, which will effectively
* lazyload it).
*/
- if (ld_init_target(lml, M_MACH) != 0)
- return (0);
-
- /*
- * Obtain a generic set of entrance criteria
- */
- if (ld_ent_setup(ofl, syspagsz) == S_ERROR)
- return (0);
+ if ((elf_rtld_load() == 0) || (ld_init_target(lml, M_MACH) != 0)) {
+ free(ofl);
+ return (NULL);
+ }
/*
- * Generate a link map place holder and use the `rt_priv' element to
- * maintain the output file descriptor.
+ * Obtain a generic set of entrance criteria, and generate a link map
+ * place holder and use the ELFPRV() element to maintain the output
+ * file descriptor.
*/
- if ((olmp = (Rt_map *)calloc(sizeof (Rt_map), 1)) == 0)
- return (0);
+ lmsz = S_DROUND(sizeof (Rt_map)) + sizeof (Rt_elfp);
+ if ((ld_ent_setup(ofl, syspagsz) == S_ERROR) ||
+ ((olmp = calloc(lmsz, 1)) == NULL)) {
+ free(ofl);
+ return (NULL);
+ }
- DBG_CALL(Dbg_file_elf(lml, name, 0, 0, 0, 0, lml->lm_lmidstr, lmco));
+ DBG_CALL(Dbg_file_elf(lml, name, 0, 0, lml->lm_lmidstr, lmco));
FLAGS(olmp) |= FLG_RT_OBJECT;
- olmp->rt_priv = (void *)ofl;
+ ELFPRV(olmp) = (void *)ofl;
/*
* Initialize string tables.
*/
- if (ld_init_strings(ofl) == S_ERROR)
- return (0);
+ if (ld_init_strings(ofl) == S_ERROR) {
+ free(ofl);
+ free(olmp);
+ olmp = NULL;
+ return (NULL);
+ }
/*
* Assign the output file name to be the initial object that got us
@@ -113,7 +124,7 @@
* don't actually generate an output file unless debugging is enabled.
*/
ofl->ofl_name = name;
- ORIGNAME(olmp) = PATHNAME(olmp) = NAME(olmp) = (char *)name;
+ NAME(olmp) = (char *)name;
LIST(olmp) = lml;
lm_append(lml, lmco, olmp);
@@ -121,6 +132,22 @@
}
/*
+ * Define a structure to retain the mapping information of the original
+ * relocatable object. Typically, mmapobj(2) maps a relocatable object into one
+ * mapping. However, if padding has been enabled by a debugger, then additional
+ * padding segments may have been added. elf_obj_file() needs to know which
+ * segment is the relocatable objects data, and retain the initial segment and
+ * the associated segment number for unmapping this object later (see
+ * elf_obj_fini()). Note, even if padding is enabled, the final shared object
+ * that is created by the link-editor for this relocatable object will have no
+ * associated padding, as ld(1) has no capabilities to provide padding.
+ */
+typedef struct {
+ mmapobj_result_t *md_mpp;
+ uint_t md_mnum;
+} Mmap_desc;
+
+/*
* Initial processing of a relocatable object. If this is the first object
* encountered we need to initialize some structures, then simply call the
* link-edit functionality to provide the initial processing of the file (ie.
@@ -129,29 +156,43 @@
* sections).
*/
Rt_map *
-elf_obj_file(Lm_list *lml, Aliste lmco, const char *name, int fd)
+elf_obj_file(Lm_list *lml, Aliste lmco, const char *name,
+ mmapobj_result_t *hmpp, mmapobj_result_t *mpp, uint_t mnum)
{
Rej_desc rej;
+ Mmap_desc md;
/*
* If this is the first relocatable object (LD_PRELOAD could provide a
* list of objects), initialize an input file descriptor and a link map.
*/
- if (!olmp) {
- /*
- * Load the link-editor library.
- */
- if ((olmp = elf_obj_init(lml, lmco, name)) == 0)
- return (0);
+ if ((olmp == NULL) && ((olmp = elf_obj_init(lml, lmco, name)) == NULL))
+ return (NULL);
+
+ DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
+
+ /*
+ * Keep track of the input image, as this must be free'd after all ELF
+ * processing is completed.
+ */
+ md.md_mpp = mpp;
+ md.md_mnum = mnum;
+ if (alist_append(&mpalp, &md, sizeof (Mmap_desc),
+ AL_CNT_MPOBJS) == NULL) {
+ remove_so(lml, olmp);
+ return (NULL);
}
/*
- * Proceed to process the input file.
+ * Pass the object mapping to the link-editor to commence processing the
+ * file.
*/
- DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
- if (ld_process_open(name, name, &fd, (Ofl_desc *)olmp->rt_priv,
- NULL, &rej) == (Ifl_desc *)S_ERROR)
- return (0);
+ if (ld_process_mem(name, name, hmpp->mr_addr, hmpp->mr_msize,
+ (Ofl_desc *)ELFPRV(olmp), &rej) == (Ifl_desc *)S_ERROR) {
+ remove_so(lml, olmp);
+ return (NULL);
+ }
+
return (olmp);
}
@@ -163,29 +204,63 @@
Rt_map *
elf_obj_fini(Lm_list *lml, Rt_map *lmp, int *in_nfavl)
{
- Ofl_desc *ofl = (Ofl_desc *)lmp->rt_priv;
- Rt_map *nlmp;
- Addr etext;
- Ehdr *ehdr;
- Phdr *phdr;
- Mmap *mmaps;
- uint_t phnum, mmapcnt;
- Lm_cntl *lmc;
+ Ofl_desc *ofl = (Ofl_desc *)ELFPRV(lmp);
+ Rt_map *nlmp, *tlmp;
+ Ehdr *ehdr;
+ Phdr *phdr;
+ mmapobj_result_t *mpp, *hmpp;
+ uint_t phnum;
+ int mnum;
+ Lm_cntl *lmc;
+ Aliste idx1;
+ Mmap_desc *mdp;
+ Fdesc fd = { 0 };
+ Grp_hdl *ghp;
+ Rej_desc rej = { 0 };
DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
if (ld_reloc_init(ofl) == S_ERROR)
- return (0);
+ return (NULL);
if (ld_sym_validate(ofl) == S_ERROR)
- return (0);
+ return (NULL);
+
+ /*
+ * At this point, all input section processing is complete. If any
+ * hardware or software capabilities have been established, ensure that
+ * they are appropriate for this platform.
+ */
+ if ((ofl->ofl_hwcap_1) && (hwcap_check(ofl->ofl_hwcap_1, &rej) == 0)) {
+ if ((lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) &&
+ (lmp != NULL) && (FLAGS1(lmp) & FL1_RT_LDDSTUB) &&
+ (NEXT(lmp) == NULL)) {
+ (void) printf(MSG_INTL(MSG_LDD_GEN_HWCAP_1),
+ ofl->ofl_name, rej.rej_str);
+ }
+ return (NULL);
+ }
+
+ if ((ofl->ofl_sfcap_1) && (sfcap_check(ofl->ofl_sfcap_1, &rej) == 0)) {
+ if ((lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) &&
+ (lmp != NULL) && (FLAGS1(lmp) & FL1_RT_LDDSTUB) &&
+ (NEXT(lmp) == NULL)) {
+ (void) printf(MSG_INTL(MSG_LDD_GEN_SFCAP_1),
+ ofl->ofl_name, rej.rej_str);
+ }
+ return (NULL);
+ }
+
+ /*
+ * Finish creating the output file.
+ */
if (ld_make_sections(ofl) == S_ERROR)
- return (0);
+ return (NULL);
if (ld_create_outfile(ofl) == S_ERROR)
- return (0);
- if ((etext = ld_update_outfile(ofl)) == (Addr)S_ERROR)
- return (0);
+ return (NULL);
+ if (ld_update_outfile(ofl) == S_ERROR)
+ return (NULL);
if (ld_reloc_process(ofl) == S_ERROR)
- return (0);
+ return (NULL);
/*
* At this point we have a memory image of the shared object. The link
@@ -199,45 +274,66 @@
*/
ehdr = ofl->ofl_nehdr;
phdr = ofl->ofl_phdr;
- if ((mmaps = calloc(ehdr->e_phnum, sizeof (Mmap))) == 0)
- return (0);
- for (mmapcnt = 0, phnum = 0; phnum < ehdr->e_phnum; phnum++) {
+
+ if ((mpp = hmpp = calloc(ehdr->e_phnum,
+ sizeof (mmapobj_result_t))) == NULL)
+ return (NULL);
+ for (mnum = 0, phnum = 0; phnum < ehdr->e_phnum; phnum++) {
if (phdr[phnum].p_type != PT_LOAD)
continue;
- mmaps[mmapcnt].m_vaddr = (caddr_t)
- (phdr[phnum].p_vaddr + (ulong_t)ehdr);
- mmaps[mmapcnt].m_msize = phdr[phnum].p_memsz;
- mmaps[mmapcnt].m_fsize = phdr[phnum].p_filesz;
- mmaps[mmapcnt].m_perm = (PROT_READ | PROT_WRITE | PROT_EXEC);
- mmapcnt++;
+ mpp[mnum].mr_addr = (caddr_t)((uintptr_t)phdr[phnum].p_vaddr +
+ (uintptr_t)ehdr);
+ mpp[mnum].mr_msize = phdr[phnum].p_memsz;
+ mpp[mnum].mr_fsize = phdr[phnum].p_filesz;
+ mpp[mnum].mr_prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
+ mnum++;
}
/*
* Generate a new link map representing the memory image created.
*/
- if ((nlmp = elf_new_lm(lml, ofl->ofl_name, ofl->ofl_name,
- ofl->ofl_osdynamic->os_outdata->d_buf, (ulong_t)ehdr,
- (ulong_t)ehdr + etext, CNTL(olmp), (ulong_t)ofl->ofl_size,
- 0, 0, 0, mmaps, mmapcnt, in_nfavl)) == 0)
- return (0);
+ fd.fd_nname = ofl->ofl_name;
+ if ((nlmp = elf_new_lmp(lml, CNTL(olmp), &fd, (Addr)hmpp->mr_addr,
+ ofl->ofl_size, 0, in_nfavl)) == NULL)
+ return (NULL);
+
+ MMAPS(nlmp) = hmpp;
+ MMAPCNT(nlmp) = mnum;
+ PADSTART(nlmp) = (ulong_t)hmpp->mr_addr;
+ PADIMLEN(nlmp) = mpp->mr_addr + mpp->mr_msize - hmpp->mr_addr;
/*
- * Remove this link map from the end of the link map list and copy its
- * contents into the link map originally created for this file (we copy
- * the contents rather than manipulate the link map pointers as parts
- * of the dlopen code have remembered the original link map address).
+ * Replace the original (temporary) link map with the new link map.
*/
- NEXT(PREV_RT_MAP(nlmp)) = 0;
/* LINTED */
lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(nlmp));
- lmc->lc_tail = PREV_RT_MAP(nlmp);
- if (CNTL(nlmp) == ALIST_OFF_DATA)
- lml->lm_tail = PREV_RT_MAP(nlmp);
lml->lm_obj--;
- PREV(nlmp) = PREV(olmp);
- NEXT(nlmp) = NEXT(olmp);
+ if ((tlmp = PREV_RT_MAP(nlmp)) == olmp)
+ tlmp = nlmp;
+
+ if (PREV(olmp)) {
+ NEXT(PREV_RT_MAP(olmp)) = (Link_map *)nlmp;
+ PREV(nlmp) = PREV(olmp);
+ } else {
+ PREV(nlmp) = NULL;
+ lmc->lc_head = nlmp;
+ if (CNTL(nlmp) == ALIST_OFF_DATA)
+ lml->lm_head = nlmp;
+ }
+
+ if (NEXT(olmp) != (Link_map *)nlmp) {
+ NEXT(nlmp) = NEXT(olmp);
+ PREV(NEXT_RT_MAP(olmp)) = (Link_map *)nlmp;
+ }
+
+ NEXT(tlmp) = NULL;
+
+ lmc->lc_tail = tlmp;
+ if (CNTL(nlmp) == ALIST_OFF_DATA)
+ lml->lm_tail = tlmp;
+
HANDLES(nlmp) = HANDLES(olmp);
GROUPS(nlmp) = GROUPS(olmp);
STDEV(nlmp) = STDEV(olmp);
@@ -248,33 +344,54 @@
MODE(nlmp) |= MODE(olmp);
NAME(nlmp) = NAME(olmp);
- PATHNAME(nlmp) = PATHNAME(olmp);
- ORIGNAME(nlmp) = ORIGNAME(olmp);
- DIRSZ(nlmp) = DIRSZ(olmp);
+
+ /*
+ * Reassign any original handles to the new link-map.
+ */
+ for (APLIST_TRAVERSE(HANDLES(nlmp), idx1, ghp)) {
+ Grp_desc *gdp;
+ Aliste idx2;
+
+ ghp->gh_ownlmp = nlmp;
+
+ for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
+ if (gdp->gd_depend == olmp) {
+ gdp->gd_depend = nlmp;
+ break;
+ }
+ }
+ }
ld_ofl_cleanup(ofl);
- free(olmp->rt_priv);
- (void) memcpy(olmp, nlmp, sizeof (Rt_map));
- free(nlmp);
- nlmp = olmp;
+ free(ELFPRV(olmp));
+ free(olmp);
olmp = 0;
/*
- * Now that we've allocated our permanent Rt_map structure, expand the
- * PATHNAME() and insert it into the FullpathNode AVL tree
+ * Unmap the original relocatable object.
*/
- if (FLAGS1(nlmp) & FL1_RT_RELATIVE)
- (void) fullpath(nlmp, 0);
+ for (ALIST_TRAVERSE(mpalp, idx1, mdp)) {
+ unmap_obj(mdp->md_mpp, mdp->md_mnum);
+ free(mdp->md_mpp);
+ }
+ free(mpalp);
+ mpalp = NULL;
+
+ /*
+ * Now that we've allocated our permanent link map structure, expand the
+ * PATHNAME() and insert this path name into the FullPathNode AVL tree.
+ */
+ (void) fullpath(nlmp, 0);
if (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)
- return (0);
+ return (NULL);
/*
* If we're being audited tell the audit library of the file we've just
* opened.
*/
- if ((lml->lm_tflags | FLAGS1(nlmp)) & LML_TFLG_AUD_MASK) {
+ if ((lml->lm_tflags | AFLAGS(nlmp)) & LML_TFLG_AUD_MASK) {
if (audit_objopen(lmp, lmp) == 0)
- return (0);
+ return (NULL);
}
return (nlmp);
}
--- a/usr/src/cmd/sgs/rtld/common/paths.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/paths.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
*/
#include <stdio.h>
+#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <string.h>
@@ -44,15 +45,72 @@
#include "msg.h"
/*
+ * Default and secure dependency search path initialization.
+ */
+void
+set_dirs(Alist **alpp, Spath_defn *sdp, uint_t flags)
+{
+ while (sdp->sd_name) {
+ Pdesc *pdp;
+
+ if ((pdp = alist_append(alpp, 0, sizeof (Pdesc),
+ AL_CNT_SPATH)) == NULL)
+ return;
+
+ pdp->pd_pname = (char *)sdp->sd_name;
+ pdp->pd_plen = sdp->sd_len;
+ pdp->pd_flags = flags;
+ sdp++;
+ }
+}
+
+static void
+print_default_dirs(Lm_list *lml, Alist *alp, int search)
+{
+ uint_t flags = 0;
+ int num = 0;
+ Aliste idx;
+ Pdesc *pdp;
+
+ if (search)
+ (void) printf(MSG_INTL(MSG_LDD_PTH_BGNDFL));
+
+ for (ALIST_TRAVERSE(alp, idx, pdp)) {
+ flags = pdp->pd_flags;
+
+ if (search) {
+ const char *fmt;
+
+ if (num++)
+ fmt = MSG_ORIG(MSG_LDD_FMT_PATHN);
+ else
+ fmt = MSG_ORIG(MSG_LDD_FMT_PATH1);
+
+ (void) printf(fmt, pdp->pd_pname);
+ } else
+ DBG_CALL(Dbg_libs_path(lml, pdp->pd_pname,
+ pdp->pd_flags, config->c_name));
+ }
+
+ if (search) {
+ if (flags & LA_SER_CONFIG)
+ (void) printf(MSG_INTL(MSG_LDD_PTH_ENDDFLC),
+ config->c_name);
+ else
+ (void) printf(MSG_INTL(MSG_LDD_PTH_ENDDFL));
+ }
+}
+
+/*
* Given a search rule type, return a list of directories to search according
* to the specified rule.
*/
-static Pnode *
+static Alist **
get_dir_list(uchar_t rules, Rt_map *lmp, uint_t flags)
{
- Pnode * dirlist = (Pnode *)0;
- Lm_list * lml = LIST(lmp);
- int search;
+ Alist **dalpp = NULL;
+ Lm_list *lml = LIST(lmp);
+ int search;
/*
* Determine whether ldd -s is in effect - ignore when we're searching
@@ -74,7 +132,7 @@
* be preceded with the appropriate search path information.
*/
if (rpl_libpath) {
- uint_t mode = (LA_SER_LIBPATH | PN_FLG_UNIQUE);
+ uint_t mode = (LA_SER_LIBPATH | PD_FLG_UNIQUE);
/*
* Note, this path may have originated from the users
@@ -105,19 +163,19 @@
(void) printf(fmt, rpl_libpath, config->c_name);
}
if (rpl_libdirs && (rtld_flags & RT_FL_SECURE) &&
- (search || DBG_ENABLED)) {
- free(rpl_libdirs);
- rpl_libdirs = 0;
- }
- if (!rpl_libdirs) {
+ (search || DBG_ENABLED))
+ remove_plist(&rpl_libdirs, 1);
+
+ if (rpl_libdirs == NULL) {
/*
* If this is a secure application we need to
* be selective over what directories we use.
*/
- rpl_libdirs = expand_paths(lmp, rpl_libpath,
- mode, PN_TKN_HWCAP);
+ (void) expand_paths(lmp, rpl_libpath,
+ &rpl_libdirs, AL_CNT_SEARCH, mode,
+ PD_TKN_HWCAP);
}
- dirlist = rpl_libdirs;
+ dalpp = &rpl_libdirs;
}
break;
case PRMENV:
@@ -129,7 +187,7 @@
*/
if (prm_libpath) {
uint_t mode =
- (LA_SER_LIBPATH | LA_SER_CONFIG | PN_FLG_UNIQUE);
+ (LA_SER_LIBPATH | LA_SER_CONFIG | PD_FLG_UNIQUE);
DBG_CALL(Dbg_libs_path(lml, prm_libpath, mode,
config->c_name));
@@ -146,19 +204,19 @@
(void) printf(MSG_INTL(MSG_LDD_PTH_LIBPATHC),
prm_libpath, config->c_name);
if (prm_libdirs && (rtld_flags & RT_FL_SECURE) &&
- (search || DBG_ENABLED)) {
- free(prm_libdirs);
- prm_libdirs = 0;
- }
- if (!prm_libdirs) {
+ (search || DBG_ENABLED))
+ remove_plist(&prm_libdirs, 1);
+
+ if (prm_libdirs == NULL) {
/*
* If this is a secure application we need to
* be selective over what directories we use.
*/
- prm_libdirs = expand_paths(lmp, prm_libpath,
- mode, PN_TKN_HWCAP);
+ (void) expand_paths(lmp, prm_libpath,
+ &prm_libdirs, AL_CNT_SEARCH, mode,
+ PD_TKN_HWCAP);
}
- dirlist = prm_libdirs;
+ dalpp = &prm_libdirs;
}
break;
case RUNPATH:
@@ -183,104 +241,86 @@
(void) printf(MSG_INTL(MSG_LDD_PTH_RUNPATH),
RPATH(lmp), NAME(lmp));
if (RLIST(lmp) && (rtld_flags & RT_FL_SECURE) &&
- (search || DBG_ENABLED)) {
- free(RLIST(lmp));
- RLIST(lmp) = 0;
- }
- if (!(RLIST(lmp)))
+ (search || DBG_ENABLED))
+ remove_plist(&RLIST(lmp), 1);
+
+ if (RLIST(lmp) == NULL) {
/*
* If this is a secure application we need to
* be selective over what directories we use.
*/
- RLIST(lmp) = expand_paths(lmp, RPATH(lmp),
- LA_SER_RUNPATH, PN_TKN_HWCAP);
- dirlist = RLIST(lmp);
+ (void) expand_paths(lmp, RPATH(lmp),
+ &RLIST(lmp), AL_CNT_SEARCH, LA_SER_RUNPATH,
+ PD_TKN_HWCAP);
+ }
+ dalpp = &RLIST(lmp);
}
break;
case DEFAULT:
if ((FLAGS1(lmp) & FL1_RT_NODEFLIB) == 0) {
if ((rtld_flags & RT_FL_SECURE) &&
(flags & (FLG_RT_PRELOAD | FLG_RT_AUDIT)))
- dirlist = LM_SECURE_DIRS(lmp);
+ dalpp = LM_SECURE_DIRS(lmp)();
else
- dirlist = LM_DFLT_DIRS(lmp);
+ dalpp = LM_DEFAULT_DIRS(lmp)();
}
/*
* For ldd(1) -s, indicate the default paths that'll be used.
*/
- if (dirlist && (search || DBG_ENABLED)) {
- Pnode * pnp = dirlist;
- int num = 0;
-
- if (search)
- (void) printf(MSG_INTL(MSG_LDD_PTH_BGNDFL));
- for (; pnp && pnp->p_name; pnp = pnp->p_next, num++) {
- if (search) {
- const char *fmt;
-
- if (num) {
- fmt =
- MSG_ORIG(MSG_LDD_FMT_PATHN);
- } else {
- fmt =
- MSG_ORIG(MSG_LDD_FMT_PATH1);
- }
- (void) printf(fmt, pnp->p_name);
- } else
- DBG_CALL(Dbg_libs_path(lml, pnp->p_name,
- pnp->p_orig, config->c_name));
- }
- /* BEGIN CSTYLED */
- if (search) {
- if (dirlist->p_orig & LA_SER_CONFIG)
- (void) printf(
- MSG_INTL(MSG_LDD_PTH_ENDDFLC),
- config->c_name);
- else
- (void) printf(
- MSG_INTL(MSG_LDD_PTH_ENDDFL));
- }
- /* END CSTYLED */
- }
+ if (dalpp && (search || DBG_ENABLED))
+ print_default_dirs(lml, *dalpp, search);
break;
default:
break;
}
- return (dirlist);
+ return (dalpp);
}
/*
- * Get the next dir in the search rules path.
+ * Get the next directory in the search rules path. The seach path "cookie"
+ * provided by the caller (sdp) maintains the state of a search in progress.
+ *
+ * Typically, a search consists of a series of rules that govern the order of
+ * a search (ie. LD_LIBRARY_PATH, followed by RPATHS, followed by defaults).
+ * Each rule can establish a corresponding series of path names, which are
+ * maintained as an Alist. The index within this Alist determines the present
+ * search directory.
*/
-Pnode *
-get_next_dir(Pnode ** dirlist, Rt_map * lmp, uint_t flags)
+Pdesc *
+get_next_dir(Spath_desc *sdp, Rt_map *lmp, uint_t flags)
{
- static unsigned char *rules = NULL;
-
/*
- * Search rules consist of one or more directories names. If this is a
- * new search, then start at the beginning of the search rules.
- * Otherwise traverse the list of directories that make up the rule.
+ * Make sure there are still rules to process.
*/
- if (!*dirlist) {
- rules = search_rules;
- } else {
- if ((*dirlist = (*dirlist)->p_next) != 0)
- return (*dirlist);
- else
- rules++;
- }
+ while (*sdp->sp_rule) {
+ Alist *alp;
- while (*rules) {
- if ((*dirlist = get_dir_list(*rules, lmp, flags)) != 0)
- return (*dirlist);
- else
- rules++;
+ /*
+ * If an Alist for this rule already exists, use if, otherwise
+ * obtain an Alist for this rule. Providing the Alist has
+ * content, and the present Alist index is less than the number
+ * of Alist members, return the associated path name descriptor.
+ */
+ if ((sdp->sp_dalpp || ((sdp->sp_dalpp =
+ get_dir_list(*sdp->sp_rule, lmp, flags)) != NULL)) &&
+ ((alp = *sdp->sp_dalpp) != NULL) &&
+ (alist_nitems(alp) > sdp->sp_idx)) {
+ return (alist_item(alp, sdp->sp_idx++));
+ }
+
+ /*
+ * If no Alist for this rule exists, or if this is the last
+ * element of this Alist, reset the Alist pointer and index,
+ * and prepare for the next rule.
+ */
+ sdp->sp_rule++;
+ sdp->sp_dalpp = NULL;
+ sdp->sp_idx = 0;
}
/*
- * If we got here, no more directories to search, return NULL.
+ * All rules and search paths have been exhausted.
*/
return (NULL);
}
@@ -294,13 +334,14 @@
Rt_map *lmp)
{
char _name[PATH_MAX];
- char *token = 0, *oname, *optr, *_optr, *nptr, * _list;
+ char *token = NULL, *oname, *ename, *optr, *_optr, *nptr, *_list;
size_t olen = 0, nlen = 0, _len;
int isaflag = 0;
uint_t flags = 0;
Lm_list *lml = LIST(lmp);
- optr = _optr = oname = *name;
+ optr = _optr = oname = ename = *name;
+ ename += *len;
nptr = _name;
while ((olen < *len) && (nlen < PATH_MAX)) {
@@ -357,7 +398,7 @@
* caller to insure the expanded path matches a
* registered secure name.
*/
- if (((omit & PN_TKN_ORIGIN) == 0) &&
+ if (((omit & PD_TKN_ORIGIN) == 0) &&
(((_len = DIRSZ(lmp)) != 0) ||
((_len = fullpath(lmp, 0)) != 0))) {
if ((nlen += _len) < PATH_MAX) {
@@ -366,7 +407,7 @@
nptr = nptr +_len;
olen += MSG_TKN_ORIGIN_SIZE;
optr += MSG_TKN_ORIGIN_SIZE;
- _flags |= PN_TKN_ORIGIN;
+ _flags |= PD_TKN_ORIGIN;
} else {
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_ERR_EXPAND1),
@@ -384,19 +425,19 @@
* established from the AT_SUN_PLATFORM aux vector, but
* if not attempt to get it from sysconf().
*/
- if (((omit & PN_TKN_PLATFORM) == 0) &&
+ if (((omit & PD_TKN_PLATFORM) == 0) &&
((platform == 0) && (platform_sz == 0))) {
char _info[SYS_NMLN];
long _size;
_size = sysinfo(SI_PLATFORM, _info, SYS_NMLN);
- if ((_size != -1) &&
- ((platform = malloc((size_t)_size)) != 0)) {
+ if ((_size != -1) && ((platform =
+ malloc((size_t)_size)) != NULL)) {
(void) strcpy(platform, _info);
platform_sz = (size_t)_size - 1;
}
}
- if (((omit & PN_TKN_PLATFORM) == 0) &&
+ if (((omit & PD_TKN_PLATFORM) == 0) &&
(platform != 0)) {
if ((nlen += platform_sz) < PATH_MAX) {
(void) strncpy(nptr, platform,
@@ -404,7 +445,7 @@
nptr = nptr + platform_sz;
olen += MSG_TKN_PLATFORM_SIZE;
optr += MSG_TKN_PLATFORM_SIZE;
- _flags |= PN_TKN_PLATFORM;
+ _flags |= PD_TKN_PLATFORM;
} else {
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_ERR_EXPAND1),
@@ -421,10 +462,10 @@
* $OSNAME expansion required. This is established
* from the sysname[] returned by uname(2).
*/
- if (((omit & PN_TKN_OSNAME) == 0) && (uts == 0))
+ if (((omit & PD_TKN_OSNAME) == 0) && (uts == NULL))
uts = conv_uts();
- if (((omit & PN_TKN_OSNAME) == 0) &&
+ if (((omit & PD_TKN_OSNAME) == 0) &&
(uts && uts->uts_osnamesz)) {
if ((nlen += uts->uts_osnamesz) < PATH_MAX) {
(void) strncpy(nptr, uts->uts_osname,
@@ -432,7 +473,7 @@
nptr = nptr + uts->uts_osnamesz;
olen += MSG_TKN_OSNAME_SIZE;
optr += MSG_TKN_OSNAME_SIZE;
- _flags |= PN_TKN_OSNAME;
+ _flags |= PD_TKN_OSNAME;
} else {
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_ERR_EXPAND1),
@@ -449,10 +490,10 @@
* $OSREL expansion required. This is established
* from the release[] returned by uname(2).
*/
- if (((omit & PN_TKN_OSREL) == 0) && (uts == 0))
+ if (((omit & PD_TKN_OSREL) == 0) && (uts == 0))
uts = conv_uts();
- if (((omit & PN_TKN_OSREL) == 0) &&
+ if (((omit & PD_TKN_OSREL) == 0) &&
(uts && uts->uts_osrelsz)) {
if ((nlen += uts->uts_osrelsz) < PATH_MAX) {
(void) strncpy(nptr, uts->uts_osrel,
@@ -460,7 +501,7 @@
nptr = nptr + uts->uts_osrelsz;
olen += MSG_TKN_OSREL_SIZE;
optr += MSG_TKN_OSREL_SIZE;
- _flags |= PN_TKN_OSREL;
+ _flags |= PD_TKN_OSREL;
} else {
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_ERR_EXPAND1),
@@ -482,12 +523,12 @@
* provided. NOTE, that two $ISLIST expansions within
* the same path aren't supported.
*/
- if ((omit & PN_TKN_ISALIST) || isaflag++)
+ if ((omit & PD_TKN_ISALIST) || isaflag++)
ok = 0;
else
ok = 1;
- if (ok && (isa == 0))
+ if (ok && (isa == NULL))
isa = conv_isalist();
if (ok && isa && isa->isa_listsz) {
@@ -501,7 +542,7 @@
nptr = nptr + opt->isa_namesz;
olen += MSG_TKN_ISALIST_SIZE;
optr += MSG_TKN_ISALIST_SIZE;
- _flags |= PN_TKN_ISALIST;
+ _flags |= PD_TKN_ISALIST;
} else {
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_ERR_EXPAND1),
@@ -515,7 +556,8 @@
(isa->isa_optno - 1)) +
isa->isa_listsz - opt->isa_namesz +
strlen(*list);
- if ((_list = lptr = malloc(mlen)) == 0)
+ if ((_list = lptr =
+ malloc(mlen)) == NULL)
return (0);
for (no = 1, opt++; no < isa->isa_optno;
@@ -554,7 +596,7 @@
* last element of the path. Therefore, all we need do
* is test the existence of the string "/$HWCAP\0".
*/
- if (((omit & PN_TKN_HWCAP) == 0) &&
+ if (((omit & PD_TKN_HWCAP) == 0) &&
(rtld_flags2 & RT_FL2_HWCAP) &&
((bptr > _name) && (*bptr == '/') &&
((*eptr == '\0') || (*eptr == ':')))) {
@@ -565,7 +607,7 @@
nptr--, nlen--;
olen += MSG_TKN_HWCAP_SIZE;
optr += MSG_TKN_HWCAP_SIZE;
- _flags |= PN_TKN_HWCAP;
+ _flags |= PD_TKN_HWCAP;
}
} else {
@@ -578,7 +620,7 @@
}
/*
- * If reserved token was found, and could not be expanded,
+ * If a reserved token was found, and could not be expanded,
* diagnose the error condition.
*/
if (token) {
@@ -639,13 +681,11 @@
if (list)
*list = _list;
} else {
- flags &= ~PN_TKN_ISALIST;
-
- if ((nptr = calloc(1, (*len + 1))) == 0)
+ flags &= ~PD_TKN_ISALIST;
+ if ((nptr = (char *)stravl_insert(*name, 0,
+ (*len + 1), 1)) == NULL)
return (0);
- (void) strncpy(nptr, *name, *len);
*name = nptr;
-
return (TKN_NONE);
}
}
@@ -678,31 +718,33 @@
* use of "$ORIGIN/../lib" will probably only match a configuration file
* entry after resolution.
*/
- if (list && ((rtld_flags & (RT_FL_DIRCFG | RT_FL_EXECNAME)) ==
- (RT_FL_DIRCFG | RT_FL_EXECNAME)) && (flags & TKN_DOTSLASH)) {
+ if (list && (rtld_flags & RT_FL_DIRCFG) && (flags & TKN_DOTSLASH)) {
int len;
if ((len = resolvepath(_name, _name, (PATH_MAX - 1))) >= 0) {
nlen = (size_t)len;
_name[nlen] = '\0';
+ flags |= PD_TKN_RESOLVED;
}
}
/*
- * Allocate permanent storage for the new string and return to the user.
+ * Allocate a new string if necessary.
+ *
+ * If any form of token expansion, or string resolution has occurred,
+ * the storage must be allocated for the new string.
+ *
+ * If we're processing a substring, for example, any string besides the
+ * last string within a search path "A:B:C", then this substring needs
+ * to be isolated with a null terminator. However, if this search path
+ * was created from a previous ISALIST expansion, then all strings must
+ * be allocated, as the isalist expansion will be freed after expansion
+ * processing.
*/
- if ((nptr = malloc(nlen + 1)) == 0)
+ if ((nptr = (char *)stravl_insert(_name, 0, (nlen + 1), 1)) == NULL)
return (0);
- (void) strcpy(nptr, _name);
*name = nptr;
*len = nlen;
-
- /*
- * Return an indication of any token expansion that may have occurred.
- * If this is a secure application, any path name expanded with the
- * $ORIGIN token must be validated against any registered trusted
- * directories.
- */
return (flags ? flags : TKN_NONE);
}
@@ -712,9 +754,11 @@
int
is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags)
{
- Pnode *sdir = LM_SECURE_DIRS(LIST(clmp)->lm_head);
- char buffer[PATH_MAX], *npath = NULL;
- Lm_list *lml = LIST(clmp);
+ Alist **salpp;
+ Aliste idx;
+ char buffer[PATH_MAX], *npath = NULL;
+ Lm_list *lml = LIST(clmp);
+ Pdesc *pdp;
/*
* If a path name originates from a configuration file, use it. The use
@@ -747,10 +791,10 @@
* . provided $ORIGIN expansion has not been employed, the
* above categories of path are deemed secure.
*/
- if ((((str == 0) && ((info & PN_FLG_FULLPATH) == 0)) ||
+ if ((((str == 0) && ((info & PD_FLG_FULLPATH) == 0)) ||
((*opath == '/') && (str != opath) &&
- ((info & PN_FLG_EXTLOAD) == 0))) &&
- ((flags & PN_TKN_ORIGIN) == 0))
+ ((info & PD_FLG_EXTLOAD) == 0))) &&
+ ((flags & PD_TKN_ORIGIN) == 0))
return (1);
/*
@@ -775,7 +819,7 @@
* any directory that has already been used to satisfy
* other dependencies, to be used.
*/
- if ((flags & PN_TKN_ORIGIN) &&
+ if ((flags & PD_TKN_ORIGIN) &&
spavl_recorded(npath, 0)) {
DBG_CALL(Dbg_libs_insecure(lml, npath, 1));
return (1);
@@ -793,7 +837,7 @@
* . any relative path.
*/
if (((info & LA_SER_LIBPATH) == 0) && (*opath == '/') &&
- ((flags & PN_TKN_ORIGIN) == 0))
+ ((flags & PD_TKN_ORIGIN) == 0))
return (1);
/*
@@ -802,7 +846,7 @@
* application to use this path name only if the path name has
* already been used to locate other dependencies.
*/
- if (flags & PN_TKN_ORIGIN) {
+ if (flags & PD_TKN_ORIGIN) {
if ((lml->lm_flags & LML_FLG_RTLDLM) &&
is_rtld_setuid())
return (1);
@@ -818,10 +862,10 @@
* Determine whether the present directory is trusted.
*/
if (npath) {
- while (sdir) {
- if (strcmp(npath, sdir->p_name) == 0)
+ salpp = LM_SECURE_DIRS(LIST(clmp)->lm_head)();
+ for (ALIST_TRAVERSE(*salpp, idx, pdp)) {
+ if (strcmp(npath, pdp->pd_pname) == 0)
return (1);
- sdir = sdir->p_next;
}
}
@@ -830,7 +874,7 @@
* diagnostic. Preloaded, or audit libraries generate a warning, as
* the process will run without them.
*/
- if (info & PN_FLG_EXTLOAD) {
+ if (info & PD_FLG_EXTLOAD) {
if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
if ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)
(void) printf(MSG_INTL(MSG_LDD_FIL_ILLEGAL),
@@ -881,11 +925,14 @@
* Determine whether a path already exists within the callers Pnode list.
*/
inline static uint_t
-is_path_unique(Pnode *pnp, const char *path)
+is_path_unique(Alist *alp, const char *path)
{
- for (; pnp; pnp = pnp->p_next) {
- if (pnp->p_len && (strcmp(pnp->p_name, path) == 0))
- return (PN_FLG_DUPLICAT);
+ Aliste idx;
+ Pdesc *pdp;
+
+ for (ALIST_TRAVERSE(alp, idx, pdp)) {
+ if (pdp->pd_plen && (strcmp(pdp->pd_pname, path) == 0))
+ return (PD_FLG_DUPLICAT);
}
return (0);
}
@@ -897,23 +944,25 @@
* of path names. Each individual path name is processed for possible reserved
* token expansion. All string nodes are maintained in allocated memory
* (regardless of whether they are constant (":"), or token expanded) to
- * simplify pnode removal.
+ * simplify path name descriptor removal.
*
* The info argument passes in auxiliary information regarding the callers
* intended use of the path names. This information may be maintained in the
- * pnode element produced to describe the path name (i.e., LA_SER_LIBPATH etc.),
- * or may be used to determine additional security or diagnostic processing.
+ * path name descriptor element produced to describe the path name (i.e.,
+ * LA_SER_LIBPATH etc.), or may be used to determine additional security or
+ * diagnostic processing.
*/
-Pnode *
-expand_paths(Rt_map *clmp, const char *list, uint_t orig, uint_t omit)
+int
+expand_paths(Rt_map *clmp, const char *list, Alist **alpp, Aliste alni,
+ uint_t orig, uint_t omit)
{
char *str, *olist = 0, *nlist = (char *)list;
- Pnode *pnp, *npnp, *opnp;
int fnull = FALSE; /* TRUE if empty final path segment seen */
- uint_t unique = 0;
+ Pdesc *pdp = NULL;
- for (pnp = opnp = 0, str = nlist; *nlist || fnull; str = nlist) {
+ for (str = nlist; *nlist || fnull; str = nlist) {
char *ostr;
+ char *elist = NULL;
size_t len, olen;
uint_t tkns = 0;
@@ -937,15 +986,16 @@
if (!(orig & (LA_SER_LIBPATH | LA_SER_RUNPATH)))
continue; /* Process next segment */
- if ((str = strdup(MSG_ORIG(MSG_FMT_CWD))) == NULL)
- return (NULL);
+ str = (char *)MSG_ORIG(MSG_FMT_CWD);
len = MSG_FMT_CWD_SIZE;
} else {
- char *elist;
+ uint_t _tkns;
len = 0;
while (*nlist && (*nlist != ':') && (*nlist != ';')) {
+ if (*nlist == '/')
+ tkns |= PD_FLG_PNSLASH;
nlist++, len++;
}
@@ -963,27 +1013,19 @@
elist = nlist;
ostr = str;
olen = len;
- if ((tkns = expand(&str, &len, &elist, orig, omit,
+ if ((_tkns = expand(&str, &len, &elist, orig, omit,
clmp)) == 0)
continue;
-
- if (elist != nlist) {
- if (olist)
- free(olist);
- nlist = olist = elist;
- }
+ tkns |= _tkns;
}
/*
* If this a secure application, validation of the expanded
* path name may be necessary.
*/
- if (rtld_flags & RT_FL_SECURE) {
- if (is_path_secure(str, clmp, orig, tkns) == 0) {
- free(str);
- continue;
- }
- }
+ if ((rtld_flags & RT_FL_SECURE) &&
+ (is_path_secure(str, clmp, orig, tkns) == 0))
+ continue;
/*
* If required, ensure that the string is unique. For search
@@ -993,12 +1035,12 @@
* so that the entry can be diagnosed later as part of unused
* processing.
*/
- if (orig & PN_FLG_UNIQUE) {
+ if (orig & PD_FLG_UNIQUE) {
Word tracing;
tracing = LIST(clmp)->lm_flags &
(LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED);
- unique = is_path_unique(pnp, str);
+ tkns |= is_path_unique(*alpp, str);
/*
* Note, use the debug strings rpl_debug and prm_debug
@@ -1007,51 +1049,138 @@
* LD_LIBRARY_PATH occurs in preparation for loading
* our debugging library.
*/
- if ((unique == PN_FLG_DUPLICAT) && (tracing == 0) &&
- (rpl_debug == 0) && (prm_debug == 0)) {
- free(str);
+ if ((tkns & PD_FLG_DUPLICAT) && (tracing == 0) &&
+ (rpl_debug == 0) && (prm_debug == 0))
continue;
- }
}
/*
- * Allocate a new Pnode for this string.
+ * Create a new pathname descriptor.
*/
- if ((npnp = calloc(1, sizeof (Pnode))) == 0) {
- free(str);
- return (NULL);
- }
- if (opnp == 0)
- pnp = npnp;
- else
- opnp->p_next = npnp;
+ if ((pdp = alist_append(alpp, 0, sizeof (Pdesc), alni)) == NULL)
+ return (0);
- if (tkns & PN_TKN_MASK) {
- char *oname;
+ pdp->pd_pname = str;
+ pdp->pd_plen = len;
+ pdp->pd_flags = (orig & LA_SER_MASK) | (tkns & PD_MSK_INHERIT);
- /*
- * If this is a path name, and any token expansion
- * occurred, maintain the original string for possible
- * diagnostic use.
- */
- if ((oname = malloc(olen + 1)) == 0) {
- free(str);
- return (NULL);
- }
- (void) strncpy(oname, ostr, olen);
- oname[olen] = '\0';
- npnp->p_oname = oname;
+ /*
+ * If token expansion occurred, maintain the original string.
+ * This string can be used to provide a more informative error
+ * diagnostic for a file that fails to load, or for displaying
+ * unused search paths.
+ */
+ if ((tkns & PD_MSK_EXPAND) && ((pdp->pd_oname =
+ stravl_insert(ostr, 0, (olen + 1), 1)) == NULL))
+ return (0);
+
+ /*
+ * Now that any duplication of the original string has occurred,
+ * release any previous old listing.
+ */
+ if (elist && (elist != nlist)) {
+ if (olist)
+ free(olist);
+ nlist = olist = elist;
}
- npnp->p_name = str;
- npnp->p_len = len;
- npnp->p_orig = (orig & LA_SER_MASK) | unique |
- (tkns & PN_TKN_MASK);
-
- opnp = npnp;
}
if (olist)
free(olist);
- return (pnp);
+ /*
+ * If no paths could be determined (perhaps because of security), then
+ * indicate a failure.
+ */
+ return (pdp != NULL);
}
+
+/*
+ * Establish an objects fully resolved path.
+ *
+ * When $ORIGIN was first introduced, the expansion of a relative path name was
+ * deferred until it was required. However now we insure a full path name is
+ * always created - things like the analyzer wish to rely on librtld_db
+ * returning a full path. The overhead of this is perceived to be low,
+ * providing the associated libc version of getcwd is available (see 4336878).
+ * This getcwd() was ported back to Solaris 8.1.
+ */
+size_t
+fullpath(Rt_map *lmp, Fdesc *fdp)
+{
+ const char *name;
+
+ /*
+ * Determine whether this path name is already resolved.
+ */
+ if (fdp && (fdp->fd_flags & FLG_FD_RESOLVED)) {
+ /*
+ * If the resolved path differed from the original name, the
+ * resolved path would have been recorded as the fd_pname.
+ * Steal this path name from the file descriptor. Otherwise,
+ * the path name is the same as the name of this object.
+ */
+ if (fdp->fd_pname)
+ PATHNAME(lmp) = fdp->fd_pname;
+ else
+ PATHNAME(lmp) = NAME(lmp);
+ } else {
+ /*
+ * If this path name has not yet been resolved, resolve the
+ * current name.
+ */
+ char _path[PATH_MAX];
+ const char *path;
+ int size, rsize;
+
+ if (fdp && fdp->fd_pname)
+ PATHNAME(lmp) = fdp->fd_pname;
+ else
+ PATHNAME(lmp) = NAME(lmp);
+
+ name = path = PATHNAME(lmp);
+ size = strlen(name);
+
+ if (path[0] != '/') {
+ /*
+ * If we can't determine the current directory (possible
+ * if too many files are open - EMFILE), or if the
+ * created path is too big, simply revert back to the
+ * initial path name.
+ */
+ if (getcwd(_path, (PATH_MAX - 2 - size)) != NULL) {
+ (void) strcat(_path, MSG_ORIG(MSG_STR_SLASH));
+ (void) strcat(_path, name);
+ path = _path;
+ size = strlen(path);
+ }
+ }
+
+ /*
+ * See if the path name can be reduced further.
+ */
+ if ((rsize = resolvepath(path, _path, (PATH_MAX - 1))) > 0) {
+ _path[rsize] = '\0';
+ path = _path;
+ size = rsize;
+ }
+
+ /*
+ * If the path name is different from the original, duplicate it
+ * so that it is available in a core file. If the duplication
+ * fails simply leave the original path name alone.
+ */
+ if ((PATHNAME(lmp) =
+ stravl_insert(path, 0, (size + 1), 0)) == NULL)
+ PATHNAME(lmp) = name;
+ }
+
+ name = ORIGNAME(lmp) = PATHNAME(lmp);
+
+ /*
+ * Establish the directory name size - this also acts as a flag that the
+ * directory name has been computed.
+ */
+ DIRSZ(lmp) = strrchr(name, '/') - name;
+ return (DIRSZ(lmp));
+}
--- a/usr/src/cmd/sgs/rtld/common/remove.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/remove.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -102,19 +102,22 @@
/*
* Allocate an array for the address range.
*/
- if ((addr = malloc(num * sizeof (Lc_addr_range_t))) == 0)
+ if ((addr = malloc(num * sizeof (Lc_addr_range_t))) == NULL)
return (1);
/*
* Fill the address range with each loadable segments size and address.
*/
for (_tobj = tobj, _addr = addr; *_tobj != NULL; _tobj++) {
- Rt_map *lmp = *_tobj;
- Mmap *mmaps;
+ Rt_map *lmp = *_tobj;
+ mmapobj_result_t *mpp = MMAPS(lmp);
+ uint_t ndx;
- for (mmaps = MMAPS(lmp); mmaps->m_vaddr; mmaps++) {
- _addr->lb = (void *)mmaps->m_vaddr;
- _addr->ub = (void *)(mmaps->m_vaddr + mmaps->m_msize);
+ for (ndx = 0; ndx < MMAPCNT(lmp); ndx++, mpp++) {
+ _addr->lb = (void *)(uintptr_t)(mpp->mr_addr +
+ mpp->mr_offset);
+ _addr->ub = (void *)(uintptr_t)(mpp->mr_addr +
+ mpp->mr_msize);
_addr++;
}
}
@@ -136,40 +139,25 @@
}
/*
- * Remove any rejection message allocations.
- */
-void
-remove_rej(Rej_desc *rej)
-{
- if (rej && (rej->rej_type)) {
- if (rej->rej_name)
- free((void *)rej->rej_name);
- if (rej->rej_str && (rej->rej_str != MSG_ORIG(MSG_EMG_ENOMEM)))
- free((void *)rej->rej_str);
- }
-}
-
-/*
- * Break down a Pnode list.
+ * Break down an Alist containing pathname descriptors. In most instances, the
+ * Alist is cleaned of all entries, but retained for later use.
*/
void
-remove_pnode(Pnode *pnp)
+remove_plist(Alist **alpp, int complete)
{
- Pnode *opnp;
+ Alist *alp = *alpp;
- for (opnp = 0; pnp; opnp = pnp, pnp = pnp->p_next) {
- if (pnp->p_name)
- free((void *)pnp->p_name);
- if (pnp->p_oname)
- free((void *)pnp->p_oname);
- if (opnp)
- free((void *)opnp);
+ if (alp) {
+ if (complete) {
+ free((void *)alp);
+ *alpp = NULL;
+ } else {
+ alp->al_nitems = 0;
+ alp->al_next = ALIST_OFF_DATA;
+ }
}
- if (opnp)
- free((void *)opnp);
}
-
/*
* Remove a link-map list descriptor. This is called to finalize the removal
* of an entire link-map list, after all link-maps have been removed, or none
@@ -277,11 +265,6 @@
return;
/*
- * Unmap the object.
- */
- LM_UNMAP_SO(lmp)(lmp);
-
- /*
* Remove any FullpathNode AVL names if they still exist.
*/
if (FPNODE(lmp))
@@ -290,47 +273,36 @@
/*
* Remove any alias names.
*/
- if (ALIAS(lmp)) {
- Aliste idx;
- char *cp;
-
- for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp))
- free(cp);
+ if (ALIAS(lmp))
free(ALIAS(lmp));
- }
/*
* Remove any of this objects filtee infrastructure. The filtees them-
* selves have already been removed.
*/
- if (((dip = DYNINFO(lmp)) != 0) && (FLAGS1(lmp) & MSK_RT_FILTER)) {
+ if (((dip = DYNINFO(lmp)) != NULL) && (FLAGS1(lmp) & MSK_RT_FILTER)) {
uint_t cnt, max = DYNINFOCNT(lmp);
for (cnt = 0; cnt < max; cnt++, dip++) {
- if (dip->di_info && (dip->di_flags & MSK_DI_FILTER))
- remove_pnode((Pnode *)dip->di_info);
+ if ((dip->di_info == NULL) ||
+ ((dip->di_flags & MSK_DI_FILTER) == 0))
+ continue;
+
+ remove_plist((Alist **)&(dip->di_info), 1);
}
}
- if (dip)
- free(DYNINFO(lmp));
/*
* Deallocate any remaining cruft and free the link-map.
*/
if (RLIST(lmp))
- remove_pnode(RLIST(lmp));
+ remove_plist(&RLIST(lmp), 1);
- if (REFNAME(lmp))
- free(REFNAME(lmp));
- if (ELFPRV(lmp))
- free(ELFPRV(lmp));
if (AUDITORS(lmp))
audit_desc_cleanup(lmp);
if (AUDINFO(lmp))
audit_info_cleanup(lmp);
- if (CONDVAR(lmp))
- free(CONDVAR(lmp));
/*
* Note that COPY_R() and COPY_S() reference the same memory
* location, and that we want to release the memory referenced
@@ -339,8 +311,6 @@
*/
if (COPY_R(lmp))
free(COPY_R(lmp));
- if (MMAPS(lmp))
- free(MMAPS(lmp));
/*
* During a dlclose() any groups this object was a part of will have
@@ -373,11 +343,11 @@
/*
* Clean up reglist if needed
*/
- if (reglist != (Reglist *)0) {
+ if (reglist) {
Reglist *cur, *prv, *del;
cur = prv = reglist;
- while (cur != (Reglist *)0) {
+ while (cur) {
if (cur->rl_lmp == lmp) {
del = cur;
if (cur == reglist) {
@@ -396,27 +366,26 @@
}
/*
- * Finally, free the various names, as these were duplicated so that
- * they were available in core files. This is left until last, to aid
- * debugging previous elements of the removal process.
+ * If this link map represents a relocatable object concatenation, then
+ * the image was simply generated in allocated memory. Free the memory.
+ * Note: memory maps were fabricated for the relocatable object, and
+ * the mapping infrastructure must be free'd, but there are no address
+ * mappings that must be unmapped.
*
- * The original name is set to the pathname by default (see fullpath()),
- * but is overridden if the file is an alternative. The pathname is set
- * to the name by default (see [aout|elf]_new_lm()), but is overridden
- * if the fullpath/resolve path differs (see fullpath()). The original
- * name is always duplicated, as it typically exists as a text string
- * (see DT_NEEDED pointer) or was passed in from user code.
+ * Otherwise, unmap the object.
*/
- if (ORIGNAME(lmp) != PATHNAME(lmp))
- free(ORIGNAME(lmp));
- if (PATHNAME(lmp) != NAME(lmp))
- free(PATHNAME(lmp));
- free(NAME(lmp));
+ if (FLAGS(lmp) & FLG_RT_IMGALLOC)
+ free((void *)ADDR(lmp));
+
+ if (MMAPS(lmp)) {
+ if ((FLAGS(lmp) & FLG_RT_IMGALLOC) == 0)
+ unmap_obj(MMAPS(lmp), MMAPCNT(lmp));
+ free(MMAPS(lmp));
+ }
free(lmp);
}
-
/*
* Traverse an objects dependency list removing callers and dependencies.
* There's a chicken and egg problem with tearing down link-maps. Any
@@ -426,7 +395,7 @@
* removed. Thus, lists between link-maps must be broken down before the
* individual link-maps themselves.
*/
-void
+static void
remove_lists(Rt_map *lmp, int lazy)
{
Aliste idx1;
@@ -517,7 +486,7 @@
* one of its dependencies can't be relocated, then tear down any objects
* that are apart of this link-map control list.
*/
-void
+static void
remove_incomplete(Lm_list *lml, Aliste lmco)
{
Rt_map *lmp;
@@ -603,7 +572,7 @@
static int
gdp_collect(APlist **ghalpp, APlist **lmalpp, Grp_hdl *ghp1)
{
- Aliste idx;
+ Aliste idx1;
Grp_desc *gdp;
int action;
@@ -619,7 +588,7 @@
* Traverse the dependencies of the group and collect the associated
* objects.
*/
- for (ALIST_TRAVERSE(ghp1->gh_depends, idx, gdp)) {
+ for (ALIST_TRAVERSE(ghp1->gh_depends, idx1, gdp)) {
Rt_map *lmp = gdp->gd_depend;
/*
@@ -660,18 +629,19 @@
uint_t cnt, max = DYNINFOCNT(lmp);
for (cnt = 0; cnt < max; cnt++, dip++) {
- Pnode *pnp;
+ Alist *falp;
+ Aliste idx2;
+ Pdesc *pdp;
- if ((dip->di_info == 0) ||
+ if (((falp = (Alist *)dip->di_info) == NULL) ||
((dip->di_flags & MSK_DI_FILTER) == 0))
continue;
- for (pnp = (Pnode *)dip->di_info; pnp;
- pnp = pnp->p_next) {
+ for (ALIST_TRAVERSE(falp, idx2, pdp)) {
Grp_hdl *ghp2;
- if ((pnp->p_len == 0) || ((ghp2 =
- (Grp_hdl *)pnp->p_info) == 0))
+ if ((pdp->pd_plen == 0) || ((ghp2 =
+ (Grp_hdl *)pdp->pd_info) == NULL))
continue;
if (gdp_collect(ghalpp, lmalpp,
@@ -732,26 +702,27 @@
max = DYNINFOCNT(lmp);
for (cnt = 0; cnt < max; cnt++, dip++) {
- Pnode *pnp;
+ Alist *falp;
+ Pdesc *pdp;
- if ((dip->di_info == 0) ||
+ if (((falp = (Alist *)dip->di_info) == NULL) ||
((dip->di_flags & MSK_DI_FILTER) == 0))
continue;
- for (pnp = (Pnode *)dip->di_info; pnp;
- pnp = pnp->p_next) {
+ for (ALIST_TRAVERSE(falp, idx2, pdp)) {
+ Aliste idx3;
Grp_hdl *ghp;
Grp_desc *gdp;
- if ((pnp->p_len == 0) ||
- ((ghp = (Grp_hdl *)pnp->p_info) == 0))
+ if ((pdp->pd_plen == 0) ||
+ ((ghp = (Grp_hdl *)pdp->pd_info) == NULL))
continue;
if (aplist_test(&ghalp, ghp, 0) ==
ALE_EXISTS)
continue;
- for (ALIST_TRAVERSE(ghp->gh_depends, idx2,
+ for (ALIST_TRAVERSE(ghp->gh_depends, idx3,
gdp)) {
Rt_map *dlmp = gdp->gd_depend;
@@ -814,7 +785,7 @@
/* LINTED */
ndx = (uintptr_t)ghp % HDLIST_SZ;
- list_delete(&hdl_list[ndx], ghp);
+ (void) aplist_delete_value(hdl_alp[ndx], ghp);
(void) free(ghp);
@@ -950,16 +921,17 @@
uint_t cnt, max = DYNINFOCNT(lmp);
for (cnt = 0; cnt < max; cnt++, dip++) {
- Pnode *pnp;
+ Alist *falp;
+ Aliste idx2;
+ Pdesc *pdp;
- if ((dip->di_info == 0) ||
+ if (((falp = (Alist *)dip->di_info) == NULL) ||
((dip->di_flags & MSK_DI_FILTER) == 0))
continue;
- for (pnp = (Pnode *)dip->di_info; pnp;
- pnp = pnp->p_next) {
- if ((Grp_hdl *)pnp->p_info == ghp) {
- pnp->p_info = 0;
+ for (ALIST_TRAVERSE(falp, idx2, pdp)) {
+ if ((Grp_hdl *)pdp->pd_info == ghp) {
+ pdp->pd_info = 0;
break;
}
}
@@ -1318,7 +1290,7 @@
* If we're being audited tell the audit library that we're
* about to go deleting dependencies.
*/
- if (clmp && ((LIST(clmp)->lm_tflags | FLAGS1(clmp)) &
+ if (clmp && ((LIST(clmp)->lm_tflags | AFLAGS(clmp)) &
LML_TFLG_AUD_ACTIVITY))
audit_activity(clmp, LA_ACT_DELETE);
@@ -1353,7 +1325,7 @@
if (clmp && dlmp &&
((LIST(dlmp)->lm_flags & LML_FLG_NOAUDIT) == 0) &&
- (FLAGS1(clmp) & LML_TFLG_AUD_OBJCLOSE))
+ (AFLAGS(clmp) & LML_TFLG_AUD_OBJCLOSE))
_audit_objclose(&(AUDITORS(clmp)->ad_list),
dlmp);
}
@@ -1382,18 +1354,19 @@
max = DYNINFOCNT(lmp);
for (cnt = 0; cnt < max; cnt++, dip++) {
- Pnode *pnp;
+ Alist *falp;
+ Aliste idx2;
+ Pdesc *pdp;
- if ((dip->di_info == 0) ||
+ if (((falp = (Alist *)dip->di_info) == NULL) ||
((dip->di_flags & MSK_DI_FILTER) == 0))
continue;
- for (pnp = (Pnode *)dip->di_info; pnp;
- pnp = pnp->p_next) {
+ for (ALIST_TRAVERSE(falp, idx2, pdp)) {
Grp_hdl *ghp;
- if ((pnp->p_len == 0) ||
- ((ghp = (Grp_hdl *)pnp->p_info) == 0))
+ if ((pdp->pd_plen == 0) ||
+ ((ghp = (Grp_hdl *)pdp->pd_info) == NULL))
continue;
/*
@@ -1408,7 +1381,7 @@
* deleted, sever its reference to the
* handle.
*/
- pnp->p_info = 0;
+ pdp->pd_info = NULL;
} else {
/*
* If this handle isn't on the deletion
@@ -1432,7 +1405,7 @@
* If called from dlclose(), determine if there are already handles on
* the orphans list that we can reinvestigate.
*/
- if ((removed == 0) && hdl_list[HDLIST_ORP].head)
+ if ((removed == 0) && aplist_nitems(hdl_alp[HDLIST_ORP]))
orphans = 1;
else
orphans = 0;
@@ -1453,7 +1426,7 @@
/* LINTED */
ndx = (uintptr_t)ghp % HDLIST_SZ;
- list_delete(&hdl_list[ndx], ghp);
+ (void) aplist_delete_value(hdl_alp[ndx], ghp);
}
/*
@@ -1519,7 +1492,8 @@
/*
* Move this handle to the orphans list.
*/
- (void) list_append(&hdl_list[HDLIST_ORP], ghp);
+ (void) aplist_append(&hdl_alp[HDLIST_ORP], ghp,
+ AL_CNT_HANDLES);
if (DBG_ENABLED) {
DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ORPHAN));
@@ -1559,8 +1533,8 @@
* handle removals occur.
*/
do {
- List list;
- Listnode *lnp;
+ APlist *alp;
+ Aliste idx;
Grp_hdl *ghp, *oghp = 0;
int title = 0;
@@ -1568,18 +1542,18 @@
* Effectively clean the HDLIST_ORP list. Any object that can't
* be removed will be re-added to the list.
*/
- list = hdl_list[HDLIST_ORP];
- hdl_list[HDLIST_ORP].head = hdl_list[HDLIST_ORP].tail = 0;
+ alp = hdl_alp[HDLIST_ORP];
+ hdl_alp[HDLIST_ORP] = NULL;
rescan = 0;
- for (LIST_TRAVERSE(&list, lnp, ghp)) {
+ for (APLIST_TRAVERSE(alp, idx, ghp)) {
int _error, _remove;
if (title++ == 0)
DBG_CALL(Dbg_file_del_rescan(ghp->gh_ownlml));
if (oghp) {
- list_delete(&list, oghp);
+ (void) aplist_delete_value(alp, oghp);
oghp = 0;
}
@@ -1593,11 +1567,13 @@
oghp = ghp;
}
if (oghp) {
- list_delete(&list, oghp);
+ (void) aplist_delete_value(alp, oghp);
oghp = 0;
}
+ if (alp)
+ free((void *)alp);
- } while (rescan && hdl_list[HDLIST_ORP].head);
+ } while (rescan && aplist_nitems(hdl_alp[HDLIST_ORP]));
return (error);
}
--- a/usr/src/cmd/sgs/rtld/common/rtld.msg Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/rtld.msg Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -70,16 +70,10 @@
@ MSG_GEN_NOFILE "%s: can't find file"
@ MSG_GEN_ALTER "%s: alternate file in use"
-@ MSG_GEN_CORTRUNC "%s: corrupt or truncated file"
@ MSG_GEN_NOSYM "%s: can't find symbol"
-@ MSG_GEN_BADTYPE "%s: bad ELF type: %s"
-@ MSG_GEN_INVPRGHDR "%s: invalid ELF program header, segments out of order"
-@ MSG_GEN_NOLOADSEG "%s: no loadable ELF segments found"
-@ MSG_GEN_MAPINUSE "%s: required mapping 0x%llx size 0x%llx, \
- is already in use by file %s"
@ MSG_GEN_NODUMP "%s: DF_1_NODUMP tagged object may not be dldump()'ed"
-@ MSG_GEN_AUDITERM "%s: auditing terminated search"
@ MSG_GEN_BADHWCAP_1 "hardware capability unsupported: %s"
+@ MSG_GEN_BADSFCAP_1 "software capability unsupported: %s"
# Move related messages
@@ -106,9 +100,8 @@
@ MSG_SYS_BRK "%s: brk failed: %s"
@ MSG_SYS_OPEN "%s: open failed: %s"
@ MSG_SYS_MMAP "%s: mmap failed: %s"
-@ MSG_SYS_MMAPANON "%s: mmap anon failed: %s"
@ MSG_SYS_MPROT "%s: mprotect failed: %s"
-@ MSG_SYS_PROC "%s: /proc error: %s"
+@ MSG_SYS_MMAPANON "mmap anon failed: %s"
@ MSG_SEC_OPEN "%s: open failed: No such file in secure directories"
@ MSG_SEC_ILLEGAL "%s: open failed: illegal insecure pathname"
@@ -166,6 +159,8 @@
lies outside memory image; relocation discarded\n"
@ MSG_LDD_REL_ERR2 "\tloading after relocation has started: interposition \
request (DF_1_INTERPOSE) ignored: %s\n"
+@ MSG_LDD_MOVE_ERR "\tmove %lld offset invalid: %s: offset=0x%llx \
+ lies outside memory image; move discarded\n"
@ MSG_LDD_CPY_SIZDIF "\trelocation %s sizes differ: %s\n\
\t\t(file %s size=0x%llx; file %s size=0x%llx)\n"
@ MSG_LDD_CPY_INSDATA "\t\t%s size used; possible insufficient data copied\n"
@@ -266,7 +261,6 @@
@ MSG_LDD_VER_FOUND "\t%s (%s) =>\t %s\n"
-
# The following strings represent reserved words, files, pathnames and symbols.
# Reference to this strings is via the MSG_ORIG() macro, and thus no message
# translation is required.
@@ -296,10 +290,7 @@
@ MSG_TKN_POSIX "POSIX"
@ MSG_TKN_DOTDOT ".."
-@ MSG_FMT_PATH "%s/%s"
@ MSG_FMT_CWD "."
-@ MSG_FMT_PARENT "/.."
-@ MSG_FMT_PROC "/proc/%d"
@ MSG_FMT_MSGFILE "/usr/lib/locale/%s/LC_MESSAGES/%s.mo"
@ MSG_FIL_RTLD "ld.so.1"
@@ -332,7 +323,6 @@
@ MSG_PTH_LIBSE "/lib/secure"
@ MSG_PTH_USRLIBSE "/usr/lib/secure"
@ MSG_PTH_DEVNULL "/dev/null"
-@ MSG_PTH_DEVZERO "/dev/zero"
@ MSG_PTH_CONFIG "/var/ld/ld.config"
@ MSG_PTH_VARTMP "/var/tmp"
@@ -344,8 +334,6 @@
@ MSG_LD_BIND_NOW "BIND_NOW"
@ MSG_LD_BIND_NOT "BIND_NOT"
@ MSG_LD_BINDINGS "BINDINGS"
-@ MSG_LD_BREADTH "BREADTH"
-@ MSG_LD_CONCURRENCY "CONCURRENCY"
@ MSG_LD_CONFGEN "CONFGEN"
@ MSG_LD_CONFIG "CONFIG"
@ MSG_LD_DEBUG "DEBUG"
@@ -369,7 +357,6 @@
@ MSG_LD_NOPAREXT "NOPAREXT"
@ MSG_LD_NOUNRESWEAK "NOUNRESWEAK"
@ MSG_LD_NOVERSION "NOVERSION"
-@ MSG_LD_ORIGIN "ORIGIN"
@ MSG_LD_PRELOAD "PRELOAD"
@ MSG_LD_PROFILE "PROFILE"
@ MSG_LD_PROFILE_OUTPUT "PROFILE_OUTPUT"
@@ -385,8 +372,6 @@
@ MSG_LD_BRAND_PREFIX "BRAND_"
-@ MSG_LD_FIX_1 "_FIX_1_"
-
@ MSG_LC_ALL "ALL="
@ MSG_LC_MESSAGES "MESSAGES="
--- a/usr/src/cmd/sgs/rtld/common/rtld.sparc32.msg Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/rtld.sparc32.msg Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -35,6 +35,8 @@
@ MSG_GEN_OLDREV "%s: has older revision than expected %s"
+@ MSG_SYS_PROC "/proc error: %s"
+
@ _END_
@ MSG_STR_AOUT "AOUT"
@@ -49,3 +51,6 @@
@ MSG_PTH_USR4LIB "/usr/4lib"
@ MSG_SYM_LAV8PLTENTER "la_sparcv8_pltenter"
+
+@ MSG_FMT_PROC "/proc/%d"
+
--- a/usr/src/cmd/sgs/rtld/common/setup.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/setup.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -73,10 +73,10 @@
*/
static Interp _interp;
-
static int
preload(const char *str, Rt_map *lmp)
{
+ Alist *palp = NULL;
Rt_map *clmp = lmp;
char *objs, *ptr, *next;
Word lmflags = lml_main.lm_flags;
@@ -84,7 +84,7 @@
DBG_CALL(Dbg_util_nl(&lml_main, DBG_NL_STD));
- if ((objs = strdup(str)) == 0)
+ if ((objs = strdup(str)) == NULL)
return (0);
/*
@@ -100,8 +100,7 @@
ptr = strtok_r(objs, MSG_ORIG(MSG_STR_DELIMIT), &next);
do {
- Pnode *pnp;
- Rt_map *nlmp = 0;
+ Rt_map *nlmp = NULL;
DBG_CALL(Dbg_file_preload(&lml_main, ptr));
@@ -111,15 +110,15 @@
*/
if (rtld_flags & RT_FL_SECURE)
rtld_flags2 |= RT_FL2_FTL2WARN;
- if ((pnp = expand_paths(clmp, ptr, PN_FLG_EXTLOAD, 0)) != 0)
- nlmp = load_one(&lml_main, ALIST_OFF_DATA, pnp, clmp,
+ if (expand_paths(clmp, ptr, &palp, AL_CNT_NEEDED,
+ PD_FLG_EXTLOAD, 0) != 0)
+ nlmp = load_one(&lml_main, ALIST_OFF_DATA, palp, clmp,
MODE(lmp), flags, 0, NULL);
- if (pnp)
- remove_pnode(pnp);
+ remove_plist(&palp, 0);
if (rtld_flags & RT_FL_SECURE)
rtld_flags2 &= ~RT_FL2_FTL2WARN;
if (nlmp && (bind_one(clmp, nlmp, BND_NEEDED) == 0))
- nlmp = 0;
+ nlmp = NULL;
/*
* Establish state for the next preloadable object. If no
@@ -127,7 +126,7 @@
* link-map list contains an interposer.
*/
flags |= FLG_RT_OBJINTPO;
- if (nlmp == 0) {
+ if (nlmp == NULL) {
if ((lmflags & LML_FLG_TRC_ENABLE) ||
(rtld_flags & RT_FL_SECURE))
continue;
@@ -157,25 +156,27 @@
} while ((ptr = strtok_r(NULL,
MSG_ORIG(MSG_STR_DELIMIT), &next)) != NULL);
+ free(palp);
free(objs);
return (1);
}
Rt_map *
setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
- char *_rtldname, Dyn *dyn_ptr, ulong_t ld_base, ulong_t interp_base, int fd,
- Phdr *phdr, char *execname, char **argv, int dz_fd, uid_t uid,
- uid_t euid, gid_t gid, gid_t egid, void *aoutdyn, int auxflags,
- uint_t hwcap_1)
+ char *_rtldname, ulong_t ld_base, ulong_t interp_base, int fd, Phdr *phdr,
+ char *execname, char **argv, uid_t uid, uid_t euid, gid_t gid, gid_t egid,
+ void *aoutdyn, int auxflags, uint_t hwcap_1)
{
- Rt_map *rlmp, *mlmp, **tobj = 0;
- Ehdr *ehdr;
- rtld_stat_t status;
- int features = 0, ldsoexec = 0;
- size_t eaddr, esize;
- char *str, *argvname;
- Mmap *mmaps;
- Word lmflags;
+ Rt_map *rlmp, *mlmp, **tobj = NULL;
+ Ehdr *ehdr;
+ rtld_stat_t status;
+ int features = 0, ldsoexec = 0;
+ size_t eaddr, esize;
+ char *str, *argvname;
+ Word lmflags;
+ mmapobj_result_t *mpp;
+ Fdesc fdr = { 0 }, fdm = { 0 };
+ Rej_desc rej = { 0 };
/*
* Now that ld.so has relocated itself, initialize our own 'environ' so
@@ -187,26 +188,9 @@
_environ = envp;
/*
- * Far the most common application execution revolves around appending
- * the application name to the users PATH definition, thus a full name
- * is passed to exec() which will in turn be returned via
- * AT_SUN_EXECNAME. Applications may also be invoked from the current
- * working directory, or via a relative name.
- *
- * Determine whether the kernel has supplied a AT_SUN_EXECNAME aux
- * vector. This vector points to the full pathname, on the stack, of
- * the object that started the process. If this is null, then
- * AT_SUN_EXECNAME isn't supported (if the pathname exceeded the system
- * limit (PATH_MAX) the exec would have failed). This flag is used to
- * determine whether we can call resolvepath().
- */
- if (execname)
- rtld_flags |= RT_FL_EXECNAME;
-
- /*
* Determine how ld.so.1 has been executed.
*/
- if ((fd == -1) && (phdr == 0)) {
+ if ((fd == -1) && (phdr == NULL)) {
/*
* If we received neither the AT_EXECFD nor the AT_PHDR aux
* vector, ld.so.1 must have been invoked directly from the
@@ -241,7 +225,7 @@
argvname = execname = (char *)MSG_INTL(MSG_STR_UNKNOWN);
if (fd == -1) {
- if ((str = strrchr(argvname, '/')) != 0)
+ if ((str = strrchr(argvname, '/')) != NULL)
procname = ++str;
else
procname = argvname;
@@ -255,7 +239,7 @@
* runtime linkers name once the application is analyzed.
*/
if (_rtldname) {
- if ((str = strrchr(_rtldname, '/')) != 0)
+ if ((str = strrchr(_rtldname, '/')) != NULL)
rtldname = ++str;
else
rtldname = _rtldname;
@@ -267,8 +251,6 @@
* Initialize any global variables.
*/
at_flags = _flags;
- if (dz_fd != FD_UNAVAIL)
- dz_init(dz_fd);
platform = _platform;
/*
@@ -276,7 +258,6 @@
*/
if ((syspagsz = _syspagsz) == 0)
syspagsz = _sysconfig(_CONFIG_PAGESIZE);
- fmap_setup();
/*
* Add the unused portion of the last data page to the free space list.
@@ -297,14 +278,14 @@
* Establish initial link-map list flags, and link-map list alists.
*/
if (alist_append(&lml_main.lm_lists, 0, sizeof (Lm_cntl),
- AL_CNT_LMLISTS) == 0)
+ AL_CNT_LMLISTS) == NULL)
return (0);
lml_main.lm_flags |= LML_FLG_BASELM;
lml_main.lm_lmid = LM_ID_BASE;
lml_main.lm_lmidstr = (char *)MSG_ORIG(MSG_LMID_BASE);
if (alist_append(&lml_rtld.lm_lists, 0, sizeof (Lm_cntl),
- AL_CNT_LMLISTS) == 0)
+ AL_CNT_LMLISTS) == NULL)
return (0);
lml_rtld.lm_flags |= (LML_FLG_RTLDLM | LML_FLG_NOAUDIT |
LML_FLG_HOLDLOCK);
@@ -320,12 +301,11 @@
* Initialize a hardware capability descriptor for use in comparing
* each loaded object.
*/
-#ifdef AT_SUN_AUXFLAGS
if (auxflags & AF_SUN_HWCAPVERIFY) {
rtld_flags2 |= RT_FL2_HWCAP;
hwcap = (ulong_t)hwcap_1;
}
-#endif
+
/*
* Look for environment strings (allows things like LD_NOAUDIT to be
* established, although debugging isn't enabled until later).
@@ -338,25 +318,30 @@
* Create a mapping descriptor for ld.so.1. We can determine our
* two segments information from known symbols.
*/
- if ((mmaps = calloc(3, sizeof (Mmap))) == 0)
+ if ((mpp = calloc(2, sizeof (mmapobj_result_t))) == NULL)
return (0);
- mmaps[0].m_vaddr = (caddr_t)M_PTRUNC(ld_base);
- mmaps[0].m_msize = (size_t)((caddr_t)&_etext - mmaps[0].m_vaddr);
- mmaps[0].m_fsize = mmaps[0].m_msize;
- mmaps[0].m_perm = (PROT_READ | PROT_EXEC);
- mmaps[1].m_vaddr = (caddr_t)M_PTRUNC((ulong_t)&r_debug);
- mmaps[1].m_msize = (size_t)((caddr_t)&_end - mmaps[1].m_vaddr);
- mmaps[1].m_fsize = (size_t)((caddr_t)&_edata - mmaps[1].m_vaddr);
- mmaps[1].m_perm = (PROT_READ | PROT_WRITE | PROT_EXEC);
+ mpp[0].mr_addr = (caddr_t)M_PTRUNC(ld_base);
+ mpp[0].mr_msize = (caddr_t)&_etext - mpp[0].mr_addr;
+ mpp[0].mr_fsize = mpp[0].mr_msize;
+ mpp[0].mr_prot = (PROT_READ | PROT_EXEC);
+
+ mpp[1].mr_addr = (caddr_t)M_PTRUNC((uintptr_t)&r_debug);
+ mpp[1].mr_msize = (caddr_t)&_end - mpp[1].mr_addr;
+ mpp[1].mr_fsize = (caddr_t)&_edata - mpp[1].mr_addr;
+ mpp[1].mr_prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
- /*
- * Create a link map structure for ld.so.1.
- */
- if ((rlmp = elf_new_lm(&lml_rtld, _rtldname, rtldname, dyn_ptr, ld_base,
- (ulong_t)&_etext, ALIST_OFF_DATA, (ulong_t)(eaddr - ld_base), 0,
- ld_base, (ulong_t)(eaddr - ld_base), mmaps, 2, NULL)) == 0) {
+ if ((fdr.fd_nname = stravl_insert(_rtldname, 0, 0, 0)) == NULL)
+ return (0);
+ if ((rlmp = elf_new_lmp(&lml_rtld, ALIST_OFF_DATA, &fdr,
+ (Addr)mpp->mr_addr, (size_t)((uintptr_t)eaddr - (uintptr_t)ld_base),
+ NULL, NULL)) == NULL)
return (0);
- }
+
+ MMAPS(rlmp) = mpp;
+ MMAPCNT(rlmp) = 2;
+ PADSTART(rlmp) = (ulong_t)mpp[0].mr_addr;
+ PADIMLEN(rlmp) = (ulong_t)mpp[0].mr_addr + (ulong_t)mpp[1].mr_addr +
+ (ulong_t)mpp[1].mr_msize;
MODE(rlmp) |= (RTLD_LAZY | RTLD_NODELETE | RTLD_GLOBAL | RTLD_WORLD);
FLAGS(rlmp) |= (FLG_RT_ANALYZED | FLG_RT_RELOCED | FLG_RT_INITDONE |
@@ -366,7 +351,7 @@
* Initialize the runtime linkers information.
*/
interp = &_interp;
- interp->i_name = NAME(rlmp);
+ interp->i_name = (char *)rtldname;
interp->i_faddr = (caddr_t)ADDR(rlmp);
ldso_plt_init(rlmp);
@@ -401,18 +386,21 @@
}
/*
- * Map in the file, if exec has not already done so. If it has,
- * simply create a new link map structure for the executable.
+ * Map in the file, if exec has not already done so, or if the file
+ * was passed as an argument to an explicit execution of ld.so.1 from
+ * the command line.
*/
if (fd != -1) {
- Rej_desc rej;
- Fct *ftp;
-
/*
- * Find out what type of object we have.
+ * Map the file. Once the object is mapped we no longer need
+ * the file descriptor.
*/
(void) rtld_fstat(fd, &status);
- if ((ftp = are_u_this(&rej, fd, &status, argvname)) == 0) {
+ fdm.fd_ftp = map_obj(&lml_main, &fdm, status.st_size, argvname,
+ fd, &rej);
+ (void) close(fd);
+
+ if (fdm.fd_ftp == NULL) {
Conv_reject_desc_buf_t rej_buf;
eprintf(&lml_main, ERR_FATAL,
@@ -422,22 +410,29 @@
}
/*
- * Map in object.
+ * Finish processing the loading of the file.
*/
- if ((mlmp = (ftp->fct_map_so)(&lml_main, ALIST_OFF_DATA,
- execname, argvname, fd, NULL)) == 0)
+ if ((fdm.fd_nname = stravl_insert(argvname, 0, 0, 0)) == NULL)
+ return (0);
+ fdm.fd_dev = status.st_dev;
+ fdm.fd_ino = status.st_ino;
+
+ if ((mlmp = load_file(&lml_main, ALIST_OFF_DATA, &fdm,
+ NULL)) == NULL)
return (0);
/*
* We now have a process name for error diagnostics.
*/
- if ((str = strrchr(argvname, '/')) != 0)
+ if ((str = strrchr(argvname, '/')) != NULL)
procname = ++str;
else
procname = argvname;
if (ldsoexec) {
- Addr brkbase = 0;
+ mmapobj_result_t *mpp = MMAPS(mlmp);
+ uint_t mnum, mapnum = MMAPCNT(mlmp);
+ void *brkbase = NULL;
/*
* Since ld.so.1 was the primary executed object - the
@@ -446,43 +441,21 @@
* the end of the object. For a shared object (ET_DYN)
* initialize it to the first page in memory.
*/
- ehdr = (Ehdr *)ADDR(mlmp);
-
- if ((FCT(mlmp) == &elf_fct) &&
- (ehdr->e_type == ET_EXEC)) {
- int i;
- Phdr *_phdr = (Phdr *)((uintptr_t)ADDR(mlmp) +
- ehdr->e_phoff);
+ for (mnum = 0; mnum < mapnum; mnum++, mpp++)
+ brkbase = mpp->mr_addr + mpp->mr_msize;
- /*
- * We scan the program headers to find the tail
- * of the memory image. We can't use MSIZE()
- * since that's already been page aligned.
- */
- for (i = 0; i < ehdr->e_phnum; i++, _phdr++) {
- if (_phdr->p_type == PT_LOAD)
- brkbase = _phdr->p_vaddr +
- _phdr->p_memsz;
- }
- }
+ if (brkbase == NULL)
+ brkbase = (void *)syspagsz;
- if (!brkbase)
- brkbase = syspagsz;
+ if (_brk_unlocked(brkbase) == -1) {
+ int err = errno;
- if (_brk_unlocked((void *)brkbase) == -1) {
- int err = errno;
eprintf(&lml_main, ERR_FATAL,
MSG_INTL(MSG_SYS_BRK), argvname,
strerror(err));
+ return (0);
}
}
-
- /*
- * The object has now been mmaped, we no longer need the file
- * descriptor.
- */
- (void) close(fd);
-
} else {
/*
* Set up function ptr and arguments according to the type
@@ -492,21 +465,40 @@
*/
if (aoutdyn) {
#ifdef A_OUT
- if ((mlmp = aout_new_lm(&lml_main, execname, argvname,
- aoutdyn, 0, 0, ALIST_OFF_DATA)) == 0)
+ mmapobj_result_t *mpp;
+
+ /*
+ * Create a mapping structure sufficient to describe
+ * a single two segments. The ADDR() of the a.out is
+ * established as 0, which is required but the AOUT
+ * relocation code.
+ */
+ if ((mpp =
+ calloc(sizeof (mmapobj_result_t), 2)) == NULL)
+ return (0);
+
+ if ((fdm.fd_nname =
+ stravl_insert(execname, 0, 0, 0)) == NULL)
+ return (0);
+ if ((mlmp = aout_new_lmp(&lml_main, ALIST_OFF_DATA,
+ &fdm, 0, 0, aoutdyn, NULL)) == NULL)
return (0);
/*
- * Set the memory size. Note, we only know the end of
- * text, and although we could find the _end by looking
- * up the symbol, this may not be present. We should
- * set ADDR to MAIN_BASE, but presently all the a.out
- * relocation code assumes ADDR is 0 for the dynamic
- * executable. (these data items are only used for
- * dladdr(3x), and there aren't many a.out dladdr(3x)
- * users to warrant spending much time on this :-).
+ * Establish the true mapping information for the a.out.
*/
- MSIZE(mlmp) = MAIN_BASE + ETEXT(mlmp);
+ if (aout_get_mmap(&lml_main, mpp)) {
+ free(mpp);
+ return (0);
+ }
+
+ MSIZE(mlmp) =
+ (size_t)(mpp[1].mr_addr + mpp[1].mr_msize) -
+ S_ALIGN((size_t)mpp[0].mr_addr, syspagsz);
+ MMAPS(mlmp) = mpp;
+ MMAPCNT(mlmp) = 2;
+ PADSTART(mlmp) = (ulong_t)mpp->mr_addr;
+ PADIMLEN(mlmp) = mpp->mr_msize;
/*
* Disable any object configuration cache (BCP apps
@@ -526,15 +518,14 @@
return (0);
#endif
} else if (phdr) {
- Phdr *pptr, *firstptr = 0, *lastptr;
- Phdr *tlsphdr = 0, *unwindphdr = 0;
- Dyn *dyn = 0;
- Cap *cap = 0;
- Off i_offset = 0;
- Addr base = 0;
- ulong_t memsize, phsize, entry, etext;
- uint_t mmapcnt = 0;
- int i;
+ Phdr *pptr;
+ Off i_offset = 0;
+ Addr base = 0;
+ ulong_t phsize;
+ mmapobj_result_t *mpp, *fmpp, *hmpp = NULL;
+ uint_t mapnum = 0;
+ int i;
+ size_t msize;
/*
* Using the executables phdr address determine the base
@@ -560,7 +551,8 @@
* Allocate a mapping array to retain mapped segment
* information.
*/
- if ((mmaps = calloc(ehdr->e_phnum, sizeof (Mmap))) == 0)
+ if ((fmpp = mpp = calloc(ehdr->e_phnum,
+ sizeof (mmapobj_result_t))) == NULL)
return (0);
/*
@@ -578,9 +570,6 @@
int perm = (PROT_READ | PROT_EXEC);
size_t off;
- if (!firstptr)
- firstptr = pptr;
- lastptr = pptr;
if (i_offset && pptr->p_filesz &&
(i_offset >= pptr->p_offset) &&
(i_offset <=
@@ -590,11 +579,8 @@
pptr->p_offset + base;
i_offset = 0;
}
- if ((pptr->p_flags &
- (PF_R | PF_W)) == PF_R)
- etext = pptr->p_vaddr +
- pptr->p_memsz + base;
- else
+
+ if (pptr->p_flags & PF_W)
perm |= PROT_WRITE;
/*
@@ -604,77 +590,70 @@
* for mprotect() if required.
*/
off = pptr->p_vaddr + base;
- mmaps[mmapcnt].m_vaddr =
- (caddr_t)M_PTRUNC(off);
- off -= (size_t)mmaps[mmapcnt].m_vaddr;
- mmaps[mmapcnt].m_msize =
- pptr->p_memsz + off;
- mmaps[mmapcnt].m_fsize =
- pptr->p_filesz + off;
- mmaps[mmapcnt].m_perm = perm;
- mmapcnt++;
+ if (hmpp == NULL) {
+ hmpp = mpp;
+ mpp->mr_addr = (caddr_t)ehdr;
+ } else
+ mpp->mr_addr = (caddr_t)off;
- } else if (pptr->p_type == PT_DYNAMIC) {
- dyn = (Dyn *)(pptr->p_vaddr + base);
- } else if ((pptr->p_type == PT_TLS) &&
- pptr->p_memsz) {
- tlsphdr = pptr;
- } else if (pptr->p_type == PT_SUNW_UNWIND) {
- unwindphdr = pptr;
- } else if (pptr->p_type == PT_SUNWCAP) {
- cap = (Cap *)(pptr->p_vaddr + base);
+ off -= (size_t)(uintptr_t)mpp->mr_addr;
+ mpp->mr_msize = pptr->p_memsz + off;
+ mpp->mr_fsize = pptr->p_filesz + off;
+ mpp->mr_prot = perm;
+
+ mpp++, mapnum++;
}
+
pptr = (Phdr *)((ulong_t)pptr + phsize);
}
-
- memsize = (lastptr->p_vaddr + lastptr->p_memsz) -
- S_ALIGN(firstptr->p_vaddr, syspagsz);
-
- entry = ehdr->e_entry;
- if (ehdr->e_type == ET_DYN)
- entry += (ulong_t)ehdr;
+ mpp--;
+ msize = (size_t)(mpp->mr_addr + mpp->mr_msize) -
+ S_ALIGN((size_t)fmpp->mr_addr, syspagsz);
- if ((mlmp = elf_new_lm(&lml_main, execname, argvname,
- dyn, (Addr)ehdr, etext, ALIST_OFF_DATA, memsize,
- entry, (ulong_t)ehdr, memsize, mmaps,
- mmapcnt, NULL)) == 0) {
+ if ((fdm.fd_nname =
+ stravl_insert(execname, 0, 0, 0)) == NULL)
return (0);
- }
- if (tlsphdr &&
- (tls_assign(&lml_main, mlmp, tlsphdr) == 0))
+ if ((mlmp = elf_new_lmp(&lml_main, ALIST_OFF_DATA, &fdm,
+ (Addr)hmpp->mr_addr, msize, NULL, NULL)) == NULL)
return (0);
- if (unwindphdr)
- PTUNWIND(mlmp) = unwindphdr;
-
- if (cap)
- cap_assign(cap, mlmp);
+ MMAPS(mlmp) = fmpp;
+ MMAPCNT(mlmp) = mapnum;
+ PADSTART(mlmp) = (ulong_t)fmpp->mr_addr;
+ PADIMLEN(mlmp) = (ulong_t)fmpp->mr_addr +
+ (ulong_t)mpp->mr_addr + (ulong_t)mpp->mr_msize;
}
}
/*
* Establish the interpretors name as that defined within the initial
* object (executable). This provides for ORIGIN processing of ld.so.1
- * dependencies.
+ * dependencies. Note, the NAME() of the object remains that which was
+ * passed to us as the SONAME on execution.
*/
if (ldsoexec == 0) {
size_t len = strlen(interp->i_name);
- (void) expand(&interp->i_name, &len, 0, 0,
- (PN_TKN_ISALIST | PN_TKN_HWCAP), rlmp);
- }
- PATHNAME(rlmp) = interp->i_name;
- if (FLAGS1(rlmp) & FL1_RT_RELATIVE)
- (void) fullpath(rlmp, 0);
- else
- ORIGNAME(rlmp) = PATHNAME(rlmp) = NAME(rlmp);
+ if (expand(&interp->i_name, &len, 0, 0,
+ (PD_TKN_ISALIST | PD_TKN_HWCAP), rlmp) & PD_TKN_RESOLVED)
+ fdr.fd_flags |= FLG_FD_RESOLVED;
+ }
+ fdr.fd_pname = interp->i_name;
+ (void) fullpath(rlmp, &fdr);
+
+ /*
+ * The runtime linker acts as a filtee for various dl*() functions that
+ * are defined in libc (and libdl). Make sure this standard name for
+ * the runtime linker is also registered in the FullPathNode AVL tree.
+ */
+ (void) fpavl_insert(&lml_rtld, rlmp, _rtldname, 0);
/*
* Having established the true runtime linkers name, simplify the name
* for error diagnostics.
*/
- if ((str = strrchr(PATHNAME(rlmp), '/')) != 0)
+ if ((str = strrchr(PATHNAME(rlmp), '/')) != NULL)
rtldname = ++str;
else
rtldname = PATHNAME(rlmp);
@@ -684,44 +663,17 @@
* as a part of loading an object, but as the kernel probably mapped
* it in, complete this processing now.
*/
- if (FLAGS1(mlmp) & FL1_RT_RELATIVE)
- (void) fullpath(mlmp, 0);
+ (void) fullpath(mlmp, 0);
/*
* Some troublesome programs will change the value of argv[0]. Dupping
* the process string protects us, and insures the string is left in
* any core files.
*/
- if ((str = (char *)strdup(procname)) == 0)
+ if ((str = (char *)strdup(procname)) == NULL)
return (0);
procname = str;
- /*
- * If the kernel has provided hardware capabilities information, and
- * the executable contains hardware capabilities information, make
- * sure it's a valid object.
- */
- if ((rtld_flags2 & RT_FL2_HWCAP) && HWCAP(mlmp)) {
- ulong_t mhwcap;
-
- if ((mhwcap = (HWCAP(mlmp) & ~hwcap)) != 0) {
- Conv_cap_val_hw1_buf_t cap_val_hw1_buf;
-
- const char *str =
- conv_cap_val_hw1(mhwcap, M_MACH, 0,
- &cap_val_hw1_buf);
-
- if (lml_main.lm_flags & LML_FLG_TRC_ENABLE) {
- (void) printf(MSG_INTL(MSG_LDD_GEN_HWCAP_1),
- NAME(mlmp), str);
- } else {
- eprintf(&lml_main, ERR_FATAL,
- MSG_INTL(MSG_GEN_BADHWCAP_1), str);
- return (0);
- }
- }
- }
-
#if defined(_ELF64)
/*
* If this is a 64-bit process, determine whether this process has
@@ -732,6 +684,36 @@
if (SFCAP(mlmp) & SF1_SUNW_ADDR32)
rtld_flags2 |= RT_FL2_ADDR32;
#endif
+ /*
+ * Validate any hardware capabilities information.
+ */
+ if (HWCAP(mlmp) && (hwcap_check(HWCAP(mlmp), &rej) == 0)) {
+ if (lml_main.lm_flags & LML_FLG_TRC_ENABLE) {
+ (void) printf(MSG_INTL(MSG_LDD_GEN_HWCAP_1),
+ NAME(mlmp), rej.rej_str);
+ } else {
+ eprintf(&lml_main, ERR_FATAL,
+ MSG_INTL(MSG_GEN_BADHWCAP_1), rej.rej_str);
+ return (0);
+ }
+ }
+
+ /*
+ * Validate any software capabilities information, other than
+ * SF1_SUNW_ADDR32. Only dependencies need check their SF1_SUNW_ADDR32
+ * use against the application enabling a 32-bit address space.
+ */
+ if ((SFCAP(mlmp) & ~SF1_SUNW_ADDR32) &&
+ (sfcap_check(SFCAP(mlmp), &rej) == 0)) {
+ if (lml_main.lm_flags & LML_FLG_TRC_ENABLE) {
+ (void) printf(MSG_INTL(MSG_LDD_GEN_SFCAP_1),
+ NAME(mlmp), rej.rej_str);
+ } else {
+ eprintf(&lml_main, ERR_FATAL,
+ MSG_INTL(MSG_GEN_BADSFCAP_1), rej.rej_str);
+ return (0);
+ }
+ }
FLAGS(mlmp) |= (FLG_RT_ISMAIN | FLG_RT_MODESET);
FLAGS1(mlmp) |= FL1_RT_USED;
@@ -742,8 +724,8 @@
* collected during tsort processing. And, if the application has no
* initarray or finiarray we can economize on establishing bindings.
*/
- INIT(mlmp) = FINI(mlmp) = 0;
- if ((INITARRAY(mlmp) == 0) && (FINIARRAY(mlmp) == 0))
+ INIT(mlmp) = FINI(mlmp) = NULL;
+ if ((INITARRAY(mlmp) == NULL) && (FINIARRAY(mlmp) == NULL))
FLAGS1(mlmp) |= FL1_RT_NOINIFIN;
/*
@@ -765,10 +747,10 @@
/*
* Add our two main link-maps to the dynlm_list
*/
- if (list_append(&dynlm_list, &lml_main) == 0)
+ if (list_append(&dynlm_list, &lml_main) == NULL)
return (0);
- if (list_append(&dynlm_list, &lml_rtld) == 0)
+ if (list_append(&dynlm_list, &lml_rtld) == NULL)
return (0);
/*
@@ -798,8 +780,7 @@
* Determine the dev/inode information for the executable to complete
* load_so() checking for those who might dlopen(a.out).
*/
- if ((FLAGS1(mlmp) & FL1_RT_RELATIVE) &&
- (rtld_stat(PATHNAME(mlmp), &status) == 0)) {
+ if (rtld_stat(PATHNAME(mlmp), &status) == 0) {
STDEV(mlmp) = status.st_dev;
STINO(mlmp) = status.st_ino;
}
@@ -884,15 +865,13 @@
DBG_CALL(Dbg_file_ldso(rlmp, envp, auxv,
LIST(rlmp)->lm_lmidstr, ALIST_OFF_DATA));
- if (FCT(mlmp) == &elf_fct) {
+ if (THIS_IS_ELF(mlmp)) {
DBG_CALL(Dbg_file_elf(&lml_main, PATHNAME(mlmp),
- (ulong_t)DYN(mlmp), ADDR(mlmp), MSIZE(mlmp),
- ENTRY(mlmp), LIST(mlmp)->lm_lmidstr,
+ ADDR(mlmp), MSIZE(mlmp), LIST(mlmp)->lm_lmidstr,
ALIST_OFF_DATA));
} else {
DBG_CALL(Dbg_file_aout(&lml_main, PATHNAME(mlmp),
- (ulong_t)AOUTDYN(mlmp), (ulong_t)ADDR(mlmp),
- (ulong_t)MSIZE(mlmp), LIST(mlmp)->lm_lmidstr,
+ ADDR(mlmp), MSIZE(mlmp), LIST(mlmp)->lm_lmidstr,
ALIST_OFF_DATA));
}
}
@@ -912,16 +891,17 @@
* Any global auditing (set using LD_AUDIT or LD_PROFILE) that
* can't be established is non-fatal.
*/
- if ((auditors = calloc(1, sizeof (Audit_desc))) == 0)
+ if ((auditors = calloc(1, sizeof (Audit_desc))) == NULL)
return (0);
for (ndx = 0; ndx < 3; ndx++) {
if (aud[ndx]) {
- if ((auditors->ad_name = strdup(aud[ndx])) == 0)
+ if ((auditors->ad_name =
+ strdup(aud[ndx])) == NULL)
return (0);
rtld_flags2 |= RT_FL2_FTL2WARN;
(void) audit_setup(mlmp, auditors,
- PN_FLG_EXTLOAD, NULL);
+ PD_FLG_EXTLOAD, NULL);
rtld_flags2 &= ~RT_FL2_FTL2WARN;
}
}
@@ -939,8 +919,8 @@
* auditing descriptor. The effect is that a
* DT_DEPAUDIT act as an LD_AUDIT.
*/
- if ((auditors == 0) &&
- ((auditors = calloc(1, sizeof (Audit_desc))) == 0))
+ if ((auditors == NULL) && ((auditors = calloc(1,
+ sizeof (Audit_desc))) == NULL))
return (0);
auditors->ad_name = AUDITORS(mlmp)->ad_name;
@@ -952,7 +932,7 @@
* Clear the local auditor information.
*/
free((void *) AUDITORS(mlmp));
- AUDITORS(mlmp) = 0;
+ AUDITORS(mlmp) = NULL;
} else {
/*
@@ -961,7 +941,7 @@
if (audit_setup(mlmp, AUDITORS(mlmp), 0, NULL) == 0)
return (0);
- FLAGS1(mlmp) |= AUDITORS(mlmp)->ad_flags;
+ AFLAGS(mlmp) |= AUDITORS(mlmp)->ad_flags;
lml_main.lm_flags |= LML_FLG_LOCAUDIT;
}
}
@@ -972,10 +952,10 @@
* establish a cookie for ld.so.1 as this may be bound to via the
* dl*() family.
*/
- if ((lml_main.lm_tflags | FLAGS1(mlmp)) & LML_TFLG_AUD_MASK) {
+ if ((lml_main.lm_tflags | AFLAGS(mlmp)) & LML_TFLG_AUD_MASK) {
if (((audit_objopen(mlmp, mlmp) == 0) ||
(audit_objopen(mlmp, rlmp) == 0)) &&
- (FLAGS1(mlmp) & LML_TFLG_AUD_MASK))
+ (AFLAGS(mlmp) & LML_TFLG_AUD_MASK))
return (0);
}
@@ -992,7 +972,7 @@
/*
* Load all dependent (needed) objects.
*/
- if (analyze_lmc(&lml_main, ALIST_OFF_DATA, mlmp, NULL) == 0)
+ if (analyze_lmc(&lml_main, ALIST_OFF_DATA, mlmp, NULL) == NULL)
return (0);
/*
@@ -1048,9 +1028,9 @@
*/
rd_event(&lml_main, RD_PREINIT, 0);
- if ((lml_main.lm_tflags | FLAGS1(mlmp)) & LML_TFLG_AUD_ACTIVITY)
+ if ((lml_main.lm_tflags | AFLAGS(mlmp)) & LML_TFLG_AUD_ACTIVITY)
audit_activity(mlmp, LA_ACT_CONSISTENT);
- if ((lml_main.lm_tflags | FLAGS1(mlmp)) & LML_TFLG_AUD_PREINIT)
+ if ((lml_main.lm_tflags | AFLAGS(mlmp)) & LML_TFLG_AUD_PREINIT)
audit_preinit(mlmp);
/*
@@ -1085,7 +1065,6 @@
rtldexit(&lml_main, 0);
}
-#ifdef AT_SUN_AUXFLAGS
/*
* Check if this instance of the linker should have a primary link
* map. This flag allows multiple copies of the -same- -version-
@@ -1122,7 +1101,7 @@
*/
if (auxflags & AF_SUN_NOPLM)
rtld_flags2 |= RT_FL2_NOPLM;
-#endif
+
/*
* Establish any static TLS for this primary link-map. Note, regardless
* of whether TLS is available, an initial handshake occurs with libc to
--- a/usr/src/cmd/sgs/rtld/common/tls.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/tls.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,7 +50,8 @@
ulong_t ndx, cnt;
if (tmid.tmi_bits == 0) {
- if ((tmid.tmi_bits = calloc(TLSBLOCKCNT, sizeof (uint_t))) == 0)
+ if ((tmid.tmi_bits =
+ calloc(TLSBLOCKCNT, sizeof (uint_t))) == NULL)
return ((ulong_t)-1);
tmid.tmi_bits[0] = 1;
tmid.tmi_lowfree = 1;
@@ -83,7 +84,7 @@
*/
if ((tmid.tmi_bits = realloc(tmid.tmi_bits,
((tmid.tmi_cnt * sizeof (uint_t)) +
- (TLSBLOCKCNT * sizeof (uint_t))))) == 0)
+ (TLSBLOCKCNT * sizeof (uint_t))))) == NULL)
return ((ulong_t)-1);
/*
@@ -275,7 +276,7 @@
* the backup TLS reservation.
*/
if ((tlsmodlist = calloc((sizeof (TLS_modinfo *) * (tlsmodcnt + 1)) +
- (sizeof (TLS_modinfo) * tlsmodcnt), 1)) == 0)
+ (sizeof (TLS_modinfo) * tlsmodcnt), 1)) == NULL)
return (0);
lml->lm_tls = 0;
@@ -305,7 +306,7 @@
*/
tlsmodndx = 0;
for (lmp = lml->lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
- if ((FCT(lmp) != &elf_fct) ||
+ if (THIS_IS_NOT_ELF(lmp) ||
(PTTLS(lmp) == 0) || (PTTLS(lmp)->p_memsz == 0))
continue;
--- a/usr/src/cmd/sgs/rtld/common/tsort.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/tsort.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -70,7 +70,7 @@
* qsort(3c) comparison function.
*/
static int
-compare(const void * lmpp1, const void * lmpp2)
+compare(const void *lmpp1, const void *lmpp2)
{
Rt_map *lmp1 = *((Rt_map **)lmpp1);
Rt_map *lmp2 = *((Rt_map **)lmpp2);
@@ -88,7 +88,7 @@
* sorted.
*/
static int
-sort_scc(Sort * sort, int fndx, int flag)
+sort_scc(Sort *sort, int fndx, int flag)
{
static const char *tfmt = 0, *ffmt;
static int cnt = 1;
@@ -122,9 +122,9 @@
Aliste idx2;
for (APLIST_TRAVERSE(DEPENDS(lmp2), idx2, bdp)) {
- Rt_map *lmp = bdp->b_depend;
+ Rt_map *lmp3 = bdp->b_depend;
- if (IDX(lmp))
+ if (IDX(lmp3) || (LIST(lmp3) != lml))
continue;
/*
@@ -132,14 +132,14 @@
* encies .init has been called, skip it.
*/
if ((flag & RT_SORT_REV) &&
- (FLAGS(lmp) & FLG_RT_INITCALL))
+ (FLAGS(lmp3) & FLG_RT_INITCALL))
continue;
- if (aplist_append(&sort->s_queue, lmp,
+ if (aplist_append(&sort->s_queue, lmp3,
sort->s_num) == NULL)
return (0);
- IDX(lmp) = ndx++;
+ IDX(lmp3) = ndx++;
}
}
}
@@ -244,7 +244,7 @@
* to sort_scc() to sort these elements.
*/
static int
-visit(Lm_list *lml, Rt_map * lmp, Sort *sort, int flag)
+visit(Lm_list *lml, Rt_map *lmp, Sort *sort, int flag)
{
APlist *alp = NULL;
int num = sort->s_lndx;
@@ -281,7 +281,7 @@
* If tracing, save the strongly connected component.
*/
if (tracing && (aplist_append(&alp, tlmp,
- AL_CNT_SCC) == 0))
+ AL_CNT_SCC) == NULL))
return (0);
} while (tlmp != lmp);
@@ -294,7 +294,7 @@
return (0);
if (tracing && (aplist_append(&sort->s_scc, alp,
- AL_CNT_SCC) == 0))
+ AL_CNT_SCC) == NULL))
return (0);
} else if (alp)
free(alp);
@@ -392,7 +392,7 @@
int flag)
{
int min;
- Aliste idx;
+ Aliste idx1;
Bnd_desc *bdp;
Dyninfo *dip;
@@ -407,7 +407,7 @@
/*
* Traverse both explicit and implicit dependencies.
*/
- for (APLIST_TRAVERSE(DEPENDS(lmp), idx, bdp)) {
+ for (APLIST_TRAVERSE(DEPENDS(lmp), idx1, bdp)) {
if ((min = _dep_visit(lml, min, lmp, bdp->b_depend,
bdp->b_flags, sort, flag)) == -1)
return (-1);
@@ -416,25 +416,27 @@
/*
* Traverse any filtee dependencies.
*/
- if (((dip = DYNINFO(lmp)) != 0) && (FLAGS1(lmp) & MSK_RT_FILTER)) {
+ if (((dip = DYNINFO(lmp)) != NULL) && (FLAGS1(lmp) & MSK_RT_FILTER)) {
uint_t cnt, max = DYNINFOCNT(lmp);
for (cnt = 0; cnt < max; cnt++, dip++) {
- Pnode *pnp = (Pnode *)dip->di_info;
+ Alist *falp;
+ Pdesc *pdp;
- if ((pnp == 0) ||
+ if (((falp = (Alist *)dip->di_info) == NULL) ||
((dip->di_flags & MSK_DI_FILTER) == 0))
continue;
- for (; pnp; pnp = pnp->p_next) {
- Grp_hdl *ghp = (Grp_hdl *)dip->di_info;
+ for (ALIST_TRAVERSE(falp, idx1, pdp)) {
+ Aliste idx2;
+ Grp_hdl *ghp;
Grp_desc *gdp;
- if ((pnp->p_len == 0) ||
- ((ghp = (Grp_hdl *)pnp->p_info) == 0))
+ if ((pdp->pd_plen == 0) ||
+ ((ghp = (Grp_hdl *)pdp->pd_info) == NULL))
continue;
- for (ALIST_TRAVERSE(ghp->gh_depends, idx,
+ for (ALIST_TRAVERSE(ghp->gh_depends, idx2,
gdp)) {
if (gdp->gd_depend == lmp)
@@ -460,59 +462,6 @@
return (min);
}
-
-#ifndef LD_BREADTH_DISABLED
-/*
- * Reverse LD_BREATH search (used to fire .init's the old fashioned way).
- */
-static void
-rb_visit(Rt_map * lmp, Sort * sort)
-{
- Rt_map * nlmp;
-
- if ((nlmp = NEXT_RT_MAP(lmp)) != 0)
- rb_visit(nlmp, sort);
-
- /*
- * Only collect objects that have been relocated and haven't already
- * been collected.
- */
- if ((FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_INITCLCT)) ==
- FLG_RT_RELOCED) {
- sort->s_lmpa[(sort->s_lndx)++] = lmp;
- FLAGS(lmp) |= FLG_RT_INITCLCT;
- LIST(lmp)->lm_init--;
- }
-}
-
-/*
- * Forward LD_BREATH search (used to fire .fini's the old fashioned way).
- */
-static void
-fb_visit(Rt_map * lmp, Sort * sort, int flag)
-{
- while (lmp) {
- /*
- * If we're called from dlclose() then we only collect those
- * objects marked for deletion.
- */
- if (!(flag & RT_SORT_DELETE) || (FLAGS(lmp) & FLG_RT_DELETE)) {
- /*
- * Only collect objects that have had their .init
- * collected, and haven't already been .fini collected.
- */
- if ((FLAGS(lmp) &
- (FLG_RT_INITCLCT | FLG_RT_FINICLCT)) ==
- (FLG_RT_INITCLCT)) {
- sort->s_lmpa[(sort->s_lndx)++] = lmp;
- FLAGS(lmp) |= FLG_RT_FINICLCT;
- }
- }
- lmp = NEXT_RT_MAP(lmp);
- }
-}
-#endif
-
/*
* Find corresponding strongly connected component structure.
*/
@@ -538,7 +487,7 @@
* Print out the .init dependency information (ldd).
*/
static void
-trace_sort(Sort * sort)
+trace_sort(Sort *sort)
{
int ndx = 0;
APlist *alp;
@@ -557,12 +506,6 @@
if (sfmt == 0)
sfmt = MSG_INTL(MSG_LDD_INIT_FMT_02);
-#ifndef LD_BREADTH_DISABLED
- if (rtld_flags & RT_FL_BREADTH) {
- (void) printf(sfmt, NAME(lmp1));
- continue;
- }
-#endif
/*
* If the only component on the strongly connected list is
* this link-map, then there are no dependencies.
@@ -603,8 +546,8 @@
static void
r_initfirst(Sort * sort, int end)
{
- Rt_map * tlmp;
- int bgn, ifst, lifst = 0;
+ Rt_map *tlmp;
+ int bgn, ifst, lifst = 0;
for (bgn = 0; bgn < sort->s_initfirst; bgn++) {
for (ifst = lifst; ifst <= end; ifst++) {
@@ -645,10 +588,10 @@
* of these elements to the front of the list.
*/
static void
-f_initfirst(Sort * sort, int end)
+f_initfirst(Sort *sort, int end)
{
- Rt_map * tlmp;
- int bgn, ifst, lifst = 0;
+ Rt_map *tlmp;
+ int bgn, ifst, lifst = 0;
for (bgn = 0; bgn < sort->s_initfirst; bgn++) {
for (ifst = lifst; ifst <= end; ifst++) {
@@ -721,10 +664,11 @@
Rt_map **
tsort(Rt_map *lmp, int num, int flag)
{
- Rt_map * _lmp;
- Lm_list * lml = LIST(lmp);
- Word init = lml->lm_flags & LML_FLG_TRC_INIT;
- Sort sort = { 0 };
+ Rt_map *_lmp;
+ Lm_list *lml = LIST(lmp);
+ Word init = lml->lm_flags & LML_FLG_TRC_INIT;
+ Sort sort = { 0 };
+ size_t size;
if (num == 0)
return (0);
@@ -740,38 +684,15 @@
/*
* Allocate memory for link-map list array. Calloc the array to insure
* all elements are zero, we might find that no objects need processing.
+ * At the same time, allocate a stack for any topological sorting that
+ * might be necessary.
*/
sort.s_lmp = lmp;
sort.s_num = num + 1;
- if ((sort.s_lmpa = calloc(sort.s_num, sizeof (Rt_map *))) == NULL)
+ size = sort.s_num * sizeof (Rt_map *);
+ if ((sort.s_lmpa = calloc(2, size)) == NULL)
return ((Rt_map **)S_ERROR);
-
-#ifndef LD_BREADTH_DISABLED
- /*
- * A breadth first search is easy, simply add each object to the
- * link-map array.
- */
- if (rtld_flags & RT_FL_BREADTH) {
- if (flag & RT_SORT_REV)
- rb_visit(lmp, &sort);
- else
- fb_visit(lmp, &sort, flag);
-
- /*
- * If tracing .init sections (only meaningful for RT_SORT_REV)
- * print out the sorted dependencies.
- */
- if (init)
- trace_sort(&sort);
-
- return (sort.s_lmpa);
- }
-#endif
- /*
- * We need to topologically sort the dependencies.
- */
- if ((sort.s_stack = malloc(sort.s_num * sizeof (Rt_map *))) == NULL)
- return ((Rt_map **)S_ERROR);
+ sort.s_stack = (Rt_map **)((uintptr_t)sort.s_lmpa + size);
/*
* Determine where to start searching for tsort() candidates. Any call
@@ -871,7 +792,7 @@
int bgn = 0, end = sort.s_lndx - 1;
while (bgn < end) {
- Rt_map * tlmp = sort.s_lmpa[end];
+ Rt_map *tlmp = sort.s_lmpa[end];
sort.s_lmpa[end] = sort.s_lmpa[bgn];
sort.s_lmpa[bgn] = tlmp;
@@ -901,9 +822,6 @@
/*
* Clean any temporary structures prior to return.
*/
- if (sort.s_stack)
- free(sort.s_stack);
-
if (sort.s_queue) {
Aliste idx;
Rt_map *lmp2;
--- a/usr/src/cmd/sgs/rtld/common/util.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/common/util.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,8 +45,8 @@
#include <dlfcn.h>
#include <unistd.h>
#include <stdlib.h>
+#include <sys/auxv.h>
#include <limits.h>
-#include <sys/auxv.h>
#include <debug.h>
#include <conv.h>
#include "_rtld.h"
@@ -57,17 +57,6 @@
static int ld_flags_env(const char *, Word *, Word *, uint_t, int);
/*
- * All error messages go through eprintf(). During process initialization these
- * messages should be directed to the standard error, however once control has
- * been passed to the applications code these messages should be stored in an
- * internal buffer for use with dlerror(). Note, fatal error conditions that
- * may occur while running the application will still cause a standard error
- * message, see rtldexit() in this file for details.
- * The `application' flag serves to indicate the transition between process
- * initialization and when the applications code is running.
- */
-
-/*
* Null function used as place where a debugger can set a breakpoint.
*/
void
@@ -400,7 +389,7 @@
* fpavl_insert() to expedite the insertion.
*/
Rt_map *
-fpavl_recorded(Lm_list *lml, const char *name, avl_index_t *where)
+fpavl_recorded(Lm_list *lml, const char *name, uint_t hash, avl_index_t *where)
{
FullPathNode fpn, *fpnp;
@@ -412,7 +401,8 @@
return (NULL);
fpn.fpn_node.pn_name = name;
- fpn.fpn_node.pn_hash = sgs_str_hash(name);
+ if ((fpn.fpn_node.pn_hash = hash) == 0)
+ fpn.fpn_node.pn_hash = sgs_str_hash(name);
if ((fpnp = avl_find(lml->lm_fpavl, &fpn, where)) == NULL)
return (NULL);
@@ -432,10 +422,11 @@
fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)
{
FullPathNode *fpnp;
+ uint_t hash = sgs_str_hash(name);
if (where == 0) {
/* LINTED */
- Rt_map *_lmp = fpavl_recorded(lml, name, &where);
+ Rt_map *_lmp = fpavl_recorded(lml, name, hash, &where);
/*
* We better not get a hit now, we do not want duplicates in
@@ -451,7 +442,7 @@
return (0);
fpnp->fpn_node.pn_name = name;
- fpnp->fpn_node.pn_hash = sgs_str_hash(name);
+ fpnp->fpn_node.pn_hash = hash;
fpnp->fpn_lmp = lmp;
if (aplist_append(&FPNODE(lmp), fpnp, AL_CNT_FPNODE) == NULL) {
@@ -465,9 +456,7 @@
}
/*
- * Remove an object from the FullPath AVL tree. Note, this is called *before*
- * the objects link-map is torn down (remove_so), which is where any NAME() and
- * PATHNAME() strings will be deallocated.
+ * Remove an object from the FullPathNode AVL tree.
*/
void
fpavl_remove(Rt_map *lmp)
@@ -492,7 +481,7 @@
* the insertion.
*/
int
-nfavl_recorded(const char *name, avl_index_t *where)
+nfavl_recorded(const char *name, uint_t hash, avl_index_t *where)
{
PathNode pn;
@@ -501,10 +490,11 @@
*/
if ((nfavl == NULL) &&
((nfavl = pnavl_create(sizeof (PathNode))) == NULL))
- return (0);
+ return (NULL);
pn.pn_name = name;
- pn.pn_hash = sgs_str_hash(name);
+ if ((pn.pn_hash = hash) == 0)
+ pn.pn_hash = sgs_str_hash(name);
if (avl_find(nfavl, &pn, where) == NULL)
return (0);
@@ -519,10 +509,11 @@
nfavl_insert(const char *name, avl_index_t where)
{
PathNode *pnp;
+ uint_t hash = sgs_str_hash(name);
if (where == 0) {
/* LINTED */
- int in_nfavl = nfavl_recorded(name, &where);
+ int in_nfavl = nfavl_recorded(name, hash, &where);
/*
* We better not get a hit now, we do not want duplicates in
@@ -534,9 +525,9 @@
/*
* Insert new node in tree.
*/
- if ((pnp = calloc(sizeof (PathNode), 1)) != 0) {
+ if ((pnp = calloc(sizeof (PathNode), 1)) != NULL) {
pnp->pn_name = name;
- pnp->pn_hash = sgs_str_hash(name);
+ pnp->pn_hash = hash;
avl_insert(nfavl, pnp, where);
}
}
@@ -612,6 +603,95 @@
}
/*
+ * Inspect the generic string AVL tree for the given string. If the string is
+ * not present, duplicate it, and insert the string in the AVL tree. Return the
+ * duplicated string to the caller.
+ *
+ * These strings are maintained for the life of ld.so.1 and represent path
+ * names, file names, and search paths. All other AVL trees that maintain
+ * FullPathNode and not-found path names use the same string pointer
+ * established for this string.
+ */
+static avl_tree_t *stravl = NULL;
+static char *strbuf = NULL;
+static PathNode *pnbuf = NULL;
+static size_t strsize = 0, pnsize = 0;
+
+const char *
+stravl_insert(const char *name, uint_t hash, size_t nsize, int substr)
+{
+ char str[PATH_MAX];
+ PathNode *pnp;
+ avl_index_t where;
+
+ /*
+ * Create the avl tree if required.
+ */
+ if ((stravl == NULL) &&
+ ((stravl = pnavl_create(sizeof (PathNode))) == NULL))
+ return (NULL);
+
+ /*
+ * Determine the string size if not provided by the caller.
+ */
+ if (nsize == 0)
+ nsize = strlen(name) + 1;
+ else if (substr) {
+ /*
+ * The string passed to us may be a multiple path string for
+ * which we only need the first component. Using the provided
+ * size, strip out the required string.
+ */
+ (void) strncpy(str, name, nsize);
+ str[nsize - 1] = '\0';
+ name = str;
+ }
+
+ /*
+ * Allocate a PathNode buffer if one doesn't exist, or any existing
+ * buffer has been used up.
+ */
+ if ((pnbuf == NULL) || (sizeof (PathNode) > pnsize)) {
+ pnsize = syspagsz;
+ if ((pnbuf = dz_map(0, 0, pnsize, (PROT_READ | PROT_WRITE),
+ MAP_PRIVATE)) == MAP_FAILED)
+ return (NULL);
+ }
+ /*
+ * Determine whether this string already exists.
+ */
+ pnbuf->pn_name = name;
+ if ((pnbuf->pn_hash = hash) == 0)
+ pnbuf->pn_hash = sgs_str_hash(name);
+
+ if ((pnp = avl_find(stravl, pnbuf, &where)) != NULL)
+ return (pnp->pn_name);
+
+ /*
+ * Allocate a string buffer if one does not exist, or if there is
+ * insufficient space for the new string in any existing buffer.
+ */
+ if ((strbuf == NULL) || (nsize > strsize)) {
+ strsize = S_ROUND(nsize, syspagsz);
+
+ if ((strbuf = dz_map(0, 0, strsize, (PROT_READ | PROT_WRITE),
+ MAP_PRIVATE)) == MAP_FAILED)
+ return (NULL);
+ }
+
+ (void) memcpy(strbuf, name, nsize);
+ pnp = pnbuf;
+ pnp->pn_name = strbuf;
+ avl_insert(stravl, pnp, where);
+
+ strbuf += nsize;
+ strsize -= nsize;
+ pnbuf++;
+ pnsize -= sizeof (PathNode);
+ return (pnp->pn_name);
+}
+
+/*
* Prior to calling an object, either via a .plt or through dlsym(), make sure
* its .init has fired. Through topological sorting, ld.so.1 attempts to fire
* init's in the correct order, however, this order is typically based on needed
@@ -633,7 +713,7 @@
(LIST(clmp) != LIST(dlmp)))
return;
- if ((dlmp == clmp) || (rtld_flags & (RT_FL_BREADTH | RT_FL_INITFIRST)))
+ if ((dlmp == clmp) || (rtld_flags & RT_FL_INITFIRST))
return;
if ((FLAGS(dlmp) & (FLG_RT_RELOCED | FLG_RT_INITDONE)) ==
@@ -653,49 +733,6 @@
}
/*
- * In a threaded environment insure the thread responsible for loading an object
- * has completed .init processing for that object before any new thread is
- * allowed to access the object. This check is only valid with libthread
- * TI_VERSION 2, where ld.so.1 implements locking through low level mutexes.
- *
- * When a new link-map is created, the thread that causes it to be loaded is
- * identified by THREADID(dlmp). Compare this with the current thread to
- * determine if it must be blocked.
- *
- * NOTE, there are a number of instances (typically only for .plt processing)
- * where we must skip this test:
- *
- * . any thread id of 0 - threads that call thr_exit() may be in this state
- * thus we can't deduce what tid they used to be. Also some of the
- * lib/libthread worker threads have this id and must bind (to themselves
- * or libc) for libthread to function.
- *
- * . libthread itself binds to libc, and as libthread is INITFIRST
- * libc's .init can't have fired yet. Luckly libc's .init is not required
- * by libthreads binding.
- *
- * . if the caller is an auditor, and the destination isn't, then don't
- * block (see comments in load_completion()).
- */
-void
-/* ARGSUSED2 */
-is_dep_ready(Rt_map *dlmp, Rt_map *clmp, int what)
-{
- thread_t tid;
-
- if ((LIST(clmp)->lm_flags & LML_FLG_NOAUDIT) &&
- (LIST(clmp) != LIST(dlmp)))
- return;
-
- if ((rtld_flags & RT_FL_CONCUR) &&
- ((FLAGS(dlmp) & FLG_RT_INITDONE) == 0) &&
- ((FLAGS(clmp) & FLG_RT_INITFRST) == 0) &&
- ((tid = rt_thr_self()) != 0) && (THREADID(dlmp) != tid)) {
- rtldexit(LIST(dlmp), 1);
- }
-}
-
-/*
* Execute .{preinit|init|fini}array sections
*/
void
@@ -776,24 +813,8 @@
if (FLAGS(lmp) & FLG_RT_INITFRST)
rtld_flags |= RT_FL_INITFIRST;
- if (INITARRAY(lmp) || iptr) {
- Aliste idx;
- Bnd_desc *bdp;
-
- /*
- * Make sure that all dependencies that have been
- * relocated to are initialized before this objects
- * .init is executed. This insures that a dependency
- * on an external item that must first be initialized
- * by its associated object is satisfied.
- */
- for (APLIST_TRAVERSE(DEPENDS(lmp), idx, bdp)) {
- if ((bdp->b_flags & BND_REFER) == 0)
- continue;
- is_dep_ready(bdp->b_depend, lmp, DBG_WAIT_INIT);
- }
+ if (INITARRAY(lmp) || iptr)
DBG_CALL(Dbg_util_call_init(lmp, flag));
- }
if (iptr) {
leave(LIST(lmp), 0);
@@ -818,15 +839,6 @@
SORTVAL(lmp) = -1;
/*
- * Wake anyone up who might be waiting on this .init.
- */
- if (FLAGS1(lmp) & FL1_RT_INITWAIT) {
- DBG_CALL(Dbg_util_broadcast(lmp));
- (void) rt_cond_broadcast(CONDVAR(lmp));
- FLAGS1(lmp) &= ~FL1_RT_INITWAIT;
- }
-
- /*
* If we're firing an INITFIRST object, and other objects must
* be fired which are not INITFIRST, make sure we grab any
* pending objects that might have been delayed as this
@@ -869,24 +881,16 @@
Bnd_desc *bdp;
/*
- * If concurrency checking isn't enabled only fire .fini if
- * .init has completed. We collect all .fini sections of
- * objects that had their .init collected, but that doesn't
- * mean at the time that the .init had completed.
+ * Only fire a .fini if the objects corresponding .init has
+ * completed. We collect all .fini sections of objects that
+ * had their .init collected, but that doesn't mean that at
+ * the time of collection, that the .init had completed.
*/
- if ((rtld_flags & RT_FL_CONCUR) ||
- (FLAGS(lmp) & FLG_RT_INITDONE)) {
+ if (FLAGS(lmp) & FLG_RT_INITDONE) {
void (*fptr)(void) = FINI(lmp);
- if (FINIARRAY(lmp) || fptr) {
- /*
- * If concurrency checking is enabled make sure
- * this object's .init is completed before
- * calling any .fini.
- */
- is_dep_ready(lmp, lmp, DBG_WAIT_FINI);
+ if (FINIARRAY(lmp) || fptr)
DBG_CALL(Dbg_util_call_fini(lmp));
- }
call_array(FINIARRAY(lmp), FINIARRAYSZ(lmp), lmp,
SHT_FINI_ARRAY);
@@ -921,13 +925,13 @@
if ((lml->lm_flags & LML_FLG_LOCAUDIT) == 0)
continue;
- if (FLAGS1(lmp) & LML_TFLG_AUD_OBJCLOSE)
+ if (AFLAGS(lmp) & LML_TFLG_AUD_OBJCLOSE)
_audit_objclose(&(AUDITORS(lmp)->ad_list), lmp);
for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) {
clmp = bdp->b_caller;
- if (FLAGS1(clmp) & LML_TFLG_AUD_OBJCLOSE) {
+ if (AFLAGS(clmp) & LML_TFLG_AUD_OBJCLOSE) {
_audit_objclose(&(AUDITORS(clmp)->ad_list),
lmp);
break;
@@ -970,7 +974,7 @@
* called last, here. This is the reverse of the explicit calls to
* audit_objopen() made in setup().
*/
- if ((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_MASK) {
+ if ((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_MASK) {
audit_objclose(lmp, (Rt_map *)lml_rtld.lm_head);
audit_objclose(lmp, lmp);
}
@@ -1060,7 +1064,7 @@
if (nlmp && nlml->lm_init && ((nlml != &lml_main) ||
(rtld_flags2 & (RT_FL2_PLMSETUP | RT_FL2_NOPLM)))) {
- if ((tobj = tsort(nlmp, LIST(nlmp)->lm_init,
+ if ((tobj = tsort(nlmp, nlml->lm_init,
RT_SORT_REV)) == (Rt_map **)S_ERROR)
tobj = 0;
}
@@ -1122,7 +1126,6 @@
return (_lnp);
}
-
/*
* Add an item after specified listnode, and return a pointer to the list
* node created.
@@ -1132,8 +1135,8 @@
{
Listnode *_lnp;
- if ((_lnp = malloc(sizeof (Listnode))) == (Listnode *)0)
- return (0);
+ if ((_lnp = malloc(sizeof (Listnode))) == NULL)
+ return (NULL);
_lnp->data = (void *)item;
_lnp->next = lnp->next;
@@ -1148,11 +1151,11 @@
* list node created.
*/
Listnode *
-list_prepend(List * lst, const void * item)
+list_prepend(List *lst, const void *item)
{
Listnode *_lnp;
- if ((_lnp = malloc(sizeof (Listnode))) == (Listnode *)0)
+ if ((_lnp = malloc(sizeof (Listnode))) == NULL)
return (0);
_lnp->data = (void *)item;
@@ -1167,7 +1170,6 @@
return (_lnp);
}
-
/*
* Delete a 'listnode' from a list.
*/
@@ -1401,9 +1403,20 @@
* Indicate each new link-map has been moved to the previous link-map
* control list.
*/
- for (lmp = nlmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp))
+ for (lmp = nlmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
CNTL(lmp) = plmco;
+ /*
+ * If these objects are being added to the main link-map
+ * control list, indicate that there are init's available
+ * for harvesting.
+ */
+ if (plmco == ALIST_OFF_DATA) {
+ lml->lm_init++;
+ lml->lm_flags |= LML_FLG_OBJADDED;
+ }
+ }
+
/*
* Move the new link-map control list, to the callers link-map control
* list.
@@ -1479,7 +1492,7 @@
#define ENV_FLG_BIND_NOW 0x0000000004ULL
#define ENV_FLG_BIND_NOT 0x0000000008ULL
#define ENV_FLG_BINDINGS 0x0000000010ULL
-#define ENV_FLG_CONCURRENCY 0x0000000020ULL
+
#define ENV_FLG_CONFGEN 0x0000000040ULL
#define ENV_FLG_CONFIG 0x0000000080ULL
#define ENV_FLG_DEBUG 0x0000000100ULL
@@ -1515,10 +1528,6 @@
#define ENV_FLG_NOUNRESWEAK 0x4000000000ULL
#define ENV_FLG_NOPAREXT 0x8000000000ULL
-#ifdef SIEBEL_DISABLE
-#define ENV_FLG_FIX_1 0x8000000000ULL
-#endif
-
#define SEL_REPLACE 0x0001
#define SEL_PERMANT 0x0002
#define SEL_ACT_RT 0x0100 /* setting rtld_flags */
@@ -1588,7 +1597,7 @@
}
}
/*
- * The LD_BIND family and LD_BREADTH (historic).
+ * The LD_BIND family.
*/
else if (*s1 == 'B') {
if ((len == MSG_LD_BIND_LAZY_SIZE) && (strncmp(s1,
@@ -1621,31 +1630,13 @@
*/
select |= SEL_ACT_SPEC_2;
variable = ENV_FLG_BINDINGS;
-#ifndef LD_BREADTH_DISABLED
- } else if ((len == MSG_LD_BREADTH_SIZE) && (strncmp(s1,
- MSG_ORIG(MSG_LD_BREADTH), MSG_LD_BREADTH_SIZE) == 0)) {
- /*
- * Besides some old patches this is no longer available.
- */
- rtld_flags |= RT_FL_BREADTH;
- return;
-#endif
}
}
/*
- * LD_CONCURRENCY and LD_CONFIG family.
+ * LD_CONFIG family.
*/
else if (*s1 == 'C') {
- if ((len == MSG_LD_CONCURRENCY_SIZE) && (strncmp(s1,
- MSG_ORIG(MSG_LD_CONCURRENCY),
- MSG_LD_CONCURRENCY_SIZE) == 0)) {
- /*
- * Waiting in the wings, as concurrency checking isn't
- * yet enabled.
- */
- select |= SEL_ACT_SPEC_2;
- variable = ENV_FLG_CONCURRENCY;
- } else if ((len == MSG_LD_CONFGEN_SIZE) && (strncmp(s1,
+ if ((len == MSG_LD_CONFGEN_SIZE) && (strncmp(s1,
MSG_ORIG(MSG_LD_CONFGEN), MSG_LD_CONFGEN_SIZE) == 0)) {
/*
* Set by crle(1) to indicate it's building a
@@ -1834,21 +1825,6 @@
}
}
/*
- * LD_ORIGIN.
- */
- else if (*s1 == 'O') {
-#ifndef EXPAND_RELATIVE
- if ((len == MSG_LD_ORIGIN_SIZE) && (strncmp(s1,
- MSG_ORIG(MSG_LD_ORIGIN), MSG_LD_ORIGIN_SIZE) == 0)) {
- /*
- * Besides some old patches this is no longer required.
- */
- rtld_flags |= RT_FL_RELATIVE;
- }
-#endif
- return;
- }
- /*
* LD_PRELOAD and LD_PROFILE family.
*/
else if (*s1 == 'P') {
@@ -1975,21 +1951,8 @@
val = LML_FLG_TRC_WARN;
variable = ENV_FLG_WARN;
}
-#ifdef SIEBEL_DISABLE
}
- /*
- * LD__FIX__ (undocumented, enable future technology that can't be
- * delivered in a patch release).
- */
- else if (*s1 == '_') {
- if ((len == MSG_LD_FIX_1_SIZE) && (strncmp(s1,
- MSG_ORIG(MSG_LD_FIX_1), MSG_LD_FIX_1_SIZE) == 0)) {
- select |= SEL_ACT_RT;
- val = RT_FL_DISFIX_1;
- variable = ENV_FLG_FIX_1;
- }
-#endif
- }
+
if (variable == 0)
return;
@@ -2098,11 +2061,6 @@
rpl_debug = MSG_ORIG(MSG_TKN_BINDINGS);
else
rpl_debug = 0;
- } else if (variable == ENV_FLG_CONCURRENCY) {
- if (s2)
- rtld_flags &= ~RT_FL_NOCONCUR;
- else
- rtld_flags |= RT_FL_NOCONCUR;
} else if (variable == ENV_FLG_CONFGEN) {
if (s2) {
rtld_flags |= RT_FL_CONFGEN;
@@ -2144,7 +2102,7 @@
}
/* END CSTYLED */
} else
- profile_lib = 0;
+ profile_lib = NULL;
} else if (variable == ENV_FLG_SIGNAL) {
killsig = s2 ? atoi(s2) : SIGKILL;
} else if (variable == ENV_FLG_TRACE_OBJS) {
@@ -2385,14 +2343,14 @@
* itself.
*/
int
-readenv_user(const char ** envp, Word *lmflags, Word *lmtflags, int aout)
+readenv_user(const char **envp, Word *lmflags, Word *lmtflags, int aout)
{
char *locale;
- if (envp == (const char **)0)
+ if (envp == NULL)
return (0);
- while (*envp != (const char *)0)
+ while (*envp != NULL)
ld_str_env(*envp++, lmflags, lmtflags, 0, aout);
/*
@@ -2408,7 +2366,7 @@
* LML_FLG_TRC_ENABLE.
*/
if ((*lmflags & LML_FLG_TRC_ENABLE) || (rtld_flags & RT_FL_NOAUDIT))
- rpl_audit = profile_lib = profile_name = 0;
+ rpl_audit = profile_lib = profile_name = NULL;
if ((*lmflags & LML_FLG_TRC_ENABLE) == 0)
*lmflags &= ~LML_MSK_TRC;
@@ -2458,7 +2416,7 @@
Word *lmflags = &(lml_main.lm_flags);
Word *lmtflags = &(lml_main.lm_tflags);
- if (envtbl == (Rtc_env *)0)
+ if (envtbl == NULL)
return (0);
while (envtbl->env_str) {
@@ -2488,7 +2446,7 @@
* LML_FLG_TRC_ENABLE.
*/
if ((*lmflags & LML_FLG_TRC_ENABLE) || (rtld_flags & RT_FL_NOAUDIT))
- prm_audit = profile_lib = profile_name = 0;
+ prm_audit = profile_lib = profile_name = NULL;
if ((*lmflags & LML_FLG_TRC_ENABLE) == 0)
*lmflags &= ~LML_MSK_TRC;
@@ -2856,6 +2814,16 @@
static char errbuf[ERRSIZE], *nextptr = errbuf, *prevptr = 0;
+/*
+ * All error messages go through eprintf(). During process initialization,
+ * these messages are directed to the standard error, however once control has
+ * been passed to the applications code these messages are stored in an internal
+ * buffer for use with dlerror(). Note, fatal error conditions that may occur
+ * while running the application will still cause a standard error message, see
+ * rtldexit() in this file for details.
+ * The RT_FL_APPLIC flag serves to indicate the transition between process
+ * initialization and when the applications code is running.
+ */
/*PRINTFLIKE3*/
void
eprintf(Lm_list *lml, Error error, const char *format, ...)
@@ -2961,12 +2929,12 @@
* overflow condition, this message may be incomplete, in which case
* make sure any partial string is null terminated.
*/
- if (overflow)
- *(prf.pr_cur) = '\0';
if ((rtld_flags & (RT_FL_APPLIC | RT_FL_SILENCERR)) == 0) {
*(prf.pr_cur - 1) = '\n';
(void) dowrite(&prf);
}
+ if (overflow)
+ *(prf.pr_cur - 1) = '\0';
DBG_CALL(Dbg_util_str(lml, nextptr));
va_end(args);
@@ -3029,8 +2997,8 @@
#if DEBUG
/*
- * Provide assfail() for ASSERT() statements,
- * see <sys/debug.h> for further details.
+ * Provide assfail() for ASSERT() statements. See <sys/debug.h> for further
+ * details.
*/
int
assfail(const char *a, const char *f, int l)
@@ -3086,115 +3054,26 @@
}
/*
- * Routines to co-ordinate the opening of /dev/zero and /proc.
- * dz_fd is exported for possible use by libld.so, and to insure it gets
- * closed on leaving ld.so.1.
- */
-int dz_fd = FD_UNAVAIL;
-
-void
-dz_init(int fd)
-{
- dz_fd = fd;
-}
-
-
-/*
- * mmap() a page from MAP_ANON
- *
- * Note: MAP_ANON is only on Solaris8++, we use this routine to
- * not only mmap(MAP_ANON) but to also probe if it is available
- * on the current OS.
+ * Map anonymous memory via MAP_ANON (added in Solaris 8).
*/
-Am_ret
-anon_map(Lm_list *lml, caddr_t *addr, size_t len, int prot, int flags)
-{
-#if defined(MAP_ANON)
- static int noanon = 0;
- caddr_t va;
-
- if (noanon == 0) {
- if ((va = (caddr_t)mmap(*addr, len, prot,
- (flags | MAP_ANON), -1, 0)) != MAP_FAILED) {
- *addr = va;
- return (AM_OK);
- }
-
- if ((errno != EBADF) && (errno != EINVAL)) {
- int err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAPANON),
- MSG_ORIG(MSG_PTH_DEVZERO), strerror(err));
- return (AM_ERROR);
- } else
- noanon = 1;
- }
-#endif
- return (AM_NOSUP);
-}
-
-/*
- * Map anonymous memory from /dev/zero, or via MAP_ANON.
- *
- * (MAP_ANON only appears on Solaris 8, so we need fall-back
- * behavior for older systems.)
- */
-caddr_t
+void *
dz_map(Lm_list *lml, caddr_t addr, size_t len, int prot, int flags)
{
caddr_t va;
- int err;
- Am_ret amret;
-
- amret = anon_map(lml, &addr, len, prot, flags);
-
- if (amret == AM_OK)
- return (addr);
- if (amret == AM_ERROR)
+
+ if ((va = (caddr_t)mmap(addr, len, prot,
+ (flags | MAP_ANON), -1, 0)) == MAP_FAILED) {
+ int err = errno;
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAPANON),
+ strerror(err));
return (MAP_FAILED);
-
- /* amret == AM_NOSUP -> fallback to a devzero mmaping */
-
- if (dz_fd == FD_UNAVAIL) {
- if ((dz_fd = open(MSG_ORIG(MSG_PTH_DEVZERO),
- O_RDONLY)) == FD_UNAVAIL) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN),
- MSG_ORIG(MSG_PTH_DEVZERO), strerror(err));
- return (MAP_FAILED);
- }
- }
-
- if ((va = mmap(addr, len, prot, flags, dz_fd, 0)) == MAP_FAILED) {
- err = errno;
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAP),
- MSG_ORIG(MSG_PTH_DEVZERO), strerror(err));
}
return (va);
}
-static int pr_fd = FD_UNAVAIL;
-
-int
-pr_open(Lm_list *lml)
-{
- char proc[16];
-
- if (pr_fd == FD_UNAVAIL) {
- (void) snprintf(proc, 16, MSG_ORIG(MSG_FMT_PROC),
- (int)getpid());
- if ((pr_fd = open(proc, O_RDONLY)) == FD_UNAVAIL) {
- int err = errno;
-
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc,
- strerror(err));
- }
- }
- return (pr_fd);
-}
-
static int nu_fd = FD_UNAVAIL;
-caddr_t
+void *
nu_map(Lm_list *lml, caddr_t addr, size_t len, int prot, int flags)
{
caddr_t va;
@@ -3240,42 +3119,45 @@
* Determine whether a search path has been used.
*/
static void
-is_path_used(Lm_list *lml, Word unref, int *nl, Pnode *pnp, const char *obj)
+is_path_used(Lm_list *lml, Word unref, int *nl, Alist *alp, const char *obj)
{
- for (; pnp; pnp = pnp->p_next) {
+ Pdesc *pdp;
+ Aliste idx;
+
+ for (ALIST_TRAVERSE(alp, idx, pdp)) {
const char *fmt, *name;
- if ((pnp->p_len == 0) || (pnp->p_orig & PN_FLG_USED))
+ if ((pdp->pd_plen == 0) || (pdp->pd_flags & PD_FLG_USED))
continue;
/*
* If this pathname originated from an expanded token, use the
* original for any diagnostic output.
*/
- if ((name = pnp->p_oname) == NULL)
- name = pnp->p_name;
+ if ((name = pdp->pd_oname) == NULL)
+ name = pdp->pd_pname;
if (unref == 0) {
if ((*nl)++ == 0)
DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
- DBG_CALL(Dbg_unused_path(lml, name, pnp->p_orig,
- (pnp->p_orig & PN_FLG_DUPLICAT), obj));
+ DBG_CALL(Dbg_unused_path(lml, name, pdp->pd_flags,
+ (pdp->pd_flags & PD_FLG_DUPLICAT), obj));
continue;
}
- if (pnp->p_orig & LA_SER_LIBPATH) {
- if (pnp->p_orig & LA_SER_CONFIG) {
- if (pnp->p_orig & PN_FLG_DUPLICAT)
+ if (pdp->pd_flags & LA_SER_LIBPATH) {
+ if (pdp->pd_flags & LA_SER_CONFIG) {
+ if (pdp->pd_flags & PD_FLG_DUPLICAT)
fmt = MSG_INTL(MSG_DUP_LDLIBPATHC);
else
fmt = MSG_INTL(MSG_USD_LDLIBPATHC);
} else {
- if (pnp->p_orig & PN_FLG_DUPLICAT)
+ if (pdp->pd_flags & PD_FLG_DUPLICAT)
fmt = MSG_INTL(MSG_DUP_LDLIBPATH);
else
fmt = MSG_INTL(MSG_USD_LDLIBPATH);
}
- } else if (pnp->p_orig & LA_SER_RUNPATH) {
+ } else if (pdp->pd_flags & LA_SER_RUNPATH) {
fmt = MSG_INTL(MSG_USD_RUNPATH);
} else
continue;
@@ -3415,47 +3297,6 @@
}
/*
- * Initialization routine for the Fmap structure. If the fmap structure is
- * already in use, any mapping is released. The structure is then initialized
- * in preparation for further use.
- */
-void
-fmap_setup()
-{
-#if defined(MAP_ALIGN)
- /*
- * If MAP_ALIGN is set, the fm_addr has been seeded with an alignment
- * value. Otherwise, if fm_addr is non-null it indicates a mapping that
- * should now be freed.
- */
- if (fmap->fm_maddr && ((fmap->fm_mflags & MAP_ALIGN) == 0))
- (void) munmap((caddr_t)fmap->fm_maddr, fmap->fm_msize);
-
- /*
- * Providing we haven't determined that this system doesn't support
- * MAP_ALIGN, initialize the mapping address with the default segment
- * alignment.
- */
- if ((rtld_flags2 & RT_FL2_NOMALIGN) == 0) {
- fmap->fm_maddr = (char *)M_SEGM_ALIGN;
- fmap->fm_mflags = MAP_PRIVATE | MAP_ALIGN;
- } else {
- fmap->fm_maddr = 0;
- fmap->fm_mflags = MAP_PRIVATE;
- }
-#else
- if (fmap->fm_maddr)
- (void) munmap((caddr_t)fmap->fm_maddr, fmap->fm_msize);
-
- fmap->fm_maddr = 0;
- fmap->fm_mflags = MAP_PRIVATE;
-#endif
-
- fmap->fm_msize = FMAP_SIZE;
- fmap->fm_hwptr = 0;
-}
-
-/*
* Generic cleanup routine called prior to returning control to the user.
* Insures that any ld.so.1 specific file descriptors or temporary mapping are
* released, and any locks dropped.
@@ -3463,9 +3304,9 @@
void
leave(Lm_list *lml, int flags)
{
- Lm_list *elml = lml;
- Rt_map *clmp;
- Aliste idx;
+ Lm_list *elml = lml;
+ Rt_map *clmp;
+ Aliste idx;
/*
* Alert the debuggers that the link-maps are consistent. Note, in the
@@ -3486,23 +3327,11 @@
aplist_delete(elml->lm_actaudit, &idx);
}
- if (dz_fd != FD_UNAVAIL) {
- (void) close(dz_fd);
- dz_fd = FD_UNAVAIL;
- }
-
- if (pr_fd != FD_UNAVAIL) {
- (void) close(pr_fd);
- pr_fd = FD_UNAVAIL;
- }
-
if (nu_fd != FD_UNAVAIL) {
(void) close(nu_fd);
nu_fd = FD_UNAVAIL;
}
- fmap_setup();
-
/*
* Reinitialize error message pointer, and any overflow indication.
*/
@@ -3510,6 +3339,12 @@
prevptr = 0;
/*
+ * Defragment any freed memory.
+ */
+ if (aplist_nitems(free_alp))
+ defrag();
+
+ /*
* Don't drop our lock if we are running on our link-map list as
* there's little point in doing so since we are single-threaded.
*
@@ -3680,13 +3515,12 @@
void
security(uid_t uid, uid_t euid, gid_t gid, gid_t egid, int auxflags)
{
-#ifdef AT_SUN_AUXFLAGS
if (auxflags != -1) {
if ((auxflags & AF_SUN_SETUGID) != 0)
rtld_flags |= RT_FL_SECURE;
return;
}
-#endif
+
if (uid == (uid_t)-1)
uid = getuid();
if (uid) {
--- a/usr/src/cmd/sgs/rtld/i386/Makefile Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/i386/Makefile Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
BASEPLAT = i386
@@ -35,14 +33,13 @@
analyze.o elf.o external.o globals.o \
malloc.o paths.o setup.o util.o \
dlfcns.o config_elf.o locale.o tsort.o \
- getcwd.o remove.o move.o tls.o \
- cap.o
+ remove.o move.o tls.o cap.o
S_COMOBJS= debug.o audit.o object.o
G_MACHOBJS= doreloc.o
-P_MACHOBJS= i386_elf.o _setup.o zero.o
+P_MACHOBJS= i386_elf.o _setup.o
CP_MACHOBJS=
--- a/usr/src/cmd/sgs/rtld/i386/_setup.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/i386/_setup.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,8 +29,6 @@
* All Rights Reserved
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* i386 specific setup routine - relocate ld.so's symbols, setup its
* environment, map in loadable sections of the executable.
@@ -49,42 +47,29 @@
#include <sys/stat.h>
#include <link.h>
#include <dlfcn.h>
-#include <debug.h>
#include "_rtld.h"
#include "_audit.h"
#include "msg.h"
-extern int _end;
-extern int _etext;
-
-
-/*
- * Stub routine to prevent atexit_init() being extracted from libc_pic.a on
- * i386 and added to ld.so.1. We don't need it.
- */
-void
-atexit_init()
-{
-}
-
/* VARARGS */
unsigned long
-_setup(Boot * ebp, Dyn * ld_dyn)
+_setup(Boot *ebp, Dyn *ld_dyn)
{
- unsigned long reladdr, relcount, ld_base = 0;
- unsigned long relent = 0;
- unsigned long strtab, soname, interp_base = 0;
+ ulong_t reladdr, relcount, ld_base = 0;
+ ulong_t relent = 0;
+ ulong_t strtab, soname, interp_base = 0;
char *_rt_name, **_envp, **_argv;
- int _syspagsz = 0, fd = -1, dz_fd = FD_UNAVAIL;
+ int _syspagsz = 0, fd = -1;
uint_t _flags = 0, hwcap_1 = 0;
- Dyn * dyn_ptr;
- Phdr * phdr = 0;
- Rt_map * lmp;
+ Dyn *dyn_ptr;
+ Phdr *phdr = NULL;
+ Rt_map *lmp;
auxv_t *auxv, *_auxv;
uid_t uid = (uid_t)-1, euid = (uid_t)-1;
gid_t gid = (gid_t)-1, egid = (gid_t)-1;
- char *_platform = 0, *_execname = 0, *_emulator = 0;
+ char *_platform = NULL, *_execname = NULL, *_emulator = NULL;
int auxflags = -1;
+
/*
* Scan the bootstrap structure to pick up the basics.
*/
@@ -102,9 +87,6 @@
case EB_AUXV:
_auxv = (auxv_t *)ebp->eb_un.eb_ptr;
break;
- case EB_DEVZERO:
- dz_fd = (int)ebp->eb_un.eb_val;
- break;
case EB_PAGESIZE:
_syspagsz = (int)ebp->eb_un.eb_val;
break;
@@ -153,34 +135,26 @@
/* real group id for the executable */
gid = (gid_t)auxv->a_un.a_val;
break;
-#ifdef AT_SUN_PLATFORM /* Defined on SunOS 5.5 & greater. */
case AT_SUN_PLATFORM:
/* platform name */
_platform = auxv->a_un.a_ptr;
break;
-#endif
-#ifdef AT_SUN_EXECNAME /* Defined on SunOS 5.6 & greater. */
case AT_SUN_EXECNAME:
/* full pathname of execed object */
_execname = auxv->a_un.a_ptr;
break;
-#endif
-#ifdef AT_SUN_AUXFLAGS /* At the behest of PSARC 2002/188 */
case AT_SUN_AUXFLAGS:
+ /* auxiliary flags */
auxflags = (int)auxv->a_un.a_val;
break;
-#endif
-#ifdef AT_SUN_HWCAP /* Hardware capabilities */
case AT_SUN_HWCAP:
+ /* hardware capabilities */
hwcap_1 = (uint_t)auxv->a_un.a_val;
break;
-#endif
-#ifdef AT_SUN_EMULATOR /* Emulation library name */
case AT_SUN_EMULATOR:
/* name of emulation library, if any */
_emulator = auxv->a_un.a_ptr;
break;
-#endif
}
}
@@ -211,18 +185,15 @@
_rt_name = (char *)strtab + soname;
/*
- * If we don't have a RELENT, just assume
- * the size.
+ * If we don't have a RELENT, just assume the size.
*/
if (relent == 0)
relent = sizeof (Rel);
/*
- * Relocate all symbols in ld.so.
- *
- * Because ld.so.1 is built with -Bsymbolic there should only be
- * RELATIVE and JMPSLOT relocations, both of which get relative
- * additions against them.
+ * As all global symbol references within ld.so.1 are protected
+ * (symbolic), only RELATIVE and JMPSLOT relocations should be left
+ * to process at runtime. Process all relative relocations now.
*/
for (; relcount; relcount--) {
ulong_t roffset;
@@ -255,8 +226,8 @@
* Continue with generic startup processing.
*/
if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform,
- _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr,
- _execname, _argv, dz_fd, uid, euid, gid, egid, NULL, auxflags,
+ _syspagsz, _rt_name, ld_base, interp_base, fd, phdr,
+ _execname, _argv, uid, euid, gid, egid, NULL, auxflags,
hwcap_1)) == NULL) {
rtldexit(&lml_main, 1);
}
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,8 +29,6 @@
* All Rights Reserved
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* x86 machine dependent and ELF file class dependent functions.
* Contains routines for performing function binding and symbol relocations.
@@ -49,9 +47,9 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_inline.h"
#include "msg.h"
-
extern void elf_rtbndr(Rt_map *, ulong_t, caddr_t);
int
@@ -69,7 +67,7 @@
}
void
-ldso_plt_init(Rt_map * lmp)
+ldso_plt_init(Rt_map *lmp)
{
/*
* There is no need to analyze ld.so because we don't map in any of
@@ -178,7 +176,6 @@
return ((caddr_t)dyn_plt);
}
-
/*
* Function binding routine - invoked on the first call to a function through
* the procedure linkage table;
@@ -274,7 +271,7 @@
rtldexit(lml, 1);
}
- if ((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_SYMBIND) {
+ if ((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_SYMBIND) {
uint_t symndx = (((uintptr_t)nsym -
(uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp));
symval = audit_symbind(lmp, nlmp, nsym, symndx, symval,
@@ -285,7 +282,7 @@
addr = rptr->r_offset;
if (!(FLAGS(lmp) & FLG_RT_FIXED))
addr += ADDR(lmp);
- if (((lml->lm_tflags | FLAGS1(lmp)) &
+ if (((lml->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -333,12 +330,6 @@
load_completion(nlmp);
/*
- * If the object we've bound to is in the process of being initialized
- * by another thread, determine whether we should block.
- */
- is_dep_ready(nlmp, lmp, DBG_WAIT_SYMBOL);
-
- /*
* Make sure the object to which we've bound has had it's .init fired.
* Cleanup before return to user code.
*/
@@ -353,93 +344,23 @@
return (symval);
}
-
-/*
- * When the relocation loop realizes that it's dealing with relative
- * relocations in a shared object, it breaks into this tighter loop
- * as an optimization.
- */
-ulong_t
-elf_reloc_relative(ulong_t relbgn, ulong_t relend, ulong_t relsiz,
- ulong_t basebgn, ulong_t etext, ulong_t emap)
-{
- ulong_t roffset = ((Rel *)relbgn)->r_offset;
- char rtype;
-
- do {
- roffset += basebgn;
-
- /*
- * If this relocation is against an address not mapped in,
- * then break out of the relative relocation loop, falling
- * back on the main relocation loop.
- */
- if (roffset < etext || roffset > emap)
- break;
-
- /*
- * Perform the actual relocation.
- */
- *((ulong_t *)roffset) += basebgn;
-
- relbgn += relsiz;
-
- if (relbgn >= relend)
- break;
-
- rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info, M_MACH);
- roffset = ((Rel *)relbgn)->r_offset;
-
- } while (rtype == R_386_RELATIVE);
-
- return (relbgn);
-}
-
-/*
- * This is the tightest loop for RELATIVE relocations for those
- * objects built with the DT_RELACOUNT .dynamic entry.
- */
-ulong_t
-elf_reloc_relacount(ulong_t relbgn, ulong_t relacount, ulong_t relsiz,
- ulong_t basebgn)
-{
- ulong_t roffset = ((Rel *) relbgn)->r_offset;
-
- for (; relacount; relacount--) {
- roffset += basebgn;
-
- /*
- * Perform the actual relocation.
- */
- *((ulong_t *)roffset) += basebgn;
-
- relbgn += relsiz;
-
- roffset = ((Rel *)relbgn)->r_offset;
-
- }
-
- return (relbgn);
-}
-
/*
* Read and process the relocations for one link object, we assume all
* relocation sections for loadable segments are stored contiguously in
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
{
- ulong_t relbgn, relend, relsiz, basebgn;
- ulong_t pltbgn, pltend, _pltbgn, _pltend;
- ulong_t roffset, rsymndx, psymndx = 0, etext = ETEXT(lmp);
- ulong_t emap, dsymndx;
+ ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend;
+ ulong_t _pltbgn, _pltend;
+ ulong_t dsymndx, roffset, rsymndx, psymndx = 0;
uchar_t rtype;
long value, pvalue;
Sym *symref, *psymref, *symdef, *psymdef;
char *name, *pname;
Rt_map *_lmp, *plmp;
- int textrel = 0, ret = 1, noplt = 0;
+ int ret = 1, noplt = 0;
int relacount = RELACOUNT(lmp), plthint = 0;
Rel *rel;
uint_t binfo, pbinfo;
@@ -451,11 +372,18 @@
* to find this useful.
*/
if ((plt == 0) && PLTGOT(lmp)) {
- if ((ulong_t)PLTGOT(lmp) < etext) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0)
- return (0);
- textrel = 1;
- }
+ mmapobj_result_t *mpp;
+
+ /*
+ * Make sure the segment is writable.
+ */
+ if ((((mpp =
+ find_segment((caddr_t)PLTGOT(lmp), lmp)) != NULL) &&
+ ((mpp->mr_prot & PROT_WRITE) == 0)) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
+ return (0);
+
elf_plt_init(PLTGOT(lmp), (caddr_t)lmp);
}
@@ -465,10 +393,8 @@
if ((pltbgn = (ulong_t)JMPREL(lmp)) != 0)
pltend = pltbgn + (ulong_t)(PLTRELSZ(lmp));
-
relsiz = (ulong_t)(RELENT(lmp));
basebgn = ADDR(lmp);
- emap = ADDR(lmp) + MSIZE(lmp);
if (PLTRELSZ(lmp))
plthint = PLTRELSZ(lmp) / relsiz;
@@ -555,41 +481,25 @@
* Loop through relocations.
*/
while (relbgn < relend) {
- uint_t sb_flags = 0;
+ mmapobj_result_t *mpp;
+ uint_t sb_flags = 0;
rtype = ELF_R_TYPE(((Rel *)relbgn)->r_info, M_MACH);
/*
* If this is a RELATIVE relocation in a shared object (the
* common case), and if we are not debugging, then jump into a
- * tighter relocation loop (elf_reloc_relative). Only make the
- * jump if we've been given a hint on the number of relocations.
+ * tighter relocation loop (elf_reloc_relative).
*/
if ((rtype == R_386_RELATIVE) &&
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
- /*
- * It's possible that the relative relocation block
- * has relocations against the text segment as well
- * as the data segment. Since our optimized relocation
- * engine does not check which segment the relocation
- * is against - just mprotect it now if it's been
- * marked as containing TEXTREL's.
- */
- if ((textrel == 0) && (FLAGS1(lmp) & FL1_RT_TEXTREL)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
- }
-
if (relacount) {
- relbgn = elf_reloc_relacount(relbgn, relacount,
- relsiz, basebgn);
+ relbgn = elf_reloc_relative_count(relbgn,
+ relacount, relsiz, basebgn, lmp, textrel);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, etext, emap);
+ relsiz, basebgn, lmp, textrel);
}
if (relbgn >= relend)
break;
@@ -602,7 +512,6 @@
* If this is a shared object, add the base address to offset.
*/
if (!(FLAGS(lmp) & FLG_RT_FIXED)) {
-
/*
* If we're processing lazy bindings, we have to step
* through the plt entries and add the base address
@@ -611,8 +520,8 @@
if (plthint && (plt == 0) &&
(rtype == R_386_JMP_SLOT) &&
((MODE(lmp) & RTLD_NOW) == 0)) {
- relbgn = elf_reloc_relacount(relbgn,
- plthint, relsiz, basebgn);
+ relbgn = elf_reloc_relative_count(relbgn,
+ plthint, relsiz, basebgn, lmp, textrel);
plthint = 0;
continue;
}
@@ -635,21 +544,18 @@
}
/*
- * If we're promoting plts determine if this one has already
+ * If we're promoting plts, determine if this one has already
* been written.
*/
- if (plt) {
- if ((*(ulong_t *)roffset < _pltbgn) ||
- (*(ulong_t *)roffset > _pltend))
- continue;
- }
+ if (plt && ((*(ulong_t *)roffset < _pltbgn) ||
+ (*(ulong_t *)roffset > _pltend)))
+ continue;
/*
* If this relocation is not against part of the image
* mapped into memory we skip it.
*/
- if ((roffset < ADDR(lmp)) || (roffset > (ADDR(lmp) +
- MSIZE(lmp)))) {
+ if ((mpp = find_segment((caddr_t)roffset, lmp)) == NULL) {
elf_reloc_bad(lmp, (void *)rel, rtype, roffset,
rsymndx);
continue;
@@ -727,7 +633,7 @@
binfo = pbinfo;
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
value = audit_symbind(lmp, _lmp,
/* LINTED */
@@ -764,8 +670,8 @@
if (elf_reloc_error(lmp, name,
rel, binfo))
continue;
-
- ret = 0;
+
+ ret = 0;
break;
} else {
@@ -826,7 +732,7 @@
pbinfo = binfo;
}
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
dsymndx = (((uintptr_t)symdef -
(uintptr_t)SYMTAB(_lmp)) /
@@ -880,15 +786,13 @@
M_REL_SHT_TYPE, rel, NULL, name));
/*
- * If this object has relocations in the text segment, turn
- * off the write protect.
+ * Make sure the segment is writable.
*/
- if ((roffset < etext) && (textrel == 0)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
+ if (((mpp->mr_prot & PROT_WRITE) == 0) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL))) {
+ ret = 0;
+ break;
}
/*
@@ -901,7 +805,7 @@
ret = 0;
break;
case R_386_JMP_SLOT:
- if (((LIST(lmp)->lm_tflags | FLAGS1(lmp)) &
+ if (((LIST(lmp)->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -949,7 +853,7 @@
}
}
- return (relocate_finish(lmp, bound, textrel, ret));
+ return (relocate_finish(lmp, bound, ret));
}
/*
@@ -1080,7 +984,7 @@
const char *
_conv_reloc_type(uint_t rel)
{
- static Conv_inv_buf_t inv_buf;
+ static Conv_inv_buf_t inv_buf;
return (conv_reloc_386_type(rel, 0, &inv_buf));
}
--- a/usr/src/cmd/sgs/rtld/i386/zero.c Wed Jan 21 09:18:26 2009 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * 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.
- *
- * 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 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-
-void
-zero(caddr_t addr, size_t len)
-{
- int _len = (int)len;
-
- while (_len-- > 0) {
- /* Align and go faster */
- if (((intptr_t)addr & ((sizeof (int) - 1))) == 0) {
- /* LINTED */
- int *w = (int *)addr;
- /* LINTED */
- while (_len > 0) {
- *w++ = 0;
- _len -= sizeof (int);
- }
- return;
- }
- *addr++ = 0;
- }
-}
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,7 +38,6 @@
uint_t w_flags;
} W_desc;
-
/*
* Flags values for dcmds
*/
@@ -81,13 +80,11 @@
static const mdb_bitmask_t rtflags1_bits[] = {
{ MSG_ORIG(MSG_FL1_COPYTOOK), FL1_RT_COPYTOOK, FL1_RT_COPYTOOK},
- { MSG_ORIG(MSG_FL1_RELATIVE), FL1_RT_RELATIVE, FL1_RT_RELATIVE },
{ MSG_ORIG(MSG_FL1_CONFSET), FL1_RT_CONFSET, FL1_RT_CONFSET },
{ MSG_ORIG(MSG_FL1_NODEFLIB), FL1_RT_NODEFLIB, FL1_RT_NODEFLIB },
{ MSG_ORIG(MSG_FL1_ENDFILTE), FL1_RT_ENDFILTE, FL1_RT_ENDFILTE },
{ MSG_ORIG(MSG_FL1_DISPREL), FL1_RT_DISPREL, FL1_RT_DISPREL },
- { MSG_ORIG(MSG_FL1_TEXTREL), FL1_RT_TEXTREL, FL1_RT_TEXTREL },
- { MSG_ORIG(MSG_FL1_INITWAIT), FL1_RT_INITWAIT, FL1_RT_INITWAIT },
+ { MSG_ORIG(MSG_FL1_DTFLAGS), FL1_RT_DTFLAGS, FL1_RT_DTFLAGS},
{ MSG_ORIG(MSG_FL1_LDDSTUB), FL1_RT_LDDSTUB, FL1_RT_LDDSTUB},
{ MSG_ORIG(MSG_FL1_NOINIFIN), FL1_RT_NOINIFIN, FL1_RT_NOINIFIN },
{ MSG_ORIG(MSG_FL1_USED), FL1_RT_USED, FL1_RT_USED },
@@ -100,7 +97,10 @@
{ MSG_ORIG(MSG_FL1_TLSSTAT), FL1_RT_TLSSTAT, FL1_RT_TLSSTAT },
{ MSG_ORIG(MSG_FL1_DIRECT), FL1_RT_DIRECT, FL1_RT_DIRECT},
{ MSG_ORIG(MSG_FL1_GLOBAUD), FL1_RT_GLOBAUD, FL1_RT_GLOBAUD},
+ { NULL, 0, 0}
+};
+static const mdb_bitmask_t rtaflags_bits[] = {
{ MSG_ORIG(MSG_LTFL_AUD_PREINIT), LML_TFLG_AUD_PREINIT,
LML_TFLG_AUD_PREINIT },
{ MSG_ORIG(MSG_LTFL_AUD_OBJSEARCH), LML_TFLG_AUD_OBJSEARCH,
@@ -274,7 +274,7 @@
{
APlist apl;
uintptr_t listcalc, listndx;
- Bnd_desc * bdp;
+ Bnd_desc *bdp;
/*
* Obtain the APlist and determine its number of elements and those
@@ -478,15 +478,19 @@
mdb_printf(MSG_ORIG(MSG_RTMAP_LINE20), FLAGS(&rtmap), rtflags_bits);
mdb_printf(MSG_ORIG(MSG_RTMAP_LINE13), FLAGS1(&rtmap));
mdb_printf(MSG_ORIG(MSG_RTMAP_LINE20), FLAGS1(&rtmap), rtflags1_bits);
- mdb_printf(MSG_ORIG(MSG_RTMAP_LINE14), MODE(&rtmap));
+ if (AFLAGS(&rtmap)) {
+ mdb_printf(MSG_ORIG(MSG_RTMAP_LINE14), AFLAGS(&rtmap));
+ mdb_printf(MSG_ORIG(MSG_RTMAP_LINE20), AFLAGS(&rtmap),
+ rtaflags_bits);
+ }
+ mdb_printf(MSG_ORIG(MSG_RTMAP_LINE15), MODE(&rtmap));
mdb_printf(MSG_ORIG(MSG_RTMAP_LINE20), MODE(&rtmap), rtmode_bits);
return (DCMD_OK);
}
-
static int
-rtmap_format(uintptr_t addr, const void * data, void * private)
+rtmap_format(uintptr_t addr, const void *data, void *private)
{
const Rt_map *lmp = (const Rt_map *)data;
W_desc *wdp = (W_desc *)private;
@@ -618,9 +622,9 @@
static int
/* ARGSUSED2 */
-format_listnode(uintptr_t addr, const void * data, void * private)
+format_listnode(uintptr_t addr, const void *data, void *private)
{
- Listnode * lnp = (Listnode *)data;
+ Listnode *lnp = (Listnode *)data;
mdb_printf(MSG_ORIG(MSG_FMT_LN), addr, lnp->data, lnp->next);
return (0);
@@ -780,6 +784,12 @@
{ MSG_ORIG(MSG_LFL_OBJREEVAL), LML_FLG_OBJREEVAL, LML_FLG_OBJREEVAL },
{ MSG_ORIG(MSG_LFL_NOPENDGLBLAZY), LML_FLG_NOPENDGLBLAZY,
LML_FLG_NOPENDGLBLAZY },
+ { MSG_ORIG(MSG_LFL_INTRPOSETSORT), LML_FLG_INTRPOSETSORT,
+ LML_FLG_INTRPOSETSORT },
+ { MSG_ORIG(MSG_LFL_AUDITNOTIFY), LML_FLG_AUDITNOTIFY,
+ LML_FLG_AUDITNOTIFY },
+ { MSG_ORIG(MSG_LFL_GROUPSEXIST), LML_FLG_GROUPSEXIST,
+ LML_FLG_GROUPSEXIST },
{ MSG_ORIG(MSG_LFL_TRC_LDDSTUB), LML_FLG_TRC_LDDSTUB,
LML_FLG_TRC_LDDSTUB },
@@ -794,6 +804,10 @@
{ MSG_ORIG(MSG_LFL_TRC_UNUSED), LML_FLG_TRC_UNUSED,
LML_FLG_TRC_UNUSED },
{ MSG_ORIG(MSG_LFL_TRC_INIT), LML_FLG_TRC_INIT, LML_FLG_TRC_INIT },
+ { MSG_ORIG(MSG_LFL_TRC_NOUNRESWEAK), LML_FLG_TRC_NOUNRESWEAK,
+ LML_FLG_TRC_NOUNRESWEAK },
+ { MSG_ORIG(MSG_LFL_TRC_NOPAREXT), LML_FLG_TRC_NOPAREXT,
+ LML_FLG_TRC_NOPAREXT },
{ NULL, 0, 0}
};
@@ -1180,7 +1194,7 @@
uint_t flg = 0;
APlist apl;
uintptr_t listcalc, listndx;
- Grp_hdl * ghp;
+ Grp_hdl *ghp;
/*
* Insure we have a valid address, and provide for a -v option.
@@ -1277,7 +1291,7 @@
APlist apl;
uint_t flg = 0;
uintptr_t listcalc, listndx;
- Grp_hdl * ghp;
+ Grp_hdl *ghp;
/*
* Insure we have a valid address, and provide for a -v option.
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -94,13 +94,11 @@
@ MSG_FLG_RELOCING "RELOCATING"
@ MSG_FL1_COPYTOOK "COPYTOOK"
-@ MSG_FL1_RELATIVE "RELATIVE"
@ MSG_FL1_CONFSET "CONFSET"
@ MSG_FL1_NODEFLIB "NO-DEFAULT-LIBPATH"
@ MSG_FL1_ENDFILTE "END-FILTEE"
@ MSG_FL1_DISPREL "DISPLACEMENT-RELOCATED"
-@ MSG_FL1_TEXTREL "TEXT-RELOCATED"
-@ MSG_FL1_INITWAIT "INIT-WAIT"
+@ MSG_FL1_DTFLAGS "DTFLAGS-AVAILABLE"
@ MSG_FL1_LDDSTUB "LDDSTUB"
@ MSG_FL1_NOINIFIN "NO-INITFINI"
@ MSG_FL1_USED "USED"
@@ -144,36 +142,41 @@
@ MSG_GPD_REMOVE "REMOVAL-CANDIDATE"
@ MSG_GPD_PROMOTE "RTLD_NOW-PROMOTER"
-@ MSG_LFL_BASELM "BASELM"
-@ MSG_LFL_RTLDLM "RTLDLM"
-@ MSG_LFL_NOAUDIT "NO-AUDIT"
-@ MSG_LFL_PLTREL "DEFERRED-PLT-RELOCATION"
-@ MSG_LFL_HOLDLOCK "HOLD-LOCK"
-@ MSG_LFL_ENVIRON "ENVIRON"
-@ MSG_LFL_INTRPOSE "INTERPOSE"
-@ MSG_LFL_LOCAUDIT "LOCAL-AUDIT"
-@ MSG_LFL_LOADAVAIL "LOAD-AVAILABLE"
-@ MSG_LFL_IGNRELERR "IGNORE-RELOCATION-ERROR"
-@ MSG_LFL_DBNOTIF "DBG-NOTIFY"
-@ MSG_LFL_STARTREL "START-RELOCATION"
-@ MSG_LFL_ATEXIT "ATEXIT"
-@ MSG_LFL_OBJADDED "OBJECT-ADDED"
-@ MSG_LFL_OBJDELETED "OBJECT-DELETED"
-@ MSG_LFL_OBJREEVAL "OBJECT-REEVALUATE"
-@ MSG_LFL_NOPENDGLBLAZY "NO-PENDING-GLOBAL-LAZY-DEPENDENCY"
+@ MSG_LFL_BASELM "BASELM"
+@ MSG_LFL_RTLDLM "RTLDLM"
+@ MSG_LFL_NOAUDIT "NO-AUDIT"
+@ MSG_LFL_PLTREL "DEFERRED-PLT-RELOCATION"
+@ MSG_LFL_HOLDLOCK "HOLD-LOCK"
+@ MSG_LFL_ENVIRON "ENVIRON"
+@ MSG_LFL_INTRPOSE "INTERPOSE"
+@ MSG_LFL_LOCAUDIT "LOCAL-AUDIT"
+@ MSG_LFL_LOADAVAIL "LOAD-AVAILABLE"
+@ MSG_LFL_IGNRELERR "IGNORE-RELOCATION-ERROR"
+@ MSG_LFL_DBNOTIF "DBG-NOTIFY"
+@ MSG_LFL_STARTREL "START-RELOCATION"
+@ MSG_LFL_ATEXIT "ATEXIT"
+@ MSG_LFL_OBJADDED "OBJECT-ADDED"
+@ MSG_LFL_OBJDELETED "OBJECT-DELETED"
+@ MSG_LFL_OBJREEVAL "OBJECT-REEVALUATE"
+@ MSG_LFL_NOPENDGLBLAZY "NO-PENDING-GLOBAL-LAZY-DEPENDENCY"
+@ MSG_LFL_INTRPOSETSORT "INTERPOSE-TSORTING-DONE"
+@ MSG_LFL_AUDITNOTIFY "AUDIT-CONSISTANT-REQUIRED"
+@ MSG_LFL_GROUPSEXIST "LOCAL-GROUPS-EXIST"
-@ MSG_LFL_TRC_LDDSTUB "TRC_LDDSTUB"
-@ MSG_LFL_TRC_ENABLE "TRC_ENABLE"
-@ MSG_LFL_TRC_WARN "TRC_WARN"
-@ MSG_LFL_TRC_VERBOSE "TRC_VERBOSE"
-@ MSG_LFL_TRC_SEARCH "TRC_SEARCH"
-@ MSG_LFL_TRC_UNREF "TRC_UNREF"
-@ MSG_LFL_TRC_UNUSED "TRC_UNUSED"
-@ MSG_LFL_TRC_INIT "TRC_INIT"
+@ MSG_LFL_TRC_LDDSTUB "LDDSTUB"
+@ MSG_LFL_TRC_ENABLE "TRACING-ENABLED"
+@ MSG_LFL_TRC_WARN "TRACE-WARNINGS"
+@ MSG_LFL_TRC_VERBOSE "TRACE-VERBOSE"
+@ MSG_LFL_TRC_SEARCH "TRACE-SEARCH"
+@ MSG_LFL_TRC_UNREF "TRACE-UNREFERENCED"
+@ MSG_LFL_TRC_UNUSED "TRACE-UNUSED"
+@ MSG_LFL_TRC_INIT "TRACE-INIT"
+@ MSG_LFL_TRC_NOUNRESWEAK "TRACE-NO-UNRESOLVED-WEAKS"
+@ MSG_LFL_TRC_NOPAREXT "TRACE-NO-PARENT-OR-EXTERN"
-@ MSG_LTFL_NOLAZYLD "NOLAZYLD"
-@ MSG_LTFL_NODIRECT "NODIRECT"
-@ MSG_LTFL_LOADFLTR "LOADFLTR"
+@ MSG_LTFL_NOLAZYLD "NO-LAZY-LOADING"
+@ MSG_LTFL_NODIRECT "NO-DIRECT"
+@ MSG_LTFL_LOADFLTR "LOAD-FILTER"
@ MSG_LTFL_AUD_PREINIT "AUD_PREINIT"
@ MSG_LTFL_AUD_OBJSEARCH "AUD_OBJSEARCH"
@@ -493,7 +496,8 @@
@ MSG_RTMAP_LINE11 " LIST: 0x%0?p [%a]\n"
@ MSG_RTMAP_LINE12 " FLAGS: 0x%08x\n"
@ MSG_RTMAP_LINE13 " FLAGS1: 0x%08x\n"
-@ MSG_RTMAP_LINE14 " MODE: 0x%08x\n"
+@ MSG_RTMAP_LINE14 " AFLAGS: 0x%08x\n"
+@ MSG_RTMAP_LINE15 " MODE: 0x%08x\n"
@ MSG_RTMAP_LINE20 " [ %#b ]\n"
@ MSG_RTMAP_HELP "\
--- a/usr/src/cmd/sgs/rtld/sparc/Makefile Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparc/Makefile Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# Object lists are organized into primary (most frequently used code) and
# secondary lists (less frequently used code, ie. a.out support).
@@ -33,8 +31,7 @@
analyze.o elf.o external.o globals.o \
malloc.o paths.o setup.o util.o \
dlfcns.o config_elf.o locale.o tsort.o \
- getcwd.o remove.o move.o tls.o \
- cap.o
+ remove.o move.o tls.o cap.o
S_COMOBJS= debug.o audit.o object.o cache_a.out.o \
a.out.o
@@ -47,7 +44,7 @@
S_MACHOBJS= sparc_a.out.o
-P_ASOBJS= boot.o boot_elf.o caller.o zero.o
+P_ASOBJS= boot.o boot_elf.o caller.o
S_ASOBJS= boot_a.out.o
--- a/usr/src/cmd/sgs/rtld/sparc/_setup.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparc/_setup.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,8 +29,6 @@
* All Rights Reserved
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* SPARC specific setup routine - relocate ld.so's symbols, setup its
* environment, map in loadable sections of the executable.
@@ -44,8 +42,6 @@
#include <signal.h>
#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
#include <sys/auxv.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -58,31 +54,26 @@
#include "_a.out.h"
#endif /* A_OUT */
-extern int _end;
-extern int _etext;
-extern void _init(void);
-
-
/* VARARGS */
unsigned long
-_setup(Boot * ebp, Dyn * ld_dyn)
+_setup(Boot *ebp, Dyn *ld_dyn)
{
- unsigned long reladdr, relacount, ld_base = 0;
- unsigned long relaent = 0;
- unsigned long strtab, soname, interp_base = 0;
+ ulong_t reladdr, relacount, ld_base = 0;
+ ulong_t relaent = 0;
+ ulong_t strtab, soname, interp_base = 0;
char *_rt_name, **_envp, **_argv;
- int _syspagsz = 0, fd = -1, dz_fd = FD_UNAVAIL;
+ int _syspagsz = 0, fd = -1;
uint_t _flags = 0, hwcap_1 = 0;
- Dyn * dyn_ptr;
- Phdr * phdr = 0;
- Rt_map * lmp;
+ Dyn *dyn_ptr;
+ Phdr *phdr = NULL;
+ Rt_map *lmp;
auxv_t *auxv, *_auxv;
uid_t uid = (uid_t)-1, euid = (uid_t)-1;
gid_t gid = (gid_t)-1, egid = (gid_t)-1;
- char *_platform = 0, *_execname = 0, *_emulator = 0;
+ char *_platform = NULL, *_execname = NULL, *_emulator = NULL;
int auxflags = -1;
#ifdef A_OUT
- void * aoutdyn = 0;
+ void *aoutdyn = NULL;
#endif /* A_OUT */
/*
@@ -92,7 +83,7 @@
switch (ebp->eb_tag) {
case EB_DYNAMIC:
#ifdef A_OUT
- aoutdyn = (struct link_dynamic *)ebp->eb_un.eb_val;
+ aoutdyn = (Link_dynamic *)ebp->eb_un.eb_val;
#endif /* A_OUT */
break;
case EB_LDSO_BASE:
@@ -107,9 +98,6 @@
case EB_AUXV:
_auxv = (auxv_t *)ebp->eb_un.eb_ptr;
break;
- case EB_DEVZERO:
- dz_fd = (int)ebp->eb_un.eb_val;
- break;
case EB_PAGESIZE:
_syspagsz = (int)ebp->eb_un.eb_val;
break;
@@ -158,34 +146,26 @@
/* real group id for the executable */
gid = (gid_t)auxv->a_un.a_val;
break;
-#ifdef AT_SUN_PLATFORM /* Defined on SunOS 5.5 & greater. */
case AT_SUN_PLATFORM:
/* platform name */
_platform = auxv->a_un.a_ptr;
break;
-#endif
-#ifdef AT_SUN_EXECNAME /* Defined on SunOS 5.6 & greater. */
case AT_SUN_EXECNAME:
/* full pathname of execed object */
_execname = auxv->a_un.a_ptr;
break;
-#endif
-#ifdef AT_SUN_AUXFLAGS /* At the behest of PSARC 2002/188 */
case AT_SUN_AUXFLAGS:
+ /* auxiliary flags */
auxflags = (int)auxv->a_un.a_val;
break;
-#endif
-#ifdef AT_SUN_HWCAP /* Hardware capabilities */
case AT_SUN_HWCAP:
+ /* hardware capabilities */
hwcap_1 = (uint_t)auxv->a_un.a_val;
break;
-#endif
-#ifdef AT_SUN_EMULATOR /* Emulation library name */
case AT_SUN_EMULATOR:
/* name of emulation library, if any */
_emulator = auxv->a_un.a_ptr;
break;
-#endif
}
}
@@ -216,22 +196,22 @@
_rt_name = (char *)strtab + soname;
/*
- * If we don't have a RELAENT, just assume
- * the size.
+ * If we don't have a RELAENT, just assume the size.
*/
if (relaent == 0)
relaent = sizeof (Rela);
/*
- * Because ld.so.1 is built with -Bsymbolic there should only be
- * RELATIVE and JMPSLOT relocations. Process all relatives first.
+ * As all global symbol references within ld.so.1 are protected
+ * (symbolic), only RELATIVE and JMPSLOT relocations should be left
+ * to process at runtime. Process all relative relocations now.
*/
for (; relacount; relacount--) {
ulong_t roffset;
roffset = ((Rela *)reladdr)->r_offset + ld_base;
*((ulong_t *)roffset) = ld_base +
- (long)(((Rela *)reladdr)->r_addend);
+ ((Rela *)reladdr)->r_addend;
reladdr += relaent;
}
@@ -248,17 +228,19 @@
/*
* Continue with generic startup processing.
*/
+ /* BEGIN CSTYLED */
if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform,
- _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr,
- _execname, _argv, dz_fd, uid, euid, gid, egid,
+ _syspagsz, _rt_name, ld_base, interp_base, fd, phdr,
+ _execname, _argv, uid, euid, gid, egid,
#ifdef A_OUT
- aoutdyn, auxflags, hwcap_1)) == (Rt_map *)0) {
+ aoutdyn, auxflags, hwcap_1)) == NULL) {
#else
/* CSTYLED */
NULL, auxflags, hwcap_1)) == NULL) {
#endif /* A_OUT */
rtldexit(&lml_main, 1);
}
+ /* END CSTYLED */
return (LM_ENTRY_PT(lmp)());
}
--- a/usr/src/cmd/sgs/rtld/sparc/common_sparc.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparc/common_sparc.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 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>
@@ -92,10 +90,10 @@
}
int
-elf_regsyms(Rt_map * lmp)
+elf_regsyms(Rt_map *lmp)
{
- Dyn * dyn;
- Sym * symdef;
+ Dyn *dyn;
+ Sym *symdef;
ulong_t rsymndx;
/*
@@ -105,7 +103,7 @@
* with any other register symbols.
*/
for (dyn = DYN(lmp); dyn->d_tag != DT_NULL; dyn++) {
- Reglist * rp;
+ Reglist *rp;
if ((dyn->d_tag != DT_SPARC_REGISTER) &&
(dyn->d_tag != DT_DEPRECATED_SPARC_REGISTER))
@@ -156,7 +154,7 @@
return (0);
}
}
- if ((rp = calloc(sizeof (Reglist), 1)) == (Reglist *)0)
+ if ((rp = calloc(sizeof (Reglist), 1)) == NULL)
return (0);
rp->rl_lmp = lmp;
rp->rl_sym = symdef;
@@ -165,73 +163,3 @@
}
return (1);
}
-
-
-/*
- * When the relocation loop realizes that it's dealing with relative
- * relocations in a shared object, it breaks into this tighter loop
- * as an optimization.
- */
-ulong_t
-elf_reloc_relative(ulong_t relbgn, ulong_t relend, ulong_t relsiz,
- ulong_t basebgn, ulong_t etext, ulong_t emap)
-{
- ulong_t roffset = ((Rela *) relbgn)->r_offset;
- Byte rtype;
-
- do {
- roffset += basebgn;
-
- /*
- * If this relocation is against an address not mapped in,
- * then break out of the relative relocation loop, falling
- * back on the main relocation loop.
- */
- if (roffset < etext || roffset > emap)
- break;
-
- /*
- * Perform the actual relocation.
- */
- *((ulong_t *)roffset) +=
- basebgn + (long)(((Rela *)relbgn)->r_addend);
-
- relbgn += relsiz;
-
- if (relbgn >= relend)
- break;
-
- rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
- roffset = ((Rela *)relbgn)->r_offset;
-
- } while (rtype == R_SPARC_RELATIVE);
-
- return (relbgn);
-}
-
-/*
- * This is the tightest loop for RELATIVE relocations for those
- * objects built with the DT_RELACOUNT .dynamic entry.
- */
-ulong_t
-elf_reloc_relacount(ulong_t relbgn, ulong_t relacount, ulong_t relsiz,
- ulong_t basebgn)
-{
- ulong_t roffset = ((Rela *) relbgn)->r_offset;
-
- for (; relacount; relacount--) {
- roffset += basebgn;
-
- /*
- * Perform the actual relocation.
- */
- *((ulong_t *)roffset) =
- basebgn + (long)(((Rela *)relbgn)->r_addend);
-
- relbgn += relsiz;
-
- roffset = ((Rela *)relbgn)->r_offset;
- }
-
- return (relbgn);
-}
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,6 +43,7 @@
#include "_a.out.h"
#include "_rtld.h"
#include "_audit.h"
+#include "_inline.h"
#include "msg.h"
extern void iflush_range(caddr_t, size_t);
@@ -85,7 +86,7 @@
entry = enter(0);
for (lmp = lml_main.lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
- if (FCT(lmp) == &aout_fct) {
+ if (THIS_IS_AOUT(lmp)) {
if (pc > (caddr_t)(LM2LP(lmp)->lp_plt) &&
pc < (caddr_t)((int)LM2LP(lmp)->lp_plt +
AOUTDYN(lmp)->v2->ld_plt_sz)) {
@@ -155,12 +156,6 @@
load_completion(llmp);
/*
- * If the object we've bound to is in the process of being initialized
- * by another thread, determine whether we should block.
- */
- is_dep_ready(nlmp, lmp, DBG_WAIT_SYMBOL);
-
- /*
* Make sure the object to which we've bound has had it's .init fired.
* Cleanup before return to user code.
*/
@@ -203,19 +198,18 @@
};
int
-aout_reloc(Rt_map * lmp, uint_t plt, int *in_nfavl)
+aout_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
{
int k; /* loop temporary */
int nr; /* number of relocations */
char *name; /* symbol being searched for */
- long *et; /* cached _etext of object */
long value; /* relocation temporary */
long *ra; /* cached relocation address */
struct relocation_info *rp; /* current relocation */
struct nlist *sp; /* symbol table of "symbol" */
Rt_map * _lmp; /* lm which holds symbol definition */
Sym * sym; /* symbol definition */
- int textrel = 0, ret = 1;
+ int ret = 1;
APlist *bound = NULL;
Lm_list *lml = LIST(lmp);
@@ -230,7 +224,6 @@
return (1);
rp = LM2LP(lmp)->lp_rp;
- et = (long *)ETEXT(lmp);
nr = GETRELSZ(AOUTDYN(lmp)) / sizeof (struct relocation_info);
/*
@@ -244,19 +237,22 @@
* Loop through relocations.
*/
for (k = 0; k < nr; k++, rp++) {
+ mmapobj_result_t *mpp;
+
/* LINTED */
ra = (long *)&((char *)ADDR(lmp))[rp->r_address];
/*
- * Check to see if we're relocating in the text segment
- * and turn off the write protect if necessary.
+ * Make sure the segment is writable.
*/
- if ((ra < et) && (textrel == 0)) {
- if (aout_set_prot(lmp, PROT_WRITE) == 0) {
+ if (((mpp = find_segment((caddr_t)ra, lmp)) != NULL) &&
+ ((mpp->mr_prot & PROT_WRITE) == 0)) {
+ if ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp,
+ AL_CNT_TEXTREL) == NULL)) {
ret = 0;
break;
}
- textrel = 1;
}
/*
@@ -278,8 +274,8 @@
* Locate symbol. Initialize the symbol lookup data
* structure.
*/
- SLOOKUP_INIT(sl, name, lmp, 0, ld_entry_cnt, 0, 0, 0, 0,
- LKUP_STDRELOC);
+ SLOOKUP_INIT(sl, name, lmp, 0, ld_entry_cnt,
+ 0, 0, 0, 0, LKUP_STDRELOC);
if ((sym = aout_lookup_sym(&sl, &_lmp,
&binfo, in_nfavl)) == 0) {
@@ -436,5 +432,5 @@
}
}
- return (relocate_finish(lmp, bound, textrel, ret));
+ return (relocate_finish(lmp, bound, ret));
}
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,8 +29,6 @@
* All Rights Reserved
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* SPARC machine dependent and ELF file class dependent functions.
* Contains routines for performing function binding and symbol relocations.
@@ -49,13 +47,12 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_inline.h"
#include "msg.h"
-
extern void iflush_range(caddr_t, size_t);
extern void plt_full_range(uintptr_t, uintptr_t);
-
int
elf_mach_flags_check(Rej_desc *rej, Ehdr *ehdr)
{
@@ -87,7 +84,7 @@
}
void
-ldso_plt_init(Rt_map * lmp)
+ldso_plt_init(Rt_map *lmp)
{
/*
* There is no need to analyze ld.so because we don't map in any of
@@ -121,7 +118,6 @@
uintptr_t vpltaddr, pltaddr;
long disp;
-
pltaddr = addr + rel->r_offset;
vpltaddr = vaddr + rel->r_offset;
disp = symval - vpltaddr - 4;
@@ -135,6 +131,7 @@
Pltbindtype rc;
pltent = (uint_t *)pltaddr;
+
/*
* The
*
@@ -183,7 +180,6 @@
return (PLT_T_FULL);
}
-
/*
* Local storage space created on the stack created for this glue
* code includes space for:
@@ -245,7 +241,8 @@
int *fail)
{
extern ulong_t elf_plt_trace();
- uintptr_t dyn_plt, *dyndata;
+ uchar_t *dyn_plt;
+ uintptr_t *dyndata;
/*
* If both pltenter & pltexit have been disabled there
@@ -262,8 +259,8 @@
* We only need to add the glue code if there is an auditing
* library that is interested in this binding.
*/
- dyn_plt = (uintptr_t)AUDINFO(rlmp)->ai_dynplts +
- (pltndx * dyn_plt_ent_size);
+ dyn_plt = (uchar_t *)((uintptr_t)AUDINFO(rlmp)->ai_dynplts +
+ (pltndx * dyn_plt_ent_size));
/*
* Have we initialized this dynamic plt entry yet? If we haven't do it
@@ -271,21 +268,22 @@
* different plt (ie. from another shared object). In that case
* we just set the plt to point to the new dyn_plt.
*/
- if (*(uint_t *)dyn_plt == 0) {
+ if (*dyn_plt == 0) {
Sym *symp;
Xword symvalue;
Lm_list *lml = LIST(rlmp);
(void) memcpy((void *)dyn_plt, dyn_plt_template,
sizeof (dyn_plt_template));
- dyndata = (uintptr_t *)(dyn_plt + sizeof (dyn_plt_template));
+ dyndata = (uintptr_t *)((uintptr_t)dyn_plt +
+ sizeof (dyn_plt_template));
/*
* relocating:
* sethi %hi(dyndata), %g1
*/
symvalue = (Xword)dyndata;
- if (do_reloc_rtld(R_SPARC_HI22, (uchar_t *)(dyn_plt + 0x20),
+ if (do_reloc_rtld(R_SPARC_HI22, (dyn_plt + 0x20),
&symvalue, MSG_ORIG(MSG_SYM_LADYNDATA),
MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) {
*fail = 1;
@@ -297,7 +295,7 @@
* or %g1, %lo(dyndata), %g1
*/
symvalue = (Xword)dyndata;
- if (do_reloc_rtld(R_SPARC_LO10, (uchar_t *)(dyn_plt + 0x24),
+ if (do_reloc_rtld(R_SPARC_LO10, (dyn_plt + 0x24),
&symvalue, MSG_ORIG(MSG_SYM_LADYNDATA),
MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) {
*fail = 1;
@@ -309,8 +307,8 @@
* call elf_plt_trace
*/
symvalue = (Xword)((uintptr_t)&elf_plt_trace -
- (dyn_plt + 0x28));
- if (do_reloc_rtld(R_SPARC_WDISP30, (uchar_t *)(dyn_plt + 0x28),
+ (uintptr_t)(dyn_plt + 0x28));
+ if (do_reloc_rtld(R_SPARC_WDISP30, (dyn_plt + 0x28),
&symvalue, MSG_ORIG(MSG_SYM_ELFPLTTRACE),
MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) {
*fail = 1;
@@ -329,12 +327,11 @@
iflush_range((void *)dyn_plt, sizeof (dyn_plt_template));
}
- (void) elf_plt_write((uintptr_t)addr, (uintptr_t)addr,
- rptr, (uintptr_t)dyn_plt, 0);
+ (void) elf_plt_write((uintptr_t)addr, (uintptr_t)addr, rptr,
+ (uintptr_t)dyn_plt, 0);
return ((caddr_t)dyn_plt);
}
-
/*
* Function binding routine - invoked on the first call to a function through
* the procedure linkage table;
@@ -359,12 +356,11 @@
Rela *rptr;
Sym *rsym, *nsym;
Xword pltndx;
- uint_t binfo, sb_flags = 0;
+ uint_t binfo, sb_flags = 0, dbg_class;
Slookup sl;
Pltbindtype pbtype;
int entry, lmflags;
- uint_t dbg_class;
- Lm_list *lml = LIST(lmp);
+ Lm_list *lml;
/*
* For compatibility with libthread (TI_VERSION 1) we track the entry
@@ -374,6 +370,7 @@
*/
entry = enter(0);
+ lml = LIST(lmp);
if ((lmflags = lml->lm_flags) & LML_FLG_RTLDLM) {
dbg_class = dbg_desc->d_class;
dbg_desc->d_class = 0;
@@ -394,7 +391,7 @@
/*
* Perform some basic sanity checks. If we didn't get a load map
* or the plt offset is invalid then its possible someone has walked
- * over the plt entries or jumped to plt0 out of the blue.
+ * over the plt entries or jumped to plt[0] out of the blue.
*/
if (!lmp || ((addr % M_PLT_ENTSIZE) != 0)) {
Conv_inv_buf_t inv_buf;
@@ -446,7 +443,7 @@
rtldexit(lml, 1);
}
- if ((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_SYMBIND) {
+ if ((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_SYMBIND) {
ulong_t symndx = (((uintptr_t)nsym -
(uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp));
@@ -461,7 +458,7 @@
pbtype = PLT_T_NONE;
if (!(rtld_flags & RT_FL_NOBIND)) {
- if (((lml->lm_tflags | FLAGS1(lmp)) &
+ if (((lml->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -508,12 +505,6 @@
load_completion(nlmp);
/*
- * If the object we've bound to is in the process of being initialized
- * by another thread, determine whether we should block.
- */
- is_dep_ready(nlmp, lmp, DBG_WAIT_SYMBOL);
-
- /*
* Make sure the object to which we've bound has had it's .init fired.
* Cleanup before return to user code.
*/
@@ -528,25 +519,22 @@
return (symval);
}
-
/*
* Read and process the relocations for one link object, we assume all
* relocation sections for loadable segments are stored contiguously in
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
{
ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend;
- ulong_t roffset, rsymndx, psymndx = 0, etext = ETEXT(lmp);
- ulong_t emap, dsymndx, pltndx;
+ ulong_t dsymndx, pltndx, roffset, rsymndx, psymndx = 0;
uchar_t rtype;
- long reladd, value, pvalue;
+ long reladd, value, pvalue, relacount = RELACOUNT(lmp);
Sym *symref, *psymref, *symdef, *psymdef;
char *name, *pname;
Rt_map *_lmp, *plmp;
- int textrel = 0, ret = 1, noplt = 0;
- long relacount = RELACOUNT(lmp);
+ int ret = 1, noplt = 0;
Rela *rel;
Pltbindtype pbtype;
uint_t binfo, pbinfo;
@@ -567,11 +555,18 @@
* to find this useful.
*/
if ((plt == 0) && PLTGOT(lmp)) {
- if ((ulong_t)PLTGOT(lmp) < etext) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0)
- return (0);
- textrel = 1;
- }
+ mmapobj_result_t *mpp;
+
+ /*
+ * Make sure the segment is writable.
+ */
+ if ((((mpp =
+ find_segment((caddr_t)PLTGOT(lmp), lmp)) != NULL) &&
+ ((mpp->mr_prot & PROT_WRITE) == 0)) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
+ return (0);
+
elf_plt_init(PLTGOT(lmp), (caddr_t)lmp);
}
@@ -626,7 +621,6 @@
relsiz = (ulong_t)(RELENT(lmp));
basebgn = ADDR(lmp);
- emap = ADDR(lmp) + MSIZE(lmp);
DBG_CALL(Dbg_reloc_run(lmp, M_REL_SHT_TYPE, plt, DBG_REL_START));
@@ -641,41 +635,26 @@
* Loop through relocations.
*/
while (relbgn < relend) {
- Addr vaddr;
- uint_t sb_flags = 0;
+ mmapobj_result_t *mpp;
+ uint_t sb_flags = 0;
+ Addr vaddr;
rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
/*
* If this is a RELATIVE relocation in a shared object (the
- * common case), and if we are not debugging, then jump into a
- * tighter relocation loop (elf_reloc_relative). Only make the
- * jump if we've been given a hint on the number of relocations.
+ * common case), and if we are not debugging, then jump into one
+ * of the tighter relocation loops.
*/
if ((rtype == R_SPARC_RELATIVE) &&
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
- /*
- * It's possible that the relative relocation block
- * has relocations against the text segment as well
- * as the data segment. Since our optimized relocation
- * engine does not check which segment the relocation
- * is against - just mprotect it now if it's been
- * marked as containing TEXTREL's.
- */
- if ((textrel == 0) && (FLAGS1(lmp) & FL1_RT_TEXTREL)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
- }
if (relacount) {
- relbgn = elf_reloc_relacount(relbgn, relacount,
- relsiz, basebgn);
+ relbgn = elf_reloc_relative_count(relbgn,
+ relacount, relsiz, basebgn, lmp, textrel);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, etext, emap);
+ relsiz, basebgn, lmp, textrel);
}
if (relbgn >= relend)
break;
@@ -713,8 +692,8 @@
* If this relocation is not against part of the image
* mapped into memory we skip it.
*/
- if ((roffset < ADDR(lmp)) || (roffset > (ADDR(lmp) +
- MSIZE(lmp)))) {
+ if ((mpp = find_segment((caddr_t)roffset,
+ lmp)) == NULL) {
elf_reloc_bad(lmp, (void *)rel, rtype, roffset,
rsymndx);
continue;
@@ -722,7 +701,7 @@
}
/*
- * If we're promoting .plts try and determine if this one has
+ * If we're promoting .plts, try and determine if this one has
* already been written. An uninitialized .plts' second
* instruction is a branch. Note, elf_plt_write() optimizes
* .plt relocations, and it's possible that a relocated entry
@@ -742,6 +721,7 @@
binfo = 0;
pltndx = (ulong_t)-1;
pbtype = PLT_T_NONE;
+
/*
* If a symbol index is specified then get the symbol table
* entry, locate the symbol definition, and determine its
@@ -812,7 +792,7 @@
binfo = pbinfo;
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
value = audit_symbind(lmp, _lmp,
/* LINTED */
@@ -911,7 +891,7 @@
pbinfo = binfo;
}
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
dsymndx = (((uintptr_t)symdef -
(uintptr_t)SYMTAB(_lmp)) /
@@ -974,16 +954,14 @@
M_REL_SHT_TYPE, rel, NULL, name));
/*
- * If this object has relocations in the text segment, turn
- * off the write protect.
+ * Make sure the segment is writable.
*/
- if ((rtype != R_SPARC_REGISTER) && (roffset < etext) &&
- (textrel == 0)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
+ if ((rtype != R_SPARC_REGISTER) &&
+ ((mpp->mr_prot & PROT_WRITE) == 0) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL))) {
+ ret = 0;
+ break;
}
/*
@@ -1038,7 +1016,7 @@
else
vaddr = ADDR(lmp);
- if (((LIST(lmp)->lm_tflags | FLAGS1(lmp)) &
+ if (((LIST(lmp)->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -1118,7 +1096,7 @@
}
}
- return (relocate_finish(lmp, bound, textrel, ret));
+ return (relocate_finish(lmp, bound, ret));
}
/*
--- a/usr/src/cmd/sgs/rtld/sparc/zero.s Wed Jan 21 09:18:26 2009 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +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 (c) 1988 AT&T
- * All Rights Reserved
- *
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Routine to zero out a section of memory (the tail end of the data segment
- * up to a page boundary). First nibble off any bytes up to the first double
- * aligned word, and then clear doubles until the byte count is zero. Note,
- * this assumes the count specified has been rounded to end on a double word
- * boundary.
- *
- * %o0 = addr, %o1 = len
- */
-#if defined(lint)
-
-#include <sys/types.h>
-
-void
-zero(caddr_t addr, size_t len)
-{
- while (len-- > 0)
- *addr++ = 0;
-}
-
-#else
-
-#include <sys/asm_linkage.h>
-
- .file "zero.s"
-
- ENTRY(zero)
- tst %o1 ! Have we any count at all?
- ba 3f ! Go find out,
- clr %g1 ! but prepare for long loop
-
-! Byte clearing loop
-
-0:
- inc %o0 ! Bump address
- deccc %o1 ! Decrement count
-3:
- bz 1f ! If no count left, exit
- andcc %o0, 7, %g0 ! Is the address less than double-word aligned?
- bnz,a 0b ! Branch if so
- clrb [%o0] ! but clear the current byte anyway
-
-! Double clearing loop
-
-2:
- std %g0, [%o0] ! Clear next 8 bytes
- subcc %o1, 8, %o1 ! Decrement count
- bnz 2b ! Branch if any left
- inc 8, %o0 ! but always increment address by 8
-1:
- retl ! Go home
- nop
- SET_SIZE(zero)
-#endif
--- a/usr/src/cmd/sgs/rtld/sparcv9/Makefile Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparcv9/Makefile Wed Jan 21 11:00:19 2009 -0800
@@ -20,11 +20,9 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# Object lists are organized into primary (most frequently used code) and
# secondary lists (less frequently used code, ie. a.out support).
@@ -33,8 +31,7 @@
analyze.o elf.o external.o globals.o \
malloc.o paths.o setup.o util.o \
dlfcns.o config_elf.o locale.o tsort.o \
- getcwd.o remove.o move.o tls.o \
- cap.o
+ remove.o move.o tls.o cap.o
S_COMOBJS= debug.o audit.o object.o
@@ -46,7 +43,7 @@
S_MACHOBJS=
-P_ASOBJS= boot.o boot_elf.o caller.o zero.o
+P_ASOBJS= boot.o boot_elf.o caller.o
S_ASOBJS=
--- a/usr/src/cmd/sgs/rtld/sparcv9/_setup.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparcv9/_setup.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,8 +29,6 @@
* All Rights Reserved
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* SPARCV9-specific setup routine - relocate ld.so's symbols, setup its
* environment, map in loadable sections of the executable.
@@ -53,28 +51,23 @@
#include "_audit.h"
#include "msg.h"
-extern int _end;
-extern int _etext;
-extern void _init(void);
-
-
/* VARARGS */
unsigned long
_setup(Boot *ebp, Dyn *ld_dyn)
{
- unsigned long reladdr, relacount, ld_base = 0;
- unsigned long relaent = 0;
- unsigned long strtab, soname, interp_base = 0;
+ ulong_t reladdr, relacount, ld_base = 0;
+ ulong_t relaent = 0;
+ ulong_t strtab, soname, interp_base = 0;
char *_rt_name, **_envp, **_argv;
- int _syspagsz = 0, fd = -1, dz_fd = FD_UNAVAIL;
+ int _syspagsz = 0, fd = -1;
uint_t _flags = 0, hwcap_1 = 0;
Dyn *dyn_ptr;
- Phdr *phdr = 0;
+ Phdr *phdr = NULL;
Rt_map *lmp;
auxv_t *auxv, *_auxv;
uid_t uid = (uid_t)-1, euid = (uid_t)-1;
gid_t gid = (gid_t)-1, egid = (gid_t)-1;
- char *_platform = 0, *_execname = 0, *_emulator = 0;
+ char *_platform = NULL, *_execname = NULL, *_emulator = NULL;
int auxflags = -1;
/*
@@ -94,12 +87,7 @@
case EB_AUXV:
_auxv = (auxv_t *)ebp->eb_un.eb_ptr;
break;
- case EB_DEVZERO:
- /* LINTED */
- dz_fd = (int)ebp->eb_un.eb_val;
- break;
case EB_PAGESIZE:
- /* LINTED */
_syspagsz = (int)ebp->eb_un.eb_val;
break;
}
@@ -111,17 +99,14 @@
switch (auxv->a_type) {
case AT_EXECFD:
/* this is the old exec that passes a file descriptor */
- /* LINTED */
fd = (int)auxv->a_un.a_val;
break;
case AT_FLAGS:
/* processor flags (MAU available, etc) */
- /* LINTED */
- _flags = (Word)auxv->a_un.a_val;
+ _flags = auxv->a_un.a_val;
break;
case AT_PAGESZ:
/* system page size */
- /* LINTED */
_syspagsz = (int)auxv->a_un.a_val;
break;
case AT_PHDR:
@@ -136,52 +121,40 @@
break;
case AT_SUN_UID:
/* effective user id for the executable */
- /* LINTED */
euid = (uid_t)auxv->a_un.a_val;
break;
case AT_SUN_RUID:
/* real user id for the executable */
- /* LINTED */
uid = (uid_t)auxv->a_un.a_val;
break;
case AT_SUN_GID:
/* effective group id for the executable */
- /* LINTED */
egid = (gid_t)auxv->a_un.a_val;
break;
case AT_SUN_RGID:
/* real group id for the executable */
- /* LINTED */
gid = (gid_t)auxv->a_un.a_val;
break;
-#ifdef AT_SUN_PLATFORM /* Defined on SunOS 5.5 & greater. */
case AT_SUN_PLATFORM:
/* platform name */
_platform = auxv->a_un.a_ptr;
break;
-#endif
-#ifdef AT_SUN_EXECNAME /* Defined on SunOS 5.6 & greater. */
case AT_SUN_EXECNAME:
/* full pathname of execed object */
_execname = auxv->a_un.a_ptr;
break;
-#endif
-#ifdef AT_SUN_AUXFLAGS /* At the behest of PSARC 2002/188 */
case AT_SUN_AUXFLAGS:
+ /* auxiliary flags */
auxflags = (int)auxv->a_un.a_val;
break;
-#endif
-#ifdef AT_SUN_HWCAP /* Hardware capabilities */
case AT_SUN_HWCAP:
+ /* hardware capabilities */
hwcap_1 = (uint_t)auxv->a_un.a_val;
break;
-#endif
-#ifdef AT_SUN_EMULATOR /* Emulation library name */
case AT_SUN_EMULATOR:
/* name of emulation library, if any */
_emulator = auxv->a_un.a_ptr;
break;
-#endif
}
}
@@ -212,15 +185,15 @@
_rt_name = (char *)strtab + soname;
/*
- * If we don't have a RELAENT, just assume
- * the size.
+ * If we don't have a RELAENT, just assume the size.
*/
if (relaent == 0)
relaent = sizeof (Rela);
/*
- * Because ld.so.1 is built with -Bsymbolic there should only be
- * RELATIVE and JMPSLOT relocations. Process all relatives first.
+ * As all global symbol references within ld.so.1 are protected
+ * (symbolic), only RELATIVE and JMPSLOT relocations should be left
+ * to process at runtime. Process all relative relocations now.
*/
for (; relacount; relacount--) {
ulong_t roffset;
@@ -245,8 +218,8 @@
* Continue with generic startup processing.
*/
if ((lmp = setup((char **)_envp, (auxv_t *)_auxv, _flags, _platform,
- _syspagsz, _rt_name, dyn_ptr, ld_base, interp_base, fd, phdr,
- _execname, _argv, dz_fd, uid, euid, gid, egid, NULL, auxflags,
+ _syspagsz, _rt_name, ld_base, interp_base, fd, phdr,
+ _execname, _argv, uid, euid, gid, egid, NULL, auxflags,
hwcap_1)) == NULL) {
rtldexit(&lml_main, 1);
}
--- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* SPARC V9 machine dependent and ELF file class dependent functions.
* Contains routines for performing function binding and symbol relocations.
@@ -44,6 +42,7 @@
#include "_rtld.h"
#include "_audit.h"
#include "_elf.h"
+#include "_inline.h"
#include "msg.h"
extern void iflush_range(caddr_t, size_t);
@@ -53,7 +52,6 @@
extern void elf_rtbndr(Rt_map *, ulong_t, caddr_t);
extern void elf_rtbndr_far(Rt_map *, ulong_t, caddr_t);
-
int
elf_mach_flags_check(Rej_desc *rej, Ehdr *ehdr)
{
@@ -95,7 +93,7 @@
void
-ldso_plt_init(Rt_map * lmp)
+ldso_plt_init(Rt_map *lmp)
{
/*
* There is no need to analyze ld.so because we don't map in any of
@@ -172,6 +170,7 @@
Pltbindtype rc;
pltent = (uint_t *)pltaddr;
+
/*
* The
*
@@ -232,8 +231,6 @@
return (PLT_T_FULL);
}
-
-
/*
* Once relocated, the following 6 instruction sequence moves
* a 64-bit immediate value into register %g1
@@ -271,7 +268,6 @@
/* to get 8-byte alignment */
};
-
int dyn_plt_ent_size = sizeof (dyn_plt_template) +
sizeof (Addr) + /* reflmp */
sizeof (Addr) + /* deflmp */
@@ -279,7 +275,6 @@
sizeof (Word) + /* sb_flags */
sizeof (Sym); /* symdef */
-
/*
* the dynamic plt entry is:
*
@@ -325,7 +320,6 @@
* Sym symdef (Elf64_Sym = 24-bytes)
*/
-
/*
* Relocate the instructions given by the VAL64_TO_G1 macro above.
* The arguments parallel those of do_reloc_rtld().
@@ -340,7 +334,7 @@
* Returns TRUE for success, FALSE for failure.
*/
static int
-reloc_val64_to_g1(Byte *off, Addr *value, const char *sym, Lm_list *lml)
+reloc_val64_to_g1(uchar_t *off, Addr *value, const char *sym, Lm_list *lml)
{
Xword tmp_value;
@@ -388,12 +382,13 @@
}
static caddr_t
-elf_plt_trace_write(caddr_t addr, Rela * rptr, Rt_map * rlmp, Rt_map * dlmp,
- Sym * sym, uint_t symndx, ulong_t pltndx, caddr_t to, uint_t sb_flags,
+elf_plt_trace_write(caddr_t addr, Rela *rptr, Rt_map *rlmp, Rt_map *dlmp,
+ Sym *sym, uint_t symndx, ulong_t pltndx, caddr_t to, uint_t sb_flags,
int *fail)
{
extern ulong_t elf_plt_trace();
- Addr dyn_plt, *dyndata;
+ uchar_t *dyn_plt;
+ uintptr_t *dyndata;
/*
* If both pltenter & pltexit have been disabled there
@@ -410,8 +405,8 @@
* We only need to add the glue code if there is an auditing
* library that is interested in this binding.
*/
- dyn_plt = (Xword)AUDINFO(rlmp)->ai_dynplts +
- (pltndx * dyn_plt_ent_size);
+ dyn_plt = (uchar_t *)((uintptr_t)AUDINFO(rlmp)->ai_dynplts +
+ (pltndx * dyn_plt_ent_size));
/*
* Have we initialized this dynamic plt entry yet? If we haven't do it
@@ -419,24 +414,24 @@
* different plt (ie. from another shared object). In that case
* we just set the plt to point to the new dyn_plt.
*/
- if (*(Word *)dyn_plt == 0) {
+ if (*dyn_plt == 0) {
Sym *symp;
Lm_list *lml = LIST(rlmp);
(void) memcpy((void *)dyn_plt, dyn_plt_template,
sizeof (dyn_plt_template));
- dyndata = (Addr *)(dyn_plt + sizeof (dyn_plt_template));
+ dyndata = (uintptr_t *)((uintptr_t)dyn_plt +
+ sizeof (dyn_plt_template));
/*
* relocating:
* VAL64_TO_G1(dyndata)
* VAL64_TO_G1(&elf_plt_trace)
*/
- if (!(reloc_val64_to_g1((Byte *) (dyn_plt + 0x14), dyndata,
+ if (!(reloc_val64_to_g1((dyn_plt + 0x14), dyndata,
MSG_ORIG(MSG_SYM_LADYNDATA), lml) &&
- reloc_val64_to_g1((Byte *) (dyn_plt + 0x30),
- (Addr *)&elf_plt_trace, MSG_ORIG(MSG_SYM_ELFPLTTRACE),
- lml))) {
+ reloc_val64_to_g1((dyn_plt + 0x30), (Addr *)&elf_plt_trace,
+ MSG_ORIG(MSG_SYM_ELFPLTTRACE), lml))) {
*fail = 1;
return (0);
}
@@ -477,7 +472,6 @@
*
* On error, causes process to terminate with a signal.
*/
-
ulong_t
elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from)
{
@@ -487,13 +481,12 @@
Rela *rptr;
Sym *rsym, *nsym;
Xword pltndx;
- uint_t binfo, sb_flags = 0;
+ uint_t binfo, sb_flags = 0, dbg_class;
ulong_t rsymndx;
Slookup sl;
Pltbindtype pbtype;
int entry, lmflags, farplt = 0;
- uint_t dbg_class;
- Lm_list *lml = LIST(lmp);
+ Lm_list *lml;
/*
* For compatibility with libthread (TI_VERSION 1) we track the entry
@@ -503,6 +496,7 @@
*/
entry = enter(0);
+ lml = LIST(lmp);
if ((lmflags = lml->lm_flags) & LML_FLG_RTLDLM) {
dbg_class = dbg_desc->d_class;
dbg_desc->d_class = 0;
@@ -588,7 +582,7 @@
rtldexit(lml, 1);
}
- if ((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_SYMBIND) {
+ if ((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_SYMBIND) {
/* LINTED */
uint_t symndx = (uint_t)(((uintptr_t)nsym -
(uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp));
@@ -604,7 +598,7 @@
pbtype = PLT_T_NONE;
if (!(rtld_flags & RT_FL_NOBIND)) {
- if (((lml->lm_tflags | FLAGS1(lmp)) &
+ if (((lml->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -653,18 +647,12 @@
load_completion(nlmp);
/*
- * If the object we've bound to is in the process of being initialized
- * by another thread, determine whether we should block.
- */
- is_dep_ready(nlmp, lmp, DBG_WAIT_SYMBOL);
-
- /*
* Make sure the object to which we've bound has had it's .init fired.
* Cleanup before return to user code.
*/
if (entry) {
is_dep_init(nlmp, lmp);
- leave(LIST(lmp), 0);
+ leave(lml, 0);
}
if (lmflags & LML_FLG_RTLDLM)
@@ -673,7 +661,6 @@
return (symval);
}
-
static int
bindpltpad(Rt_map *lmp, List *padlist, Addr value, void **pltaddr,
const char *fname, const char *sname)
@@ -714,7 +701,6 @@
rel.r_info = 0;
rel.r_addend = 0;
-
/*
* elf_plt_write assumes the plt was previously filled
* with NOP's, so fill it in now.
@@ -752,11 +738,10 @@
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
{
ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend;
- ulong_t roffset, rsymndx, psymndx = 0, etext = ETEXT(lmp);
- ulong_t emap, pltndx;
+ ulong_t pltndx, roffset, rsymndx, psymndx = 0;
uint_t dsymndx, binfo, pbinfo;
Byte rtype;
long reladd;
@@ -764,7 +749,7 @@
Sym *symref, *psymref, *symdef, *psymdef;
char *name, *pname;
Rt_map *_lmp, *plmp;
- int textrel = 0, ret = 1, noplt = 0;
+ int ret = 1, noplt = 0;
long relacount = RELACOUNT(lmp);
Rela *rel;
Pltbindtype pbtype;
@@ -786,13 +771,18 @@
* to find this useful.
*/
if ((plt == 0) && PLTGOT(lmp)) {
- Xword pltoff;
+ mmapobj_result_t *mpp;
+ Xword pltoff;
- if ((ulong_t)PLTGOT(lmp) < etext) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0)
- return (0);
- textrel = 1;
- }
+ /*
+ * Make sure the segment is writable.
+ */
+ if ((((mpp =
+ find_segment((caddr_t)PLTGOT(lmp), lmp)) != NULL) &&
+ ((mpp->mr_prot & PROT_WRITE) == 0)) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
+ return (0);
/*
* Install the lm pointer in .PLT2 as per the ABI.
@@ -867,7 +857,6 @@
relsiz = (ulong_t)(RELENT(lmp));
basebgn = ADDR(lmp);
- emap = ADDR(lmp) + MSIZE(lmp);
DBG_CALL(Dbg_reloc_run(lmp, M_REL_SHT_TYPE, plt, DBG_REL_START));
@@ -882,8 +871,9 @@
* Loop through relocations.
*/
while (relbgn < relend) {
- Addr vaddr;
- uint_t sb_flags = 0;
+ mmapobj_result_t *mpp;
+ uint_t sb_flags = 0;
+ Addr vaddr;
rtype = (Byte)ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
@@ -896,28 +886,13 @@
*/
if ((rtype == R_SPARC_RELATIVE) &&
((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
- /*
- * It's possible that the relative relocation block
- * has relocations against the text segment as well
- * as the data segment. Since our optimized relocation
- * engine does not check which segment the relocation
- * is against - just mprotect it now if it's been
- * marked as containing TEXTREL's.
- */
- if ((textrel == 0) && (FLAGS1(lmp) & FL1_RT_TEXTREL)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
- }
if (relacount) {
- relbgn = elf_reloc_relacount(relbgn, relacount,
- relsiz, basebgn);
+ relbgn = elf_reloc_relative_count(relbgn,
+ relacount, relsiz, basebgn, lmp, textrel);
relacount = 0;
} else {
relbgn = elf_reloc_relative(relbgn, relend,
- relsiz, basebgn, etext, emap);
+ relsiz, basebgn, lmp, textrel);
}
if (relbgn >= relend)
break;
@@ -956,8 +931,8 @@
* If this relocation is not against part of the image
* mapped into memory we skip it.
*/
- if ((roffset < ADDR(lmp)) || (roffset > (ADDR(lmp) +
- MSIZE(lmp)))) {
+ if ((mpp = find_segment((caddr_t)roffset,
+ lmp)) == NULL) {
elf_reloc_bad(lmp, (void *)rel, rtype, roffset,
rsymndx);
continue;
@@ -965,7 +940,7 @@
}
/*
- * If we're promoting plts determine if this one has already
+ * If we're promoting plts, determine if this one has already
* been written. An uninitialized plts' second instruction is a
* branch.
*/
@@ -982,6 +957,7 @@
binfo = 0;
pltndx = (ulong_t)-1;
pbtype = PLT_T_NONE;
+
/*
* If a symbol index is specified then get the symbol table
* entry, locate the symbol definition, and determine its
@@ -1054,7 +1030,7 @@
binfo = pbinfo;
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
value = audit_symbind(lmp, _lmp,
/* LINTED */
@@ -1153,7 +1129,7 @@
pbinfo = binfo;
}
if ((LIST(_lmp)->lm_tflags |
- FLAGS1(_lmp)) &
+ AFLAGS(_lmp)) &
LML_TFLG_AUD_SYMBIND) {
/* LINTED */
dsymndx = (((uintptr_t)symdef -
@@ -1220,16 +1196,14 @@
M_REL_SHT_TYPE, rel, NULL, name));
/*
- * If this object has relocations in the text segment, turn
- * off the write protect.
+ * Make sure the segment is writable.
*/
- if ((rtype != R_SPARC_REGISTER) && (roffset < etext) &&
- (textrel == 0)) {
- if (elf_set_prot(lmp, PROT_WRITE) == 0) {
- ret = 0;
- break;
- }
- textrel = 1;
+ if ((rtype != R_SPARC_REGISTER) &&
+ ((mpp->mr_prot & PROT_WRITE) == 0) &&
+ ((set_prot(lmp, mpp, 1) == 0) ||
+ (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL))) {
+ ret = 0;
+ break;
}
/*
@@ -1284,7 +1258,7 @@
else
vaddr = ADDR(lmp);
- if (((LIST(lmp)->lm_tflags | FLAGS1(lmp)) &
+ if (((LIST(lmp)->lm_tflags | AFLAGS(lmp)) &
(LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
AUDINFO(lmp)->ai_dynplts) {
int fail = 0;
@@ -1385,22 +1359,20 @@
* Free up any items on the pltpadlist if it was allocated
*/
if (pltpadlist.head) {
- Listnode * lnp;
- Listnode * plnp;
- Pltpadinfo * pip;
+ Listnode *lnp, *plnp = NULL;
+ Pltpadinfo *pip;
- plnp = 0;
for (LIST_TRAVERSE(&pltpadlist, lnp, pip)) {
- if (plnp != 0)
+ if (plnp)
free(plnp);
free(pip);
plnp = lnp;
}
- if (plnp != 0)
+ if (plnp)
free(plnp);
}
- return (relocate_finish(lmp, bound, textrel, ret));
+ return (relocate_finish(lmp, bound, ret));
}
/*
--- a/usr/src/cmd/sgs/rtld/sparcv9/zero.s Wed Jan 21 09:18:26 2009 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Routine to zero out a section of memory (the tail end of the data segment
- * up to a page boundary). First nibble off any bytes up to the first double
- * aligned word, and then clear doubles until the byte count is zero. Note,
- * this assumes the count specified has been rounded to end on a double word
- * boundary.
- *
- * %o0 = addr, %o1 = len
- */
-#if defined(lint)
-
-#include <sys/types.h>
-
-void
-zero(caddr_t addr, size_t len)
-{
- while (len-- > 0)
- *addr++ = 0;
-}
-
-#else
-
-#include <sys/asm_linkage.h>
-
- .file "zero.s"
-
- ENTRY(zero)
- tst %o1 ! Have we any count at all?
- ba 3f ! Go find out,
- clr %g1 ! but prepare for long loop
-
-! Byte clearing loop
-
-0:
- inc %o0 ! Bump address
- deccc %o1 ! Decrement count
-3:
- bz,pn %xcc, 1f ! If no count left, exit
- andcc %o0, 7, %g0 ! Is the address less than double-word aligned?
- bnz,a 0b ! Branch if so
- clrb [%o0] ! but clear the current byte anyway
-
-! Double clearing loop
-
-2:
- stx %g0, [%o0] ! Clear next 8 bytes
- subcc %o1, 8, %o1 ! Decrement count
- bnz,pt %xcc, 2b ! Branch if any left
- inc 8, %o0 ! but always increment address by 8
-1:
- retl ! Go home
- nop
- SET_SIZE(zero)
-#endif
--- a/usr/src/cmd/sgs/tools/common/alist.c Wed Jan 21 09:18:26 2009 -0800
+++ b/usr/src/cmd/sgs/tools/common/alist.c Wed Jan 21 11:00:19 2009 -0800
@@ -20,19 +20,14 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sgs.h>
#include <string.h>
#include <stdio.h>
#include <sys/debug.h>
-
-
/*
* Alist manipulation. An Alist is a list of elements formed into an array.
* Traversal of the list is an array scan, which because of the locality of
@@ -41,8 +36,6 @@
* See alist.h for more background information about array lists.
*/
-
-
/*
* Insert a value into an array at a specified index:
*
@@ -249,13 +242,9 @@
return (&lp->apl_data[idx]);
}
-
-
-
-
/*
* Append a value to a list. These are convenience wrappers on top
- * of the insert operation. See the decription of those routine above
+ * of the insert operation. See the description of those routine above
* for details.
*/
void *
@@ -275,10 +264,6 @@
return (aplist_insert(lpp, ptr, init_arritems, ndx));
}
-
-
-
-
/*
* Delete the item at a specified index/offset, and decrement the variable
* containing the index:
@@ -371,10 +356,6 @@
(*idxp)--;
}
-
-
-
-
/*
* Delete the pointer with a specified value from the APlist.
*
@@ -409,12 +390,6 @@
return (0);
}
-
-
-
-
-
-
/*
* Search the APlist for an element with a given value, and
* if not found, optionally append the element to the end of the list.
@@ -464,12 +439,6 @@
return (ALE_CREATE);
}
-
-
-
-
-
-
/*
* Reset the given list to its empty state. Any memory allocated by the
* list is preserved, ready for reuse, but the list is set to its