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