Merge trunk version 213968 into gupc branch.
[official-gcc.git] / lto-plugin / lto-plugin.c
blob910e23cd6092df6fcb80ec120fdfb5ed728e3dc2
1 /* LTO plugin for gold and/or GNU ld.
2 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3 Contributed by Rafael Avila de Espindola (espindola@google.com).
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.
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.
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/>. */
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.
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.
27 More information at http://gcc.gnu.org/wiki/whopr/driver.
29 This plugin should be passed the lto-wrapper options and will forward them.
30 It also has 2 options of its 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. */
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38 #if HAVE_STDINT_H
39 #include <stdint.h>
40 #endif
41 #include <assert.h>
42 #include <errno.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <inttypes.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <fcntl.h>
50 #include <sys/types.h>
51 #ifdef HAVE_SYS_WAIT_H
52 #include <sys/wait.h>
53 #endif
54 #ifndef WIFEXITED
55 #define WIFEXITED(S) (((S) & 0xff) == 0)
56 #endif
57 #ifndef WEXITSTATUS
58 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
59 #endif
60 #include <libiberty.h>
61 #include <hashtab.h>
62 #include "../gcc/lto/common.h"
63 #include "simple-object.h"
64 #include "plugin-api.h"
66 /* We need to use I64 instead of ll width-specifier on native Windows.
67 The reason for this is that older MS-runtimes don't support the ll. */
68 #ifdef __MINGW32__
69 #define PRI_LL "I64"
70 #else
71 #define PRI_LL "ll"
72 #endif
74 /* Handle opening elf files on hosts, such as Windows, that may use
75 text file handling that will break binary access. */
76 #ifndef O_BINARY
77 # define O_BINARY 0
78 #endif
80 /* Segment name for LTO sections. This is only used for Mach-O.
81 FIXME: This needs to be kept in sync with darwin.c. */
83 #define LTO_SEGMENT_NAME "__GNU_LTO"
85 /* LTO magic section name. */
87 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
88 #define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
90 /* The part of the symbol table the plugin has to keep track of. Note that we
91 must keep SYMS until all_symbols_read is called to give the linker time to
92 copy the symbol information.
93 The id must be 64bit to minimze collisions. */
95 struct sym_aux
97 uint32_t slot;
98 unsigned long long id;
99 unsigned next_conflict;
102 struct plugin_symtab
104 int nsyms;
105 struct sym_aux *aux;
106 struct ld_plugin_symbol *syms;
107 unsigned long long id;
110 /* Encapsulates object file data during symbol scan. */
111 struct plugin_objfile
113 int found;
114 simple_object_read *objfile;
115 struct plugin_symtab *out;
116 const struct ld_plugin_input_file *file;
119 /* All that we have to remember about a file. */
121 struct plugin_file_info
123 char *name;
124 void *handle;
125 struct plugin_symtab symtab;
126 struct plugin_symtab conflicts;
129 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
130 stdio file streams, we do simple label translation here. */
132 enum symbol_style
134 ss_none, /* No underscore prefix. */
135 ss_win32, /* Underscore prefix any symbol not beginning with '@'. */
136 ss_uscore, /* Underscore prefix all symbols. */
139 static char *arguments_file_name;
140 static ld_plugin_register_claim_file register_claim_file;
141 static ld_plugin_register_all_symbols_read register_all_symbols_read;
142 static ld_plugin_get_symbols get_symbols, get_symbols_v2;
143 static ld_plugin_register_cleanup register_cleanup;
144 static ld_plugin_add_input_file add_input_file;
145 static ld_plugin_add_input_library add_input_library;
146 static ld_plugin_message message;
147 static ld_plugin_add_symbols add_symbols;
149 static struct plugin_file_info *claimed_files = NULL;
150 static unsigned int num_claimed_files = 0;
152 static char **output_files = NULL;
153 static unsigned int num_output_files = 0;
155 static char **lto_wrapper_argv;
156 static int lto_wrapper_num_args;
158 static char **pass_through_items = NULL;
159 static unsigned int num_pass_through_items;
161 static char debug;
162 static char nop;
163 static char *resolution_file = NULL;
165 /* The version of gold being used, or -1 if not gold. The number is
166 MAJOR * 100 + MINOR. */
167 static int gold_version = -1;
169 /* Not used by default, but can be overridden at runtime
170 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
171 (in fact, only first letter of style arg is checked.) */
172 static enum symbol_style sym_style = ss_none;
174 static void
175 check_1 (int gate, enum ld_plugin_level level, const char *text)
177 if (gate)
178 return;
180 if (message)
181 message (level, text);
182 else
184 /* If there is no nicer way to inform the user, fallback to stderr. */
185 fprintf (stderr, "%s\n", text);
186 if (level == LDPL_FATAL)
187 abort ();
191 /* This little wrapper allows check to be called with a non-integer
192 first argument, such as a pointer that must be non-NULL. We can't
193 use c99 bool type to coerce it into range, so we explicitly test. */
194 #define check(GATE, LEVEL, TEXT) check_1 (((GATE) != 0), (LEVEL), (TEXT))
196 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
197 by P and the result is written in ENTRY. The slot number is stored in SLOT.
198 Returns the address of the next entry. */
200 static char *
201 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
202 struct sym_aux *aux)
204 unsigned char t;
205 enum ld_plugin_symbol_kind translate_kind[] =
207 LDPK_DEF,
208 LDPK_WEAKDEF,
209 LDPK_UNDEF,
210 LDPK_WEAKUNDEF,
211 LDPK_COMMON
214 enum ld_plugin_symbol_visibility translate_visibility[] =
216 LDPV_DEFAULT,
217 LDPV_PROTECTED,
218 LDPV_INTERNAL,
219 LDPV_HIDDEN
222 switch (sym_style)
224 case ss_win32:
225 if (p[0] == '@')
227 /* cf. Duff's device. */
228 case ss_none:
229 entry->name = xstrdup (p);
230 break;
232 /* FALL-THROUGH. */
233 case ss_uscore:
234 entry->name = concat ("_", p, NULL);
235 break;
236 default:
237 check (0, LDPL_FATAL, "invalid symbol style requested");
238 break;
240 while (*p)
241 p++;
242 p++;
244 entry->version = NULL;
246 entry->comdat_key = p;
247 while (*p)
248 p++;
249 p++;
251 if (strlen (entry->comdat_key) == 0)
252 entry->comdat_key = NULL;
253 else
254 entry->comdat_key = xstrdup (entry->comdat_key);
256 t = *p;
257 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
258 entry->def = translate_kind[t];
259 p++;
261 t = *p;
262 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
263 entry->visibility = translate_visibility[t];
264 p++;
266 memcpy (&entry->size, p, sizeof (uint64_t));
267 p += 8;
269 memcpy (&aux->slot, p, sizeof (uint32_t));
270 p += 4;
272 entry->resolution = LDPR_UNKNOWN;
274 aux->next_conflict = -1;
276 return p;
279 /* Translate the IL symbol table located between DATA and END. Append the
280 slots and symbols to OUT. */
282 static void
283 translate (char *data, char *end, struct plugin_symtab *out)
285 struct sym_aux *aux;
286 struct ld_plugin_symbol *syms = NULL;
287 int n, len;
289 /* This overestimates the output buffer sizes, but at least
290 the algorithm is O(1) now. */
292 len = (end - data)/8 + out->nsyms + 1;
293 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
294 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
296 for (n = out->nsyms; data < end; n++)
298 aux[n].id = out->id;
299 data = parse_table_entry (data, &syms[n], &aux[n]);
302 assert(n < len);
304 out->nsyms = n;
305 out->syms = syms;
306 out->aux = aux;
309 /* Free all memory that is no longer needed after writing the symbol
310 resolution. */
312 static void
313 free_1 (void)
315 unsigned int i;
316 for (i = 0; i < num_claimed_files; i++)
318 struct plugin_file_info *info = &claimed_files[i];
319 struct plugin_symtab *symtab = &info->symtab;
320 unsigned int j;
321 for (j = 0; j < symtab->nsyms; j++)
323 struct ld_plugin_symbol *s = &symtab->syms[j];
324 free (s->name);
325 free (s->comdat_key);
327 free (symtab->syms);
328 symtab->syms = NULL;
332 /* Free all remaining memory. */
334 static void
335 free_2 (void)
337 unsigned int i;
338 for (i = 0; i < num_claimed_files; i++)
340 struct plugin_file_info *info = &claimed_files[i];
341 struct plugin_symtab *symtab = &info->symtab;
342 free (symtab->aux);
343 free (info->name);
346 for (i = 0; i < num_output_files; i++)
347 free (output_files[i]);
348 free (output_files);
350 free (claimed_files);
351 claimed_files = NULL;
352 num_claimed_files = 0;
354 free (arguments_file_name);
355 arguments_file_name = NULL;
358 /* Dump SYMTAB to resolution file F. */
360 static void
361 dump_symtab (FILE *f, struct plugin_symtab *symtab)
363 unsigned j;
365 for (j = 0; j < symtab->nsyms; j++)
367 uint32_t slot = symtab->aux[j].slot;
368 unsigned int resolution = symtab->syms[j].resolution;
370 assert (resolution != LDPR_UNKNOWN);
372 fprintf (f, "%u %" PRI_LL "x %s %s\n",
373 (unsigned int) slot, symtab->aux[j].id,
374 lto_resolution_str[resolution],
375 symtab->syms[j].name);
379 /* Finish the conflicts' resolution information after the linker resolved
380 the original symbols */
382 static void
383 finish_conflict_resolution (struct plugin_symtab *symtab,
384 struct plugin_symtab *conflicts)
386 int i, j;
388 if (conflicts->nsyms == 0)
389 return;
391 for (i = 0; i < symtab->nsyms; i++)
393 int resolution = LDPR_UNKNOWN;
395 if (symtab->aux[i].next_conflict == -1)
396 continue;
398 switch (symtab->syms[i].def)
400 case LDPK_DEF:
401 case LDPK_COMMON: /* ??? */
402 resolution = LDPR_RESOLVED_IR;
403 break;
404 case LDPK_WEAKDEF:
405 resolution = LDPR_PREEMPTED_IR;
406 break;
407 case LDPK_UNDEF:
408 case LDPK_WEAKUNDEF:
409 resolution = symtab->syms[i].resolution;
410 break;
411 default:
412 assert (0);
415 assert (resolution != LDPR_UNKNOWN);
417 for (j = symtab->aux[i].next_conflict;
418 j != -1;
419 j = conflicts->aux[j].next_conflict)
420 conflicts->syms[j].resolution = resolution;
424 /* Free symbol table SYMTAB. */
426 static void
427 free_symtab (struct plugin_symtab *symtab)
429 free (symtab->syms);
430 symtab->syms = NULL;
431 free (symtab->aux);
432 symtab->aux = NULL;
435 /* Writes the relocations to disk. */
437 static void
438 write_resolution (void)
440 unsigned int i;
441 FILE *f;
443 check (resolution_file, LDPL_FATAL, "resolution file not specified");
444 f = fopen (resolution_file, "w");
445 check (f, LDPL_FATAL, "could not open file");
447 fprintf (f, "%d\n", num_claimed_files);
449 for (i = 0; i < num_claimed_files; i++)
451 struct plugin_file_info *info = &claimed_files[i];
452 struct plugin_symtab *symtab = &info->symtab;
453 struct ld_plugin_symbol *syms = symtab->syms;
455 /* Version 2 of API supports IRONLY_EXP resolution that is
456 accepted by GCC-4.7 and newer. */
457 if (get_symbols_v2)
458 get_symbols_v2 (info->handle, symtab->nsyms, syms);
459 else
460 get_symbols (info->handle, symtab->nsyms, syms);
462 finish_conflict_resolution (symtab, &info->conflicts);
464 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
465 dump_symtab (f, symtab);
466 if (info->conflicts.nsyms)
468 dump_symtab (f, &info->conflicts);
469 free_symtab (&info->conflicts);
472 fclose (f);
475 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
476 stdout. */
478 static void
479 add_output_files (FILE *f)
481 for (;;)
483 const unsigned piece = 32;
484 char *buf, *s = xmalloc (piece);
485 size_t len;
487 buf = s;
488 cont:
489 if (!fgets (buf, piece, f))
491 free (s);
492 break;
494 len = strlen (s);
495 if (s[len - 1] != '\n')
497 s = xrealloc (s, len + piece);
498 buf = s + len;
499 goto cont;
501 s[len - 1] = '\0';
503 num_output_files++;
504 output_files
505 = xrealloc (output_files, num_output_files * sizeof (char *));
506 output_files[num_output_files - 1] = s;
507 add_input_file (output_files[num_output_files - 1]);
511 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
512 argument list. */
514 static void
515 exec_lto_wrapper (char *argv[])
517 int t, i;
518 int status;
519 char *at_args;
520 FILE *args;
521 FILE *wrapper_output;
522 char *new_argv[3];
523 struct pex_obj *pex;
524 const char *errmsg;
526 /* Write argv to a file to avoid a command line that is too long. */
527 arguments_file_name = make_temp_file ("");
528 check (arguments_file_name, LDPL_FATAL,
529 "Failed to generate a temorary file name");
531 args = fopen (arguments_file_name, "w");
532 check (args, LDPL_FATAL, "could not open arguments file");
534 t = writeargv (&argv[1], args);
535 check (t == 0, LDPL_FATAL, "could not write arguments");
536 t = fclose (args);
537 check (t == 0, LDPL_FATAL, "could not close arguments file");
539 at_args = concat ("@", arguments_file_name, NULL);
540 check (at_args, LDPL_FATAL, "could not allocate");
542 for (i = 1; argv[i]; i++)
544 char *a = argv[i];
545 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
547 for (i = 0; argv[i]; i++)
548 fprintf (stderr, "%s ", argv[i]);
549 fprintf (stderr, "\n");
550 break;
554 new_argv[0] = argv[0];
555 new_argv[1] = at_args;
556 new_argv[2] = NULL;
558 if (debug)
560 for (i = 0; new_argv[i]; i++)
561 fprintf (stderr, "%s ", new_argv[i]);
562 fprintf (stderr, "\n");
566 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
567 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
569 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
570 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
571 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
573 wrapper_output = pex_read_output (pex, 0);
574 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
576 add_output_files (wrapper_output);
578 t = pex_get_status (pex, 1, &status);
579 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
580 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
581 "lto-wrapper failed");
583 pex_free (pex);
585 free (at_args);
588 /* Pass the original files back to the linker. */
590 static void
591 use_original_files (void)
593 unsigned i;
594 for (i = 0; i < num_claimed_files; i++)
596 struct plugin_file_info *info = &claimed_files[i];
597 add_input_file (info->name);
602 /* Called by the linker once all symbols have been read. */
604 static enum ld_plugin_status
605 all_symbols_read_handler (void)
607 unsigned i;
608 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
609 char **lto_argv;
610 const char **lto_arg_ptr;
611 if (num_claimed_files == 0)
612 return LDPS_OK;
614 if (nop)
616 use_original_files ();
617 return LDPS_OK;
620 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
621 lto_arg_ptr = (const char **) lto_argv;
622 assert (lto_wrapper_argv);
624 write_resolution ();
626 free_1 ();
628 for (i = 0; i < lto_wrapper_num_args; i++)
629 *lto_arg_ptr++ = lto_wrapper_argv[i];
631 for (i = 0; i < num_claimed_files; i++)
633 struct plugin_file_info *info = &claimed_files[i];
635 *lto_arg_ptr++ = info->name;
638 *lto_arg_ptr++ = NULL;
639 exec_lto_wrapper (lto_argv);
641 free (lto_argv);
643 /* --pass-through is not needed when using gold 1.11 or later. */
644 if (pass_through_items && gold_version < 111)
646 unsigned int i;
647 for (i = 0; i < num_pass_through_items; i++)
649 if (strncmp (pass_through_items[i], "-l", 2) == 0)
650 add_input_library (pass_through_items[i] + 2);
651 else
652 add_input_file (pass_through_items[i]);
653 free (pass_through_items[i]);
654 pass_through_items[i] = NULL;
656 free (pass_through_items);
657 pass_through_items = NULL;
660 return LDPS_OK;
663 /* Remove temporary files at the end of the link. */
665 static enum ld_plugin_status
666 cleanup_handler (void)
668 unsigned int i;
669 int t;
671 if (debug)
672 return LDPS_OK;
674 if (arguments_file_name)
676 t = unlink (arguments_file_name);
677 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
680 for (i = 0; i < num_output_files; i++)
682 t = unlink (output_files[i]);
683 check (t == 0, LDPL_FATAL, "could not unlink output file");
686 free_2 ();
687 return LDPS_OK;
690 #define SWAP(type, a, b) \
691 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
693 /* Compare two hash table entries */
695 static int eq_sym (const void *a, const void *b)
697 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
698 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
700 return !strcmp (as->name, bs->name);
703 /* Hash a symbol */
705 static hashval_t hash_sym (const void *a)
707 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
709 return htab_hash_string (as->name);
712 /* Determine how strong a symbol is */
714 static int symbol_strength (struct ld_plugin_symbol *s)
716 switch (s->def)
718 case LDPK_UNDEF:
719 case LDPK_WEAKUNDEF:
720 return 0;
721 case LDPK_WEAKDEF:
722 return 1;
723 default:
724 return 2;
728 /* In the ld -r case we can get dups in the LTO symbol tables, where
729 the same symbol can have different resolutions (e.g. undefined and defined).
731 We have to keep that in the LTO symbol tables, but the dups confuse
732 gold and then finally gcc by supplying incorrect resolutions.
734 Problem is that the main gold symbol table doesn't know about subids
735 and does not distingush the same symbols in different states.
737 So we drop duplicates from the linker visible symbol table
738 and keep them in a private table. Then later do own symbol
739 resolution for the duplicated based on the results for the
740 originals.
742 Then when writing out the resolution file readd the dropped symbols.
744 XXX how to handle common? */
746 static void
747 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
749 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
750 int i;
751 int out;
752 int outlen;
754 outlen = t->nsyms;
755 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
756 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
758 /* Move all duplicate symbols into the auxiliary conflicts table. */
759 out = 0;
760 for (i = 0; i < t->nsyms; i++)
762 struct ld_plugin_symbol *s = &t->syms[i];
763 struct sym_aux *aux = &t->aux[i];
764 void **slot;
766 slot = htab_find_slot (symtab, s, INSERT);
767 if (*slot != NULL)
769 int cnf;
770 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
771 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
773 /* Always let the linker resolve the strongest symbol */
774 if (symbol_strength (orig) < symbol_strength (s))
776 SWAP (struct ld_plugin_symbol, *orig, *s);
777 SWAP (uint32_t, orig_aux->slot, aux->slot);
778 SWAP (unsigned long long, orig_aux->id, aux->id);
779 /* Don't swap conflict chain pointer */
782 /* Move current symbol into the conflicts table */
783 cnf = conflicts->nsyms++;
784 conflicts->syms[cnf] = *s;
785 conflicts->aux[cnf] = *aux;
786 aux = &conflicts->aux[cnf];
788 /* Update conflicts chain of the original symbol */
789 aux->next_conflict = orig_aux->next_conflict;
790 orig_aux->next_conflict = cnf;
792 continue;
795 /* Remove previous duplicates in the main table */
796 if (out < i)
798 t->syms[out] = *s;
799 t->aux[out] = *aux;
802 /* Put original into the hash table */
803 *slot = &t->syms[out];
804 out++;
807 assert (conflicts->nsyms <= outlen);
808 assert (conflicts->nsyms + out == t->nsyms);
810 t->nsyms = out;
811 htab_delete (symtab);
814 /* Process one section of an object file. */
816 static int
817 process_symtab (void *data, const char *name, off_t offset, off_t length)
819 struct plugin_objfile *obj = (struct plugin_objfile *)data;
820 char *s;
821 char *secdatastart, *secdata;
823 if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
824 return 1;
826 s = strrchr (name, '.');
827 if (s)
828 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
829 secdata = secdatastart = xmalloc (length);
830 offset += obj->file->offset;
831 if (offset != lseek (obj->file->fd, offset, SEEK_SET))
832 goto err;
836 ssize_t got = read (obj->file->fd, secdata, length);
837 if (got == 0)
838 break;
839 else if (got > 0)
841 secdata += got;
842 length -= got;
844 else if (errno != EINTR)
845 goto err;
847 while (length > 0);
848 if (length > 0)
849 goto err;
851 translate (secdatastart, secdata, obj->out);
852 obj->found++;
853 free (secdatastart);
854 return 1;
856 err:
857 if (message)
858 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
859 /* Force claim_file_handler to abandon this file. */
860 obj->found = 0;
861 free (secdatastart);
862 return 0;
865 /* Callback used by gold to check if the plugin will claim FILE. Writes
866 the result in CLAIMED. */
868 static enum ld_plugin_status
869 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
871 enum ld_plugin_status status;
872 struct plugin_objfile obj;
873 struct plugin_file_info lto_file;
874 int err;
875 const char *errmsg;
877 memset (&lto_file, 0, sizeof (struct plugin_file_info));
879 if (file->offset != 0)
881 char *objname;
882 /* We pass the offset of the actual file, not the archive header.
883 Can't use PRIx64, because that's C99, so we have to print the
884 64-bit hex int as two 32-bit ones. */
885 int lo, hi, t;
886 lo = file->offset & 0xffffffff;
887 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
888 t = hi ? asprintf (&objname, "%s@0x%x%08x", file->name, lo, hi)
889 : asprintf (&objname, "%s@0x%x", file->name, lo);
890 check (t >= 0, LDPL_FATAL, "asprintf failed");
891 lto_file.name = objname;
893 else
895 lto_file.name = xstrdup (file->name);
897 lto_file.handle = file->handle;
899 *claimed = 0;
900 obj.file = file;
901 obj.found = 0;
902 obj.out = &lto_file.symtab;
903 errmsg = NULL;
904 obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
905 &errmsg, &err);
906 /* No file, but also no error code means unrecognized format; just skip it. */
907 if (!obj.objfile && !err)
908 goto err;
910 if (obj.objfile)
911 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
913 if (!obj.objfile || errmsg)
915 if (err && message)
916 message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
917 xstrerror (err));
918 else if (message)
919 message (LDPL_FATAL, "%s: %s", file->name, errmsg);
920 goto err;
923 if (obj.found == 0)
924 goto err;
926 if (obj.found > 1)
927 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
929 status = add_symbols (file->handle, lto_file.symtab.nsyms,
930 lto_file.symtab.syms);
931 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
933 *claimed = 1;
934 num_claimed_files++;
935 claimed_files =
936 xrealloc (claimed_files,
937 num_claimed_files * sizeof (struct plugin_file_info));
938 claimed_files[num_claimed_files - 1] = lto_file;
940 goto cleanup;
942 err:
943 free (lto_file.name);
945 cleanup:
946 if (obj.objfile)
947 simple_object_release_read (obj.objfile);
949 return LDPS_OK;
952 /* Parse the plugin options. */
954 static void
955 process_option (const char *option)
957 if (strcmp (option, "-debug") == 0)
958 debug = 1;
959 else if (strcmp (option, "-nop") == 0)
960 nop = 1;
961 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
963 num_pass_through_items++;
964 pass_through_items = xrealloc (pass_through_items,
965 num_pass_through_items * sizeof (char *));
966 pass_through_items[num_pass_through_items - 1] =
967 xstrdup (option + strlen ("-pass-through="));
969 else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
971 switch (option[sizeof ("-sym-style=") - 1])
973 case 'w':
974 sym_style = ss_win32;
975 break;
976 case 'u':
977 sym_style = ss_uscore;
978 break;
979 default:
980 sym_style = ss_none;
981 break;
984 else
986 int size;
987 char *opt = xstrdup (option);
988 lto_wrapper_num_args += 1;
989 size = lto_wrapper_num_args * sizeof (char *);
990 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
991 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
992 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
993 resolution_file = opt + sizeof ("-fresolution=") - 1;
997 /* Called by gold after loading the plugin. TV is the transfer vector. */
999 enum ld_plugin_status
1000 onload (struct ld_plugin_tv *tv)
1002 struct ld_plugin_tv *p;
1003 enum ld_plugin_status status;
1005 p = tv;
1006 while (p->tv_tag)
1008 switch (p->tv_tag)
1010 case LDPT_MESSAGE:
1011 message = p->tv_u.tv_message;
1012 break;
1013 case LDPT_REGISTER_CLAIM_FILE_HOOK:
1014 register_claim_file = p->tv_u.tv_register_claim_file;
1015 break;
1016 case LDPT_ADD_SYMBOLS:
1017 add_symbols = p->tv_u.tv_add_symbols;
1018 break;
1019 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
1020 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
1021 break;
1022 case LDPT_GET_SYMBOLS_V2:
1023 get_symbols_v2 = p->tv_u.tv_get_symbols;
1024 break;
1025 case LDPT_GET_SYMBOLS:
1026 get_symbols = p->tv_u.tv_get_symbols;
1027 break;
1028 case LDPT_REGISTER_CLEANUP_HOOK:
1029 register_cleanup = p->tv_u.tv_register_cleanup;
1030 break;
1031 case LDPT_ADD_INPUT_FILE:
1032 add_input_file = p->tv_u.tv_add_input_file;
1033 break;
1034 case LDPT_ADD_INPUT_LIBRARY:
1035 add_input_library = p->tv_u.tv_add_input_library;
1036 break;
1037 case LDPT_OPTION:
1038 process_option (p->tv_u.tv_string);
1039 break;
1040 case LDPT_GOLD_VERSION:
1041 gold_version = p->tv_u.tv_val;
1042 break;
1043 default:
1044 break;
1046 p++;
1049 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1050 check (add_symbols, LDPL_FATAL, "add_symbols not found");
1051 status = register_claim_file (claim_file_handler);
1052 check (status == LDPS_OK, LDPL_FATAL,
1053 "could not register the claim_file callback");
1055 if (register_cleanup)
1057 status = register_cleanup (cleanup_handler);
1058 check (status == LDPS_OK, LDPL_FATAL,
1059 "could not register the cleanup callback");
1062 if (register_all_symbols_read)
1064 check (get_symbols, LDPL_FATAL, "get_symbols not found");
1065 status = register_all_symbols_read (all_symbols_read_handler);
1066 check (status == LDPS_OK, LDPL_FATAL,
1067 "could not register the all_symbols_read callback");
1070 /* Support -fno-use-linker-plugin by failing to load the plugin
1071 for the case where it is auto-loaded by BFD. */
1072 char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
1073 if (collect_gcc_options
1074 && strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
1075 return LDPS_ERR;
1077 return LDPS_OK;