OSDN Git Service

2010-04-23 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / lto-plugin / lto-plugin.c
1 /* LTO plugin for gold.
2    Copyright (C) 2009 Free Software Foundation, Inc.
3    Contributed by Rafael Avila de Espindola (espindola@google.com).
4
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.
9
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.
14
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/>.  */
18
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.
21
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.
26
27    More information at http://gcc.gnu.org/wiki/whopr/driver.
28
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.  */
34
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
48 /* The presence of gelf.h is checked by the toplevel configure script.  */
49 #include <gelf.h>
50
51 #include "plugin-api.h"
52 #include "../gcc/lto/common.h"
53
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. */
57
58 struct plugin_symtab
59 {
60   int nsyms;
61   uint32_t *slots;
62   struct ld_plugin_symbol *syms;
63 };
64
65 /* All that we have to remember about a file. */
66
67 struct plugin_file_info
68 {
69   char *name;
70   void *handle;
71   struct plugin_symtab symtab;
72 };
73
74
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;
84
85 static struct plugin_file_info *claimed_files = NULL;
86 static unsigned int num_claimed_files = 0;
87
88 static char **output_files = NULL;
89 static unsigned int num_output_files = 0;
90
91 static char **lto_wrapper_argv;
92 static int lto_wrapper_num_args;
93
94 static char **pass_through_items = NULL;
95 static unsigned int num_pass_through_items;
96
97 static bool debug;
98 static bool nop;
99 static char *resolution_file = NULL;
100
101 static void
102 check (bool gate, enum ld_plugin_level level, const char *text)
103 {
104   if (gate)
105     return;
106
107   if (message)
108     message (level, text);
109   else
110     {
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 ();
115     }
116 }
117
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. */
121
122 static char *
123 parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
124 {
125   unsigned char t;
126   enum ld_plugin_symbol_kind translate_kind[] =
127     {
128       LDPK_DEF,
129       LDPK_WEAKDEF,
130       LDPK_UNDEF,
131       LDPK_WEAKUNDEF,
132       LDPK_COMMON
133     };
134
135   enum ld_plugin_symbol_visibility translate_visibility[] =
136     {
137       LDPV_DEFAULT,
138       LDPV_PROTECTED,
139       LDPV_INTERNAL,
140       LDPV_HIDDEN
141     };
142
143   entry->name = xstrdup (p);
144   while (*p)
145     p++;
146   p++;
147
148   entry->version = NULL;
149
150   entry->comdat_key = p;
151   while (*p)
152     p++;
153   p++;
154
155   if (strlen (entry->comdat_key) == 0)
156     entry->comdat_key = NULL;
157   else
158     entry->comdat_key = xstrdup (entry->comdat_key);
159
160   t = *p;
161   check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
162   entry->def = translate_kind[t];
163   p++;
164
165   t = *p;
166   check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
167   entry->visibility = translate_visibility[t];
168   p++;
169
170   entry->size = *(uint64_t *) p;
171   p += 8;
172
173   *slot = *(uint32_t *) p;
174   p += 4;
175
176   entry->resolution = LDPR_UNKNOWN;
177
178   return p;
179 }
180
181 /* Return the section in ELF that is named NAME. */
182
183 static Elf_Scn *
184 get_section (Elf *elf, const char *name)
185 {
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);
192
193   while ((section = elf_nextscn(elf, section)) != 0)
194     {
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;
203     }
204   return NULL;
205 }
206
207 /* Returns the IL symbol table of file ELF. */
208
209 static Elf_Data *
210 get_symtab (Elf *elf)
211 {
212   Elf_Data *data = 0;
213   Elf_Scn *section = get_section (elf, ".gnu.lto_.symtab");
214   if (!section)
215     return NULL;
216
217   data = elf_getdata (section, data);
218   assert (data);
219   return data;
220 }
221
222 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
223
224 static void
225 translate (Elf_Data *symtab, struct plugin_symtab *out)
226 {
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;
232
233   while (data < end)
234     {
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]);
241     }
242
243   out->nsyms = n;
244   out->syms = syms;
245   out->slots = slots;
246 }
247
248 /* Free all memory that is no longer needed after writing the symbol
249    resolution. */
250
251 static void
252 free_1 (void)
253 {
254   unsigned int i;
255   for (i = 0; i < num_claimed_files; i++)
256     {
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++)
261         {
262           struct ld_plugin_symbol *s = &symtab->syms[j];
263           free (s->name);
264           if (s->comdat_key)
265             free (s->comdat_key);
266         }
267       free (symtab->syms);
268       symtab->syms = NULL;
269     }
270 }
271
272 /* Free all remaining memory. */
273
274 static void
275 free_2 (void)
276 {
277   unsigned int i;
278   for (i = 0; i < num_claimed_files; i++)
279     {
280       struct plugin_file_info *info = &claimed_files[i];
281       struct plugin_symtab *symtab = &info->symtab;
282       free (symtab->slots);
283       free (info->name);
284     }
285
286   for (i = 0; i < num_output_files; i++)
287     free (output_files[i]);
288   free (output_files);
289
290   free (claimed_files);
291   claimed_files = NULL;
292   num_claimed_files = 0;
293
294   if (arguments_file_name)
295     free (arguments_file_name);
296   arguments_file_name = NULL;
297
298   if (resolution_file)
299     {
300       free (resolution_file);
301       resolution_file = NULL;
302     }
303 }
304
305 /*  Writes the relocations to disk. */
306
307 static void
308 write_resolution (void)
309 {
310   unsigned int i;
311   FILE *f;
312
313   f = fopen (resolution_file, "w");
314   check (f, LDPL_FATAL, "could not open file");
315
316   fprintf (f, "%d\n", num_claimed_files);
317
318   for (i = 0; i < num_claimed_files; i++)
319     {
320       struct plugin_file_info *info = &claimed_files[i];
321       struct plugin_symtab *symtab = &info->symtab;
322       struct ld_plugin_symbol *syms = symtab->syms;
323       unsigned j;
324
325       assert (syms);
326       get_symbols (info->handle, symtab->nsyms, syms);
327
328       fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
329
330       for (j = 0; j < info->symtab.nsyms; j++)
331         {
332           uint32_t slot = symtab->slots[j];
333           unsigned int resolution = syms[j].resolution;
334           fprintf (f, "%d %s %s\n", slot, lto_resolution_str[resolution], syms[j].name);
335         }
336     }
337   fclose (f);
338 }
339
340 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
341    stdout. */
342
343 static void
344 add_output_files (FILE *f)
345 {
346   for (;;)
347     {
348       const unsigned piece = 32;
349       char *buf, *s = xmalloc (piece);
350       size_t len;
351
352       buf = s;
353 cont:
354       if (!fgets (buf, piece, f))
355         break;
356       len = strlen (s);
357       if (s[len - 1] != '\n')
358         {
359           s = xrealloc (s, len + piece);
360           buf = s + len;
361           goto cont;
362         }
363       s[len - 1] = '\0';
364
365       num_output_files++;
366       output_files
367         = xrealloc (output_files, num_output_files * sizeof (char *));
368       output_files[num_output_files - 1] = s;
369       add_input_file (output_files[num_output_files - 1]);
370     }
371 }
372
373 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
374    argument list. */
375
376 static void
377 exec_lto_wrapper (char *argv[])
378 {
379   int t, i;
380   int status;
381   char *at_args;
382   FILE *args;
383   FILE *wrapper_output;
384   char *new_argv[3];
385   struct pex_obj *pex;
386   const char *errmsg;
387
388   /* Write argv to a file to avoid a command line that is too long. */
389   arguments_file_name = make_temp_file ("");
390   check (arguments_file_name, LDPL_FATAL,
391          "Failed to generate a temorary file name");
392
393   args = fopen (arguments_file_name, "w");
394   check (args, LDPL_FATAL, "could not open arguments file");
395
396   t = writeargv (&argv[1], args);
397   check (t == 0, LDPL_FATAL, "could not write arguments");
398   t = fclose (args);
399   check (t == 0, LDPL_FATAL, "could not close arguments file");
400
401   at_args = concat ("@", arguments_file_name, NULL);
402   check (at_args, LDPL_FATAL, "could not allocate");
403
404   for (i = 1; argv[i]; i++)
405     {
406       char *a = argv[i];
407       if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
408         {
409           for (i = 0; argv[i]; i++)
410             fprintf (stderr, "%s ", argv[i]);
411           fprintf (stderr, "\n");
412           break;
413         }
414     }
415
416   new_argv[0] = argv[0];
417   new_argv[1] = at_args;
418   new_argv[2] = NULL;
419
420   if (debug)
421     {
422       for (i = 0; new_argv[i]; i++)
423         fprintf (stderr, "%s ", new_argv[i]);
424       fprintf (stderr, "\n");
425     }
426
427
428   pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
429   check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
430
431   errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
432   check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
433   check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
434
435   wrapper_output = pex_read_output (pex, 0);
436   check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
437
438   add_output_files (wrapper_output);
439
440   t = pex_get_status (pex, 1, &status);
441   check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
442   check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
443          "lto-wrapper failed");
444
445   pex_free (pex);
446
447   free (at_args);
448 }
449
450 /* Pass the original files back to the linker. */
451
452 static void
453 use_original_files (void)
454 {
455   unsigned i;
456   for (i = 0; i < num_claimed_files; i++)
457     {
458       struct plugin_file_info *info = &claimed_files[i];
459       add_input_file (info->name);
460     }
461 }
462
463
464 /* Called by the linker once all symbols have been read. */
465
466 static enum ld_plugin_status
467 all_symbols_read_handler (void)
468 {
469   unsigned i;
470   unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 2 + 1;
471   char **lto_argv;
472   const char **lto_arg_ptr;
473   if (num_claimed_files == 0)
474     return LDPS_OK;
475
476   if (nop)
477     {
478       use_original_files ();
479       return LDPS_OK;
480     }
481
482   lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
483   lto_arg_ptr = (const char **) lto_argv;
484   assert (lto_wrapper_argv);
485
486   resolution_file = make_temp_file ("");
487
488   write_resolution ();
489
490   free_1 ();
491
492   for (i = 0; i < lto_wrapper_num_args; i++)
493     *lto_arg_ptr++ = lto_wrapper_argv[i];
494
495   *lto_arg_ptr++ = "-fresolution";
496   *lto_arg_ptr++ = resolution_file;
497
498   for (i = 0; i < num_claimed_files; i++)
499     {
500       struct plugin_file_info *info = &claimed_files[i];
501
502       *lto_arg_ptr++ = info->name;
503     }
504
505   *lto_arg_ptr++ = NULL;
506   exec_lto_wrapper (lto_argv);
507
508   free (lto_argv);
509
510   if (pass_through_items)
511     {
512       unsigned int i;
513       for (i = 0; i < num_pass_through_items; i++)
514         {
515           if (strncmp (pass_through_items[i], "-l", 2) == 0)
516             add_input_library (pass_through_items[i] + 2);
517           else
518             add_input_file (pass_through_items[i]);
519           free (pass_through_items[i]);
520           pass_through_items[i] = NULL;
521         }
522       free (pass_through_items);
523       pass_through_items = NULL;
524     }
525
526   return LDPS_OK;
527 }
528
529 /* Remove temporary files at the end of the link. */
530
531 static enum ld_plugin_status
532 cleanup_handler (void)
533 {
534   unsigned int i;
535   int t;
536
537   if (debug)
538     return LDPS_OK;
539
540   if (arguments_file_name)
541     {
542       t = unlink (arguments_file_name);
543       check (t == 0, LDPL_FATAL, "could not unlink arguments file");
544     }
545
546   if (resolution_file)
547     {
548       t = unlink (resolution_file);
549       check (t == 0, LDPL_FATAL, "could not unlink resolution file");
550     }
551
552   for (i = 0; i < num_output_files; i++)
553     {
554       t = unlink (output_files[i]);
555       check (t == 0, LDPL_FATAL, "could not unlink output file");
556     }
557
558   free_2 ();
559   return LDPS_OK;
560 }
561
562 /* Callback used by gold to check if the plugin will claim FILE. Writes
563    the result in CLAIMED. */
564
565 static enum ld_plugin_status
566 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
567 {
568   enum ld_plugin_status status;
569   Elf *elf;
570   struct plugin_file_info lto_file;
571   Elf_Data *symtab;
572
573   if (file->offset != 0)
574     {
575       char *objname;
576       Elf *archive;
577       off_t offset;
578       /* We pass the offset of the actual file, not the archive header. */
579       int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
580                         (int64_t) file->offset);
581       check (t >= 0, LDPL_FATAL, "asprintf failed");
582       lto_file.name = objname;
583
584       archive = elf_begin (file->fd, ELF_C_READ, NULL);
585       check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
586              "Not an archive and offset not 0");
587
588       /* elf_rand expects the offset to point to the ar header, not the
589          object itself. Subtract the size of the ar header (60 bytes).
590          We don't uses sizeof (struct ar_hd) to avoid including ar.h */
591
592       offset = file->offset - 60;
593       check (offset == elf_rand (archive, offset), LDPL_FATAL,
594              "could not seek in archive");
595       elf = elf_begin (file->fd, ELF_C_READ, archive);
596       check (elf != NULL, LDPL_FATAL, "could not find archive member");
597       elf_end (archive);
598     }
599   else
600     {
601       lto_file.name = xstrdup (file->name);
602       elf = elf_begin (file->fd, ELF_C_READ, NULL);
603     }
604   lto_file.handle = file->handle;
605
606   *claimed = 0;
607
608   if (!elf)
609     goto err;
610
611   symtab = get_symtab (elf);
612   if (!symtab)
613     goto err;
614
615   translate (symtab, &lto_file.symtab);
616
617   status = add_symbols (file->handle, lto_file.symtab.nsyms,
618                         lto_file.symtab.syms);
619   check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
620
621   *claimed = 1;
622   num_claimed_files++;
623   claimed_files =
624     xrealloc (claimed_files,
625               num_claimed_files * sizeof (struct plugin_file_info));
626   claimed_files[num_claimed_files - 1] = lto_file;
627
628   goto cleanup;
629
630  err:
631   free (lto_file.name);
632
633  cleanup:
634   if (elf)
635     elf_end (elf);
636
637   return LDPS_OK;
638 }
639
640 /* Parse the plugin options. */
641
642 static void
643 process_option (const char *option)
644 {
645   if (strcmp (option, "-debug") == 0)
646     debug = 1;
647   else if (strcmp (option, "-nop") == 0)
648     nop = 1;
649   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
650     {
651       num_pass_through_items++;
652       pass_through_items = xrealloc (pass_through_items,
653                                      num_pass_through_items * sizeof (char *));
654       pass_through_items[num_pass_through_items - 1] =
655           xstrdup (option + strlen ("-pass-through="));
656     }
657   else
658     {
659       int size;
660       lto_wrapper_num_args += 1;
661       size = lto_wrapper_num_args * sizeof (char *);
662       lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
663       lto_wrapper_argv[lto_wrapper_num_args - 1] = xstrdup(option);
664     }
665 }
666
667 /* Called by gold after loading the plugin. TV is the transfer vector. */
668
669 enum ld_plugin_status
670 onload (struct ld_plugin_tv *tv)
671 {
672   struct ld_plugin_tv *p;
673   enum ld_plugin_status status;
674
675   unsigned version = elf_version (EV_CURRENT);
676   check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
677
678   p = tv;
679   while (p->tv_tag)
680     {
681       switch (p->tv_tag)
682         {
683         case LDPT_MESSAGE:
684           message = p->tv_u.tv_message;
685           break;
686         case LDPT_REGISTER_CLAIM_FILE_HOOK:
687           register_claim_file = p->tv_u.tv_register_claim_file;
688           break;
689         case LDPT_ADD_SYMBOLS:
690           add_symbols = p->tv_u.tv_add_symbols;
691           break;
692         case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
693           register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
694           break;
695         case LDPT_GET_SYMBOLS:
696           get_symbols = p->tv_u.tv_get_symbols;
697           break;
698         case LDPT_REGISTER_CLEANUP_HOOK:
699           register_cleanup = p->tv_u.tv_register_cleanup;
700           break;
701         case LDPT_ADD_INPUT_FILE:
702           add_input_file = p->tv_u.tv_add_input_file;
703           break;
704         case LDPT_ADD_INPUT_LIBRARY:
705           add_input_library = p->tv_u.tv_add_input_library;
706           break;
707         case LDPT_OPTION:
708           process_option (p->tv_u.tv_string);
709           break;
710         default:
711           break;
712         }
713       p++;
714     }
715
716   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
717   check (add_symbols, LDPL_FATAL, "add_symbols not found");
718   status = register_claim_file (claim_file_handler);
719   check (status == LDPS_OK, LDPL_FATAL,
720          "could not register the claim_file callback");
721
722   if (register_cleanup)
723     {
724       status = register_cleanup (cleanup_handler);
725       check (status == LDPS_OK, LDPL_FATAL,
726              "could not register the cleanup callback");
727     }
728
729   if (register_all_symbols_read)
730     {
731       check (get_symbols, LDPL_FATAL, "get_symbols not found");
732       status = register_all_symbols_read (all_symbols_read_handler);
733       check (status == LDPS_OK, LDPL_FATAL,
734              "could not register the all_symbols_read callback");
735     }
736
737   return LDPS_OK;
738 }