1 /* Plugin control for the GNU linker.
2 Copyright 2010 Free Software Foundation, Inc.
4 This file is part of the GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
22 #include "libiberty.h"
33 #include "plugin-api.h"
36 /* The suffix to append to the name of the real (claimed) object file
37 when generating a dummy BFD to hold the IR symbols sent from the
39 #define IRONLY_SUFFIX ".ironly\004"
41 /* This is sizeof an array of chars, not sizeof a const char *. We
42 also have to avoid inadvertently counting the trailing NUL. */
43 #define IRONLY_SUFFIX_LEN (sizeof (IRONLY_SUFFIX) - 1)
45 /* Stores a single argument passed to a plugin. */
46 typedef struct plugin_arg
48 struct plugin_arg
*next
;
52 /* Holds all details of a single plugin. */
55 /* Next on the list of plugins, or NULL at end of chain. */
57 /* The argument string given to --plugin. */
59 /* The shared library handle returned by dlopen. */
61 /* The list of argument string given to --plugin-opt. */
63 /* Number of args in the list, for convenience. */
65 /* The plugin's event handlers. */
66 ld_plugin_claim_file_handler claim_file_handler
;
67 ld_plugin_all_symbols_read_handler all_symbols_read_handler
;
68 ld_plugin_cleanup_handler cleanup_handler
;
69 /* TRUE if the cleanup handlers have been called. */
70 bfd_boolean cleanup_done
;
73 /* The master list of all plugins. */
74 static plugin_t
*plugins_list
= NULL
;
76 /* We keep a tail pointer for easy linking on the end. */
77 static plugin_t
**plugins_tail_chain_ptr
= &plugins_list
;
79 /* The last plugin added to the list, for receiving args. */
80 static plugin_t
*last_plugin
= NULL
;
82 /* The tail of the arg chain of the last plugin added to the list. */
83 static plugin_arg_t
**last_plugin_args_tail_chain_ptr
= NULL
;
85 /* The plugin which is currently having a callback executed. */
86 static plugin_t
*called_plugin
= NULL
;
88 /* Last plugin to cause an error, if any. */
89 static const char *error_plugin
= NULL
;
91 /* A hash table that records symbols referenced by non-IR files. Used
92 at get_symbols time to determine whether any prevailing defs from
93 IR files are referenced only from other IR files, so tthat we can
94 we can distinguish the LDPR_PREVAILING_DEF and LDPR_PREVAILING_DEF_IRONLY
95 cases when establishing symbol resolutions. */
96 static struct bfd_hash_table
*non_ironly_hash
= NULL
;
98 /* Set at all symbols read time, to avoid recursively offering the plugin
99 its own newly-added input files and libs to claim. */
100 static bfd_boolean no_more_claiming
= FALSE
;
102 /* If the --allow-multiple-definition command-line option is active, we
103 have to disable it so that BFD always calls our hook, and simulate the
104 effect (when not resolving IR vs. real symbols) ourselves by ensuring
105 TRUE is returned from the hook. */
106 static bfd_boolean plugin_cached_allow_multiple_defs
= FALSE
;
108 /* List of tags to set in the constant leading part of the tv array. */
109 static const enum ld_plugin_tag tv_header_tags
[] =
116 LDPT_REGISTER_CLAIM_FILE_HOOK
,
117 LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
,
118 LDPT_REGISTER_CLEANUP_HOOK
,
121 LDPT_RELEASE_INPUT_FILE
,
124 LDPT_ADD_INPUT_LIBRARY
,
125 LDPT_SET_EXTRA_LIBRARY_PATH
128 /* How many entries in the constant leading part of the tv array. */
129 static const size_t tv_header_size
= ARRAY_SIZE (tv_header_tags
);
131 /* Helper function for exiting with error status. */
133 set_plugin_error (const char *plugin
)
135 error_plugin
= plugin
;
139 /* Test if an error occurred. */
141 plugin_error_p (void)
143 return error_plugin
!= NULL
;
146 /* Return name of plugin which caused an error if any. */
147 const char *plugin_error_plugin (void)
149 return error_plugin
? error_plugin
: _("<no plugin>");
152 /* Handle -plugin arg: find and load plugin, or return error. */
153 int plugin_opt_plugin (const char *plugin
)
157 newplug
= xmalloc (sizeof *newplug
);
158 memset (newplug
, 0, sizeof *newplug
);
159 newplug
->name
= plugin
;
160 newplug
->dlhandle
= dlopen (plugin
, RTLD_NOW
);
161 if (!newplug
->dlhandle
)
162 return set_plugin_error (plugin
);
164 /* Chain on end, so when we run list it is in command-line order. */
165 *plugins_tail_chain_ptr
= newplug
;
166 plugins_tail_chain_ptr
= &newplug
->next
;
168 /* Record it as current plugin for receiving args. */
169 last_plugin
= newplug
;
170 last_plugin_args_tail_chain_ptr
= &newplug
->args
;
174 /* Accumulate option arguments for last-loaded plugin, or return
176 int plugin_opt_plugin_arg (const char *arg
)
178 plugin_arg_t
*newarg
;
181 return set_plugin_error (_("<no plugin>"));
183 newarg
= xmalloc (sizeof *newarg
);
187 /* Chain on end to preserve command-line order. */
188 *last_plugin_args_tail_chain_ptr
= newarg
;
189 last_plugin_args_tail_chain_ptr
= &newarg
->next
;
190 last_plugin
->n_args
++;
194 /* Create a dummy BFD. */
196 plugin_get_ir_dummy_bfd (const char *name
, bfd
*srctemplate
)
199 bfd
*abfd
= bfd_create (
200 concat (name
, IRONLY_SUFFIX
, (const char *)NULL
),
202 bfd_set_arch_info (abfd
, bfd_get_arch_info (srctemplate
));
203 bfd_make_writable (abfd
);
204 /* Create a minimal set of sections to own the symbols. */
205 sec
= bfd_make_section_old_way (abfd
, ".text");
206 bfd_set_section_flags (abfd
, sec
,
207 SEC_CODE
| SEC_HAS_CONTENTS
| SEC_READONLY
208 | SEC_ALLOC
| SEC_LOAD
| SEC_KEEP
);
209 sec
->output_section
= sec
;
210 sec
->output_offset
= 0;
214 /* Check if the BFD is an IR dummy. */
216 is_ir_dummy_bfd (const bfd
*abfd
)
218 size_t namlen
= strlen (abfd
->filename
);
219 if (namlen
< IRONLY_SUFFIX_LEN
)
221 return !strcmp (abfd
->filename
+ namlen
- IRONLY_SUFFIX_LEN
, IRONLY_SUFFIX
);
224 /* Helpers to convert between BFD and GOLD symbol formats. */
225 static enum ld_plugin_status
226 asymbol_from_plugin_symbol (bfd
*abfd
, asymbol
*asym
,
227 const struct ld_plugin_symbol
*ldsym
)
229 flagword flags
= BSF_NO_FLAGS
;
230 struct bfd_section
*section
;
232 asym
->the_bfd
= abfd
;
233 asym
->name
= ldsym
->version
234 ? concat (ldsym
->name
, "@", ldsym
->version
, NULL
)
244 section
= bfd_get_section_by_name (abfd
, ".text");
251 section
= bfd_und_section_ptr
;
256 section
= bfd_com_section_ptr
;
257 asym
->value
= ldsym
->size
;
264 asym
->section
= section
;
266 /* Visibility only applies on ELF targets. */
267 if (bfd_get_flavour (abfd
) == bfd_target_elf_flavour
)
269 elf_symbol_type
*elfsym
= elf_symbol_from (abfd
, asym
);
271 einfo (_("%P%F: %s: non-ELF symbol in ELF BFD!"), asym
->name
);
272 elfsym
->internal_elf_sym
.st_other
&= ~3;
273 elfsym
->internal_elf_sym
.st_other
|= ldsym
->visibility
;
279 /* Register a claim-file handler. */
280 static enum ld_plugin_status
281 register_claim_file (ld_plugin_claim_file_handler handler
)
283 ASSERT (called_plugin
);
284 called_plugin
->claim_file_handler
= handler
;
288 /* Register an all-symbols-read handler. */
289 static enum ld_plugin_status
290 register_all_symbols_read (ld_plugin_all_symbols_read_handler handler
)
292 ASSERT (called_plugin
);
293 called_plugin
->all_symbols_read_handler
= handler
;
297 /* Register a cleanup handler. */
298 static enum ld_plugin_status
299 register_cleanup (ld_plugin_cleanup_handler handler
)
301 ASSERT (called_plugin
);
302 called_plugin
->cleanup_handler
= handler
;
306 /* Add symbols from a plugin-claimed input file. */
307 static enum ld_plugin_status
308 add_symbols (void *handle
, int nsyms
, const struct ld_plugin_symbol
*syms
)
313 ASSERT (called_plugin
);
314 symptrs
= xmalloc (nsyms
* sizeof *symptrs
);
315 for (n
= 0; n
< nsyms
; n
++)
317 enum ld_plugin_status rv
;
318 asymbol
*bfdsym
= bfd_make_empty_symbol (abfd
);
320 rv
= asymbol_from_plugin_symbol (abfd
, bfdsym
, syms
+ n
);
324 bfd_set_symtab (abfd
, symptrs
, nsyms
);
328 /* Get the input file information with an open (possibly re-opened)
330 static enum ld_plugin_status
331 get_input_file (const void *handle
, struct ld_plugin_input_file
*file
)
333 ASSERT (called_plugin
);
339 /* Release the input file. */
340 static enum ld_plugin_status
341 release_input_file (const void *handle
)
343 ASSERT (called_plugin
);
348 /* Get the symbol resolution info for a plugin-claimed input file. */
349 static enum ld_plugin_status
350 get_symbols (const void *handle
, int nsyms
, struct ld_plugin_symbol
*syms
)
352 const bfd
*abfd
= handle
;
354 ASSERT (called_plugin
);
355 for (n
= 0; n
< nsyms
; n
++)
357 struct bfd_link_hash_entry
*blhe
;
360 blhe
= bfd_link_hash_lookup (link_info
.hash
, syms
[n
].name
,
364 syms
[n
].resolution
= LDPR_UNKNOWN
;
368 /* Determine resolution from blhe type and symbol's original type. */
369 if (blhe
->type
== bfd_link_hash_undefined
370 || blhe
->type
== bfd_link_hash_undefweak
)
372 syms
[n
].resolution
= LDPR_UNDEF
;
375 if (blhe
->type
!= bfd_link_hash_defined
376 && blhe
->type
!= bfd_link_hash_defweak
377 && blhe
->type
!= bfd_link_hash_common
)
379 /* We should not have a new, indirect or warning symbol here. */
380 einfo ("%P%F: %s: plugin symbol table corrupt (sym type %d)",
381 called_plugin
->name
, blhe
->type
);
384 /* We need to know if the sym is referenced from non-IR files. */
385 ironly
= !bfd_hash_lookup (non_ironly_hash
, syms
[n
].name
, FALSE
, FALSE
);
387 /* If it was originally undefined or common, then it has been
388 resolved; determine how. */
389 if (syms
[n
].def
== LDPK_UNDEF
|| syms
[n
].def
== LDPK_WEAKUNDEF
390 || syms
[n
].def
== LDPK_COMMON
)
392 asection
*owner_sec
= (syms
[n
].def
== LDPK_COMMON
)
393 ? blhe
->u
.c
.p
->section
394 : blhe
->u
.def
.section
;
395 if (owner_sec
->owner
== link_info
.output_bfd
)
396 syms
[n
].resolution
= LDPR_RESOLVED_EXEC
;
397 else if (owner_sec
->owner
== abfd
)
398 syms
[n
].resolution
= (ironly
)
399 ? LDPR_PREVAILING_DEF_IRONLY
400 : LDPR_PREVAILING_DEF
;
401 else if (is_ir_dummy_bfd (owner_sec
->owner
))
402 syms
[n
].resolution
= LDPR_RESOLVED_IR
;
403 else if (owner_sec
->owner
->flags
& DYNAMIC
)
404 syms
[n
].resolution
= LDPR_RESOLVED_DYN
;
406 syms
[n
].resolution
= LDPR_RESOLVED_EXEC
;
410 /* Was originally def, or weakdef. Does it prevail? If the
411 owner is the original dummy bfd that supplied it, then this
412 is the definition that has prevailed. */
413 if (blhe
->u
.def
.section
->owner
== link_info
.output_bfd
)
414 syms
[n
].resolution
= LDPR_PREEMPTED_REG
;
415 else if (blhe
->u
.def
.section
->owner
== abfd
)
417 syms
[n
].resolution
= (ironly
)
418 ? LDPR_PREVAILING_DEF_IRONLY
419 : LDPR_PREVAILING_DEF
;
423 /* Was originally def, weakdef, or common, but has been pre-empted. */
424 syms
[n
].resolution
= is_ir_dummy_bfd (blhe
->u
.def
.section
->owner
)
426 : LDPR_PREEMPTED_REG
;
431 /* Add a new (real) input file generated by a plugin. */
432 static enum ld_plugin_status
433 add_input_file (const char *pathname
)
435 ASSERT (called_plugin
);
436 if (!lang_add_input_file (xstrdup (pathname
), lang_input_file_is_file_enum
,
442 /* Add a new (real) library required by a plugin. */
443 static enum ld_plugin_status
444 add_input_library (const char *pathname
)
446 ASSERT (called_plugin
);
447 if (!lang_add_input_file (xstrdup (pathname
), lang_input_file_is_l_enum
,
453 /* Set the extra library path to be used by libraries added via
454 add_input_library. */
455 static enum ld_plugin_status
456 set_extra_library_path (const char *path
)
458 ASSERT (called_plugin
);
459 ldfile_add_library_path (xstrdup (path
), FALSE
);
463 /* Issue a diagnostic message from a plugin. */
464 static enum ld_plugin_status
465 message (int level
, const char *format
, ...)
468 va_start (args
, format
);
473 vfinfo (stdout
, format
, args
, FALSE
);
476 vfinfo (stdout
, format
, args
, TRUE
);
482 char *newfmt
= ACONCAT ((level
== LDPL_FATAL
? "%F" : "%X",
484 vfinfo (stderr
, newfmt
, args
, TRUE
);
493 /* Helper to size leading part of tv array and set it up. */
495 set_tv_header (struct ld_plugin_tv
*tv
)
500 static const unsigned int major
= (unsigned)(BFD_VERSION
/ 100000000UL);
501 static const unsigned int minor
= (unsigned)(BFD_VERSION
/ 1000000UL) % 100;
504 return tv_header_size
;
506 for (i
= 0; i
< tv_header_size
; i
++)
508 tv
[i
].tv_tag
= tv_header_tags
[i
];
509 #define TVU(x) tv[i].tv_u.tv_ ## x
510 switch (tv
[i
].tv_tag
)
513 TVU(message
) = message
;
515 case LDPT_API_VERSION
:
516 TVU(val
) = LD_PLUGIN_API_VERSION
;
518 case LDPT_GNU_LD_VERSION
:
519 TVU(val
) = major
* 100 + minor
;
521 case LDPT_LINKER_OUTPUT
:
522 TVU(val
) = link_info
.relocatable
? LDPO_REL
523 : (link_info
.shared
? LDPO_DYN
: LDPO_EXEC
);
525 case LDPT_OUTPUT_NAME
:
526 TVU(string
) = output_filename
;
528 case LDPT_REGISTER_CLAIM_FILE_HOOK
:
529 TVU(register_claim_file
) = register_claim_file
;
531 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
:
532 TVU(register_all_symbols_read
) = register_all_symbols_read
;
534 case LDPT_REGISTER_CLEANUP_HOOK
:
535 TVU(register_cleanup
) = register_cleanup
;
537 case LDPT_ADD_SYMBOLS
:
538 TVU(add_symbols
) = add_symbols
;
540 case LDPT_GET_INPUT_FILE
:
541 TVU(get_input_file
) = get_input_file
;
543 case LDPT_RELEASE_INPUT_FILE
:
544 TVU(release_input_file
) = release_input_file
;
546 case LDPT_GET_SYMBOLS
:
547 TVU(get_symbols
) = get_symbols
;
549 case LDPT_ADD_INPUT_FILE
:
550 TVU(add_input_file
) = add_input_file
;
552 case LDPT_ADD_INPUT_LIBRARY
:
553 TVU(add_input_library
) = add_input_library
;
555 case LDPT_SET_EXTRA_LIBRARY_PATH
:
556 TVU(set_extra_library_path
) = set_extra_library_path
;
559 /* Added a new entry to the array without adding
560 a new case to set up its value is a bug. */
565 return tv_header_size
;
568 /* Append the per-plugin args list and trailing LDPT_NULL to tv. */
570 set_tv_plugin_args (plugin_t
*plugin
, struct ld_plugin_tv
*tv
)
572 plugin_arg_t
*arg
= plugin
->args
;
575 tv
->tv_tag
= LDPT_OPTION
;
576 tv
->tv_u
.tv_string
= arg
->arg
;
580 tv
->tv_tag
= LDPT_NULL
;
584 /* Load up and initialise all plugins after argument parsing. */
585 int plugin_load_plugins (void)
587 struct ld_plugin_tv
*my_tv
;
588 unsigned int max_args
= 0;
589 plugin_t
*curplug
= plugins_list
;
591 /* If there are no plugins, we need do nothing this run. */
595 /* First pass over plugins to find max # args needed so that we
596 can size and allocate the tv array. */
599 if (curplug
->n_args
> max_args
)
600 max_args
= curplug
->n_args
;
601 curplug
= curplug
->next
;
604 /* Allocate tv array and initialise constant part. */
605 my_tv
= xmalloc ((max_args
+ 1 + tv_header_size
) * sizeof *my_tv
);
606 set_tv_header (my_tv
);
608 /* Pass over plugins again, activating them. */
609 curplug
= plugins_list
;
612 enum ld_plugin_status rv
;
613 ld_plugin_onload onloadfn
= dlsym (curplug
->dlhandle
, "onload");
615 onloadfn
= dlsym (curplug
->dlhandle
, "_onload");
617 return set_plugin_error (curplug
->name
);
618 set_tv_plugin_args (curplug
, &my_tv
[tv_header_size
]);
619 called_plugin
= curplug
;
620 rv
= (*onloadfn
) (my_tv
);
621 called_plugin
= NULL
;
623 return set_plugin_error (curplug
->name
);
624 curplug
= curplug
->next
;
627 /* Since plugin(s) inited ok, assume they're going to want symbol
628 resolutions, which needs us to track which symbols are referenced
629 by non-IR files using the linker's notice callback. */
630 link_info
.notice_all
= TRUE
;
635 /* Call 'claim file' hook for all plugins. */
637 plugin_call_claim_file (const struct ld_plugin_input_file
*file
, int *claimed
)
639 plugin_t
*curplug
= plugins_list
;
641 if (no_more_claiming
)
643 while (curplug
&& !*claimed
)
645 if (curplug
->claim_file_handler
)
647 enum ld_plugin_status rv
;
648 called_plugin
= curplug
;
649 rv
= (*curplug
->claim_file_handler
) (file
, claimed
);
650 called_plugin
= NULL
;
652 set_plugin_error (curplug
->name
);
654 curplug
= curplug
->next
;
656 return plugin_error_p () ? -1 : 0;
659 /* Call 'all symbols read' hook for all plugins. */
661 plugin_call_all_symbols_read (void)
663 plugin_t
*curplug
= plugins_list
;
665 /* Disable any further file-claiming. */
666 no_more_claiming
= TRUE
;
668 /* If --allow-multiple-definition is in effect, we need to disable it,
669 as the plugin infrastructure relies on the multiple_definition
670 callback to swap out the dummy IR-only BFDs for new real ones
671 when it starts opening the files added during this callback. */
672 plugin_cached_allow_multiple_defs
= link_info
.allow_multiple_definition
;
673 link_info
.allow_multiple_definition
= FALSE
;
677 if (curplug
->all_symbols_read_handler
)
679 enum ld_plugin_status rv
;
680 called_plugin
= curplug
;
681 rv
= (*curplug
->all_symbols_read_handler
) ();
682 called_plugin
= NULL
;
684 set_plugin_error (curplug
->name
);
686 curplug
= curplug
->next
;
688 return plugin_error_p () ? -1 : 0;
691 /* Call 'cleanup' hook for all plugins. */
693 plugin_call_cleanup (void)
695 plugin_t
*curplug
= plugins_list
;
698 if (curplug
->cleanup_handler
&& !curplug
->cleanup_done
)
700 enum ld_plugin_status rv
;
701 curplug
->cleanup_done
= TRUE
;
702 called_plugin
= curplug
;
703 rv
= (*curplug
->cleanup_handler
) ();
704 called_plugin
= NULL
;
706 set_plugin_error (curplug
->name
);
707 dlclose (curplug
->dlhandle
);
709 curplug
= curplug
->next
;
711 return plugin_error_p () ? -1 : 0;
714 /* Lazily init the non_ironly hash table. */
716 init_non_ironly_hash (void)
718 if (non_ironly_hash
== NULL
)
721 (struct bfd_hash_table
*) xmalloc (sizeof (struct bfd_hash_table
));
722 if (!bfd_hash_table_init_n (non_ironly_hash
,
724 sizeof (struct bfd_hash_entry
),
726 einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
730 /* To determine which symbols should be resolved LDPR_PREVAILING_DEF
731 and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
732 the linker adds them to the linker hash table. If we see a symbol
733 being referenced from a non-IR file, we add it to the non_ironly hash
734 table. If we can't find it there at get_symbols time, we know that
735 it was referenced only by IR files. We have to notice_all symbols,
736 because we won't necessarily know until later which ones will be
737 contributed by IR files. */
739 plugin_notice (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
740 const char *name
, bfd
*abfd
,
741 asection
*section
, bfd_vma value ATTRIBUTE_UNUSED
)
743 bfd_boolean is_ref
= bfd_is_und_section (section
);
744 bfd_boolean is_dummy
= is_ir_dummy_bfd (abfd
);
745 init_non_ironly_hash ();
746 /* We only care about refs, not defs, indicated by section pointing
747 to the undefined section (according to the bfd linker notice callback
748 interface definition). */
749 if (is_ref
&& !is_dummy
)
751 /* This is a ref from a non-IR file, so note the ref'd symbol
752 in the non-IR-only hash. */
753 if (!bfd_hash_lookup (non_ironly_hash
, name
, TRUE
, TRUE
))
754 einfo (_("%P%X: %s: hash table failure adding symbol %s"),
755 abfd
->filename
, name
);
757 else if (!is_ref
&& is_dummy
)
759 /* No further processing since this is a def from an IR dummy BFD. */
763 /* Continue with cref/nocrossref/trace-sym processing. */
767 /* When we add new object files to the link at all symbols read time,
768 these contain the real code and symbols generated from the IR files,
769 and so duplicate all the definitions already supplied by the dummy
770 IR-only BFDs that we created at claim files time. We use the linker's
771 multiple-definitions callback hook to fix up the clash, discarding
772 the symbol from the IR-only BFD in favour of the symbol from the
773 real BFD. We return true if this was not-really-a-clash because
774 we've fixed it up, or anyway if --allow-multiple-definition was in
775 effect (before we disabled it to ensure we got called back). */
777 plugin_multiple_definition (struct bfd_link_info
*info
, const char *name
,
778 bfd
*obfd
, asection
*osec ATTRIBUTE_UNUSED
,
779 bfd_vma oval ATTRIBUTE_UNUSED
,
780 bfd
*nbfd
, asection
*nsec
, bfd_vma nval
)
782 if (is_ir_dummy_bfd (obfd
))
784 struct bfd_link_hash_entry
*blhe
= bfd_link_hash_lookup (info
->hash
,
785 name
, FALSE
, FALSE
, FALSE
);
787 einfo (_("%P%X: %s: can't find IR symbol '%s'"), nbfd
->filename
,
789 else if (blhe
->type
!= bfd_link_hash_defined
)
790 einfo (_("%P%x: %s: bad IR symbol type %d"), name
, blhe
->type
);
791 /* Replace it with new details. */
792 blhe
->u
.def
.section
= nsec
;
793 blhe
->u
.def
.value
= nval
;
796 return plugin_cached_allow_multiple_defs
;