OSDN Git Service

cb785c428a8a491a20323df48d9f742eef54f01f
[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
299 /*  Writes the relocations to disk. */
300
301 static void
302 write_resolution (void)
303 {
304   unsigned int i;
305   FILE *f;
306
307   check (resolution_file, LDPL_FATAL, "resolution file not specified");
308   f = fopen (resolution_file, "w");
309   check (f, LDPL_FATAL, "could not open file");
310
311   fprintf (f, "%d\n", num_claimed_files);
312
313   for (i = 0; i < num_claimed_files; i++)
314     {
315       struct plugin_file_info *info = &claimed_files[i];
316       struct plugin_symtab *symtab = &info->symtab;
317       struct ld_plugin_symbol *syms = symtab->syms;
318       unsigned j;
319
320       assert (syms);
321       get_symbols (info->handle, symtab->nsyms, syms);
322
323       fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
324
325       for (j = 0; j < info->symtab.nsyms; j++)
326         {
327           uint32_t slot = symtab->slots[j];
328           unsigned int resolution = syms[j].resolution;
329           fprintf (f, "%d %s %s\n", slot, lto_resolution_str[resolution], syms[j].name);
330         }
331     }
332   fclose (f);
333 }
334
335 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
336    stdout. */
337
338 static void
339 add_output_files (FILE *f)
340 {
341   for (;;)
342     {
343       const unsigned piece = 32;
344       char *buf, *s = xmalloc (piece);
345       size_t len;
346
347       buf = s;
348 cont:
349       if (!fgets (buf, piece, f))
350         break;
351       len = strlen (s);
352       if (s[len - 1] != '\n')
353         {
354           s = xrealloc (s, len + piece);
355           buf = s + len;
356           goto cont;
357         }
358       s[len - 1] = '\0';
359
360       num_output_files++;
361       output_files
362         = xrealloc (output_files, num_output_files * sizeof (char *));
363       output_files[num_output_files - 1] = s;
364       add_input_file (output_files[num_output_files - 1]);
365     }
366 }
367
368 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
369    argument list. */
370
371 static void
372 exec_lto_wrapper (char *argv[])
373 {
374   int t, i;
375   int status;
376   char *at_args;
377   FILE *args;
378   FILE *wrapper_output;
379   char *new_argv[3];
380   struct pex_obj *pex;
381   const char *errmsg;
382
383   /* Write argv to a file to avoid a command line that is too long. */
384   arguments_file_name = make_temp_file ("");
385   check (arguments_file_name, LDPL_FATAL,
386          "Failed to generate a temorary file name");
387
388   args = fopen (arguments_file_name, "w");
389   check (args, LDPL_FATAL, "could not open arguments file");
390
391   t = writeargv (&argv[1], args);
392   check (t == 0, LDPL_FATAL, "could not write arguments");
393   t = fclose (args);
394   check (t == 0, LDPL_FATAL, "could not close arguments file");
395
396   at_args = concat ("@", arguments_file_name, NULL);
397   check (at_args, LDPL_FATAL, "could not allocate");
398
399   for (i = 1; argv[i]; i++)
400     {
401       char *a = argv[i];
402       if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
403         {
404           for (i = 0; argv[i]; i++)
405             fprintf (stderr, "%s ", argv[i]);
406           fprintf (stderr, "\n");
407           break;
408         }
409     }
410
411   new_argv[0] = argv[0];
412   new_argv[1] = at_args;
413   new_argv[2] = NULL;
414
415   if (debug)
416     {
417       for (i = 0; new_argv[i]; i++)
418         fprintf (stderr, "%s ", new_argv[i]);
419       fprintf (stderr, "\n");
420     }
421
422
423   pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
424   check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
425
426   errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
427   check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
428   check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
429
430   wrapper_output = pex_read_output (pex, 0);
431   check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
432
433   add_output_files (wrapper_output);
434
435   t = pex_get_status (pex, 1, &status);
436   check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
437   check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
438          "lto-wrapper failed");
439
440   pex_free (pex);
441
442   free (at_args);
443 }
444
445 /* Pass the original files back to the linker. */
446
447 static void
448 use_original_files (void)
449 {
450   unsigned i;
451   for (i = 0; i < num_claimed_files; i++)
452     {
453       struct plugin_file_info *info = &claimed_files[i];
454       add_input_file (info->name);
455     }
456 }
457
458
459 /* Called by the linker once all symbols have been read. */
460
461 static enum ld_plugin_status
462 all_symbols_read_handler (void)
463 {
464   unsigned i;
465   unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
466   char **lto_argv;
467   const char **lto_arg_ptr;
468   if (num_claimed_files == 0)
469     return LDPS_OK;
470
471   if (nop)
472     {
473       use_original_files ();
474       return LDPS_OK;
475     }
476
477   lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
478   lto_arg_ptr = (const char **) lto_argv;
479   assert (lto_wrapper_argv);
480
481   write_resolution ();
482
483   free_1 ();
484
485   for (i = 0; i < lto_wrapper_num_args; i++)
486     *lto_arg_ptr++ = lto_wrapper_argv[i];
487
488   for (i = 0; i < num_claimed_files; i++)
489     {
490       struct plugin_file_info *info = &claimed_files[i];
491
492       *lto_arg_ptr++ = info->name;
493     }
494
495   *lto_arg_ptr++ = NULL;
496   exec_lto_wrapper (lto_argv);
497
498   free (lto_argv);
499
500   if (pass_through_items)
501     {
502       unsigned int i;
503       for (i = 0; i < num_pass_through_items; i++)
504         {
505           if (strncmp (pass_through_items[i], "-l", 2) == 0)
506             add_input_library (pass_through_items[i] + 2);
507           else
508             add_input_file (pass_through_items[i]);
509           free (pass_through_items[i]);
510           pass_through_items[i] = NULL;
511         }
512       free (pass_through_items);
513       pass_through_items = NULL;
514     }
515
516   return LDPS_OK;
517 }
518
519 /* Remove temporary files at the end of the link. */
520
521 static enum ld_plugin_status
522 cleanup_handler (void)
523 {
524   unsigned int i;
525   int t;
526
527   if (debug)
528     return LDPS_OK;
529
530   if (arguments_file_name)
531     {
532       t = unlink (arguments_file_name);
533       check (t == 0, LDPL_FATAL, "could not unlink arguments file");
534     }
535
536   for (i = 0; i < num_output_files; i++)
537     {
538       t = unlink (output_files[i]);
539       check (t == 0, LDPL_FATAL, "could not unlink output file");
540     }
541
542   free_2 ();
543   return LDPS_OK;
544 }
545
546 /* Callback used by gold to check if the plugin will claim FILE. Writes
547    the result in CLAIMED. */
548
549 static enum ld_plugin_status
550 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
551 {
552   enum ld_plugin_status status;
553   Elf *elf;
554   struct plugin_file_info lto_file;
555   Elf_Data *symtab;
556
557   if (file->offset != 0)
558     {
559       char *objname;
560       Elf *archive;
561       off_t offset;
562       /* We pass the offset of the actual file, not the archive header. */
563       int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
564                         (int64_t) file->offset);
565       check (t >= 0, LDPL_FATAL, "asprintf failed");
566       lto_file.name = objname;
567
568       archive = elf_begin (file->fd, ELF_C_READ, NULL);
569       check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
570              "Not an archive and offset not 0");
571
572       /* elf_rand expects the offset to point to the ar header, not the
573          object itself. Subtract the size of the ar header (60 bytes).
574          We don't uses sizeof (struct ar_hd) to avoid including ar.h */
575
576       offset = file->offset - 60;
577       check (offset == elf_rand (archive, offset), LDPL_FATAL,
578              "could not seek in archive");
579       elf = elf_begin (file->fd, ELF_C_READ, archive);
580       check (elf != NULL, LDPL_FATAL, "could not find archive member");
581       elf_end (archive);
582     }
583   else
584     {
585       lto_file.name = xstrdup (file->name);
586       elf = elf_begin (file->fd, ELF_C_READ, NULL);
587     }
588   lto_file.handle = file->handle;
589
590   *claimed = 0;
591
592   if (!elf)
593     goto err;
594
595   symtab = get_symtab (elf);
596   if (!symtab)
597     goto err;
598
599   translate (symtab, &lto_file.symtab);
600
601   status = add_symbols (file->handle, lto_file.symtab.nsyms,
602                         lto_file.symtab.syms);
603   check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
604
605   *claimed = 1;
606   num_claimed_files++;
607   claimed_files =
608     xrealloc (claimed_files,
609               num_claimed_files * sizeof (struct plugin_file_info));
610   claimed_files[num_claimed_files - 1] = lto_file;
611
612   goto cleanup;
613
614  err:
615   free (lto_file.name);
616
617  cleanup:
618   if (elf)
619     elf_end (elf);
620
621   return LDPS_OK;
622 }
623
624 /* Parse the plugin options. */
625
626 static void
627 process_option (const char *option)
628 {
629   if (strcmp (option, "-debug") == 0)
630     debug = 1;
631   else if (strcmp (option, "-nop") == 0)
632     nop = 1;
633   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
634     {
635       num_pass_through_items++;
636       pass_through_items = xrealloc (pass_through_items,
637                                      num_pass_through_items * sizeof (char *));
638       pass_through_items[num_pass_through_items - 1] =
639           xstrdup (option + strlen ("-pass-through="));
640     }
641   else
642     {
643       int size;
644       char *opt = xstrdup (option);
645       lto_wrapper_num_args += 1;
646       size = lto_wrapper_num_args * sizeof (char *);
647       lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
648       lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
649       if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
650         resolution_file = opt + sizeof ("-fresolution=") - 1;
651     }
652 }
653
654 /* Called by gold after loading the plugin. TV is the transfer vector. */
655
656 enum ld_plugin_status
657 onload (struct ld_plugin_tv *tv)
658 {
659   struct ld_plugin_tv *p;
660   enum ld_plugin_status status;
661
662   unsigned version = elf_version (EV_CURRENT);
663   check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
664
665   p = tv;
666   while (p->tv_tag)
667     {
668       switch (p->tv_tag)
669         {
670         case LDPT_MESSAGE:
671           message = p->tv_u.tv_message;
672           break;
673         case LDPT_REGISTER_CLAIM_FILE_HOOK:
674           register_claim_file = p->tv_u.tv_register_claim_file;
675           break;
676         case LDPT_ADD_SYMBOLS:
677           add_symbols = p->tv_u.tv_add_symbols;
678           break;
679         case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
680           register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
681           break;
682         case LDPT_GET_SYMBOLS:
683           get_symbols = p->tv_u.tv_get_symbols;
684           break;
685         case LDPT_REGISTER_CLEANUP_HOOK:
686           register_cleanup = p->tv_u.tv_register_cleanup;
687           break;
688         case LDPT_ADD_INPUT_FILE:
689           add_input_file = p->tv_u.tv_add_input_file;
690           break;
691         case LDPT_ADD_INPUT_LIBRARY:
692           add_input_library = p->tv_u.tv_add_input_library;
693           break;
694         case LDPT_OPTION:
695           process_option (p->tv_u.tv_string);
696           break;
697         default:
698           break;
699         }
700       p++;
701     }
702
703   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
704   check (add_symbols, LDPL_FATAL, "add_symbols not found");
705   status = register_claim_file (claim_file_handler);
706   check (status == LDPS_OK, LDPL_FATAL,
707          "could not register the claim_file callback");
708
709   if (register_cleanup)
710     {
711       status = register_cleanup (cleanup_handler);
712       check (status == LDPS_OK, LDPL_FATAL,
713              "could not register the cleanup callback");
714     }
715
716   if (register_all_symbols_read)
717     {
718       check (get_symbols, LDPL_FATAL, "get_symbols not found");
719       status = register_all_symbols_read (all_symbols_read_handler);
720       check (status == LDPS_OK, LDPL_FATAL,
721              "could not register the all_symbols_read callback");
722     }
723
724   return LDPS_OK;
725 }