changeset 13004:92dfdb3a48cc

6935867 .dynamic could be readonly in sharable objects
author Rod Evans <Rod.Evans@Oracle.COM>
date Mon, 02 Aug 2010 14:04:48 -0700
parents b4084e8201cf
children c7857ae656c6
files usr/src/cmd/sgs/include/i386/machdep_x86.h usr/src/cmd/sgs/include/sparc/machdep_sparc.h usr/src/cmd/sgs/libld/common/sections.c usr/src/cmd/sgs/libld/common/update.c usr/src/cmd/sgs/packages/common/SUNWonld-README usr/src/cmd/sgs/rtld/common/elf.c usr/src/uts/common/sys/link.h
diffstat 7 files changed, 130 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sgs/include/i386/machdep_x86.h	Mon Aug 02 13:32:36 2010 -0700
+++ b/usr/src/cmd/sgs/include/i386/machdep_x86.h	Mon Aug 02 14:04:48 2010 -0700
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  *
  * Global include file for all sgs ia32 based machine dependent macros,
  * constants and declarations.
@@ -218,23 +217,27 @@
  * maintained consistently, where appropriate, in each platform specific header
  * file.
  *
- *  o	null identifies that this section does not need to be added to the
+ *  -	null identifies that this section does not need to be added to the
  *	output image (ie. shared object sections or sections we're going to
  *	recreate (sym tables, string tables, relocations, etc.)).
  *
- *  o	any user defined section will be first in the associated segment.
+ *  -	any user defined section will be first in the associated segment.
  *
- *  o	interp and capabilities sections are next, as these are accessed
+ *  -	interp and capabilities sections are next, as these are accessed
  *	immediately the first page of the image is mapped.
  *
- *  o	the syminfo, hash, dynsym, dynstr and rel's are grouped together as
- *	these will all be accessed first by ld.so.1 to perform relocations.
+ *  -	objects that do not provide an interp normally have a read-only
+ *	.dynamic section that comes next (in this case, there is no need to
+ *	update a DT_DEBUG entry at runtime).
  *
- *  o	the got and dynamic are grouped together as these may also be
+ *  -	the syminfo, hash, dynsym, dynstr and rel's are grouped together as
+ *	these will all be accessed together by ld.so.1 to perform relocations.
+ *
+ *  -	the got and dynamic are grouped together as these may also be
  *	accessed first by ld.so.1 to perform relocations, fill in DT_DEBUG
  *	(executables only), and .got[0].
  *
- *  o	unknown sections (stabs, comments, etc.) go at the end.
+ *  -	unknown sections (stabs, comments, etc.) go at the end.
  *
  * Note that .tlsbss/.bss are given the largest identifiers.  This insures that
  * if any unknown sections become associated to the same segment as the .bss,
@@ -245,28 +248,31 @@
 
 #define	M_ID_INTERP	0x02			/* SHF_ALLOC */
 #define	M_ID_CAP	0x03
+#define	M_ID_CAPINFO	0x04
+#define	M_ID_CAPCHAIN	0x05
 
-#define	M_ID_UNWINDHDR	0x06
-#define	M_ID_UNWIND	0x07
-#define	M_ID_CAPINFO	0x08
-#define	M_ID_CAPCHAIN	0x09
-#define	M_ID_SYMINFO	0x0a
-#define	M_ID_HASH	0x0b
-#define	M_ID_LDYNSYM	0x0c			/* always right before DYNSYM */
-#define	M_ID_DYNSYM	0x0d
-#define	M_ID_DYNSTR	0x0e
-#define	M_ID_VERSION	0x0f
-#define	M_ID_DYNSORT	0x10
-#define	M_ID_REL	0x11
-#define	M_ID_PLT	0x12			/* SHF_ALLOC + SHF_EXECINSTR */
+#define	M_ID_DYNAMIC	0x06			/* if no .interp, then no */
+						/*    DT_DEBUG is required */
+#define	M_ID_UNWINDHDR	0x07
+#define	M_ID_UNWIND	0x08
+
+#define	M_ID_SYMINFO	0x09
+#define	M_ID_HASH	0x0a
+#define	M_ID_LDYNSYM	0x0b			/* always right before DYNSYM */
+#define	M_ID_DYNSYM	0x0c
+#define	M_ID_DYNSTR	0x0d
+#define	M_ID_VERSION	0x0e
+#define	M_ID_DYNSORT	0x0f
+#define	M_ID_REL	0x10
+#define	M_ID_PLT	0x11			/* SHF_ALLOC + SHF_EXECINSTR */
+#define	M_ID_ARRAY	0x12
 #define	M_ID_TEXT	0x13
 #define	M_ID_DATA	0x20
 
 /*	M_ID_USER	0x01			dual entry - listed above */
 #define	M_ID_GOT	0x03			/* SHF_ALLOC + SHF_WRITE */
