aboutsummaryrefslogtreecommitdiff
path: root/ld/plugin.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-08-12 10:43:33 +0930
committerAlan Modra <amodra@gmail.com>2014-08-12 20:47:36 +0930
commit4613510308cea27713e8c7424b2afee9b99f6226 (patch)
tree50a2534571a7e765830e335172d4f2fdfd6ff4fc /ld/plugin.c
parent88d3f0870bdcb030d1b9f56f48e389860ff41918 (diff)
downloadbinutils-4613510308cea27713e8c7424b2afee9b99f6226.zip
binutils-4613510308cea27713e8c7424b2afee9b99f6226.tar.gz
binutils-4613510308cea27713e8c7424b2afee9b99f6226.tar.bz2
Change ld "notice" interface for better handling of indirect symbols
The main aim of this change was to have non_ir_ref set correctly on new indirect symbols. I could have added a "copy" param to the "notice" function, so that indirect symbols could be created in plugin_notice, but it seemed cleaner to create indirect syms earlier and pass them rather than "string" to "notice". include/ * bfdlink.h (struct bfd_link_callbacks <notice>): Remove "string" param, add "inh". bfd/ * coff-aux.c (coff_m68k_aux_link_add_one_symbol): Only call "notice" here when not calling the generic add_symbol function. Formatting. Correct handling of indirect symbols. Update notice call. * elflink.c (_bfd_elf_notice_as_needed): Update notice call. * linker.c (_bfd_generic_link_add_one_symbol): Create indirect symbols early. Update notice call. Add comments regarding weak symbols vs. indirect. ld/ * ldmain.c (notice): Update args. * plugin.c (plugin_notice): Likewise. Follow warning sym link. Handle new indirect symbol.
Diffstat (limited to 'ld/plugin.c')
-rw-r--r--ld/plugin.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/ld/plugin.c b/ld/plugin.c
index 8d6ae05..8cca7d0 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -127,8 +127,9 @@ static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
/* Forward references. */
static bfd_boolean plugin_notice (struct bfd_link_info *,
- struct bfd_link_hash_entry *, bfd *,
- asection *, bfd_vma, flagword, const char *);
+ struct bfd_link_hash_entry *,
+ struct bfd_link_hash_entry *,
+ bfd *, asection *, bfd_vma, flagword);
#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
@@ -962,16 +963,21 @@ plugin_call_cleanup (void)
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,
- const char *string)
+ 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))
;
@@ -981,16 +987,15 @@ plugin_notice (struct bfd_link_info *info,
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)
{
- 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;
+ 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. */
@@ -1031,13 +1036,13 @@ plugin_notice (struct bfd_link_info *info,
}
/* Continue with cref/nocrossref/trace-sym processing. */
- if (h == NULL
+ if (orig_h == NULL
|| orig_notice_all
|| (info->notice_hash != NULL
- && bfd_hash_lookup (info->notice_hash, h->root.string,
+ && bfd_hash_lookup (info->notice_hash, orig_h->root.string,
FALSE, FALSE) != NULL))
- return (*orig_callbacks->notice) (info, h,
- abfd, section, value, flags, string);
+ return (*orig_callbacks->notice) (info, orig_h, inh,
+ abfd, section, value, flags);
return TRUE;
}