Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5199 serge 1
/* Plugin control for the GNU linker.
2
   Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
3
 
4
   This file is part of the GNU Binutils.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
 
21
#include "sysdep.h"
22
#include "libiberty.h"
23
#include "bfd.h"
24
#include "bfdlink.h"
25
#include "bfdver.h"
26
#include "ld.h"
27
#include "ldmain.h"
28
#include "ldmisc.h"
29
#include "ldexp.h"
30
#include "ldlang.h"
31
#include "ldfile.h"
32
#include "plugin.h"
33
#include "plugin-api.h"
34
#include "elf-bfd.h"
35
#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
36
#include 
37
#endif
38
 
39
/* Report plugin symbols.  */
40
bfd_boolean report_plugin_symbols;
41
 
42
/* The suffix to append to the name of the real (claimed) object file
43
   when generating a dummy BFD to hold the IR symbols sent from the
44
   plugin.  For cosmetic use only; appears in maps, crefs etc.  */
45
#define IRONLY_SUFFIX " (symbol from plugin)"
46
 
47
/* Stores a single argument passed to a plugin.  */
48
typedef struct plugin_arg
49
{
50
  struct plugin_arg *next;
51
  const char *arg;
52
} plugin_arg_t;
53
 
54
/* Holds all details of a single plugin.  */
55
typedef struct plugin
56
{
57
  /* Next on the list of plugins, or NULL at end of chain.  */
58
  struct plugin *next;
59
  /* The argument string given to --plugin.  */
60
  const char *name;
61
  /* The shared library handle returned by dlopen.  */
62
  void *dlhandle;
63
  /* The list of argument string given to --plugin-opt.  */
64
  plugin_arg_t *args;
65
  /* Number of args in the list, for convenience.  */
66
  size_t n_args;
67
  /* The plugin's event handlers.  */
68
  ld_plugin_claim_file_handler claim_file_handler;
69
  ld_plugin_all_symbols_read_handler all_symbols_read_handler;
70
  ld_plugin_cleanup_handler cleanup_handler;
71
  /* TRUE if the cleanup handlers have been called.  */
72
  bfd_boolean cleanup_done;
73
} plugin_t;
74
 
75
/* The master list of all plugins.  */
76
static plugin_t *plugins_list = NULL;
77
 
78
/* We keep a tail pointer for easy linking on the end.  */
79
static plugin_t **plugins_tail_chain_ptr = &plugins_list;
80
 
81
/* The last plugin added to the list, for receiving args.  */
82
static plugin_t *last_plugin = NULL;
83
 
84
/* The tail of the arg chain of the last plugin added to the list.  */
85
static plugin_arg_t **last_plugin_args_tail_chain_ptr = NULL;
86
 
87
/* The plugin which is currently having a callback executed.  */
88
static plugin_t *called_plugin = NULL;
89
 
90
/* Last plugin to cause an error, if any.  */
91
static const char *error_plugin = NULL;
92
 
93
/* State of linker "notice" interface before we poked at it.  */
94
static bfd_boolean orig_notice_all;
95
 
96
/* Original linker callbacks, and the plugin version.  */
97
static const struct bfd_link_callbacks *orig_callbacks;
98
static struct bfd_link_callbacks plugin_callbacks;
99
 
100
/* Set at all symbols read time, to avoid recursively offering the plugin
101
   its own newly-added input files and libs to claim.  */
102
bfd_boolean no_more_claiming = FALSE;
103
 
104
/* List of tags to set in the constant leading part of the tv array. */
105
static const enum ld_plugin_tag tv_header_tags[] =
106
{
107
  LDPT_MESSAGE,
108
  LDPT_API_VERSION,
109
  LDPT_GNU_LD_VERSION,
110
  LDPT_LINKER_OUTPUT,
111
  LDPT_OUTPUT_NAME,
112
  LDPT_REGISTER_CLAIM_FILE_HOOK,
113
  LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
114
  LDPT_REGISTER_CLEANUP_HOOK,
115
  LDPT_ADD_SYMBOLS,
116
  LDPT_GET_INPUT_FILE,
117
  LDPT_RELEASE_INPUT_FILE,
118
  LDPT_GET_SYMBOLS,
119
  LDPT_GET_SYMBOLS_V2,
120
  LDPT_ADD_INPUT_FILE,
121
  LDPT_ADD_INPUT_LIBRARY,
122
  LDPT_SET_EXTRA_LIBRARY_PATH
123
};
124
 
125
/* How many entries in the constant leading part of the tv array.  */
126
static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
127
 
128
/* Forward references.  */
129
static bfd_boolean plugin_notice (struct bfd_link_info *,
130
				  struct bfd_link_hash_entry *, bfd *,
131
				  asection *, bfd_vma, flagword, const char *);
132
 
133
#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
134
 
