/* FUNCTION bfd_decode_symclass DESCRIPTION Return a character corresponding to the symbol class of @var{symbol}, or '?' for an unknown class. SYNOPSIS int bfd_decode_symclass (asymbol *symbol); */ int bfd_decode_symclass (asymbol *symbol) { char c; if (symbol->section && bfd_is_com_section (symbol->section)) return 'C'; if (bfd_is_und_section (symbol->section)) { if (symbol->flags & BSF_WEAK) { /* If weak, determine if it's specifically an object or non-object weak. */ if (symbol->flags & BSF_OBJECT) return 'v'; else return 'w'; } else return 'U'; } if (bfd_is_ind_section (symbol->section)) return 'I'; if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION) return 'i'; if (symbol->flags & BSF_WEAK) { /* If weak, determine if it's specifically an object or non-object weak. */ if (symbol->flags & BSF_OBJECT) return 'V'; else return 'W'; } if (symbol->flags & BSF_GNU_UNIQUE) return 'u'; if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) return '?'; if (bfd_is_abs_section (symbol->section)) c = 'a'; else if (symbol->section) { c = coff_section_type (symbol->section->name); if (c == '?') c = decode_section_type (symbol->section); } else return '?'; if (symbol->flags & BSF_GLOBAL) c = TOUPPER (c); return c; /* We don't have to handle these cases just yet, but we will soon: N_SETV: 'v'; N_SETA: 'l'; N_SETT: 'x'; N_SETD: 'z'; N_SETB: 's'; N_INDR: 'i'; */ }
/* To determine which symbols should be resolved LDPR_PREVAILING_DEF and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as the linker adds them to the linker hash table. Mark those referenced from a non-IR file with non_ir_ref. We have to notice_all symbols, because we won't necessarily know until later which ones will be contributed by IR files. */ static bfd_boolean plugin_notice (struct bfd_link_info *info, struct bfd_link_hash_entry *h, bfd *abfd, asection *section, bfd_vma value, flagword flags, const char *string) { if (h != NULL) { bfd *sym_bfd; /* No further processing if this def/ref is from an IR dummy BFD. */ if (is_ir_dummy_bfd (abfd)) return TRUE; /* Making an indirect symbol counts as a reference unless this is a brand new symbol. */ if (bfd_is_ind_section (section) || (flags & BSF_INDIRECT) != 0) { if (h->type != bfd_link_hash_new) { struct bfd_link_hash_entry *inh; h->non_ir_ref = TRUE; inh = bfd_wrapped_link_hash_lookup (abfd, info, string, FALSE, FALSE, FALSE); if (inh != NULL) inh->non_ir_ref = TRUE; } } /* Nothing to do here for warning symbols. */ else if ((flags & BSF_WARNING) != 0) ; /* Nothing to do here for constructor symbols. */ else if ((flags & BSF_CONSTRUCTOR) != 0) ; /* If this is a ref, set non_ir_ref. */ else if (bfd_is_und_section (section)) h->non_ir_ref = TRUE; /* Otherwise, it must be a new def. Ensure any symbol defined in an IR dummy BFD takes on a new value from a real BFD. Weak symbols are not normally overridden by a new weak definition, and strong symbols will normally cause multiple definition errors. Avoid this by making the symbol appear to be undefined. */ else if (((h->type == bfd_link_hash_defweak || h->type == bfd_link_hash_defined) && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner)) || (h->type == bfd_link_hash_common && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner))) { h->type = bfd_link_hash_undefweak; h->u.undef.abfd = sym_bfd; } } /* Continue with cref/nocrossref/trace-sym processing. */ if (h == NULL || orig_notice_all || (info->notice_hash != NULL && bfd_hash_lookup (info->notice_hash, h->root.string, FALSE, FALSE) != NULL)) return (*orig_callbacks->notice) (info, h, abfd, section, value, flags, string); return TRUE; }
/* To determine which symbols should be resolved LDPR_PREVAILING_DEF and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as the linker adds them to the linker hash table. Mark those referenced from a non-IR file with non_ir_ref. We have to notice_all symbols, because we won't necessarily know until later which ones will be contributed by IR files. */ static bfd_boolean plugin_notice (struct bfd_link_info *info, struct bfd_link_hash_entry *h, struct bfd_link_hash_entry *inh, bfd *abfd, asection *section, bfd_vma value, flagword flags) { struct bfd_link_hash_entry *orig_h = h; if (h != NULL) { bfd *sym_bfd; if (h->type == bfd_link_hash_warning) h = h->u.i.link; /* Nothing to do here if this def/ref is from an IR dummy BFD. */ if (is_ir_dummy_bfd (abfd)) ; /* Making an indirect symbol counts as a reference unless this is a brand new symbol. */ else if (bfd_is_ind_section (section) || (flags & BSF_INDIRECT) != 0) { /* ??? Some of this is questionable. See comments in _bfd_generic_link_add_one_symbol for case IND. */ if (h->type != bfd_link_hash_new) { h->non_ir_ref = TRUE; inh->non_ir_ref = TRUE; } else if (inh->type == bfd_link_hash_new) inh->non_ir_ref = TRUE; } /* Nothing to do here for warning symbols. */ else if ((flags & BSF_WARNING) != 0) ; /* Nothing to do here for constructor symbols. */ else if ((flags & BSF_CONSTRUCTOR) != 0) ; /* If this is a ref, set non_ir_ref. */ else if (bfd_is_und_section (section)) { /* Replace the undefined dummy bfd with the real one. */ if ((h->type == bfd_link_hash_undefined || h->type == bfd_link_hash_undefweak) && (h->u.undef.abfd == NULL || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0)) h->u.undef.abfd = abfd; h->non_ir_ref = TRUE; } /* Otherwise, it must be a new def. */ else { /* A common symbol should be merged with other commons or defs with the same name. In particular, a common ought to be overridden by a def in a -flto object. In that sense a common is also a ref. */ if (bfd_is_com_section (section)) h->non_ir_ref = TRUE; /* Ensure any symbol defined in an IR dummy BFD takes on a new value from a real BFD. Weak symbols are not normally overridden by a new weak definition, and strong symbols will normally cause multiple definition errors. Avoid this by making the symbol appear to be undefined. */ if (((h->type == bfd_link_hash_defweak || h->type == bfd_link_hash_defined) && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner)) || (h->type == bfd_link_hash_common && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner))) { h->type = bfd_link_hash_undefweak; h->u.undef.abfd = sym_bfd; } } } /* Continue with cref/nocrossref/trace-sym processing. */ if (orig_h == NULL || orig_notice_all || (info->notice_hash != NULL && bfd_hash_lookup (info->notice_hash, orig_h->root.string, FALSE, FALSE) != NULL)) return (*orig_callbacks->notice) (info, orig_h, inh, abfd, section, value, flags); return TRUE; }