2010-10-14 Jeremie Salvucci <jeremie.salvucci@free.fr>
[official-gcc.git] / lto-plugin / lto-plugin.c
blob433f545391f2f0e7925813a1e807cdb0aca74a2c
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 #include <assert.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <inttypes.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42 #include <fcntl.h>
43 #include <sys/types.h>
44 #include <sys/wait.h>
45 #include <stdbool.h>
46 #include <libiberty.h>
47 #include <hashtab.h>
48 #include "../gcc/lto/common.h"
50 /* Common definitions for/from the object format dependent code. */
51 #include "lto-plugin.h"
53 static char *arguments_file_name;
54 static ld_plugin_register_claim_file register_claim_file;
55 static ld_plugin_register_all_symbols_read register_all_symbols_read;
56 static ld_plugin_get_symbols get_symbols;
57 static ld_plugin_register_cleanup register_cleanup;
58 static ld_plugin_add_input_file add_input_file;
59 static ld_plugin_add_input_library add_input_library;
60 static ld_plugin_message message;
62 /* These are not static because the object format dependent
63 claim_file hooks in lto-plugin-{coff,elf}.c need them. */
64 ld_plugin_add_symbols add_symbols;
66 struct plugin_file_info *claimed_files = NULL;
67 unsigned int num_claimed_files = 0;
69 static char **output_files = NULL;
70 static unsigned int num_output_files = 0;
72 static char **lto_wrapper_argv;
73 static int lto_wrapper_num_args;
75 static char **pass_through_items = NULL;
76 static unsigned int num_pass_through_items;
78 static bool debug;
79 static bool nop;
80 static char *resolution_file = NULL;
82 void
83 check (bool gate, enum ld_plugin_level level, const char *text)
85 if (gate)
86 return;
88 if (message)
89 message (level, text);
90 else
92 /* If there is no nicer way to inform the user, fallback to stderr. */
93 fprintf (stderr, "%s\n", text);
94 if (level == LDPL_FATAL)
95 abort ();
99 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
100 by P and the result is written in ENTRY. The slot number is stored in SLOT.
101 Returns the address of the next entry. */
103 char *
104 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
105 struct sym_aux *aux)
107 unsigned char t;
108 enum ld_plugin_symbol_kind translate_kind[] =
110 LDPK_DEF,
111 LDPK_WEAKDEF,
112 LDPK_UNDEF,
113 LDPK_WEAKUNDEF,
114 LDPK_COMMON
117 enum ld_plugin_symbol_visibility translate_visibility[] =
119 LDPV_DEFAULT,
120 LDPV_PROTECTED,
121 LDPV_INTERNAL,
122 LDPV_HIDDEN
125 entry->name = xstrdup (p);
126 while (*p)
127 p++;
128 p++;
130 entry->version = NULL;
132 entry->comdat_key = p;
133 while (*p)
134 p++;
135 p++;
137 if (strlen (entry->comdat_key) == 0)
138 entry->comdat_key = NULL;
139 else
140 entry->comdat_key = xstrdup (entry->comdat_key);
142 t = *p;
143 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
144 entry->def = translate_kind[t];
145 p++;
147 t = *p;
148 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
149 entry->visibility = translate_visibility[t];
150 p++;
152 entry->size = *(uint64_t *) p;
153 p += 8;
155 aux->slot = *(uint32_t *) p;
156 p += 4;
158 entry->resolution = LDPR_UNKNOWN;
160 aux->next_conflict = -1;
162 return p;
165 /* Translate the IL symbol table located between DATA and END. Append the
166 slots and symbols to OUT. */
168 void
169 translate (char *data, char *end, struct plugin_symtab *out)
171 struct sym_aux *aux;
172 struct ld_plugin_symbol *syms = NULL;
173 int n, len;
175 /* This overestimates the output buffer sizes, but at least
176 the algorithm is O(1) now. */
178 len = (end - data)/8 + out->nsyms + 1;
179 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
180 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
182 for (n = out->nsyms; data < end; n++)
184 aux[n].id = out->id;
185 data = parse_table_entry (data, &syms[n], &aux[n]);
188 assert(n < len);
190 out->nsyms = n;
191 out->syms = syms;
192 out->aux = aux;
195 /* Free all memory that is no longer needed after writing the symbol
196 resolution. */
198 static void
199 free_1 (void)
201 unsigned int i;
202 for (i = 0; i < num_claimed_files; i++)
204 struct plugin_file_info *info = &claimed_files[i];
205 struct plugin_symtab *symtab = &info->symtab;
206 unsigned int j;
207 for (j = 0; j < symtab->nsyms; j++)
209 struct ld_plugin_symbol *s = &symtab->syms[j];
210 free (s->name);
211 if (s->comdat_key)
212 free (s->comdat_key);
214 free (symtab->syms);
215 symtab->syms = NULL;
219 /* Free all remaining memory. */
221 static void
222 free_2 (void)
224 unsigned int i;
225 for (i = 0; i < num_claimed_files; i++)
227 struct plugin_file_info *info = &claimed_files[i];
228 struct plugin_symtab *symtab = &info->symtab;
229 free (symtab->aux);
230 free (info->name);
233 for (i = 0; i < num_output_files; i++)
234 free (output_files[i]);
235 free (output_files);
237 free (claimed_files);
238 claimed_files = NULL;
239 num_claimed_files = 0;
241 if (arguments_file_name)
242 free (arguments_file_name);
243 arguments_file_name = NULL;
246 /* Dump SYMTAB to resolution file F. */
248 static void
249 dump_symtab (FILE *f, struct plugin_symtab *symtab)
251 unsigned j;
253 for (j = 0; j < symtab->nsyms; j++)
255 uint32_t slot = symtab->aux[j].slot;
256 unsigned int resolution = symtab->syms[j].resolution;
258 assert (resolution != LDPR_UNKNOWN);
260 fprintf (f, "%u %x %s %s\n", (unsigned int) slot, symtab->aux[j].id,
261 lto_resolution_str[resolution],
262 symtab->syms[j].name);
266 /* Finish the conflicts' resolution information after the linker resolved
267 the original symbols */
269 static void
270 finish_conflict_resolution (struct plugin_symtab *symtab,
271 struct plugin_symtab *conflicts)
273 int i, j;
275 if (conflicts->nsyms == 0)
276 return;
278 for (i = 0; i < symtab->nsyms; i++)
280 int resolution = LDPR_UNKNOWN;
282 if (symtab->aux[i].next_conflict == -1)
283 continue;
285 switch (symtab->syms[i].def)
287 case LDPK_DEF:
288 case LDPK_COMMON: /* ??? */
289 resolution = LDPR_RESOLVED_IR;
290 break;
291 case LDPK_WEAKDEF:
292 resolution = LDPR_PREEMPTED_IR;
293 break;
294 case LDPK_UNDEF:
295 case LDPK_WEAKUNDEF:
296 resolution = symtab->syms[i].resolution;
297 break;
298 default:
299 assert (0);
302 assert (resolution != LDPR_UNKNOWN);
304 for (j = symtab->aux[i].next_conflict;
305 j != -1;
306 j = conflicts->aux[j].next_conflict)
307 conflicts->syms[j].resolution = resolution;
311 /* Free symbol table SYMTAB. */
313 static void
314 free_symtab (struct plugin_symtab *symtab)
316 free (symtab->syms);
317 symtab->syms = NULL;
318 free (symtab->aux);
319 symtab->aux = NULL;
322 /* Writes the relocations to disk. */
324 static void
325 write_resolution (void)
327 unsigned int i;
328 FILE *f;
330 check (resolution_file, LDPL_FATAL, "resolution file not specified");
331 f = fopen (resolution_file, "w");
332 check (f, LDPL_FATAL, "could not open file");
334 fprintf (f, "%d\n", num_claimed_files);
336 for (i = 0; i < num_claimed_files; i++)
338 struct plugin_file_info *info = &claimed_files[i];
339 struct plugin_symtab *symtab = &info->symtab;
340 struct ld_plugin_symbol *syms = symtab->syms;
342 get_symbols (info->handle, symtab->nsyms, syms);
344 finish_conflict_resolution (symtab, &info->conflicts);
346 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
347 dump_symtab (f, symtab);
348 if (info->conflicts.nsyms)
350 dump_symtab (f, &info->conflicts);
351 free_symtab (&info->conflicts);
354 fclose (f);
357 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
358 stdout. */
360 static void
361 add_output_files (FILE *f)
363 for (;;)
365 const unsigned piece = 32;
366 char *buf, *s = xmalloc (piece);
367 size_t len;
369 buf = s;
370 cont:
371 if (!fgets (buf, piece, f))
372 break;
373 len = strlen (s);
374 if (s[len - 1] != '\n')
376 s = xrealloc (s, len + piece);
377 buf = s + len;
378 goto cont;
380 s[len - 1] = '\0';
382 num_output_files++;
383 output_files
384 = xrealloc (output_files, num_output_files * sizeof (char *));
385 output_files[num_output_files - 1] = s;
386 add_input_file (output_files[num_output_files - 1]);
390 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
391 argument list. */
393 static void
394 exec_lto_wrapper (char *argv[])
396 int t, i;
397 int status;
398 char *at_args;
399 FILE *args;
400 FILE *wrapper_output;
401 char *new_argv[3];
402 struct pex_obj *pex;
403 const char *errmsg;
405 /* Write argv to a file to avoid a command line that is too long. */
406 arguments_file_name = make_temp_file ("");
407 check (arguments_file_name, LDPL_FATAL,
408 "Failed to generate a temorary file name");
410 args = fopen (arguments_file_name, "w");
411 check (args, LDPL_FATAL, "could not open arguments file");
413 t = writeargv (&argv[1], args);
414 check (t == 0, LDPL_FATAL, "could not write arguments");
415 t = fclose (args);
416 check (t == 0, LDPL_FATAL, "could not close arguments file");
418 at_args = concat ("@", arguments_file_name, NULL);
419 check (at_args, LDPL_FATAL, "could not allocate");
421 for (i = 1; argv[i]; i++)
423 char *a = argv[i];
424 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
426 for (i = 0; argv[i]; i++)
427 fprintf (stderr, "%s ", argv[i]);
428 fprintf (stderr, "\n");
429 break;
433 new_argv[0] = argv[0];
434 new_argv[1] = at_args;
435 new_argv[2] = NULL;
437 if (debug)
439 for (i = 0; new_argv[i]; i++)
440 fprintf (stderr, "%s ", new_argv[i]);
441 fprintf (stderr, "\n");
445 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
446 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
448 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
449 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
450 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
452 wrapper_output = pex_read_output (pex, 0);
453 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
455 add_output_files (wrapper_output);
457 t = pex_get_status (pex, 1, &status);
458 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
459 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
460 "lto-wrapper failed");
462 pex_free (pex);
464 free (at_args);
467 /* Pass the original files back to the linker. */
469 static void
470 use_original_files (void)
472 unsigned i;
473 for (i = 0; i < num_claimed_files; i++)
475 struct plugin_file_info *info = &claimed_files[i];
476 add_input_file (info->name);
481 /* Called by the linker once all symbols have been read. */
483 static enum ld_plugin_status
484 all_symbols_read_handler (void)
486 unsigned i;
487 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
488 char **lto_argv;
489 const char **lto_arg_ptr;
490 if (num_claimed_files == 0)
491 return LDPS_OK;
493 if (nop)
495 use_original_files ();
496 return LDPS_OK;
499 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
500 lto_arg_ptr = (const char **) lto_argv;
501 assert (lto_wrapper_argv);
503 write_resolution ();
505 free_1 ();
507 for (i = 0; i < lto_wrapper_num_args; i++)
508 *lto_arg_ptr++ = lto_wrapper_argv[i];
510 for (i = 0; i < num_claimed_files; i++)
512 struct plugin_file_info *info = &claimed_files[i];
514 *lto_arg_ptr++ = info->name;
517 *lto_arg_ptr++ = NULL;
518 exec_lto_wrapper (lto_argv);
520 free (lto_argv);
522 if (pass_through_items)
524 unsigned int i;
525 for (i = 0; i < num_pass_through_items; i++)
527 if (strncmp (pass_through_items[i], "-l", 2) == 0)
528 add_input_library (pass_through_items[i] + 2);
529 else
530 add_input_file (pass_through_items[i]);
531 free (pass_through_items[i]);
532 pass_through_items[i] = NULL;
534 free (pass_through_items);
535 pass_through_items = NULL;
538 return LDPS_OK;
541 /* Remove temporary files at the end of the link. */
543 static enum ld_plugin_status
544 cleanup_handler (void)
546 unsigned int i;
547 int t;
549 if (debug)
550 return LDPS_OK;
552 if (arguments_file_name)
554 t = unlink (arguments_file_name);
555 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
558 for (i = 0; i < num_output_files; i++)
560 t = unlink (output_files[i]);
561 check (t == 0, LDPL_FATAL, "could not unlink output file");
564 free_2 ();
565 return LDPS_OK;
568 #define SWAP(type, a, b) \
569 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
571 /* Compare two hash table entries */
573 static int eq_sym (const void *a, const void *b)
575 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
576 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
578 return !strcmp (as->name, bs->name);
581 /* Hash a symbol */
583 static hashval_t hash_sym (const void *a)
585 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
587 return htab_hash_string (as->name);
590 /* Determine how strong a symbol is */
592 static int symbol_strength (struct ld_plugin_symbol *s)
594 switch (s->def)
596 case LDPK_UNDEF:
597 case LDPK_WEAKUNDEF:
598 return 0;
599 case LDPK_WEAKDEF:
600 return 1;
601 default:
602 return 2;
606 /* In the ld -r case we can get dups in the LTO symbol tables, where
607 the same symbol can have different resolutions (e.g. undefined and defined).
609 We have to keep that in the LTO symbol tables, but the dups confuse
610 gold and then finally gcc by supplying incorrect resolutions.
612 Problem is that the main gold symbol table doesn't know about subids
613 and does not distingush the same symbols in different states.
615 So we drop duplicates from the linker visible symbol table
616 and keep them in a private table. Then later do own symbol
617 resolution for the duplicated based on the results for the
618 originals.
620 Then when writing out the resolution file readd the dropped symbols.
622 XXX how to handle common? */
624 void
625 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
627 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
628 int i;
629 int out;
630 int outlen;
632 outlen = t->nsyms;
633 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
634 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
636 /* Move all duplicate symbols into the auxillary conflicts table. */
637 out = 0;
638 for (i = 0; i < t->nsyms; i++)
640 struct ld_plugin_symbol *s = &t->syms[i];
641 struct sym_aux *aux = &t->aux[i];
642 void **slot;
644 slot = htab_find_slot (symtab, s, INSERT);
645 if (*slot != NULL)
647 int cnf;
648 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
649 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
651 /* Always let the linker resolve the strongest symbol */
652 if (symbol_strength (orig) < symbol_strength (s))
654 SWAP (struct ld_plugin_symbol, *orig, *s);
655 SWAP (uint32_t, orig_aux->slot, aux->slot);
656 SWAP (unsigned, orig_aux->id, aux->id);
657 /* Don't swap conflict chain pointer */
660 /* Move current symbol into the conflicts table */
661 cnf = conflicts->nsyms++;
662 conflicts->syms[cnf] = *s;
663 conflicts->aux[cnf] = *aux;
664 aux = &conflicts->aux[cnf];
666 /* Update conflicts chain of the original symbol */
667 aux->next_conflict = orig_aux->next_conflict;
668 orig_aux->next_conflict = cnf;
670 continue;
673 /* Remove previous duplicates in the main table */
674 if (out < i)
676 t->syms[out] = *s;
677 t->aux[out] = *aux;
680 /* Put original into the hash table */
681 *slot = &t->syms[out];
682 out++;
685 assert (conflicts->nsyms <= outlen);
686 assert (conflicts->nsyms + out == t->nsyms);
688 t->nsyms = out;
689 htab_delete (symtab);
692 /* Parse the plugin options. */
694 static void
695 process_option (const char *option)
697 if (strcmp (option, "-debug") == 0)
698 debug = 1;
699 else if (strcmp (option, "-nop") == 0)
700 nop = 1;
701 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
703 num_pass_through_items++;
704 pass_through_items = xrealloc (pass_through_items,
705 num_pass_through_items * sizeof (char *));
706 pass_through_items[num_pass_through_items - 1] =
707 xstrdup (option + strlen ("-pass-through="));
709 else
711 int size;
712 char *opt = xstrdup (option);
713 lto_wrapper_num_args += 1;
714 size = lto_wrapper_num_args * sizeof (char *);
715 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
716 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
717 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
718 resolution_file = opt + sizeof ("-fresolution=") - 1;
722 /* Called by gold after loading the plugin. TV is the transfer vector. */
724 enum ld_plugin_status
725 onload (struct ld_plugin_tv *tv)
727 struct ld_plugin_tv *p;
728 enum ld_plugin_status status;
730 status = onload_format_checks (tv);
731 if (status != LDPS_OK)
732 return status;
734 p = tv;
735 while (p->tv_tag)
737 switch (p->tv_tag)
739 case LDPT_MESSAGE:
740 message = p->tv_u.tv_message;
741 break;
742 case LDPT_REGISTER_CLAIM_FILE_HOOK:
743 register_claim_file = p->tv_u.tv_register_claim_file;
744 break;
745 case LDPT_ADD_SYMBOLS:
746 add_symbols = p->tv_u.tv_add_symbols;
747 break;
748 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
749 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
750 break;
751 case LDPT_GET_SYMBOLS:
752 get_symbols = p->tv_u.tv_get_symbols;
753 break;
754 case LDPT_REGISTER_CLEANUP_HOOK:
755 register_cleanup = p->tv_u.tv_register_cleanup;
756 break;
757 case LDPT_ADD_INPUT_FILE:
758 add_input_file = p->tv_u.tv_add_input_file;
759 break;
760 case LDPT_ADD_INPUT_LIBRARY:
761 add_input_library = p->tv_u.tv_add_input_library;
762 break;
763 case LDPT_OPTION:
764 process_option (p->tv_u.tv_string);
765 break;
766 default:
767 break;
769 p++;
772 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
773 check (add_symbols, LDPL_FATAL, "add_symbols not found");
774 status = register_claim_file (claim_file_handler);
775 check (status == LDPS_OK, LDPL_FATAL,
776 "could not register the claim_file callback");
778 if (register_cleanup)
780 status = register_cleanup (cleanup_handler);
781 check (status == LDPS_OK, LDPL_FATAL,
782 "could not register the cleanup callback");
785 if (register_all_symbols_read)
787 check (get_symbols, LDPL_FATAL, "get_symbols not found");
788 status = register_all_symbols_read (all_symbols_read_handler);
789 check (status == LDPS_OK, LDPL_FATAL,
790 "could not register the all_symbols_read callback");
793 return LDPS_OK;