135
#define RTLD_NOW 0	/* Dummy value.  */
136
 
137
static void *
138
dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
139
{
140
  return LoadLibrary (file);
141
}
142
 
143
static void *
144
dlsym (void *handle, const char *name)
145
{
146
  return GetProcAddress (handle, name);
147
}
148
 
149
static int
150
dlclose (void *handle)
151
{
152
  FreeLibrary (handle);
153
  return 0;
154
}
155
 
156
#endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)  */
157
 
158
#ifndef HAVE_DLFCN_H
159
static const char *
160
dlerror (void)
161
{
162
  return "";
163
}
164
#endif
165
 
166
/* Helper function for exiting with error status.  */
167
static int
168
set_plugin_error (const char *plugin)
169
{
170
  error_plugin = plugin;
171
  return -1;
172
}
173
 
174
/* Test if an error occurred.  */
175
static bfd_boolean
176
plugin_error_p (void)
177
{
178
  return error_plugin != NULL;
179
}
180
 
181
/* Return name of plugin which caused an error if any.  */
182
const char *
183
plugin_error_plugin (void)
184
{
185
  return error_plugin ? error_plugin : _("");
186
}
187
 
188
/* Handle -plugin arg: find and load plugin, or return error.  */
189
void
190
plugin_opt_plugin (const char *plugin)
191
{
192
  plugin_t *newplug;
193
 
194
  newplug = xmalloc (sizeof *newplug);
195
  memset (newplug, 0, sizeof *newplug);
196
  newplug->name = plugin;
197
  newplug->dlhandle = dlopen (plugin, RTLD_NOW);
198
  if (!newplug->dlhandle)
199
    einfo (_("%P%F: %s: error loading plugin: %s\n"), plugin, dlerror ());
200
 
201
  /* Chain on end, so when we run list it is in command-line order.  */
202
  *plugins_tail_chain_ptr = newplug;
203
  plugins_tail_chain_ptr = &newplug->next;
204
 
205
  /* Record it as current plugin for receiving args.  */
206
  last_plugin = newplug;
207
  last_plugin_args_tail_chain_ptr = &newplug->args;
208
}
209
 
210
/* Accumulate option arguments for last-loaded plugin, or return
211
   error if none.  */
212
int
213
plugin_opt_plugin_arg (const char *arg)
214
{
215
  plugin_arg_t *newarg;
216
 
217
  if (!last_plugin)
218
    return set_plugin_error (_(""));
219
 
220
  newarg = xmalloc (sizeof *newarg);
221
  newarg->arg = arg;
222
  newarg->next = NULL;
223
 
224
  /* Chain on end to preserve command-line order.  */
225
  *last_plugin_args_tail_chain_ptr = newarg;
226
  last_plugin_args_tail_chain_ptr = &newarg->next;
227
  last_plugin->n_args++;
228
  return 0;
229
}
230
 
231
/* Create a dummy BFD.  */
232
bfd *
233
plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
234
{
235
  bfd *abfd;
236
 
237
  bfd_use_reserved_id = 1;
238
  abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *) NULL),
239
		     srctemplate);
240
  if (abfd != NULL)
241
    {
242
      abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN;
243
      bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
244
      bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate));
245
      if (bfd_make_writable (abfd)
246
	  && bfd_copy_private_bfd_data (srctemplate, abfd))
247
	{
248
	  flagword flags;
249
 
250
	  /* Create section to own the symbols.  */
251
	  flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
252
		   | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE);
253
	  if (bfd_make_section_anyway_with_flags (abfd, ".text", flags))
254
	    return abfd;
255
	}
256
    }
257
  einfo (_("could not create dummy IR bfd: %F%E\n"));
258
  return NULL;
259
}
260
 
261
/* Check if the BFD passed in is an IR dummy object file.  */
262
static bfd_boolean
263
is_ir_dummy_bfd (const bfd *abfd)
264
{
265
  /* ABFD can sometimes legitimately be NULL, e.g. when called from one
266
     of the linker callbacks for a symbol in the *ABS* or *UND* sections.
267
     Likewise, the usrdata field may be NULL if ABFD was added by the
268
     backend without a corresponding input statement, as happens e.g.
269
     when processing DT_NEEDED dependencies.  */
270
  return (abfd
271
	  && abfd->usrdata
272
	  && ((lang_input_statement_type *)(abfd->usrdata))->flags.claimed);
273
}
274
 
275
/* Helpers to convert between BFD and GOLD symbol formats.  */
276
static enum ld_plugin_status
277
asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
278
			    const struct ld_plugin_symbol *ldsym)
