]> git.ipfire.org Git - thirdparty/gcc.git/blame - lto-plugin/lto-plugin.c
lto-plugin: Honor link_output_name for -foffload-objects file name
[thirdparty/gcc.git] / lto-plugin / lto-plugin.c
CommitLineData
4fe0e1a4 1/* LTO plugin for linkers like gold, GNU ld or mold.
7adcbafe 2 Copyright (C) 2009-2022 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
4fe0e1a4
ML
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.
d7f09764 21
4fe0e1a4
ML
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
d7f09764
DN
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
1ea226fa 35 -linker-output-auto-nolto-rel: Switch from rel to nolto-rel mode without
5269b246
EB
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;
db494fd6 802 const char *suffix = ".ofldlist";
e6861a99 803
db494fd6
TB
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);
e6861a99
IV
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);
d7f09764 825
e6861a99
IV
826 arg = concat ("-foffload-objects=", offload_objects_file_name, NULL);
827 check (arg, LDPL_FATAL, "could not allocate");
828 *lto_arg_ptr++ = arg;
d7f09764
DN
829 }
830
e6861a99 831 for (i = 0; i < num_claimed_files; i++)
443743fd 832 {
e6861a99 833 struct plugin_file_info *info = &claimed_files[i];
443743fd
IV
834
835 *lto_arg_ptr++ = info->name;
836 }
837
d7f09764
DN
838 *lto_arg_ptr++ = NULL;
839 exec_lto_wrapper (lto_argv);
840
841 free (lto_argv);
842
e3bb089d
ILT
843 /* --pass-through is not needed when using gold 1.11 or later. */
844 if (pass_through_items && gold_version < 111)
d7f09764
DN
845 {
846 unsigned int i;
847 for (i = 0; i < num_pass_through_items; i++)
848 {
a2d7e58f 849 if (startswith (pass_through_items[i], "-l"))
d520c7fb
RAE
850 add_input_library (pass_through_items[i] + 2);
851 else
852 add_input_file (pass_through_items[i]);
d7f09764
DN
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
c101cff8
IS
863/* Helper, as used in collect2. */
864static int
865file_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
873static void
874maybe_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
d7f09764
DN
886/* Remove temporary files at the end of the link. */
887
888static enum ld_plugin_status
889cleanup_handler (void)
890{
a8a5ac48 891 unsigned int i;
d7f09764 892
1cddcdca
RAE
893 if (debug)
894 return LDPS_OK;
895
94086ef6 896 if (arguments_file_name)
c101cff8 897 maybe_unlink (arguments_file_name);
d7f09764 898
a8a5ac48 899 for (i = 0; i < num_output_files; i++)
c101cff8 900 maybe_unlink (output_files[i]);
a8a5ac48 901
d7f09764
DN
902 free_2 ();
903 return LDPS_OK;
904}
905
d2c57fe9
AK
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
911static 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
921static 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
930static 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
48215350 962static void
d2c57fe9
AK
963resolve_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
3f417959 974 /* Move all duplicate symbols into the auxiliary conflicts table. */
d2c57fe9
AK
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);
ad7715f3 994 SWAP (unsigned long long, orig_aux->id, aux->id);
d2c57fe9
AK
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
48215350
DK
1030/* Process one section of an object file. */
1031
1032static int
1033process_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;
2486c24a 1037 char *secdatastart, *secdata;
48215350 1038
a2d7e58f 1039 if (!startswith (name, ".gnu.lto_.symtab"))
48215350
DK
1040 return 1;
1041
1042 s = strrchr (name, '.');
1043 if (s)
8cfa7899 1044 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
2486c24a 1045 secdata = secdatastart = xmalloc (length);
48215350 1046 offset += obj->file->offset;
2486c24a
RB
1047 if (offset != lseek (obj->file->fd, offset, SEEK_SET))
1048 goto err;
1049
1050 do
48215350 1051 {
2486c24a
RB
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;
48215350 1062 }
2486c24a
RB
1063 while (length > 0);
1064 if (length > 0)
1065 goto err;
48215350 1066
2486c24a 1067 translate (secdatastart, secdata, obj->out);
48215350 1068 obj->found++;
2486c24a 1069 free (secdatastart);
48215350 1070 return 1;
2486c24a
RB
1071
1072err:
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;
48215350
DK
1079}
1080
c8429c2a
ML
1081/* Process one section of an object file. */
1082
1083static int
1084process_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
a2d7e58f 1091 if (!startswith (name, ".gnu.lto_.ext_symtab"))
c8429c2a
ML
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
1124err:
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
fc8b3540
IV
1134/* Find an offload section of an object file. */
1135
1136static int
1137process_offload_section (void *data, const char *name, off_t offset, off_t len)
1138{
a2d7e58f 1139 if (startswith (name, ".gnu.offload_lto_.opts"))
fc8b3540
IV
1140 {
1141 struct plugin_objfile *obj = (struct plugin_objfile *) data;
1142 obj->offload = 1;
1143 return 0;
1144 }
1145
1146 return 1;
1147}
1148
4fe0e1a4 1149/* Callback used by a linker to check if the plugin will claim FILE. Writes
48215350
DK
1150 the result in CLAIMED. */
1151
1152static enum ld_plugin_status
1153claim_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 {
d19e0f01
DK
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
5c2dee6f
GJL
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;
d19e0f01
DK
1171 lo = file->offset & 0xffffffff;
1172 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
5c2dee6f
GJL
1173 lto_file.name = hi ? xasprintf ("%s@0x%x%08x", file->name, hi, lo)
1174 : xasprintf ("%s@0x%x", file->name, lo);
48215350
DK
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;
fc8b3540 1185 obj.offload = 0;
48215350
DK
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
c8429c2a
ML
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)
ad2a3715
NC
1201 {
1202 obj.out->last_sym = 0;
1203 errmsg = simple_object_find_sections (obj.objfile,
1204 process_symtab_extension,
1205 &obj, &err);
1206 }
c8429c2a 1207 }
48215350
DK
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
fc8b3540
IV
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)
48215350
DK
1224 goto err;
1225
1226 if (obj.found > 1)
1227 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
1228
443743fd
IV
1229 if (obj.found > 0)
1230 {
c8429c2a
ML
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);
443743fd
IV
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;
e6861a99
IV
1244
1245 *claimed = 1;
443743fd
IV
1246 }
1247
e6861a99 1248 if (offload_files == NULL)
443743fd 1249 {
e6861a99
IV
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;
443743fd 1255 }
48215350 1256
e6861a99
IV
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 }
48215350
DK
1310
1311 goto cleanup;
1312
1313 err:
de54061d 1314 non_claimed_files++;
48215350
DK
1315 free (lto_file.name);
1316
1317 cleanup:
1318 if (obj.objfile)
1319 simple_object_release_read (obj.objfile);
48215350
DK
1320
1321 return LDPS_OK;
1322}
1323
d7f09764
DN
1324/* Parse the plugin options. */
1325
1326static void
1327process_option (const char *option)
1328{
de54061d 1329 if (strcmp (option, "-linker-output-known") == 0)
5269b246 1330 linker_output_known = true;
1ea226fa
RV
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))
5269b246
EB
1334 linker_output_auto_nolto_rel = true;
1335 else if (strcmp (option, "-debug") == 0)
c101cff8
IS
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;
d7f09764
DN
1342 else if (strcmp (option, "-nop") == 0)
1343 nop = 1;
a2d7e58f 1344 else if (startswith (option, "-pass-through="))
d7f09764
DN
1345 {
1346 num_pass_through_items++;
ed0f0c0f
RG
1347 pass_through_items = xrealloc (pass_through_items,
1348 num_pass_through_items * sizeof (char *));
d520c7fb 1349 pass_through_items[num_pass_through_items - 1] =
ed0f0c0f 1350 xstrdup (option + strlen ("-pass-through="));
d7f09764 1351 }
a2d7e58f 1352 else if (startswith (option, "-sym-style="))
48215350
DK
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 }
c6c7ac04
RB
1367 else if (startswith (option, "-ltrans-objects="))
1368 ltrans_objects = xstrdup (option + strlen ("-ltrans-objects="));
d7f09764
DN
1369 else
1370 {
1371 int size;
5cd0e96b 1372 char *opt = xstrdup (option);
d7f09764
DN
1373 lto_wrapper_num_args += 1;
1374 size = lto_wrapper_num_args * sizeof (char *);
ed0f0c0f 1375 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
5cd0e96b 1376 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
a2d7e58f 1377 if (startswith (option, "-fresolution="))
5cd0e96b 1378 resolution_file = opt + sizeof ("-fresolution=") - 1;
d7f09764 1379 }
c101cff8
IS
1380 save_temps = save_temps || debug;
1381 verbose = verbose || debug;
d7f09764
DN
1382}
1383
4fe0e1a4 1384/* Called by a linker after loading the plugin. TV is the transfer vector. */
d7f09764
DN
1385
1386enum ld_plugin_status
1387onload (struct ld_plugin_tv *tv)
1388{
1389 struct ld_plugin_tv *p;
1390 enum ld_plugin_status status;
d7f09764 1391
d7f09764
DN
1392 p = tv;
1393 while (p->tv_tag)
1394 {
1395 switch (p->tv_tag)
1396 {
33662270
RAE
1397 case LDPT_MESSAGE:
1398 message = p->tv_u.tv_message;
1399 break;
d7f09764
DN
1400 case LDPT_REGISTER_CLAIM_FILE_HOOK:
1401 register_claim_file = p->tv_u.tv_register_claim_file;
1402 break;
c8429c2a
ML
1403 case LDPT_ADD_SYMBOLS_V2:
1404 add_symbols_v2 = p->tv_u.tv_add_symbols;
1405 break;
d7f09764
DN
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;
ed0d2da0
JH
1412 case LDPT_GET_SYMBOLS_V2:
1413 get_symbols_v2 = p->tv_u.tv_get_symbols;
1414 break;
d7f09764
DN
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;
d520c7fb
RAE
1424 case LDPT_ADD_INPUT_LIBRARY:
1425 add_input_library = p->tv_u.tv_add_input_library;
1426 break;
d7f09764
DN
1427 case LDPT_OPTION:
1428 process_option (p->tv_u.tv_string);
1429 break;
e3bb089d
ILT
1430 case LDPT_GOLD_VERSION:
1431 gold_version = p->tv_u.tv_val;
1432 break;
1ff9ed6f
JH
1433 case LDPT_LINKER_OUTPUT:
1434 linker_output = (enum ld_plugin_output_file_type) p->tv_u.tv_val;
5269b246 1435 linker_output_set = true;
1ff9ed6f 1436 break;
c101cff8
IS
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;
d7f09764
DN
1441 default:
1442 break;
1443 }
1444 p++;
1445 }
1446
33662270
RAE
1447 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1448 check (add_symbols, LDPL_FATAL, "add_symbols not found");
d7f09764 1449 status = register_claim_file (claim_file_handler);
33662270
RAE
1450 check (status == LDPS_OK, LDPL_FATAL,
1451 "could not register the claim_file callback");
d7f09764
DN
1452
1453 if (register_cleanup)
1454 {
1455 status = register_cleanup (cleanup_handler);
33662270
RAE
1456 check (status == LDPS_OK, LDPL_FATAL,
1457 "could not register the cleanup callback");
d7f09764
DN
1458 }
1459
1460 if (register_all_symbols_read)
1461 {
33662270 1462 check (get_symbols, LDPL_FATAL, "get_symbols not found");
d7f09764 1463 status = register_all_symbols_read (all_symbols_read_handler);
33662270
RAE
1464 check (status == LDPS_OK, LDPL_FATAL,
1465 "could not register the all_symbols_read callback");
d7f09764
DN
1466 }
1467
21b624f0 1468 char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
c101cff8
IS
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
1dedc12d 1476 if (strstr (collect_gcc_options, "'-save-temps'"))
c101cff8
IS
1477 save_temps = true;
1478
1479 if (strstr (collect_gcc_options, "'-v'")
1480 || strstr (collect_gcc_options, "'--verbose'"))
1481 verbose = true;
1dedc12d
AO
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 }
c101cff8 1552 }
21b624f0 1553
d7f09764
DN
1554 return LDPS_OK;
1555}