/* Plugin control for the GNU linker.
- Copyright 2010 Free Software Foundation, Inc.
+ Copyright 2010, 2011 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
TRUE is returned from the hook. */
static bfd_boolean plugin_cached_allow_multiple_defs = FALSE;
+/* Call 'cleanup' hook for all plugins at exit. */
+static void plugin_call_cleanup (void);
+
/* List of tags to set in the constant leading part of the tv array. */
static const enum ld_plugin_tag tv_header_tags[] =
{
srctemplate);
bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
bfd_make_writable (abfd);
+ bfd_copy_private_bfd_data (srctemplate, abfd);
+ bfd_set_gp_size (abfd, bfd_get_gp_size (abfd));
/* Create a minimal set of sections to own the symbols. */
sec = bfd_make_section_old_way (abfd, ".text");
bfd_set_section_flags (abfd, sec,
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
{
elf_symbol_type *elfsym = elf_symbol_from (abfd, asym);
+ unsigned char visibility;
+
if (!elfsym)
- einfo (_("%P%F: %s: non-ELF symbol in ELF BFD!"), asym->name);
- elfsym->internal_elf_sym.st_other &= ~3;
- elfsym->internal_elf_sym.st_other |= ldsym->visibility;
+ einfo (_("%P%F: %s: non-ELF symbol in ELF BFD!\n"), asym->name);
+ switch (ldsym->visibility)
+ {
+ default:
+ einfo (_("%P%F: unknown ELF symbol visibility: %d!\n"),
+ ldsym->visibility);
+ case LDPV_DEFAULT:
+ visibility = STV_DEFAULT;
+ break;
+ case LDPV_PROTECTED:
+ visibility = STV_PROTECTED;
+ break;
+ case LDPV_INTERNAL:
+ visibility = STV_INTERNAL;
+ break;
+ case LDPV_HIDDEN:
+ visibility = STV_HIDDEN;
+ break;
+ }
+ elfsym->internal_elf_sym.st_other
+ = (visibility | (elfsym->internal_elf_sym.st_other
+ & ~ELF_ST_VISIBILITY (-1)));
}
return LDPS_OK;
opportunities during LTRANS at worst; it will not give false
negatives, which can lead to the disastrous conclusion that the
related symbol is IRONLY. (See GCC PR46319 for an example.) */
- return lsym->visibility == LDPV_DEFAULT
- || lsym->visibility == LDPV_PROTECTED;
+ return (lsym->visibility == LDPV_DEFAULT
+ || lsym->visibility == LDPV_PROTECTED);
}
return FALSE;
}
&& blhe->type != bfd_link_hash_common)
{
/* We should not have a new, indirect or warning symbol here. */
- einfo ("%P%F: %s: plugin symbol table corrupt (sym type %d)",
+ einfo ("%P%F: %s: plugin symbol table corrupt (sym type %d)\n",
called_plugin->name, blhe->type);
}
: LDPR_PREVAILING_DEF);
else if (is_ir_dummy_bfd (owner_sec->owner))
syms[n].resolution = LDPR_RESOLVED_IR;
- else if (owner_sec->owner->flags & DYNAMIC)
+ else if (owner_sec->owner != NULL
+ && (owner_sec->owner->flags & DYNAMIC) != 0)
syms[n].resolution = LDPR_RESOLVED_DYN;
else
syms[n].resolution = LDPR_RESOLVED_EXEC;
{
case LDPL_INFO:
vfinfo (stdout, format, args, FALSE);
+ putchar ('\n');
break;
case LDPL_WARNING:
vfinfo (stdout, format, args, TRUE);
+ putchar ('\n');
break;
case LDPL_FATAL:
case LDPL_ERROR:
default:
{
- char *newfmt = ACONCAT ((level == LDPL_FATAL ? "%F" : "%X",
- format, NULL));
+ char *newfmt = ACONCAT ((level == LDPL_FATAL
+ ? "%P%F: " : "%P%X: ",
+ format, "\n", NULL));
+ fflush (stdout);
vfinfo (stderr, newfmt, args, TRUE);
+ fflush (stderr);
}
break;
}
if (!curplug)
return 0;
+ xatexit (plugin_call_cleanup);
+
/* First pass over plugins to find max # args needed so that we
can size and allocate the tv array. */
while (curplug)
return plugin_error_p () ? -1 : 0;
}
-/* Call 'cleanup' hook for all plugins. */
-int
+/* Call 'cleanup' hook for all plugins at exit. */
+static void
plugin_call_cleanup (void)
{
plugin_t *curplug = plugins_list;
}
curplug = curplug->next;
}
- return plugin_error_p () ? -1 : 0;
+ if (plugin_error_p ())
+ info_msg (_("%P: %s: error in plugin cleanup (ignored)\n"),
+ plugin_error_plugin ());
}
/* Lazily init the non_ironly hash table. */
/* This is a ref from a non-IR file, so note the ref'd symbol
in the non-IR-only hash. */
if (!bfd_hash_lookup (non_ironly_hash, name, TRUE, TRUE))
- einfo (_("%P%X: %s: hash table failure adding symbol %s"),
+ einfo (_("%P%X: %s: hash table failure adding symbol %s\n"),
abfd->filename, name);
}
else if (!is_ref && is_dummy)
struct bfd_link_hash_entry *blhe
= bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
if (!blhe)
- einfo (_("%P%X: %s: can't find IR symbol '%s'"), nbfd->filename,
+ einfo (_("%P%X: %s: can't find IR symbol '%s'\n"), nbfd->filename,
name);
else if (blhe->type != bfd_link_hash_defined)
- einfo (_("%P%x: %s: bad IR symbol type %d"), name, blhe->type);
+ einfo (_("%P%x: %s: bad IR symbol type %d\n"), name, blhe->type);
/* Replace it with new details. */
blhe->u.def.section = nsec;
blhe->u.def.value = nval;