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)
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. */
43 #include <sys/types.h>
46 #include <libiberty.h>
48 /* The presence of gelf.h is checked by the toplevel configure script. */
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. */
68 struct ld_plugin_symbol *syms;
72 /* All that we have to remember about a file. */
74 struct plugin_file_info
78 struct plugin_symtab symtab;
82 static char *arguments_file_name;
83 static ld_plugin_register_claim_file register_claim_file;
84 static ld_plugin_add_symbols add_symbols;
85 static ld_plugin_register_all_symbols_read register_all_symbols_read;
86 static ld_plugin_get_symbols get_symbols;
87 static ld_plugin_register_cleanup register_cleanup;
88 static ld_plugin_add_input_file add_input_file;
89 static ld_plugin_add_input_library add_input_library;
90 static ld_plugin_message message;
92 static struct plugin_file_info *claimed_files = NULL;
93 static unsigned int num_claimed_files = 0;
95 static char **output_files = NULL;
96 static unsigned int num_output_files = 0;
98 static char **lto_wrapper_argv;
99 static int lto_wrapper_num_args;
101 static char **pass_through_items = NULL;
102 static unsigned int num_pass_through_items;
106 static char *resolution_file = NULL;
109 check (bool gate, enum ld_plugin_level level, const char *text)
115 message (level, text);
118 /* If there is no nicer way to inform the user, fallback to stderr. */
119 fprintf (stderr, "%s\n", text);
120 if (level == LDPL_FATAL)
125 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
126 by P and the result is written in ENTRY. The slot number is stored in SLOT.
127 Returns the address of the next entry. */
130 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
134 enum ld_plugin_symbol_kind translate_kind[] =
143 enum ld_plugin_symbol_visibility translate_visibility[] =
151 entry->name = xstrdup (p);
156 entry->version = NULL;
158 entry->comdat_key = p;
163 if (strlen (entry->comdat_key) == 0)
164 entry->comdat_key = NULL;
166 entry->comdat_key = xstrdup (entry->comdat_key);
169 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
170 entry->def = translate_kind[t];
174 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
175 entry->visibility = translate_visibility[t];
178 entry->size = *(uint64_t *) p;
181 aux->slot = *(uint32_t *) p;
184 entry->resolution = LDPR_UNKNOWN;
189 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
191 /* Translate the IL symbol table SYMTAB. Append the slots and symbols to OUT. */
194 translate (Elf_Data *symtab, struct plugin_symtab *out)
197 char *data = symtab->d_buf;
198 char *end = data + symtab->d_size;
199 struct ld_plugin_symbol *syms = NULL;
202 /* This overestimates the output buffer sizes, but at least
203 the algorithm is O(1) now. */
205 len = (end - data)/8 + out->nsyms + 1;
206 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
207 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
209 for (n = out->nsyms; data < end; n++)
212 data = parse_table_entry (data, &syms[n], &aux[n]);
215 fprintf (stderr, "n = %d len = %d end-data=%lu\n", n, len, end-data);
223 /* Process all lto symtabs of file ELF. */
226 process_symtab (Elf *elf, struct plugin_symtab *out)
229 Elf_Scn *section = 0;
231 GElf_Ehdr *t = gelf_getehdr (elf, &header);
234 assert (t == &header);
236 while ((section = elf_nextscn(elf, section)) != 0)
239 GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
241 assert (tshdr == &shdr);
242 t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
244 if (strncmp (t, LTO_SECTION_PREFIX, strlen (LTO_SECTION_PREFIX)) == 0)
246 char *s = strrchr (t, '.');
248 sscanf (s, ".%x", &out->id);
249 translate (elf_getdata (section, NULL), out);
256 /* Free all memory that is no longer needed after writing the symbol
263 for (i = 0; i < num_claimed_files; i++)
265 struct plugin_file_info *info = &claimed_files[i];
266 struct plugin_symtab *symtab = &info->symtab;
268 for (j = 0; j < symtab->nsyms; j++)
270 struct ld_plugin_symbol *s = &symtab->syms[j];
273 free (s->comdat_key);
280 /* Free all remaining memory. */
286 for (i = 0; i < num_claimed_files; i++)
288 struct plugin_file_info *info = &claimed_files[i];
289 struct plugin_symtab *symtab = &info->symtab;
294 for (i = 0; i < num_output_files; i++)
295 free (output_files[i]);
298 free (claimed_files);
299 claimed_files = NULL;
300 num_claimed_files = 0;
302 if (arguments_file_name)
303 free (arguments_file_name);
304 arguments_file_name = NULL;
307 /* Writes the relocations to disk. */
310 write_resolution (void)
315 check (resolution_file, LDPL_FATAL, "resolution file not specified");
316 f = fopen (resolution_file, "w");
317 check (f, LDPL_FATAL, "could not open file");
319 fprintf (f, "%d\n", num_claimed_files);
321 for (i = 0; i < num_claimed_files; i++)
323 struct plugin_file_info *info = &claimed_files[i];
324 struct plugin_symtab *symtab = &info->symtab;
325 struct ld_plugin_symbol *syms = symtab->syms;
328 get_symbols (info->handle, symtab->nsyms, syms);
330 fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
332 for (j = 0; j < info->symtab.nsyms; j++)
334 uint32_t slot = symtab->aux[j].slot;
335 unsigned int resolution = syms[j].resolution;
336 fprintf (f, "%d %x %s %s\n", slot, symtab->aux[j].id,
337 lto_resolution_str[resolution], syms[j].name);
343 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
347 add_output_files (FILE *f)
351 const unsigned piece = 32;
352 char *buf, *s = xmalloc (piece);
357 if (!fgets (buf, piece, f))
360 if (s[len - 1] != '\n')
362 s = xrealloc (s, len + piece);
370 = xrealloc (output_files, num_output_files * sizeof (char *));
371 output_files[num_output_files - 1] = s;
372 add_input_file (output_files[num_output_files - 1]);
376 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
380 exec_lto_wrapper (char *argv[])
386 FILE *wrapper_output;
391 /* Write argv to a file to avoid a command line that is too long. */
392 arguments_file_name = make_temp_file ("");
393 check (arguments_file_name, LDPL_FATAL,
394 "Failed to generate a temorary file name");
396 args = fopen (arguments_file_name, "w");
397 check (args, LDPL_FATAL, "could not open arguments file");
399 t = writeargv (&argv[1], args);
400 check (t == 0, LDPL_FATAL, "could not write arguments");
402 check (t == 0, LDPL_FATAL, "could not close arguments file");
404 at_args = concat ("@", arguments_file_name, NULL);
405 check (at_args, LDPL_FATAL, "could not allocate");
407 for (i = 1; argv[i]; i++)
410 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
412 for (i = 0; argv[i]; i++)
413 fprintf (stderr, "%s ", argv[i]);
414 fprintf (stderr, "\n");
419 new_argv[0] = argv[0];
420 new_argv[1] = at_args;
425 for (i = 0; new_argv[i]; i++)
426 fprintf (stderr, "%s ", new_argv[i]);
427 fprintf (stderr, "\n");
431 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
432 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
434 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
435 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
436 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
438 wrapper_output = pex_read_output (pex, 0);
439 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
441 add_output_files (wrapper_output);
443 t = pex_get_status (pex, 1, &status);
444 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
445 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
446 "lto-wrapper failed");
453 /* Pass the original files back to the linker. */
456 use_original_files (void)
459 for (i = 0; i < num_claimed_files; i++)
461 struct plugin_file_info *info = &claimed_files[i];
462 add_input_file (info->name);
467 /* Called by the linker once all symbols have been read. */
469 static enum ld_plugin_status
470 all_symbols_read_handler (void)
473 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
475 const char **lto_arg_ptr;
476 if (num_claimed_files == 0)
481 use_original_files ();
485 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
486 lto_arg_ptr = (const char **) lto_argv;
487 assert (lto_wrapper_argv);
493 for (i = 0; i < lto_wrapper_num_args; i++)
494 *lto_arg_ptr++ = lto_wrapper_argv[i];
496 for (i = 0; i < num_claimed_files; i++)
498 struct plugin_file_info *info = &claimed_files[i];
500 *lto_arg_ptr++ = info->name;
503 *lto_arg_ptr++ = NULL;
504 exec_lto_wrapper (lto_argv);
508 if (pass_through_items)
511 for (i = 0; i < num_pass_through_items; i++)
513 if (strncmp (pass_through_items[i], "-l", 2) == 0)
514 add_input_library (pass_through_items[i] + 2);
516 add_input_file (pass_through_items[i]);
517 free (pass_through_items[i]);
518 pass_through_items[i] = NULL;
520 free (pass_through_items);
521 pass_through_items = NULL;
527 /* Remove temporary files at the end of the link. */
529 static enum ld_plugin_status
530 cleanup_handler (void)
538 if (arguments_file_name)
540 t = unlink (arguments_file_name);
541 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
544 for (i = 0; i < num_output_files; i++)
546 t = unlink (output_files[i]);
547 check (t == 0, LDPL_FATAL, "could not unlink output file");
554 /* Callback used by gold to check if the plugin will claim FILE. Writes
555 the result in CLAIMED. */
557 static enum ld_plugin_status
558 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
560 enum ld_plugin_status status;
562 struct plugin_file_info lto_file;
564 memset (<o_file, 0, sizeof (struct plugin_file_info));
566 if (file->offset != 0)
571 /* We pass the offset of the actual file, not the archive header. */
572 int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
573 (int64_t) file->offset);
574 check (t >= 0, LDPL_FATAL, "asprintf failed");
575 lto_file.name = objname;
577 archive = elf_begin (file->fd, ELF_C_READ, NULL);
578 check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
579 "Not an archive and offset not 0");
581 /* elf_rand expects the offset to point to the ar header, not the
582 object itself. Subtract the size of the ar header (60 bytes).
583 We don't uses sizeof (struct ar_hd) to avoid including ar.h */
585 offset = file->offset - 60;
586 check (offset == elf_rand (archive, offset), LDPL_FATAL,
587 "could not seek in archive");
588 elf = elf_begin (file->fd, ELF_C_READ, archive);
589 check (elf != NULL, LDPL_FATAL, "could not find archive member");
594 lto_file.name = xstrdup (file->name);
595 elf = elf_begin (file->fd, ELF_C_READ, NULL);
597 lto_file.handle = file->handle;
601 if (!elf || !process_symtab (elf, <o_file.symtab))
604 status = add_symbols (file->handle, lto_file.symtab.nsyms,
605 lto_file.symtab.syms);
606 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
611 xrealloc (claimed_files,
612 num_claimed_files * sizeof (struct plugin_file_info));
613 claimed_files[num_claimed_files - 1] = lto_file;
618 free (lto_file.name);
627 /* Parse the plugin options. */
630 process_option (const char *option)
632 if (strcmp (option, "-debug") == 0)
634 else if (strcmp (option, "-nop") == 0)
636 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
638 num_pass_through_items++;
639 pass_through_items = xrealloc (pass_through_items,
640 num_pass_through_items * sizeof (char *));
641 pass_through_items[num_pass_through_items - 1] =
642 xstrdup (option + strlen ("-pass-through="));
647 char *opt = xstrdup (option);
648 lto_wrapper_num_args += 1;
649 size = lto_wrapper_num_args * sizeof (char *);
650 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
651 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
652 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
653 resolution_file = opt + sizeof ("-fresolution=") - 1;
657 /* Called by gold after loading the plugin. TV is the transfer vector. */
659 enum ld_plugin_status
660 onload (struct ld_plugin_tv *tv)
662 struct ld_plugin_tv *p;
663 enum ld_plugin_status status;
665 unsigned version = elf_version (EV_CURRENT);
666 check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
674 message = p->tv_u.tv_message;
676 case LDPT_REGISTER_CLAIM_FILE_HOOK:
677 register_claim_file = p->tv_u.tv_register_claim_file;
679 case LDPT_ADD_SYMBOLS:
680 add_symbols = p->tv_u.tv_add_symbols;
682 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
683 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
685 case LDPT_GET_SYMBOLS:
686 get_symbols = p->tv_u.tv_get_symbols;
688 case LDPT_REGISTER_CLEANUP_HOOK:
689 register_cleanup = p->tv_u.tv_register_cleanup;
691 case LDPT_ADD_INPUT_FILE:
692 add_input_file = p->tv_u.tv_add_input_file;
694 case LDPT_ADD_INPUT_LIBRARY:
695 add_input_library = p->tv_u.tv_add_input_library;
698 process_option (p->tv_u.tv_string);
706 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
707 check (add_symbols, LDPL_FATAL, "add_symbols not found");
708 status = register_claim_file (claim_file_handler);
709 check (status == LDPS_OK, LDPL_FATAL,
710 "could not register the claim_file callback");
712 if (register_cleanup)
714 status = register_cleanup (cleanup_handler);
715 check (status == LDPS_OK, LDPL_FATAL,
716 "could not register the cleanup callback");
719 if (register_all_symbols_read)
721 check (get_symbols, LDPL_FATAL, "get_symbols not found");
722 status = register_all_symbols_read (all_symbols_read_handler);
723 check (status == LDPS_OK, LDPL_FATAL,
724 "could not register the all_symbols_read callback");