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