-#define	M_ID_DYNAMIC	0x05
-#define	M_ID_ARRAY	0x06
-/*	M_ID_UNWIND	0x07			dual entry - listed above */
+/*	M_ID_DYNAMIC	0x06			dual entry - listed above */
+/*	M_ID_UNWIND	0x08			dual entry - listed above */
 
 #define	M_ID_UNKNOWN	0xfb			/* just before TLS */
 
--- a/usr/src/cmd/sgs/include/sparc/machdep_sparc.h	Mon Aug 02 13:32:36 2010 -0700
+++ b/usr/src/cmd/sgs/include/sparc/machdep_sparc.h	Mon Aug 02 14:04:48 2010 -0700
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  *
  * Global include file for all sgs SPARC machine dependent macros, constants
  * and declarations.
@@ -195,30 +194,33 @@
 #define	M_STACK_PERM	(PF_R | PF_W | PF_X)
 #endif
 
-
 /*
  * Define a set of identifies for special sections.  These allow the sections
  * to be ordered within the output file image.  These values should be
  * maintained consistently, where appropriate, in each platform specific header
  * file.
  *
- *  o	null identifies that this section does not need to be added to the
+ *  -	null identifies that this section does not need to be added to the
  *	output image (ie. shared object sections or sections we're going to
  *	recreate (sym tables, string tables, relocations, etc.)).
  *
- *  o	any user defined section will be first in the associated segment.
+ *  -	any user defined section will be first in the associated segment.
  *
- *  o	interp and capabilities sections are next, as these are accessed
+ *  -	interp and capabilities sections are next, as these are accessed
  *	immediately the first page of the image is mapped.
  *
- *  o	the syminfo, hash, dynsym, dynstr and rel's are grouped together as
- *	these will all be accessed first by ld.so.1 to perform relocations.
+ *  -	objects that do not provide an interp normally have a read-only
+ *	.dynamic section that comes next (in this case, there is no need to
+ *	update a DT_DEBUG entry at runtime).
  *
- *  o	the got, dynamic, and plt are grouped together as these may also be
+ *  -	the syminfo, hash, dynsym, dynstr and rel's are grouped together as
+ *	these will all be accessed together by ld.so.1 to perform relocations.
+ *
+ *  -	the got, dynamic, and plt are grouped together as these may also be
  *	accessed first by ld.so.1 to perform relocations, fill in DT_DEBUG
  *	(executables only), and .plt[0].
  *
- *  o	unknown sections (stabs, comments etc.) go at the end.
+ *  -	unknown sections (stabs, comments, etc.) go at the end.
  *
  * Note that .tlsbss/.bss are given the largest identifiers.  This insures that
  * if any unknown sections become associated to the same segment as the .bss,
@@ -229,19 +231,23 @@
 
 #define	M_ID_INTERP	0x02			/* SHF_ALLOC */
 #define	M_ID_CAP	0x03
+#define	M_ID_CAPINFO	0x04
+#define	M_ID_CAPCHAIN	0x05
 