279
{
280
  flagword flags = BSF_NO_FLAGS;
281
  struct bfd_section *section;
282
 
283
  asym->the_bfd = abfd;
284
  asym->name = (ldsym->version
285
		? concat (ldsym->name, "@", ldsym->version, (const char *) NULL)
286
		: ldsym->name);
287
  asym->value = 0;
288
  switch (ldsym->def)
289
    {
290
    case LDPK_WEAKDEF:
291
      flags = BSF_WEAK;
292
      /* FALLTHRU */
293
    case LDPK_DEF:
294
      flags |= BSF_GLOBAL;
295
      if (ldsym->comdat_key)
296
	{
297
	  char *name = concat (".gnu.linkonce.t.", ldsym->comdat_key,
298
			       (const char *) NULL);
299
	  section = bfd_get_section_by_name (abfd, name);
300
	  if (section != NULL)
301
	    free (name);
302
	  else
303
	    {
304
	      flagword sflags;
305
 
306
	      sflags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
307
			| SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE
308
			| SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD);
309
	      section = bfd_make_section_anyway_with_flags (abfd, name, sflags);
310
	      if (section == NULL)
311
		return LDPS_ERR;
312
	    }
313
	}
314
      else
315
	section = bfd_get_section_by_name (abfd, ".text");
316
      break;
317
 
318
    case LDPK_WEAKUNDEF:
319
      flags = BSF_WEAK;
320
      /* FALLTHRU */
321
    case LDPK_UNDEF:
322
      section = bfd_und_section_ptr;
323
      break;
324
 
325
    case LDPK_COMMON:
326
      flags = BSF_GLOBAL;
327
      section = bfd_com_section_ptr;
328
      asym->value = ldsym->size;
329
      /* For ELF targets, set alignment of common symbol to 1.  */
330
      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
331
	{
332
	  ((elf_symbol_type *) asym)->internal_elf_sym.st_shndx = SHN_COMMON;
333
	  ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
334
	}
335
      break;
336
 
337
    default:
338
      return LDPS_ERR;
339
    }
340
  asym->flags = flags;
341
  asym->section = section;
342
 
343
  /* Visibility only applies on ELF targets.  */
344
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
345
    {
346
      elf_symbol_type *elfsym = elf_symbol_from (abfd, asym);
347
      unsigned char visibility;
348
 
349
      if (!elfsym)
350
	einfo (_("%P%F: %s: non-ELF symbol in ELF BFD!\n"), asym->name);
351
      switch (ldsym->visibility)
352
	{
353
	default:
354
	  einfo (_("%P%F: unknown ELF symbol visibility: %d!\n"),
355
		 ldsym->visibility);
356
	case LDPV_DEFAULT:
357
	  visibility = STV_DEFAULT;
358
	  break;
359
	case LDPV_PROTECTED:
360
	  visibility = STV_PROTECTED;
361
	  break;
362
	case LDPV_INTERNAL:
363
	  visibility = STV_INTERNAL;
364
	  break;
365
	case LDPV_HIDDEN:
366
	  visibility = STV_HIDDEN;
367
	  break;
368
	}
369
      elfsym->internal_elf_sym.st_other
370
	= (visibility | (elfsym->internal_elf_sym.st_other
371
			 & ~ELF_ST_VISIBILITY (-1)));
372
    }
373
 
374
  return LDPS_OK;
375
}
376
 
377
/* Register a claim-file handler.  */
378
static enum ld_plugin_status
379
register_claim_file (ld_plugin_claim_file_handler handler)
380
{
381
  ASSERT (called_plugin);
382
  called_plugin->claim_file_handler = handler;
383
  return LDPS_OK;
384
}
385
 
386
/* Register an all-symbols-read handler.  */
387
static enum ld_plugin_status
388
register_all_symbols_read (ld_plugin_all_symbols_read_handler handler)
389
{
390
  ASSERT (called_plugin);
391
  called_plugin->all_symbols_read_handler = handler;
392
  return LDPS_OK;
393
}
394
 
395
/* Register a cleanup handler.  */
396
static enum ld_plugin_status
397
register_cleanup (ld_plugin_cleanup_handler handler)
398
{
399
  ASSERT (called_plugin);
400
  called_plugin->cleanup_handler = handler;
401
  return LDPS_OK;
402
}
403
 
404
/* Add symbols from a plugin-claimed input file.  */
405
static enum ld_plugin_status
406
add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
407
{
408
  asymbol **symptrs;
409
  bfd *abfd = handle;
410
  int n;
411
 
412
  ASSERT (called_plugin);
413
  symptrs = xmalloc (nsyms * sizeof *symptrs);
414
  for (n = 0; n < nsyms; n++)
415
    {
416
      enum ld_plugin_status rv;
417
      asymbol *bfdsym;
418
 
419
      bfdsym = bfd_make_empty_symbol (abfd);
420
      symptrs[n] = bfdsym;
421
      rv = asymbol_from_plugin_symbol (abfd, bfdsym, syms + n);
422
      if (rv != LDPS_OK)
423
	return rv;
424
    }
425
  bfd_set_symtab (abfd, symptrs, nsyms);
426
  return LDPS_OK;
427
}
428
 
