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