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