429
/* Get the input file information with an open (possibly re-opened)
430
   file descriptor.  */
431
static enum ld_plugin_status
432
get_input_file (const void *handle ATTRIBUTE_UNUSED,
433
                struct ld_plugin_input_file *file ATTRIBUTE_UNUSED)
434
{
435
  ASSERT (called_plugin);
436
  return LDPS_ERR;
437
}
438
 
439
/* Release the input file.  */
440
static enum ld_plugin_status
441
release_input_file (const void *handle ATTRIBUTE_UNUSED)
442
{
443
  ASSERT (called_plugin);
444
  return LDPS_ERR;
445
}
446
 
447
/* Return TRUE if a defined symbol might be reachable from outside the
448
   universe of claimed objects.  */
449
static inline bfd_boolean
450
is_visible_from_outside (struct ld_plugin_symbol *lsym,
451
			 struct bfd_link_hash_entry *blhe)
452
{
453
  struct bfd_sym_chain *sym;
454
 
455
  if (link_info.relocatable)
456
    return TRUE;
457
  if (link_info.export_dynamic || !link_info.executable)
458
    {
459
      /* Check if symbol is hidden by version script.  */
460
      if (bfd_hide_sym_by_version (link_info.version_info,
461
				   blhe->root.string))
462
	return FALSE;
463
      /* Only ELF symbols really have visibility.  */
464
      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
465
	{
466
	  struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe;
467
	  int vis = ELF_ST_VISIBILITY (el->other);
468
	  return vis == STV_DEFAULT || vis == STV_PROTECTED;
469
	}
470
      /* On non-ELF targets, we can safely make inferences by considering
471
	 what visibility the plugin would have liked to apply when it first
472
	 sent us the symbol.  During ELF symbol processing, visibility only
473
	 ever becomes more restrictive, not less, when symbols are merged,
474
	 so this is a conservative estimate; it may give false positives,
475
	 declaring something visible from outside when it in fact would
476
	 not have been, but this will only lead to missed optimisation
477
	 opportunities during LTRANS at worst; it will not give false
478
	 negatives, which can lead to the disastrous conclusion that the
479
	 related symbol is IRONLY.  (See GCC PR46319 for an example.)  */
480
      return (lsym->visibility == LDPV_DEFAULT
481
	      || lsym->visibility == LDPV_PROTECTED);
482
    }
483
 
484
  for (sym = &entry_symbol; sym != NULL; sym = sym->next)
485
    if (sym->name
486
	&& strcmp (sym->name, blhe->root.string) == 0)
487
      return TRUE;
488
 
489
  return FALSE;
490
}
491
 
492
/* Get the symbol resolution info for a plugin-claimed input file.  */
493
static enum ld_plugin_status
494
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
495
	     int def_ironly_exp)
496
{
497
  const bfd *abfd = handle;
498
  int n;
499
 
500
  ASSERT (called_plugin);
501
  for (n = 0; n < nsyms; n++)
502
    {
503
      struct bfd_link_hash_entry *blhe;
504
      asection *owner_sec;
505
      int res;
506
 
507
      if (syms[n].def != LDPK_UNDEF)
508
	blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
509
				     FALSE, FALSE, TRUE);
510
      else
511
	blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
512
					     syms[n].name, FALSE, FALSE, TRUE);
513
      if (!blhe)
514
	{
515
	  res = LDPR_UNKNOWN;
516
	  goto report_symbol;
517
	}
518
 
519
      /* Determine resolution from blhe type and symbol's original type.  */
520
      if (blhe->type == bfd_link_hash_undefined
521
	  || blhe->type == bfd_link_hash_undefweak)
522
	{
523
	  res = LDPR_UNDEF;
524
	  goto report_symbol;
525
	}
526
      if (blhe->type != bfd_link_hash_defined
527
	  && blhe->type != bfd_link_hash_defweak
528
	  && blhe->type != bfd_link_hash_common)
529
	{
530
	  /* We should not have a new, indirect or warning symbol here.  */
531
	  einfo ("%P%F: %s: plugin symbol table corrupt (sym type %d)\n",
532
		 called_plugin->name, blhe->type);
533
	}
534
 
535
      /* Find out which section owns the symbol.  Since it's not undef,
536
	 it must have an owner; if it's not a common symbol, both defs
537
	 and weakdefs keep it in the same place. */
538
      owner_sec = (blhe->type == bfd_link_hash_common
539
		   ? blhe->u.c.p->section
540
		   : blhe->u.def.section);
541
 
542
 
543
      /* If it was originally undefined or common, then it has been
544
	 resolved; determine how.  */
