]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/plugin.c
PR ld/12365
[thirdparty/binutils-gdb.git] / ld / plugin.c
CommitLineData
5d3236ee 1/* Plugin control for the GNU linker.
e922bcab 2 Copyright 2010, 2011 Free Software Foundation, Inc.
5d3236ee
DK
3
4 This file is part of the GNU Binutils.
5
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.
10
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.
15
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. */
20
21#include "sysdep.h"
22#include "libiberty.h"
23#include "bfd.h"
24#include "bfdlink.h"
25#include "bfdver.h"
26#include "ld.h"
27#include "ldmain.h"
28#include "ldmisc.h"
29#include "ldexp.h"
30#include "ldlang.h"
31#include "ldfile.h"
32#include "plugin.h"
33#include "plugin-api.h"
34#include "elf-bfd.h"
3917d5d5 35#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
f31d24a0 36#include <windows.h>
3917d5d5 37#endif
5d3236ee 38
1715a13c
L
39/* Report plugin symbols. */
40bfd_boolean report_plugin_symbols;
41
5d3236ee
DK
42/* The suffix to append to the name of the real (claimed) object file
43 when generating a dummy BFD to hold the IR symbols sent from the
cf4dc96f
DK
44 plugin. For cosmetic use only; appears in maps, crefs etc. */
45#define IRONLY_SUFFIX " (symbol from plugin)"
5d3236ee
DK
46
47/* Stores a single argument passed to a plugin. */
48typedef struct plugin_arg
49{
50 struct plugin_arg *next;
51 const char *arg;
52} plugin_arg_t;
53
54/* Holds all details of a single plugin. */
55typedef struct plugin
56{
57 /* Next on the list of plugins, or NULL at end of chain. */
58 struct plugin *next;
59 /* The argument string given to --plugin. */
60 const char *name;
61 /* The shared library handle returned by dlopen. */
62 void *dlhandle;
63 /* The list of argument string given to --plugin-opt. */
64 plugin_arg_t *args;
65 /* Number of args in the list, for convenience. */
66 size_t n_args;
67 /* The plugin's event handlers. */
68 ld_plugin_claim_file_handler claim_file_handler;
69 ld_plugin_all_symbols_read_handler all_symbols_read_handler;
70 ld_plugin_cleanup_handler cleanup_handler;
71 /* TRUE if the cleanup handlers have been called. */
72 bfd_boolean cleanup_done;
73} plugin_t;
74
75/* The master list of all plugins. */
76static plugin_t *plugins_list = NULL;
77
78/* We keep a tail pointer for easy linking on the end. */
79static plugin_t **plugins_tail_chain_ptr = &plugins_list;
80
81/* The last plugin added to the list, for receiving args. */
82static plugin_t *last_plugin = NULL;
83
84/* The tail of the arg chain of the last plugin added to the list. */
85static plugin_arg_t **last_plugin_args_tail_chain_ptr = NULL;
86
87/* The plugin which is currently having a callback executed. */
88static plugin_t *called_plugin = NULL;
89
90/* Last plugin to cause an error, if any. */
91static const char *error_plugin = NULL;
92
93/* A hash table that records symbols referenced by non-IR files. Used
94 at get_symbols time to determine whether any prevailing defs from
95 IR files are referenced only from other IR files, so tthat we can
96 we can distinguish the LDPR_PREVAILING_DEF and LDPR_PREVAILING_DEF_IRONLY
97 cases when establishing symbol resolutions. */
98static struct bfd_hash_table *non_ironly_hash = NULL;
99
24f58f47 100/* State of linker "notice" interface before we poked at it. */
9e2278f5 101static bfd_boolean orig_notice_all;
9e2278f5
AM
102
103/* Original linker callbacks, and the plugin version. */
104static const struct bfd_link_callbacks *orig_callbacks;
105static struct bfd_link_callbacks plugin_callbacks;
106
5d3236ee
DK
107/* Set at all symbols read time, to avoid recursively offering the plugin
108 its own newly-added input files and libs to claim. */
9e2278f5 109bfd_boolean no_more_claiming = FALSE;
5d3236ee
DK
110
111/* List of tags to set in the constant leading part of the tv array. */
112static const enum ld_plugin_tag tv_header_tags[] =
113{
114 LDPT_MESSAGE,
115 LDPT_API_VERSION,
116 LDPT_GNU_LD_VERSION,
117 LDPT_LINKER_OUTPUT,
118 LDPT_OUTPUT_NAME,
119 LDPT_REGISTER_CLAIM_FILE_HOOK,
120 LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
121 LDPT_REGISTER_CLEANUP_HOOK,
122 LDPT_ADD_SYMBOLS,
123 LDPT_GET_INPUT_FILE,
124 LDPT_RELEASE_INPUT_FILE,
125 LDPT_GET_SYMBOLS,
126 LDPT_ADD_INPUT_FILE,
127 LDPT_ADD_INPUT_LIBRARY,
128 LDPT_SET_EXTRA_LIBRARY_PATH
129};
130
131/* How many entries in the constant leading part of the tv array. */
132static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
133
9e2278f5
AM
134/* Forward references. */
135static bfd_boolean plugin_notice (struct bfd_link_info *info,
136 const char *name, bfd *abfd,
137 asection *section, bfd_vma value);
138static bfd_boolean plugin_multiple_definition (struct bfd_link_info *info,
24f58f47
AM
139 struct bfd_link_hash_entry *h,
140 bfd *nbfd,
9e2278f5
AM
141 asection *nsec,
142 bfd_vma nval);
143
3917d5d5
DK
144#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
145
146#define RTLD_NOW 0 /* Dummy value. */
147
148static void *
149dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
150{
151 return LoadLibrary (file);
152}
153
154static void *
155dlsym (void *handle, const char *name)
156{
157 return GetProcAddress (handle, name);
158}
159
160static int
161dlclose (void *handle)
162{
163 FreeLibrary (handle);
164 return 0;
165}
166
167#endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */
168
5d3236ee
DK
169/* Helper function for exiting with error status. */
170static int
171set_plugin_error (const char *plugin)
172{
173 error_plugin = plugin;
174 return -1;
175}
176
177/* Test if an error occurred. */
178static bfd_boolean
179plugin_error_p (void)
180{
181 return error_plugin != NULL;
182}
183
184/* Return name of plugin which caused an error if any. */
d44ad554
DK
185const char *
186plugin_error_plugin (void)
5d3236ee
DK
187{
188 return error_plugin ? error_plugin : _("<no plugin>");
189}
190
191/* Handle -plugin arg: find and load plugin, or return error. */
d44ad554
DK
192int
193plugin_opt_plugin (const char *plugin)
5d3236ee
DK
194{
195 plugin_t *newplug;
196
197 newplug = xmalloc (sizeof *newplug);
198 memset (newplug, 0, sizeof *newplug);
199 newplug->name = plugin;
200 newplug->dlhandle = dlopen (plugin, RTLD_NOW);
201 if (!newplug->dlhandle)
202 return set_plugin_error (plugin);
203
204 /* Chain on end, so when we run list it is in command-line order. */
205 *plugins_tail_chain_ptr = newplug;
206 plugins_tail_chain_ptr = &newplug->next;
207
208 /* Record it as current plugin for receiving args. */
209 last_plugin = newplug;
210 last_plugin_args_tail_chain_ptr = &newplug->args;
211 return 0;
212}
213
214/* Accumulate option arguments for last-loaded plugin, or return
215 error if none. */
d44ad554
DK
216int
217plugin_opt_plugin_arg (const char *arg)
5d3236ee
DK
218{
219 plugin_arg_t *newarg;
220
221 if (!last_plugin)
222 return set_plugin_error (_("<no plugin>"));
223
224 newarg = xmalloc (sizeof *newarg);
225 newarg->arg = arg;
226 newarg->next = NULL;
227
228 /* Chain on end to preserve command-line order. */
229 *last_plugin_args_tail_chain_ptr = newarg;
230 last_plugin_args_tail_chain_ptr = &newarg->next;
231 last_plugin->n_args++;
232 return 0;
233}
234
235/* Create a dummy BFD. */
236bfd *
237plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
238{
bc110b6e
AM
239 bfd *abfd;
240
241 bfd_use_reserved_id = 1;
9e2278f5 242 abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *) NULL),
bc110b6e 243 srctemplate);
9e2278f5
AM
244 if (abfd != NULL)
245 {
246 abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN;
247 bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
248 bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate));
249 if (bfd_make_writable (abfd)
250 && bfd_copy_private_bfd_data (srctemplate, abfd))
251 {
252 flagword flags;
253
254 /* Create sections to own the symbols. */
255 flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
256 | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE);
257 if (bfd_make_section_anyway_with_flags (abfd, ".text", flags))
258 return abfd;
259 }
260 }
261 einfo (_("could not create dummy IR bfd: %F%E\n"));
262 return NULL;
5d3236ee
DK
263}
264
d44ad554
DK
265/* Check if the BFD passed in is an IR dummy object file. */
266static bfd_boolean
5d3236ee
DK
267is_ir_dummy_bfd (const bfd *abfd)
268{
cf4dc96f
DK
269 /* ABFD can sometimes legitimately be NULL, e.g. when called from one
270 of the linker callbacks for a symbol in the *ABS* or *UND* sections.
271 Likewise, the usrdata field may be NULL if ABFD was added by the
272 backend without a corresponding input statement, as happens e.g.
273 when processing DT_NEEDED dependencies. */
9e2278f5
AM
274 return (abfd
275 && abfd->usrdata
276 && ((lang_input_statement_type *)(abfd->usrdata))->claimed);
5d3236ee
DK
277}
278
279/* Helpers to convert between BFD and GOLD symbol formats. */
280static enum ld_plugin_status
281asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
f84854b6 282 const struct ld_plugin_symbol *ldsym)
5d3236ee
DK
283{
284 flagword flags = BSF_NO_FLAGS;
285 struct bfd_section *section;
286
287 asym->the_bfd = abfd;
f84854b6 288 asym->name = (ldsym->version
9e2278f5 289 ? concat (ldsym->name, "@", ldsym->version, (const char *) NULL)
f84854b6 290 : ldsym->name);
5d3236ee
DK
291 asym->value = 0;
292 switch (ldsym->def)
293 {
294 case LDPK_WEAKDEF:
295 flags = BSF_WEAK;
296 /* FALLTHRU */
297 case LDPK_DEF:
298 flags |= BSF_GLOBAL;
299 section = bfd_get_section_by_name (abfd, ".text");
300 break;
301
302 case LDPK_WEAKUNDEF:
303 flags = BSF_WEAK;
304 /* FALLTHRU */
305 case LDPK_UNDEF:
306 section = bfd_und_section_ptr;
307 break;
308
309 case LDPK_COMMON:
310 flags = BSF_GLOBAL;
311 section = bfd_com_section_ptr;
312 asym->value = ldsym->size;
5c08b7d4
L
313 /* For ELF targets, set alignment of common symbol to 1. */
314 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
315 ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
5d3236ee
DK
316 break;
317
318 default:
319 return LDPS_ERR;
320 }
321 asym->flags = flags;
322 asym->section = section;
323
324 /* Visibility only applies on ELF targets. */
325 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
326 {
327 elf_symbol_type *elfsym = elf_symbol_from (abfd, asym);
cfac8028
L
328 unsigned char visibility;
329
5d3236ee 330 if (!elfsym)
ea360572 331 einfo (_("%P%F: %s: non-ELF symbol in ELF BFD!\n"), asym->name);
cfac8028
L
332 switch (ldsym->visibility)
333 {
334 default:
ea360572 335 einfo (_("%P%F: unknown ELF symbol visibility: %d!\n"),
cfac8028
L
336 ldsym->visibility);
337 case LDPV_DEFAULT:
338 visibility = STV_DEFAULT;
339 break;
340 case LDPV_PROTECTED:
341 visibility = STV_PROTECTED;
342 break;
343 case LDPV_INTERNAL:
344 visibility = STV_INTERNAL;
345 break;
346 case LDPV_HIDDEN:
347 visibility = STV_HIDDEN;
348 break;
349 }
350 elfsym->internal_elf_sym.st_other
351 = (visibility | (elfsym->internal_elf_sym.st_other
352 & ~ELF_ST_VISIBILITY (-1)));
5d3236ee
DK
353 }
354
355 return LDPS_OK;
356}
357
358/* Register a claim-file handler. */
359static enum ld_plugin_status
360register_claim_file (ld_plugin_claim_file_handler handler)
361{
362 ASSERT (called_plugin);
363 called_plugin->claim_file_handler = handler;
364 return LDPS_OK;
365}
366
367/* Register an all-symbols-read handler. */
368static enum ld_plugin_status
369register_all_symbols_read (ld_plugin_all_symbols_read_handler handler)
370{
371 ASSERT (called_plugin);
372 called_plugin->all_symbols_read_handler = handler;
373 return LDPS_OK;
374}
375
376/* Register a cleanup handler. */
377static enum ld_plugin_status
378register_cleanup (ld_plugin_cleanup_handler handler)
379{
380 ASSERT (called_plugin);
381 called_plugin->cleanup_handler = handler;
382 return LDPS_OK;
383}
384
385/* Add symbols from a plugin-claimed input file. */
386static enum ld_plugin_status
387add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
388{
389 asymbol **symptrs;
390 bfd *abfd = handle;
391 int n;
392 ASSERT (called_plugin);
393 symptrs = xmalloc (nsyms * sizeof *symptrs);
394 for (n = 0; n < nsyms; n++)
395 {
396 enum ld_plugin_status rv;
397 asymbol *bfdsym = bfd_make_empty_symbol (abfd);
398 symptrs[n] = bfdsym;
399 rv = asymbol_from_plugin_symbol (abfd, bfdsym, syms + n);
400 if (rv != LDPS_OK)
401 return rv;
402 }
403 bfd_set_symtab (abfd, symptrs, nsyms);
404 return LDPS_OK;
405}
406
407/* Get the input file information with an open (possibly re-opened)
408 file descriptor. */
409static enum ld_plugin_status
410get_input_file (const void *handle, struct ld_plugin_input_file *file)
411{
412 ASSERT (called_plugin);
413 handle = handle;
414 file = file;
415 return LDPS_ERR;
416}
417
418/* Release the input file. */
419static enum ld_plugin_status
420release_input_file (const void *handle)
421{
422 ASSERT (called_plugin);
423 handle = handle;
424 return LDPS_ERR;
425}
426
42a851a9
DK
427/* Return TRUE if a defined symbol might be reachable from outside the
428 universe of claimed objects. */
429static inline bfd_boolean
430is_visible_from_outside (struct ld_plugin_symbol *lsym, asection *section,
f84854b6 431 struct bfd_link_hash_entry *blhe)
42a851a9
DK
432{
433 /* Section's owner may be NULL if it is the absolute
434 section, fortunately is_ir_dummy_bfd handles that. */
435 if (!is_ir_dummy_bfd (section->owner))
436 return TRUE;
437 if (link_info.relocatable)
438 return TRUE;
439 if (link_info.export_dynamic || link_info.shared)
440 {
441 /* Only ELF symbols really have visibility. */
442 if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
443 {
444 struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe;
445 int vis = ELF_ST_VISIBILITY (el->other);
446 return vis == STV_DEFAULT || vis == STV_PROTECTED;
447 }
448 /* On non-ELF targets, we can safely make inferences by considering
f84854b6 449 what visibility the plugin would have liked to apply when it first
42a851a9
DK
450 sent us the symbol. During ELF symbol processing, visibility only
451 ever becomes more restrictive, not less, when symbols are merged,
452 so this is a conservative estimate; it may give false positives,
453 declaring something visible from outside when it in fact would
454 not have been, but this will only lead to missed optimisation
455 opportunities during LTRANS at worst; it will not give false
456 negatives, which can lead to the disastrous conclusion that the
457 related symbol is IRONLY. (See GCC PR46319 for an example.) */
cfac8028
L
458 return (lsym->visibility == LDPV_DEFAULT
459 || lsym->visibility == LDPV_PROTECTED);
42a851a9
DK
460 }
461 return FALSE;
462}
463
5d3236ee
DK
464/* Get the symbol resolution info for a plugin-claimed input file. */
465static enum ld_plugin_status
466get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
467{
468 const bfd *abfd = handle;
469 int n;
470 ASSERT (called_plugin);
471 for (n = 0; n < nsyms; n++)
472 {
473 struct bfd_link_hash_entry *blhe;
474 bfd_boolean ironly;
42a851a9 475 asection *owner_sec;
10be1b6a
DK
476 if (syms[n].def != LDPK_UNDEF)
477 blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
478 FALSE, FALSE, TRUE);
479 else
480 blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
481 syms[n].name, FALSE, FALSE, TRUE);
5d3236ee
DK
482 if (!blhe)
483 {
484 syms[n].resolution = LDPR_UNKNOWN;
1715a13c 485 goto report_symbol;
5d3236ee
DK
486 }
487
488 /* Determine resolution from blhe type and symbol's original type. */
489 if (blhe->type == bfd_link_hash_undefined
f84854b6 490 || blhe->type == bfd_link_hash_undefweak)
5d3236ee
DK
491 {
492 syms[n].resolution = LDPR_UNDEF;
1715a13c 493 goto report_symbol;
5d3236ee
DK
494 }
495 if (blhe->type != bfd_link_hash_defined
f84854b6
L
496 && blhe->type != bfd_link_hash_defweak
497 && blhe->type != bfd_link_hash_common)
5d3236ee
DK
498 {
499 /* We should not have a new, indirect or warning symbol here. */
ea360572 500 einfo ("%P%F: %s: plugin symbol table corrupt (sym type %d)\n",
f84854b6 501 called_plugin->name, blhe->type);
5d3236ee
DK
502 }
503
42a851a9
DK
504 /* Find out which section owns the symbol. Since it's not undef,
505 it must have an owner; if it's not a common symbol, both defs
506 and weakdefs keep it in the same place. */
9e2278f5
AM
507 owner_sec = (blhe->type == bfd_link_hash_common
508 ? blhe->u.c.p->section
509 : blhe->u.def.section);
42a851a9
DK
510
511 /* We need to know if the sym is referenced from non-IR files. Or
f84854b6 512 even potentially-referenced, perhaps in a future final link if
42a851a9
DK
513 this is a partial one, perhaps dynamically at load-time if the
514 symbol is externally visible. */
8ff09c12
L
515 ironly = (!is_visible_from_outside (&syms[n], owner_sec, blhe)
516 && !bfd_hash_lookup (non_ironly_hash, syms[n].name,
174b85fc 517 FALSE, FALSE));
5d3236ee
DK
518
519 /* If it was originally undefined or common, then it has been
f84854b6
L
520 resolved; determine how. */
521 if (syms[n].def == LDPK_UNDEF
522 || syms[n].def == LDPK_WEAKUNDEF
5d3236ee
DK
523 || syms[n].def == LDPK_COMMON)
524 {
5d3236ee
DK
525 if (owner_sec->owner == link_info.output_bfd)
526 syms[n].resolution = LDPR_RESOLVED_EXEC;
527 else if (owner_sec->owner == abfd)
f84854b6
L
528 syms[n].resolution = (ironly
529 ? LDPR_PREVAILING_DEF_IRONLY
530 : LDPR_PREVAILING_DEF);
5d3236ee
DK
531 else if (is_ir_dummy_bfd (owner_sec->owner))
532 syms[n].resolution = LDPR_RESOLVED_IR;
cc322803
L
533 else if (owner_sec->owner != NULL
534 && (owner_sec->owner->flags & DYNAMIC) != 0)
5d3236ee
DK
535 syms[n].resolution = LDPR_RESOLVED_DYN;
536 else
537 syms[n].resolution = LDPR_RESOLVED_EXEC;
1715a13c 538 goto report_symbol;
5d3236ee
DK
539 }
540
541 /* Was originally def, or weakdef. Does it prevail? If the
f84854b6 542 owner is the original dummy bfd that supplied it, then this
5d3236ee 543 is the definition that has prevailed. */
42a851a9 544 if (owner_sec->owner == link_info.output_bfd)
5d3236ee 545 syms[n].resolution = LDPR_PREEMPTED_REG;
42a851a9 546 else if (owner_sec->owner == abfd)
5d3236ee 547 {
f84854b6 548 syms[n].resolution = (ironly
5d3236ee 549 ? LDPR_PREVAILING_DEF_IRONLY
f84854b6 550 : LDPR_PREVAILING_DEF);
1715a13c 551 goto report_symbol;
5d3236ee
DK
552 }
553
554 /* Was originally def, weakdef, or common, but has been pre-empted. */
1715a13c
L
555 syms[n].resolution = (is_ir_dummy_bfd (owner_sec->owner)
556 ? LDPR_PREEMPTED_IR
557 : LDPR_PREEMPTED_REG);
558
9e2278f5 559 report_symbol:
1715a13c 560 if (report_plugin_symbols)
9e2278f5
AM
561 einfo (_("%P: %B: symbol `%s' "
562 "definition: %d, visibility: %d, resolution: %d\n"),
563 abfd, syms[n].name,
564 syms[n].def, syms[n].visibility, syms[n].resolution);
5d3236ee
DK
565 }
566 return LDPS_OK;
567}
568
569/* Add a new (real) input file generated by a plugin. */
570static enum ld_plugin_status
571add_input_file (const char *pathname)
572{
573 ASSERT (called_plugin);
d4cb7acd 574 if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_file_enum,
f84854b6 575 NULL))
5d3236ee
DK
576 return LDPS_ERR;
577 return LDPS_OK;
578}
579
580/* Add a new (real) library required by a plugin. */
581static enum ld_plugin_status
582add_input_library (const char *pathname)
583{
584 ASSERT (called_plugin);
d4cb7acd 585 if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_l_enum,
f84854b6 586 NULL))
5d3236ee
DK
587 return LDPS_ERR;
588 return LDPS_OK;
589}
590
591/* Set the extra library path to be used by libraries added via
592 add_input_library. */
593static enum ld_plugin_status
594set_extra_library_path (const char *path)
595{
596 ASSERT (called_plugin);
d4cb7acd 597 ldfile_add_library_path (xstrdup (path), FALSE);
5d3236ee
DK
598 return LDPS_OK;
599}
600
601/* Issue a diagnostic message from a plugin. */
602static enum ld_plugin_status
603message (int level, const char *format, ...)
604{
605 va_list args;
606 va_start (args, format);
607
608 switch (level)
609 {
610 case LDPL_INFO:
611 vfinfo (stdout, format, args, FALSE);
d251c5c4 612 putchar ('\n');
5d3236ee
DK
613 break;
614 case LDPL_WARNING:
615 vfinfo (stdout, format, args, TRUE);
d251c5c4 616 putchar ('\n');
5d3236ee
DK
617 break;
618 case LDPL_FATAL:
619 case LDPL_ERROR:
620 default:
9e2278f5
AM
621 {
622 char *newfmt = ACONCAT ((level == LDPL_FATAL ? "%P%F: " : "%P%X: ",
623 format, "\n", (const char *) NULL));
624 fflush (stdout);
625 vfinfo (stderr, newfmt, args, TRUE);
626 fflush (stderr);
627 }
5d3236ee
DK
628 break;
629 }
630
631 va_end (args);
632 return LDPS_OK;
633}
634
635/* Helper to size leading part of tv array and set it up. */
636static size_t
637set_tv_header (struct ld_plugin_tv *tv)
638{
639 size_t i;
640
641 /* Version info. */
642 static const unsigned int major = (unsigned)(BFD_VERSION / 100000000UL);
643 static const unsigned int minor = (unsigned)(BFD_VERSION / 1000000UL) % 100;
644
645 if (!tv)
646 return tv_header_size;
647
648 for (i = 0; i < tv_header_size; i++)
649 {
650 tv[i].tv_tag = tv_header_tags[i];
651#define TVU(x) tv[i].tv_u.tv_ ## x
652 switch (tv[i].tv_tag)
653 {
f84854b6
L
654 case LDPT_MESSAGE:
655 TVU(message) = message;
656 break;
657 case LDPT_API_VERSION:
658 TVU(val) = LD_PLUGIN_API_VERSION;
659 break;
660 case LDPT_GNU_LD_VERSION:
661 TVU(val) = major * 100 + minor;
662 break;
663 case LDPT_LINKER_OUTPUT:
664 TVU(val) = (link_info.relocatable
665 ? LDPO_REL
666 : (link_info.shared ? LDPO_DYN : LDPO_EXEC));
667 break;
668 case LDPT_OUTPUT_NAME:
669 TVU(string) = output_filename;
670 break;
671 case LDPT_REGISTER_CLAIM_FILE_HOOK:
672 TVU(register_claim_file) = register_claim_file;
673 break;
674 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
675 TVU(register_all_symbols_read) = register_all_symbols_read;
676 break;
677 case LDPT_REGISTER_CLEANUP_HOOK:
678 TVU(register_cleanup) = register_cleanup;
679 break;
680 case LDPT_ADD_SYMBOLS:
681 TVU(add_symbols) = add_symbols;
682 break;
683 case LDPT_GET_INPUT_FILE:
684 TVU(get_input_file) = get_input_file;
685 break;
686 case LDPT_RELEASE_INPUT_FILE:
687 TVU(release_input_file) = release_input_file;
688 break;
689 case LDPT_GET_SYMBOLS:
690 TVU(get_symbols) = get_symbols;
691 break;
692 case LDPT_ADD_INPUT_FILE:
693 TVU(add_input_file) = add_input_file;
694 break;
695 case LDPT_ADD_INPUT_LIBRARY:
696 TVU(add_input_library) = add_input_library;
697 break;
698 case LDPT_SET_EXTRA_LIBRARY_PATH:
699 TVU(set_extra_library_path) = set_extra_library_path;
700 break;
701 default:
702 /* Added a new entry to the array without adding
703 a new case to set up its value is a bug. */
704 FAIL ();
5d3236ee
DK
705 }
706#undef TVU
707 }
708 return tv_header_size;
709}
710
711/* Append the per-plugin args list and trailing LDPT_NULL to tv. */
712static void
713set_tv_plugin_args (plugin_t *plugin, struct ld_plugin_tv *tv)
714{
715 plugin_arg_t *arg = plugin->args;
716 while (arg)
717 {
718 tv->tv_tag = LDPT_OPTION;
719 tv->tv_u.tv_string = arg->arg;
720 arg = arg->next;
721 tv++;
722 }
723 tv->tv_tag = LDPT_NULL;
724 tv->tv_u.tv_val = 0;
725}
726
d44ad554
DK
727/* Return true if any plugins are active this run. Only valid
728 after options have been processed. */
729bfd_boolean
730plugin_active_plugins_p (void)
731{
732 return plugins_list != NULL;
733}
734
9e2278f5
AM
735/* Init the non_ironly hash table. */
736static void
737init_non_ironly_hash (void)
738{
739 struct bfd_sym_chain *sym;
740
741 non_ironly_hash
742 = (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table));
743 if (!bfd_hash_table_init_n (non_ironly_hash,
744 bfd_hash_newfunc,
745 sizeof (struct bfd_hash_entry),
746 61))
747 einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
748
749 for (sym = &entry_symbol; sym != NULL; sym = sym->next)
750 if (sym->name
751 && !bfd_hash_lookup (non_ironly_hash, sym->name, TRUE, TRUE))
752 einfo (_("%P%X: hash table failure adding symbol %s\n"),
753 sym->name);
754}
755
5d3236ee 756/* Load up and initialise all plugins after argument parsing. */
d44ad554
DK
757int
758plugin_load_plugins (void)
5d3236ee
DK
759{
760 struct ld_plugin_tv *my_tv;
761 unsigned int max_args = 0;
762 plugin_t *curplug = plugins_list;
763
764 /* If there are no plugins, we need do nothing this run. */
765 if (!curplug)
766 return 0;
767
768 /* First pass over plugins to find max # args needed so that we
769 can size and allocate the tv array. */
770 while (curplug)
771 {
772 if (curplug->n_args > max_args)
773 max_args = curplug->n_args;
774 curplug = curplug->next;
775 }
776
777 /* Allocate tv array and initialise constant part. */
778 my_tv = xmalloc ((max_args + 1 + tv_header_size) * sizeof *my_tv);
779 set_tv_header (my_tv);
780
781 /* Pass over plugins again, activating them. */
782 curplug = plugins_list;
783 while (curplug)
784 {
785 enum ld_plugin_status rv;
786 ld_plugin_onload onloadfn = dlsym (curplug->dlhandle, "onload");
787 if (!onloadfn)
788 onloadfn = dlsym (curplug->dlhandle, "_onload");
789 if (!onloadfn)
f84854b6 790 return set_plugin_error (curplug->name);
5d3236ee
DK
791 set_tv_plugin_args (curplug, &my_tv[tv_header_size]);
792 called_plugin = curplug;
793 rv = (*onloadfn) (my_tv);
794 called_plugin = NULL;
795 if (rv != LDPS_OK)
f84854b6 796 return set_plugin_error (curplug->name);
5d3236ee
DK
797 curplug = curplug->next;
798 }
799
800 /* Since plugin(s) inited ok, assume they're going to want symbol
801 resolutions, which needs us to track which symbols are referenced
802 by non-IR files using the linker's notice callback. */
9e2278f5
AM
803 orig_notice_all = link_info.notice_all;
804 orig_callbacks = link_info.callbacks;
805 plugin_callbacks = *orig_callbacks;
806 plugin_callbacks.notice = &plugin_notice;
5d3236ee 807 link_info.notice_all = TRUE;
9e2278f5
AM
808 link_info.callbacks = &plugin_callbacks;
809 init_non_ironly_hash ();
5d3236ee
DK
810
811 return 0;
812}
813
814/* Call 'claim file' hook for all plugins. */
815int
816plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
817{
818 plugin_t *curplug = plugins_list;
819 *claimed = FALSE;
820 if (no_more_claiming)
821 return 0;
822 while (curplug && !*claimed)
823 {
824 if (curplug->claim_file_handler)
825 {
826 enum ld_plugin_status rv;
827 called_plugin = curplug;
828 rv = (*curplug->claim_file_handler) (file, claimed);
829 called_plugin = NULL;
830 if (rv != LDPS_OK)
831 set_plugin_error (curplug->name);
832 }
833 curplug = curplug->next;
834 }
835 return plugin_error_p () ? -1 : 0;
836}
837
838/* Call 'all symbols read' hook for all plugins. */
839int
840plugin_call_all_symbols_read (void)
841{
842 plugin_t *curplug = plugins_list;
843
844 /* Disable any further file-claiming. */
845 no_more_claiming = TRUE;
846
9e2278f5 847 plugin_callbacks.multiple_definition = &plugin_multiple_definition;
5d3236ee
DK
848
849 while (curplug)
850 {
851 if (curplug->all_symbols_read_handler)
852 {
853 enum ld_plugin_status rv;
854 called_plugin = curplug;
855 rv = (*curplug->all_symbols_read_handler) ();
856 called_plugin = NULL;
857 if (rv != LDPS_OK)
858 set_plugin_error (curplug->name);
859 }
860 curplug = curplug->next;
861 }
862 return plugin_error_p () ? -1 : 0;
863}
864
e73d965c 865/* Call 'cleanup' hook for all plugins at exit. */
498cd2a0 866void
5d3236ee
DK
867plugin_call_cleanup (void)
868{
869 plugin_t *curplug = plugins_list;
870 while (curplug)
871 {
872 if (curplug->cleanup_handler && !curplug->cleanup_done)
873 {
874 enum ld_plugin_status rv;
875 curplug->cleanup_done = TRUE;
876 called_plugin = curplug;
877 rv = (*curplug->cleanup_handler) ();
878 called_plugin = NULL;
879 if (rv != LDPS_OK)
880 set_plugin_error (curplug->name);
881 dlclose (curplug->dlhandle);
882 }
883 curplug = curplug->next;
884 }
e73d965c
L
885 if (plugin_error_p ())
886 info_msg (_("%P: %s: error in plugin cleanup (ignored)\n"),
887 plugin_error_plugin ());
5d3236ee
DK
888}
889
5d3236ee
DK
890/* To determine which symbols should be resolved LDPR_PREVAILING_DEF
891 and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
892 the linker adds them to the linker hash table. If we see a symbol
893 being referenced from a non-IR file, we add it to the non_ironly hash
894 table. If we can't find it there at get_symbols time, we know that
895 it was referenced only by IR files. We have to notice_all symbols,
896 because we won't necessarily know until later which ones will be
897 contributed by IR files. */
9e2278f5
AM
898static bfd_boolean
899plugin_notice (struct bfd_link_info *info,
900 const char *name,
901 bfd *abfd,
902 asection *section,
903 bfd_vma value)
5d3236ee 904{
9e2278f5 905 if (name != NULL)
5d3236ee 906 {
9e2278f5
AM
907 /* No further processing if this def/ref is from an IR dummy BFD. */
908 if (is_ir_dummy_bfd (abfd))
909 return TRUE;
910
911 /* We only care about refs, not defs, indicated by section
912 pointing to the undefined section (according to the bfd
913 linker notice callback interface definition). */
914 if (bfd_is_und_section (section))
915 {
916 /* This is a ref from a non-IR file, so note the ref'd
917 symbol in the non-IR-only hash. */
918 if (!bfd_hash_lookup (non_ironly_hash, name, TRUE, TRUE))
919 einfo (_("%P%X: %s: hash table failure adding symbol %s\n"),
920 abfd->filename, name);
921 }
5d3236ee
DK
922 }
923
924 /* Continue with cref/nocrossref/trace-sym processing. */
9e2278f5
AM
925 if (name == NULL
926 || orig_notice_all
927 || (info->notice_hash != NULL
928 && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
929 return (*orig_callbacks->notice) (info, name, abfd, section, value);
5d3236ee
DK
930 return TRUE;
931}
932
933/* When we add new object files to the link at all symbols read time,
934 these contain the real code and symbols generated from the IR files,
935 and so duplicate all the definitions already supplied by the dummy
936 IR-only BFDs that we created at claim files time. We use the linker's
937 multiple-definitions callback hook to fix up the clash, discarding
938 the symbol from the IR-only BFD in favour of the symbol from the
939 real BFD. We return true if this was not-really-a-clash because
940 we've fixed it up, or anyway if --allow-multiple-definition was in
941 effect (before we disabled it to ensure we got called back). */
9e2278f5 942static bfd_boolean
24f58f47
AM
943plugin_multiple_definition (struct bfd_link_info *info,
944 struct bfd_link_hash_entry *h,
f84854b6 945 bfd *nbfd, asection *nsec, bfd_vma nval)
5d3236ee 946{
24f58f47
AM
947 if (h->type == bfd_link_hash_defined
948 && is_ir_dummy_bfd (h->u.def.section->owner))
5d3236ee 949 {
5d3236ee 950 /* Replace it with new details. */
24f58f47
AM
951 h->u.def.section = nsec;
952 h->u.def.value = nval;
5d3236ee
DK
953 return TRUE;
954 }
9e2278f5 955
24f58f47 956 return (*orig_callbacks->multiple_definition) (info, h, nbfd, nsec, nval);
5d3236ee 957}