summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRod Evans <Rod.Evans@Sun.COM>2009-07-23 11:33:37 -0700
committerRod Evans <Rod.Evans@Sun.COM>2009-07-23 11:33:37 -0700
commit28bda19c304ae9f3ffa10394ef34c6e8f9e4c5f5 (patch)
treefd156b4b29fc736883b5bccbebafe6b979e06194
parent7623016fd42aadb1a19e2c2810fe6142c795c73b (diff)
downloadillumos-gate-28bda19c304ae9f3ffa10394ef34c6e8f9e4c5f5.tar.gz
6862967 rd_loadobj_iter() failing for core files
6856173 streams core dumps when compiled in 64bit with a very large static array size 6834197 ld pukes when given an empty plate
-rw-r--r--usr/src/cmd/sgs/include/libld.h14
-rw-r--r--usr/src/cmd/sgs/include/list.h75
-rw-r--r--usr/src/cmd/sgs/include/rtld.h6
-rw-r--r--usr/src/cmd/sgs/libld/common/args.c5
-rw-r--r--usr/src/cmd/sgs/libld/common/entry.c3
-rw-r--r--usr/src/cmd/sgs/libld/common/map.c3
-rw-r--r--usr/src/cmd/sgs/libld/common/resolve.c56
-rw-r--r--usr/src/cmd/sgs/libld/common/syms.c70
-rw-r--r--usr/src/cmd/sgs/libld/common/update.c40
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/rd_elf.c155
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README30
11 files changed, 338 insertions, 119 deletions
diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h
index 609d62bed1..9e965feda2 100644
--- a/usr/src/cmd/sgs/include/libld.h
+++ b/usr/src/cmd/sgs/include/libld.h
@@ -390,7 +390,7 @@ struct ofl_desc {
#define FLG_OF1_TLSOREL 0x00100000 /* output relocation against .tlsbss */
/* section */
#define FLG_OF1_MEMORY 0x00200000 /* produce a memory model */
-
+#define FLG_OF1_NGLBDIR 0x00400000 /* no DT_1_DIRECT flag allowed */
#define FLG_OF1_ENCDIFF 0x00800000 /* Host running linker has different */
/* byte order than output object */
#define FLG_OF1_VADDR 0x01000000 /* user segment defines a vaddr */
@@ -544,7 +544,7 @@ struct ifl_desc { /* input file descriptor */
Word ifl_shstrndx; /* index to .shstrtab */
Word ifl_vercnt; /* number of versions in file */
Half ifl_neededndx; /* index to NEEDED in .dyn section */
- Word ifl_flags; /* Explicit/implicit reference */
+ Word ifl_flags; /* explicit/implicit reference */
Is_desc **ifl_isdesc; /* isdesc[scn ndx] = Is_desc ptr */
Sdf_desc *ifl_sdfdesc; /* control definition */
Versym *ifl_versym; /* version symbol table array */
@@ -954,14 +954,14 @@ struct sym_avlnode {
* Structure to manage the shared object definition lists. There are two lists
* that use this structure:
*
- * o ofl_soneed; maintain the list of implicitly required dependencies
+ * - ofl_soneed; maintain the list of implicitly required dependencies
* (ie. shared objects needed by other shared objects). These definitions
* may include RPATH's required to locate the dependencies, and any
* version requirements.
*
- * o ofl_socntl; maintains the shared object control definitions. These are
+ * - ofl_socntl; maintains the shared object control definitions. These are
* provided by the user (via a mapfile) and are used to indicate any
- * verion control requirements.
+ * version control requirements.
*/
struct sdf_desc {
const char *sdf_name; /* the shared objects file name */
@@ -995,12 +995,12 @@ struct sdv_desc {
* Structures to manage versioning information. Two versioning structures are
* defined:
*
- * o a version descriptor maintains a linked list of versions and their
+ * - a version descriptor maintains a linked list of versions and their
* associated dependencies. This is used to build the version definitions
* for an image being created (see map_symbol), and to determine the
* version dependency graph for any input files that are versioned.
*
- * o a version index array contains each version of an input file that is
+ * - a version index array contains each version of an input file that is
* being processed. It informs us which versions are available for
* binding, and is used to generate any version dependency information.
*/
diff --git a/usr/src/cmd/sgs/include/list.h b/usr/src/cmd/sgs/include/list.h
new file mode 100644
index 0000000000..b35ff06268
--- /dev/null
+++ b/usr/src/cmd/sgs/include/list.h
@@ -0,0 +1,75 @@
+/*
+ * 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 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This file maintains an old style of list processing that is required by
+ * librtld_db to iterate over older core files/process images.
+ */
+#ifndef _LIST_H
+#define _LIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/elftypes.h>
+
+typedef struct listnode Listnode;
+typedef struct list List;
+
+struct listnode { /* a node on a linked list */
+ void *data; /* the data item */
+ Listnode *next; /* the next element */
+};
+
+struct list { /* a linked list */
+ Listnode *head; /* the first element */
+ Listnode *tail; /* the last element */
+};
+
+
+#ifdef _SYSCALL32
+typedef struct listnode32 Listnode32;
+typedef struct list32 List32;
+
+struct listnode32 { /* a node on a linked list */
+ Elf32_Addr data; /* the data item */
+ Elf32_Addr next; /* the next element */
+};
+
+struct list32 { /* a linked list */
+ Elf32_Addr head; /* the first element */
+ Elf32_Addr tail; /* the last element */
+};
+#endif /* _SYSCALL32 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIST_H */
diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h
index ffe2325c9f..d9b214cad1 100644
--- a/usr/src/cmd/sgs/include/rtld.h
+++ b/usr/src/cmd/sgs/include/rtld.h
@@ -133,6 +133,9 @@ typedef struct {
*
* Added rtld_flags & FLG_RT_RELOCED to stable flags range
*
+ * Valid fields for R_RTLDDB_VERSION6
+ *
+ * rtd_dynlmlst converted from a List to APlist
*/
#define R_RTLDDB_VERSION1 1 /* base version level - used for core */
/* file examination */
@@ -141,7 +144,8 @@ typedef struct {
#define R_RTLDDB_VERSION3 3
#define R_RTLDDB_VERSION4 4
#define R_RTLDDB_VERSION5 5
-#define R_RTLDDB_VERSION R_RTLDDB_VERSION5 /* current version */
+#define R_RTLDDB_VERSION6 6
+#define R_RTLDDB_VERSION R_RTLDDB_VERSION6 /* current version */
typedef struct rtld_db_priv {
struct r_debug rtd_rdebug; /* original r_debug structure */
diff --git a/usr/src/cmd/sgs/libld/common/args.c b/usr/src/cmd/sgs/libld/common/args.c
index a56575e809..0d2b086ddc 100644
--- a/usr/src/cmd/sgs/libld/common/args.c
+++ b/usr/src/cmd/sgs/libld/common/args.c
@@ -420,8 +420,8 @@ check_flags(Ofl_desc * ofl, int argc)
* by -zdirect or mapfile DIRECT directives.
*/
if (Bdflag == SET_FALSE) {
- ofl->ofl_flags1 |=
- (FLG_OF1_NDIRECT | FLG_OF1_ALNODIR);
+ ofl->ofl_flags1 |= (FLG_OF1_NDIRECT |
+ FLG_OF1_NGLBDIR | FLG_OF1_ALNODIR);
ofl->ofl_flags |= FLG_OF_SYMINFO;
}
}
@@ -1638,7 +1638,6 @@ parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
} else if (strcmp(optarg,
MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
- ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
} else if (strcmp(optarg,
MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
ofl->ofl_flags1 |= FLG_OF1_IGNORE;
diff --git a/usr/src/cmd/sgs/libld/common/entry.c b/usr/src/cmd/sgs/libld/common/entry.c
index 47eecf28eb..c6bfb1acd2 100644
--- a/usr/src/cmd/sgs/libld/common/entry.c
+++ b/usr/src/cmd/sgs/libld/common/entry.c
@@ -128,7 +128,8 @@ static const Ent_desc ent_desc[] = {
#if defined(_ELF64) /* (amd64-only) */
{NULL, MSG_ORIG(MSG_ENT_LRODATA), NULL,
- SHF_ALLOC + SHF_AMD64_LARGE, SHF_ALLOC + SHF_AMD64_LARGE,
+ SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE,
+ SHF_ALLOC + SHF_AMD64_LARGE,
(Sg_desc *)LD_LRODATA, 0, FLG_EC_BUILTIN},
#endif
{NULL, MSG_ORIG(MSG_ENT_TEXT), NULL,
diff --git a/usr/src/cmd/sgs/libld/common/map.c b/usr/src/cmd/sgs/libld/common/map.c
index f83fb5a0d1..e44411b626 100644
--- a/usr/src/cmd/sgs/libld/common/map.c
+++ b/usr/src/cmd/sgs/libld/common/map.c
@@ -1600,7 +1600,8 @@ map_version(const char *mapfile, char *name, Ofl_desc *ofl)
MSG_ORIG(MSG_MAP_NODIRECT)) == 0) {
sym_flags1 |= FLG_SY1_NDIR;
ofl->ofl_flags |= FLG_OF_SYMINFO;
- ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
+ ofl->ofl_flags1 |=
+ (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
} else if (strcmp(Start_tok,
MSG_ORIG(MSG_MAP_FILTER)) == 0) {
dftflag = filter = FLG_SY_STDFLTR;
diff --git a/usr/src/cmd/sgs/libld/common/resolve.c b/usr/src/cmd/sgs/libld/common/resolve.c
index 5ec2df0d1c..8267d0be92 100644
--- a/usr/src/cmd/sgs/libld/common/resolve.c
+++ b/usr/src/cmd/sgs/libld/common/resolve.c
@@ -54,7 +54,7 @@ typedef enum {
/* ARGSUSED0 */
static void
sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
- int ndx, Word nshndx, Word nsymflags)
+ int ndx, Word nshndx, Word nsymflags)
{
}
@@ -266,7 +266,7 @@ sym_visibility(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl)
/*ARGSUSED4*/
static void
sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
- int ndx, Word nshndx, Word nsymflags)
+ int ndx, Word nshndx, Word nsymflags)
{
uchar_t otype = ELF_ST_TYPE(sdp->sd_sym->st_info);
uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
@@ -298,7 +298,7 @@ sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
/*ARGSUSED4*/
static void
sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
- int ndx, Word nshndx, Word nsymflags)
+ int ndx, Word nshndx, Word nsymflags)
{
/*
* Perform any machine specific type checking.
@@ -517,7 +517,7 @@ sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
*/
static void
sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
- int ndx, Word nshndx, Word nsymflags)
+ int ndx, Word nshndx, Word nsymflags)
{
Sym *osym = sdp->sd_sym;
uchar_t obind = ELF_ST_BIND(osym->st_info);
@@ -545,7 +545,7 @@ sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
*/
static void
sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
- int ndx, Word nshndx, Word nsymflags)
+ int ndx, Word nshndx, Word nsymflags)
{
Conv_inv_buf_t inv_buf1, inv_buf2;
Sym *osym = sdp->sd_sym;
@@ -610,17 +610,17 @@ sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
* Having provided the user with any necessary warnings, take the
* appropriate symbol:
*
- * o if one symbol is from a shared object and the other is from a
+ * - if one symbol is from a shared object and the other is from a
* relocatable object, take the relocatable objects symbol (the
* run-time linker is always going to find the relocatable object
* symbol regardless of the binding), else
*
- * o if both symbols are from relocatable objects and one symbol is
+ * - if both symbols are from relocatable objects and one symbol is
* weak take the non-weak symbol (two non-weak symbols would have
* generated the fatal error condition above unless -z muldefs is
* in effect), else
*
- * o take the first symbol definition encountered.
+ * - take the first symbol definition encountered.
*/
if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
if (warn)
@@ -648,7 +648,7 @@ sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
*/
static void
sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
- int ndx, Word nshndx, Word nsymflags)
+ int ndx, Word nshndx, Word nsymflags)
{
Conv_inv_buf_t inv_buf1, inv_buf2;
Sym *osym = sdp->sd_sym;
@@ -666,12 +666,12 @@ sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
/*
* Special rules for functions.
*
- * o If both definitions are from relocatable objects, have the same
+ * - If both definitions are from relocatable objects, have the same
* binding (ie. two weaks or two non-weaks), and the real
* definition is a function (the other must be tentative), treat
* this as a multiply defined symbol error, else
*
- * o if the real symbol definition is a function within a shared
+ * - if the real symbol definition is a function within a shared
* library and the tentative symbol is a relocatable object, and
* the tentative is not weak and the function real, then retain the
* tentative definition.
@@ -774,18 +774,18 @@ sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
* Having provided the user with any necessary warnings, take the
* appropriate symbol:
*
- * o if the original symbol is from relocatable file and it is
+ * - if the original symbol is from relocatable file and it is
* a protected tentative symbol, take the original one.
*
- * o if the original symbol is from shared object and the new
+ * - if the original symbol is from shared object and the new
* symbol is a protected tentative symbol from a relocatable file,
* take the new one.
*
- * o if the original symbol is tentative, and providing the original
+ * - if the original symbol is tentative, and providing the original
* symbol isn't strong and the new symbol weak, take the real
* symbol, else
*
- * o if the original symbol is weak and the new tentative symbol is
+ * - if the original symbol is weak and the new tentative symbol is
* strong take the new symbol.
*
* Refer to the System V ABI Page 4-27 for a description of the binding
@@ -830,7 +830,7 @@ sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
*/
static void
sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
- int ndx, Word nshndx, Word nsymflags)
+ int ndx, Word nshndx, Word nsymflags)
{
Sym *osym = sdp->sd_sym;
uchar_t obind = ELF_ST_BIND(osym->st_info);
@@ -923,10 +923,10 @@ sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
* Having provided the necessary warning indicate which
* relocatable object we are going to take.
*
- * o if one symbol is weak and the other is non-weak
+ * - if one symbol is weak and the other is non-weak
* take the non-weak symbol, else
*
- * o take the largest alignment (as we still have to check
+ * - take the largest alignment (as we still have to check
* the symbols size simply save the largest value for
* updating later).
*/
@@ -972,11 +972,11 @@ sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
* Having provided the necessary warning indicate what course
* of action we are going to take.
*
- * o if the file types differ, take the relocatable object
+ * - if the file types differ, take the relocatable object
* and apply the largest symbol size, else
- * o if one symbol is weak and the other is non-weak, take
+ * - if one symbol is weak and the other is non-weak, take
* the non-weak symbol, else
- * o simply take the largest symbol reference.
+ * - simply take the largest symbol reference.
*/
if (nfile != ofile) {
if (nfile == ET_REL) {
@@ -1019,13 +1019,13 @@ sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
/*
* If the sizes are the same
*
- * o if the file types differ, take the relocatable object,
+ * - if the file types differ, take the relocatable object,
* else
*
- * o if one symbol is weak and the other is non-weak, take
+ * - if one symbol is weak and the other is non-weak, take
* the non-weak symbol, else
*
- * o take the first reference.
+ * - take the first reference.
*/
if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN))
return;
@@ -1051,7 +1051,7 @@ sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
* procedure to be called (if any).
*/
static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *,
- Sym *, Ifl_desc *, Ofl_desc *, int, Word, Word) = {
+ Sym *, Ifl_desc *, Ofl_desc *, int, Word, Word) = {
/* defined undef tent */
/* ET_REL ET_REL ET_REL */
@@ -1200,8 +1200,10 @@ ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx,
sdp->sd_flags1 |=
(FLG_SY1_NDIR | FLG_SY1_SINGLE);
- if (sdp->sd_ref == REF_REL_NEED)
- ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
+ if (sdp->sd_ref == REF_REL_NEED) {
+ ofl->ofl_flags1 |=
+ (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
+ }
}
} else if (vis == STV_PROTECTED) {
sdp->sd_flags1 |= FLG_SY1_PROTECT;
diff --git a/usr/src/cmd/sgs/libld/common/syms.c b/usr/src/cmd/sgs/libld/common/syms.c
index cb8847b488..71f75e9bd3 100644
--- a/usr/src/cmd/sgs/libld/common/syms.c
+++ b/usr/src/cmd/sgs/libld/common/syms.c
@@ -214,6 +214,15 @@ ld_sym_nodirect(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
/*
* Get the associated symbol table.
*/
+ if ((sifshdr->sh_link == 0) || (sifshdr->sh_link >= ifl->ifl_shnum)) {
+ /*
+ * Broken input file
+ */
+ eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
+ ifl->ifl_name, isp->is_name, EC_XWORD(sifshdr->sh_link));
+ ofl->ofl_flags |= FLG_OF_FATAL;
+ return (0);
+ }
symshdr = ifl->ifl_isdesc[sifshdr->sh_link]->is_shdr;
symdata = ifl->ifl_isdesc[sifshdr->sh_link]->is_indata->d_buf;
@@ -237,7 +246,7 @@ ld_sym_nodirect(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
sym = (Sym *)(symdata + _cnt);
str = (char *)(strdata + sym->st_name);
- if (sdp = ld_sym_find(str, SYM_NOHASH, 0, ofl)) {
+ if ((sdp = ld_sym_find(str, SYM_NOHASH, NULL, ofl)) != NULL) {
if (ifl != sdp->sd_file)
continue;
@@ -448,7 +457,7 @@ ld_sym_enter(const char *name, Sym *osym, Word hash, Ifl_desc *ifl,
break;
case STV_SINGLETON:
sdp->sd_flags1 |= (FLG_SY1_SINGLE | FLG_SY1_NDIR);
- ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
+ ofl->ofl_flags1 |= (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
break;
case STV_ELIMINATE:
sdp->sd_flags1 |= (FLG_SY1_HIDDEN | FLG_SY1_ELIM);
@@ -730,7 +739,7 @@ sym_add_spec(const char *name, const char *uname, Word sdaux_id,
usdp->sd_flags1 |= flags1;
}
- if (name && (sdp = ld_sym_find(name, SYM_NOHASH, 0, ofl)) &&
+ if (name && (sdp = ld_sym_find(name, SYM_NOHASH, NULL, ofl)) &&
(sdp->sd_sym->st_shndx == SHN_UNDEF)) {
uchar_t bind;
@@ -928,7 +937,7 @@ ld_sym_spec(Ofl_desc *ofl)
* Make sure it gets assigned the appropriate special attributes.
*/
if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U),
- SYM_NOHASH, 0, ofl)) != 0) && (sdp->sd_ref != REF_DYN_SEEN)) {
+ SYM_NOHASH, NULL, ofl)) != 0) && (sdp->sd_ref != REF_DYN_SEEN)) {
if (sym_add_spec(MSG_ORIG(MSG_SYM_GOFTBL),
MSG_ORIG(MSG_SYM_GOFTBL_U), SDAUX_ID_GOT, FLG_SY_DYNSORT,
(FLG_SY1_DEFAULT | FLG_SY1_EXPDEF), ofl) == S_ERROR)
@@ -959,13 +968,13 @@ ld_sym_adjust_vis(Sym_desc *sdp, Ofl_desc *ofl)
*
* A symbol is a candidate for auto-reduction/elimination if:
*
- * . the symbol wasn't explicitly defined within a mapfile
+ * - the symbol wasn't explicitly defined within a mapfile
* (in which case all the necessary state has been applied
* to the symbol), or
- * . the symbol isn't one of the family of reserved
+ * - the symbol isn't one of the family of reserved
* special symbols (ie. _end, _etext, etc.), or
- * . the symbol isn't a SINGLETON, or
- * . the symbol wasn't explicitly defined within a version
+ * - the symbol isn't a SINGLETON, or
+ * - the symbol wasn't explicitly defined within a version
* definition associated with an input relocatable object.
*
* Indicate that the symbol has been reduced as it may be
@@ -1121,9 +1130,10 @@ ld_sym_validate(Ofl_desc *ofl)
needed = FLG_OF_FATAL;
/*
- * If the output image is being versioned all symbol definitions must be
- * associated with a version. Any symbol that isn't is classified as
- * undefined and a fatal error condition will be indicated.
+ * If the output image is being versioned, then all symbol definitions
+ * must be associated with a version. Any symbol that isn't associated
+ * with a version is classified as undefined, and a fatal error
+ * condition is indicated.
*/
if ((oflags & FLG_OF_VERDEF) && (ofl->ofl_vercnt > VER_NDX_GLOBAL))
verdesc = FLG_OF_FATAL;
@@ -1148,7 +1158,7 @@ ld_sym_validate(Ofl_desc *ofl)
for (i = 0; special[i] != NULL; i++) {
if (((sdp = ld_sym_find(special[i],
- SYM_NOHASH, 0, ofl)) != NULL) &&
+ SYM_NOHASH, NULL, ofl)) != NULL) &&
(sdp->sd_sym->st_size == 0)) {
if (ld_sym_copy(sdp) == S_ERROR)
return (S_ERROR);
@@ -1337,7 +1347,7 @@ ld_sym_validate(Ofl_desc *ofl)
* allow being directly bound to.
*/
if (sdp->sd_flags1 & FLG_SY1_NDIR)
- ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
+ ofl->ofl_flags1 |= FLG_OF1_NGLBDIR;
if (sdp->sd_file->ifl_vercnt) {
int vndx;
@@ -1382,15 +1392,23 @@ ld_sym_validate(Ofl_desc *ofl)
/*
* If the output image is to be versioned then all symbol
- * definitions must be associated with a version.
+ * definitions must be associated with a version. Remove any
+ * versioning that might be left associated with an undefined
+ * symbol.
*/
- if (verdesc && (sdp->sd_ref == REF_REL_NEED) &&
- (sym->st_shndx != SHN_UNDEF) &&
- (!(sdp->sd_flags1 & FLG_SY1_HIDDEN)) &&
- (sdp->sd_aux->sa_overndx == 0)) {
- sym_undef_entry(ofl, sdp, NOVERSION);
- ofl->ofl_flags |= verdesc;
- continue;
+ if (verdesc && (sdp->sd_ref == REF_REL_NEED)) {
+ if (sym->st_shndx == SHN_UNDEF) {
+ if (sdp->sd_aux && sdp->sd_aux->sa_overndx)
+ sdp->sd_aux->sa_overndx = 0;
+ } else {
+ if ((!(sdp->sd_flags1 & FLG_SY1_HIDDEN)) &&
+ sdp->sd_aux &&
+ (sdp->sd_aux->sa_overndx == 0)) {
+ sym_undef_entry(ofl, sdp, NOVERSION);
+ ofl->ofl_flags |= verdesc;
+ continue;
+ }
+ }
}
/*
@@ -1603,8 +1621,8 @@ ld_sym_validate(Ofl_desc *ofl)
*/
ret = 0;
if (ofl->ofl_entry) {
- if ((sdp =
- ld_sym_find(ofl->ofl_entry, SYM_NOHASH, 0, ofl)) == NULL) {
+ if ((sdp = ld_sym_find(ofl->ofl_entry, SYM_NOHASH,
+ NULL, ofl)) == NULL) {
eprintf(ofl->ofl_lml, ERR_FATAL,
MSG_INTL(MSG_ARG_NOENTRY), ofl->ofl_entry);
ret++;
@@ -1615,12 +1633,12 @@ ld_sym_validate(Ofl_desc *ofl)
ofl->ofl_entry = (void *)sdp;
}
} else if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_START),
- SYM_NOHASH, 0, ofl)) != NULL) && (ensure_sym_local(ofl,
+ SYM_NOHASH, NULL, ofl)) != NULL) && (ensure_sym_local(ofl,
sdp, 0) == 0)) {
ofl->ofl_entry = (void *)sdp;
} else if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_MAIN),
- SYM_NOHASH, 0, ofl)) != NULL) && (ensure_sym_local(ofl,
+ SYM_NOHASH, NULL, ofl)) != NULL) && (ensure_sym_local(ofl,
sdp, 0) == 0)) {
ofl->ofl_entry = (void *)sdp;
}
@@ -1968,7 +1986,7 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl)
* won't become part of the output image, but we must
* process it to test for register conflicts.
*/
- rsdp = sdp = 0;
+ rsdp = sdp = NULL;
if (sdflags & FLG_SY_REGSYM) {
/*
* The presence of FLG_SY_REGSYM means that
diff --git a/usr/src/cmd/sgs/libld/common/update.c b/usr/src/cmd/sgs/libld/common/update.c
index 1967c1acfc..984bdadcf7 100644
--- a/usr/src/cmd/sgs/libld/common/update.c
+++ b/usr/src/cmd/sgs/libld/common/update.c
@@ -308,9 +308,9 @@ update_osym(Ofl_desc *ofl)
if (!(flags & FLG_OF_NOVERSEC) &&
(flags & (FLG_OF_VERNEED | FLG_OF_VERDEF))) {
versym = (Versym *)ofl->ofl_osversym->os_outdata->d_buf;
- versym[0] = 0;
+ versym[0] = NULL;
} else
- versym = 0;
+ versym = NULL;
/*
* If syminfo section exists be prepared to fill it in.
@@ -319,7 +319,7 @@ update_osym(Ofl_desc *ofl)
syminfo = ofl->ofl_ossyminfo->os_outdata->d_buf;
syminfo[0].si_flags = SYMINFO_CURRENT;
} else
- syminfo = 0;
+ syminfo = NULL;
/*
* Setup our string tables.
@@ -949,8 +949,8 @@ update_osym(Ofl_desc *ofl)
ssndx = ofl->ofl_scopecnt + ofl->ofl_elimcnt;
/*
- * Traverse the internal symbol table updating information and
- * allocating common.
+ * Traverse the internal symbol table updating global symbol information
+ * and allocating common.
*/
for (sav = avl_first(&ofl->ofl_symavl); sav;
sav = AVL_NEXT(&ofl->ofl_symavl, sav)) {
@@ -1222,16 +1222,22 @@ update_osym(Ofl_desc *ofl)
if (sdp->sd_ref == REF_DYN_NEED) {
/*
* A reference is bound to a needed dependency.
- * Save this symbol descriptor, as its boundto
- * element will need updating after the .dynamic
- * section has been created. Flag whether this
- * reference is lazy loadable, and if a direct
- * binding is to be established.
+ * Save the syminfo entry, so that when the
+ * .dynamic section has been updated, a
+ * DT_NEEDED entry can be associated
+ * (see update_osyminfo()).
*/
if (aplist_append(alpp, sdp,
AL_CNT_OFL_SYMINFOSYMS) == NULL)
return (0);
+ /*
+ * Flag that the symbol has a direct association
+ * with the external reference (this is an old
+ * tagging, that has no real effect by itself).
+ * And flag whether this reference is lazy
+ * loadable.
+ */
syminfo[ndx].si_flags |= SYMINFO_FLG_DIRECT;
if (sdp->sd_flags & FLG_SY_LAZYLD)
syminfo[ndx].si_flags |=
@@ -2428,11 +2434,17 @@ update_odynamic(Ofl_desc *ofl)
* via a mapfile, or -znodirect was used on the command line, then
* clear the DF_1_DIRECT flag. The resultant object will use per-symbol
* direct bindings rather than be enabled for global direct bindings.
+ *
+ * If any no-direct bindings exist within this object, set the
+ * DF_1_NODIRECT flag. ld(1) recognizes this flag when processing
+ * dependencies, and performs extra work to ensure that no direct
+ * bindings are established to the no-direct symbols that exist
+ * within these dependencies.
*/
- if (ofl->ofl_flags1 & FLG_OF1_NDIRECT) {
+ if (ofl->ofl_flags1 & FLG_OF1_NGLBDIR)
ofl->ofl_dtflags_1 &= ~DF_1_DIRECT;
+ if (ofl->ofl_flags1 & FLG_OF1_NDIRECT)
ofl->ofl_dtflags_1 |= DF_1_NODIRECT;
- }
dyn->d_tag = DT_FLAGS_1;
dyn->d_un.d_val = ofl->ofl_dtflags_1;
@@ -3271,10 +3283,10 @@ ld_update_outfile(Ofl_desc *ofl)
* If we are creating a PT_SUNWDTRACE segment, remember where
* the program header is. The header values are assigned after
* update_osym() has completed and the symbol table addresses
- * have been udpated.
+ * have been updated.
*/
if (phdr->p_type == PT_SUNWDTRACE) {
- if ((ofl->ofl_dtracesym) &&
+ if (ofl->ofl_dtracesym &&
((flags & FLG_OF_RELOBJ) == 0)) {
dtracesgp = sgp;
dtracesndx = segndx;
diff --git a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
index b1b5ce96b9..332ae3ca6d 100644
--- a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
+++ b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
@@ -30,6 +30,7 @@
#include <rtld_db.h>
#include <rtld.h>
#include <alist.h>
+#include <list.h>
#include <_rtld_db.h>
#include <msg.h>
#include <limits.h>
@@ -54,17 +55,24 @@
#define validate_rdebug32 validate_rdebug64
#define TAPlist APlist
#define TLm_list Lm_list
+#define TList List
+#define TListnode Listnode
#define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_64
#else /* ELF32 */
#define Rt_map Rt_map32
#define Rtld_db_priv Rtld_db_priv32
#define TAPlist APlist32
#define TLm_list Lm_list32
+#define TList List32
+#define TListnode Listnode32
+#define Lm_list Lm_list32
#define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
#endif /* _ELF64 */
#else /* _LP64 */
#define TAPlist APlist
#define TLm_list Lm_list
+#define TList List
+#define TListnode Listnode
#define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
#endif /* _LP64 */
@@ -86,6 +94,7 @@ validate_rdebug32(struct rd_agent *rap)
if (rap->rd_rdebug == 0)
return (RD_ERR);
+
/*
* The rtld_db_priv structure contains both the traditional (exposed)
* r_debug structure as well as private data only available to
@@ -736,8 +745,10 @@ _rd_loadobj_iter32_native(rd_agent_t *rap, rl_iter_f *cb, void *client_data,
}
/*
- * Read the initial APlist information that contains the link-map list
- * entries.
+ * As of VERSION6, rtd_dynlmlst points to an APlist. Prior to VERSION6
+ * rtd_dynlmlst pointed to a List. But, there was a window where the
+ * version was not incremented, and this must be worked around by
+ * interpreting the APlist data. Read the initial APlist information.
*/
if (ps_pread(rap->rd_psp, (psaddr_t)addr, (char *)&apl,
sizeof (TAPlist)) != PS_OK) {
@@ -747,50 +758,130 @@ _rd_loadobj_iter32_native(rd_agent_t *rap, rl_iter_f *cb, void *client_data,
}
/*
- * Iterate through each apl.ap_data[] entry.
+ * The rtd_dynlmlst change from a List to an APlist occurred under
+ * 6801536 in snv_112. However, this change neglected to preserve
+ * backward compatibility by maintaining List processing and using a
+ * version increment to detect the change. 6862967, intergrated in
+ * snv_121 corrects the version detection. However, to catch objects
+ * built between these releases, we look at the first element of the
+ * APlist. apl_arritems indicates the number of APlist items that are
+ * available. This was originally initialized with a AL_CNT_DYNLIST
+ * value of 2 (one entry for LM_ID_BASE and one entry for LM_ID_LDSO).
+ * It is possible that the use of an auditor results in an additional
+ * link-map list, in which case the original apl_arritems would have
+ * been doubled.
+ *
+ * Therefore, if the debugging verion is VERSION6, or the apl_arritems
+ * entry has a value less than or equal to 4 and the debugging version
+ * is VERSION5, then we process APlists. Otherwise, fall back to List
+ * processing.
*/
- for (datap = (uintptr_t)((char *)(uintptr_t)addr +
- ((size_t)(((TAPlist *)0)->apl_data))), nitems = 0;
- nitems < apl.apl_nitems; nitems++, datap += sizeof (Addr)) {
- TLm_list lm;
- ulong_t ident;
-
+ if ((rap->rd_rdebugvers >= R_RTLDDB_VERSION6) ||
+ ((rap->rd_rdebugvers == R_RTLDDB_VERSION5) &&
+ (apl.apl_arritems <= 4))) {
/*
- * Obtain the Lm_list address for this apl.ap_data[] entry.
+ * Iterate through each apl.ap_data[] entry.
*/
- if (ps_pread(rap->rd_psp, (psaddr_t)datap, (char *)&addr,
- sizeof (Addr)) != PS_OK) {
- LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5),
- EC_ADDR(datap)));
- return (RD_DBERR);
+ for (datap = (uintptr_t)((char *)(uintptr_t)addr +
+ ((size_t)(((TAPlist *)0)->apl_data))), nitems = 0;
+ nitems < apl.apl_nitems; nitems++, datap += sizeof (Addr)) {
+ TLm_list lm;
+ ulong_t ident;
+
+ /*
+ * Obtain the Lm_list address for this apl.ap_data[]
+ * entry.
+ */
+ if (ps_pread(rap->rd_psp, (psaddr_t)datap,
+ (char *)&addr, sizeof (Addr)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5),
+ EC_ADDR(datap)));
+ return (RD_DBERR);
+ }
+
+ /*
+ * Obtain the Lm_list data for this Lm_list address.
+ */
+ if (ps_pread(rap->rd_psp, (psaddr_t)addr, (char *)&lm,
+ sizeof (TLm_list)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_6),
+ EC_ADDR((uintptr_t)addr)));
+ return (RD_DBERR);
+ }
+
+ /*
+ * Determine IDENT of current LM_LIST
+ */
+ if (lm.lm_flags & LML_FLG_BASELM)
+ ident = LM_ID_BASE;
+ else if (lm.lm_flags & LML_FLG_RTLDLM)
+ ident = LM_ID_LDSO;
+ else
+ ident = (ulong_t)addr;
+
+ if ((rc = iter_map(rap, ident, (psaddr_t)lm.lm_head,
+ cb, client_data, abort_iterp)) != RD_OK)
+ return (rc);
+
+ if (*abort_iterp != 0)
+ break;
}
+ } else {
+ TList list;
+ TListnode lnode;
+ Addr lnp;
/*
- * Obtain the Lm_list data for this Lm_list address.
+ * Re-read the dynlmlst address to obtain a List structure.
*/
- if (ps_pread(rap->rd_psp, (psaddr_t)addr, (char *)&lm,
- sizeof (TLm_list)) != PS_OK) {
- LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_6),
- EC_ADDR((uintptr_t)addr)));
+ if (ps_pread(rap->rd_psp, (psaddr_t)db_priv.rtd_dynlmlst,
+ (char *)&list, sizeof (TList)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_3),
+ EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
return (RD_DBERR);
}
/*
- * Determine IDENT of current LM_LIST
+ * Iterate through the link-map list.
*/
- if (lm.lm_flags & LML_FLG_BASELM)
- ident = LM_ID_BASE;
- else if (lm.lm_flags & LML_FLG_RTLDLM)
- ident = LM_ID_LDSO;
- else
- ident = (ulong_t)addr;
+ for (lnp = (Addr)list.head; lnp; lnp = (Addr)lnode.next) {
+ Lm_list lml;
+ ulong_t ident;
+
+ /*
+ * Iterate through the List of Lm_list's.
+ */
+ if (ps_pread(rap->rd_psp, (psaddr_t)lnp, (char *)&lnode,
+ sizeof (TListnode)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_4),
+ EC_ADDR(lnp)));
+ return (RD_DBERR);
+ }
- if ((rc = iter_map(rap, ident, (psaddr_t)lm.lm_head,
- cb, client_data, abort_iterp)) != RD_OK) {
- return (rc);
+ if (ps_pread(rap->rd_psp, (psaddr_t)lnode.data,
+ (char *)&lml, sizeof (Lm_list)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5),
+ EC_ADDR((uintptr_t)lnode.data)));
+ return (RD_DBERR);
+ }
+
+ /*
+ * Determine IDENT of current LM_LIST
+ */
+ if (lml.lm_flags & LML_FLG_BASELM)
+ ident = LM_ID_BASE;
+ else if (lml.lm_flags & LML_FLG_RTLDLM)
+ ident = LM_ID_LDSO;
+ else
+ ident = (unsigned long)lnode.data;
+
+ if ((rc = iter_map(rap, ident, (psaddr_t)lml.lm_head,
+ cb, client_data, abort_iterp)) != RD_OK)
+ return (rc);
+
+ if (*abort_iterp != 0)
+ break;
}
- if (*abort_iterp != 0)
- break;
}
return (rc);
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index d84ce0aa0b..53e711e0e6 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1198,7 +1198,6 @@ All the above changes are incorporated in the following patches:
mozilla (D)
PSARC/2007/413 Add -zglobalaudit option to ld
6602294 ps_pbrandname breaks apps linked directly against librtld_db
- (link-editor components only)
--------------------------------------------------------------------------------
All the above changes are incorporated in the following patches:
Solaris/SunOS 5.10_sparc patch T127111-07
@@ -1254,12 +1253,30 @@ Bugid Risk Synopsis
6805502 The addition of "inline" keywords to sgs code broke the lint
verification in S10
6807864 ld.so.1 is susceptible to a fatal dlsym()/setlocale() race
+--------------------------------------------------------------------------------
+All the above changes are incorporated in the following patches:
+ Solaris/SunOS 5.10_sparc patch T141692-01
+ Solaris/SunOS 5.10_x86 patch T141693-01
+NOTE: The fix for 6805502 is only applicable to s10.
+--------------------------------------------------------------------------------
6826410 ld needs to sort sections using 32-bit sort keys
--------------------------------------------------------------------------------
All the above changes are incorporated in the following patches:
+ Solaris/SunOS 5.10_sparc patch T141771-01
+ Solaris/SunOS 5.10_x86 patch T141772-01
+NOTE: The fix for 6826410 is also available for s9 in the following patches:
+ Solaris/SunOS 5.9_sparc patch T112963-33
+ Solaris/SunOS 5.9_x86 patch T113986-27
+--------------------------------------------------------------------------------
+6568447 bcp is broken by 6551627
+6599700 librtld_db needs better plugin support
+6713830 mdb dumped core reading a gcore
+6756048 rd_loadobj_iter() should always invoke brand plugin callback
+6786744 32-bit dbx failed with unknown rtld_db.so error on snv_104
+--------------------------------------------------------------------------------
+All the above changes are incorporated in the following patches:
Solaris/SunOS 5.10_sparc patch TXXXXXX-XX
Solaris/SunOS 5.10_x86 patch TXXXXXX-XX
-NOTE: The fix for 6805502 is only applicable to s10.
--------------------------------------------------------------------------------
--------------
@@ -1382,7 +1399,6 @@ Bugid Risk Synopsis
6671255 link-editor should support cross linking (D)
PSARC/2008/179 cross link-editor
6674666 elfedit dyn:posflag1 needs option to locate element via NEEDED item
-6568447 bcp is broken by 6551627 (link-editor components only)
6675591 elfwrap - wrap data in an ELF file (D,P)
PSARC/2008/198 elfwrap - wrap data in an ELF file
6678244 elfdump dynamic section sanity checking needs refinement
@@ -1405,8 +1421,6 @@ Bugid Risk Synopsis
6705846 multithreaded C++ application seems to get deadlocked in the dynamic
linker code
6686343 ldd(1) - unused search path diagnosis should be enabled
-6599700 librtld_db needs better plugin support (link-editor components only)
-6713830 mdb dumped core reading a gcore
6712292 ld.so.1 should fall back to an interposer for failed direct bindings
6716350 usr/src/cmd/sgs should be linted by nightly builds
6720509 usr/src/cmd/sgs/sgsdemangler should be removed
@@ -1430,7 +1444,6 @@ Bugid Risk Synopsis
(link-editor components only)
PSARC/2008/622 32-bit Address Restriction Software Capabilities Flag
6756953 customer requests that DT_CONFIG strings be honored for secure apps (D)
-6756048 rd_loadobj_iter() should always invoke brand plugin callback
6765299 ld --version-script option not compatible with GNU ld (D)
6748160 problem with -zrescan (D)
PSARC/2008/651 New ld archive rescan options
@@ -1444,7 +1457,6 @@ Bugid Risk Synopsis
6782977 ld segfaults after support lib version error sends bad args to vprintf()
6773695 ld -z nopartial can break non-pic objects
6778453 RTLD_GROUP prevents use of application defined malloc
-6786744 32-bit dbx failed with unknown rtld_db.so error on snv_104
6789925 64-bit applications with SF1_SUNW_ADDR32 require non-default starting
address
6792906 ld -z nopartial fix breaks TLS
@@ -1491,3 +1503,7 @@ Bugid Risk Synopsis
6853809 ld.so.1: rescan fallback optimization is invalid
6854158 ld.so.1: interposition can be skipped because of incorrect
caller/destination validation
+6862967 rd_loadobj_iter() failing for core files
+6856173 streams core dumps when compiled in 64bit with a very large static
+ array size
+6834197 ld pukes when given an empty plate