]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/plugin.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / ld / plugin.c
CommitLineData
5d3236ee 1/* Plugin control for the GNU linker.
250d07de 2 Copyright (C) 2010-2021 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"
0381901e 24#if BFD_SUPPORTS_PLUGINS
5d3236ee
DK
25#include "bfdlink.h"
26#include "bfdver.h"
1ff6de03 27#include "ctf-api.h"
5d3236ee
DK
28#include "ld.h"
29#include "ldmain.h"
30#include "ldmisc.h"
31#include "ldexp.h"
32#include "ldlang.h"
33#include "ldfile.h"
7d0b9ebc 34#include "plugin-api.h"
5ae0078c 35#include "../bfd/plugin.h"
5d3236ee 36#include "plugin.h"
5d3236ee 37#include "elf-bfd.h"
2aec968d
L
38#if HAVE_MMAP
39# include <sys/mman.h>
40# ifndef MAP_FAILED
41# define MAP_FAILED ((void *) -1)
42# endif
43# ifndef PROT_READ
44# define PROT_READ 0
45# endif
46# ifndef MAP_PRIVATE
47# define MAP_PRIVATE 0
48# endif
49#endif
f4b78d18
L
50#include <errno.h>
51#if !(defined(errno) || defined(_MSC_VER) && defined(_INC_ERRNO))
52extern int errno;
53#endif
3917d5d5 54#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
f31d24a0 55#include <windows.h>
3917d5d5 56#endif
5d3236ee 57
1715a13c
L
58/* Report plugin symbols. */
59bfd_boolean report_plugin_symbols;
60
5d3236ee
DK
61/* The suffix to append to the name of the real (claimed) object file
62 when generating a dummy BFD to hold the IR symbols sent from the
cf4dc96f
DK
63 plugin. For cosmetic use only; appears in maps, crefs etc. */
64#define IRONLY_SUFFIX " (symbol from plugin)"
5d3236ee
DK
65
66/* Stores a single argument passed to a plugin. */
67typedef struct plugin_arg
68{
69 struct plugin_arg *next;
70 const char *arg;
71} plugin_arg_t;
72
73/* Holds all details of a single plugin. */
74typedef struct plugin
75{
76 /* Next on the list of plugins, or NULL at end of chain. */
77 struct plugin *next;
78 /* The argument string given to --plugin. */
79 const char *name;
80 /* The shared library handle returned by dlopen. */
81 void *dlhandle;
82 /* The list of argument string given to --plugin-opt. */
83 plugin_arg_t *args;
84 /* Number of args in the list, for convenience. */
85 size_t n_args;
86 /* The plugin's event handlers. */
87 ld_plugin_claim_file_handler claim_file_handler;
88 ld_plugin_all_symbols_read_handler all_symbols_read_handler;
89 ld_plugin_cleanup_handler cleanup_handler;
90 /* TRUE if the cleanup handlers have been called. */
91 bfd_boolean cleanup_done;
92} plugin_t;
93
2aec968d
L
94typedef struct view_buffer
95{
96 char *addr;
97 size_t filesize;
98 off_t offset;
99} view_buffer_t;
100
f4b78d18
L
101/* The internal version of struct ld_plugin_input_file with a BFD
102 pointer. */
103typedef struct plugin_input_file
104{
105 bfd *abfd;
2aec968d 106 view_buffer_t view_buffer;
f4b78d18
L
107 char *name;
108 int fd;
38604796 109 bfd_boolean use_mmap;
f4b78d18
L
110 off_t offset;
111 off_t filesize;
112} plugin_input_file_t;
113
5d3236ee
DK
114/* The master list of all plugins. */
115static plugin_t *plugins_list = NULL;
116
117/* We keep a tail pointer for easy linking on the end. */
118static plugin_t **plugins_tail_chain_ptr = &plugins_list;
119
120/* The last plugin added to the list, for receiving args. */
121static plugin_t *last_plugin = NULL;
122
123/* The tail of the arg chain of the last plugin added to the list. */
124static plugin_arg_t **last_plugin_args_tail_chain_ptr = NULL;
125
126/* The plugin which is currently having a callback executed. */
127static plugin_t *called_plugin = NULL;
128
129/* Last plugin to cause an error, if any. */
130static const char *error_plugin = NULL;
131
24f58f47 132/* State of linker "notice" interface before we poked at it. */
9e2278f5 133static bfd_boolean orig_notice_all;
9e2278f5
AM
134
135/* Original linker callbacks, and the plugin version. */
136static const struct bfd_link_callbacks *orig_callbacks;
137static struct bfd_link_callbacks plugin_callbacks;
138
5d3236ee
DK
139/* Set at all symbols read time, to avoid recursively offering the plugin
140 its own newly-added input files and libs to claim. */
9e2278f5 141bfd_boolean no_more_claiming = FALSE;
5d3236ee 142
38604796
L
143#if HAVE_MMAP && HAVE_GETPAGESIZE
144/* Page size used by mmap. */
145static off_t plugin_pagesize;
146#endif
147
5d3236ee
DK
148/* List of tags to set in the constant leading part of the tv array. */
149static const enum ld_plugin_tag tv_header_tags[] =
150{
151 LDPT_MESSAGE,
152 LDPT_API_VERSION,
153 LDPT_GNU_LD_VERSION,
154 LDPT_LINKER_OUTPUT,
155 LDPT_OUTPUT_NAME,
156 LDPT_REGISTER_CLAIM_FILE_HOOK,
157 LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
158 LDPT_REGISTER_CLEANUP_HOOK,
159 LDPT_ADD_SYMBOLS,
160 LDPT_GET_INPUT_FILE,
15f7a26b 161 LDPT_GET_VIEW,
5d3236ee
DK
162 LDPT_RELEASE_INPUT_FILE,
163 LDPT_GET_SYMBOLS,
69ee6ab2 164 LDPT_GET_SYMBOLS_V2,
5d3236ee
DK
165 LDPT_ADD_INPUT_FILE,
166 LDPT_ADD_INPUT_LIBRARY,
167 LDPT_SET_EXTRA_LIBRARY_PATH
168};
169
170/* How many entries in the constant leading part of the tv array. */
171static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
172
9e2278f5 173/* Forward references. */
16d96b5b 174static bfd_boolean plugin_notice (struct bfd_link_info *,
46135103
AM
175 struct bfd_link_hash_entry *,
176 struct bfd_link_hash_entry *,
177 bfd *, asection *, bfd_vma, flagword);
9e2278f5 178
cb001c0d 179static bfd_cleanup plugin_object_p (bfd *);
5ae0078c 180
3917d5d5
DK
181#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
182
183#define RTLD_NOW 0 /* Dummy value. */
184
185static void *
186dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
187{
188 return LoadLibrary (file);
189}
190
191static void *
192dlsym (void *handle, const char *name)
193{
194 return GetProcAddress (handle, name);
195}
196
197static int
198dlclose (void *handle)
199{
200 FreeLibrary (handle);
201 return 0;
202}
203
204#endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */
205
d82184d7
L
206#ifndef HAVE_DLFCN_H
207static const char *
208dlerror (void)
209{
210 return "";
211}
212#endif
213
5d3236ee
DK
214/* Helper function for exiting with error status. */
215static int
216set_plugin_error (const char *plugin)
217{
218 error_plugin = plugin;
219 return -1;
220}
221
222/* Test if an error occurred. */
223static bfd_boolean
224plugin_error_p (void)
225{
226 return error_plugin != NULL;
227}
228
229/* Return name of plugin which caused an error if any. */
d44ad554
DK
230const char *
231plugin_error_plugin (void)
5d3236ee
DK
232{
233 return error_plugin ? error_plugin : _("<no plugin>");
234}
235
236/* Handle -plugin arg: find and load plugin, or return error. */
d82184d7 237void
d44ad554 238plugin_opt_plugin (const char *plugin)
5d3236ee
DK
239{
240 plugin_t *newplug;
c3e1c28e 241 plugin_t *curplug = plugins_list;
5d3236ee
DK
242
243 newplug = xmalloc (sizeof *newplug);
244 memset (newplug, 0, sizeof *newplug);
245 newplug->name = plugin;
246 newplug->dlhandle = dlopen (plugin, RTLD_NOW);
247 if (!newplug->dlhandle)
df5f2391 248 einfo (_("%F%P: %s: error loading plugin: %s\n"), plugin, dlerror ());
5d3236ee 249
c3e1c28e
L
250 /* Check if plugin has been loaded already. */
251 while (curplug)
252 {
253 if (newplug->dlhandle == curplug->dlhandle)
254 {
255 einfo (_("%P: %s: duplicated plugin\n"), plugin);
256 free (newplug);
257 return;
258 }
259 curplug = curplug->next;
260 }
261
5d3236ee
DK
262 /* Chain on end, so when we run list it is in command-line order. */
263 *plugins_tail_chain_ptr = newplug;
264 plugins_tail_chain_ptr = &newplug->next;
265
266 /* Record it as current plugin for receiving args. */
267 last_plugin = newplug;
268 last_plugin_args_tail_chain_ptr = &newplug->args;
5d3236ee
DK
269}
270
271/* Accumulate option arguments for last-loaded plugin, or return
272 error if none. */
d44ad554
DK
273int
274plugin_opt_plugin_arg (const char *arg)
5d3236ee
DK
275{
276 plugin_arg_t *newarg;
277
278 if (!last_plugin)
279 return set_plugin_error (_("<no plugin>"));
280
97964ab3
AM
281 /* Ignore -pass-through= from GCC driver. */
282 if (*arg == '-')
283 {
284 const char *p = arg + 1;
285
286 if (*p == '-')
287 ++p;
288 if (strncmp (p, "pass-through=", 13) == 0)
289 return 0;
290 }
291
5d3236ee
DK
292 newarg = xmalloc (sizeof *newarg);
293 newarg->arg = arg;
294 newarg->next = NULL;
295
296 /* Chain on end to preserve command-line order. */
297 *last_plugin_args_tail_chain_ptr = newarg;
298 last_plugin_args_tail_chain_ptr = &newarg->next;
299 last_plugin->n_args++;
300 return 0;
301}
302
37a3056a
L
303/* Generate a dummy BFD to represent an IR file, for any callers of
304 plugin_call_claim_file to use as the handle in the ld_plugin_input_file
305 struct that they build to pass in. The BFD is initially writable, so
306 that symbols can be added to it; it must be made readable after the
307 add_symbols hook has been called so that it can be read when linking. */
308static bfd *
5d3236ee
DK
309plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
310{
bc110b6e 311 bfd *abfd;
4a07dc81 312 bfd_boolean bfd_plugin_target;
bc110b6e
AM
313
314 bfd_use_reserved_id = 1;
4a07dc81 315 bfd_plugin_target = bfd_plugin_target_p (srctemplate->xvec);
9e2278f5 316 abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *) NULL),
4a07dc81 317 bfd_plugin_target ? link_info.output_bfd : srctemplate);
9e2278f5
AM
318 if (abfd != NULL)
319 {
320 abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN;
5ae0078c
L
321 if (!bfd_make_writable (abfd))
322 goto report_error;
4a07dc81 323 if (!bfd_plugin_target)
5ae0078c
L
324 {
325 bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
326 bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate));
327 if (!bfd_copy_private_bfd_data (srctemplate, abfd))
328 goto report_error;
329 }
9e2278f5
AM
330 {
331 flagword flags;
332
c77ec726 333 /* Create section to own the symbols. */
9e2278f5
AM
334 flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
335 | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE);
336 if (bfd_make_section_anyway_with_flags (abfd, ".text", flags))
337 return abfd;
338 }
339 }
dc1e8a47 340 report_error:
df5f2391 341 einfo (_("%F%P: could not create dummy IR bfd: %E\n"));
9e2278f5 342 return NULL;
5d3236ee
DK
343}
344
d44ad554 345/* Check if the BFD passed in is an IR dummy object file. */
23ebe1a0 346static inline bfd_boolean
5d3236ee
DK
347is_ir_dummy_bfd (const bfd *abfd)
348{
cf4dc96f 349 /* ABFD can sometimes legitimately be NULL, e.g. when called from one
23ebe1a0
AM
350 of the linker callbacks for a symbol in the *ABS* or *UND* sections. */
351 return abfd != NULL && (abfd->flags & BFD_PLUGIN) != 0;
5d3236ee
DK
352}
353
354/* Helpers to convert between BFD and GOLD symbol formats. */
355static enum ld_plugin_status
356asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
f84854b6 357 const struct ld_plugin_symbol *ldsym)
5d3236ee
DK
358{
359 flagword flags = BSF_NO_FLAGS;
360 struct bfd_section *section;
361
362 asym->the_bfd = abfd;
f84854b6 363 asym->name = (ldsym->version
9e2278f5 364 ? concat (ldsym->name, "@", ldsym->version, (const char *) NULL)
f84854b6 365 : ldsym->name);
5d3236ee
DK
366 asym->value = 0;
367 switch (ldsym->def)
368 {
369 case LDPK_WEAKDEF:
370 flags = BSF_WEAK;
371 /* FALLTHRU */
372 case LDPK_DEF:
373 flags |= BSF_GLOBAL;
c77ec726
AM
374 if (ldsym->comdat_key)
375 {
376 char *name = concat (".gnu.linkonce.t.", ldsym->comdat_key,
377 (const char *) NULL);
378 section = bfd_get_section_by_name (abfd, name);
379 if (section != NULL)
380 free (name);
381 else
382 {
383 flagword sflags;
384
385 sflags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
386 | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE
387 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD);
388 section = bfd_make_section_anyway_with_flags (abfd, name, sflags);
389 if (section == NULL)
390 return LDPS_ERR;
391 }
392 }
393 else
394 section = bfd_get_section_by_name (abfd, ".text");
5d3236ee
DK
395 break;
396
397 case LDPK_WEAKUNDEF:
398 flags = BSF_WEAK;
399 /* FALLTHRU */
400 case LDPK_UNDEF:
401 section = bfd_und_section_ptr;
402 break;
403
404 case LDPK_COMMON:
405 flags = BSF_GLOBAL;
406 section = bfd_com_section_ptr;
407 asym->value = ldsym->size;
408 break;
409
410 default:
411 return LDPS_ERR;
412 }
413 asym->flags = flags;
414 asym->section = section;
415
5d3236ee
DK
416 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
417 {
c1229f84 418 elf_symbol_type *elfsym = elf_symbol_from (asym);
cfac8028
L
419 unsigned char visibility;
420
5d3236ee 421 if (!elfsym)
df5f2391 422 einfo (_("%F%P: %s: non-ELF symbol in ELF BFD!\n"), asym->name);
0410b450
AM
423
424 if (ldsym->def == LDPK_COMMON)
425 {
426 elfsym->internal_elf_sym.st_shndx = SHN_COMMON;
427 elfsym->internal_elf_sym.st_value = 1;
428 }
429
cfac8028
L
430 switch (ldsym->visibility)
431 {
432 default:
df5f2391 433 einfo (_("%F%P: unknown ELF symbol visibility: %d!\n"),
cfac8028 434 ldsym->visibility);
2b804145
AM
435 return LDPS_ERR;
436
cfac8028
L
437 case LDPV_DEFAULT:
438 visibility = STV_DEFAULT;
439 break;
440 case LDPV_PROTECTED:
441 visibility = STV_PROTECTED;
442 break;
443 case LDPV_INTERNAL:
444 visibility = STV_INTERNAL;
445 break;
446 case LDPV_HIDDEN:
447 visibility = STV_HIDDEN;
448 break;
449 }
0410b450 450 elfsym->internal_elf_sym.st_other |= visibility;
5d3236ee
DK
451 }
452
453 return LDPS_OK;
454}
455
456/* Register a claim-file handler. */
457static enum ld_plugin_status
458register_claim_file (ld_plugin_claim_file_handler handler)
459{
460 ASSERT (called_plugin);
461 called_plugin->claim_file_handler = handler;
462 return LDPS_OK;
463}
464
465/* Register an all-symbols-read handler. */
466static enum ld_plugin_status
467register_all_symbols_read (ld_plugin_all_symbols_read_handler handler)
468{
469 ASSERT (called_plugin);
470 called_plugin->all_symbols_read_handler = handler;
471 return LDPS_OK;
472}
473
474/* Register a cleanup handler. */
475static enum ld_plugin_status
476register_cleanup (ld_plugin_cleanup_handler handler)
477{
478 ASSERT (called_plugin);
479 called_plugin->cleanup_handler = handler;
480 return LDPS_OK;
481}
482
483/* Add symbols from a plugin-claimed input file. */
484static enum ld_plugin_status
485add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
486{
487 asymbol **symptrs;
f4b78d18
L
488 plugin_input_file_t *input = handle;
489 bfd *abfd = input->abfd;
7fe550fc 490 int n;
43e1669b 491
5d3236ee
DK
492 ASSERT (called_plugin);
493 symptrs = xmalloc (nsyms * sizeof *symptrs);
7fe550fc 494 for (n = 0; n < nsyms; n++)
5d3236ee
DK
495 {
496 enum ld_plugin_status rv;
0c511000
AM
497 asymbol *bfdsym;
498
0c511000 499 bfdsym = bfd_make_empty_symbol (abfd);
7fe550fc 500 symptrs[n] = bfdsym;
5d3236ee
DK
501 rv = asymbol_from_plugin_symbol (abfd, bfdsym, syms + n);
502 if (rv != LDPS_OK)
503 return rv;
504 }
7fe550fc 505 bfd_set_symtab (abfd, symptrs, nsyms);
5d3236ee
DK
506 return LDPS_OK;
507}
508
509/* Get the input file information with an open (possibly re-opened)
510 file descriptor. */
511static enum ld_plugin_status
f4b78d18 512get_input_file (const void *handle, struct ld_plugin_input_file *file)
5d3236ee 513{
f4b78d18
L
514 const plugin_input_file_t *input = handle;
515
5d3236ee 516 ASSERT (called_plugin);
f4b78d18
L
517
518 file->name = input->name;
519 file->offset = input->offset;
520 file->filesize = input->filesize;
521 file->handle = (void *) handle;
522
523 return LDPS_OK;
5d3236ee
DK
524}
525
15f7a26b
L
526/* Get view of the input file. */
527static enum ld_plugin_status
f4b78d18 528get_view (const void *handle, const void **viewp)
15f7a26b 529{
2aec968d 530 plugin_input_file_t *input = (plugin_input_file_t *) handle;
f4b78d18 531 char *buffer;
2aec968d 532 size_t size = input->filesize;
38604796
L
533 off_t offset = input->offset;
534#if HAVE_MMAP && HAVE_GETPAGESIZE
535 off_t bias;
fe905789 536#endif
f4b78d18 537
15f7a26b 538 ASSERT (called_plugin);
f4b78d18 539
2aec968d
L
540 /* FIXME: einfo should support %lld. */
541 if ((off_t) size != input->filesize)
df5f2391 542 einfo (_("%F%P: unsupported input file size: %s (%ld bytes)\n"),
2aec968d 543 input->name, (long) input->filesize);
f4b78d18 544
2aec968d
L
545 /* Check the cached view buffer. */
546 if (input->view_buffer.addr != NULL
547 && input->view_buffer.filesize == size
38604796 548 && input->view_buffer.offset == offset)
2aec968d
L
549 {
550 *viewp = input->view_buffer.addr;
551 return LDPS_OK;
552 }
553
554 input->view_buffer.filesize = size;
38604796 555 input->view_buffer.offset = offset;
f4b78d18 556
2aec968d 557#if HAVE_MMAP
fe905789 558# if HAVE_GETPAGESIZE
38604796
L
559 bias = offset % plugin_pagesize;
560 offset -= bias;
fe905789
L
561 size += bias;
562# endif
563 buffer = mmap (NULL, size, PROT_READ, MAP_PRIVATE, input->fd, offset);
564 if (buffer != MAP_FAILED)
38604796
L
565 {
566 input->use_mmap = TRUE;
567# if HAVE_GETPAGESIZE
568 buffer += bias;
b677c456 569# endif
38604796
L
570 }
571 else
2aec968d 572#endif
f4b78d18 573 {
2aec968d
L
574 char *p;
575
38604796
L
576 input->use_mmap = FALSE;
577
578 if (lseek (input->fd, offset, SEEK_SET) < 0)
2aec968d
L
579 return LDPS_ERR;
580
581 buffer = bfd_alloc (input->abfd, size);
582 if (buffer == NULL)
583 return LDPS_ERR;
584
585 p = buffer;
586 do
f4b78d18 587 {
2aec968d
L
588 ssize_t got = read (input->fd, p, size);
589 if (got == 0)
590 break;
591 else if (got > 0)
592 {
593 p += got;
594 size -= got;
595 }
596 else if (errno != EINTR)
597 return LDPS_ERR;
f4b78d18 598 }
2aec968d 599 while (size > 0);
f4b78d18 600 }
2aec968d
L
601
602 input->view_buffer.addr = buffer;
603 *viewp = buffer;
f4b78d18
L
604
605 return LDPS_OK;
15f7a26b
L
606}
607
5d3236ee
DK
608/* Release the input file. */
609static enum ld_plugin_status
f4b78d18 610release_input_file (const void *handle)
5d3236ee 611{
119d62ff 612 plugin_input_file_t *input = (plugin_input_file_t *) handle;
5d3236ee 613 ASSERT (called_plugin);
f4b78d18 614 if (input->fd != -1)
119d62ff
L
615 {
616 close (input->fd);
617 input->fd = -1;
618 }
f4b78d18 619 return LDPS_OK;
5d3236ee
DK
620}
621
42a851a9
DK
622/* Return TRUE if a defined symbol might be reachable from outside the
623 universe of claimed objects. */
624static inline bfd_boolean
9bbc1a67 625is_visible_from_outside (struct ld_plugin_symbol *lsym,
f84854b6 626 struct bfd_link_hash_entry *blhe)
42a851a9 627{
0e1862bb 628 if (bfd_link_relocatable (&link_info))
42a851a9 629 return TRUE;
4070765b 630 if (blhe->non_ir_ref_dynamic
59fa66c5
L
631 || link_info.export_dynamic
632 || bfd_link_dll (&link_info))
42a851a9 633 {
fd91d419
L
634 /* Check if symbol is hidden by version script. */
635 if (bfd_hide_sym_by_version (link_info.version_info,
636 blhe->root.string))
637 return FALSE;
42a851a9
DK
638 /* Only ELF symbols really have visibility. */
639 if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
640 {
641 struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe;
642 int vis = ELF_ST_VISIBILITY (el->other);
643 return vis == STV_DEFAULT || vis == STV_PROTECTED;
644 }
645 /* On non-ELF targets, we can safely make inferences by considering
f84854b6 646 what visibility the plugin would have liked to apply when it first
42a851a9
DK
647 sent us the symbol. During ELF symbol processing, visibility only
648 ever becomes more restrictive, not less, when symbols are merged,
649 so this is a conservative estimate; it may give false positives,
650 declaring something visible from outside when it in fact would
651 not have been, but this will only lead to missed optimisation
652 opportunities during LTRANS at worst; it will not give false
653 negatives, which can lead to the disastrous conclusion that the
654 related symbol is IRONLY. (See GCC PR46319 for an example.) */
cfac8028
L
655 return (lsym->visibility == LDPV_DEFAULT
656 || lsym->visibility == LDPV_PROTECTED);
42a851a9 657 }
35ed3f94 658
42a851a9
DK
659 return FALSE;
660}
661
8e5cb9a5 662/* Return LTO kind string name that corresponds to IDX enum value. */
7ea79cb3 663static const char *
8e5cb9a5 664get_lto_kind (unsigned int idx)
7ea79cb3 665{
666 static char buffer[64];
667 const char *lto_kind_str[5] =
668 {
669 "DEF",
670 "WEAKDEF",
671 "UNDEF",
672 "WEAKUNDEF",
673 "COMMON"
674 };
675
8e5cb9a5
JB
676 if (idx < ARRAY_SIZE (lto_kind_str))
677 return lto_kind_str [idx];
7ea79cb3 678
8e5cb9a5 679 sprintf (buffer, _("unknown LTO kind value %x"), idx);
7ea79cb3 680 return buffer;
681}
682
8e5cb9a5 683/* Return LTO resolution string name that corresponds to IDX enum value. */
7ea79cb3 684static const char *
8e5cb9a5 685get_lto_resolution (unsigned int idx)
7ea79cb3 686{
687 static char buffer[64];
688 static const char *lto_resolution_str[10] =
689 {
690 "UNKNOWN",
691 "UNDEF",
692 "PREVAILING_DEF",
693 "PREVAILING_DEF_IRONLY",
694 "PREEMPTED_REG",
695 "PREEMPTED_IR",
696 "RESOLVED_IR",
697 "RESOLVED_EXEC",
698 "RESOLVED_DYN",
699 "PREVAILING_DEF_IRONLY_EXP",
700 };
701
8e5cb9a5
JB
702 if (idx < ARRAY_SIZE (lto_resolution_str))
703 return lto_resolution_str [idx];
7ea79cb3 704
8e5cb9a5 705 sprintf (buffer, _("unknown LTO resolution value %x"), idx);
7ea79cb3 706 return buffer;
707}
708
8e5cb9a5 709/* Return LTO visibility string name that corresponds to IDX enum value. */
7ea79cb3 710static const char *
8e5cb9a5 711get_lto_visibility (unsigned int idx)
7ea79cb3 712{
713 static char buffer[64];
714 const char *lto_visibility_str[4] =
715 {
716 "DEFAULT",
717 "PROTECTED",
718 "INTERNAL",
719 "HIDDEN"
720 };
721
8e5cb9a5
JB
722 if (idx < ARRAY_SIZE (lto_visibility_str))
723 return lto_visibility_str [idx];
7ea79cb3 724
8e5cb9a5 725 sprintf (buffer, _("unknown LTO visibility value %x"), idx);
7ea79cb3 726 return buffer;
727}
728
5d3236ee
DK
729/* Get the symbol resolution info for a plugin-claimed input file. */
730static enum ld_plugin_status
69ee6ab2
AM
731get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
732 int def_ironly_exp)
5d3236ee 733{
f4b78d18
L
734 const plugin_input_file_t *input = handle;
735 const bfd *abfd = (const bfd *) input->abfd;
5d3236ee 736 int n;
69ee6ab2 737
5d3236ee
DK
738 ASSERT (called_plugin);
739 for (n = 0; n < nsyms; n++)
740 {
741 struct bfd_link_hash_entry *blhe;
42a851a9 742 asection *owner_sec;
69ee6ab2 743 int res;
6fe014bc
L
744 struct bfd_link_hash_entry *h
745 = bfd_link_hash_lookup (link_info.hash, syms[n].name,
746 FALSE, FALSE, TRUE);
747 enum { wrap_none, wrapper, wrapped } wrap_status = wrap_none;
69ee6ab2 748
6fe014bc
L
749 if (syms[n].def != LDPK_UNDEF && syms[n].def != LDPK_WEAKUNDEF)
750 {
751 blhe = h;
a78fca7b 752 if (blhe && link_info.wrap_hash != NULL)
6fe014bc
L
753 {
754 /* Check if a symbol is a wrapper symbol. */
755 struct bfd_link_hash_entry *unwrap
756 = unwrap_hash_lookup (&link_info, (bfd *) abfd, blhe);
757 if (unwrap && unwrap != h)
758 wrap_status = wrapper;
759 }
760 }
10be1b6a 761 else
6fe014bc
L
762 {
763 blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
764 &link_info, syms[n].name,
765 FALSE, FALSE, TRUE);
766 /* Check if a symbol is a wrapped symbol. */
767 if (blhe && blhe != h)
768 wrap_status = wrapped;
769 }
5d3236ee
DK
770 if (!blhe)
771 {
3355cb3b
L
772 /* The plugin is called to claim symbols in an archive element
773 from plugin_object_p. But those symbols aren't needed to
774 create output. They are defined and referenced only within
775 IR. */
776 switch (syms[n].def)
777 {
778 default:
779 abort ();
780 case LDPK_UNDEF:
781 case LDPK_WEAKUNDEF:
782 res = LDPR_UNDEF;
783 break;
784 case LDPK_DEF:
785 case LDPK_WEAKDEF:
786 case LDPK_COMMON:
787 res = LDPR_PREVAILING_DEF_IRONLY;
788 break;
789 }
1715a13c 790 goto report_symbol;
5d3236ee
DK
791 }
792
793 /* Determine resolution from blhe type and symbol's original type. */
794 if (blhe->type == bfd_link_hash_undefined
f84854b6 795 || blhe->type == bfd_link_hash_undefweak)
5d3236ee 796 {
69ee6ab2 797 res = LDPR_UNDEF;
1715a13c 798 goto report_symbol;
5d3236ee
DK
799 }
800 if (blhe->type != bfd_link_hash_defined
f84854b6
L
801 && blhe->type != bfd_link_hash_defweak
802 && blhe->type != bfd_link_hash_common)
5d3236ee
DK
803 {
804 /* We should not have a new, indirect or warning symbol here. */
df5f2391 805 einfo (_("%F%P: %s: plugin symbol table corrupt (sym type %d)\n"),
f84854b6 806 called_plugin->name, blhe->type);
5d3236ee
DK
807 }
808
42a851a9
DK
809 /* Find out which section owns the symbol. Since it's not undef,
810 it must have an owner; if it's not a common symbol, both defs
811 and weakdefs keep it in the same place. */
9e2278f5
AM
812 owner_sec = (blhe->type == bfd_link_hash_common
813 ? blhe->u.c.p->section
814 : blhe->u.def.section);
42a851a9 815
5d3236ee
DK
816
817 /* If it was originally undefined or common, then it has been
f84854b6
L
818 resolved; determine how. */
819 if (syms[n].def == LDPK_UNDEF
820 || syms[n].def == LDPK_WEAKUNDEF
5d3236ee
DK
821 || syms[n].def == LDPK_COMMON)
822 {
5d3236ee 823 if (owner_sec->owner == link_info.output_bfd)
69ee6ab2 824 res = LDPR_RESOLVED_EXEC;
5d3236ee 825 else if (owner_sec->owner == abfd)
69ee6ab2 826 res = LDPR_PREVAILING_DEF_IRONLY;
5d3236ee 827 else if (is_ir_dummy_bfd (owner_sec->owner))
69ee6ab2 828 res = LDPR_RESOLVED_IR;
cc322803
L
829 else if (owner_sec->owner != NULL
830 && (owner_sec->owner->flags & DYNAMIC) != 0)
69ee6ab2 831 res = LDPR_RESOLVED_DYN;
5d3236ee 832 else
69ee6ab2 833 res = LDPR_RESOLVED_EXEC;
5d3236ee
DK
834 }
835
836 /* Was originally def, or weakdef. Does it prevail? If the
f84854b6 837 owner is the original dummy bfd that supplied it, then this
5d3236ee 838 is the definition that has prevailed. */
69ee6ab2
AM
839 else if (owner_sec->owner == link_info.output_bfd)
840 res = LDPR_PREEMPTED_REG;
42a851a9 841 else if (owner_sec->owner == abfd)
69ee6ab2 842 res = LDPR_PREVAILING_DEF_IRONLY;
5d3236ee
DK
843
844 /* Was originally def, weakdef, or common, but has been pre-empted. */
69ee6ab2
AM
845 else if (is_ir_dummy_bfd (owner_sec->owner))
846 res = LDPR_PREEMPTED_IR;
847 else
848 res = LDPR_PREEMPTED_REG;
849
850 if (res == LDPR_PREVAILING_DEF_IRONLY)
851 {
852 /* We need to know if the sym is referenced from non-IR files. Or
853 even potentially-referenced, perhaps in a future final link if
854 this is a partial one, perhaps dynamically at load-time if the
6fe014bc
L
855 symbol is externally visible. Also check for wrapper symbol. */
856 if (blhe->non_ir_ref_regular || wrap_status == wrapper)
69ee6ab2 857 res = LDPR_PREVAILING_DEF;
6fe014bc
L
858 else if (wrap_status == wrapped)
859 res = LDPR_RESOLVED_IR;
9bbc1a67 860 else if (is_visible_from_outside (&syms[n], blhe))
69ee6ab2
AM
861 res = def_ironly_exp;
862 }
1715a13c 863
9e2278f5 864 report_symbol:
69ee6ab2 865 syms[n].resolution = res;
1715a13c 866 if (report_plugin_symbols)
871b3ab2 867 einfo (_("%P: %pB: symbol `%s' "
7ea79cb3 868 "definition: %s, visibility: %s, resolution: %s\n"),
9e2278f5 869 abfd, syms[n].name,
7ea79cb3 870 get_lto_kind (syms[n].def),
871 get_lto_visibility (syms[n].visibility),
872 get_lto_resolution (res));
5d3236ee
DK
873 }
874 return LDPS_OK;
875}
876
69ee6ab2
AM
877static enum ld_plugin_status
878get_symbols_v1 (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
879{
880 return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF);
881}
882
883static enum ld_plugin_status
884get_symbols_v2 (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
885{
886 return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF_IRONLY_EXP);
887}
888
5d3236ee
DK
889/* Add a new (real) input file generated by a plugin. */
890static enum ld_plugin_status
891add_input_file (const char *pathname)
892{
ce875075
AM
893 lang_input_statement_type *is;
894
5d3236ee 895 ASSERT (called_plugin);
ce875075
AM
896 is = lang_add_input_file (xstrdup (pathname), lang_input_file_is_file_enum,
897 NULL);
898 if (!is)
5d3236ee 899 return LDPS_ERR;
ce875075 900 is->flags.lto_output = 1;
5d3236ee
DK
901 return LDPS_OK;
902}
903
904/* Add a new (real) library required by a plugin. */
905static enum ld_plugin_status
906add_input_library (const char *pathname)
907{
ce875075
AM
908 lang_input_statement_type *is;
909
5d3236ee 910 ASSERT (called_plugin);
ce875075
AM
911 is = lang_add_input_file (xstrdup (pathname), lang_input_file_is_l_enum,
912 NULL);
913 if (!is)
5d3236ee 914 return LDPS_ERR;
ce875075 915 is->flags.lto_output = 1;
5d3236ee
DK
916 return LDPS_OK;
917}
918
919/* Set the extra library path to be used by libraries added via
920 add_input_library. */
921static enum ld_plugin_status
922set_extra_library_path (const char *path)
923{
924 ASSERT (called_plugin);
d4cb7acd 925 ldfile_add_library_path (xstrdup (path), FALSE);
5d3236ee
DK
926 return LDPS_OK;
927}
928
929/* Issue a diagnostic message from a plugin. */
930static enum ld_plugin_status
931message (int level, const char *format, ...)
932{
933 va_list args;
934 va_start (args, format);
935
936 switch (level)
937 {
938 case LDPL_INFO:
939 vfinfo (stdout, format, args, FALSE);
d251c5c4 940 putchar ('\n');
5d3236ee
DK
941 break;
942 case LDPL_WARNING:
45e81354 943 {
df5f2391 944 char *newfmt = concat (_("%P: warning: "), format, "\n",
e1fa0163 945 (const char *) NULL);
45e81354 946 vfinfo (stdout, newfmt, args, TRUE);
e1fa0163 947 free (newfmt);
45e81354 948 }
5d3236ee
DK
949 break;
950 case LDPL_FATAL:
951 case LDPL_ERROR:
952 default:
9e2278f5 953 {
df5f2391
AM
954 char *newfmt = concat (level == LDPL_FATAL ? "%F" : "%X",
955 _("%P: error: "), format, "\n",
e1fa0163 956 (const char *) NULL);
9e2278f5
AM
957 fflush (stdout);
958 vfinfo (stderr, newfmt, args, TRUE);
959 fflush (stderr);
e1fa0163 960 free (newfmt);
9e2278f5 961 }
5d3236ee
DK
962 break;
963 }
964
965 va_end (args);
966 return LDPS_OK;
967}
968
969/* Helper to size leading part of tv array and set it up. */
69ee6ab2 970static void
5d3236ee
DK
971set_tv_header (struct ld_plugin_tv *tv)
972{
973 size_t i;
974
975 /* Version info. */
976 static const unsigned int major = (unsigned)(BFD_VERSION / 100000000UL);
977 static const unsigned int minor = (unsigned)(BFD_VERSION / 1000000UL) % 100;
978
5d3236ee
DK
979 for (i = 0; i < tv_header_size; i++)
980 {
981 tv[i].tv_tag = tv_header_tags[i];
982#define TVU(x) tv[i].tv_u.tv_ ## x
983 switch (tv[i].tv_tag)
984 {
f84854b6
L
985 case LDPT_MESSAGE:
986 TVU(message) = message;
987 break;
988 case LDPT_API_VERSION:
989 TVU(val) = LD_PLUGIN_API_VERSION;
990 break;
991 case LDPT_GNU_LD_VERSION:
992 TVU(val) = major * 100 + minor;
993 break;
994 case LDPT_LINKER_OUTPUT:
64d94ba0
AM
995 TVU(val) = (bfd_link_relocatable (&link_info) ? LDPO_REL
996 : bfd_link_pde (&link_info) ? LDPO_EXEC
997 : bfd_link_pie (&link_info) ? LDPO_PIE
998 : LDPO_DYN);
f84854b6
L
999 break;
1000 case LDPT_OUTPUT_NAME:
1001 TVU(string) = output_filename;
1002 break;
1003 case LDPT_REGISTER_CLAIM_FILE_HOOK:
1004 TVU(register_claim_file) = register_claim_file;
1005 break;
1006 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
1007 TVU(register_all_symbols_read) = register_all_symbols_read;
1008 break;
1009 case LDPT_REGISTER_CLEANUP_HOOK:
1010 TVU(register_cleanup) = register_cleanup;
1011 break;
1012 case LDPT_ADD_SYMBOLS:
1013 TVU(add_symbols) = add_symbols;
1014 break;
1015 case LDPT_GET_INPUT_FILE:
1016 TVU(get_input_file) = get_input_file;
1017 break;
15f7a26b
L
1018 case LDPT_GET_VIEW:
1019 TVU(get_view) = get_view;
1020 break;
f84854b6
L
1021 case LDPT_RELEASE_INPUT_FILE:
1022 TVU(release_input_file) = release_input_file;
1023 break;
1024 case LDPT_GET_SYMBOLS:
69ee6ab2
AM
1025 TVU(get_symbols) = get_symbols_v1;
1026 break;
1027 case LDPT_GET_SYMBOLS_V2:
1028 TVU(get_symbols) = get_symbols_v2;
f84854b6
L
1029 break;
1030 case LDPT_ADD_INPUT_FILE:
1031 TVU(add_input_file) = add_input_file;
1032 break;
1033 case LDPT_ADD_INPUT_LIBRARY:
1034 TVU(add_input_library) = add_input_library;
1035 break;
1036 case LDPT_SET_EXTRA_LIBRARY_PATH:
1037 TVU(set_extra_library_path) = set_extra_library_path;
1038 break;
1039 default:
1040 /* Added a new entry to the array without adding
1041 a new case to set up its value is a bug. */
1042 FAIL ();
5d3236ee
DK
1043 }
1044#undef TVU
1045 }
5d3236ee
DK
1046}
1047
1048/* Append the per-plugin args list and trailing LDPT_NULL to tv. */
1049static void
1050set_tv_plugin_args (plugin_t *plugin, struct ld_plugin_tv *tv)
1051{
1052 plugin_arg_t *arg = plugin->args;
1053 while (arg)
1054 {
1055 tv->tv_tag = LDPT_OPTION;
1056 tv->tv_u.tv_string = arg->arg;
1057 arg = arg->next;
1058 tv++;
1059 }
1060 tv->tv_tag = LDPT_NULL;
1061 tv->tv_u.tv_val = 0;
1062}
1063
1064/* Load up and initialise all plugins after argument parsing. */
d82184d7 1065void
d44ad554 1066plugin_load_plugins (void)
5d3236ee
DK
1067{
1068 struct ld_plugin_tv *my_tv;
1069 unsigned int max_args = 0;
1070 plugin_t *curplug = plugins_list;
1071
1072 /* If there are no plugins, we need do nothing this run. */
1073 if (!curplug)
d82184d7 1074 return;
5d3236ee
DK
1075
1076 /* First pass over plugins to find max # args needed so that we
1077 can size and allocate the tv array. */
1078 while (curplug)
1079 {
1080 if (curplug->n_args > max_args)
1081 max_args = curplug->n_args;
1082 curplug = curplug->next;
1083 }
1084
1085 /* Allocate tv array and initialise constant part. */
1086 my_tv = xmalloc ((max_args + 1 + tv_header_size) * sizeof *my_tv);
1087 set_tv_header (my_tv);
1088
1089 /* Pass over plugins again, activating them. */
1090 curplug = plugins_list;
1091 while (curplug)
1092 {
1093 enum ld_plugin_status rv;
a8f9d13e
AM
1094 ld_plugin_onload onloadfn;
1095
1096 onloadfn = (ld_plugin_onload) dlsym (curplug->dlhandle, "onload");
5d3236ee 1097 if (!onloadfn)
a8f9d13e 1098 onloadfn = (ld_plugin_onload) dlsym (curplug->dlhandle, "_onload");
5d3236ee 1099 if (!onloadfn)
df5f2391 1100 einfo (_("%F%P: %s: error loading plugin: %s\n"),
d82184d7 1101 curplug->name, dlerror ());
5d3236ee
DK
1102 set_tv_plugin_args (curplug, &my_tv[tv_header_size]);
1103 called_plugin = curplug;
1104 rv = (*onloadfn) (my_tv);
1105 called_plugin = NULL;
1106 if (rv != LDPS_OK)
df5f2391 1107 einfo (_("%F%P: %s: plugin error: %d\n"), curplug->name, rv);
5d3236ee
DK
1108 curplug = curplug->next;
1109 }
1110
1111 /* Since plugin(s) inited ok, assume they're going to want symbol
1112 resolutions, which needs us to track which symbols are referenced
1113 by non-IR files using the linker's notice callback. */
9e2278f5
AM
1114 orig_notice_all = link_info.notice_all;
1115 orig_callbacks = link_info.callbacks;
1116 plugin_callbacks = *orig_callbacks;
1117 plugin_callbacks.notice = &plugin_notice;
5d3236ee 1118 link_info.notice_all = TRUE;
61f41c3c 1119 link_info.lto_plugin_active = TRUE;
9e2278f5 1120 link_info.callbacks = &plugin_callbacks;
38604796 1121
5ae0078c
L
1122 register_ld_plugin_object_p (plugin_object_p);
1123
38604796 1124#if HAVE_MMAP && HAVE_GETPAGESIZE
fd5a1509 1125 plugin_pagesize = getpagesize ();
38604796 1126#endif
5d3236ee
DK
1127}
1128
1129/* Call 'claim file' hook for all plugins. */
02d00247 1130static int
5d3236ee
DK
1131plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
1132{
1133 plugin_t *curplug = plugins_list;
1134 *claimed = FALSE;
5d3236ee
DK
1135 while (curplug && !*claimed)
1136 {
1137 if (curplug->claim_file_handler)
1138 {
1139 enum ld_plugin_status rv;
ace667e5 1140
5d3236ee
DK
1141 called_plugin = curplug;
1142 rv = (*curplug->claim_file_handler) (file, claimed);
1143 called_plugin = NULL;
1144 if (rv != LDPS_OK)
1145 set_plugin_error (curplug->name);
1146 }
1147 curplug = curplug->next;
1148 }
1149 return plugin_error_p () ? -1 : 0;
1150}
1151
35a1e5f3
L
1152/* Duplicates a character string with memory attached to ABFD. */
1153
1154static char *
1155plugin_strdup (bfd *abfd, const char *str)
1156{
1157 size_t strlength;
1158 char *copy;
1159 strlength = strlen (str) + 1;
1160 copy = bfd_alloc (abfd, strlength);
1161 if (copy == NULL)
df5f2391 1162 einfo (_("%F%P: plugin_strdup failed to allocate memory: %s\n"),
35a1e5f3
L
1163 bfd_get_error ());
1164 memcpy (copy, str, strlength);
1165 return copy;
1166}
1167
cb001c0d
AM
1168static void
1169plugin_cleanup (bfd *abfd ATTRIBUTE_UNUSED)
1170{
1171}
1172
1173static bfd_cleanup
5ae0078c 1174plugin_object_p (bfd *ibfd)
02d00247 1175{
5ae0078c 1176 int claimed;
f4b78d18 1177 plugin_input_file_t *input;
35a1e5f3
L
1178 struct ld_plugin_input_file file;
1179 bfd *abfd;
5ae0078c
L
1180
1181 /* Don't try the dummy object file. */
1182 if ((ibfd->flags & BFD_PLUGIN) != 0)
1183 return NULL;
1184
49f30d83 1185 if (ibfd->plugin_format != bfd_plugin_unknown)
5ae0078c
L
1186 {
1187 if (ibfd->plugin_format == bfd_plugin_yes)
cb001c0d 1188 return plugin_cleanup;
5ae0078c
L
1189 else
1190 return NULL;
1191 }
1192
02d00247
AM
1193 /* We create a dummy BFD, initially empty, to house whatever symbols
1194 the plugin may want to add. */
607b4833 1195 abfd = plugin_get_ir_dummy_bfd (bfd_get_filename (ibfd), ibfd);
f4b78d18
L
1196
1197 input = bfd_alloc (abfd, sizeof (*input));
1198 if (input == NULL)
df5f2391 1199 einfo (_("%F%P: plugin failed to allocate memory for input: %s\n"),
f4b78d18
L
1200 bfd_get_error ());
1201
7d0b9ebc
AM
1202 if (!bfd_plugin_open_input (ibfd, &file))
1203 return NULL;
35a1e5f3 1204
607b4833 1205 if (file.name == bfd_get_filename (ibfd))
7d0b9ebc 1206 {
35a1e5f3
L
1207 /* We must copy filename attached to ibfd if it is not an archive
1208 member since it may be freed by bfd_close below. */
7d0b9ebc 1209 file.name = plugin_strdup (abfd, file.name);
35a1e5f3
L
1210 }
1211
35a1e5f3 1212 file.handle = input;
f4b78d18 1213 input->abfd = abfd;
2aec968d
L
1214 input->view_buffer.addr = NULL;
1215 input->view_buffer.filesize = 0;
1216 input->view_buffer.offset = 0;
7d0b9ebc 1217 input->fd = file.fd;
d319a098 1218 input->use_mmap = FALSE;
7d0b9ebc
AM
1219 input->offset = file.offset;
1220 input->filesize = file.filesize;
607b4833 1221 input->name = plugin_strdup (abfd, bfd_get_filename (ibfd));
f4b78d18 1222
5ae0078c
L
1223 claimed = 0;
1224
35a1e5f3 1225 if (plugin_call_claim_file (&file, &claimed))
df5f2391 1226 einfo (_("%F%P: %s: plugin reported error claiming file\n"),
02d00247 1227 plugin_error_plugin ());
f4b78d18 1228
7d0b9ebc 1229 if (input->fd != -1 && !bfd_plugin_target_p (ibfd->xvec))
f4b78d18 1230 {
5ae0078c
L
1231 /* FIXME: fd belongs to us, not the plugin. GCC plugin, which
1232 doesn't need fd after plugin_call_claim_file, doesn't use
1233 BFD plugin target vector. Since GCC plugin doesn't call
1234 release_input_file, we close it here. LLVM plugin, which
1235 needs fd after plugin_call_claim_file and calls
1236 release_input_file after it is done, uses BFD plugin target
1237 vector. This scheme doesn't work when a plugin needs fd and
1238 doesn't use BFD plugin target vector neither. */
7d0b9ebc 1239 close (input->fd);
f4b78d18
L
1240 input->fd = -1;
1241 }
1242
02d00247
AM
1243 if (claimed)
1244 {
5ae0078c
L
1245 ibfd->plugin_format = bfd_plugin_yes;
1246 ibfd->plugin_dummy_bfd = abfd;
35a1e5f3 1247 bfd_make_readable (abfd);
2aa90762 1248 abfd->no_export = ibfd->no_export;
cb001c0d 1249 return plugin_cleanup;
02d00247
AM
1250 }
1251 else
1252 {
38604796
L
1253#if HAVE_MMAP
1254 if (input->use_mmap)
1255 {
1256 /* If plugin didn't claim the file, unmap the buffer. */
1257 char *addr = input->view_buffer.addr;
1258 off_t size = input->view_buffer.filesize;
1259# if HAVE_GETPAGESIZE
1260 off_t bias = input->view_buffer.offset % plugin_pagesize;
1261 size += bias;
1262 addr -= bias;
1263# endif
1264 munmap (addr, size);
1265 }
1266#endif
1267
02d00247
AM
1268 /* If plugin didn't claim the file, we don't need the dummy bfd.
1269 Can't avoid speculatively creating it, alas. */
5ae0078c 1270 ibfd->plugin_format = bfd_plugin_no;
f4b78d18 1271 bfd_close_all_done (abfd);
5ae0078c
L
1272 return NULL;
1273 }
1274}
1275
1276void
1277plugin_maybe_claim (lang_input_statement_type *entry)
1278{
fb47deda 1279 ASSERT (entry->header.type == lang_input_statement_enum);
5ae0078c
L
1280 if (plugin_object_p (entry->the_bfd))
1281 {
1282 bfd *abfd = entry->the_bfd->plugin_dummy_bfd;
1283
1284 /* Discard the real file's BFD and substitute the dummy one. */
1285
b0cffb47
AM
1286 /* We can't call bfd_close on archives. BFD archive handling
1287 caches elements, and add_archive_element keeps pointers to
1288 the_bfd and the_bfd->filename in a lang_input_statement_type
1289 linker script statement. */
5ae0078c
L
1290 if (entry->the_bfd->my_archive == NULL)
1291 bfd_close (entry->the_bfd);
1292 entry->the_bfd = abfd;
1293 entry->flags.claimed = 1;
02d00247
AM
1294 }
1295}
1296
5d3236ee
DK
1297/* Call 'all symbols read' hook for all plugins. */
1298int
1299plugin_call_all_symbols_read (void)
1300{
1301 plugin_t *curplug = plugins_list;
1302
1303 /* Disable any further file-claiming. */
1304 no_more_claiming = TRUE;
1305
5d3236ee
DK
1306 while (curplug)
1307 {
1308 if (curplug->all_symbols_read_handler)
1309 {
1310 enum ld_plugin_status rv;
1311 called_plugin = curplug;
1312 rv = (*curplug->all_symbols_read_handler) ();
1313 called_plugin = NULL;
1314 if (rv != LDPS_OK)
1315 set_plugin_error (curplug->name);
1316 }
1317 curplug = curplug->next;
1318 }
1319 return plugin_error_p () ? -1 : 0;
1320}
1321
e73d965c 1322/* Call 'cleanup' hook for all plugins at exit. */
498cd2a0 1323void
5d3236ee
DK
1324plugin_call_cleanup (void)
1325{
1326 plugin_t *curplug = plugins_list;
1327 while (curplug)
1328 {
1329 if (curplug->cleanup_handler && !curplug->cleanup_done)
1330 {
1331 enum ld_plugin_status rv;
1332 curplug->cleanup_done = TRUE;
1333 called_plugin = curplug;
1334 rv = (*curplug->cleanup_handler) ();
1335 called_plugin = NULL;
1336 if (rv != LDPS_OK)
d82184d7
L
1337 info_msg (_("%P: %s: error in plugin cleanup: %d (ignored)\n"),
1338 curplug->name, rv);
5d3236ee
DK
1339 dlclose (curplug->dlhandle);
1340 }
1341 curplug = curplug->next;
1342 }
5d3236ee
DK
1343}
1344
5d3236ee
DK
1345/* To determine which symbols should be resolved LDPR_PREVAILING_DEF
1346 and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
35ed3f94 1347 the linker adds them to the linker hash table. Mark those
bc4e12de 1348 referenced from a non-IR file with non_ir_ref_regular or
4070765b
AM
1349 non_ir_ref_dynamic as appropriate. We have to notice_all symbols,
1350 because we won't necessarily know until later which ones will be
1351 contributed by IR files. */
9e2278f5
AM
1352static bfd_boolean
1353plugin_notice (struct bfd_link_info *info,
35ed3f94 1354 struct bfd_link_hash_entry *h,
46135103 1355 struct bfd_link_hash_entry *inh,
9e2278f5
AM
1356 bfd *abfd,
1357 asection *section,
16d96b5b 1358 bfd_vma value,
46135103 1359 flagword flags)
5d3236ee 1360{
46135103
AM
1361 struct bfd_link_hash_entry *orig_h = h;
1362
35ed3f94 1363 if (h != NULL)
5d3236ee 1364 {
cd6eee13 1365 bfd *sym_bfd;
4070765b 1366 bfd_boolean ref = FALSE;
cd6eee13 1367
46135103
AM
1368 if (h->type == bfd_link_hash_warning)
1369 h = h->u.i.link;
1370
4a2b04a7 1371 /* Nothing to do here if this def/ref is from an IR dummy BFD. */
9e2278f5 1372 if (is_ir_dummy_bfd (abfd))
4a2b04a7 1373 ;
9e2278f5 1374
16d96b5b
AM
1375 /* Making an indirect symbol counts as a reference unless this
1376 is a brand new symbol. */
4a2b04a7
L
1377 else if (bfd_is_ind_section (section)
1378 || (flags & BSF_INDIRECT) != 0)
16d96b5b 1379 {
46135103
AM
1380 /* ??? Some of this is questionable. See comments in
1381 _bfd_generic_link_add_one_symbol for case IND. */
4070765b
AM
1382 if (h->type != bfd_link_hash_new
1383 || inh->type == bfd_link_hash_new)
16d96b5b 1384 {
4070765b 1385 if ((abfd->flags & DYNAMIC) == 0)
bc4e12de 1386 inh->non_ir_ref_regular = TRUE;
4070765b
AM
1387 else
1388 inh->non_ir_ref_dynamic = TRUE;
16d96b5b 1389 }
4070765b
AM
1390
1391 if (h->type != bfd_link_hash_new)
1392 ref = TRUE;
16d96b5b
AM
1393 }
1394
1395 /* Nothing to do here for warning symbols. */
1396 else if ((flags & BSF_WARNING) != 0)
1397 ;
1398
1399 /* Nothing to do here for constructor symbols. */
1400 else if ((flags & BSF_CONSTRUCTOR) != 0)
1401 ;
1402
35ed3f94 1403 /* If this is a ref, set non_ir_ref. */
16d96b5b 1404 else if (bfd_is_und_section (section))
3d5bef4c
L
1405 {
1406 /* Replace the undefined dummy bfd with the real one. */
4070765b
AM
1407 if ((h->type == bfd_link_hash_undefined
1408 || h->type == bfd_link_hash_undefweak)
1409 && (h->u.undef.abfd == NULL
1410 || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
59fa66c5 1411 h->u.undef.abfd = abfd;
4070765b 1412 ref = TRUE;
3d5bef4c 1413 }
35ed3f94 1414
af4fa23f
AM
1415
1416 /* A common symbol should be merged with other commons or
1417 defs with the same name. In particular, a common ought
1418 to be overridden by a def in a -flto object. In that
1419 sense a common is also a ref. */
1420 else if (bfd_is_com_section (section))
cd6eee13 1421 {
af4fa23f
AM
1422 if (h->type == bfd_link_hash_common
1423 && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner))
0616a280
AM
1424 {
1425 h->type = bfd_link_hash_undefweak;
1426 h->u.undef.abfd = sym_bfd;
1427 }
af4fa23f
AM
1428 ref = TRUE;
1429 }
4070765b 1430
af4fa23f
AM
1431 /* Otherwise, it must be a new def.
1432 Ensure any symbol defined in an IR dummy BFD takes on a
1433 new value from a real BFD. Weak symbols are not normally
1434 overridden by a new weak definition, and strong symbols
1435 will normally cause multiple definition errors. Avoid
0e6a3f07
L
1436 this by making the symbol appear to be undefined.
1437
1438 NB: We change the previous definition in the IR object to
04e433a8
L
1439 undefweak only after all LTO symbols have been read or for
1440 non-ELF targets. */
1441 else if ((info->lto_all_symbols_read
1442 || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
0e6a3f07
L
1443 && (((h->type == bfd_link_hash_defweak
1444 || h->type == bfd_link_hash_defined)
1445 && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
1446 || (h->type == bfd_link_hash_common
1447 && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner))))
af4fa23f
AM
1448 {
1449 h->type = bfd_link_hash_undefweak;
1450 h->u.undef.abfd = sym_bfd;
4070765b
AM
1451 }
1452
1453 if (ref)
1454 {
1455 if ((abfd->flags & DYNAMIC) == 0)
bc4e12de 1456 h->non_ir_ref_regular = TRUE;
4070765b
AM
1457 else
1458 h->non_ir_ref_dynamic = TRUE;
cd6eee13 1459 }
5d3236ee
DK
1460 }
1461
1462 /* Continue with cref/nocrossref/trace-sym processing. */
46135103 1463 if (orig_h == NULL
9e2278f5
AM
1464 || orig_notice_all
1465 || (info->notice_hash != NULL
46135103 1466 && bfd_hash_lookup (info->notice_hash, orig_h->root.string,
35ed3f94 1467 FALSE, FALSE) != NULL))
46135103
AM
1468 return (*orig_callbacks->notice) (info, orig_h, inh,
1469 abfd, section, value, flags);
5d3236ee
DK
1470 return TRUE;
1471}
0381901e 1472#endif /* BFD_SUPPORTS_PLUGINS */