Subversion Repositories Kolibri OS

Rev

Rev 5199 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5199 Rev 6324
Line 1... Line 1...
1
/* Plugin control for the GNU linker.
1
/* Plugin control for the GNU linker.
2
   Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
2
   Copyright (C) 2010-2015 Free Software Foundation, Inc.
Line 3... Line 3...
3
 
3
 
Line 4... Line 4...
4
   This file is part of the GNU Binutils.
4
   This file is part of the GNU Binutils.
5
 
5
 
Line 19... Line 19...
19
   MA 02110-1301, USA.  */
19
   MA 02110-1301, USA.  */
Line 20... Line 20...
20
 
20
 
21
#include "sysdep.h"
21
#include "sysdep.h"
22
#include "libiberty.h"
22
#include "libiberty.h"
-
 
23
#include "bfd.h"
23
#include "bfd.h"
24
#include "libbfd.h"
24
#include "bfdlink.h"
25
#include "bfdlink.h"
25
#include "bfdver.h"
26
#include "bfdver.h"
26
#include "ld.h"
27
#include "ld.h"
27
#include "ldmain.h"
28
#include "ldmain.h"
28
#include "ldmisc.h"
29
#include "ldmisc.h"
29
#include "ldexp.h"
30
#include "ldexp.h"
30
#include "ldlang.h"
31
#include "ldlang.h"
-
 
32
#include "ldfile.h"
31
#include "ldfile.h"
33
#include "../bfd/plugin.h"
32
#include "plugin.h"
34
#include "plugin.h"
33
#include "plugin-api.h"
35
#include "plugin-api.h"
34
#include "elf-bfd.h"
36
#include "elf-bfd.h"
35
#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
37
#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
Line 70... Line 72...
70
  ld_plugin_cleanup_handler cleanup_handler;
72
  ld_plugin_cleanup_handler cleanup_handler;
71
  /* TRUE if the cleanup handlers have been called.  */
73
  /* TRUE if the cleanup handlers have been called.  */
72
  bfd_boolean cleanup_done;
74
  bfd_boolean cleanup_done;
73
} plugin_t;
75
} plugin_t;
Line -... Line 76...
-
 
76
 
-
 
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;
74
 
96
 
75
/* The master list of all plugins.  */
97
/* The master list of all plugins.  */
Line 76... Line 98...
76
static plugin_t *plugins_list = NULL;
98
static plugin_t *plugins_list = NULL;
77
 
99
 
Line 112... Line 134...
112
  LDPT_REGISTER_CLAIM_FILE_HOOK,
134
  LDPT_REGISTER_CLAIM_FILE_HOOK,
113
  LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
135
  LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
114
  LDPT_REGISTER_CLEANUP_HOOK,
136
  LDPT_REGISTER_CLEANUP_HOOK,
115
  LDPT_ADD_SYMBOLS,
137
  LDPT_ADD_SYMBOLS,
116
  LDPT_GET_INPUT_FILE,
138
  LDPT_GET_INPUT_FILE,
-
 
139
  LDPT_GET_VIEW,
117
  LDPT_RELEASE_INPUT_FILE,
140
  LDPT_RELEASE_INPUT_FILE,
118
  LDPT_GET_SYMBOLS,
141
  LDPT_GET_SYMBOLS,
119
  LDPT_GET_SYMBOLS_V2,
142
  LDPT_GET_SYMBOLS_V2,
120
  LDPT_ADD_INPUT_FILE,
143
  LDPT_ADD_INPUT_FILE,
121
  LDPT_ADD_INPUT_LIBRARY,
144
  LDPT_ADD_INPUT_LIBRARY,
Line 125... Line 148...
125
/* How many entries in the constant leading part of the tv array.  */
148
/* 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);
149
static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
Line 127... Line 150...
127
 
150
 
128
/* Forward references.  */
151
/* Forward references.  */
-
 