-#define	M_ID_UNWINDHDR	0x06
-#define	M_ID_UNWIND	0x07
-#define	M_ID_CAPINFO 	0x08
-#define	M_ID_CAPCHAIN 	0x09
-#define	M_ID_SYMINFO	0x0a
-#define	M_ID_HASH	0x0b
-#define	M_ID_LDYNSYM	0x0c			/* always right before DYNSYM */
-#define	M_ID_DYNSYM	0x0d
-#define	M_ID_DYNSTR	0x0e
-#define	M_ID_VERSION	0x0f
-#define	M_ID_DYNSORT	0x10
-#define	M_ID_REL	0x11
+#define	M_ID_DYNAMIC	0x06			/* if no .interp, then no */
+						/*    DT_DEBUG is required */
+#define	M_ID_UNWINDHDR	0x07
+#define	M_ID_UNWIND	0x08
+
+#define	M_ID_SYMINFO	0x09
+#define	M_ID_HASH	0x0a
+#define	M_ID_LDYNSYM	0x0b			/* always right before DYNSYM */
+#define	M_ID_DYNSYM	0x0c
+#define	M_ID_DYNSTR	0x0d
+#define	M_ID_VERSION	0x0e
+#define	M_ID_DYNSORT	0x0f
+#define	M_ID_REL	0x10
+#define	M_ID_ARRAY	0x11
 #define	M_ID_TEXT	0x12			/* SHF_ALLOC + SHF_EXECINSTR */
 #define	M_ID_DATA	0x20
 
@@ -249,9 +255,8 @@
 #define	M_ID_GOTDATA	0x02			/* SHF_ALLOC + SHF_WRITE */
 #define	M_ID_GOT	0x03
 #define	M_ID_PLT	0x04
-#define	M_ID_DYNAMIC	0x05
-#define	M_ID_ARRAY	0x06
-/*	M_ID_UNWIND	0x07			dual entry - listed above */
+/*	M_ID_DYNAMIC	0x06			dual entry - listed above */
+/*	M_ID_UNWIND	0x08			dual entry - listed above */
 
 #define	M_ID_UNKNOWN	0xfc			/* just before TLS */
 
--- a/usr/src/cmd/sgs/libld/common/sections.c	Mon Aug 02 13:32:36 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/sections.c	Mon Aug 02 14:04:48 2010 -0700
@@ -523,11 +523,12 @@
 
 	case SHT_DYNAMIC:
 		/*
-		 * A dynamic section may or may not be allocable, depending
-		 * on context, so we leave that flag unset and leave it to
-		 * the caller to add it if necessary.
+		 * A dynamic section may or may not be allocable, and may or
+		 * may not be writable, depending on context, so we leave the
+		 * flags unset and leave it to the caller to add them if
+		 * necessary.
 		 */
-		SET_SEC_INFO_WORD_ALIGN(ELF_T_DYN, SHF_WRITE, sizeof (Dyn))
+		SET_SEC_INFO_WORD_ALIGN(ELF_T_DYN, 0, sizeof (Dyn))
 		break;
 
 	case SHT_NOBITS:
@@ -958,10 +959,22 @@
 	    &isec, &shdr, &data) == S_ERROR)
 		return (S_ERROR);
 
-	/* new_section() does not set SHF_ALLOC. Add it if needed */
+	/*
+	 * new_section() does not set SHF_ALLOC.  If we're building anything
+	 * besides a relocatable object, then the .dynamic section should
+	 * reside in allocatable memory.
+	 */
 	if (not_relobj)
 		shdr->sh_flags |= SHF_ALLOC;
 
+	/*
+	 * new_section() does not set SHF_WRITE.  If we're building an object
+	 * that specifies an interpretor, then a DT_DEBUG entry is created,
+	 * which is initialized to the applications link-map list at runtime.
+	 */
+	if (ofl->ofl_osinterp)
+		shdr->sh_flags |= SHF_WRITE;
+
 	osp = ofl->ofl_osdynamic =
 	    ld_place_section(ofl, isec, NULL, ld_targ.t_id.id_dynamic, NULL);
 
