Subversion Repositories Kolibri OS

Rev

Rev 5199 | Details | Compare with Previous | Last modification | View Log | RSS feed

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