152
static bfd_boolean plugin_notice (struct bfd_link_info *,
129
static bfd_boolean plugin_notice (struct bfd_link_info *,
153
				  struct bfd_link_hash_entry *,
130
				  struct bfd_link_hash_entry *, bfd *,
154
				  struct bfd_link_hash_entry *,
-
 
155
				  bfd *, asection *, bfd_vma, flagword);
-
 
156
 
Line 131... Line 157...
131
				  asection *, bfd_vma, flagword, const char *);
157
static const bfd_target * plugin_object_p (bfd *);
Line 132... Line 158...
132
 
158
 
Line 215... Line 241...
215
  plugin_arg_t *newarg;
241
  plugin_arg_t *newarg;
Line 216... Line 242...
216
 
242
 
217
  if (!last_plugin)
243
  if (!last_plugin)
Line -... Line 244...
-
 
244
    return set_plugin_error (_(""));
-
 
245
 
-
 
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;
218
    return set_plugin_error (_(""));
255
    }
219
 
256
 
220
  newarg = xmalloc (sizeof *newarg);
257
  newarg = xmalloc (sizeof *newarg);
Line 221... Line 258...
221
  newarg->arg = arg;
258
  newarg->arg = arg;
Line 226... Line 263...
226
  last_plugin_args_tail_chain_ptr = &newarg->next;
263
  last_plugin_args_tail_chain_ptr = &newarg->next;
227
  last_plugin->n_args++;
264
  last_plugin->n_args++;
228
  return 0;
265
  return 0;
229
}
266
}
Line 230... Line 267...
230
 
267
 
-
 
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
231
/* Create a dummy BFD.  */
272
   add_symbols hook has been called so that it can be read when linking.  */
232
bfd *
273
static bfd *
233
plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
274
plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
234
{
275
{
-
 
276
  bfd *abfd;
Line 235... Line 277...
235
  bfd *abfd;
277
  bfd_boolean bfd_plugin_target;
-
 
278
 
236
 
279
  bfd_use_reserved_id = 1;
237
  bfd_use_reserved_id = 1;
280
  bfd_plugin_target = bfd_plugin_target_p (srctemplate->xvec);
238
  abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *) NULL),
281
  abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *) NULL),
239
		     srctemplate);
282
		     bfd_plugin_target ? link_info.output_bfd : srctemplate);
240
  if (abfd != NULL)
283
  if (abfd != NULL)
-
 
284
    {
-
 
285
      abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN;
-
 
286
      if (!bfd_make_writable (abfd))
-
 
287
	goto report_error;
241
    {
288
      if (!bfd_plugin_target)
242
      abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN;
289
	{
243
      bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
-
 
244
      bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate));
290
      bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
-
 
291
      bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate));
-
 
292
	  if (!bfd_copy_private_bfd_data (srctemplate, abfd))
245
      if (bfd_make_writable (abfd)
293
	    goto report_error;
246
	  && bfd_copy_private_bfd_data (srctemplate, abfd))
294
	}
Line 247... Line 295...
247
	{
295
	{
248
	  flagword flags;
296
	  flagword flags;
249
 
297
 
250
	  /* Create section to own the symbols.  */
298
	  /* Create section to own the symbols.  */
251
	  flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
299
	  flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
252
		   | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE);
300
		   | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE);
253
	  if (bfd_make_section_anyway_with_flags (abfd, ".text", flags))
301
	  if (bfd_make_section_anyway_with_flags (abfd, ".text", flags))
-
 
302
	    return abfd;
254
	    return abfd;
303
	}
255
	}
304
    }
256
    }
305
report_error:
Line 257... Line 306...
257
  einfo (_("could not create dummy IR bfd: %F%E\n"));
306
  einfo (_("could not create dummy IR bfd: %F%E\n"));
258
  return NULL;
307
  return NULL;
259
}
308
}
260
 
309
 
