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