OSDN Git Service

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