261
/* Check if the BFD passed in is an IR dummy object file.  */
310
/* Check if the BFD passed in is an IR dummy object file.  */
262
static bfd_boolean
311
static inline bfd_boolean
263
is_ir_dummy_bfd (const bfd *abfd)
312
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.  */
313
{
Line 270... Line 314...
270
  return (abfd
314
  /* ABFD can sometimes legitimately be NULL, e.g. when called from one
271
	  && abfd->usrdata
315
     of the linker callbacks for a symbol in the *ABS* or *UND* sections.  */
272
	  && ((lang_input_statement_type *)(abfd->usrdata))->flags.claimed);
316
  return abfd != NULL && (abfd->flags & BFD_PLUGIN) != 0;
Line 404... Line 448...
404
/* Add symbols from a plugin-claimed input file.  */
448
/* Add symbols from a plugin-claimed input file.  */
405
static enum ld_plugin_status
449
static enum ld_plugin_status
406
add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
450
add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
407
{
451
{
408
  asymbol **symptrs;
452
  asymbol **symptrs;
-
 
453
  plugin_input_file_t *input = handle;
409
  bfd *abfd = handle;
454
  bfd *abfd = input->abfd;
410
  int n;
455
  int n;
Line 411... Line 456...
411
 
456
 
412
  ASSERT (called_plugin);
457
  ASSERT (called_plugin);
413
  symptrs = xmalloc (nsyms * sizeof *symptrs);
458
  symptrs = xmalloc (nsyms * sizeof *symptrs);
Line 427... Line 472...
427
}
472
}
Line 428... Line 473...
428
 
473
 
429
/* Get the input file information with an open (possibly re-opened)
474
/* Get the input file information with an open (possibly re-opened)
430
   file descriptor.  */
475
   file descriptor.  */
431
static enum ld_plugin_status
476
static enum ld_plugin_status
-
 
477
get_input_file (const void *handle, struct ld_plugin_input_file *file)
432
get_input_file (const void *handle ATTRIBUTE_UNUSED,
478
{
-
 
479
  const plugin_input_file_t *input = handle;
-
 
480
 
-
 
481
  ASSERT (called_plugin);
-
 
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
433
                struct ld_plugin_input_file *file ATTRIBUTE_UNUSED)
493
get_view (const void *handle, const void **viewp)
434
{
494
{
435
  ASSERT (called_plugin);
495
  ASSERT (called_plugin);
436
  return LDPS_ERR;
496
  return LDPS_ERR;
Line 437... Line 497...
437
}
497
}
438
 
498
 
439
/* Release the input file.  */
499
/* Release the input file.  */
440
static enum ld_plugin_status
500
static enum ld_plugin_status
441
release_input_file (const void *handle ATTRIBUTE_UNUSED)
501
release_input_file (const void *handle)
442
{
502
{
443
  ASSERT (called_plugin);
503
  ASSERT (called_plugin);
Line 450... Line 510...
450
is_visible_from_outside (struct ld_plugin_symbol *lsym,
510
is_visible_from_outside (struct ld_plugin_symbol *lsym,
451
			 struct bfd_link_hash_entry *blhe)
511
			 struct bfd_link_hash_entry *blhe)
452
{
512
{
453
  struct bfd_sym_chain *sym;
513
  struct bfd_sym_chain *sym;
Line 454... Line 514...
454
 
514
 
455
  if (link_info.relocatable)
515
  if (bfd_link_relocatable (&link_info))
456
    return TRUE;
516
    return TRUE;
457
  if (link_info.export_dynamic || !link_info.executable)
517
  if (link_info.export_dynamic || bfd_link_dll (&link_info))
458
    {
518
    {
459
      /* Check if symbol is hidden by version script.  */
519
      /* Check if symbol is hidden by version script.  */
460
      if (bfd_hide_sym_by_version (link_info.version_info,
520
      if (bfd_hide_sym_by_version (link_info.version_info,
461
				   blhe->root.string))
521
				   blhe->root.string))
Line 492... Line 552...
492
/* Get the symbol resolution info for a plugin-claimed input file.  */
552
/* Get the symbol resolution info for a plugin-claimed input file.  */
493
static enum ld_plugin_status
553
static enum ld_plugin_status
494
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
554
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
495
	     int def_ironly_exp)
555
	     int def_ironly_exp)
496
{
556
{
-
 
557
  const plugin_input_file_t *input = handle;
497
  const bfd *abfd = handle;
558
  const bfd *abfd = (const bfd *) input->abfd;
498
  int n;
559
  int n;
Line 499... Line 560...
499
 
560
 
500
  ASSERT (called_plugin);
561
  ASSERT (called_plugin);
501
  for (n = 0; n < nsyms; n++)
562
  for (n = 0; n < nsyms; n++)
Line 610... Line 671...
610
 
671
 
611
/* Add a new (real) input file generated by a plugin.  */
672
/* Add a new (real) input file generated by a plugin.  */
612
static enum ld_plugin_status
673
static enum ld_plugin_status
613
add_input_file (const char *pathname)
674
add_input_file (const char *pathname)
-
 
675
{
-
 
676
  lang_input_statement_type *is;
614
{
677
 
615
  ASSERT (called_plugin);
678
  ASSERT (called_plugin);
616
  if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_file_enum,
679
  is = lang_add_input_file (xstrdup (pathname), lang_input_file_is_file_enum,
-
 
680
			    NULL);
617
			    NULL))
681
  if (!is)
-
 
682
    return LDPS_ERR;
618
    return LDPS_ERR;
683
  is->flags.lto_output = 1;
619
  return LDPS_OK;
684
  return LDPS_OK;
Line 620... Line 685...
620
}
685
}
621
 
686
 
622
/* Add a new (real) library required by a plugin.  */
687
/* Add a new (real) library required by a plugin.  */
623
static enum ld_plugin_status
688
static enum ld_plugin_status
-
 
689
add_input_library (const char *pathname)
-
 
690
{
624
add_input_library (const char *pathname)
691
  lang_input_statement_type *is;
625
{
692
 
626
  ASSERT (called_plugin);
693
  ASSERT (called_plugin);
-
 
694
  is = lang_add_input_file (xstrdup (pathname), lang_input_file_is_l_enum,
627
  if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_l_enum,
695
			    NULL);
-
 
696
  if (!is)
628
			    NULL))
697
    return LDPS_ERR;
629
    return LDPS_ERR;
698
  is->flags.lto_output = 1;
Line 630... Line 699...
630
  return LDPS_OK;
699
  return LDPS_OK;
631
}
700
}
Line 652... Line 721...
652
    case LDPL_INFO:
721
    case LDPL_INFO:
653
      vfinfo (stdout, format, args, FALSE);
722
      vfinfo (stdout, format, args, FALSE);
654
      putchar ('\n');
723
      putchar ('\n');
655
      break;
724
      break;
656
    case LDPL_WARNING:
725
    case LDPL_WARNING:
-
 
726
      {
-
 
727
	char *newfmt = ACONCAT (("%P: warning: ", format, "\n",
-
 
728
				 (const char *) NULL));
657
      vfinfo (stdout, format, args, TRUE);
729
	vfinfo (stdout, newfmt, args, TRUE);
658
      putchar ('\n');
730
      }
659
      break;
731
      break;
660
    case LDPL_FATAL:
732
    case LDPL_FATAL:
661
    case LDPL_ERROR:
733
    case LDPL_ERROR:
662
    default:
734
    default:
663
      {
735
      {
664
	char *newfmt = ACONCAT ((level == LDPL_FATAL ? "%P%F: " : "%P%X: ",
736
	char *newfmt = ACONCAT ((level == LDPL_FATAL ? "%P%F" : "%P%X",
-
 
737
				 ": error: ", format, "\n",
665
				 format, "\n", (const char *) NULL));
738
				 (const char *) NULL));
666
	fflush (stdout);
739
	fflush (stdout);
667
	vfinfo (stderr, newfmt, args, TRUE);
740
	vfinfo (stderr, newfmt, args, TRUE);
668
	fflush (stderr);
741
	fflush (stderr);
669
      }
742
      }
670
      break;
743
      break;
Line 698... Line 771...
698
	  break;
771
	  break;
699
	case LDPT_GNU_LD_VERSION:
772
	case LDPT_GNU_LD_VERSION:
700
	  TVU(val) = major * 100 + minor;
773
	  TVU(val) = major * 100 + minor;
701
	  break;
774
	  break;
702
	case LDPT_LINKER_OUTPUT:
775
	case LDPT_LINKER_OUTPUT:
703
	  TVU(val) = (link_info.relocatable
776
	  TVU(val) = (bfd_link_relocatable (&link_info) ? LDPO_REL
704
		      ? LDPO_REL
-
 
705
		      : (link_info.executable
777
		      : bfd_link_pde (&link_info) ? LDPO_EXEC
706
			 ? (link_info.pie ? LDPO_PIE : LDPO_EXEC)
778
		      : bfd_link_pie (&link_info) ? LDPO_PIE
707
			 : LDPO_DYN));
779
		      : LDPO_DYN);
708
	  break;
780
	  break;
709
	case LDPT_OUTPUT_NAME:
781
	case LDPT_OUTPUT_NAME:
710
	  TVU(string) = output_filename;
782
	  TVU(string) = output_filename;
711
	  break;
783
	  break;
712
	case LDPT_REGISTER_CLAIM_FILE_HOOK:
784
	case LDPT_REGISTER_CLAIM_FILE_HOOK:
Line 722... Line 794...
722
	  TVU(add_symbols) = add_symbols;
794
	  TVU(add_symbols) = add_symbols;
723
	  break;
795
	  break;
724
	case LDPT_GET_INPUT_FILE:
796
	case LDPT_GET_INPUT_FILE:
725
	  TVU(get_input_file) = get_input_file;
797
	  TVU(get_input_file) = get_input_file;
726
	  break;
798
	  break;
-
 
799
	case LDPT_GET_VIEW:
-
 
800
	  TVU(get_view) = get_view;
-
 
801
	  break;
727
	case LDPT_RELEASE_INPUT_FILE:
802
	case LDPT_RELEASE_INPUT_FILE:
728
	  TVU(release_input_file) = release_input_file;
803
	  TVU(release_input_file) = release_input_file;
729
	  break;
804
	  break;
730
	case LDPT_GET_SYMBOLS:
805
	case LDPT_GET_SYMBOLS:
731
	  TVU(get_symbols) = get_symbols_v1;
806
	  TVU(get_symbols) = get_symbols_v1;
Line 765... Line 840...
765
    }
840
    }
766
  tv->tv_tag = LDPT_NULL;
841
  tv->tv_tag = LDPT_NULL;
767
  tv->tv_u.tv_val = 0;
842
  tv->tv_u.tv_val = 0;
768
}
843
}
Line 769... Line -...
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
 