545
      if (syms[n].def == LDPK_UNDEF
546
	  || syms[n].def == LDPK_WEAKUNDEF
547
	  || syms[n].def == LDPK_COMMON)
548
	{
549
	  if (owner_sec->owner == link_info.output_bfd)
550
	    res = LDPR_RESOLVED_EXEC;
551
	  else if (owner_sec->owner == abfd)
552
	    res = LDPR_PREVAILING_DEF_IRONLY;
553
	  else if (is_ir_dummy_bfd (owner_sec->owner))
554
	    res = LDPR_RESOLVED_IR;
555
	  else if (owner_sec->owner != NULL
556
		   && (owner_sec->owner->flags & DYNAMIC) != 0)
557
	    res = LDPR_RESOLVED_DYN;
558
	  else
559
	    res = LDPR_RESOLVED_EXEC;
560
	}
561
 
562
      /* Was originally def, or weakdef.  Does it prevail?  If the
563
	 owner is the original dummy bfd that supplied it, then this
564
	 is the definition that has prevailed.  */
565
      else if (owner_sec->owner == link_info.output_bfd)
566
	res = LDPR_PREEMPTED_REG;
567
      else if (owner_sec->owner == abfd)
568
	res = LDPR_PREVAILING_DEF_IRONLY;
569
 
570
      /* Was originally def, weakdef, or common, but has been pre-empted.  */
571
      else if (is_ir_dummy_bfd (owner_sec->owner))
572
	res = LDPR_PREEMPTED_IR;
573
      else
574
	res = LDPR_PREEMPTED_REG;
575
 
576
      if (res == LDPR_PREVAILING_DEF_IRONLY)
577
	{
578
	  /* We need to know if the sym is referenced from non-IR files.  Or
579
	     even potentially-referenced, perhaps in a future final link if
580
	     this is a partial one, perhaps dynamically at load-time if the
581
	     symbol is externally visible.  */
582
	  if (blhe->non_ir_ref)
583
	    res = LDPR_PREVAILING_DEF;
584
	  else if (is_visible_from_outside (&syms[n], blhe))
585
	    res = def_ironly_exp;
586
	}
587
 
588
    report_symbol:
589
      syms[n].resolution = res;
590
      if (report_plugin_symbols)
591
	einfo (_("%P: %B: symbol `%s' "
592
		 "definition: %d, visibility: %d, resolution: %d\n"),
593
	       abfd, syms[n].name,
594
	       syms[n].def, syms[n].visibility, res);
595
    }
596
  return LDPS_OK;
597
}
598
 
599
static enum ld_plugin_status
600
get_symbols_v1 (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
601
{
602
  return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF);
603
}
604
 
605
static enum ld_plugin_status
606
get_symbols_v2 (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
607
{
608
  return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF_IRONLY_EXP);
609
}
610
 
611
/* Add a new (real) input file generated by a plugin.  */
612
static enum ld_plugin_status
613
add_input_file (const char *pathname)
614
{
615
  ASSERT (called_plugin);
616
  if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_file_enum,
617
			    NULL))
618
    return LDPS_ERR;
619
  return LDPS_OK;
620
}
621
 
622
/* Add a new (real) library required by a plugin.  */
623
static enum ld_plugin_status
624
add_input_library (const char *pathname)
625
{
626
  ASSERT (called_plugin);
627
  if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_l_enum,
628
			    NULL))
629
    return LDPS_ERR;
630
  return LDPS_OK;
631
}
632
 
633
/* Set the extra library path to be used by libraries added via
634
   add_input_library.  */
635
static enum ld_plugin_status
636
set_extra_library_path (const char *path)
637
{
638
  ASSERT (called_plugin);
639
  ldfile_add_library_path (xstrdup (path), FALSE);
640
  return LDPS_OK;
641
}
642
 
643
/* Issue a diagnostic message from a plugin.  */
644
static enum ld_plugin_status
645
message (int level, const char *format, ...)
646
{
647
  va_list args;
648
  va_start (args, format);
649
 
650
  switch (level)
651
    {
652
    case LDPL_INFO:
653
      vfinfo (stdout, format, args, FALSE);
654
      putchar ('\n');
655
      break;
656
    case LDPL_WARNING:
657
      vfinfo (stdout, format, args, TRUE);
658
      putchar ('\n');
659
      break;
660
    case LDPL_FATAL:
661
    case LDPL_ERROR:
662
    default:
663
      {
664
	char *newfmt = ACONCAT ((level == LDPL_FATAL ? "%P%F: " : "%P%X: ",
665
				 format, "\n", (const char *) NULL));
666
	fflush (stdout);
667
	vfinfo (stderr, newfmt, args, TRUE);
668
	fflush (stderr);
669
      }
670
      break;
671
    }
672
 
673
  va_end (args);
674
  return LDPS_OK;
675
}
676
 