@@ -1084,6 +1097,7 @@
 
 	if (not_relobj) {
 		Aliste	idx;
+		Sg_desc	*sgp;
 
 		if (ofl->ofl_config) {
 			cnt++;
@@ -1111,8 +1125,8 @@
 		}
 
 		/*
-		 * Reserve entries for the HASH, STRTAB, STRSZ, SYMTAB, SYMENT,
-		 * and CHECKSUM.
+		 * Reserve entries for the DT_HASH, DT_STRTAB, DT_STRSZ,
+		 * DT_SYMTAB, DT_SYMENT, and DT_CHECKSUM.
 		 */
 		cnt += 6;
 
@@ -1143,49 +1157,50 @@
 			cnt += 2;		/* DT_VERNEED & DT_VERNEEDNUM */
 
 		if ((flags & FLG_OF_COMREL) && ofl->ofl_relocrelcnt)
-			cnt++;			/* RELACOUNT */
-
-		if (flags & FLG_OF_TEXTREL)	/* TEXTREL */
+			cnt++;			/* DT_RELACOUNT */
+
+		if (flags & FLG_OF_TEXTREL)	/* DT_TEXTREL */
 			cnt++;
 
-		if (ofl->ofl_osfiniarray)	/* FINI_ARRAY & FINI_ARRAYSZ */
-			cnt += 2;
-
-		if (ofl->ofl_osinitarray)	/* INIT_ARRAY & INIT_ARRAYSZ */
-			cnt += 2;
-
-		if (ofl->ofl_ospreinitarray)	/* PREINIT_ARRAY & */
-			cnt += 2;		/*	PREINIT_ARRAYSZ */
+		if (ofl->ofl_osfiniarray)	/* DT_FINI_ARRAY */
+			cnt += 2;		/*    DT_FINI_ARRAYSZ */
+
+		if (ofl->ofl_osinitarray)	/* DT_INIT_ARRAY */
+			cnt += 2;		/*    DT_INIT_ARRAYSZ */
+
+		if (ofl->ofl_ospreinitarray)	/* DT_PREINIT_ARRAY & */
+			cnt += 2;		/*    DT_PREINIT_ARRAYSZ */
 
 		/*
-		 * If we have plt's reserve a PLT, PLTSZ, PLTREL and JMPREL.
+		 * If we have plt's reserve a DT_PLTRELSZ, DT_PLTREL and
+		 * DT_JMPREL.
 		 */
 		if (ofl->ofl_pltcnt)
 			cnt += 3;
 
 		/*
-		 * If pltpadding is needed (Sparcv9)
+		 * If plt padding is needed (Sparcv9).
 		 */
 		if (ofl->ofl_pltpad)
 			cnt += 2;		/* DT_PLTPAD & DT_PLTPADSZ */
 
 		/*
-		 * If we have any relocations reserve a REL, RELSZ and
-		 * RELENT entry.
+		 * If we have any relocations reserve a DT_REL, DT_RELSZ and
+		 * DT_RELENT entry.
 		 */
 		if (ofl->ofl_relocsz)
 			cnt += 3;
 
 		/*
-		 * If a syminfo section is required create SYMINFO, SYMINSZ,
-		 * and SYMINENT entries.
+		 * If a syminfo section is required create DT_SYMINFO,
+		 * DT_SYMINSZ, and DT_SYMINENT entries.
 		 */
 		if (flags & FLG_OF_SYMINFO)
 			cnt += 3;
 
 		/*
 		 * If there are any partially initialized sections allocate
-		 * MOVEENT, MOVESZ and MOVETAB.
+		 * DT_MOVETAB, DT_MOVESZ and DT_MOVEENT.
 		 */
 		if (ofl->ofl_osmove)
 			cnt += 3;
@@ -1203,42 +1218,37 @@
 			cnt++;
 
 		/*
-		 * These two entries should only be placed in a segment
-		 * which is writable.  If it's a read-only segment
-		 * (due to mapfile magic, e.g. libdl.so.1) then don't allocate
-		 * these entries.
+		 * The following entry should only be placed in a segment that
+		 * is writable.
 		 */
-		if ((osp->os_sgdesc) &&
-		    (osp->os_sgdesc->sg_phdr.p_flags & PF_W)) {
-			cnt++;			/* FEATURE_1 */
-
-			if (ofl->ofl_osinterp)
-				cnt++;		/* DEBUG */
-		}
+		if (((sgp = osp->os_sgdesc) != NULL) &&
+		    (sgp->sg_phdr.p_flags & PF_W) && ofl->ofl_osinterp)
+			cnt++;		/* DT_DEBUG */
 
 		/*
 		 * Capabilities require a .dynamic entry for the .SUNW_cap
 		 * section.
 		 */
 		if (ofl->ofl_oscap)
-			cnt++;			/* SUNW_CAP */
+			cnt++;			/* DT_SUNW_CAP */
 
 		/*
 		 * Symbol capabilities require a .dynamic entry for the
 		 * .SUNW_capinfo section.
 		 */
 		if (ofl->ofl_oscapinfo)
-			cnt++;			/* SUNW_CAPINFO */
+			cnt++;			/* DT_SUNW_CAPINFO */
 
 		/*
 		 * Capabilities chain information requires a .SUNW_capchain
-		 * entry, an entry size, and total size.
+		 * entry (DT_SUNW_CAPCHAIN), entry size (DT_SUNW_CAPCHAINENT),
+		 * and total size (DT_SUNW_CAPCHAINSZ).
 		 */
 		if (ofl->ofl_oscapchain)
-			cnt += 3;		/* SUNW_CAPCHAIN/ENT/SZ */
+			cnt += 3;
 
 		if (flags & FLG_OF_SYMBOLIC)
-			cnt++;			/* SYMBOLIC */
+			cnt++;			/* DT_SYMBOLIC */
 	}
 
 	/*
@@ -1334,18 +1344,20 @@
 		return (1);
 
 	/*
-	 * We always build an .interp section for dynamic executables.  However
-	 * if the user has specifically specified an interpreter we'll build
-	 * this section for any output (presumably the user knows what they are
-	 * doing. refer ABI section 5-4, and ld.1 man page use of -I).
+	 * An .interp section is always created for a dynamic executable.
+	 * A user can define the interpreter to use.  This definition overrides
+	 * the default that would be recorded in an executable, and triggers
+	 * the creation of an .interp section in any other object.  Presumably
+	 * the user knows what they are doing.  Refer to the generic ELF ABI
+	 * section 5-4, and the ld(1) -I option.
 	 */
 	if (((ofl->ofl_flags & (FLG_OF_DYNAMIC | FLG_OF_EXEC |
 	    FLG_OF_RELOBJ)) != (FLG_OF_DYNAMIC | FLG_OF_EXEC)) && !iname)
 		return (1);
 
 	/*
-	 * In the case of a dynamic executable supply a default interpreter
-	 * if a specific interpreter has not been specified.
+	 * In the case of a dynamic executable, supply a default interpreter
+	 * if the user has not specified their own.
 	 */
 	if (iname == NULL)
 		iname = ofl->ofl_interp = ld_targ.t_m.m_def_interp;