844
 
778
/* Load up and initialise all plugins after argument parsing.  */
845
/* Load up and initialise all plugins after argument parsing.  */
779
void
846
void
780
plugin_load_plugins (void)
847
plugin_load_plugins (void)
781
{
848
{
Line 828... Line 895...
828
  orig_notice_all = link_info.notice_all;
895
  orig_notice_all = link_info.notice_all;
829
  orig_callbacks = link_info.callbacks;
896
  orig_callbacks = link_info.callbacks;
830
  plugin_callbacks = *orig_callbacks;
897
  plugin_callbacks = *orig_callbacks;
831
  plugin_callbacks.notice = &plugin_notice;
898
  plugin_callbacks.notice = &plugin_notice;
832
  link_info.notice_all = TRUE;
899
  link_info.notice_all = TRUE;
-
 
900
  link_info.lto_plugin_active = TRUE;
833
  link_info.callbacks = &plugin_callbacks;
901
  link_info.callbacks = &plugin_callbacks;
-
 
902
 
-
 
903
  register_ld_plugin_object_p (plugin_object_p);
-
 
904
 
-
 
905
#if HAVE_MMAP && HAVE_GETPAGESIZE
-
 
906
  plugin_pagesize = getpagesize ();
-
 
907
#endif
834
}
908
}
Line 835... Line 909...
835
 