677
/* Helper to size leading part of tv array and set it up. */
678
static void
679
set_tv_header (struct ld_plugin_tv *tv)
680
{
681
  size_t i;
682
 
683
  /* Version info.  */
684
  static const unsigned int major = (unsigned)(BFD_VERSION / 100000000UL);
685
  static const unsigned int minor = (unsigned)(BFD_VERSION / 1000000UL) % 100;
686
 
687
  for (i = 0; i < tv_header_size; i++)
688
    {
689
      tv[i].tv_tag = tv_header_tags[i];
690
#define TVU(x) tv[i].tv_u.tv_ ## x
691
      switch (tv[i].tv_tag)
692
	{
693
	case LDPT_MESSAGE:
694
	  TVU(message) = message;
695
	  break;
696
	case LDPT_API_VERSION:
697
	  TVU(val) = LD_PLUGIN_API_VERSION;
698
	  break;
699
	case LDPT_GNU_LD_VERSION:
700
	  TVU(val) = major * 100 + minor;
701
	  break;
702
	case LDPT_LINKER_OUTPUT:
703
	  TVU(val) = (link_info.relocatable
704
		      ? LDPO_REL
705
		      : (link_info.executable
706
			 ? (link_info.pie ? LDPO_PIE : LDPO_EXEC)
707
			 : LDPO_DYN));
708
	  break;
709
	case LDPT_OUTPUT_NAME:
710
	  TVU(string) = output_filename;
711
	  break;
712
	case LDPT_REGISTER_CLAIM_FILE_HOOK:
713
	  TVU(register_claim_file) = register_claim_file;
714
	  break;
715
	case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
716
	  TVU(register_all_symbols_read) = register_all_symbols_read;
717
	  break;
718
	case LDPT_REGISTER_CLEANUP_HOOK:
719
	  TVU(register_cleanup) = register_cleanup;
720
	  break;
721
	case LDPT_ADD_SYMBOLS:
722
	  TVU(add_symbols) = add_symbols;
723
	  break;
724
	case LDPT_GET_INPUT_FILE:
725
	  TVU(get_input_file) = get_input_file;
726
	  break;
727
	case LDPT_RELEASE_INPUT_FILE:
728
	  TVU(release_input_file) = release_input_file;
729
	  break;
730
	case LDPT_GET_SYMBOLS:
731
	  TVU(get_symbols) = get_symbols_v1;
732
	  break;
733
	case LDPT_GET_SYMBOLS_V2:
734
	  TVU(get_symbols) = get_symbols_v2;
735
	  break;
736
	case LDPT_ADD_INPUT_FILE:
737
	  TVU(add_input_file) = add_input_file;
738
	  break;
739
	case LDPT_ADD_INPUT_LIBRARY:
740
	  TVU(add_input_library) = add_input_library;
741
	  break;
742
	case LDPT_SET_EXTRA_LIBRARY_PATH:
743
	  TVU(set_extra_library_path) = set_extra_library_path;
744
	  break;
745
	default:
746
	  /* Added a new entry to the array without adding
747
	     a new case to set up its value is a bug.  */
748
	  FAIL ();
749
	}
750
#undef TVU
751
    }
752
}
753
 
754
/* Append the per-plugin args list and trailing LDPT_NULL to tv.  */
755
static void
756
set_tv_plugin_args (plugin_t *plugin, struct ld_plugin_tv *tv)
757
{
758
  plugin_arg_t *arg = plugin->args;
759
  while (arg)
760
    {
761
      tv->tv_tag = LDPT_OPTION;
762
      tv->tv_u.tv_string = arg->arg;
763
      arg = arg->next;
764
      tv++;
765
    }
766
  tv->tv_tag = LDPT_NULL;
767
  tv->tv_u.tv_val = 0;
768
}
769
 
770
/* Return true if any plugins are active this run.  Only valid
771
   after options have been processed.  */
772
bfd_boolean
773
plugin_active_plugins_p (void)
774
{
775
  return plugins_list != NULL;
776
}
777
 
