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. */
44 #include <sys/types.h>
47 #include <libiberty.h>
49 /* The presence of gelf.h is checked by the toplevel configure script. */
52 #include "plugin-api.h"
53 #include "../gcc/lto/common.h"
55 /* The part of the symbol table the plugin has to keep track of. Note that we
56 must keep SYMS until all_symbols_read is called to give the linker time to
57 copy the symbol information. */
63 struct ld_plugin_symbol *syms;
66 /* All that we have to remember about a file. */
68 struct plugin_file_info
72 struct plugin_symtab symtab;
77 static char *temp_obj_dir_name;
78 static ld_plugin_register_claim_file register_claim_file;
79 static ld_plugin_add_symbols add_symbols;
80 static ld_plugin_register_all_symbols_read register_all_symbols_read;
81 static ld_plugin_get_symbols get_symbols;
82 static ld_plugin_register_cleanup register_cleanup;
83 static ld_plugin_add_input_file add_input_file;
84 static ld_plugin_add_input_library add_input_library;
85 static ld_plugin_message message;
87 static struct plugin_file_info *claimed_files = NULL;
88 static unsigned int num_claimed_files = 0;
90 static char **output_files = NULL;
91 static unsigned int num_output_files = 0;
93 static char **lto_wrapper_argv;
94 static int lto_wrapper_num_args;
96 static char **pass_through_items = NULL;
97 static unsigned int num_pass_through_items;
101 static char *resolution_file = NULL;
104 check (bool gate, enum ld_plugin_level level, const char *text)
110 message (level, text);
113 /* If there is no nicer way to inform the user, fallback to stderr. */
114 fprintf (stderr, "%s\n", text);
115 if (level == LDPL_FATAL)
120 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
121 by P and the result is written in ENTRY. The slot number is stored in SLOT.
122 Returns the address of the next entry. */
125 parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
128 enum ld_plugin_symbol_kind translate_kind[] =
137 enum ld_plugin_symbol_visibility translate_visibility[] =
145 entry->name = strdup (p);
150 entry->version = NULL;
152 entry->comdat_key = p;
157 if (strlen (entry->comdat_key) == 0)
158 entry->comdat_key = NULL;
160 entry->comdat_key = strdup (entry->comdat_key);
163 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
164 entry->def = translate_kind[t];
168 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
169 entry->visibility = translate_visibility[t];
172 entry->size = *(uint64_t *) p;
175 *slot = *(uint32_t *) p;
178 entry->resolution = LDPR_UNKNOWN;
183 /* Return the section in ELF that is named NAME. */
186 get_section (Elf *elf, const char *name)
188 Elf_Scn *section = 0;
190 GElf_Ehdr *t = gelf_getehdr (elf, &header);
193 assert (t == &header);
195 while ((section = elf_nextscn(elf, section)) != 0)
198 GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
200 assert (tshdr == &shdr);
201 t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
203 if (strcmp (t, name) == 0)
209 /* Returns the IL symbol table of file ELF. */
212 get_symtab (Elf *elf)
215 Elf_Scn *section = get_section (elf, ".gnu.lto_.symtab");
219 data = elf_getdata (section, data);
224 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
227 translate (Elf_Data *symtab, struct plugin_symtab *out)
229 uint32_t *slots = NULL;
230 char *data = symtab->d_buf;
231 char *end = data + symtab->d_size;
232 struct ld_plugin_symbol *syms = NULL;
238 syms = realloc (syms, n * sizeof (struct ld_plugin_symbol));
239 check (syms, LDPL_FATAL, "could not allocate memory");
240 slots = realloc (slots, n * sizeof (uint32_t));
241 check (slots, LDPL_FATAL, "could not allocate memory");
242 data = parse_table_entry (data, &syms[n - 1], &slots[n - 1]);
250 /* Free all memory that is no longer needed after writing the symbol
257 for (i = 0; i < num_claimed_files; i++)
259 struct plugin_file_info *info = &claimed_files[i];
260 struct plugin_symtab *symtab = &info->symtab;
262 for (j = 0; j < symtab->nsyms; j++)
264 struct ld_plugin_symbol *s = &symtab->syms[j];
267 free (s->comdat_key);
274 /* Free all remaining memory. */
280 for (i = 0; i < num_claimed_files; i++)
282 struct plugin_file_info *info = &claimed_files[i];
283 struct plugin_symtab *symtab = &info->symtab;
284 free (symtab->slots);
288 for (i = 0; i < num_output_files; i++)
289 free (output_files[i]);
292 free (claimed_files);
293 claimed_files = NULL;
294 num_claimed_files = 0;
296 free (temp_obj_dir_name);
297 temp_obj_dir_name = NULL;
301 free (resolution_file);
302 resolution_file = NULL;
306 /* Writes the relocations to disk. */
309 write_resolution (void)
314 if (!resolution_file)
317 f = fopen (resolution_file, "w");
318 check (f, LDPL_FATAL, "could not open file");
320 fprintf (f, "%d\n", num_claimed_files);
322 for (i = 0; i < num_claimed_files; i++)
324 struct plugin_file_info *info = &claimed_files[i];
325 struct plugin_symtab *symtab = &info->symtab;
326 struct ld_plugin_symbol *syms = symtab->syms;
330 get_symbols (info->handle, symtab->nsyms, syms);
332 fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
334 for (j = 0; j < info->symtab.nsyms; j++)
336 uint32_t slot = symtab->slots[j];
337 unsigned int resolution = syms[j].resolution;
338 fprintf (f, "%d %s\n", slot, lto_resolution_str[resolution]);
344 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
348 add_output_files (FILE *f)
350 char fname[1000]; /* FIXME: Remove this restriction. */
355 char *s = fgets (fname, sizeof (fname), f);
360 check (s[len - 1] == '\n', LDPL_FATAL, "file name too long");
364 output_files = realloc (output_files, num_output_files * sizeof (char *));
365 output_files[num_output_files - 1] = strdup (s);
366 add_input_file (output_files[num_output_files - 1]);
370 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
374 exec_lto_wrapper (char *argv[])
381 FILE *wrapper_output;
386 /* Write argv to a file to avoid a command line that is too long. */
387 t = asprintf (&at_args, "@%s/arguments", temp_obj_dir_name);
388 check (t >= 0, LDPL_FATAL, "asprintf failed");
390 args_name = at_args + 1;
391 args = fopen (args_name, "w");
392 check (args, LDPL_FATAL, "could not open arguments file");
394 t = writeargv (&argv[1], args);
395 check (t == 0, LDPL_FATAL, "could not write arguments");
397 check (t == 0, LDPL_FATAL, "could not close arguments file");
399 new_argv[0] = argv[0];
400 new_argv[1] = at_args;
406 for (i = 0; new_argv[i]; i++)
407 fprintf (stderr, "%s ", new_argv[i]);
408 fprintf (stderr, "\n");
412 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
413 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
415 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
416 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
417 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
419 wrapper_output = pex_read_output (pex, 0);
420 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
422 add_output_files (wrapper_output);
424 t = pex_get_status (pex, 1, &status);
425 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
426 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
427 "lto-wrapper failed");
431 t = unlink (args_name);
432 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
436 /* Pass the original files back to the linker. */
439 use_original_files (void)
442 for (i = 0; i < num_claimed_files; i++)
444 struct plugin_file_info *info = &claimed_files[i];
445 add_input_file (info->name);
450 /* Called by the linker once all symbols have been read. */
452 static enum ld_plugin_status
453 all_symbols_read_handler (void)
456 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
458 const char **lto_arg_ptr;
459 if (num_claimed_files == 0)
464 use_original_files ();
468 lto_argv = (char **) calloc (sizeof (char *), num_lto_args);
469 lto_arg_ptr = (const char **) lto_argv;
470 assert (lto_wrapper_argv);
476 for (i = 0; i < lto_wrapper_num_args; i++)
477 *lto_arg_ptr++ = lto_wrapper_argv[i];
479 for (i = 0; i < num_claimed_files; i++)
481 struct plugin_file_info *info = &claimed_files[i];
483 *lto_arg_ptr++ = info->name;
486 *lto_arg_ptr++ = NULL;
487 exec_lto_wrapper (lto_argv);
491 if (pass_through_items)
494 for (i = 0; i < num_pass_through_items; i++)
496 if (strncmp (pass_through_items[i], "-l", 2) == 0)
497 add_input_library (pass_through_items[i] + 2);
499 add_input_file (pass_through_items[i]);
500 free (pass_through_items[i]);
501 pass_through_items[i] = NULL;
503 free (pass_through_items);
504 pass_through_items = NULL;
510 /* Remove temporary files at the end of the link. */
512 static enum ld_plugin_status
513 cleanup_handler (void)
515 /* Note: we cannot use LDPL_FATAL in here as that would produce
522 for (i = 0; i < num_claimed_files; i++)
524 struct plugin_file_info *info = &claimed_files[i];
527 t = unlink (info->name);
528 check (t == 0, LDPL_ERROR, "could not unlink temporary file");
532 /* If we are being called from an error handler, it is possible
533 that the arguments file is still exists. */
534 t = asprintf (&arguments, "%s/arguments", temp_obj_dir_name);
535 check (t >= 0, LDPL_ERROR, "asprintf failed");
536 if (stat(arguments, &buf) == 0)
538 t = unlink (arguments);
539 check (t == 0, LDPL_ERROR, "could not unlink arguments file");
543 t = rmdir (temp_obj_dir_name);
544 check (t == 0, LDPL_ERROR, "could not remove temporary directory");
550 /* Callback used by gold to check if the plugin will claim FILE. Writes
551 the result in CLAIMED. */
553 static enum ld_plugin_status
554 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
556 enum ld_plugin_status status;
558 struct plugin_file_info lto_file;
562 if (file->offset != 0)
564 /* FIXME lto: lto1 should know how to handle archives. */
566 off_t size = file->filesize;
569 static int objnum = 0;
571 int t = asprintf (&objname, "%s/obj%d.o",
572 temp_obj_dir_name, objnum);
573 check (t >= 0, LDPL_FATAL, "asprintf failed");
576 fd = open (objname, O_RDWR | O_CREAT, 0666);
577 check (fd > 0, LDPL_FATAL, "could not open/create temporary file");
578 offset = lseek (file->fd, file->offset, SEEK_SET);
579 check (offset == file->offset, LDPL_FATAL, "could not seek");
584 off_t s = sizeof (buf) < size ? sizeof (buf) : size;
585 r = read (file->fd, buf, s);
586 written = write (fd, buf, r);
587 check (written == r, LDPL_FATAL, "could not write to temporary file");
590 lto_file.name = objname;
592 lto_file.handle = file->handle;
597 lto_file.name = strdup (file->name);
598 lto_file_fd = file->fd;
599 lto_file.handle = file->handle;
602 elf = elf_begin (lto_file_fd, ELF_C_READ, NULL);
609 symtab = get_symtab (elf);
613 translate (symtab, <o_file.symtab);
615 status = add_symbols (file->handle, lto_file.symtab.nsyms,
616 lto_file.symtab.syms);
617 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
622 realloc (claimed_files,
623 num_claimed_files * sizeof (struct plugin_file_info));
624 claimed_files[num_claimed_files - 1] = lto_file;
629 if (file->offset != 0)
631 int t = unlink (lto_file.name);
632 check (t == 0, LDPL_FATAL, "could not unlink file");
634 free (lto_file.name);
643 /* Parse the plugin options. */
646 process_option (const char *option)
648 if (strcmp (option, "-debug") == 0)
650 else if (strcmp (option, "-nop") == 0)
652 else if (!strncmp (option, "-resolution=", strlen("-resolution=")))
654 resolution_file = strdup (option + strlen("-resolution="));
656 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
658 num_pass_through_items++;
659 pass_through_items = realloc (pass_through_items,
660 num_pass_through_items * sizeof (char *));
661 pass_through_items[num_pass_through_items - 1] =
662 strdup (option + strlen ("-pass-through="));
667 lto_wrapper_num_args += 1;
668 size = lto_wrapper_num_args * sizeof (char *);
669 lto_wrapper_argv = (char **) realloc (lto_wrapper_argv, size);
670 lto_wrapper_argv[lto_wrapper_num_args - 1] = strdup(option);
674 /* Called by gold after loading the plugin. TV is the transfer vector. */
676 enum ld_plugin_status
677 onload (struct ld_plugin_tv *tv)
679 struct ld_plugin_tv *p;
680 enum ld_plugin_status status;
683 unsigned version = elf_version (EV_CURRENT);
684 check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
692 message = p->tv_u.tv_message;
694 case LDPT_REGISTER_CLAIM_FILE_HOOK:
695 register_claim_file = p->tv_u.tv_register_claim_file;
697 case LDPT_ADD_SYMBOLS:
698 add_symbols = p->tv_u.tv_add_symbols;
700 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
701 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
703 case LDPT_GET_SYMBOLS:
704 get_symbols = p->tv_u.tv_get_symbols;
706 case LDPT_REGISTER_CLEANUP_HOOK:
707 register_cleanup = p->tv_u.tv_register_cleanup;
709 case LDPT_ADD_INPUT_FILE:
710 add_input_file = p->tv_u.tv_add_input_file;
712 case LDPT_ADD_INPUT_LIBRARY:
713 add_input_library = p->tv_u.tv_add_input_library;
716 process_option (p->tv_u.tv_string);
724 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
725 check (add_symbols, LDPL_FATAL, "add_symbols not found");
726 status = register_claim_file (claim_file_handler);
727 check (status == LDPS_OK, LDPL_FATAL,
728 "could not register the claim_file callback");
730 if (register_cleanup)
732 status = register_cleanup (cleanup_handler);
733 check (status == LDPS_OK, LDPL_FATAL,
734 "could not register the cleanup callback");
737 if (register_all_symbols_read)
739 check (get_symbols, LDPL_FATAL, "get_symbols not found");
740 status = register_all_symbols_read (all_symbols_read_handler);
741 check (status == LDPS_OK, LDPL_FATAL,
742 "could not register the all_symbols_read callback");
745 temp_obj_dir_name = strdup ("tmp_objectsXXXXXX");
746 t = mkdtemp (temp_obj_dir_name);
747 assert (t == temp_obj_dir_name);