909
 
836
/* Call 'claim file' hook for all plugins.  */
910
/* Call 'claim file' hook for all plugins.  */
837
static int
911
static int
Line 855... Line 929...
855
      curplug = curplug->next;
929
      curplug = curplug->next;
856
    }
930
    }
857
  return plugin_error_p () ? -1 : 0;
931
  return plugin_error_p () ? -1 : 0;
858
}
932
}
Line -... Line 933...
-
 
933
 
859
 
934
/* Duplicates a character string with memory attached to ABFD.  */
860
void
935
 
861
plugin_maybe_claim (struct ld_plugin_input_file *file,
936
static char *
862
		    lang_input_statement_type *entry)
937
plugin_strdup (bfd *abfd, const char *str)
-
 
938
{
-
 
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
}
-
 
949
 
-
 
950
static const bfd_target *
-
 
951
plugin_object_p (bfd *ibfd)
863
{
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)
Line 864... Line 979...
864
  int claimed = 0;
979
    return NULL;
865
 
980
 
866
  /* We create a dummy BFD, initially empty, to house whatever symbols
981
  /* We create a dummy BFD, initially empty, to house whatever symbols
-
 
982
     the plugin may want to add.  */
-
 
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;
867
     the plugin may want to add.  */
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
 
868
  file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename,