778
/* Load up and initialise all plugins after argument parsing.  */
779
void
780
plugin_load_plugins (void)
781
{
782
  struct ld_plugin_tv *my_tv;
783
  unsigned int max_args = 0;
784
  plugin_t *curplug = plugins_list;
785
 
786
  /* If there are no plugins, we need do nothing this run.  */
787
  if (!curplug)
788
    return;
789
 
790
  /* First pass over plugins to find max # args needed so that we
791
     can size and allocate the tv array.  */
792
  while (curplug)
793
    {
794
      if (curplug->n_args > max_args)
795
	max_args = curplug->n_args;
796
      curplug = curplug->next;
797
    }
798
 
799
  /* Allocate tv array and initialise constant part.  */
800
  my_tv = xmalloc ((max_args + 1 + tv_header_size) * sizeof *my_tv);
801
  set_tv_header (my_tv);
802
 
803
  /* Pass over plugins again, activating them.  */
804
  curplug = plugins_list;
805
  while (curplug)
806
    {
807
      enum ld_plugin_status rv;
808
      ld_plugin_onload onloadfn;
809
 
810
      onloadfn = (ld_plugin_onload) dlsym (curplug->dlhandle, "onload");
811
      if (!onloadfn)
812
	onloadfn = (ld_plugin_onload) dlsym (curplug->dlhandle, "_onload");
813
      if (!onloadfn)
814
        einfo (_("%P%F: %s: error loading plugin: %s\n"),
815
	       curplug->name, dlerror ());
816
      set_tv_plugin_args (curplug, &my_tv[tv_header_size]);
817
      called_plugin = curplug;
818
      rv = (*onloadfn) (my_tv);
819
      called_plugin = NULL;
820
      if (rv != LDPS_OK)
821
	einfo (_("%P%F: %s: plugin error: %d\n"), curplug->name, rv);
822
      curplug = curplug->next;
823
    }
824
 
825
  /* Since plugin(s) inited ok, assume they're going to want symbol
826
     resolutions, which needs us to track which symbols are referenced
827
     by non-IR files using the linker's notice callback.  */
828
  orig_notice_all = link_info.notice_all;
829
  orig_callbacks = link_info.callbacks;
830
  plugin_callbacks = *orig_callbacks;
831
  plugin_callbacks.notice = &plugin_notice;
832
  link_info.notice_all = TRUE;
833
  link_info.callbacks = &plugin_callbacks;
834
}
835
 
836
/* Call 'claim file' hook for all plugins.  */
837
static int
838
plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
839
{
840
  plugin_t *curplug = plugins_list;
841
  *claimed = FALSE;
842
  if (no_more_claiming)
843
    return 0;
844
  while (curplug && !*claimed)
845
    {
846
      if (curplug->claim_file_handler)
847
	{
848
	  enum ld_plugin_status rv;
849
	  called_plugin = curplug;
850
	  rv = (*curplug->claim_file_handler) (file, claimed);
851
	  called_plugin = NULL;
852
	  if (rv != LDPS_OK)
853
	    set_plugin_error (curplug->name);
854
	}
855
      curplug = curplug->next;
856
    }
857
  return plugin_error_p () ? -1 : 0;
858
}
859
 
860
void
861
plugin_maybe_claim (struct ld_plugin_input_file *file,
862
		    lang_input_statement_type *entry)
863
{
864
  int claimed = 0;
865
 
866
  /* We create a dummy BFD, initially empty, to house whatever symbols
867
     the plugin may want to add.  */
868
  file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename,
869
					  entry->the_bfd);
870
  if (plugin_call_claim_file (file, &claimed))
871
    einfo (_("%P%F: %s: plugin reported error claiming file\n"),
872
	   plugin_error_plugin ());
873
  /* fd belongs to us, not the plugin; but we don't need it.  */
874
  close (file->fd);
875
  if (claimed)
876
    {
877
      /* Discard the real file's BFD and substitute the dummy one.  */
878
 
879
      /* BFD archive handling caches elements so we can't call
880
	 bfd_close for archives.  */
881
      if (entry->the_bfd->my_archive == NULL)
882
	bfd_close (entry->the_bfd);
883
      entry->the_bfd = file->handle;
884
      entry->flags.claimed = TRUE;
885
      bfd_make_readable (entry->the_bfd);
886
    }
887
  else
888
    {
889
      /* If plugin didn't claim the file, we don't need the dummy bfd.
890
	 Can't avoid speculatively creating it, alas.  */
891
      bfd_close_all_done (file->handle);
892
      entry->flags.claimed = FALSE;
893
    }
894
}
895
 
896
/* Call 'all symbols read' hook for all plugins.  */
897
int
898
plugin_call_all_symbols_read (void)
899
{
900
  plugin_t *curplug = plugins_list;
901
 
902
  /* Disable any further file-claiming.  */
903
  no_more_claiming = TRUE;
904
 
905
  while (curplug)
906
    {
907
      if (curplug->all_symbols_read_handler)
908
	{
909
	  enum ld_plugin_status rv;
910
	  called_plugin = curplug;
911
	  rv = (*curplug->all_symbols_read_handler) ();
912
	  called_plugin = NULL;
913
	  if (rv != LDPS_OK)
914
	    set_plugin_error (curplug->name);
915
	}
916
      curplug = curplug->next;
917
    }
918
  return plugin_error_p () ? -1 : 0;
919
}
920
 
