xref: /netbsd-src/external/gpl3/gcc.old/dist/lto-plugin/lto-plugin.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1 /* LTO plugin for gold and/or GNU ld.
2    Copyright (C) 2009-2020 Free Software Foundation, Inc.
3    Contributed by Rafael Avila de Espindola (espindola@google.com).
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9 
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING3.  If not see
17 <http://www.gnu.org/licenses/>.  */
18 
19 /* The plugin has only one external function: onload. Gold passes it an array of
20    function that the plugin uses to communicate back to gold.
21 
22    With the functions provided by gold, the plugin can be notified when
23    gold first analyzes a file and pass a symbol table back to gold. The plugin
24    is also notified when all symbols have been read and it is time to generate
25    machine code for the necessary symbols.
26 
27    More information at http://gcc.gnu.org/wiki/whopr/driver.
28 
29    This plugin should be passed the lto-wrapper options and will forward them.
30    It also has options at his own:
31    -debug: Print the command line used to run lto-wrapper.
32    -nop: Instead of running lto-wrapper, pass the original to the plugin. This
33    only works if the input files are hybrid.
34    -linker-output-known: Do not determine linker output
35    -sym-style={none,win32,underscore|uscore}
36    -pass-through  */
37 
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41 #if HAVE_STDINT_H
42 #include <stdint.h>
43 #endif
44 #include <stdbool.h>
45 #include <assert.h>
46 #include <errno.h>
47 #include <string.h>
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <inttypes.h>
51 #include <sys/stat.h>
52 #include <unistd.h>
53 #include <fcntl.h>
54 #include <sys/types.h>
55 #ifdef HAVE_SYS_WAIT_H
56 #include <sys/wait.h>
57 #endif
58 #ifndef WIFEXITED
59 #define WIFEXITED(S) (((S) & 0xff) == 0)
60 #endif
61 #ifndef WEXITSTATUS
62 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
63 #endif
64 #include <libiberty.h>
65 #include <hashtab.h>
66 #include "../gcc/lto/common.h"
67 #include "simple-object.h"
68 #include "plugin-api.h"
69 
70 /* We need to use I64 instead of ll width-specifier on native Windows.
71    The reason for this is that older MS-runtimes don't support the ll.  */
72 #ifdef __MINGW32__
73 #define PRI_LL "I64"
74 #else
75 #define PRI_LL "ll"
76 #endif
77 
78 /* Handle opening elf files on hosts, such as Windows, that may use
79    text file handling that will break binary access.  */
80 #ifndef O_BINARY
81 # define O_BINARY 0
82 #endif
83 
84 /* Segment name for LTO sections.  This is only used for Mach-O.
85    FIXME: This needs to be kept in sync with darwin.c.  */
86 
87 #define LTO_SEGMENT_NAME "__GNU_LTO"
88 
89 /* LTO magic section name.  */
90 
91 #define LTO_SYMTAB_PREFIX	    ".gnu.lto_.symtab"
92 #define LTO_SYMTAB_PREFIX_LEN	    (sizeof (LTO_SYMTAB_PREFIX) - 1)
93 #define LTO_SYMTAB_EXT_PREFIX	    ".gnu.lto_.ext_symtab"
94 #define LTO_SYMTAB_EXT_PREFIX_LEN   (sizeof (LTO_SYMTAB_EXT_PREFIX) - 1)
95 #define LTO_LTO_PREFIX		    ".gnu.lto_.lto"
96 #define LTO_LTO_PREFIX_LEN	    (sizeof (LTO_LTO_PREFIX) - 1)
97 #define OFFLOAD_SECTION		    ".gnu.offload_lto_.opts"
98 #define OFFLOAD_SECTION_LEN	    (sizeof (OFFLOAD_SECTION) - 1)
99 
100 /* The part of the symbol table the plugin has to keep track of. Note that we
101    must keep SYMS until all_symbols_read is called to give the linker time to
102    copy the symbol information.
103    The id must be 64bit to minimze collisions. */
104 
105 struct sym_aux
106 {
107   uint32_t slot;
108   unsigned long long id;
109   unsigned next_conflict;
110 };
111 
112 struct plugin_symtab
113 {
114   int nsyms;
115   int last_sym;
116   struct sym_aux *aux;
117   struct ld_plugin_symbol *syms;
118   unsigned long long id;
119 };
120 
121 /* Encapsulates object file data during symbol scan.  */
122 struct plugin_objfile
123 {
124   int found;
125   int offload;
126   simple_object_read *objfile;
127   struct plugin_symtab *out;
128   const struct ld_plugin_input_file *file;
129 };
130 
131 /* All that we have to remember about a file. */
132 
133 struct plugin_file_info
134 {
135   char *name;
136   void *handle;
137   struct plugin_symtab symtab;
138   struct plugin_symtab conflicts;
139 };
140 
141 /* List item with name of the file with offloading.  */
142 
143 struct plugin_offload_file
144 {
145   char *name;
146   struct plugin_offload_file *next;
147 };
148 
149 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
150    stdio file streams, we do simple label translation here.  */
151 
152 enum symbol_style
153 {
154   ss_none,	/* No underscore prefix. */
155   ss_win32,	/* Underscore prefix any symbol not beginning with '@'.  */
156   ss_uscore,	/* Underscore prefix all symbols.  */
157 };
158 
159 static char *arguments_file_name;
160 static ld_plugin_register_claim_file register_claim_file;
161 static ld_plugin_register_all_symbols_read register_all_symbols_read;
162 static ld_plugin_get_symbols get_symbols, get_symbols_v2;
163 static ld_plugin_register_cleanup register_cleanup;
164 static ld_plugin_add_input_file add_input_file;
165 static ld_plugin_add_input_library add_input_library;
166 static ld_plugin_message message;
167 static ld_plugin_add_symbols add_symbols, add_symbols_v2;
168 
169 static struct plugin_file_info *claimed_files = NULL;
170 static unsigned int num_claimed_files = 0;
171 static unsigned int non_claimed_files = 0;
172 
173 /* List of files with offloading.  */
174 static struct plugin_offload_file *offload_files;
175 /* Last file in the list.  */
176 static struct plugin_offload_file *offload_files_last;
177 /* Last non-archive file in the list.  */
178 static struct plugin_offload_file *offload_files_last_obj;
179 /* Last LTO file in the list.  */
180 static struct plugin_offload_file *offload_files_last_lto;
181 /* Total number of files with offloading.  */
182 static unsigned num_offload_files;
183 
184 static char **output_files = NULL;
185 static unsigned int num_output_files = 0;
186 
187 static char **lto_wrapper_argv;
188 static int lto_wrapper_num_args;
189 
190 static char **pass_through_items = NULL;
191 static unsigned int num_pass_through_items;
192 
193 static bool debug;
194 static bool save_temps;
195 static bool verbose;
196 static char nop;
197 static char *resolution_file = NULL;
198 static enum ld_plugin_output_file_type linker_output;
199 static int linker_output_set;
200 static int linker_output_known;
201 static const char *link_output_name = NULL;
202 
203 /* The version of gold being used, or -1 if not gold.  The number is
204    MAJOR * 100 + MINOR.  */
205 static int gold_version = -1;
206 
207 /* Not used by default, but can be overridden at runtime
208    by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
209    (in fact, only first letter of style arg is checked.)  */
210 static enum symbol_style sym_style = ss_none;
211 
212 static void
check_1(int gate,enum ld_plugin_level level,const char * text)213 check_1 (int gate, enum ld_plugin_level level, const char *text)
214 {
215   if (gate)
216     return;
217 
218   if (message)
219     message (level, text);
220   else
221     {
222       /* If there is no nicer way to inform the user, fallback to stderr. */
223       fprintf (stderr, "%s\n", text);
224       if (level == LDPL_FATAL)
225 	abort ();
226     }
227 }
228 
229 /* This little wrapper allows check to be called with a non-integer
230    first argument, such as a pointer that must be non-NULL.  We can't
231    use c99 bool type to coerce it into range, so we explicitly test.  */
232 #define check(GATE, LEVEL, TEXT) check_1 (((GATE) != 0), (LEVEL), (TEXT))
233 
234 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
235    by P and the result is written in ENTRY. The slot number is stored in SLOT.
236    Returns the address of the next entry. */
237 
238 static char *
parse_table_entry(char * p,struct ld_plugin_symbol * entry,struct sym_aux * aux)239 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
240 		   struct sym_aux *aux)
241 {
242   unsigned char t;
243   enum ld_plugin_symbol_kind translate_kind[] =
244     {
245       LDPK_DEF,
246       LDPK_WEAKDEF,
247       LDPK_UNDEF,
248       LDPK_WEAKUNDEF,
249       LDPK_COMMON
250     };
251 
252   enum ld_plugin_symbol_visibility translate_visibility[] =
253     {
254       LDPV_DEFAULT,
255       LDPV_PROTECTED,
256       LDPV_INTERNAL,
257       LDPV_HIDDEN
258     };
259 
260   switch (sym_style)
261     {
262     case ss_win32:
263       if (p[0] == '@')
264 	{
265     /* cf. Duff's device.  */
266     case ss_none:
267 	  entry->name = xstrdup (p);
268 	  break;
269 	}
270     /* FALL-THROUGH.  */
271     case ss_uscore:
272       entry->name = concat ("_", p, NULL);
273       break;
274     default:
275       check (0, LDPL_FATAL, "invalid symbol style requested");
276       break;
277     }
278   while (*p)
279     p++;
280   p++;
281 
282   entry->version = NULL;
283 
284   entry->comdat_key = p;
285   while (*p)
286     p++;
287   p++;
288 
289   if (strlen (entry->comdat_key) == 0)
290     entry->comdat_key = NULL;
291   else
292     entry->comdat_key = xstrdup (entry->comdat_key);
293 
294   entry->unused = entry->section_kind = entry->symbol_type = 0;
295 
296   t = *p;
297   check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
298   entry->def = translate_kind[t];
299   p++;
300 
301   t = *p;
302   check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
303   entry->visibility = translate_visibility[t];
304   p++;
305 
306   memcpy (&entry->size, p, sizeof (uint64_t));
307   p += 8;
308 
309   memcpy (&aux->slot, p, sizeof (uint32_t));
310   p += 4;
311 
312   entry->resolution = LDPR_UNKNOWN;
313 
314   aux->next_conflict = -1;
315 
316   return p;
317 }
318 
319 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
320    by P and the result is written in ENTRY. The slot number is stored in SLOT.
321    Returns the address of the next entry. */
322 
323 static char *
parse_table_entry_extension(char * p,struct ld_plugin_symbol * entry)324 parse_table_entry_extension (char *p, struct ld_plugin_symbol *entry)
325 {
326   unsigned char t;
327   enum ld_plugin_symbol_type symbol_types[] =
328     {
329       LDST_UNKNOWN,
330       LDST_FUNCTION,
331       LDST_VARIABLE,
332     };
333 
334   t = *p;
335   check (t <= 2, LDPL_FATAL, "invalid symbol type found");
336   entry->symbol_type = symbol_types[t];
337   p++;
338   entry->section_kind = *p;
339   p++;
340 
341   return p;
342 }
343 
344 
345 /* Translate the IL symbol table located between DATA and END. Append the
346    slots and symbols to OUT. */
347 
348 static void
translate(char * data,char * end,struct plugin_symtab * out)349 translate (char *data, char *end, struct plugin_symtab *out)
350 {
351   struct sym_aux *aux;
352   struct ld_plugin_symbol *syms = NULL;
353   int n, len;
354 
355   /* This overestimates the output buffer sizes, but at least
356      the algorithm is O(1) now. */
357 
358   len = (end - data)/8 + out->nsyms + 1;
359   syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
360   aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
361 
362   for (n = out->nsyms; data < end; n++)
363     {
364       aux[n].id = out->id;
365       data = parse_table_entry (data, &syms[n], &aux[n]);
366     }
367 
368   assert(n < len);
369 
370   out->nsyms = n;
371   out->syms = syms;
372   out->aux = aux;
373 }
374 
375 static void
parse_symtab_extension(char * data,char * end,struct plugin_symtab * out)376 parse_symtab_extension (char *data, char *end, struct plugin_symtab *out)
377 {
378   unsigned long i;
379   unsigned char version;
380 
381   if (data >= end)
382     /* FIXME: Issue an error ?  */
383     return;
384 
385   version = *data;
386   data++;
387 
388   if (version != 1)
389     return;
390 
391   /* Version 1 contains the following data per entry:
392      - symbol_type
393      - section_kind
394      .  */
395 
396   unsigned long nsyms = (end - data) / 2;
397 
398   for (i = 0; i < nsyms; i++)
399     data = parse_table_entry_extension (data, out->syms + i + out->last_sym);
400 
401   out->last_sym += nsyms;
402 }
403 
404 /* Free all memory that is no longer needed after writing the symbol
405    resolution. */
406 
407 static void
free_1(struct plugin_file_info * files,unsigned num_files)408 free_1 (struct plugin_file_info *files, unsigned num_files)
409 {
410   unsigned int i;
411   for (i = 0; i < num_files; i++)
412     {
413       struct plugin_file_info *info = &files[i];
414       struct plugin_symtab *symtab = &info->symtab;
415       unsigned int j;
416       for (j = 0; j < symtab->nsyms; j++)
417 	{
418 	  struct ld_plugin_symbol *s = &symtab->syms[j];
419 	  free (s->name);
420 	  free (s->comdat_key);
421 	}
422       free (symtab->syms);
423       symtab->syms = NULL;
424     }
425 }
426 
427 /* Free all remaining memory. */
428 
429 static void
free_2(void)430 free_2 (void)
431 {
432   unsigned int i;
433   for (i = 0; i < num_claimed_files; i++)
434     {
435       struct plugin_file_info *info = &claimed_files[i];
436       struct plugin_symtab *symtab = &info->symtab;
437       free (symtab->aux);
438       free (info->name);
439     }
440 
441   for (i = 0; i < num_output_files; i++)
442     free (output_files[i]);
443   free (output_files);
444 
445   free (claimed_files);
446   claimed_files = NULL;
447   num_claimed_files = 0;
448 
449   while (offload_files)
450     {
451       struct plugin_offload_file *ofld = offload_files;
452       offload_files = offload_files->next;
453       free (ofld);
454     }
455   num_offload_files = 0;
456 
457   free (arguments_file_name);
458   arguments_file_name = NULL;
459 }
460 
461 /* Dump SYMTAB to resolution file F. */
462 
463 static void
dump_symtab(FILE * f,struct plugin_symtab * symtab)464 dump_symtab (FILE *f, struct plugin_symtab *symtab)
465 {
466   unsigned j;
467 
468   for (j = 0; j < symtab->nsyms; j++)
469     {
470       uint32_t slot = symtab->aux[j].slot;
471       unsigned int resolution = symtab->syms[j].resolution;
472 
473       assert (resolution != LDPR_UNKNOWN);
474 
475       fprintf (f, "%u %" PRI_LL "x %s %s\n",
476                (unsigned int) slot, symtab->aux[j].id,
477 	       lto_resolution_str[resolution],
478 	       symtab->syms[j].name);
479     }
480 }
481 
482 /* Finish the conflicts' resolution information after the linker resolved
483    the original symbols */
484 
485 static void
finish_conflict_resolution(struct plugin_symtab * symtab,struct plugin_symtab * conflicts)486 finish_conflict_resolution (struct plugin_symtab *symtab,
487 			   struct plugin_symtab *conflicts)
488 {
489   int i, j;
490 
491   if (conflicts->nsyms == 0)
492     return;
493 
494   for (i = 0; i < symtab->nsyms; i++)
495     {
496       char resolution = LDPR_UNKNOWN;
497 
498       if (symtab->aux[i].next_conflict == -1)
499 	continue;
500 
501       switch (symtab->syms[i].def)
502 	{
503 	case LDPK_DEF:
504 	case LDPK_COMMON: /* ??? */
505 	  resolution = LDPR_RESOLVED_IR;
506 	  break;
507 	case LDPK_WEAKDEF:
508 	  resolution = LDPR_PREEMPTED_IR;
509 	  break;
510 	case LDPK_UNDEF:
511 	case LDPK_WEAKUNDEF:
512 	  resolution = symtab->syms[i].resolution;
513 	  break;
514 	default:
515 	  assert (0);
516 	}
517 
518       assert (resolution != LDPR_UNKNOWN);
519 
520       for (j = symtab->aux[i].next_conflict;
521 	   j != -1;
522 	   j = conflicts->aux[j].next_conflict)
523 	conflicts->syms[j].resolution = resolution;
524     }
525 }
526 
527 /* Free symbol table SYMTAB. */
528 
529 static void
free_symtab(struct plugin_symtab * symtab)530 free_symtab (struct plugin_symtab *symtab)
531 {
532   free (symtab->syms);
533   symtab->syms = NULL;
534   free (symtab->aux);
535   symtab->aux = NULL;
536 }
537 
538 /*  Writes the relocations to disk. */
539 
540 static void
write_resolution(void)541 write_resolution (void)
542 {
543   unsigned int i;
544   FILE *f;
545 
546   check (resolution_file, LDPL_FATAL, "resolution file not specified");
547   f = fopen (resolution_file, "w");
548   check (f, LDPL_FATAL, "could not open file");
549 
550   fprintf (f, "%d\n", num_claimed_files);
551 
552   for (i = 0; i < num_claimed_files; i++)
553     {
554       struct plugin_file_info *info = &claimed_files[i];
555       struct plugin_symtab *symtab = &info->symtab;
556       struct ld_plugin_symbol *syms = symtab->syms;
557 
558       /* Version 2 of API supports IRONLY_EXP resolution that is
559          accepted by GCC-4.7 and newer.  */
560       if (get_symbols_v2)
561         get_symbols_v2 (info->handle, symtab->nsyms, syms);
562       else
563         get_symbols (info->handle, symtab->nsyms, syms);
564 
565       finish_conflict_resolution (symtab, &info->conflicts);
566 
567       fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
568       dump_symtab (f, symtab);
569       if (info->conflicts.nsyms)
570 	{
571 	  dump_symtab (f, &info->conflicts);
572 	  free_symtab (&info->conflicts);
573 	}
574     }
575   fclose (f);
576 }
577 
578 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
579    stdout. */
580 
581 static void
add_output_files(FILE * f)582 add_output_files (FILE *f)
583 {
584   for (;;)
585     {
586       const unsigned piece = 32;
587       char *buf, *s = xmalloc (piece);
588       size_t len;
589 
590       buf = s;
591 cont:
592       if (!fgets (buf, piece, f))
593 	{
594 	  free (s);
595 	  break;
596 	}
597       len = strlen (s);
598       if (s[len - 1] != '\n')
599 	{
600 	  s = xrealloc (s, len + piece);
601 	  buf = s + len;
602 	  goto cont;
603 	}
604       s[len - 1] = '\0';
605 
606       num_output_files++;
607       output_files
608 	= xrealloc (output_files, num_output_files * sizeof (char *));
609       output_files[num_output_files - 1] = s;
610       add_input_file (output_files[num_output_files - 1]);
611     }
612 }
613 
614 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
615    argument list. */
616 
617 static void
exec_lto_wrapper(char * argv[])618 exec_lto_wrapper (char *argv[])
619 {
620   int t, i;
621   int status;
622   char *at_args;
623   FILE *args;
624   FILE *wrapper_output;
625   char *new_argv[3];
626   struct pex_obj *pex;
627   const char *errmsg;
628 
629   /* Write argv to a file to avoid a command line that is too long
630      Save the file locally on save-temps.  */
631   if (save_temps && link_output_name)
632     {
633       arguments_file_name = (char *) xmalloc (strlen (link_output_name)
634 				  + sizeof (".lto_wrapper_args") + 1);
635       strcpy (arguments_file_name, link_output_name);
636       strcat (arguments_file_name, ".lto_wrapper_args");
637     }
638   else
639      arguments_file_name = make_temp_file (".lto_wrapper_args");
640   check (arguments_file_name, LDPL_FATAL,
641          "Failed to generate a temorary file name");
642 
643   args = fopen (arguments_file_name, "w");
644   check (args, LDPL_FATAL, "could not open arguments file");
645 
646   t = writeargv (&argv[1], args);
647   check (t == 0, LDPL_FATAL, "could not write arguments");
648   t = fclose (args);
649   check (t == 0, LDPL_FATAL, "could not close arguments file");
650 
651   at_args = concat ("@", arguments_file_name, NULL);
652   check (at_args, LDPL_FATAL, "could not allocate");
653 
654   for (i = 1; argv[i]; i++)
655     {
656       char *a = argv[i];
657       /* Check the input argument list for a verbose marker too.  */
658       if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
659 	{
660 	  verbose = true;
661 	  break;
662 	}
663     }
664 
665   if (verbose)
666     {
667       for (i = 0; argv[i]; i++)
668 	fprintf (stderr, "%s ", argv[i]);
669       fprintf (stderr, "\n");
670     }
671 
672   new_argv[0] = argv[0];
673   new_argv[1] = at_args;
674   new_argv[2] = NULL;
675 
676   if (debug)
677     {
678       for (i = 0; new_argv[i]; i++)
679 	fprintf (stderr, "%s ", new_argv[i]);
680       fprintf (stderr, "\n");
681     }
682 
683   pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
684   check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
685 
686   errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
687   check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
688   check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
689 
690   wrapper_output = pex_read_output (pex, 0);
691   check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
692 
693   add_output_files (wrapper_output);
694 
695   t = pex_get_status (pex, 1, &status);
696   check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
697   check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
698          "lto-wrapper failed");
699 
700   pex_free (pex);
701 
702   free (at_args);
703 }
704 
705 /* Pass the original files back to the linker. */
706 
707 static void
use_original_files(void)708 use_original_files (void)
709 {
710   unsigned i;
711   for (i = 0; i < num_claimed_files; i++)
712     {
713       struct plugin_file_info *info = &claimed_files[i];
714       add_input_file (info->name);
715     }
716 }
717 
718 
719 /* Called by the linker once all symbols have been read. */
720 
721 static enum ld_plugin_status
all_symbols_read_handler(void)722 all_symbols_read_handler (void)
723 {
724   unsigned i;
725   unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 2
726     	   + !linker_output_known;
727   char **lto_argv;
728   const char *linker_output_str = NULL;
729   const char **lto_arg_ptr;
730   if (num_claimed_files + num_offload_files == 0)
731     return LDPS_OK;
732 
733   if (nop)
734     {
735       use_original_files ();
736       return LDPS_OK;
737     }
738 
739   lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
740   lto_arg_ptr = (const char **) lto_argv;
741   assert (lto_wrapper_argv);
742 
743   write_resolution ();
744 
745   free_1 (claimed_files, num_claimed_files);
746 
747   for (i = 0; i < lto_wrapper_num_args; i++)
748     *lto_arg_ptr++ = lto_wrapper_argv[i];
749 
750   if (!linker_output_known)
751     {
752       assert (linker_output_set);
753       switch (linker_output)
754 	{
755 	case LDPO_REL:
756 	  if (non_claimed_files)
757 	    {
758 	      message (LDPL_WARNING, "incremental linking of LTO and non-LTO "
759 		       "objects; using -flinker-output=nolto-rel which will "
760 		       "bypass whole program optimization");
761 	      linker_output_str = "-flinker-output=nolto-rel";
762 	    }
763 	  else
764 	    linker_output_str = "-flinker-output=rel";
765 	  break;
766 	case LDPO_DYN:
767 	  linker_output_str = "-flinker-output=dyn";
768 	  break;
769 	case LDPO_PIE:
770 	  linker_output_str = "-flinker-output=pie";
771 	  break;
772 	case LDPO_EXEC:
773 	  linker_output_str = "-flinker-output=exec";
774 	  break;
775 	default:
776 	  message (LDPL_FATAL, "unsupported linker output %i", linker_output);
777 	  break;
778 	}
779       *lto_arg_ptr++ = xstrdup (linker_output_str);
780     }
781 
782   if (num_offload_files > 0)
783     {
784       FILE *f;
785       char *arg;
786       char *offload_objects_file_name;
787       struct plugin_offload_file *ofld;
788 
789       offload_objects_file_name = make_temp_file (".ofldlist");
790       check (offload_objects_file_name, LDPL_FATAL,
791 	     "Failed to generate a temporary file name");
792       f = fopen (offload_objects_file_name, "w");
793       check (f, LDPL_FATAL, "could not open file with offload objects");
794       fprintf (f, "%u\n", num_offload_files);
795 
796       /* Skip the dummy item at the start of the list.  */
797       ofld = offload_files->next;
798       while (ofld)
799 	{
800 	  fprintf (f, "%s\n", ofld->name);
801 	  ofld = ofld->next;
802 	}
803       fclose (f);
804 
805       arg = concat ("-foffload-objects=", offload_objects_file_name, NULL);
806       check (arg, LDPL_FATAL, "could not allocate");
807       *lto_arg_ptr++ = arg;
808     }
809 
810   for (i = 0; i < num_claimed_files; i++)
811     {
812       struct plugin_file_info *info = &claimed_files[i];
813 
814       *lto_arg_ptr++ = info->name;
815     }
816 
817   *lto_arg_ptr++ = NULL;
818   exec_lto_wrapper (lto_argv);
819 
820   free (lto_argv);
821 
822   /* --pass-through is not needed when using gold 1.11 or later.  */
823   if (pass_through_items && gold_version < 111)
824     {
825       unsigned int i;
826       for (i = 0; i < num_pass_through_items; i++)
827         {
828           if (strncmp (pass_through_items[i], "-l", 2) == 0)
829             add_input_library (pass_through_items[i] + 2);
830           else
831             add_input_file (pass_through_items[i]);
832           free (pass_through_items[i]);
833           pass_through_items[i] = NULL;
834         }
835       free (pass_through_items);
836       pass_through_items = NULL;
837     }
838 
839   return LDPS_OK;
840 }
841 
842 /* Helper, as used in collect2.  */
843 static int
file_exists(const char * name)844 file_exists (const char *name)
845 {
846   return access (name, R_OK) == 0;
847 }
848 
849 /* Unlink FILE unless we have save-temps set.
850    Note that we're saving files if verbose output is set. */
851 
852 static void
maybe_unlink(const char * file)853 maybe_unlink (const char *file)
854 {
855   if (save_temps && file_exists (file))
856     {
857       if (verbose)
858 	fprintf (stderr, "[Leaving %s]\n", file);
859       return;
860     }
861 
862   unlink_if_ordinary (file);
863 }
864 
865 /* Remove temporary files at the end of the link. */
866 
867 static enum ld_plugin_status
cleanup_handler(void)868 cleanup_handler (void)
869 {
870   unsigned int i;
871 
872   if (debug)
873     return LDPS_OK;
874 
875   if (arguments_file_name)
876     maybe_unlink (arguments_file_name);
877 
878   for (i = 0; i < num_output_files; i++)
879     maybe_unlink (output_files[i]);
880 
881   free_2 ();
882   return LDPS_OK;
883 }
884 
885 #define SWAP(type, a, b) \
886   do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
887 
888 /* Compare two hash table entries */
889 
eq_sym(const void * a,const void * b)890 static int eq_sym (const void *a, const void *b)
891 {
892   const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
893   const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
894 
895   return !strcmp (as->name, bs->name);
896 }
897 
898 /* Hash a symbol */
899 
hash_sym(const void * a)900 static hashval_t hash_sym (const void *a)
901 {
902   const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
903 
904   return htab_hash_string (as->name);
905 }
906 
907 /* Determine how strong a symbol is */
908 
symbol_strength(struct ld_plugin_symbol * s)909 static int symbol_strength (struct ld_plugin_symbol *s)
910 {
911   switch (s->def)
912     {
913     case LDPK_UNDEF:
914     case LDPK_WEAKUNDEF:
915       return 0;
916     case LDPK_WEAKDEF:
917       return 1;
918     default:
919       return 2;
920     }
921 }
922 
923 /* In the ld -r case we can get dups in the LTO symbol tables, where
924    the same symbol can have different resolutions (e.g. undefined and defined).
925 
926    We have to keep that in the LTO symbol tables, but the dups confuse
927    gold and then finally gcc by supplying incorrect resolutions.
928 
929    Problem is that the main gold symbol table doesn't know about subids
930    and does not distingush the same symbols in different states.
931 
932    So we drop duplicates from the linker visible symbol table
933    and keep them in a private table. Then later do own symbol
934    resolution for the duplicated based on the results for the
935    originals.
936 
937    Then when writing out the resolution file readd the dropped symbols.
938 
939    XXX how to handle common? */
940 
941 static void
resolve_conflicts(struct plugin_symtab * t,struct plugin_symtab * conflicts)942 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
943 {
944   htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
945   int i;
946   int out;
947   int outlen;
948 
949   outlen = t->nsyms;
950   conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
951   conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
952 
953   /* Move all duplicate symbols into the auxiliary conflicts table. */
954   out = 0;
955   for (i = 0; i < t->nsyms; i++)
956     {
957       struct ld_plugin_symbol *s = &t->syms[i];
958       struct sym_aux *aux = &t->aux[i];
959       void **slot;
960 
961       slot = htab_find_slot (symtab, s, INSERT);
962       if (*slot != NULL)
963 	{
964 	  int cnf;
965 	  struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
966 	  struct sym_aux *orig_aux = &t->aux[orig - t->syms];
967 
968 	  /* Always let the linker resolve the strongest symbol */
969 	  if (symbol_strength (orig) < symbol_strength (s))
970 	    {
971 	      SWAP (struct ld_plugin_symbol, *orig, *s);
972 	      SWAP (uint32_t, orig_aux->slot, aux->slot);
973 	      SWAP (unsigned long long, orig_aux->id, aux->id);
974 	      /* Don't swap conflict chain pointer */
975 	    }
976 
977 	  /* Move current symbol into the conflicts table */
978 	  cnf = conflicts->nsyms++;
979 	  conflicts->syms[cnf] = *s;
980 	  conflicts->aux[cnf] = *aux;
981 	  aux = &conflicts->aux[cnf];
982 
983 	  /* Update conflicts chain of the original symbol */
984 	  aux->next_conflict = orig_aux->next_conflict;
985 	  orig_aux->next_conflict = cnf;
986 
987 	  continue;
988 	}
989 
990       /* Remove previous duplicates in the main table */
991       if (out < i)
992 	{
993 	  t->syms[out] = *s;
994 	  t->aux[out] = *aux;
995 	}
996 
997       /* Put original into the hash table */
998       *slot = &t->syms[out];
999       out++;
1000     }
1001 
1002   assert (conflicts->nsyms <= outlen);
1003   assert (conflicts->nsyms + out == t->nsyms);
1004 
1005   t->nsyms = out;
1006   htab_delete (symtab);
1007 }
1008 
1009 /* Process one section of an object file.  */
1010 
1011 static int
process_symtab(void * data,const char * name,off_t offset,off_t length)1012 process_symtab (void *data, const char *name, off_t offset, off_t length)
1013 {
1014   struct plugin_objfile *obj = (struct plugin_objfile *)data;
1015   char *s;
1016   char *secdatastart, *secdata;
1017 
1018   if (strncmp (name, LTO_SYMTAB_PREFIX, LTO_SYMTAB_PREFIX_LEN) != 0)
1019     return 1;
1020 
1021   s = strrchr (name, '.');
1022   if (s)
1023     sscanf (s, ".%" PRI_LL "x", &obj->out->id);
1024   secdata = secdatastart = xmalloc (length);
1025   offset += obj->file->offset;
1026   if (offset != lseek (obj->file->fd, offset, SEEK_SET))
1027     goto err;
1028 
1029   do
1030     {
1031       ssize_t got = read (obj->file->fd, secdata, length);
1032       if (got == 0)
1033 	break;
1034       else if (got > 0)
1035 	{
1036 	  secdata += got;
1037 	  length -= got;
1038 	}
1039       else if (errno != EINTR)
1040 	goto err;
1041     }
1042   while (length > 0);
1043   if (length > 0)
1044     goto err;
1045 
1046   translate (secdatastart, secdata, obj->out);
1047   obj->found++;
1048   free (secdatastart);
1049   return 1;
1050 
1051 err:
1052   if (message)
1053     message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
1054   /* Force claim_file_handler to abandon this file.  */
1055   obj->found = 0;
1056   free (secdatastart);
1057   return 0;
1058 }
1059 
1060 /* Process one section of an object file.  */
1061 
1062 static int
process_symtab_extension(void * data,const char * name,off_t offset,off_t length)1063 process_symtab_extension (void *data, const char *name, off_t offset,
1064 			  off_t length)
1065 {
1066   struct plugin_objfile *obj = (struct plugin_objfile *)data;
1067   char *s;
1068   char *secdatastart, *secdata;
1069 
1070   if (strncmp (name, LTO_SYMTAB_EXT_PREFIX, LTO_SYMTAB_EXT_PREFIX_LEN) != 0)
1071     return 1;
1072 
1073   s = strrchr (name, '.');
1074   if (s)
1075     sscanf (s, ".%" PRI_LL "x", &obj->out->id);
1076   secdata = secdatastart = xmalloc (length);
1077   offset += obj->file->offset;
1078   if (offset != lseek (obj->file->fd, offset, SEEK_SET))
1079     goto err;
1080 
1081   do
1082     {
1083       ssize_t got = read (obj->file->fd, secdata, length);
1084       if (got == 0)
1085 	break;
1086       else if (got > 0)
1087 	{
1088 	  secdata += got;
1089 	  length -= got;
1090 	}
1091       else if (errno != EINTR)
1092 	goto err;
1093     }
1094   while (length > 0);
1095   if (length > 0)
1096     goto err;
1097 
1098   parse_symtab_extension (secdatastart, secdata, obj->out);
1099   obj->found++;
1100   free (secdatastart);
1101   return 1;
1102 
1103 err:
1104   if (message)
1105     message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
1106   /* Force claim_file_handler to abandon this file.  */
1107   obj->found = 0;
1108   free (secdatastart);
1109   return 0;
1110 }
1111 
1112 
1113 /* Find an offload section of an object file.  */
1114 
1115 static int
process_offload_section(void * data,const char * name,off_t offset,off_t len)1116 process_offload_section (void *data, const char *name, off_t offset, off_t len)
1117 {
1118   if (!strncmp (name, OFFLOAD_SECTION, OFFLOAD_SECTION_LEN))
1119     {
1120       struct plugin_objfile *obj = (struct plugin_objfile *) data;
1121       obj->offload = 1;
1122       return 0;
1123     }
1124 
1125   return 1;
1126 }
1127 
1128 /* Callback used by gold to check if the plugin will claim FILE. Writes
1129    the result in CLAIMED. */
1130 
1131 static enum ld_plugin_status
claim_file_handler(const struct ld_plugin_input_file * file,int * claimed)1132 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
1133 {
1134   enum ld_plugin_status status;
1135   struct plugin_objfile obj;
1136   struct plugin_file_info lto_file;
1137   int err;
1138   const char *errmsg;
1139 
1140   memset (&lto_file, 0, sizeof (struct plugin_file_info));
1141 
1142   if (file->offset != 0)
1143     {
1144       /* We pass the offset of the actual file, not the archive header.
1145          Can't use PRIx64, because that's C99, so we have to print the
1146 	 64-bit hex int as two 32-bit ones.  Use xasprintf instead of
1147 	 asprintf because asprintf doesn't work as expected on some older
1148 	 mingw32 hosts.  */
1149       int lo, hi;
1150       lo = file->offset & 0xffffffff;
1151       hi = ((int64_t)file->offset >> 32) & 0xffffffff;
1152       lto_file.name = hi ? xasprintf ("%s@0x%x%08x", file->name, hi, lo)
1153       			 : xasprintf ("%s@0x%x", file->name, lo);
1154     }
1155   else
1156     {
1157       lto_file.name = xstrdup (file->name);
1158     }
1159   lto_file.handle = file->handle;
1160 
1161   *claimed = 0;
1162   obj.file = file;
1163   obj.found = 0;
1164   obj.offload = 0;
1165   obj.out = &lto_file.symtab;
1166   errmsg = NULL;
1167   obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
1168 			&errmsg, &err);
1169   /* No file, but also no error code means unrecognized format; just skip it.  */
1170   if (!obj.objfile && !err)
1171     goto err;
1172 
1173    if (obj.objfile)
1174     {
1175       errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj,
1176 					    &err);
1177       /*  Parsing symtab extension should be done only for add_symbols_v2 and
1178 	  later versions.  */
1179       if (!errmsg && add_symbols_v2 != NULL)
1180 	{
1181 	  obj.out->last_sym = 0;
1182 	  errmsg = simple_object_find_sections (obj.objfile,
1183 						process_symtab_extension,
1184 						&obj, &err);
1185 	}
1186     }
1187 
1188   if (!obj.objfile || errmsg)
1189     {
1190       if (err && message)
1191 	message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
1192 		xstrerror (err));
1193       else if (message)
1194 	message (LDPL_FATAL, "%s: %s", file->name, errmsg);
1195       goto err;
1196     }
1197 
1198   if (obj.objfile)
1199     simple_object_find_sections (obj.objfile, process_offload_section,
1200 				 &obj, &err);
1201 
1202   if (obj.found == 0 && obj.offload == 0)
1203     goto err;
1204 
1205   if (obj.found > 1)
1206     resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
1207 
1208   if (obj.found > 0)
1209     {
1210       if (add_symbols_v2)
1211 	status = add_symbols_v2 (file->handle, lto_file.symtab.nsyms,
1212 				 lto_file.symtab.syms);
1213       else
1214 	status = add_symbols (file->handle, lto_file.symtab.nsyms,
1215 			      lto_file.symtab.syms);
1216       check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
1217 
1218       num_claimed_files++;
1219       claimed_files =
1220 	xrealloc (claimed_files,
1221 		  num_claimed_files * sizeof (struct plugin_file_info));
1222       claimed_files[num_claimed_files - 1] = lto_file;
1223 
1224       *claimed = 1;
1225     }
1226 
1227   if (offload_files == NULL)
1228     {
1229       /* Add dummy item to the start of the list.  */
1230       offload_files = xmalloc (sizeof (struct plugin_offload_file));
1231       offload_files->name = NULL;
1232       offload_files->next = NULL;
1233       offload_files_last = offload_files;
1234     }
1235 
1236   /* If this is an LTO file without offload, and it is the first LTO file, save
1237      the pointer to the last offload file in the list.  Further offload LTO
1238      files will be inserted after it, if any.  */
1239   if (*claimed && obj.offload == 0 && offload_files_last_lto == NULL)
1240     offload_files_last_lto = offload_files_last;
1241 
1242   if (obj.offload == 1)
1243     {
1244       /* Add file to the list.  The order must be exactly the same as the final
1245 	 order after recompilation and linking, otherwise host and target tables
1246 	 with addresses wouldn't match.  If a static library contains both LTO
1247 	 and non-LTO objects, ld and gold link them in a different order.  */
1248       struct plugin_offload_file *ofld
1249 	= xmalloc (sizeof (struct plugin_offload_file));
1250       ofld->name = lto_file.name;
1251       ofld->next = NULL;
1252 
1253       if (*claimed && offload_files_last_lto == NULL && file->offset != 0
1254 	  && gold_version == -1)
1255 	{
1256 	  /* ld only: insert first LTO file from the archive after the last real
1257 	     object file immediately preceding the archive, or at the begin of
1258 	     the list if there was no real objects before archives.  */
1259 	  if (offload_files_last_obj != NULL)
1260 	    {
1261 	      ofld->next = offload_files_last_obj->next;
1262 	      offload_files_last_obj->next = ofld;
1263 	    }
1264 	  else
1265 	    {
1266 	      ofld->next = offload_files->next;
1267 	      offload_files->next = ofld;
1268 	    }
1269 	}
1270       else if (*claimed && offload_files_last_lto != NULL)
1271 	{
1272 	  /* Insert LTO file after the last LTO file in the list.  */
1273 	  ofld->next = offload_files_last_lto->next;
1274 	  offload_files_last_lto->next = ofld;
1275 	}
1276       else
1277 	/* Add non-LTO file or first non-archive LTO file to the end of the
1278 	   list.  */
1279 	offload_files_last->next = ofld;
1280 
1281       if (ofld->next == NULL)
1282 	offload_files_last = ofld;
1283       if (file->offset == 0)
1284 	offload_files_last_obj = ofld;
1285       if (*claimed)
1286 	offload_files_last_lto = ofld;
1287       num_offload_files++;
1288     }
1289 
1290   goto cleanup;
1291 
1292  err:
1293   non_claimed_files++;
1294   free (lto_file.name);
1295 
1296  cleanup:
1297   if (obj.objfile)
1298     simple_object_release_read (obj.objfile);
1299 
1300   return LDPS_OK;
1301 }
1302 
1303 /* Parse the plugin options. */
1304 
1305 static void
process_option(const char * option)1306 process_option (const char *option)
1307 {
1308   if (strcmp (option, "-linker-output-known") == 0)
1309     linker_output_known = 1;
1310   if (strcmp (option, "-debug") == 0)
1311     debug = true;
1312   else if ((strcmp (option, "-v") == 0)
1313            || (strcmp (option, "--verbose") == 0))
1314     verbose = true;
1315   else if (strcmp (option, "-save-temps") == 0)
1316     save_temps = true;
1317   else if (strcmp (option, "-nop") == 0)
1318     nop = 1;
1319   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
1320     {
1321       num_pass_through_items++;
1322       pass_through_items = xrealloc (pass_through_items,
1323 				     num_pass_through_items * sizeof (char *));
1324       pass_through_items[num_pass_through_items - 1] =
1325           xstrdup (option + strlen ("-pass-through="));
1326     }
1327   else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
1328     {
1329       switch (option[sizeof ("-sym-style=") - 1])
1330 	{
1331 	case 'w':
1332 	  sym_style = ss_win32;
1333 	  break;
1334 	case 'u':
1335 	  sym_style = ss_uscore;
1336 	  break;
1337 	default:
1338 	  sym_style = ss_none;
1339 	  break;
1340 	}
1341     }
1342   else
1343     {
1344       int size;
1345       char *opt = xstrdup (option);
1346       lto_wrapper_num_args += 1;
1347       size = lto_wrapper_num_args * sizeof (char *);
1348       lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
1349       lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
1350       if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
1351 	resolution_file = opt + sizeof ("-fresolution=") - 1;
1352     }
1353   save_temps = save_temps || debug;
1354   verbose = verbose || debug;
1355 }
1356 
1357 /* Called by gold after loading the plugin. TV is the transfer vector. */
1358 
1359 enum ld_plugin_status
onload(struct ld_plugin_tv * tv)1360 onload (struct ld_plugin_tv *tv)
1361 {
1362   struct ld_plugin_tv *p;
1363   enum ld_plugin_status status;
1364 
1365   p = tv;
1366   while (p->tv_tag)
1367     {
1368       switch (p->tv_tag)
1369 	{
1370         case LDPT_MESSAGE:
1371           message = p->tv_u.tv_message;
1372           break;
1373 	case LDPT_REGISTER_CLAIM_FILE_HOOK:
1374 	  register_claim_file = p->tv_u.tv_register_claim_file;
1375 	  break;
1376 	case LDPT_ADD_SYMBOLS_V2:
1377 	  add_symbols_v2 = p->tv_u.tv_add_symbols;
1378 	  break;
1379 	case LDPT_ADD_SYMBOLS:
1380 	  add_symbols = p->tv_u.tv_add_symbols;
1381 	  break;
1382 	case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
1383 	  register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
1384 	  break;
1385 	case LDPT_GET_SYMBOLS_V2:
1386 	  get_symbols_v2 = p->tv_u.tv_get_symbols;
1387 	  break;
1388 	case LDPT_GET_SYMBOLS:
1389 	  get_symbols = p->tv_u.tv_get_symbols;
1390 	  break;
1391 	case LDPT_REGISTER_CLEANUP_HOOK:
1392 	  register_cleanup = p->tv_u.tv_register_cleanup;
1393 	  break;
1394 	case LDPT_ADD_INPUT_FILE:
1395 	  add_input_file = p->tv_u.tv_add_input_file;
1396 	  break;
1397 	case LDPT_ADD_INPUT_LIBRARY:
1398 	  add_input_library = p->tv_u.tv_add_input_library;
1399 	  break;
1400 	case LDPT_OPTION:
1401 	  process_option (p->tv_u.tv_string);
1402 	  break;
1403 	case LDPT_GOLD_VERSION:
1404 	  gold_version = p->tv_u.tv_val;
1405 	  break;
1406 	case LDPT_LINKER_OUTPUT:
1407 	  linker_output = (enum ld_plugin_output_file_type) p->tv_u.tv_val;
1408 	  linker_output_set = 1;
1409 	  break;
1410 	case LDPT_OUTPUT_NAME:
1411 	  /* We only use this to make user-friendly temp file names.  */
1412 	  link_output_name = p->tv_u.tv_string;
1413 	  break;
1414 	default:
1415 	  break;
1416 	}
1417       p++;
1418     }
1419 
1420   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1421   check (add_symbols, LDPL_FATAL, "add_symbols not found");
1422   status = register_claim_file (claim_file_handler);
1423   check (status == LDPS_OK, LDPL_FATAL,
1424 	 "could not register the claim_file callback");
1425 
1426   if (register_cleanup)
1427     {
1428       status = register_cleanup (cleanup_handler);
1429       check (status == LDPS_OK, LDPL_FATAL,
1430 	     "could not register the cleanup callback");
1431     }
1432 
1433   if (register_all_symbols_read)
1434     {
1435       check (get_symbols, LDPL_FATAL, "get_symbols not found");
1436       status = register_all_symbols_read (all_symbols_read_handler);
1437       check (status == LDPS_OK, LDPL_FATAL,
1438 	     "could not register the all_symbols_read callback");
1439     }
1440 
1441   char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
1442   if (collect_gcc_options)
1443     {
1444       /* Support -fno-use-linker-plugin by failing to load the plugin
1445 	 for the case where it is auto-loaded by BFD.  */
1446       if (strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
1447 	return LDPS_ERR;
1448 
1449       if ( strstr (collect_gcc_options, "'-save-temps'"))
1450 	save_temps = true;
1451 
1452       if (strstr (collect_gcc_options, "'-v'")
1453           || strstr (collect_gcc_options, "'--verbose'"))
1454 	verbose = true;
1455     }
1456 
1457   return LDPS_OK;
1458 }
1459