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