2010-07-27 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc/alias-decl.git] / lto-plugin / lto-plugin.c
blobf2ca90ccf7435ff8f0b58c47c48c110ad6ecdf33
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 sym_aux
60 uint32_t slot;
61 unsigned id;
64 struct plugin_symtab
66 int nsyms;
67 struct sym_aux *aux;
68 struct ld_plugin_symbol *syms;
69 unsigned id;
72 /* All that we have to remember about a file. */
74 struct plugin_file_info
76 char *name;
77 void *handle;
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;
104 static bool debug;
105 static bool nop;
106 static char *resolution_file = NULL;
108 static void
109 check (bool gate, enum ld_plugin_level level, const char *text)
111 if (gate)
112 return;
114 if (message)
115 message (level, text);
116 else
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)
121 abort ();
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. */
129 static char *
130 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
131 struct sym_aux *aux)
133 unsigned char t;
134 enum ld_plugin_symbol_kind translate_kind[] =
136 LDPK_DEF,
137 LDPK_WEAKDEF,
138 LDPK_UNDEF,
139 LDPK_WEAKUNDEF,
140 LDPK_COMMON
143 enum ld_plugin_symbol_visibility translate_visibility[] =
145 LDPV_DEFAULT,
146 LDPV_PROTECTED,
147 LDPV_INTERNAL,
148 LDPV_HIDDEN
151 entry->name = xstrdup (p);
152 while (*p)
153 p++;
154 p++;
156 entry->version = NULL;
158 entry->comdat_key = p;
159 while (*p)
160 p++;
161 p++;
163 if (strlen (entry->comdat_key) == 0)
164 entry->comdat_key = NULL;
165 else
166 entry->comdat_key = xstrdup (entry->comdat_key);
168 t = *p;
169 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
170 entry->def = translate_kind[t];
171 p++;
173 t = *p;
174 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
175 entry->visibility = translate_visibility[t];
176 p++;
178 entry->size = *(uint64_t *) p;
179 p += 8;
181 aux->slot = *(uint32_t *) p;
182 p += 4;
184 entry->resolution = LDPR_UNKNOWN;
186 return p;
189 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
191 /* Translate the IL symbol table SYMTAB. Append the slots and symbols to OUT. */
193 static void
194 translate (Elf_Data *symtab, struct plugin_symtab *out)
196 struct sym_aux *aux;
197 char *data = symtab->d_buf;
198 char *end = data + symtab->d_size;
199 struct ld_plugin_symbol *syms = NULL;
200 int n, len;
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++)
211 aux[n].id = out->id;
212 data = parse_table_entry (data, &syms[n], &aux[n]);
215 fprintf (stderr, "n = %d len = %d end-data=%lu\n", n, len,
216 (unsigned long) (end - data));
217 assert(n < len);
219 out->nsyms = n;
220 out->syms = syms;
221 out->aux = aux;
224 /* Process all lto symtabs of file ELF. */
226 static int
227 process_symtab (Elf *elf, struct plugin_symtab *out)
229 int found = 0;
230 Elf_Scn *section = 0;
231 GElf_Ehdr header;
232 GElf_Ehdr *t = gelf_getehdr (elf, &header);
233 if (t == NULL)
234 return 0;
235 assert (t == &header);
237 while ((section = elf_nextscn(elf, section)) != 0)
239 GElf_Shdr shdr;
240 GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
241 const char *t;
242 assert (tshdr == &shdr);
243 t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
244 assert (t != NULL);
245 if (strncmp (t, LTO_SECTION_PREFIX, strlen (LTO_SECTION_PREFIX)) == 0)
247 char *s = strrchr (t, '.');
248 if (s)
249 sscanf (s, ".%x", &out->id);
250 translate (elf_getdata (section, NULL), out);
251 found = 1;
254 return found;
257 /* Free all memory that is no longer needed after writing the symbol
258 resolution. */
260 static void
261 free_1 (void)
263 unsigned int i;
264 for (i = 0; i < num_claimed_files; i++)
266 struct plugin_file_info *info = &claimed_files[i];
267 struct plugin_symtab *symtab = &info->symtab;
268 unsigned int j;
269 for (j = 0; j < symtab->nsyms; j++)
271 struct ld_plugin_symbol *s = &symtab->syms[j];
272 free (s->name);
273 if (s->comdat_key)
274 free (s->comdat_key);
276 free (symtab->syms);
277 symtab->syms = NULL;
281 /* Free all remaining memory. */
283 static void
284 free_2 (void)
286 unsigned int i;
287 for (i = 0; i < num_claimed_files; i++)
289 struct plugin_file_info *info = &claimed_files[i];
290 struct plugin_symtab *symtab = &info->symtab;
291 free (symtab->aux);
292 free (info->name);
295 for (i = 0; i < num_output_files; i++)
296 free (output_files[i]);
297 free (output_files);
299 free (claimed_files);
300 claimed_files = NULL;
301 num_claimed_files = 0;
303 if (arguments_file_name)
304 free (arguments_file_name);
305 arguments_file_name = NULL;
308 /* Writes the relocations to disk. */
310 static void
311 write_resolution (void)
313 unsigned int i;
314 FILE *f;
316 check (resolution_file, LDPL_FATAL, "resolution file not specified");
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;
327 unsigned j;
329 get_symbols (info->handle, symtab->nsyms, syms);
331 fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
333 for (j = 0; j < info->symtab.nsyms; j++)
335 uint32_t slot = symtab->aux[j].slot;
336 unsigned int resolution = syms[j].resolution;
337 fprintf (f, "%d %x %s %s\n", slot, symtab->aux[j].id,
338 lto_resolution_str[resolution], syms[j].name);
341 fclose (f);
344 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
345 stdout. */
347 static void
348 add_output_files (FILE *f)
350 for (;;)
352 const unsigned piece = 32;
353 char *buf, *s = xmalloc (piece);
354 size_t len;
356 buf = s;
357 cont:
358 if (!fgets (buf, piece, f))
359 break;
360 len = strlen (s);
361 if (s[len - 1] != '\n')
363 s = xrealloc (s, len + piece);
364 buf = s + len;
365 goto cont;
367 s[len - 1] = '\0';
369 num_output_files++;
370 output_files
371 = xrealloc (output_files, num_output_files * sizeof (char *));
372 output_files[num_output_files - 1] = s;
373 add_input_file (output_files[num_output_files - 1]);
377 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
378 argument list. */
380 static void
381 exec_lto_wrapper (char *argv[])
383 int t, i;
384 int status;
385 char *at_args;
386 FILE *args;
387 FILE *wrapper_output;
388 char *new_argv[3];
389 struct pex_obj *pex;
390 const char *errmsg;
392 /* Write argv to a file to avoid a command line that is too long. */
393 arguments_file_name = make_temp_file ("");
394 check (arguments_file_name, LDPL_FATAL,
395 "Failed to generate a temorary file name");
397 args = fopen (arguments_file_name, "w");
398 check (args, LDPL_FATAL, "could not open arguments file");
400 t = writeargv (&argv[1], args);
401 check (t == 0, LDPL_FATAL, "could not write arguments");
402 t = fclose (args);
403 check (t == 0, LDPL_FATAL, "could not close arguments file");
405 at_args = concat ("@", arguments_file_name, NULL);
406 check (at_args, LDPL_FATAL, "could not allocate");
408 for (i = 1; argv[i]; i++)
410 char *a = argv[i];
411 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
413 for (i = 0; argv[i]; i++)
414 fprintf (stderr, "%s ", argv[i]);
415 fprintf (stderr, "\n");
416 break;
420 new_argv[0] = argv[0];
421 new_argv[1] = at_args;
422 new_argv[2] = NULL;
424 if (debug)
426 for (i = 0; new_argv[i]; i++)
427 fprintf (stderr, "%s ", new_argv[i]);
428 fprintf (stderr, "\n");
432 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
433 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
435 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
436 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
437 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
439 wrapper_output = pex_read_output (pex, 0);
440 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
442 add_output_files (wrapper_output);
444 t = pex_get_status (pex, 1, &status);
445 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
446 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
447 "lto-wrapper failed");
449 pex_free (pex);
451 free (at_args);
454 /* Pass the original files back to the linker. */
456 static void
457 use_original_files (void)
459 unsigned i;
460 for (i = 0; i < num_claimed_files; i++)
462 struct plugin_file_info *info = &claimed_files[i];
463 add_input_file (info->name);
468 /* Called by the linker once all symbols have been read. */
470 static enum ld_plugin_status
471 all_symbols_read_handler (void)
473 unsigned i;
474 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
475 char **lto_argv;
476 const char **lto_arg_ptr;
477 if (num_claimed_files == 0)
478 return LDPS_OK;
480 if (nop)
482 use_original_files ();
483 return LDPS_OK;
486 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
487 lto_arg_ptr = (const char **) lto_argv;
488 assert (lto_wrapper_argv);
490 write_resolution ();
492 free_1 ();
494 for (i = 0; i < lto_wrapper_num_args; i++)
495 *lto_arg_ptr++ = lto_wrapper_argv[i];
497 for (i = 0; i < num_claimed_files; i++)
499 struct plugin_file_info *info = &claimed_files[i];
501 *lto_arg_ptr++ = info->name;
504 *lto_arg_ptr++ = NULL;
505 exec_lto_wrapper (lto_argv);
507 free (lto_argv);
509 if (pass_through_items)
511 unsigned int i;
512 for (i = 0; i < num_pass_through_items; i++)
514 if (strncmp (pass_through_items[i], "-l", 2) == 0)
515 add_input_library (pass_through_items[i] + 2);
516 else
517 add_input_file (pass_through_items[i]);
518 free (pass_through_items[i]);
519 pass_through_items[i] = NULL;
521 free (pass_through_items);
522 pass_through_items = NULL;
525 return LDPS_OK;
528 /* Remove temporary files at the end of the link. */
530 static enum ld_plugin_status
531 cleanup_handler (void)
533 unsigned int i;
534 int t;
536 if (debug)
537 return LDPS_OK;
539 if (arguments_file_name)
541 t = unlink (arguments_file_name);
542 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
545 for (i = 0; i < num_output_files; i++)
547 t = unlink (output_files[i]);
548 check (t == 0, LDPL_FATAL, "could not unlink output file");
551 free_2 ();
552 return LDPS_OK;
555 /* Callback used by gold to check if the plugin will claim FILE. Writes
556 the result in CLAIMED. */
558 static enum ld_plugin_status
559 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
561 enum ld_plugin_status status;
562 Elf *elf;
563 struct plugin_file_info lto_file;
565 memset (&lto_file, 0, sizeof (struct plugin_file_info));
567 if (file->offset != 0)
569 char *objname;
570 Elf *archive;
571 off_t offset;
572 /* We pass the offset of the actual file, not the archive header. */
573 int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
574 (int64_t) file->offset);
575 check (t >= 0, LDPL_FATAL, "asprintf failed");
576 lto_file.name = objname;
578 archive = elf_begin (file->fd, ELF_C_READ, NULL);
579 check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
580 "Not an archive and offset not 0");
582 /* elf_rand expects the offset to point to the ar header, not the
583 object itself. Subtract the size of the ar header (60 bytes).
584 We don't uses sizeof (struct ar_hd) to avoid including ar.h */
586 offset = file->offset - 60;
587 check (offset == elf_rand (archive, offset), LDPL_FATAL,
588 "could not seek in archive");
589 elf = elf_begin (file->fd, ELF_C_READ, archive);
590 check (elf != NULL, LDPL_FATAL, "could not find archive member");
591 elf_end (archive);
593 else
595 lto_file.name = xstrdup (file->name);
596 elf = elf_begin (file->fd, ELF_C_READ, NULL);
598 lto_file.handle = file->handle;
600 *claimed = 0;
602 if (!elf || !process_symtab (elf, &lto_file.symtab))
603 goto err;
605 status = add_symbols (file->handle, lto_file.symtab.nsyms,
606 lto_file.symtab.syms);
607 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
609 *claimed = 1;
610 num_claimed_files++;
611 claimed_files =
612 xrealloc (claimed_files,
613 num_claimed_files * sizeof (struct plugin_file_info));
614 claimed_files[num_claimed_files - 1] = lto_file;
616 goto cleanup;
618 err:
619 free (lto_file.name);
621 cleanup:
622 if (elf)
623 elf_end (elf);
625 return LDPS_OK;
628 /* Parse the plugin options. */
630 static void
631 process_option (const char *option)
633 if (strcmp (option, "-debug") == 0)
634 debug = 1;
635 else if (strcmp (option, "-nop") == 0)
636 nop = 1;
637 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
639 num_pass_through_items++;
640 pass_through_items = xrealloc (pass_through_items,
641 num_pass_through_items * sizeof (char *));
642 pass_through_items[num_pass_through_items - 1] =
643 xstrdup (option + strlen ("-pass-through="));
645 else
647 int size;
648 char *opt = xstrdup (option);
649 lto_wrapper_num_args += 1;
650 size = lto_wrapper_num_args * sizeof (char *);
651 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
652 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
653 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
654 resolution_file = opt + sizeof ("-fresolution=") - 1;
658 /* Called by gold after loading the plugin. TV is the transfer vector. */
660 enum ld_plugin_status
661 onload (struct ld_plugin_tv *tv)
663 struct ld_plugin_tv *p;
664 enum ld_plugin_status status;
666 unsigned version = elf_version (EV_CURRENT);
667 check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
669 p = tv;
670 while (p->tv_tag)
672 switch (p->tv_tag)
674 case LDPT_MESSAGE:
675 message = p->tv_u.tv_message;
676 break;
677 case LDPT_REGISTER_CLAIM_FILE_HOOK:
678 register_claim_file = p->tv_u.tv_register_claim_file;
679 break;
680 case LDPT_ADD_SYMBOLS:
681 add_symbols = p->tv_u.tv_add_symbols;
682 break;
683 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
684 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
685 break;
686 case LDPT_GET_SYMBOLS:
687 get_symbols = p->tv_u.tv_get_symbols;
688 break;
689 case LDPT_REGISTER_CLEANUP_HOOK:
690 register_cleanup = p->tv_u.tv_register_cleanup;
691 break;
692 case LDPT_ADD_INPUT_FILE:
693 add_input_file = p->tv_u.tv_add_input_file;
694 break;
695 case LDPT_ADD_INPUT_LIBRARY:
696 add_input_library = p->tv_u.tv_add_input_library;
697 break;
698 case LDPT_OPTION:
699 process_option (p->tv_u.tv_string);
700 break;
701 default:
702 break;
704 p++;
707 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
708 check (add_symbols, LDPL_FATAL, "add_symbols not found");
709 status = register_claim_file (claim_file_handler);
710 check (status == LDPS_OK, LDPL_FATAL,
711 "could not register the claim_file callback");
713 if (register_cleanup)
715 status = register_cleanup (cleanup_handler);
716 check (status == LDPS_OK, LDPL_FATAL,
717 "could not register the cleanup callback");
720 if (register_all_symbols_read)
722 check (get_symbols, LDPL_FATAL, "get_symbols not found");
723 status = register_all_symbols_read (all_symbols_read_handler);
724 check (status == LDPS_OK, LDPL_FATAL,
725 "could not register the all_symbols_read callback");
728 return LDPS_OK;