]> git.ipfire.org Git - thirdparty/gcc.git/blame - lto-plugin/lto-plugin.c
Detect overflow by atomic functions [PR102453].
[thirdparty/gcc.git] / lto-plugin / lto-plugin.c
CommitLineData
1cd0b716 1/* LTO plugin for gold and/or GNU ld.
99dee823 2 Copyright (C) 2009-2021 Free Software Foundation, Inc.
d7f09764
DN
3 Contributed by Rafael Avila de Espindola (espindola@google.com).
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 3, or (at your option)
8any later version.
9
10This program is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along 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.
de54061d 30 It also has options at his own:
d7f09764
DN
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
de54061d
JH
33 only works if the input files are hybrid.
34 -linker-output-known: Do not determine linker output
5269b246
EB
35 -linker-output-auto-notlo-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.
de54061d
JH
38 -sym-style={none,win32,underscore|uscore}
39 -pass-through */
d7f09764 40
48215350
DK
41#ifdef HAVE_CONFIG_H
42#include "config.h"
43#endif
d19e0f01
DK
44#if HAVE_STDINT_H
45#include <stdint.h>
46#endif
c101cff8 47#include <stdbool.h>
d7f09764 48#include <assert.h>
2486c24a 49#include <errno.h>
d7f09764
DN
50#include <string.h>
51#include <stdlib.h>
52#include <stdio.h>
53#include <inttypes.h>
d7f09764
DN
54#include <sys/stat.h>
55#include <unistd.h>
56#include <fcntl.h>
57#include <sys/types.h>
a2254c5d 58#ifdef HAVE_SYS_WAIT_H
d7f09764 59#include <sys/wait.h>
a2254c5d 60#endif
ec692d5f
KT
61#ifndef WIFEXITED
62#define WIFEXITED(S) (((S) & 0xff) == 0)
63#endif
64#ifndef WEXITSTATUS
65#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
66#endif
d7f09764 67#include <libiberty.h>
d2c57fe9 68#include <hashtab.h>
d7f09764 69#include "../gcc/lto/common.h"
48215350
DK
70#include "simple-object.h"
71#include "plugin-api.h"
d7f09764 72
8cfa7899
KT
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
48215350
DK
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
a2d7e58f 92/* Return true if STR string starts with PREFIX. */
48215350 93
a2d7e58f
ML
94static inline bool
95startswith (const char *str, const char *prefix)
96{
97 return strncmp (str, prefix, strlen (prefix)) == 0;
98}
48215350
DK
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
ad7715f3
L
102 copy the symbol information.
103 The id must be 64bit to minimze collisions. */
48215350
DK
104
105struct sym_aux
106{
107 uint32_t slot;
ad7715f3 108 unsigned long long id;
48215350
DK
109 unsigned next_conflict;
110};
111
112struct plugin_symtab
113{
114 int nsyms;
ad2a3715 115 int last_sym;
48215350
DK
116 struct sym_aux *aux;
117 struct ld_plugin_symbol *syms;
ad7715f3 118 unsigned long long id;
48215350
DK
119};
120
121/* Encapsulates object file data during symbol scan. */
122struct plugin_objfile
123{
124 int found;
fc8b3540 125 int offload;
48215350
DK
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
133struct plugin_file_info
134{
135 char *name;
136 void *handle;
137 struct plugin_symtab symtab;
138 struct plugin_symtab conflicts;
139};
140
e6861a99
IV
141/* List item with name of the file with offloading. */
142
143struct plugin_offload_file
144{
145 char *name;
146 struct plugin_offload_file *next;
147};
148
48215350
DK
149/* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
150 stdio file streams, we do simple label translation here. */
151
152enum 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};
d7f09764 158
94086ef6 159static char *arguments_file_name;
d7f09764 160static ld_plugin_register_claim_file register_claim_file;
d7f09764 161static ld_plugin_register_all_symbols_read register_all_symbols_read;
ed0d2da0 162static ld_plugin_get_symbols get_symbols, get_symbols_v2;
d7f09764
DN
163static ld_plugin_register_cleanup register_cleanup;
164static ld_plugin_add_input_file add_input_file;
d520c7fb 165static ld_plugin_add_input_library add_input_library;
33662270 166static ld_plugin_message message;
c8429c2a 167static ld_plugin_add_symbols add_symbols, add_symbols_v2;
d7f09764 168
48215350
DK
169static struct plugin_file_info *claimed_files = NULL;
170static unsigned int num_claimed_files = 0;
de54061d 171static unsigned int non_claimed_files = 0;
d7f09764 172
e6861a99
IV
173/* List of files with offloading. */
174static struct plugin_offload_file *offload_files;
175/* Last file in the list. */
176static struct plugin_offload_file *offload_files_last;
177/* Last non-archive file in the list. */
178static struct plugin_offload_file *offload_files_last_obj;
179/* Last LTO file in the list. */
180static struct plugin_offload_file *offload_files_last_lto;
181/* Total number of files with offloading. */
182static unsigned num_offload_files;
443743fd 183
d7f09764
DN
184static char **output_files = NULL;
185static unsigned int num_output_files = 0;
186
187static char **lto_wrapper_argv;
188static int lto_wrapper_num_args;
189
190static char **pass_through_items = NULL;
191static unsigned int num_pass_through_items;
192
c6c7ac04
RB
193static char *ltrans_objects = NULL;
194
c101cff8
IS
195static bool debug;
196static bool save_temps;
197static bool verbose;
d19e0f01 198static char nop;
b10071c5 199static char *resolution_file = NULL;
1ff9ed6f 200static enum ld_plugin_output_file_type linker_output;
5269b246
EB
201static bool linker_output_set;
202static bool linker_output_known;
203static bool linker_output_auto_nolto_rel;
c101cff8 204static const char *link_output_name = NULL;
d7f09764 205
1dedc12d
AO
206/* This indicates link_output_name already contains the dot of the
207 suffix, so we can skip it in extensions. */
208static int skip_in_suffix = 0;
209
e3bb089d
ILT
210/* The version of gold being used, or -1 if not gold. The number is
211 MAJOR * 100 + MINOR. */
212static int gold_version = -1;
213
77754180 214/* Not used by default, but can be overridden at runtime
48215350
DK
215 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
216 (in fact, only first letter of style arg is checked.) */
77754180 217static enum symbol_style sym_style = ss_none;
48215350
DK
218
219static void
d19e0f01 220check_1 (int gate, enum ld_plugin_level level, const char *text)
33662270
RAE
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
d19e0f01
DK
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
d7f09764
DN
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
48215350 245static char *
73ce4d1e
AK
246parse_table_entry (char *p, struct ld_plugin_symbol *entry,
247 struct sym_aux *aux)
d7f09764
DN
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
48215350
DK
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:
d19e0f01 282 check (0, LDPL_FATAL, "invalid symbol style requested");
48215350
DK
283 break;
284 }
d7f09764
DN
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
ed0f0c0f 299 entry->comdat_key = xstrdup (entry->comdat_key);
d7f09764 300
c8429c2a
ML
301 entry->unused = entry->section_kind = entry->symbol_type = 0;
302
d7f09764 303 t = *p;
33662270 304 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
d7f09764
DN
305 entry->def = translate_kind[t];
306 p++;
307
308 t = *p;
33662270 309 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
d7f09764
DN
310 entry->visibility = translate_visibility[t];
311 p++;
312
47782a9d 313 memcpy (&entry->size, p, sizeof (uint64_t));
d7f09764
DN
314 p += 8;
315
47782a9d 316 memcpy (&aux->slot, p, sizeof (uint32_t));
d7f09764
DN
317 p += 4;
318
319 entry->resolution = LDPR_UNKNOWN;
320
d2c57fe9
AK
321 aux->next_conflict = -1;
322
d7f09764
DN
323 return p;
324}
325
c8429c2a
ML
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
330static char *
331parse_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
1cd0b716
DK
352/* Translate the IL symbol table located between DATA and END. Append the
353 slots and symbols to OUT. */
73ce4d1e 354
48215350 355static void
1cd0b716 356translate (char *data, char *end, struct plugin_symtab *out)
73ce4d1e
AK
357{
358 struct sym_aux *aux;
73ce4d1e
AK
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
73ce4d1e
AK
375 assert(n < len);
376
377 out->nsyms = n;
378 out->syms = syms;
379 out->aux = aux;
380}
381
c8429c2a
ML
382static void
383parse_symtab_extension (char *data, char *end, struct plugin_symtab *out)
384{
ad2a3715
NC
385 unsigned long i;
386 unsigned char version;
387
388 if (data >= end)
389 /* FIXME: Issue an error ? */
390 return;
c8429c2a 391
ad2a3715 392 version = *data;
c8429c2a
ML
393 data++;
394
ad2a3715
NC
395 if (version != 1)
396 return;
397
c8429c2a
ML
398 /* Version 1 contains the following data per entry:
399 - symbol_type
400 - section_kind
401 . */
402
ad2a3715
NC
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;
c8429c2a
ML
409}
410
b10071c5
RAE
411/* Free all memory that is no longer needed after writing the symbol
412 resolution. */
d7f09764
DN
413
414static void
443743fd 415free_1 (struct plugin_file_info *files, unsigned num_files)
d7f09764
DN
416{
417 unsigned int i;
443743fd 418 for (i = 0; i < num_files; i++)
d7f09764 419 {
443743fd 420 struct plugin_file_info *info = &files[i];
d7f09764
DN
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);
04695783 427 free (s->comdat_key);
d7f09764
DN
428 }
429 free (symtab->syms);
430 symtab->syms = NULL;
431 }
432}
433
434/* Free all remaining memory. */
435
436static void
437free_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;
73ce4d1e 444 free (symtab->aux);
d7f09764
DN
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
e6861a99
IV
456 while (offload_files)
457 {
458 struct plugin_offload_file *ofld = offload_files;
459 offload_files = offload_files->next;
460 free (ofld);
461 }
443743fd
IV
462 num_offload_files = 0;
463
04695783 464 free (arguments_file_name);
94086ef6 465 arguments_file_name = NULL;
d7f09764
DN
466}
467
d2c57fe9
AK
468/* Dump SYMTAB to resolution file F. */
469
470static void
471dump_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
8cfa7899 482 fprintf (f, "%u %" PRI_LL "x %s %s\n",
ad7715f3 483 (unsigned int) slot, symtab->aux[j].id,
d2c57fe9
AK
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
492static void
493finish_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 {
c8429c2a 503 char resolution = LDPR_UNKNOWN;
d2c57fe9
AK
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
536static void
537free_symtab (struct plugin_symtab *symtab)
538{
539 free (symtab->syms);
540 symtab->syms = NULL;
541 free (symtab->aux);
542 symtab->aux = NULL;
543}
544
d7f09764
DN
545/* Writes the relocations to disk. */
546
547static void
548write_resolution (void)
549{
550 unsigned int i;
551 FILE *f;
d7f09764 552
5cd0e96b 553 check (resolution_file, LDPL_FATAL, "resolution file not specified");
b10071c5 554 f = fopen (resolution_file, "w");
33662270 555 check (f, LDPL_FATAL, "could not open file");
d7f09764
DN
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;
b10071c5 563 struct ld_plugin_symbol *syms = symtab->syms;
d7f09764 564
ed0d2da0
JH
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);
d7f09764 571
d2c57fe9 572 finish_conflict_resolution (symtab, &info->conflicts);
d7f09764 573
d2c57fe9
AK
574 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
575 dump_symtab (f, symtab);
576 if (info->conflicts.nsyms)
d7f09764 577 {
d2c57fe9
AK
578 dump_symtab (f, &info->conflicts);
579 free_symtab (&info->conflicts);
d7f09764 580 }
d7f09764
DN
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
588static void
589add_output_files (FILE *f)
590{
d7f09764
DN
591 for (;;)
592 {
ed0f0c0f
RG
593 const unsigned piece = 32;
594 char *buf, *s = xmalloc (piece);
d7f09764 595 size_t len;
d7f09764 596
ed0f0c0f
RG
597 buf = s;
598cont:
599 if (!fgets (buf, piece, f))
44538c62
KT
600 {
601 free (s);
602 break;
603 }
d7f09764 604 len = strlen (s);
ed0f0c0f
RG
605 if (s[len - 1] != '\n')
606 {
607 s = xrealloc (s, len + piece);
608 buf = s + len;
609 goto cont;
610 }
d7f09764
DN
611 s[len - 1] = '\0';
612
613 num_output_files++;
ed0f0c0f
RG
614 output_files
615 = xrealloc (output_files, num_output_files * sizeof (char *));
616 output_files[num_output_files - 1] = s;
d7f09764
DN
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
624static void
625exec_lto_wrapper (char *argv[])
626{
f0d61983 627 int t, i;
d7f09764
DN
628 int status;
629 char *at_args;
d7f09764
DN
630 FILE *args;
631 FILE *wrapper_output;
632 char *new_argv[3];
633 struct pex_obj *pex;
634 const char *errmsg;
635
c101cff8
IS
636 /* Write argv to a file to avoid a command line that is too long
637 Save the file locally on save-temps. */
e9fc9d07
ML
638 const char *suffix = ".lto_wrapper_args";
639 suffix += skip_in_suffix;
c101cff8 640 if (save_temps && link_output_name)
e9fc9d07 641 arguments_file_name = concat (link_output_name, suffix, NULL);
c101cff8 642 else
1dedc12d 643 arguments_file_name = make_temp_file (".lto_wrapper_args");
94086ef6
RAE
644 check (arguments_file_name, LDPL_FATAL,
645 "Failed to generate a temorary file name");
d7f09764 646
94086ef6 647 args = fopen (arguments_file_name, "w");
33662270 648 check (args, LDPL_FATAL, "could not open arguments file");
d7f09764
DN
649
650 t = writeargv (&argv[1], args);
33662270 651 check (t == 0, LDPL_FATAL, "could not write arguments");
d7f09764 652 t = fclose (args);
33662270 653 check (t == 0, LDPL_FATAL, "could not close arguments file");
d7f09764 654
94086ef6
RAE
655 at_args = concat ("@", arguments_file_name, NULL);
656 check (at_args, LDPL_FATAL, "could not allocate");
657
f0d61983
L
658 for (i = 1; argv[i]; i++)
659 {
660 char *a = argv[i];
c101cff8 661 /* Check the input argument list for a verbose marker too. */
f0d61983
L
662 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
663 {
c101cff8 664 verbose = true;
f0d61983
L
665 break;
666 }
667 }
668
c101cff8
IS
669 if (verbose)
670 {
671 for (i = 0; argv[i]; i++)
672 fprintf (stderr, "%s ", argv[i]);
673 fprintf (stderr, "\n");
674 }
675
d7f09764
DN
676 new_argv[0] = argv[0];
677 new_argv[1] = at_args;
678 new_argv[2] = NULL;
679
680 if (debug)
681 {
d7f09764
DN
682 for (i = 0; new_argv[i]; i++)
683 fprintf (stderr, "%s ", new_argv[i]);
684 fprintf (stderr, "\n");
685 }
686
d7f09764 687 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
33662270 688 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
d7f09764
DN
689
690 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
33662270
RAE
691 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
692 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
d7f09764
DN
693
694 wrapper_output = pex_read_output (pex, 0);
33662270 695 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
d7f09764
DN
696
697 add_output_files (wrapper_output);
698
699 t = pex_get_status (pex, 1, &status);
33662270
RAE
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");
d7f09764
DN
703
704 pex_free (pex);
705
d7f09764
DN
706 free (at_args);
707}
708
709/* Pass the original files back to the linker. */
710
711static void
712use_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
725static enum ld_plugin_status
726all_symbols_read_handler (void)
727{
5269b246
EB
728 const unsigned num_lto_args
729 = num_claimed_files + lto_wrapper_num_args + 2
730 + !linker_output_known + !linker_output_auto_nolto_rel;
d7f09764 731 unsigned i;
d7f09764 732 char **lto_argv;
aea40b08 733 const char *linker_output_str = NULL;
d7f09764 734 const char **lto_arg_ptr;
443743fd 735 if (num_claimed_files + num_offload_files == 0)
d7f09764
DN
736 return LDPS_OK;
737
d7f09764
DN
738 if (nop)
739 {
740 use_original_files ();
741 return LDPS_OK;
742 }
743
c6c7ac04
RB
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
ed0f0c0f 752 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
d7f09764
DN
753 lto_arg_ptr = (const char **) lto_argv;
754 assert (lto_wrapper_argv);
755
756 write_resolution ();
757
443743fd 758 free_1 (claimed_files, num_claimed_files);
b10071c5 759
d7f09764
DN
760 for (i = 0; i < lto_wrapper_num_args; i++)
761 *lto_arg_ptr++ = lto_wrapper_argv[i];
762
de54061d 763 if (!linker_output_known)
1ff9ed6f 764 {
de54061d
JH
765 assert (linker_output_set);
766 switch (linker_output)
767 {
768 case LDPO_REL:
769 if (non_claimed_files)
770 {
5269b246
EB
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");
de54061d
JH
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);
1ff9ed6f 794 }
e6861a99
IV
795
796 if (num_offload_files > 0)
d7f09764 797 {
e6861a99
IV
798 FILE *f;
799 char *arg;
800 char *offload_objects_file_name;
801 struct plugin_offload_file *ofld;
802
803 offload_objects_file_name = make_temp_file (".ofldlist");
804 check (offload_objects_file_name, LDPL_FATAL,
805 "Failed to generate a temporary file name");
806 f = fopen (offload_objects_file_name, "w");
807 check (f, LDPL_FATAL, "could not open file with offload objects");
808 fprintf (f, "%u\n", num_offload_files);
809
810 /* Skip the dummy item at the start of the list. */
811 ofld = offload_files->next;
812 while (ofld)
813 {
814 fprintf (f, "%s\n", ofld->name);
815 ofld = ofld->next;
816 }
817 fclose (f);
d7f09764 818
e6861a99
IV
819 arg = concat ("-foffload-objects=", offload_objects_file_name, NULL);
820 check (arg, LDPL_FATAL, "could not allocate");
821 *lto_arg_ptr++ = arg;
d7f09764
DN
822 }
823
e6861a99 824 for (i = 0; i < num_claimed_files; i++)
443743fd 825 {
e6861a99 826 struct plugin_file_info *info = &claimed_files[i];
443743fd
IV
827
828 *lto_arg_ptr++ = info->name;
829 }
830
d7f09764
DN
831 *lto_arg_ptr++ = NULL;
832 exec_lto_wrapper (lto_argv);
833
834 free (lto_argv);
835
e3bb089d
ILT
836 /* --pass-through is not needed when using gold 1.11 or later. */
837 if (pass_through_items && gold_version < 111)
d7f09764
DN
838 {
839 unsigned int i;
840 for (i = 0; i < num_pass_through_items; i++)
841 {
a2d7e58f 842 if (startswith (pass_through_items[i], "-l"))
d520c7fb
RAE
843 add_input_library (pass_through_items[i] + 2);
844 else
845 add_input_file (pass_through_items[i]);
d7f09764
DN
846 free (pass_through_items[i]);
847 pass_through_items[i] = NULL;
848 }
849 free (pass_through_items);
850 pass_through_items = NULL;
851 }
852
853 return LDPS_OK;
854}
855
c101cff8
IS
856/* Helper, as used in collect2. */
857static int
858file_exists (const char *name)
859{
860 return access (name, R_OK) == 0;
861}
862
863/* Unlink FILE unless we have save-temps set.
864 Note that we're saving files if verbose output is set. */
865
866static void
867maybe_unlink (const char *file)
868{
869 if (save_temps && file_exists (file))
870 {
871 if (verbose)
872 fprintf (stderr, "[Leaving %s]\n", file);
873 return;
874 }
875
876 unlink_if_ordinary (file);
877}
878
d7f09764
DN
879/* Remove temporary files at the end of the link. */
880
881static enum ld_plugin_status
882cleanup_handler (void)
883{
a8a5ac48 884 unsigned int i;
d7f09764 885
1cddcdca
RAE
886 if (debug)
887 return LDPS_OK;
888
94086ef6 889 if (arguments_file_name)
c101cff8 890 maybe_unlink (arguments_file_name);
d7f09764 891
a8a5ac48 892 for (i = 0; i < num_output_files; i++)
c101cff8 893 maybe_unlink (output_files[i]);
a8a5ac48 894
d7f09764
DN
895 free_2 ();
896 return LDPS_OK;
897}
898
d2c57fe9
AK
899#define SWAP(type, a, b) \
900 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
901
902/* Compare two hash table entries */
903
904static int eq_sym (const void *a, const void *b)
905{
906 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
907 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
908
909 return !strcmp (as->name, bs->name);
910}
911
912/* Hash a symbol */
913
914static hashval_t hash_sym (const void *a)
915{
916 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
917
918 return htab_hash_string (as->name);
919}
920
921/* Determine how strong a symbol is */
922
923static int symbol_strength (struct ld_plugin_symbol *s)
924{
925 switch (s->def)
926 {
927 case LDPK_UNDEF:
928 case LDPK_WEAKUNDEF:
929 return 0;
930 case LDPK_WEAKDEF:
931 return 1;
932 default:
933 return 2;
934 }
935}
936
937/* In the ld -r case we can get dups in the LTO symbol tables, where
938 the same symbol can have different resolutions (e.g. undefined and defined).
939
940 We have to keep that in the LTO symbol tables, but the dups confuse
941 gold and then finally gcc by supplying incorrect resolutions.
942
943 Problem is that the main gold symbol table doesn't know about subids
944 and does not distingush the same symbols in different states.
945
946 So we drop duplicates from the linker visible symbol table
947 and keep them in a private table. Then later do own symbol
948 resolution for the duplicated based on the results for the
949 originals.
950
951 Then when writing out the resolution file readd the dropped symbols.
952
953 XXX how to handle common? */
954
48215350 955static void
d2c57fe9
AK
956resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
957{
958 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
959 int i;
960 int out;
961 int outlen;
962
963 outlen = t->nsyms;
964 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
965 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
966
3f417959 967 /* Move all duplicate symbols into the auxiliary conflicts table. */
d2c57fe9
AK
968 out = 0;
969 for (i = 0; i < t->nsyms; i++)
970 {
971 struct ld_plugin_symbol *s = &t->syms[i];
972 struct sym_aux *aux = &t->aux[i];
973 void **slot;
974
975 slot = htab_find_slot (symtab, s, INSERT);
976 if (*slot != NULL)
977 {
978 int cnf;
979 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
980 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
981
982 /* Always let the linker resolve the strongest symbol */
983 if (symbol_strength (orig) < symbol_strength (s))
984 {
985 SWAP (struct ld_plugin_symbol, *orig, *s);
986 SWAP (uint32_t, orig_aux->slot, aux->slot);
ad7715f3 987 SWAP (unsigned long long, orig_aux->id, aux->id);
d2c57fe9
AK
988 /* Don't swap conflict chain pointer */
989 }
990
991 /* Move current symbol into the conflicts table */
992 cnf = conflicts->nsyms++;
993 conflicts->syms[cnf] = *s;
994 conflicts->aux[cnf] = *aux;
995 aux = &conflicts->aux[cnf];
996
997 /* Update conflicts chain of the original symbol */
998 aux->next_conflict = orig_aux->next_conflict;
999 orig_aux->next_conflict = cnf;
1000
1001 continue;
1002 }
1003
1004 /* Remove previous duplicates in the main table */
1005 if (out < i)
1006 {
1007 t->syms[out] = *s;
1008 t->aux[out] = *aux;
1009 }
1010
1011 /* Put original into the hash table */
1012 *slot = &t->syms[out];
1013 out++;
1014 }
1015
1016 assert (conflicts->nsyms <= outlen);
1017 assert (conflicts->nsyms + out == t->nsyms);
1018
1019 t->nsyms = out;
1020 htab_delete (symtab);
1021}
1022
48215350
DK
1023/* Process one section of an object file. */
1024
1025static int
1026process_symtab (void *data, const char *name, off_t offset, off_t length)
1027{
1028 struct plugin_objfile *obj = (struct plugin_objfile *)data;
1029 char *s;
2486c24a 1030 char *secdatastart, *secdata;
48215350 1031
a2d7e58f 1032 if (!startswith (name, ".gnu.lto_.symtab"))
48215350
DK
1033 return 1;
1034
1035 s = strrchr (name, '.');
1036 if (s)
8cfa7899 1037 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
2486c24a 1038 secdata = secdatastart = xmalloc (length);
48215350 1039 offset += obj->file->offset;
2486c24a
RB
1040 if (offset != lseek (obj->file->fd, offset, SEEK_SET))
1041 goto err;
1042
1043 do
48215350 1044 {
2486c24a
RB
1045 ssize_t got = read (obj->file->fd, secdata, length);
1046 if (got == 0)
1047 break;
1048 else if (got > 0)
1049 {
1050 secdata += got;
1051 length -= got;
1052 }
1053 else if (errno != EINTR)
1054 goto err;
48215350 1055 }
2486c24a
RB
1056 while (length > 0);
1057 if (length > 0)
1058 goto err;
48215350 1059
2486c24a 1060 translate (secdatastart, secdata, obj->out);
48215350 1061 obj->found++;
2486c24a 1062 free (secdatastart);
48215350 1063 return 1;
2486c24a
RB
1064
1065err:
1066 if (message)
1067 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
1068 /* Force claim_file_handler to abandon this file. */
1069 obj->found = 0;
1070 free (secdatastart);
1071 return 0;
48215350
DK
1072}
1073
c8429c2a
ML
1074/* Process one section of an object file. */
1075
1076static int
1077process_symtab_extension (void *data, const char *name, off_t offset,
1078 off_t length)
1079{
1080 struct plugin_objfile *obj = (struct plugin_objfile *)data;
1081 char *s;
1082 char *secdatastart, *secdata;
1083
a2d7e58f 1084 if (!startswith (name, ".gnu.lto_.ext_symtab"))
c8429c2a
ML
1085 return 1;
1086
1087 s = strrchr (name, '.');
1088 if (s)
1089 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
1090 secdata = secdatastart = xmalloc (length);
1091 offset += obj->file->offset;
1092 if (offset != lseek (obj->file->fd, offset, SEEK_SET))
1093 goto err;
1094
1095 do
1096 {
1097 ssize_t got = read (obj->file->fd, secdata, length);
1098 if (got == 0)
1099 break;
1100 else if (got > 0)
1101 {
1102 secdata += got;
1103 length -= got;
1104 }
1105 else if (errno != EINTR)
1106 goto err;
1107 }
1108 while (length > 0);
1109 if (length > 0)
1110 goto err;
1111
1112 parse_symtab_extension (secdatastart, secdata, obj->out);
1113 obj->found++;
1114 free (secdatastart);
1115 return 1;
1116
1117err:
1118 if (message)
1119 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
1120 /* Force claim_file_handler to abandon this file. */
1121 obj->found = 0;
1122 free (secdatastart);
1123 return 0;
1124}
1125
1126
fc8b3540
IV
1127/* Find an offload section of an object file. */
1128
1129static int
1130process_offload_section (void *data, const char *name, off_t offset, off_t len)
1131{
a2d7e58f 1132 if (startswith (name, ".gnu.offload_lto_.opts"))
fc8b3540
IV
1133 {
1134 struct plugin_objfile *obj = (struct plugin_objfile *) data;
1135 obj->offload = 1;
1136 return 0;
1137 }
1138
1139 return 1;
1140}
1141
48215350
DK
1142/* Callback used by gold to check if the plugin will claim FILE. Writes
1143 the result in CLAIMED. */
1144
1145static enum ld_plugin_status
1146claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
1147{
1148 enum ld_plugin_status status;
1149 struct plugin_objfile obj;
1150 struct plugin_file_info lto_file;
1151 int err;
1152 const char *errmsg;
1153
1154 memset (&lto_file, 0, sizeof (struct plugin_file_info));
1155
1156 if (file->offset != 0)
1157 {
d19e0f01
DK
1158 /* We pass the offset of the actual file, not the archive header.
1159 Can't use PRIx64, because that's C99, so we have to print the
5c2dee6f
GJL
1160 64-bit hex int as two 32-bit ones. Use xasprintf instead of
1161 asprintf because asprintf doesn't work as expected on some older
1162 mingw32 hosts. */
1163 int lo, hi;
d19e0f01
DK
1164 lo = file->offset & 0xffffffff;
1165 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
5c2dee6f
GJL
1166 lto_file.name = hi ? xasprintf ("%s@0x%x%08x", file->name, hi, lo)
1167 : xasprintf ("%s@0x%x", file->name, lo);
48215350
DK
1168 }
1169 else
1170 {
1171 lto_file.name = xstrdup (file->name);
1172 }
1173 lto_file.handle = file->handle;
1174
1175 *claimed = 0;
1176 obj.file = file;
1177 obj.found = 0;
fc8b3540 1178 obj.offload = 0;
48215350
DK
1179 obj.out = &lto_file.symtab;
1180 errmsg = NULL;
1181 obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
1182 &errmsg, &err);
1183 /* No file, but also no error code means unrecognized format; just skip it. */
1184 if (!obj.objfile && !err)
1185 goto err;
1186
c8429c2a
ML
1187 if (obj.objfile)
1188 {
1189 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj,
1190 &err);
1191 /* Parsing symtab extension should be done only for add_symbols_v2 and
1192 later versions. */
1193 if (!errmsg && add_symbols_v2 != NULL)
ad2a3715
NC
1194 {
1195 obj.out->last_sym = 0;
1196 errmsg = simple_object_find_sections (obj.objfile,
1197 process_symtab_extension,
1198 &obj, &err);
1199 }
c8429c2a 1200 }
48215350
DK
1201
1202 if (!obj.objfile || errmsg)
1203 {
1204 if (err && message)
1205 message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
1206 xstrerror (err));
1207 else if (message)
1208 message (LDPL_FATAL, "%s: %s", file->name, errmsg);
1209 goto err;
1210 }
1211
fc8b3540
IV
1212 if (obj.objfile)
1213 simple_object_find_sections (obj.objfile, process_offload_section,
1214 &obj, &err);
1215
1216 if (obj.found == 0 && obj.offload == 0)
48215350
DK
1217 goto err;
1218
1219 if (obj.found > 1)
1220 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
1221
443743fd
IV
1222 if (obj.found > 0)
1223 {
c8429c2a
ML
1224 if (add_symbols_v2)
1225 status = add_symbols_v2 (file->handle, lto_file.symtab.nsyms,
1226 lto_file.symtab.syms);
1227 else
1228 status = add_symbols (file->handle, lto_file.symtab.nsyms,
1229 lto_file.symtab.syms);
443743fd
IV
1230 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
1231
1232 num_claimed_files++;
1233 claimed_files =
1234 xrealloc (claimed_files,
1235 num_claimed_files * sizeof (struct plugin_file_info));
1236 claimed_files[num_claimed_files - 1] = lto_file;
e6861a99
IV
1237
1238 *claimed = 1;
443743fd
IV
1239 }
1240
e6861a99 1241 if (offload_files == NULL)
443743fd 1242 {
e6861a99
IV
1243 /* Add dummy item to the start of the list. */
1244 offload_files = xmalloc (sizeof (struct plugin_offload_file));
1245 offload_files->name = NULL;
1246 offload_files->next = NULL;
1247 offload_files_last = offload_files;
443743fd 1248 }
48215350 1249
e6861a99
IV
1250 /* If this is an LTO file without offload, and it is the first LTO file, save
1251 the pointer to the last offload file in the list. Further offload LTO
1252 files will be inserted after it, if any. */
1253 if (*claimed && obj.offload == 0 && offload_files_last_lto == NULL)
1254 offload_files_last_lto = offload_files_last;
1255
1256 if (obj.offload == 1)
1257 {
1258 /* Add file to the list. The order must be exactly the same as the final
1259 order after recompilation and linking, otherwise host and target tables
1260 with addresses wouldn't match. If a static library contains both LTO
1261 and non-LTO objects, ld and gold link them in a different order. */
1262 struct plugin_offload_file *ofld
1263 = xmalloc (sizeof (struct plugin_offload_file));
1264 ofld->name = lto_file.name;
1265 ofld->next = NULL;
1266
1267 if (*claimed && offload_files_last_lto == NULL && file->offset != 0
1268 && gold_version == -1)
1269 {
1270 /* ld only: insert first LTO file from the archive after the last real
1271 object file immediately preceding the archive, or at the begin of
1272 the list if there was no real objects before archives. */
1273 if (offload_files_last_obj != NULL)
1274 {
1275 ofld->next = offload_files_last_obj->next;
1276 offload_files_last_obj->next = ofld;
1277 }
1278 else
1279 {
1280 ofld->next = offload_files->next;
1281 offload_files->next = ofld;
1282 }
1283 }
1284 else if (*claimed && offload_files_last_lto != NULL)
1285 {
1286 /* Insert LTO file after the last LTO file in the list. */
1287 ofld->next = offload_files_last_lto->next;
1288 offload_files_last_lto->next = ofld;
1289 }
1290 else
1291 /* Add non-LTO file or first non-archive LTO file to the end of the
1292 list. */
1293 offload_files_last->next = ofld;
1294
1295 if (ofld->next == NULL)
1296 offload_files_last = ofld;
1297 if (file->offset == 0)
1298 offload_files_last_obj = ofld;
1299 if (*claimed)
1300 offload_files_last_lto = ofld;
1301 num_offload_files++;
1302 }
48215350
DK
1303
1304 goto cleanup;
1305
1306 err:
de54061d 1307 non_claimed_files++;
48215350
DK
1308 free (lto_file.name);
1309
1310 cleanup:
1311 if (obj.objfile)
1312 simple_object_release_read (obj.objfile);
48215350
DK
1313
1314 return LDPS_OK;
1315}
1316
d7f09764
DN
1317/* Parse the plugin options. */
1318
1319static void
1320process_option (const char *option)
1321{
de54061d 1322 if (strcmp (option, "-linker-output-known") == 0)
5269b246
EB
1323 linker_output_known = true;
1324 else if (strcmp (option, "-linker-output-auto-notlo-rel") == 0)
1325 linker_output_auto_nolto_rel = true;
1326 else if (strcmp (option, "-debug") == 0)
c101cff8
IS
1327 debug = true;
1328 else if ((strcmp (option, "-v") == 0)
1329 || (strcmp (option, "--verbose") == 0))
1330 verbose = true;
1331 else if (strcmp (option, "-save-temps") == 0)
1332 save_temps = true;
d7f09764
DN
1333 else if (strcmp (option, "-nop") == 0)
1334 nop = 1;
a2d7e58f 1335 else if (startswith (option, "-pass-through="))
d7f09764
DN
1336 {
1337 num_pass_through_items++;
ed0f0c0f
RG
1338 pass_through_items = xrealloc (pass_through_items,
1339 num_pass_through_items * sizeof (char *));
d520c7fb 1340 pass_through_items[num_pass_through_items - 1] =
ed0f0c0f 1341 xstrdup (option + strlen ("-pass-through="));
d7f09764 1342 }
a2d7e58f 1343 else if (startswith (option, "-sym-style="))
48215350
DK
1344 {
1345 switch (option[sizeof ("-sym-style=") - 1])
1346 {
1347 case 'w':
1348 sym_style = ss_win32;
1349 break;
1350 case 'u':
1351 sym_style = ss_uscore;
1352 break;
1353 default:
1354 sym_style = ss_none;
1355 break;
1356 }
1357 }
c6c7ac04
RB
1358 else if (startswith (option, "-ltrans-objects="))
1359 ltrans_objects = xstrdup (option + strlen ("-ltrans-objects="));
d7f09764
DN
1360 else
1361 {
1362 int size;
5cd0e96b 1363 char *opt = xstrdup (option);
d7f09764
DN
1364 lto_wrapper_num_args += 1;
1365 size = lto_wrapper_num_args * sizeof (char *);
ed0f0c0f 1366 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
5cd0e96b 1367 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
a2d7e58f 1368 if (startswith (option, "-fresolution="))
5cd0e96b 1369 resolution_file = opt + sizeof ("-fresolution=") - 1;
d7f09764 1370 }
c101cff8
IS
1371 save_temps = save_temps || debug;
1372 verbose = verbose || debug;
d7f09764
DN
1373}
1374
1375/* Called by gold after loading the plugin. TV is the transfer vector. */
1376
1377enum ld_plugin_status
1378onload (struct ld_plugin_tv *tv)
1379{
1380 struct ld_plugin_tv *p;
1381 enum ld_plugin_status status;
d7f09764 1382
d7f09764
DN
1383 p = tv;
1384 while (p->tv_tag)
1385 {
1386 switch (p->tv_tag)
1387 {
33662270
RAE
1388 case LDPT_MESSAGE:
1389 message = p->tv_u.tv_message;
1390 break;
d7f09764
DN
1391 case LDPT_REGISTER_CLAIM_FILE_HOOK:
1392 register_claim_file = p->tv_u.tv_register_claim_file;
1393 break;
c8429c2a
ML
1394 case LDPT_ADD_SYMBOLS_V2:
1395 add_symbols_v2 = p->tv_u.tv_add_symbols;
1396 break;
d7f09764
DN
1397 case LDPT_ADD_SYMBOLS:
1398 add_symbols = p->tv_u.tv_add_symbols;
1399 break;
1400 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
1401 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
1402 break;
ed0d2da0
JH
1403 case LDPT_GET_SYMBOLS_V2:
1404 get_symbols_v2 = p->tv_u.tv_get_symbols;
1405 break;
d7f09764
DN
1406 case LDPT_GET_SYMBOLS:
1407 get_symbols = p->tv_u.tv_get_symbols;
1408 break;
1409 case LDPT_REGISTER_CLEANUP_HOOK:
1410 register_cleanup = p->tv_u.tv_register_cleanup;
1411 break;
1412 case LDPT_ADD_INPUT_FILE:
1413 add_input_file = p->tv_u.tv_add_input_file;
1414 break;
d520c7fb
RAE
1415 case LDPT_ADD_INPUT_LIBRARY:
1416 add_input_library = p->tv_u.tv_add_input_library;
1417 break;
d7f09764
DN
1418 case LDPT_OPTION:
1419 process_option (p->tv_u.tv_string);
1420 break;
e3bb089d
ILT
1421 case LDPT_GOLD_VERSION:
1422 gold_version = p->tv_u.tv_val;
1423 break;
1ff9ed6f
JH
1424 case LDPT_LINKER_OUTPUT:
1425 linker_output = (enum ld_plugin_output_file_type) p->tv_u.tv_val;
5269b246 1426 linker_output_set = true;
1ff9ed6f 1427 break;
c101cff8
IS
1428 case LDPT_OUTPUT_NAME:
1429 /* We only use this to make user-friendly temp file names. */
1430 link_output_name = p->tv_u.tv_string;
1431 break;
d7f09764
DN
1432 default:
1433 break;
1434 }
1435 p++;
1436 }
1437
33662270
RAE
1438 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1439 check (add_symbols, LDPL_FATAL, "add_symbols not found");
d7f09764 1440 status = register_claim_file (claim_file_handler);
33662270
RAE
1441 check (status == LDPS_OK, LDPL_FATAL,
1442 "could not register the claim_file callback");
d7f09764
DN
1443
1444 if (register_cleanup)
1445 {
1446 status = register_cleanup (cleanup_handler);
33662270
RAE
1447 check (status == LDPS_OK, LDPL_FATAL,
1448 "could not register the cleanup callback");
d7f09764
DN
1449 }
1450
1451 if (register_all_symbols_read)
1452 {
33662270 1453 check (get_symbols, LDPL_FATAL, "get_symbols not found");
d7f09764 1454 status = register_all_symbols_read (all_symbols_read_handler);
33662270
RAE
1455 check (status == LDPS_OK, LDPL_FATAL,
1456 "could not register the all_symbols_read callback");
d7f09764
DN
1457 }
1458
21b624f0 1459 char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
c101cff8
IS
1460 if (collect_gcc_options)
1461 {
1462 /* Support -fno-use-linker-plugin by failing to load the plugin
1463 for the case where it is auto-loaded by BFD. */
1464 if (strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
1465 return LDPS_ERR;
1466
1dedc12d 1467 if (strstr (collect_gcc_options, "'-save-temps'"))
c101cff8
IS
1468 save_temps = true;
1469
1470 if (strstr (collect_gcc_options, "'-v'")
1471 || strstr (collect_gcc_options, "'--verbose'"))
1472 verbose = true;
1dedc12d
AO
1473
1474 const char *p;
1475 if ((p = strstr (collect_gcc_options, "'-dumpdir'")))
1476 {
1477 p += sizeof ("'-dumpdir'");
1478 while (*p == ' ')
1479 p++;
1480 const char *start = p;
1481 int ticks = 0, escapes = 0;
1482 /* Count ticks (') and escaped (\.) characters. Stop at the
1483 end of the options or at a blank after an even number of
1484 ticks (not counting escaped ones. */
1485 for (p = start; *p; p++)
1486 {
1487 if (*p == '\'')
1488 {
1489 ticks++;
1490 continue;
1491 }
1492 else if ((ticks % 2) != 0)
1493 {
1494 if (*p == ' ')
1495 break;
1496 if (*p == '\\')
1497 {
1498 if (*++p)
1499 escapes++;
1500 else
1501 p--;
1502 }
1503 }
1504 }
1505
1506 /* Now allocate a new link_output_name and decode dumpdir
1507 into it. The loop uses the same logic, except it counts
1508 ticks and escapes backwards (so ticks is adjusted if we
1509 find an odd number of them), and it copies characters
1510 that are escaped or not otherwise skipped. */
1511 int len = p - start - ticks - escapes + 1;
1512 char *q = xmalloc (len);
1513 link_output_name = q;
1514 int oddticks = (ticks % 2);
1515 ticks += oddticks;
1516 for (p = start; *p; p++)
1517 {
1518 if (*p == '\'')
1519 {
1520 ticks--;
1521 continue;
1522 }
1523 else if ((ticks % 2) != 0)
1524 {
1525 if (*p == ' ')
1526 break;
1527 if (*p == '\\')
1528 {
1529 if (*++p)
1530 escapes--;
1531 else
1532 p--;
1533 }
1534 }
1535 *q++ = *p;
1536 }
1537 *q = '\0';
1538 assert (escapes == 0);
1539 assert (ticks == oddticks);
1540 assert (q - link_output_name == len - 1);
1541 skip_in_suffix = 1;
1542 }
c101cff8 1543 }
21b624f0 1544
d7f09764
DN
1545 return LDPS_OK;
1546}