Merged r158907 through r159238 into branch.
[official-gcc.git] / lto-plugin / lto-plugin.c
blobcb785c428a8a491a20323df48d9f742eef54f01f
1 /* LTO plugin for gold.
2 Copyright (C) 2009 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>
48 /* The presence of gelf.h is checked by the toplevel configure script. */
49 #include <gelf.h>
51 #include "plugin-api.h"
52 #include "../gcc/lto/common.h"
54 /* The part of the symbol table the plugin has to keep track of. Note that we
55 must keep SYMS until all_symbols_read is called to give the linker time to
56 copy the symbol information. */
58 struct plugin_symtab
60 int nsyms;
61 uint32_t *slots;
62 struct ld_plugin_symbol *syms;
65 /* All that we have to remember about a file. */
67 struct plugin_file_info
69 char *name;
70 void *handle;
71 struct plugin_symtab symtab;
75 static char *arguments_file_name;
76 static ld_plugin_register_claim_file register_claim_file;
77 static ld_plugin_add_symbols add_symbols;
78 static ld_plugin_register_all_symbols_read register_all_symbols_read;
79 static ld_plugin_get_symbols get_symbols;
80 static ld_plugin_register_cleanup register_cleanup;
81 static ld_plugin_add_input_file add_input_file;
82 static ld_plugin_add_input_library add_input_library;
83 static ld_plugin_message message;
85 static struct plugin_file_info *claimed_files = NULL;
86 static unsigned int num_claimed_files = 0;
88 static char **output_files = NULL;
89 static unsigned int num_output_files = 0;
91 static char **lto_wrapper_argv;
92 static int lto_wrapper_num_args;
94 static char **pass_through_items = NULL;
95 static unsigned int num_pass_through_items;
97 static bool debug;
98 static bool nop;
99 static char *resolution_file = NULL;
101 static void
102 check (bool gate, enum ld_plugin_level level, const char *text)
104 if (gate)
105 return;
107 if (message)
108 message (level, text);
109 else
111 /* If there is no nicer way to inform the user, fallback to stderr. */
112 fprintf (stderr, "%s\n", text);
113 if (level == LDPL_FATAL)
114 abort ();
118 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
119 by P and the result is written in ENTRY. The slot number is stored in SLOT.
120 Returns the address of the next entry. */
122 static char *
123 parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
125 unsigned char t;
126 enum ld_plugin_symbol_kind translate_kind[] =
128 LDPK_DEF,
129 LDPK_WEAKDEF,
130 LDPK_UNDEF,
131 LDPK_WEAKUNDEF,
132 LDPK_COMMON
135 enum ld_plugin_symbol_visibility translate_visibility[] =
137 LDPV_DEFAULT,
138 LDPV_PROTECTED,
139 LDPV_INTERNAL,
140 LDPV_HIDDEN
143 entry->name = xstrdup (p);
144 while (*p)
145 p++;
146 p++;
148 entry->version = NULL;
150 entry->comdat_key = p;
151 while (*p)
152 p++;
153 p++;
155 if (strlen (entry->comdat_key) == 0)
156 entry->comdat_key = NULL;
157 else
158 entry->comdat_key = xstrdup (entry->comdat_key);
160 t = *p;
161 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
162 entry->def = translate_kind[t];
163 p++;
165 t = *p;
166 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
167 entry->visibility = translate_visibility[t];
168 p++;
170 entry->size = *(uint64_t *) p;
171 p += 8;
173 *slot = *(uint32_t *) p;
174 p += 4;
176 entry->resolution = LDPR_UNKNOWN;
178 return p;
181 /* Return the section in ELF that is named NAME. */
183 static Elf_Scn *
184 get_section (Elf *elf, const char *name)
186 Elf_Scn *section = 0;
187 GElf_Ehdr header;
188 GElf_Ehdr *t = gelf_getehdr (elf, &header);
189 if (t == NULL)
190 return NULL;
191 assert (t == &header);
193 while ((section = elf_nextscn(elf, section)) != 0)
195 GElf_Shdr shdr;
196 GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
197 const char *t;
198 assert (tshdr == &shdr);
199 t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
200 assert (t != NULL);
201 if (strcmp (t, name) == 0)
202 return section;
204 return NULL;
207 /* Returns the IL symbol table of file ELF. */
209 static Elf_Data *
210 get_symtab (Elf *elf)
212 Elf_Data *data = 0;
213 Elf_Scn *section = get_section (elf, ".gnu.lto_.symtab");
214 if (!section)
215 return NULL;
217 data = elf_getdata (section, data);
218 assert (data);
219 return data;
222 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
224 static void
225 translate (Elf_Data *symtab, struct plugin_symtab *out)
227 uint32_t *slots = NULL;
228 char *data = symtab->d_buf;
229 char *end = data + symtab->d_size;
230 struct ld_plugin_symbol *syms = NULL;
231 int n = 0;
233 while (data < end)
235 n++;
236 syms = xrealloc (syms, n * sizeof (struct ld_plugin_symbol));
237 check (syms, LDPL_FATAL, "could not allocate memory");
238 slots = xrealloc (slots, n * sizeof (uint32_t));
239 check (slots, LDPL_FATAL, "could not allocate memory");
240 data = parse_table_entry (data, &syms[n - 1], &slots[n - 1]);
243 out->nsyms = n;
244 out->syms = syms;
245 out->slots = slots;
248 /* Free all memory that is no longer needed after writing the symbol
249 resolution. */
251 static void
252 free_1 (void)
254 unsigned int i;
255 for (i = 0; i < num_claimed_files; i++)
257 struct plugin_file_info *info = &claimed_files[i];
258 struct plugin_symtab *symtab = &info->symtab;
259 unsigned int j;
260 for (j = 0; j < symtab->nsyms; j++)
262 struct ld_plugin_symbol *s = &symtab->syms[j];
263 free (s->name);
264 if (s->comdat_key)
265 free (s->comdat_key);
267 free (symtab->syms);
268 symtab->syms = NULL;
272 /* Free all remaining memory. */
274 static void
275 free_2 (void)
277 unsigned int i;
278 for (i = 0; i < num_claimed_files; i++)
280 struct plugin_file_info *info = &claimed_files[i];
281 struct plugin_symtab *symtab = &info->symtab;
282 free (symtab->slots);
283 free (info->name);
286 for (i = 0; i < num_output_files; i++)
287 free (output_files[i]);
288 free (output_files);
290 free (claimed_files);
291 claimed_files = NULL;
292 num_claimed_files = 0;
294 if (arguments_file_name)
295 free (arguments_file_name);
296 arguments_file_name = NULL;
299 /* Writes the relocations to disk. */
301 static void
302 write_resolution (void)
304 unsigned int i;
305 FILE *f;
307 check (resolution_file, LDPL_FATAL, "resolution file not specified");
308 f = fopen (resolution_file, "w");
309 check (f, LDPL_FATAL, "could not open file");
311 fprintf (f, "%d\n", num_claimed_files);
313 for (i = 0; i < num_claimed_files; i++)
315 struct plugin_file_info *info = &claimed_files[i];
316 struct plugin_symtab *symtab = &info->symtab;
317 struct ld_plugin_symbol *syms = symtab->syms;
318 unsigned j;
320 assert (syms);
321 get_symbols (info->handle, symtab->nsyms, syms);
323 fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
325 for (j = 0; j < info->symtab.nsyms; j++)
327 uint32_t slot = symtab->slots[j];
328 unsigned int resolution = syms[j].resolution;
329 fprintf (f, "%d %s %s\n", slot, lto_resolution_str[resolution], syms[j].name);
332 fclose (f);
335 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
336 stdout. */
338 static void
339 add_output_files (FILE *f)
341 for (;;)
343 const unsigned piece = 32;
344 char *buf, *s = xmalloc (piece);
345 size_t len;
347 buf = s;
348 cont:
349 if (!fgets (buf, piece, f))
350 break;
351 len = strlen (s);
352 if (s[len - 1] != '\n')
354 s = xrealloc (s, len + piece);
355 buf = s + len;
356 goto cont;
358 s[len - 1] = '\0';
360 num_output_files++;
361 output_files
362 = xrealloc (output_files, num_output_files * sizeof (char *));
363 output_files[num_output_files - 1] = s;
364 add_input_file (output_files[num_output_files - 1]);
368 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
369 argument list. */
371 static void
372 exec_lto_wrapper (char *argv[])
374 int t, i;
375 int status;
376 char *at_args;
377 FILE *args;
378 FILE *wrapper_output;
379 char *new_argv[3];
380 struct pex_obj *pex;
381 const char *errmsg;
383 /* Write argv to a file to avoid a command line that is too long. */
384 arguments_file_name = make_temp_file ("");
385 check (arguments_file_name, LDPL_FATAL,
386 "Failed to generate a temorary file name");
388 args = fopen (arguments_file_name, "w");
389 check (args, LDPL_FATAL, "could not open arguments file");
391 t = writeargv (&argv[1], args);
392 check (t == 0, LDPL_FATAL, "could not write arguments");
393 t = fclose (args);
394 check (t == 0, LDPL_FATAL, "could not close arguments file");
396 at_args = concat ("@", arguments_file_name, NULL);
397 check (at_args, LDPL_FATAL, "could not allocate");
399 for (i = 1; argv[i]; i++)
401 char *a = argv[i];
402 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
404 for (i = 0; argv[i]; i++)
405 fprintf (stderr, "%s ", argv[i]);
406 fprintf (stderr, "\n");
407 break;
411 new_argv[0] = argv[0];
412 new_argv[1] = at_args;
413 new_argv[2] = NULL;
415 if (debug)
417 for (i = 0; new_argv[i]; i++)
418 fprintf (stderr, "%s ", new_argv[i]);
419 fprintf (stderr, "\n");
423 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
424 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
426 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
427 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
428 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
430 wrapper_output = pex_read_output (pex, 0);
431 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
433 add_output_files (wrapper_output);
435 t = pex_get_status (pex, 1, &status);
436 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
437 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
438 "lto-wrapper failed");
440 pex_free (pex);
442 free (at_args);
445 /* Pass the original files back to the linker. */
447 static void
448 use_original_files (void)
450 unsigned i;
451 for (i = 0; i < num_claimed_files; i++)
453 struct plugin_file_info *info = &claimed_files[i];
454 add_input_file (info->name);
459 /* Called by the linker once all symbols have been read. */
461 static enum ld_plugin_status
462 all_symbols_read_handler (void)
464 unsigned i;
465 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
466 char **lto_argv;
467 const char **lto_arg_ptr;
468 if (num_claimed_files == 0)
469 return LDPS_OK;
471 if (nop)
473 use_original_files ();
474 return LDPS_OK;
477 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
478 lto_arg_ptr = (const char **) lto_argv;
479 assert (lto_wrapper_argv);
481 write_resolution ();
483 free_1 ();
485 for (i = 0; i < lto_wrapper_num_args; i++)
486 *lto_arg_ptr++ = lto_wrapper_argv[i];
488 for (i = 0; i < num_claimed_files; i++)
490 struct plugin_file_info *info = &claimed_files[i];
492 *lto_arg_ptr++ = info->name;
495 *lto_arg_ptr++ = NULL;
496 exec_lto_wrapper (lto_argv);
498 free (lto_argv);
500 if (pass_through_items)
502 unsigned int i;
503 for (i = 0; i < num_pass_through_items; i++)
505 if (strncmp (pass_through_items[i], "-l", 2) == 0)
506 add_input_library (pass_through_items[i] + 2);
507 else
508 add_input_file (pass_through_items[i]);
509 free (pass_through_items[i]);
510 pass_through_items[i] = NULL;
512 free (pass_through_items);
513 pass_through_items = NULL;
516 return LDPS_OK;
519 /* Remove temporary files at the end of the link. */
521 static enum ld_plugin_status
522 cleanup_handler (void)
524 unsigned int i;
525 int t;
527 if (debug)
528 return LDPS_OK;
530 if (arguments_file_name)
532 t = unlink (arguments_file_name);
533 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
536 for (i = 0; i < num_output_files; i++)
538 t = unlink (output_files[i]);
539 check (t == 0, LDPL_FATAL, "could not unlink output file");
542 free_2 ();
543 return LDPS_OK;
546 /* Callback used by gold to check if the plugin will claim FILE. Writes
547 the result in CLAIMED. */
549 static enum ld_plugin_status
550 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
552 enum ld_plugin_status status;
553 Elf *elf;
554 struct plugin_file_info lto_file;
555 Elf_Data *symtab;
557 if (file->offset != 0)
559 char *objname;
560 Elf *archive;
561 off_t offset;
562 /* We pass the offset of the actual file, not the archive header. */
563 int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
564 (int64_t) file->offset);
565 check (t >= 0, LDPL_FATAL, "asprintf failed");
566 lto_file.name = objname;
568 archive = elf_begin (file->fd, ELF_C_READ, NULL);
569 check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
570 "Not an archive and offset not 0");
572 /* elf_rand expects the offset to point to the ar header, not the
573 object itself. Subtract the size of the ar header (60 bytes).
574 We don't uses sizeof (struct ar_hd) to avoid including ar.h */
576 offset = file->offset - 60;
577 check (offset == elf_rand (archive, offset), LDPL_FATAL,
578 "could not seek in archive");
579 elf = elf_begin (file->fd, ELF_C_READ, archive);
580 check (elf != NULL, LDPL_FATAL, "could not find archive member");
581 elf_end (archive);
583 else
585 lto_file.name = xstrdup (file->name);
586 elf = elf_begin (file->fd, ELF_C_READ, NULL);
588 lto_file.handle = file->handle;
590 *claimed = 0;
592 if (!elf)
593 goto err;
595 symtab = get_symtab (elf);
596 if (!symtab)
597 goto err;
599 translate (symtab, &lto_file.symtab);
601 status = add_symbols (file->handle, lto_file.symtab.nsyms,
602 lto_file.symtab.syms);
603 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
605 *claimed = 1;
606 num_claimed_files++;
607 claimed_files =
608 xrealloc (claimed_files,
609 num_claimed_files * sizeof (struct plugin_file_info));
610 claimed_files[num_claimed_files - 1] = lto_file;
612 goto cleanup;
614 err:
615 free (lto_file.name);
617 cleanup:
618 if (elf)
619 elf_end (elf);
621 return LDPS_OK;
624 /* Parse the plugin options. */
626 static void
627 process_option (const char *option)
629 if (strcmp (option, "-debug") == 0)
630 debug = 1;
631 else if (strcmp (option, "-nop") == 0)
632 nop = 1;
633 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
635 num_pass_through_items++;
636 pass_through_items = xrealloc (pass_through_items,
637 num_pass_through_items * sizeof (char *));
638 pass_through_items[num_pass_through_items - 1] =
639 xstrdup (option + strlen ("-pass-through="));
641 else
643 int size;
644 char *opt = xstrdup (option);
645 lto_wrapper_num_args += 1;
646 size = lto_wrapper_num_args * sizeof (char *);
647 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
648 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
649 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
650 resolution_file = opt + sizeof ("-fresolution=") - 1;
654 /* Called by gold after loading the plugin. TV is the transfer vector. */
656 enum ld_plugin_status
657 onload (struct ld_plugin_tv *tv)
659 struct ld_plugin_tv *p;
660 enum ld_plugin_status status;
662 unsigned version = elf_version (EV_CURRENT);
663 check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
665 p = tv;
666 while (p->tv_tag)
668 switch (p->tv_tag)
670 case LDPT_MESSAGE:
671 message = p->tv_u.tv_message;
672 break;
673 case LDPT_REGISTER_CLAIM_FILE_HOOK:
674 register_claim_file = p->tv_u.tv_register_claim_file;
675 break;
676 case LDPT_ADD_SYMBOLS:
677 add_symbols = p->tv_u.tv_add_symbols;
678 break;
679 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
680 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
681 break;
682 case LDPT_GET_SYMBOLS:
683 get_symbols = p->tv_u.tv_get_symbols;
684 break;
685 case LDPT_REGISTER_CLEANUP_HOOK:
686 register_cleanup = p->tv_u.tv_register_cleanup;
687 break;
688 case LDPT_ADD_INPUT_FILE:
689 add_input_file = p->tv_u.tv_add_input_file;
690 break;
691 case LDPT_ADD_INPUT_LIBRARY:
692 add_input_library = p->tv_u.tv_add_input_library;
693 break;
694 case LDPT_OPTION:
695 process_option (p->tv_u.tv_string);
696 break;
697 default:
698 break;
700 p++;
703 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
704 check (add_symbols, LDPL_FATAL, "add_symbols not found");
705 status = register_claim_file (claim_file_handler);
706 check (status == LDPS_OK, LDPL_FATAL,
707 "could not register the claim_file callback");
709 if (register_cleanup)
711 status = register_cleanup (cleanup_handler);
712 check (status == LDPS_OK, LDPL_FATAL,
713 "could not register the cleanup callback");
716 if (register_all_symbols_read)
718 check (get_symbols, LDPL_FATAL, "get_symbols not found");
719 status = register_all_symbols_read (all_symbols_read_handler);
720 check (status == LDPS_OK, LDPL_FATAL,
721 "could not register the all_symbols_read callback");
724 return LDPS_OK;