921
/* Call 'cleanup' hook for all plugins at exit.  */
922
void
923
plugin_call_cleanup (void)
924
{
925
  plugin_t *curplug = plugins_list;
926
  while (curplug)
927
    {
928
      if (curplug->cleanup_handler && !curplug->cleanup_done)
929
	{
930
	  enum ld_plugin_status rv;
931
	  curplug->cleanup_done = TRUE;
932
	  called_plugin = curplug;
933
	  rv = (*curplug->cleanup_handler) ();
934
	  called_plugin = NULL;
935
	  if (rv != LDPS_OK)
936
	    info_msg (_("%P: %s: error in plugin cleanup: %d (ignored)\n"),
937
		      curplug->name, rv);
938
	  dlclose (curplug->dlhandle);
939
	}
940
      curplug = curplug->next;
941
    }
942
}
943
 
944
/* To determine which symbols should be resolved LDPR_PREVAILING_DEF
945
   and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
946
   the linker adds them to the linker hash table.  Mark those
947
   referenced from a non-IR file with non_ir_ref.  We have to
948
   notice_all symbols, because we won't necessarily know until later
949
   which ones will be contributed by IR files.  */
950
static bfd_boolean
951
plugin_notice (struct bfd_link_info *info,
952
	       struct bfd_link_hash_entry *h,
953
	       bfd *abfd,
954
	       asection *section,
955
	       bfd_vma value,
956
	       flagword flags,
957
	       const char *string)
958
{
959
  if (h != NULL)
960
    {
961
      bfd *sym_bfd;
962
 
963
      /* Nothing to do here if this def/ref is from an IR dummy BFD.  */
964
      if (is_ir_dummy_bfd (abfd))
965
	;
966
 
967
      /* Making an indirect symbol counts as a reference unless this
968
	 is a brand new symbol.  */
969
      else if (bfd_is_ind_section (section)
970
	       || (flags & BSF_INDIRECT) != 0)
971
	{
972
	  if (h->type != bfd_link_hash_new)
973
	    {
974
	      struct bfd_link_hash_entry *inh;
975
 
976
	      h->non_ir_ref = TRUE;
977
	      inh = bfd_wrapped_link_hash_lookup (abfd, info, string, FALSE,
978
						  FALSE, FALSE);
979
	      if (inh != NULL)
980
		inh->non_ir_ref = TRUE;
981
	    }
982
	}
983
 
984
      /* Nothing to do here for warning symbols.  */
985
      else if ((flags & BSF_WARNING) != 0)
986
	;
987
 
988
      /* Nothing to do here for constructor symbols.  */
989
      else if ((flags & BSF_CONSTRUCTOR) != 0)
990
	;
991
 
992
      /* If this is a ref, set non_ir_ref.  */
993
      else if (bfd_is_und_section (section))
994
	{
995
	  /* Replace the undefined dummy bfd with the real one.  */
996
	  if ((h->type == bfd_link_hash_undefined
997
	       || h->type == bfd_link_hash_undefweak)
998
	      && (h->u.undef.abfd == NULL
999
		  || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
1000
	    h->u.undef.abfd = abfd;
1001
	  h->non_ir_ref = TRUE;
1002
	}
1003
 
1004
      /* Otherwise, it must be a new def.  Ensure any symbol defined
1005
	 in an IR dummy BFD takes on a new value from a real BFD.
1006
	 Weak symbols are not normally overridden by a new weak
1007
	 definition, and strong symbols will normally cause multiple
1008
	 definition errors.  Avoid this by making the symbol appear
1009
	 to be undefined.  */
1010
      else if (((h->type == bfd_link_hash_defweak
1011
		 || h->type == bfd_link_hash_defined)
1012
		&& is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
1013
	       || (h->type == bfd_link_hash_common
1014
		   && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
1015
	{
1016
	  h->type = bfd_link_hash_undefweak;
1017
	  h->u.undef.abfd = sym_bfd;
1018
	}
1019
    }
1020
 
1021
  /* Continue with cref/nocrossref/trace-sym processing.  */
1022
  if (h == NULL
1023
      || orig_notice_all
1024
      || (info->notice_hash != NULL
1025
	  && bfd_hash_lookup (info->notice_hash, h->root.string,
1026
			      FALSE, FALSE) != NULL))
1027
    return (*orig_callbacks->notice) (info, h,
1028
				      abfd, section, value, flags, string);
1029
  return TRUE;
1030
}
1031
 
1032
/* Return true if bfd is a dynamic library that should be reloaded.  */
1033
 
1034
bfd_boolean
1035
plugin_should_reload (bfd *abfd)
1036
{
1037
  return ((abfd->flags & DYNAMIC) != 0
1038
	  && bfd_get_flavour (abfd) == bfd_target_elf_flavour
1039
	  && bfd_get_format (abfd) == bfd_object
1040
	  && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
1041
}