diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/archive.c | 1 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 4 | ||||
-rw-r--r-- | bfd/elf.c | 10 | ||||
-rw-r--r-- | bfd/elf32-mips.c | 5 | ||||
-rw-r--r-- | bfd/elf64-ia64-vms.c | 4 | ||||
-rw-r--r-- | bfd/elfcode.h | 3 | ||||
-rw-r--r-- | bfd/elflink.c | 177 | ||||
-rw-r--r-- | bfd/elfn32-mips.c | 5 | ||||
-rw-r--r-- | bfd/linker.c | 44 | ||||
-rw-r--r-- | bfd/syms.c | 14 |
10 files changed, 218 insertions, 49 deletions
diff --git a/bfd/archive.c b/bfd/archive.c index 1715474ea6c..7e0a7533681 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -2372,6 +2372,7 @@ _bfd_compute_and_write_armap (bfd *arch, unsigned int elength) if (((flags & (BSF_GLOBAL | BSF_WEAK + | BSF_SECONDARY | BSF_INDIRECT | BSF_GNU_UNIQUE)) != 0 || bfd_is_com_section (sec)) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 51fa54f1d43..bb5b536e081 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -6337,6 +6337,10 @@ typedef struct bfd_symbol with this name and type in use. BSF_OBJECT must also be set. */ #define BSF_GNU_UNIQUE (1 << 23) + /* A secondary global symbol, overridable without warnings by + a regular or weak global symbol of the same name. */ +#define BSF_SECONDARY (1 << 24) + flagword flags; /* A pointer to the section to which this symbol is diff --git a/bfd/elf.c b/bfd/elf.c index 35c0f6cdf43..29cfec333e3 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -3625,7 +3625,10 @@ sym_is_global (bfd *abfd, asymbol *sym) if (bed->elf_backend_sym_is_global) return (*bed->elf_backend_sym_is_global) (abfd, sym); - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 + return ((sym->flags & (BSF_GLOBAL + | BSF_WEAK + | BSF_SECONDARY + | BSF_GNU_UNIQUE)) != 0 || bfd_is_und_section (bfd_get_section (sym)) || bfd_is_com_section (bfd_get_section (sym))); } @@ -7408,8 +7411,9 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"), #endif sym.st_info = ELF_ST_INFO (STB_GLOBAL, type); } + /* Output undefined secondary symbols as weak. */ else if (bfd_is_und_section (syms[idx]->section)) - sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK) + sym.st_info = ELF_ST_INFO (((flags & (BSF_WEAK | BSF_SECONDARY)) ? STB_WEAK : STB_GLOBAL), type); @@ -7423,6 +7427,8 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"), bind = STB_LOCAL; else if (flags & BSF_GNU_UNIQUE) bind = STB_GNU_UNIQUE; + else if (flags & BSF_SECONDARY) + bind = STB_SECONDARY; else if (flags & BSF_WEAK) bind = STB_WEAK; else if (flags & BSF_GLOBAL) diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index fff08e5568d..f1755799207 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -2258,7 +2258,10 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) if (SGI_COMPAT (abfd)) return (sym->flags & BSF_SECTION_SYM) == 0; else - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 + return ((sym->flags & (BSF_GLOBAL + | BSF_WEAK + | BSF_SECONDARY + | BSF_GNU_UNIQUE)) != 0 || bfd_is_und_section (bfd_get_section (sym)) || bfd_is_com_section (bfd_get_section (sym))); } diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c index 4dc5363f6bc..129413358ff 100644 --- a/bfd/elf64-ia64-vms.c +++ b/bfd/elf64-ia64-vms.c @@ -4926,6 +4926,10 @@ error_free_dyn: flags = BSF_WEAK; break; + case STB_SECONDARY: + flags = BSF_SECONDARY; + break; + case STB_GNU_UNIQUE: flags = BSF_GNU_UNIQUE; break; diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 7e309cf998e..17f44bc0907 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1280,6 +1280,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic) case STB_WEAK: sym->symbol.flags |= BSF_WEAK; break; + case STB_SECONDARY: + sym->symbol.flags |= BSF_SECONDARY; + break; case STB_GNU_UNIQUE: sym->symbol.flags |= BSF_GNU_UNIQUE; break; diff --git a/bfd/elflink.c b/bfd/elflink.c index 8659099df0d..c4a0c1278e1 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -926,7 +926,8 @@ elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, overriding a new definition. We set TYPE_CHANGE_OK if it is OK for the type to change. We set SIZE_CHANGE_OK if it is OK for the size to change. By OK to change, we mean that we shouldn't warn if the - type or size does change. */ + type or size does change. If OLDSECONARY is TRUE, the old definion + is a secondary symbol. */ static bfd_boolean _bfd_elf_merge_symbol (bfd *abfd, @@ -936,6 +937,7 @@ _bfd_elf_merge_symbol (bfd *abfd, asection **psec, bfd_vma *pvalue, struct elf_link_hash_entry **sym_hash, + bfd_boolean oldsecondary, bfd **poldbfd, bfd_boolean *pold_weak, unsigned int *pold_alignment, @@ -952,7 +954,7 @@ _bfd_elf_merge_symbol (bfd *abfd, int bind; bfd *oldbfd; bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; - bfd_boolean newweak, oldweak, newfunc, oldfunc; + bfd_boolean newweak, oldweak, newfunc, oldfunc, weakbind; const struct elf_backend_data *bed; char *new_version; @@ -1073,9 +1075,17 @@ _bfd_elf_merge_symbol (bfd *abfd, if (poldbfd && *poldbfd == NULL) *poldbfd = oldbfd; + /* Set OLDSECONADRY if it isn't TRUE. */ + if (!oldsecondary) + oldsecondary = h->root.secondary != 0; + + /* Treat secondary symbols as weak symbols. */ + weakbind = bind == STB_WEAK || bind == STB_SECONDARY; + /* Differentiate strong and weak symbols. */ - newweak = bind == STB_WEAK; - oldweak = (h->root.type == bfd_link_hash_defweak + newweak = weakbind; + oldweak = (oldsecondary + || h->root.type == bfd_link_hash_defweak || h->root.type == bfd_link_hash_undefweak); if (pold_weak) *pold_weak = oldweak; @@ -1106,7 +1116,7 @@ _bfd_elf_merge_symbol (bfd *abfd, { if (bfd_is_und_section (sec)) { - if (bind != STB_WEAK) + if (!weakbind) { h->ref_dynamic_nonweak = 1; hi->ref_dynamic_nonweak = 1; @@ -1357,7 +1367,7 @@ _bfd_elf_merge_symbol (bfd *abfd, if (newdef && !newdyn && olddyn) newweak = FALSE; - if (olddef && newdyn) + if (olddef && newdyn && !oldsecondary) oldweak = FALSE; /* Allow changes between different types of function symbol. */ @@ -1472,10 +1482,14 @@ _bfd_elf_merge_symbol (bfd *abfd, represent variables; this can cause confusion in principle, but any such confusion would seem to indicate an erroneous program or shared library. We also permit a common symbol in a regular - object to override a weak symbol in a shared object. */ + object to override a weak symbol in a shared object. + + We let a definition in a dynamic object override the old secondary + symbol. */ if (newdyn && newdef + && !oldsecondary && (olddef || (h->root.type == bfd_link_hash_common && (newweak || newfunc)))) @@ -1514,8 +1528,9 @@ _bfd_elf_merge_symbol (bfd *abfd, *size_change_ok = TRUE; } - /* Skip weak definitions of symbols that are already defined. */ - if (newdef && olddef && newweak) + /* Skip weak definitions of symbols that are already defined unless + the old definition is secondary. */ + if (newdef && olddef && newweak && !oldsecondary) { /* Don't skip new non-IR weak syms. */ if (!(oldbfd != NULL @@ -1546,18 +1561,20 @@ _bfd_elf_merge_symbol (bfd *abfd, always take precedence over symbols from dynamic objects, even if they are defined after the dynamic object in the link. + The new non-secondary definition overrides the old secondary + definition. + As above, we again permit a common symbol in a regular object to override a definition in a shared object if the shared object symbol is a function or is weak. */ flip = NULL; - if (!newdyn + if (((!newdyn && olddyn && h->def_dynamic) || oldsecondary) + && bind != STB_SECONDARY && (newdef || (bfd_is_com_section (sec) && (oldweak || oldfunc))) - && olddyn - && olddef - && h->def_dynamic) + && olddef) { /* Change the hash table entry to undefined, and let _bfd_generic_link_add_one_symbol do the right thing with the @@ -1660,8 +1677,8 @@ _bfd_elf_merge_symbol (bfd *abfd, /* This function is called to create an indirect symbol from the default for the symbol with the default version if needed. The - symbol is described by H, NAME, SYM, SEC, and VALUE. We - set DYNSYM if the new indirect symbol is dynamic. */ + symbol is described by H, NAME, SYM, SEC, VALUE, and OLDSECONDARY. + We set DYNSYM if the new indirect symbol is dynamic. */ static bfd_boolean _bfd_elf_add_default_symbol (bfd *abfd, @@ -1671,6 +1688,7 @@ _bfd_elf_add_default_symbol (bfd *abfd, Elf_Internal_Sym *sym, asection *sec, bfd_vma value, + bfd_boolean oldsecondary, bfd **poldbfd, bfd_boolean *dynsym) { @@ -1716,6 +1734,11 @@ _bfd_elf_add_default_symbol (bfd *abfd, } } + /* Handle the unversioned STB_SECONDARY symbol with the versioned + definition. */ + if (p == NULL) + return TRUE; + bed = get_elf_backend_data (abfd); collect = bed->collect; dynamic = (abfd->flags & DYNAMIC) != 0; @@ -1736,8 +1759,9 @@ _bfd_elf_add_default_symbol (bfd *abfd, matched = TRUE; tmp_sec = sec; if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, - &hi, poldbfd, NULL, NULL, &skip, &override, - &type_change_ok, &size_change_ok, &matched)) + &hi, oldsecondary, poldbfd, NULL, NULL, + &skip, &override, &type_change_ok, + &size_change_ok, &matched)) return FALSE; if (skip) @@ -1856,8 +1880,9 @@ nondefault: size_change_ok = FALSE; tmp_sec = sec; if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, - &hi, poldbfd, NULL, NULL, &skip, &override, - &type_change_ok, &size_change_ok, &matched)) + &hi, oldsecondary, poldbfd, NULL, NULL, &skip, + &override, &type_change_ok, &size_change_ok, + &matched)) return FALSE; if (skip) @@ -3003,31 +3028,41 @@ _bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info) return tls; } -/* Return TRUE iff this is a non-common, definition of a non-function symbol. */ +/* Return TRUE iff this is a non-common, definition of a + non-function symbol, unless IGNORE_SECONDARY is TRUE. */ + static bfd_boolean -is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, - Elf_Internal_Sym *sym) +is_global_symbol_definition (bfd *abfd, Elf_Internal_Sym *sym, + bfd_boolean ignore_secondary) { - const struct elf_backend_data *bed; + /* Ignore secondary symbols. */ + if (ignore_secondary && ELF_ST_BIND (sym->st_info) == STB_SECONDARY) + return FALSE; /* Local symbols do not count, but target specific ones might. */ if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL && ELF_ST_BIND (sym->st_info) < STB_LOOS) return FALSE; - bed = get_elf_backend_data (abfd); - /* Function symbols do not count. */ - if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))) - return FALSE; - /* If the section is undefined, then so is the symbol. */ if (sym->st_shndx == SHN_UNDEF) return FALSE; - /* If the symbol is defined in the common section, then - it is a common definition and so does not count. */ - if (bed->common_definition (sym)) - return FALSE; + /* If secondary symbols are ignored, count function and common + symbols as global definition. */ + if (!ignore_secondary) + { + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + + /* Function symbols do not count. */ + if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))) + return FALSE; + + /* If the symbol is defined in the common section, then + it is a common definition and so does not count. */ + if (bed->common_definition (sym)) + return FALSE; + } /* If the symbol is in a target specific section then we must rely upon the backend to tell us what it is. */ @@ -3046,9 +3081,12 @@ is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, /* Search the symbol table of the archive element of the archive ABFD whose archive map contains a mention of SYMDEF, and determine if - the symbol is defined in this element. */ + the symbol is defined in this element. Igore seconday defintion, + it IGNORE_SECONDARY is TRUE. */ + static bfd_boolean -elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) +elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef, + bfd_boolean ignore_secondary) { Elf_Internal_Shdr * hdr; bfd_size_type symcount; @@ -3113,7 +3151,8 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) if (strcmp (name, symdef->name) == 0) { - result = is_global_data_symbol_definition (abfd, isym); + result = is_global_symbol_definition (abfd, isym, + ignore_secondary); break; } } @@ -3962,6 +4001,7 @@ error_free_dyn: unsigned int old_alignment; bfd *old_bfd; bfd_boolean matched; + bfd_boolean oldsecondary; override = FALSE; @@ -3989,6 +4029,10 @@ error_free_dyn: flags = BSF_WEAK; break; + case STB_SECONDARY: + flags = BSF_SECONDARY; + break; + case STB_GNU_UNIQUE: flags = BSF_GNU_UNIQUE; break; @@ -4224,7 +4268,7 @@ error_free_dyn: | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value, - sym_hash, &old_bfd, &old_weak, + sym_hash, FALSE, &old_bfd, &old_weak, &old_alignment, &skip, &override, &type_change_ok, &size_change_ok, &matched)) @@ -4247,7 +4291,12 @@ error_free_dyn: && vernum > 1 && definition) h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1]; + + /* Remember if the old definition is secondary. */ + oldsecondary = h->root.secondary != 0; } + else + oldsecondary = FALSE; if (! (_bfd_generic_link_add_one_symbol (info, abfd, name, flags, sec, value, NULL, FALSE, bed->collect, @@ -4327,10 +4376,14 @@ error_free_dyn: if (! definition) { h->ref_regular = 1; - if (bind != STB_WEAK) + /* Treat secondary symbols as weak symbols. */ + if (bind != STB_WEAK && bind != STB_SECONDARY) h->ref_regular_nonweak = 1; } - else + /* Mark it defined in a regular object if it is a + non-secondary definition or it hasn't been defined + in a dynamic object. */ + else if (!h->def_dynamic || bind != STB_SECONDARY) { h->def_regular = 1; if (h->def_dynamic) @@ -4359,6 +4412,13 @@ error_free_dyn: { h->def_dynamic = 1; hi->def_dynamic = 1; + /* Dynamic definition overrides regular old secondary + definition. */ + if (oldsecondary) + { + h->def_regular = 0; + hi->def_regular = 0; + } } /* If the indirect symbol has been forced local, don't @@ -4377,7 +4437,8 @@ error_free_dyn: if (definition || (!override && h->root.type == bfd_link_hash_common)) if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym, - sec, value, &old_bfd, &dynsym)) + sec, value, oldsecondary, + &old_bfd, &dynsym)) goto error_free_vers; /* Check the alignment when a common symbol is involved. This @@ -5169,16 +5230,27 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) map alone. Instead we must read in the element's symbol table and check that to see what kind of symbol definition this is. */ - if (! elf_link_is_defined_archive_symbol (abfd, symdef)) + if (! elf_link_is_defined_archive_symbol (abfd, symdef, + FALSE)) continue; } - else if (h->root.type != bfd_link_hash_undefined) + /* Keep searching if a definition is secondary. */ + else if (h->root.type != bfd_link_hash_undefined + && !h->root.secondary) { if (h->root.type != bfd_link_hash_undefweak) /* Symbol must be defined. Don't check it again. */ included[i] = TRUE; continue; } + else if (h->root.secondary + && h->root.type == bfd_link_hash_defweak) + { + /* Ignore another secondary definition. */ + if (! elf_link_is_defined_archive_symbol (abfd, symdef, + TRUE)) + continue; + } /* We need to include this archive member. */ element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); @@ -9190,7 +9262,21 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, h->type); else if (h->root.type == bfd_link_hash_undefweak || h->root.type == bfd_link_hash_defweak) - sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); + { + /* Generate defined secondary symbols for "ld -shared -z secondary" + and "ld -r". For undefined secondary symbols, we convert them + to weak symbols. We also convert defined secondary symbols in + executables to weak symbols since their bindings in executables + are final and can't be changed. */ + if ((bfd_link_relocatable (flinfo->info) + || (!bfd_link_executable (flinfo->info) + && flinfo->info->emit_secondary)) + && h->root.type == bfd_link_hash_defweak + && h->root.secondary) + sym.st_info = ELF_ST_INFO (STB_SECONDARY, h->type); + else + sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); + } else sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); sym.st_target_internal = h->target_internal; @@ -9302,7 +9388,8 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) if (sym.st_shndx == SHN_UNDEF && h->ref_regular && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL - || ELF_ST_BIND (sym.st_info) == STB_WEAK)) + || ELF_ST_BIND (sym.st_info) == STB_WEAK + || ELF_ST_BIND (sym.st_info) == STB_SECONDARY)) { int bindtype; unsigned int type = ELF_ST_TYPE (sym.st_info); @@ -9328,10 +9415,12 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) sym.st_size = 0; /* If a non-weak symbol with non-default visibility is not defined - locally, it is a fatal error. */ + locally, it is a fatal error. Treat secondary symbols as weak + symbols. */ if (!bfd_link_relocatable (flinfo->info) && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT && ELF_ST_BIND (sym.st_info) != STB_WEAK + && ELF_ST_BIND (sym.st_info) != STB_SECONDARY && h->root.type == bfd_link_hash_undefined && !h->def_regular) { diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 504c3f39c69..7321f6d8261 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -3461,7 +3461,10 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) if (SGI_COMPAT (abfd)) return (sym->flags & BSF_SECTION_SYM) == 0; else - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 + return ((sym->flags & (BSF_GLOBAL + | BSF_WEAK + | BSF_SECONDARY + | BSF_GNU_UNIQUE)) != 0 || bfd_is_und_section (bfd_get_section (sym)) || bfd_is_com_section (bfd_get_section (sym))); } diff --git a/bfd/linker.c b/bfd/linker.c index 86a7a1945ba..233fc8c9d21 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -1444,6 +1444,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, struct bfd_link_hash_entry *h; struct bfd_link_hash_entry *inh = NULL; bfd_boolean cycle; + unsigned int secondary; BFD_ASSERT (section != NULL); @@ -1508,15 +1509,53 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, return FALSE; } + /* Since secondary symbols have lower precedence than weak symbols, + we treat them as weak symbols here. */ + secondary = (flags & BSF_SECONDARY) != 0; + if (secondary) + switch (row) + { + default: + break; + + case UNDEF_ROW: + row = UNDEFW_ROW; + break; + + case DEF_ROW: + row = DEFW_ROW; + break; + } + if (hashp != NULL) *hashp = h; do { enum link_action action; + enum bfd_link_hash_type type; + + type = h->type; + /* Convert a secondary symbol to a weak symbol. Backend is + responsible to let a weak symbol override a secondary + symbol. */ + if (h->secondary) + switch (type) + { + default: + break; + + case bfd_link_hash_undefined: + type = bfd_link_hash_undefweak; + break; + + case bfd_link_hash_defined: + type = bfd_link_hash_defweak; + break; + } cycle = FALSE; - action = link_action[(int) row][(int) h->type]; + action = link_action[(int) row][(int) type]; switch (action) { case FAIL: @@ -1562,6 +1601,9 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, h->u.def.value = value; h->linker_def = 0; + /* Mark if this is a secondary symbol. */ + h->secondary = secondary; + /* If we have been asked to, we act like collect2 and identify all functions that might be global constructors and destructors and pass them up in a diff --git a/bfd/syms.c b/bfd/syms.c index 9d7a1f43c13..a514efb5ded 100644 --- a/bfd/syms.c +++ b/bfd/syms.c @@ -306,6 +306,10 @@ CODE_FRAGMENT . with this name and type in use. BSF_OBJECT must also be set. *} .#define BSF_GNU_UNIQUE (1 << 23) . +. {* A secondary global symbol, overridable without warnings by +. a regular or weak global symbol of the same name. *} +.#define BSF_SECONDARY (1 << 24) +. . flagword flags; . . {* A pointer to the section to which this symbol is @@ -489,6 +493,7 @@ bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol) ((type & BSF_LOCAL) ? (type & BSF_GLOBAL) ? '!' : 'l' : (type & BSF_GLOBAL) ? 'g' + : (type & BSF_SECONDARY) ? 's' : (type & BSF_GNU_UNIQUE) ? 'u' : ' '), (type & BSF_WEAK) ? 'w' : ' ', (type & BSF_CONSTRUCTOR) ? 'C' : ' ', @@ -692,6 +697,15 @@ bfd_decode_symclass (asymbol *symbol) } if (symbol->flags & BSF_GNU_UNIQUE) return 'u'; + if (symbol->flags & BSF_SECONDARY) + { + /* If secondary, determine if it's specifically an object + or non-object weak. */ + if (symbol->flags & BSF_OBJECT) + return 'Y'; + else + return 'S'; + } if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) return '?'; |