1025
  claimed = 0;
869
					  entry->the_bfd);
1026
 
870
  if (plugin_call_claim_file (file, &claimed))
1027
  if (plugin_call_claim_file (&file, &claimed))
-
 
1028
    einfo (_("%P%F: %s: plugin reported error claiming file\n"),
-
 
1029
	   plugin_error_plugin ());
-
 
1030
 
871
    einfo (_("%P%F: %s: plugin reported error claiming file\n"),
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
872
	   plugin_error_plugin ());
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;
873
  /* fd belongs to us, not the plugin; but we don't need it.  */
1043
    }
874
  close (file->fd);
1044
 
-
 
1045
  if (claimed)
-
 
1046
    {
-
 
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
    {
875
  if (claimed)
1082
      bfd *abfd = entry->the_bfd->plugin_dummy_bfd;
Line 876... Line 1083...
876
    {
1083
 
877
      /* Discard the real file's BFD and substitute the dummy one.  */
1084
      /* Discard the real file's BFD and substitute the dummy one.  */
878
 
1085
 
879
      /* BFD archive handling caches elements so we can't call
1086
      /* BFD archive handling caches elements so we can't call
880
	 bfd_close for archives.  */
1087
	 bfd_close for archives.  */
881
      if (entry->the_bfd->my_archive == NULL)
1088
      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.  */
1089
	bfd_close (entry->the_bfd);
891
      bfd_close_all_done (file->handle);
1090
      entry->the_bfd = abfd;
Line 892... Line 1091...
892
      entry->flags.claimed = FALSE;
1091
      entry->flags.claimed = 1;
893
    }
1092
    }
Line 948... Line 1147...
948
   notice_all symbols, because we won't necessarily know until later
1147
   notice_all symbols, because we won't necessarily know until later
949
   which ones will be contributed by IR files.  */
1148
   which ones will be contributed by IR files.  */
950
static bfd_boolean
1149
static bfd_boolean
951
plugin_notice (struct bfd_link_info *info,
1150
plugin_notice (struct bfd_link_info *info,
952
	       struct bfd_link_hash_entry *h,
1151
	       struct bfd_link_hash_entry *h,
-
 
1152
	       struct bfd_link_hash_entry *inh,
953
	       bfd *abfd,
1153
	       bfd *abfd,
954
	       asection *section,
1154
	       asection *section,
955
	       bfd_vma value,
1155
	       bfd_vma value,
956
	       flagword flags,
1156
	       flagword flags)
957
	       const char *string)
-
 
958
{
1157
{
-
 
1158
  struct bfd_link_hash_entry *orig_h = h;
-
 
1159
 
959
  if (h != NULL)
1160
  if (h != NULL)
960
    {
1161
    {
961
      bfd *sym_bfd;
1162
      bfd *sym_bfd;
Line -... Line 1163...
-
 
1163
 
-
 
1164
      if (h->type == bfd_link_hash_warning)
-
 
1165
	h = h->u.i.link;
962
 
1166
 
963
      /* Nothing to do here if this def/ref is from an IR dummy BFD.  */
1167
      /* Nothing to do here if this def/ref is from an IR dummy BFD.  */
964
      if (is_ir_dummy_bfd (abfd))
1168
      if (is_ir_dummy_bfd (abfd))
Line 965... Line 1169...
965
	;
1169
	;
966
 
1170
 
967
      /* Making an indirect symbol counts as a reference unless this
1171
      /* Making an indirect symbol counts as a reference unless this
968
	 is a brand new symbol.  */
1172
	 is a brand new symbol.  */
969
      else if (bfd_is_ind_section (section)
1173
      else if (bfd_is_ind_section (section)
-
 
1174
	       || (flags & BSF_INDIRECT) != 0)
-
 
1175
	{
970
	       || (flags & BSF_INDIRECT) != 0)
1176
	  /* ??? Some of this is questionable.  See comments in
971
	{
1177
	     _bfd_generic_link_add_one_symbol for case IND.  */
972
	  if (h->type != bfd_link_hash_new)
-
 
973
	    {
-
 
974
	      struct bfd_link_hash_entry *inh;
1178
	  if (h->type != bfd_link_hash_new)
975
 
-
 
976
	      h->non_ir_ref = TRUE;
-
 
977
	      inh = bfd_wrapped_link_hash_lookup (abfd, info, string, FALSE,
-
 
978
						  FALSE, FALSE);
1179
	    {
979
	      if (inh != NULL)
1180
	      h->non_ir_ref = TRUE;
-
 
1181
		inh->non_ir_ref = TRUE;
-
 
1182
	    }
980
		inh->non_ir_ref = TRUE;
1183
	  else if (inh->type == bfd_link_hash_new)
Line 981... Line 1184...
981
	    }
1184
	    inh->non_ir_ref = TRUE;
982
	}
1185
	}
983
 
1186
 
Line 1017... Line 1220...
1017
	  h->u.undef.abfd = sym_bfd;
1220
	  h->u.undef.abfd = sym_bfd;
1018
	}
1221
	}
1019
    }
1222
    }
Line 1020... Line 1223...
1020
 
1223
 
1021
  /* Continue with cref/nocrossref/trace-sym processing.  */
1224
  /* Continue with cref/nocrossref/trace-sym processing.  */
1022
  if (h == NULL
1225
  if (orig_h == NULL
1023
      || orig_notice_all
1226
      || orig_notice_all
1024
      || (info->notice_hash != NULL
1227
      || (info->notice_hash != NULL
1025
	  && bfd_hash_lookup (info->notice_hash, h->root.string,
1228
	  && bfd_hash_lookup (info->notice_hash, orig_h->root.string,
1026
			      FALSE, FALSE) != NULL))
1229
			      FALSE, FALSE) != NULL))
1027
    return (*orig_callbacks->notice) (info, h,
1230
    return (*orig_callbacks->notice) (info, orig_h, inh,
1028
				      abfd, section, value, flags, string);
1231
				      abfd, section, value, flags);
1029
  return TRUE;
1232
  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);
-