summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.c136
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.msg18
-rw-r--r--usr/src/cmd/sgs/include/debug.h10
-rw-r--r--usr/src/cmd/sgs/include/libld.h43
-rw-r--r--usr/src/cmd/sgs/libld/common/syms.c54
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/dynamic.c10
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/mapfile-vers7
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README1
-rw-r--r--usr/src/cmd/sgs/rtld/common/elf.c2
9 files changed, 143 insertions, 138 deletions
diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.c b/usr/src/cmd/sgs/elfdump/common/elfdump.c
index a6e0299182..648a9c1b9d 100644
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.c
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.c
@@ -511,8 +511,8 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *file,
* Walk the Eh_frame's
*/
while (off < datasize) {
- uint_t cieid, cielength, cieversion,
- cieretaddr;
+ uint_t cieid, cielength, cieversion;
+ uint_t cieretaddr;
int cieRflag, cieLflag, ciePflag, cieZflag;
uint_t cieaugndx, length, id;
uint64_t ciecalign, ciedalign;
@@ -565,7 +565,8 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *file,
cieretaddr);
if (cieaugstr[0])
- dbg_print(0, MSG_ORIG(MSG_UNW_CIEAUXVAL));
+ dbg_print(0,
+ MSG_ORIG(MSG_UNW_CIEAXVAL));
for (cieaugndx = 0; cieaugstr[cieaugndx];
cieaugndx++) {
@@ -573,48 +574,48 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *file,
switch (cieaugstr[cieaugndx]) {
case 'z':
- val = uleb_extract(&data[off],
- &ndx);
- dbg_print(0,
- MSG_ORIG(MSG_UNW_CIEAUXSIZE),
- val);
- cieZflag = 1;
- break;
+ val = uleb_extract(&data[off],
+ &ndx);
+ dbg_print(0,
+ MSG_ORIG(MSG_UNW_CIEAXSIZ),
+ val);
+ cieZflag = 1;
+ break;
case 'P':
- ciePflag = data[off + ndx];
- ndx += 1;
-
- persVal = dwarf_ehe_extract(
- &data[off],
- &ndx, ciePflag, ehdr->e_ident,
- shdr->sh_addr + off + ndx);
- dbg_print(0,
- MSG_ORIG(MSG_UNW_CIEAUXPERS),
- ciePflag,
- conv_dwarf_ehe(ciePflag),
- EC_XWORD(persVal));
- break;
+ ciePflag = data[off + ndx];
+ ndx += 1;
+
+ persVal = dwarf_ehe_extract(
+ &data[off], &ndx, ciePflag,
+ ehdr->e_ident,
+ shdr->sh_addr + off + ndx);
+ dbg_print(0,
+ MSG_ORIG(MSG_UNW_CIEAXPERS),
+ ciePflag,
+ conv_dwarf_ehe(ciePflag),
+ EC_XWORD(persVal));
+ break;
case 'R':
- val = data[off + ndx];
- ndx += 1;
- dbg_print(0,
- MSG_ORIG(MSG_UNW_CIEAUXCENC),
- val, conv_dwarf_ehe(val));
- cieRflag = val;
- break;
+ val = data[off + ndx];
+ ndx += 1;
+ dbg_print(0,
+ MSG_ORIG(MSG_UNW_CIEAXCENC),
+ val, conv_dwarf_ehe(val));
+ cieRflag = val;
+ break;
case 'L':
- val = data[off + ndx];
- ndx += 1;
- dbg_print(0,
- MSG_ORIG(MSG_UNW_CIEAUXLSDA),
- val, conv_dwarf_ehe(val));
- cieLflag = val;
- break;
+ val = data[off + ndx];
+ ndx += 1;
+ dbg_print(0,
+ MSG_ORIG(MSG_UNW_CIEAXLSDA),
+ val, conv_dwarf_ehe(val));
+ cieLflag = val;
+ break;
default:
- dbg_print(0,
- MSG_ORIG(MSG_UNW_CIEAUXUNEC),
- cieaugstr[cieaugndx]);
- break;
+ dbg_print(0,
+ MSG_ORIG(MSG_UNW_CIEAXUNEC),
+ cieaugstr[cieaugndx]);
+ break;
}
}
if ((cielength + 4) > ndx)
@@ -648,21 +649,21 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *file,
if (cieaugstr[0])
dbg_print(0,
- MSG_ORIG(MSG_UNW_FDEAUXVAL));
+ MSG_ORIG(MSG_UNW_FDEAXVAL));
if (cieZflag) {
uint64_t val;
val = uleb_extract(&data[off], &ndx);
dbg_print(0,
- MSG_ORIG(MSG_UNW_FDEAUXSIZE),
+ MSG_ORIG(MSG_UNW_FDEAXSIZE),
EC_XWORD(val));
if (val & cieLflag) {
- fdeinitloc = dwarf_ehe_extract(
- &data[off], &ndx, cieLflag,
- ehdr->e_ident,
- shdr->sh_addr + off + ndx);
- dbg_print(0,
- MSG_ORIG(MSG_UNW_FDEAUXLSDA),
- EC_XWORD(val));
+ fdeinitloc = dwarf_ehe_extract(
+ &data[off], &ndx, cieLflag,
+ ehdr->e_ident,
+ shdr->sh_addr + off + ndx);
+ dbg_print(0,
+ MSG_ORIG(MSG_UNW_FDEAXLSDA),
+ EC_XWORD(val));
}
}
if ((fdelength + 4) > ndx)
@@ -955,8 +956,7 @@ version_def(Verdef *vdf, Word shnum, Cache *vcache, Cache *scache,
const char *name, *dep;
Half vcnt = vdf->vd_cnt - 1;
Half ndx = vdf->vd_ndx;
- Verdaux *vdap = (Verdaux *)((uintptr_t)vdf +
- vdf->vd_aux);
+ Verdaux *vdap = (Verdaux *)((uintptr_t)vdf + vdf->vd_aux);
/*
* Obtain the name and first dependency (if any).
@@ -1004,8 +1004,7 @@ version_need(Verneed *vnd, Word shnum, Cache *vcache, Cache *scache,
vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
const char *name, *dep;
Half vcnt = vnd->vn_cnt;
- Vernaux *vnap = (Vernaux *)((uintptr_t)vnd +
- vnd->vn_aux);
+ Vernaux *vnap = (Vernaux *)((uintptr_t)vnd + vnd->vn_aux);
/*
* Obtain the name of the needed file and the version name
@@ -1314,19 +1313,20 @@ output_symbol(SYMTBL_STATE *state, Word symndx, Word disp_symndx, Sym *sym)
Word _shxndx;
if (symndx > state->shxndx.n) {
- (void) fprintf(stderr,
- MSG_INTL(MSG_ERR_BADSYMXINDEX1),
- state->file, state->secname, EC_WORD(symndx));
+ (void) fprintf(stderr,
+ MSG_INTL(MSG_ERR_BADSYMXINDEX1),
+ state->file, state->secname,
+ EC_WORD(symndx));
} else if ((_shxndx =
state->shxndx.data[symndx]) > state->shnum) {
- (void) fprintf(stderr,
- MSG_INTL(MSG_ERR_BADSYMXINDEX2),
- state->file, state->secname, EC_WORD(symndx),
- EC_WORD(_shxndx));
+ (void) fprintf(stderr,
+ MSG_INTL(MSG_ERR_BADSYMXINDEX2),
+ state->file, state->secname,
+ EC_WORD(symndx), EC_WORD(_shxndx));
} else {
- shndx = _shxndx;
- tshdr = state->cache[shndx].c_shdr;
- sec = state->cache[shndx].c_name;
+ shndx = _shxndx;
+ tshdr = state->cache[shndx].c_shdr;
+ sec = state->cache[shndx].c_name;
}
} else {
(void) fprintf(stderr,
@@ -1362,8 +1362,8 @@ output_symbol(SYMTBL_STATE *state, Word symndx, Word disp_symndx, Sym *sym)
* - If this is not a GNU "hidden bit" issue, then
* issue a generic "out of range" error.
*/
- if (VERNDX_INVALID(sym->st_shndx, state->versym->num_verdef,
- state->versym->data, verndx)) {
+ if (VERNDX_INVALID_DIAG(sym->st_shndx,
+ state->versym->num_verdef, state->versym->data, symndx)) {
if (state->versym->gnu && (verndx & 0x8000) &&
((verndx & ~0x8000) <=
state->versym->num_verdef)) {
@@ -1800,7 +1800,7 @@ dynamic(Cache *cache, Word shnum, Ehdr *ehdr, const char *file)
*/
end_ndx = ndx;
while ((end_ndx < (numdyn - 1)) &&
- ((dyn + 1)->d_tag == DT_NULL)) {
+ ((dyn + 1)->d_tag == DT_NULL)) {
dyn++;
end_ndx++;
}
@@ -2415,7 +2415,7 @@ group(Cache *cache, Word shnum, const char *file, uint_t flags)
name = cache[grpdata[gcnt]].c_name;
(void) printf(MSG_ORIG(MSG_GRP_ENTRY), index, name,
- EC_XWORD(grpdata[gcnt]));
+ EC_XWORD(grpdata[gcnt]));
}
}
}
diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.msg b/usr/src/cmd/sgs/elfdump/common/elfdump.msg
index 17ce8847cf..8adc9f5cf3 100644
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg
@@ -282,21 +282,21 @@
@ MSG_UNW_CIEVERS " version: %d augstring: `%s'"
@ MSG_UNW_CIECALGN " codealign: 0x%llx dataalign: %lld \
retaddr: %d"
-@ MSG_UNW_CIEAUXVAL " Auxiliary vals:"
-@ MSG_UNW_CIEAUXSIZE " size: %d"
-@ MSG_UNW_CIEAUXPERS " pers: 0x%02x %s 0x%08llx"
-@ MSG_UNW_CIEAUXCENC " cenc: 0x%02x %s"
-@ MSG_UNW_CIEAUXLSDA " lsda: 0x%02x %s"
-@ MSG_UNW_CIEAUXUNEC " Unexpected aug val: %c"
+@ MSG_UNW_CIEAXVAL " Auxiliary vals:"
+@ MSG_UNW_CIEAXSIZ " size: %d"
+@ MSG_UNW_CIEAXPERS " pers: 0x%02x %s 0x%08llx"
+@ MSG_UNW_CIEAXCENC " cenc: 0x%02x %s"
+@ MSG_UNW_CIEAXLSDA " lsda: 0x%02x %s"
+@ MSG_UNW_CIEAXUNEC " Unexpected aug val: %c"
@ MSG_UNW_CIECFI " CallFrameInstructions:"
@ MSG_UNW_CIEPRE " "
@ MSG_UNW_FDE " FDE: [0x%08llx]"
@ MSG_UNW_FDELNGTH " length: 0x%02x cieptr: 0x%02x"
@ MSG_UNW_FDEINITLOC " initloc: 0x%08llx addrrange: 0x%04llx"
-@ MSG_UNW_FDEAUXVAL " Auxiliary vals:"
-@ MSG_UNW_FDEAUXSIZE " size: 0x%llx"
-@ MSG_UNW_FDEAUXLSDA " lsda: 0x%llx"
+@ MSG_UNW_FDEAXVAL " Auxiliary vals:"
+@ MSG_UNW_FDEAXSIZE " size: 0x%llx"
+@ MSG_UNW_FDEAXLSDA " lsda: 0x%llx"
@ MSG_UNW_FDECFI " CallFrameInstructions:"
@ MSG_UNW_FDEPRE " "
diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h
index f8a5781c44..9325ccd346 100644
--- a/usr/src/cmd/sgs/include/debug.h
+++ b/usr/src/cmd/sgs/include/debug.h
@@ -962,16 +962,6 @@ extern void Elf_ver_line_5(Lm_list *, const char *, const char *);
extern void Elf_ver_need_title(Lm_list *);
-/*
- * Establish GElf_*() interfaces. These are wrappers around the
- * Elf64*() versions of the above functions, callable from either
- * 32 or 64-bit code. Note that they omit the Lm_list argument.
- * It is not needed, since GElf is never used within the runtime loader
- * itself, only in ELF applications.
- */
-extern void GElf_dyn_entry(GElf_Dyn *, int, const char *, GElf_Half);
-
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h
index 070eb0cd33..f1a8691181 100644
--- a/usr/src/cmd/sgs/include/libld.h
+++ b/usr/src/cmd/sgs/include/libld.h
@@ -939,13 +939,24 @@ struct ver_index {
* entry:
* _shndx - Symbol section index
* _vercnt - # of versions defined by object containing symbol
- * _versym_arr - NULL, or pointer to versym array
- * _verndx - Version index of symbol. Note that this argument is
- * only evaluated if _versym_arr is non-NULL.
+ * in its verdef section. 0 implies that there is no verdef.
+ * _versym - Pointer to versym array, or NULL if there isn't one.
+ * _symndx - Index of symbol within containing symbol table
+ * Used to index _versym, but only if _versym is non-NULL.
*
* note:
- * _vercnt and _verndx are evaluated more than once. Beware
- * of expensive computations, or computations with side effects.
+ * _vercnt and _versym[_symndx] are evaluated more than once.
+ * Beware of expensive computations, or computations with side effects.
+ *
+ * There are two versions of this macro:
+ *
+ * VERNDX_INVALID - Used by ld and rtld
+ * VERNDX_INVALID_DIAG - Used by diagnostic tools such as elfdump.
+ *
+ * The difference is that VERNDX_INVALID does not examine the versym
+ * array if the number of defined versions is 0. This allows us to
+ * run GNU binaries (See below for details). However, the diagnostic
+ * tools will report them.
*
* If we encounter a defined symbol with a version that is outside the
* range of the valid versions supplied by the file, then we quietly
@@ -973,14 +984,22 @@ struct ver_index {
*
* In this case, there will be a versym section (containing version
* indexes 0 and 1). However, there are no versions defined, and
- * hence no corresponding verdef section. We treat this case specially:
- * If the versym section is present (_versym_arr is non-NULL)
- * and the verdef section is not, we act as if _vercnt is 1.
+ * hence no corresponding verdef section.
+ *
+ * We have also seen objects produced by the GNU ld in which an object
+ * with no verdef section contains symbols with version symbols greater
+ * than 1. For both of these reasons, we allow and ignore arbitrary
+ * versions in the case where there is a versym section but the vesion
+ * count (_vercnt) is 0.
*/
-#define VERNDX_INVALID(_shndx, _vercnt, _versym_arr, _verndx) \
- (((_shndx) != SHN_UNDEF) && (_versym_arr != NULL) && \
- ((_verndx) > ((_vercnt == 0) ? 1 : _vercnt)) && \
- ((_verndx) < VER_NDX_LORESERVE))
+#define VERNDX_INVALID_DIAG(_shndx, _vercnt, _versym, _symndx) \
+ (((_shndx) != SHN_UNDEF) && (_versym != NULL) && \
+ ((_versym)[_symndx] > ((_vercnt == 0) ? 1 : _vercnt)) && \
+ ((_versym)[_symndx] < VER_NDX_LORESERVE))
+#define VERNDX_INVALID(_shndx, _vercnt, _versym, _symndx) \
+ (((_shndx) != SHN_UNDEF) && (_versym != NULL) && \
+ ((_versym)[_symndx] > _vercnt) && ((_vercnt) > 0) && \
+ ((_versym)[_symndx] < VER_NDX_LORESERVE))
diff --git a/usr/src/cmd/sgs/libld/common/syms.c b/usr/src/cmd/sgs/libld/common/syms.c
index 3a0e46b862..212d294093 100644
--- a/usr/src/cmd/sgs/libld/common/syms.c
+++ b/usr/src/cmd/sgs/libld/common/syms.c
@@ -434,7 +434,9 @@ ld_sym_enter(const char *name, Sym *osym, Word hash, Ifl_desc *ifl,
((nsym->st_shndx == SHN_COMMON) ||
(nsym->st_shndx == SHN_X86_64_LCOMMON)))))
#else
+ /* BEGIN CSTYLED */
(nsym->st_shndx == SHN_COMMON))))
+ /* END CSTYLED */
#endif
sdp->sd_flags |= FLG_SY_GLOBREF;
@@ -565,15 +567,16 @@ sym_add_spec(const char *name, const char *uname, Word sdaux_id,
*/
if (!(usdp->sd_flags1 & FLG_SY1_LOCL) &&
(flags1 & FLG_SY1_GLOB)) {
- usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
- if (sdaux_id == SDAUX_ID_GOT) {
- usdp->sd_flags1 &= ~FLG_SY1_NDIR;
- usdp->sd_flags1 |= FLG_SY1_PROT;
- usdp->sd_sym->st_other = STV_PROTECTED;
- } else if (((usdp->sd_flags1 & FLG_SY1_DIR) == 0) &&
- ((ofl->ofl_flags & FLG_OF_SYMBOLIC) == 0)) {
- usdp->sd_flags1 |= FLG_SY1_NDIR;
- }
+ usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
+ if (sdaux_id == SDAUX_ID_GOT) {
+ usdp->sd_flags1 &= ~FLG_SY1_NDIR;
+ usdp->sd_flags1 |= FLG_SY1_PROT;
+ usdp->sd_sym->st_other = STV_PROTECTED;
+ } else if (
+ ((usdp->sd_flags1 & FLG_SY1_DIR) == 0) &&
+ ((ofl->ofl_flags & FLG_OF_SYMBOLIC) == 0)) {
+ usdp->sd_flags1 |= FLG_SY1_NDIR;
+ }
}
usdp->sd_flags1 |= flags1;
@@ -688,10 +691,10 @@ static void
sym_undef_title(Ofl_desc *ofl)
{
eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FMT_UNDEF),
- MSG_INTL(MSG_SYM_UNDEF_ITM_11),
- MSG_INTL(MSG_SYM_UNDEF_ITM_21),
- MSG_INTL(MSG_SYM_UNDEF_ITM_12),
- MSG_INTL(MSG_SYM_UNDEF_ITM_22));
+ MSG_INTL(MSG_SYM_UNDEF_ITM_11),
+ MSG_INTL(MSG_SYM_UNDEF_ITM_21),
+ MSG_INTL(MSG_SYM_UNDEF_ITM_12),
+ MSG_INTL(MSG_SYM_UNDEF_ITM_22));
undef_title = FALSE;
}
@@ -1339,7 +1342,7 @@ ld_sym_validate(Ofl_desc *ofl)
*/
if (sym->st_shndx == SHN_X86_64_LCOMMON) {
lbsssize = (Xword)S_ROUND(lbsssize, sym->st_value) +
- sym->st_size;
+ sym->st_size;
if (sym->st_value > lbssalign)
lbssalign = sym->st_value;
}
@@ -2011,8 +2014,8 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl)
* comment that accompanies the VERSYM_INVALID macro in libld.h
* for additional details.
*/
- if (VERNDX_INVALID(shndx, ifl->ifl_vercnt, ifl->ifl_versym,
- ifl->ifl_versym[ndx]))
+ if (VERNDX_INVALID(shndx, ifl->ifl_vercnt,
+ ifl->ifl_versym, ndx))
continue;
/*
@@ -2279,15 +2282,16 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl)
s_dynbits = ssdp->sd_flags &
(FLG_SY_DYNSORT | FLG_SY_NODYNSORT);
if (!(w_dynbits && s_dynbits)) {
- if (s_dynbits) {
- if (s_dynbits == FLG_SY_DYNSORT)
- wsdp->sd_flags |=
- FLG_SY_NODYNSORT;
- } else if (w_dynbits !=
- FLG_SY_NODYNSORT) {
- ssdp->sd_flags |=
- FLG_SY_NODYNSORT;
- }
+ if (s_dynbits) {
+ if (s_dynbits ==
+ FLG_SY_DYNSORT)
+ wsdp->sd_flags |=
+ FLG_SY_NODYNSORT;
+ } else if (w_dynbits !=
+ FLG_SY_NODYNSORT) {
+ ssdp->sd_flags |=
+ FLG_SY_NODYNSORT;
+ }
}
break;
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/dynamic.c b/usr/src/cmd/sgs/liblddbg/common/dynamic.c
index aadb44cc41..9e5ef03f85 100644
--- a/usr/src/cmd/sgs/liblddbg/common/dynamic.c
+++ b/usr/src/cmd/sgs/liblddbg/common/dynamic.c
@@ -51,14 +51,6 @@ Elf_dyn_entry(Lm_list *lml, Dyn *dyn, int ndx, const char *name, Half mach)
conv_dyn_tag(dyn->d_tag, mach, 0), EC_XWORD(dyn->d_un.d_val), name);
}
-#ifdef _ELF64
-void
-GElf_dyn_entry(GElf_Dyn *dyn, int ndx, const char *name, GElf_Half mach)
-{
- Elf_dyn_entry(NULL, dyn, ndx, name, mach);
-}
-#endif
-
/*
* Variant of Elf_dyn_entry() specifically for DT_NULL. Handles the
* case of multiple adjacent DT_NULL entries by displaying them on
@@ -76,6 +68,6 @@ Elf_dyn_null_entry(Lm_list *lml, Dyn *dyn, int start_ndx, int end_ndx)
MSG_ORIG(MSG_FMT_INDEX_RANGE), start_ndx, end_ndx);
dbg_print(lml, MSG_INTL(MSG_DYN_ENTRY), index,
conv_dyn_tag(DT_NULL, 0, 0), EC_XWORD(dyn->d_un.d_val),
- MSG_ORIG(MSG_STR_EMPTY));
+ MSG_ORIG(MSG_STR_EMPTY));
}
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
index 4aa8eeb491..2184bf3308 100644
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
@@ -429,16 +429,16 @@ SUNWprivate_4.59 {
Dbg32_ver_symbol;
Dbg64_ver_symbol;
-} SUNWprivate_3.21;
+} SUNWprivate_3.22;
# The following interfaces are used by various parts of the link-editors and
# elfdump(1). The link-editors are always packaged together but there
# seems to be a variety of old elfdump's lying around. elfdump only uses
# this interface, and thus by separating in from the ever changing Dbg_*
-# interfaces we can provide a stable verioning environment for this utility.
+# interfaces we can provide a stable versioning environment for this utility.
-SUNWprivate_3.21 {
+SUNWprivate_3.22 {
global:
Elf_syminfo_entry;
Elf_syminfo_title;
@@ -452,7 +452,6 @@ SUNWprivate_3.21 {
Elf64_demangle_name;
Elf32_dyn_entry;
Elf64_dyn_entry;
- GElf_dyn_entry;
Elf32_dyn_null_entry;
Elf64_dyn_null_entry;
Elf32_dyn_title;
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index cc181d1419..6a9941d78c 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1241,3 +1241,4 @@ Bugid Risk Synopsis
6556563 elfdump section overlap checking is too slow for large files
5006034 need ?E mapfile feature extension (D)
6561987 data vac_conflict faults on lipthread libthread libs in s10.
+6565476 rtld symbol version check prevents GNU ld binary from running
diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c
index 6e0bb39253..cb6ac5679a 100644
--- a/usr/src/cmd/sgs/rtld/common/elf.c
+++ b/usr/src/cmd/sgs/rtld/common/elf.c
@@ -1857,7 +1857,7 @@ elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* for additional details.
*/
if (VERNDX_INVALID(sym->st_shndx, VERDEFNUM(ilmp),
- VERSYM(ilmp), VERSYM(ilmp)[ndx])) {
+ VERSYM(ilmp), ndx)) {
DBG_CALL(Dbg_syms_ignore_badver(ilmp, name,
ndx, VERSYM(ilmp)[ndx]));
if ((ndx = chainptr[ndx]) != 0)