--- a/usr/src/cmd/sgs/libld/common/update.c	Mon Aug 02 13:32:36 2010 -0700
+++ b/usr/src/cmd/sgs/libld/common/update.c	Mon Aug 02 14:04:48 2010 -0700
@@ -2200,6 +2200,7 @@
 
 	if (not_relobj) {
 		Aliste	idx;
+		Sg_desc	*sgp;
 
 		if (ofl->ofl_config) {
 			dyn->d_tag = DT_CONFIG;
@@ -2502,19 +2503,10 @@
 			dyn++;
 		}
 
-		if (ofl->ofl_osdynamic->os_sgdesc &&
-		    (ofl->ofl_osdynamic->os_sgdesc->sg_phdr.p_flags & PF_W)) {
-			if (ofl->ofl_osinterp) {
-				dyn->d_tag = DT_DEBUG;
-				dyn->d_un.d_ptr = 0;
-				dyn++;
-			}
-
-			dyn->d_tag = DT_FEATURE_1;
-			if (ofl->ofl_osmove)
-				dyn->d_un.d_val = 0;
-			else
-				dyn->d_un.d_val = DTF_1_PARINIT;
+		if (((sgp = ofl->ofl_osdynamic->os_sgdesc) != NULL) &&
+		    (sgp->sg_phdr.p_flags & PF_W) && ofl->ofl_osinterp) {
+			dyn->d_tag = DT_DEBUG;
+			dyn->d_un.d_ptr = 0;
 			dyn++;
 		}
 
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Mon Aug 02 13:32:36 2010 -0700
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Mon Aug 02 14:04:48 2010 -0700
@@ -1618,3 +1618,4 @@
 	be more flexible. (D)
 6971440 moe can core dump while processing libc.
 6972234 sgs demo's could use some cleanup
+6935867 .dynamic could be readonly in sharable objects
--- a/usr/src/cmd/sgs/rtld/common/elf.c	Mon Aug 02 13:32:36 2010 -0700
+++ b/usr/src/cmd/sgs/rtld/common/elf.c	Mon Aug 02 14:04:48 2010 -0700
@@ -1824,7 +1824,6 @@
 				SYMENT(lmp) = dyn->d_un.d_val;
 				break;
 			case DT_FEATURE_1:
-				dyn->d_un.d_val |= DTF_1_PARINIT;
 				if (dyn->d_un.d_val & DTF_1_CONFEXP)
 					crle = 1;
 				break;
--- a/usr/src/uts/common/sys/link.h	Mon Aug 02 13:32:36 2010 -0700
+++ b/usr/src/uts/common/sys/link.h	Mon Aug 02 14:04:48 2010 -0700
@@ -182,7 +182,7 @@
 #define	DT_PLTPADSZ	0x6ffffdf9	/* pltpadding size */
 #define	DT_MOVEENT	0x6ffffdfa	/* move table entry size */
 #define	DT_MOVESZ	0x6ffffdfb	/* move table size */
-#define	DT_FEATURE_1	0x6ffffdfc	/* feature holder */
+#define	DT_FEATURE_1	0x6ffffdfc	/* feature holder (unused) */
 #define	DT_POSFLAG_1	0x6ffffdfd	/* flags for DT_* entries, effecting */
 					/*	the following DT_* entry. */
 					/*	See DF_P1_* definitions */
@@ -273,7 +273,7 @@
 #define	DF_1_NOOPEN	0x00000040	/* set RTLD_NOOPEN for this object */
 #define	DF_1_ORIGIN	0x00000080	/* ORIGIN processing required */
 #define	DF_1_DIRECT	0x00000100	/* direct binding enabled */
-#define	DF_1_TRANS	0x00000200	/* unused historical name */
+#define	DF_1_TRANS	0x00000200	/* unused obsolete name */
 #define	DF_1_INTERPOSE	0x00000400	/* object is an interposer */
 #define	DF_1_NODEFLIB	0x00000800	/* ignore default library search path */
 #define	DF_1_NODUMP	0x00001000	/* object can't be dldump(3x)'ed */
@@ -297,7 +297,7 @@
 #define	DF_1_SINGLETON	0x02000000	/* singleton symbols exist */
 
 /*
- * Values set to DT_FEATURE_1 tag's d_val.
+ * Values set to DT_FEATURE_1 tag's d_val (unused obsolete tag)
  */
 #define	DTF_1_PARINIT	0x00000001	/* partially initialization feature */
 #define	DTF_1_CONFEXP	0x00000002	/* configuration file expected */
@@ -461,7 +461,7 @@
 					/*	to object containing defn. */
 #define	SYMINFO_FLG_FILTER	0x0002	/* symbol ref is associated to a */
 					/* 	standard filter */
-#define	SYMINFO_FLG_PASSTHRU	SYMINFO_FLG_FILTER /* unused historical name */
+#define	SYMINFO_FLG_PASSTHRU	SYMINFO_FLG_FILTER /* unused obsolete name */
 #define	SYMINFO_FLG_COPY	0x0004	/* symbol is a copy-reloc */
 #define	SYMINFO_FLG_LAZYLOAD	0x0008	/* object containing defn. should be */
 					/*	lazily-loaded */