diff options
author | Rod Evans <Rod.Evans@Sun.COM> | 2009-07-23 11:33:37 -0700 |
---|---|---|
committer | Rod Evans <Rod.Evans@Sun.COM> | 2009-07-23 11:33:37 -0700 |
commit | 28bda19c304ae9f3ffa10394ef34c6e8f9e4c5f5 (patch) | |
tree | fd156b4b29fc736883b5bccbebafe6b979e06194 | |
parent | 7623016fd42aadb1a19e2c2810fe6142c795c73b (diff) | |
download | illumos-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.h | 14 | ||||
-rw-r--r-- | usr/src/cmd/sgs/include/list.h | 75 | ||||
-rw-r--r-- | usr/src/cmd/sgs/include/rtld.h | 6 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/args.c | 5 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/entry.c | 3 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/map.c | 3 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/resolve.c | 56 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/syms.c | 70 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/update.c | 40 | ||||
-rw-r--r-- | usr/src/cmd/sgs/librtld_db/common/rd_elf.c | 155 | ||||
-rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 30 |
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 |