OSDN Git Service

gcc:
[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 sym_aux
59 {
60   uint32_t slot;
61   unsigned id;
62 };
63
64 struct plugin_symtab
65 {
66   int nsyms;
67   struct sym_aux *aux;
68   struct ld_plugin_symbol *syms;
69   unsigned id;
70 };
71
72 /* All that we have to remember about a file. */
73
74 struct plugin_file_info
75 {
76   char *name;
77   void *handle;
78   struct plugin_symtab symtab;
79 };
80
81
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;
91
92 static struct plugin_file_info *claimed_files = NULL;
93 static unsigned int num_claimed_files = 0;
94
95 static char **output_files = NULL;
96 static unsigned int num_output_files = 0;
97
98 static char **lto_wrapper_argv;
99 static int lto_wrapper_num_args;
100
101 static char **pass_through_items = NULL;
102 static unsigned int num_pass_through_items;
103
104 static bool debug;
105 static bool nop;
106 static char *resolution_file = NULL;
107
108 static void
109 check (bool gate, enum ld_plugin_level level, const char *text)
110 {
111   if (gate)
112     return;
113
114   if (message)
115     message (level, text);
116   else
117     {
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 ();
122     }
123 }
124
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. */
128
129 static char *
130 parse_table_entry (char *p, struct ld_plugin_symbol *entry, 
131                    struct sym_aux *aux)
132 {
133   unsigned char t;
134   enum ld_plugin_symbol_kind translate_kind[] =
135     {
136       LDPK_DEF,
137       LDPK_WEAKDEF,
138       LDPK_UNDEF,
139       LDPK_WEAKUNDEF,
140       LDPK_COMMON
141     };
142
143   enum ld_plugin_symbol_visibility translate_visibility[] =
144     {
145       LDPV_DEFAULT,
146       LDPV_PROTECTED,
147       LDPV_INTERNAL,
148       LDPV_HIDDEN
149     };
150
151   entry->name = xstrdup (p);
152   while (*p)
153     p++;
154   p++;
155
156   entry->version = NULL;
157
158   entry->comdat_key = p;
159   while (*p)
160     p++;
161   p++;
162
163   if (strlen (entry->comdat_key) == 0)
164     entry->comdat_key = NULL;
165   else
166     entry->comdat_key = xstrdup (entry->comdat_key);
167
168   t = *p;
169   check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
170   entry->def = translate_kind[t];
171   p++;
172
173   t = *p;
174   check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
175   entry->visibility = translate_visibility[t];
176   p++;
177
178   entry->size = *(uint64_t *) p;
179   p += 8;
180
181   aux->slot = *(uint32_t *) p;
182   p += 4;
183
184   entry->resolution = LDPR_UNKNOWN;
185
186   return p;
187 }
188
189 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
190
191 /* Translate the IL symbol table SYMTAB. Append the slots and symbols to OUT. */
192
193 static void
194 translate (Elf_Data *symtab, struct plugin_symtab *out)
195 {
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;
201
202   /* This overestimates the output buffer sizes, but at least 
203      the algorithm is O(1) now. */
204
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));
208   
209   for (n = out->nsyms; data < end; n++) 
210     { 
211       aux[n].id = out->id; 
212       data = parse_table_entry (data, &syms[n], &aux[n]);
213     }
214
215   fprintf (stderr, "n = %d len = %d end-data=%lu\n", n, len, end-data);
216   assert(n < len);
217
218   out->nsyms = n;
219   out->syms = syms;
220   out->aux = aux;
221 }
222
223 /* Process all lto symtabs of file ELF. */
224
225 static int
226 process_symtab (Elf *elf, struct plugin_symtab *out)
227 {
228   int found = 0;
229   Elf_Scn *section = 0;
230   GElf_Ehdr header;
231   GElf_Ehdr *t = gelf_getehdr (elf, &header);
232   if (t == NULL)
233     return 0;
234   assert (t == &header);
235
236   while ((section = elf_nextscn(elf, section)) != 0)
237     {
238       GElf_Shdr shdr;
239       GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
240       const char *t;
241       assert (tshdr == &shdr);
242       t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
243       assert (t != NULL);
244       if (strncmp (t, LTO_SECTION_PREFIX, strlen (LTO_SECTION_PREFIX)) == 0) 
245         {
246           char *s = strrchr (t, '.');
247           if (s)
248               sscanf (s, ".%x", &out->id);
249           translate (elf_getdata (section, NULL), out);
250           found = 1;
251         }
252     }
253   return found;
254 }
255
256 /* Free all memory that is no longer needed after writing the symbol
257    resolution. */
258
259 static void
260 free_1 (void)
261 {
262   unsigned int i;
263   for (i = 0; i < num_claimed_files; i++)
264     {
265       struct plugin_file_info *info = &claimed_files[i];
266       struct plugin_symtab *symtab = &info->symtab;
267       unsigned int j;
268       for (j = 0; j < symtab->nsyms; j++)
269         {
270           struct ld_plugin_symbol *s = &symtab->syms[j];
271           free (s->name);
272           if (s->comdat_key)
273             free (s->comdat_key);
274         }
275       free (symtab->syms);
276       symtab->syms = NULL;
277     }
278 }
279
280 /* Free all remaining memory. */
281
282 static void
283 free_2 (void)
284 {
285   unsigned int i;
286   for (i = 0; i < num_claimed_files; i++)
287     {
288       struct plugin_file_info *info = &claimed_files[i];
289       struct plugin_symtab *symtab = &info->symtab;
290       free (symtab->aux);
291       free (info->name);
292     }
293
294   for (i = 0; i < num_output_files; i++)
295     free (output_files[i]);
296   free (output_files);
297
298   free (claimed_files);
299   claimed_files = NULL;
300   num_claimed_files = 0;
301
302   if (arguments_file_name)
303     free (arguments_file_name);
304   arguments_file_name = NULL;
305 }
306
307 /*  Writes the relocations to disk. */
308
309 static void
310 write_resolution (void)
311 {
312   unsigned int i;
313   FILE *f;
314
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");
318
319   fprintf (f, "%d\n", num_claimed_files);
320
321   for (i = 0; i < num_claimed_files; i++)
322     {
323       struct plugin_file_info *info = &claimed_files[i];
324       struct plugin_symtab *symtab = &info->symtab;
325       struct ld_plugin_symbol *syms = symtab->syms;
326       unsigned j;
327
328       get_symbols (info->handle, symtab->nsyms, syms);
329
330       fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
331
332       for (j = 0; j < info->symtab.nsyms; j++)
333         {
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);
338         }
339     }
340   fclose (f);
341 }
342
343 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
344    stdout. */
345
346 static void
347 add_output_files (FILE *f)
348 {
349   for (;;)
350     {
351       const unsigned piece = 32;
352       char *buf, *s = xmalloc (piece);
353       size_t len;
354
355       buf = s;
356 cont:
357       if (!fgets (buf, piece, f))
358         break;
359       len = strlen (s);
360       if (s[len - 1] != '\n')
361         {
362           s = xrealloc (s, len + piece);
363           buf = s + len;
364           goto cont;
365         }
366       s[len - 1] = '\0';
367
368       num_output_files++;
369       output_files
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]);
373     }
374 }
375
376 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
377    argument list. */
378
379 static void
380 exec_lto_wrapper (char *argv[])
381 {
382   int t, i;
383   int status;
384   char *at_args;
385   FILE *args;
386   FILE *wrapper_output;
387   char *new_argv[3];
388   struct pex_obj *pex;
389   const char *errmsg;
390
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");
395
396   args = fopen (arguments_file_name, "w");
397   check (args, LDPL_FATAL, "could not open arguments file");
398
399   t = writeargv (&argv[1], args);
400   check (t == 0, LDPL_FATAL, "could not write arguments");
401   t = fclose (args);
402   check (t == 0, LDPL_FATAL, "could not close arguments file");
403
404   at_args = concat ("@", arguments_file_name, NULL);
405   check (at_args, LDPL_FATAL, "could not allocate");
406
407   for (i = 1; argv[i]; i++)
408     {
409       char *a = argv[i];
410       if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
411         {
412           for (i = 0; argv[i]; i++)
413             fprintf (stderr, "%s ", argv[i]);
414           fprintf (stderr, "\n");
415           break;
416         }
417     }
418
419   new_argv[0] = argv[0];
420   new_argv[1] = at_args;
421   new_argv[2] = NULL;
422
423   if (debug)
424     {
425       for (i = 0; new_argv[i]; i++)
426         fprintf (stderr, "%s ", new_argv[i]);
427       fprintf (stderr, "\n");
428     }
429
430
431   pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
432   check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
433
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");
437
438   wrapper_output = pex_read_output (pex, 0);
439   check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
440
441   add_output_files (wrapper_output);
442
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");
447
448   pex_free (pex);
449
450   free (at_args);
451 }
452
453 /* Pass the original files back to the linker. */
454
455 static void
456 use_original_files (void)
457 {
458   unsigned i;
459   for (i = 0; i < num_claimed_files; i++)
460     {
461       struct plugin_file_info *info = &claimed_files[i];
462       add_input_file (info->name);
463     }
464 }
465
466
467 /* Called by the linker once all symbols have been read. */
468
469 static enum ld_plugin_status
470 all_symbols_read_handler (void)
471 {
472   unsigned i;
473   unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
474   char **lto_argv;
475   const char **lto_arg_ptr;
476   if (num_claimed_files == 0)
477     return LDPS_OK;
478
479   if (nop)
480     {
481       use_original_files ();
482       return LDPS_OK;
483     }
484
485   lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
486   lto_arg_ptr = (const char **) lto_argv;
487   assert (lto_wrapper_argv);
488
489   write_resolution ();
490
491   free_1 ();
492
493   for (i = 0; i < lto_wrapper_num_args; i++)
494     *lto_arg_ptr++ = lto_wrapper_argv[i];
495
496   for (i = 0; i < num_claimed_files; i++)
497     {
498       struct plugin_file_info *info = &claimed_files[i];
499
500       *lto_arg_ptr++ = info->name;
501     }
502
503   *lto_arg_ptr++ = NULL;
504   exec_lto_wrapper (lto_argv);
505
506   free (lto_argv);
507
508   if (pass_through_items)
509     {
510       unsigned int i;
511       for (i = 0; i < num_pass_through_items; i++)
512         {
513           if (strncmp (pass_through_items[i], "-l", 2) == 0)
514             add_input_library (pass_through_items[i] + 2);
515           else
516             add_input_file (pass_through_items[i]);
517           free (pass_through_items[i]);
518           pass_through_items[i] = NULL;
519         }
520       free (pass_through_items);
521       pass_through_items = NULL;
522     }
523
524   return LDPS_OK;
525 }
526
527 /* Remove temporary files at the end of the link. */
528
529 static enum ld_plugin_status
530 cleanup_handler (void)
531 {
532   unsigned int i;
533   int t;
534
535   if (debug)
536     return LDPS_OK;
537
538   if (arguments_file_name)
539     {
540       t = unlink (arguments_file_name);
541       check (t == 0, LDPL_FATAL, "could not unlink arguments file");
542     }
543
544   for (i = 0; i < num_output_files; i++)
545     {
546       t = unlink (output_files[i]);
547       check (t == 0, LDPL_FATAL, "could not unlink output file");
548     }
549
550   free_2 ();
551   return LDPS_OK;
552 }
553
554 /* Callback used by gold to check if the plugin will claim FILE. Writes
555    the result in CLAIMED. */
556
557 static enum ld_plugin_status
558 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
559 {
560   enum ld_plugin_status status;
561   Elf *elf;
562   struct plugin_file_info lto_file;
563
564   memset (&lto_file, 0, sizeof (struct plugin_file_info));
565
566   if (file->offset != 0)
567     {
568       char *objname;
569       Elf *archive;
570       off_t offset;
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;
576
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");
580
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 */
584
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");
590       elf_end (archive);
591     }
592   else
593     {
594       lto_file.name = xstrdup (file->name);
595       elf = elf_begin (file->fd, ELF_C_READ, NULL);
596     }
597   lto_file.handle = file->handle;
598
599   *claimed = 0;
600
601   if (!elf || !process_symtab (elf, &lto_file.symtab))
602     goto err;
603
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");
607
608   *claimed = 1;
609   num_claimed_files++;
610   claimed_files =
611     xrealloc (claimed_files,
612               num_claimed_files * sizeof (struct plugin_file_info));
613   claimed_files[num_claimed_files - 1] = lto_file;
614
615   goto cleanup;
616
617  err:
618   free (lto_file.name);
619
620  cleanup:
621   if (elf)
622     elf_end (elf);
623
624   return LDPS_OK;
625 }
626
627 /* Parse the plugin options. */
628
629 static void
630 process_option (const char *option)
631 {
632   if (strcmp (option, "-debug") == 0)
633     debug = 1;
634   else if (strcmp (option, "-nop") == 0)
635     nop = 1;
636   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
637     {
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="));
643     }
644   else
645     {
646       int size;
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;
654     }
655 }
656
657 /* Called by gold after loading the plugin. TV is the transfer vector. */
658
659 enum ld_plugin_status
660 onload (struct ld_plugin_tv *tv)
661 {
662   struct ld_plugin_tv *p;
663   enum ld_plugin_status status;
664
665   unsigned version = elf_version (EV_CURRENT);
666   check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
667
668   p = tv;
669   while (p->tv_tag)
670     {
671       switch (p->tv_tag)
672         {
673         case LDPT_MESSAGE:
674           message = p->tv_u.tv_message;
675           break;
676         case LDPT_REGISTER_CLAIM_FILE_HOOK:
677           register_claim_file = p->tv_u.tv_register_claim_file;
678           break;
679         case LDPT_ADD_SYMBOLS:
680           add_symbols = p->tv_u.tv_add_symbols;
681           break;
682         case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
683           register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
684           break;
685         case LDPT_GET_SYMBOLS:
686           get_symbols = p->tv_u.tv_get_symbols;
687           break;
688         case LDPT_REGISTER_CLEANUP_HOOK:
689           register_cleanup = p->tv_u.tv_register_cleanup;
690           break;
691         case LDPT_ADD_INPUT_FILE:
692           add_input_file = p->tv_u.tv_add_input_file;
693           break;
694         case LDPT_ADD_INPUT_LIBRARY:
695           add_input_library = p->tv_u.tv_add_input_library;
696           break;
697         case LDPT_OPTION:
698           process_option (p->tv_u.tv_string);
699           break;
700         default:
701           break;
702         }
703       p++;
704     }
705
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");
711
712   if (register_cleanup)
713     {
714       status = register_cleanup (cleanup_handler);
715       check (status == LDPS_OK, LDPL_FATAL,
716              "could not register the cleanup callback");
717     }
718
719   if (register_all_symbols_read)
720     {
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");
725     }
726
727   return LDPS_OK;
728 }