OSDN Git Service

2009-11-04 Rafael Avila de Espindola <espindola@google.com>
[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 <ar.h>
41 #include <sys/stat.h>
42 #include <unistd.h>
43 #include <fcntl.h>
44 #include <sys/types.h>
45 #include <sys/wait.h>
46 #include <stdbool.h>
47 #include <libiberty.h>
48
49 /* The presence of gelf.h is checked by the toplevel configure script.  */
50 #include <gelf.h>
51
52 #include "plugin-api.h"
53 #include "../gcc/lto/common.h"
54
55 /* The part of the symbol table the plugin has to keep track of. Note that we
56    must keep SYMS until all_symbols_read is called to give the linker time to
57    copy the symbol information. */
58
59 struct plugin_symtab
60 {
61   int nsyms;
62   uint32_t *slots;
63   struct ld_plugin_symbol *syms;
64 };
65
66 /* All that we have to remember about a file. */
67
68 struct plugin_file_info
69 {
70   char *name;
71   void *handle;
72   struct plugin_symtab symtab;
73   unsigned char temp;
74 };
75
76
77 static char *temp_obj_dir_name;
78 static ld_plugin_register_claim_file register_claim_file;
79 static ld_plugin_add_symbols add_symbols;
80 static ld_plugin_register_all_symbols_read register_all_symbols_read;
81 static ld_plugin_get_symbols get_symbols;
82 static ld_plugin_register_cleanup register_cleanup;
83 static ld_plugin_add_input_file add_input_file;
84 static ld_plugin_add_input_library add_input_library;
85 static ld_plugin_message message;
86
87 static struct plugin_file_info *claimed_files = NULL;
88 static unsigned int num_claimed_files = 0;
89
90 static char **output_files = NULL;
91 static unsigned int num_output_files = 0;
92
93 static char **lto_wrapper_argv;
94 static int lto_wrapper_num_args;
95
96 static char **pass_through_items = NULL;
97 static unsigned int num_pass_through_items;
98
99 static bool debug;
100 static bool nop;
101 static char *resolution_file = NULL;
102
103 static void
104 check (bool gate, enum ld_plugin_level level, const char *text)
105 {
106   if (gate)
107     return;
108
109   if (message)
110     message (level, text);
111   else
112     {
113       /* If there is no nicer way to inform the user, fallback to stderr. */
114       fprintf (stderr, "%s\n", text);
115       if (level == LDPL_FATAL)
116         abort ();
117     }
118 }
119
120 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
121    by P and the result is written in ENTRY. The slot number is stored in SLOT.
122    Returns the address of the next entry. */
123
124 static char *
125 parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
126 {
127   unsigned char t;
128   enum ld_plugin_symbol_kind translate_kind[] =
129     {
130       LDPK_DEF,
131       LDPK_WEAKDEF,
132       LDPK_UNDEF,
133       LDPK_WEAKUNDEF,
134       LDPK_COMMON
135     };
136
137   enum ld_plugin_symbol_visibility translate_visibility[] =
138     {
139       LDPV_DEFAULT,
140       LDPV_PROTECTED,
141       LDPV_INTERNAL,
142       LDPV_HIDDEN
143     };
144
145   entry->name = strdup (p);
146   while (*p)
147     p++;
148   p++;
149
150   entry->version = NULL;
151
152   entry->comdat_key = p;
153   while (*p)
154     p++;
155   p++;
156
157   if (strlen (entry->comdat_key) == 0)
158     entry->comdat_key = NULL;
159   else
160     entry->comdat_key = strdup (entry->comdat_key);
161
162   t = *p;
163   check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
164   entry->def = translate_kind[t];
165   p++;
166
167   t = *p;
168   check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
169   entry->visibility = translate_visibility[t];
170   p++;
171
172   entry->size = *(uint64_t *) p;
173   p += 8;
174
175   *slot = *(uint32_t *) p;
176   p += 4;
177
178   entry->resolution = LDPR_UNKNOWN;
179
180   return p;
181 }
182
183 /* Return the section in ELF that is named NAME. */
184
185 static Elf_Scn *
186 get_section (Elf *elf, const char *name)
187 {
188   Elf_Scn *section = 0;
189   GElf_Ehdr header;
190   GElf_Ehdr *t = gelf_getehdr (elf, &header);
191   if (t == NULL)
192     return NULL;
193   assert (t == &header);
194
195   while ((section = elf_nextscn(elf, section)) != 0)
196     {
197       GElf_Shdr shdr;
198       GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
199       const char *t;
200       assert (tshdr == &shdr);
201       t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
202       assert (t != NULL);
203       if (strcmp (t, name) == 0)
204         return section;
205     }
206   return NULL;
207 }
208
209 /* Returns the IL symbol table of file ELF. */
210
211 static Elf_Data *
212 get_symtab (Elf *elf)
213 {
214   Elf_Data *data = 0;
215   Elf_Scn *section = get_section (elf, ".gnu.lto_.symtab");
216   if (!section)
217     return NULL;
218
219   data = elf_getdata (section, data);
220   assert (data);
221   return data;
222 }
223
224 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
225
226 static void
227 translate (Elf_Data *symtab, struct plugin_symtab *out)
228 {
229   uint32_t *slots = NULL;
230   char *data = symtab->d_buf;
231   char *end = data + symtab->d_size;
232   struct ld_plugin_symbol *syms = NULL;
233   int n = 0;
234
235   while (data < end)
236     {
237       n++;
238       syms = realloc (syms, n * sizeof (struct ld_plugin_symbol));
239       check (syms, LDPL_FATAL, "could not allocate memory");
240       slots = realloc (slots, n * sizeof (uint32_t));
241       check (slots, LDPL_FATAL, "could not allocate memory");
242       data = parse_table_entry (data, &syms[n - 1], &slots[n - 1]);
243     }
244
245   out->nsyms = n;
246   out->syms = syms;
247   out->slots = slots;
248 }
249
250 /* Free all memory that is no longer needed after writing the symbol
251    resolution. */
252
253 static void
254 free_1 (void)
255 {
256   unsigned int i;
257   for (i = 0; i < num_claimed_files; i++)
258     {
259       struct plugin_file_info *info = &claimed_files[i];
260       struct plugin_symtab *symtab = &info->symtab;
261       unsigned int j;
262       for (j = 0; j < symtab->nsyms; j++)
263         {
264           struct ld_plugin_symbol *s = &symtab->syms[j];
265           free (s->name);
266           if (s->comdat_key)
267             free (s->comdat_key);
268         }
269       free (symtab->syms);
270       symtab->syms = NULL;
271     }
272 }
273
274 /* Free all remaining memory. */
275
276 static void
277 free_2 (void)
278 {
279   unsigned int i;
280   for (i = 0; i < num_claimed_files; i++)
281     {
282       struct plugin_file_info *info = &claimed_files[i];
283       struct plugin_symtab *symtab = &info->symtab;
284       free (symtab->slots);
285       free (info->name);
286     }
287
288   for (i = 0; i < num_output_files; i++)
289     free (output_files[i]);
290   free (output_files);
291
292   free (claimed_files);
293   claimed_files = NULL;
294   num_claimed_files = 0;
295
296   free (temp_obj_dir_name);
297   temp_obj_dir_name = NULL;
298
299   if (resolution_file)
300     {
301       free (resolution_file);
302       resolution_file = NULL;
303     }
304 }
305
306 /*  Writes the relocations to disk. */
307
308 static void
309 write_resolution (void)
310 {
311   unsigned int i;
312   FILE *f;
313
314   if (!resolution_file)
315     return;
316
317   f = fopen (resolution_file, "w");
318   check (f, LDPL_FATAL, "could not open file");
319
320   fprintf (f, "%d\n", num_claimed_files);
321
322   for (i = 0; i < num_claimed_files; i++)
323     {
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;
328
329       assert (syms);
330       get_symbols (info->handle, symtab->nsyms, syms);
331
332       fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
333
334       for (j = 0; j < info->symtab.nsyms; j++)
335         {
336           uint32_t slot = symtab->slots[j];
337           unsigned int resolution = syms[j].resolution;
338           fprintf (f, "%d %s\n", slot, lto_resolution_str[resolution]);
339         }
340     }
341   fclose (f);
342 }
343
344 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
345    stdout. */
346
347 static void
348 add_output_files (FILE *f)
349 {
350   char fname[1000]; /* FIXME: Remove this restriction. */
351
352   for (;;)
353     {
354       size_t len;
355       char *s = fgets (fname, sizeof (fname), f);
356       if (!s)
357         break;
358
359       len = strlen (s);
360       check (s[len - 1] == '\n', LDPL_FATAL, "file name too long");
361       s[len - 1] = '\0';
362
363       num_output_files++;
364       output_files = realloc (output_files, num_output_files * sizeof (char *));
365       output_files[num_output_files - 1] = strdup (s);
366       add_input_file (output_files[num_output_files - 1]);
367     }
368 }
369
370 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
371    argument list. */
372
373 static void
374 exec_lto_wrapper (char *argv[])
375 {
376   int t;
377   int status;
378   char *at_args;
379   char *args_name;
380   FILE *args;
381   FILE *wrapper_output;
382   char *new_argv[3];
383   struct pex_obj *pex;
384   const char *errmsg;
385
386   /* Write argv to a file to avoid a command line that is too long. */
387   t = asprintf (&at_args, "@%s/arguments", temp_obj_dir_name);
388   check (t >= 0, LDPL_FATAL, "asprintf failed");
389
390   args_name = at_args + 1;
391   args = fopen (args_name, "w");
392   check (args, LDPL_FATAL, "could not open arguments file");
393
394   t = writeargv (&argv[1], args);
395   check (t == 0, LDPL_FATAL, "could not write arguments");
396   t = fclose (args);
397   check (t == 0, LDPL_FATAL, "could not close arguments file");
398
399   new_argv[0] = argv[0];
400   new_argv[1] = at_args;
401   new_argv[2] = NULL;
402
403   if (debug)
404     {
405       int i;
406       for (i = 0; new_argv[i]; i++)
407         fprintf (stderr, "%s ", new_argv[i]);
408       fprintf (stderr, "\n");
409     }
410
411
412   pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
413   check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
414
415   errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
416   check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
417   check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
418
419   wrapper_output = pex_read_output (pex, 0);
420   check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
421
422   add_output_files (wrapper_output);
423
424   t = pex_get_status (pex, 1, &status);
425   check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
426   check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
427          "lto-wrapper failed");
428
429   pex_free (pex);
430
431   t = unlink (args_name);
432   check (t == 0, LDPL_FATAL, "could not unlink arguments file");
433   free (at_args);
434 }
435
436 /* Pass the original files back to the linker. */
437
438 static void
439 use_original_files (void)
440 {
441   unsigned i;
442   for (i = 0; i < num_claimed_files; i++)
443     {
444       struct plugin_file_info *info = &claimed_files[i];
445       add_input_file (info->name);
446     }
447 }
448
449
450 /* Called by the linker once all symbols have been read. */
451
452 static enum ld_plugin_status
453 all_symbols_read_handler (void)
454 {
455   unsigned i;
456   unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
457   char **lto_argv;
458   const char **lto_arg_ptr;
459   if (num_claimed_files == 0)
460     return LDPS_OK;
461
462   if (nop)
463     {
464       use_original_files ();
465       return LDPS_OK;
466     }
467
468   lto_argv = (char **) calloc (sizeof (char *), num_lto_args);
469   lto_arg_ptr = (const char **) lto_argv;
470   assert (lto_wrapper_argv);
471
472   write_resolution ();
473
474   free_1 ();
475
476   for (i = 0; i < lto_wrapper_num_args; i++)
477     *lto_arg_ptr++ = lto_wrapper_argv[i];
478
479   for (i = 0; i < num_claimed_files; i++)
480     {
481       struct plugin_file_info *info = &claimed_files[i];
482
483       *lto_arg_ptr++ = info->name;
484     }
485
486   *lto_arg_ptr++ = NULL;
487   exec_lto_wrapper (lto_argv);
488
489   free (lto_argv);
490
491   if (pass_through_items)
492     {
493       unsigned int i;
494       for (i = 0; i < num_pass_through_items; i++)
495         {
496           if (strncmp (pass_through_items[i], "-l", 2) == 0)
497             add_input_library (pass_through_items[i] + 2);
498           else
499             add_input_file (pass_through_items[i]);
500           free (pass_through_items[i]);
501           pass_through_items[i] = NULL;
502         }
503       free (pass_through_items);
504       pass_through_items = NULL;
505     }
506
507   return LDPS_OK;
508 }
509
510 /* Remove temporary files at the end of the link. */
511
512 static enum ld_plugin_status
513 cleanup_handler (void)
514 {
515   int t;
516   unsigned i;
517   char *arguments;
518   struct stat buf;
519
520   for (i = 0; i < num_claimed_files; i++)
521     {
522       struct plugin_file_info *info = &claimed_files[i];
523       if (info->temp)
524         {
525           t = unlink (info->name);
526           check (t == 0, LDPL_FATAL, "could not unlink temporary file");
527         }
528     }
529
530   if (debug)
531     return LDPS_OK;
532
533   /* If we are being called from an error handler, it is possible
534      that the arguments file is still exists. */
535   t = asprintf (&arguments, "%s/arguments", temp_obj_dir_name);
536   check (t >= 0, LDPL_FATAL, "asprintf failed");
537   if (stat(arguments, &buf) == 0)
538     {
539       t = unlink (arguments);
540       check (t == 0, LDPL_FATAL, "could not unlink arguments file");
541     }
542   free (arguments);
543
544   t = rmdir (temp_obj_dir_name);
545   check (t == 0, LDPL_FATAL, "could not remove temporary directory");
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   int lto_file_fd;
562
563   if (file->offset != 0)
564     {
565       /* FIXME lto: lto1 should know how to handle archives. */
566       int fd;
567       off_t size = file->filesize;
568       off_t offset;
569
570       static int objnum = 0;
571       char *objname;
572       int t = asprintf (&objname, "%s/obj%d.o",
573                         temp_obj_dir_name, objnum);
574       check (t >= 0, LDPL_FATAL, "asprintf failed");
575       objnum++;
576
577       fd = open (objname, O_RDWR | O_CREAT, 0666);
578       check (fd > 0, LDPL_FATAL, "could not open/create temporary file");
579       offset = lseek (file->fd, file->offset, SEEK_SET);
580       check (offset == file->offset, LDPL_FATAL, "could not seek");
581       while (size > 0)
582         {
583           ssize_t r, written;
584           char buf[1000];
585           off_t s = sizeof (buf) < size ? sizeof (buf) : size;
586           r = read (file->fd, buf, s);
587           written = write (fd, buf, r);
588           check (written == r, LDPL_FATAL, "could not write to temporary file");
589           size -= r;
590         }
591       lto_file.name = objname;
592       lto_file_fd = fd;
593       lto_file.handle = file->handle;
594       lto_file.temp = 1;
595     }
596   else
597     {
598       lto_file.name = strdup (file->name);
599       lto_file_fd = file->fd;
600       lto_file.handle = file->handle;
601       lto_file.temp = 0;
602     }
603   elf = elf_begin (lto_file_fd, ELF_C_READ, NULL);
604
605   *claimed = 0;
606
607   if (!elf)
608     goto err;
609
610   symtab = get_symtab (elf);
611   if (!symtab)
612     goto err;
613
614   translate (symtab, &lto_file.symtab);
615
616   status = add_symbols (file->handle, lto_file.symtab.nsyms,
617                         lto_file.symtab.syms);
618   check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
619
620   *claimed = 1;
621   num_claimed_files++;
622   claimed_files =
623     realloc (claimed_files,
624              num_claimed_files * sizeof (struct plugin_file_info));
625   claimed_files[num_claimed_files - 1] = lto_file;
626
627   goto cleanup;
628
629  err:
630   if (file->offset != 0)
631     {
632       int t = unlink (lto_file.name);
633       check (t == 0, LDPL_FATAL, "could not unlink file");
634     }
635   free (lto_file.name);
636
637  cleanup:
638   if (elf)
639     elf_end (elf);
640
641   if (file->offset != 0)
642     close (lto_file_fd);
643
644   return LDPS_OK;
645 }
646
647 /* Parse the plugin options. */
648
649 static void
650 process_option (const char *option)
651 {
652   if (strcmp (option, "-debug") == 0)
653     debug = 1;
654   else if (strcmp (option, "-nop") == 0)
655     nop = 1;
656   else if (!strncmp (option, "-resolution=", strlen("-resolution=")))
657     {
658       resolution_file = strdup (option + strlen("-resolution="));
659     }
660   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
661     {
662       num_pass_through_items++;
663       pass_through_items = realloc (pass_through_items,
664                                     num_pass_through_items * sizeof (char *));
665       pass_through_items[num_pass_through_items - 1] =
666           strdup (option + strlen ("-pass-through="));
667     }
668   else
669     {
670       int size;
671       lto_wrapper_num_args += 1;
672       size = lto_wrapper_num_args * sizeof (char *);
673       lto_wrapper_argv = (char **) realloc (lto_wrapper_argv, size);
674       lto_wrapper_argv[lto_wrapper_num_args - 1] = strdup(option);
675     }
676 }
677
678 /* Called by gold after loading the plugin. TV is the transfer vector. */
679
680 enum ld_plugin_status
681 onload (struct ld_plugin_tv *tv)
682 {
683   struct ld_plugin_tv *p;
684   enum ld_plugin_status status;
685   char *t;
686
687   unsigned version = elf_version (EV_CURRENT);
688   check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
689
690   p = tv;
691   while (p->tv_tag)
692     {
693       switch (p->tv_tag)
694         {
695         case LDPT_MESSAGE:
696           message = p->tv_u.tv_message;
697           break;
698         case LDPT_REGISTER_CLAIM_FILE_HOOK:
699           register_claim_file = p->tv_u.tv_register_claim_file;
700           break;
701         case LDPT_ADD_SYMBOLS:
702           add_symbols = p->tv_u.tv_add_symbols;
703           break;
704         case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
705           register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
706           break;
707         case LDPT_GET_SYMBOLS:
708           get_symbols = p->tv_u.tv_get_symbols;
709           break;
710         case LDPT_REGISTER_CLEANUP_HOOK:
711           register_cleanup = p->tv_u.tv_register_cleanup;
712           break;
713         case LDPT_ADD_INPUT_FILE:
714           add_input_file = p->tv_u.tv_add_input_file;
715           break;
716         case LDPT_ADD_INPUT_LIBRARY:
717           add_input_library = p->tv_u.tv_add_input_library;
718           break;
719         case LDPT_OPTION:
720           process_option (p->tv_u.tv_string);
721           break;
722         default:
723           break;
724         }
725       p++;
726     }
727
728   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
729   check (add_symbols, LDPL_FATAL, "add_symbols not found");
730   status = register_claim_file (claim_file_handler);
731   check (status == LDPS_OK, LDPL_FATAL,
732          "could not register the claim_file callback");
733
734   if (register_cleanup)
735     {
736       status = register_cleanup (cleanup_handler);
737       check (status == LDPS_OK, LDPL_FATAL,
738              "could not register the cleanup callback");
739     }
740
741   if (register_all_symbols_read)
742     {
743       check (get_symbols, LDPL_FATAL, "get_symbols not found");
744       status = register_all_symbols_read (all_symbols_read_handler);
745       check (status == LDPS_OK, LDPL_FATAL,
746              "could not register the all_symbols_read callback");
747     }
748
749   temp_obj_dir_name = strdup ("tmp_objectsXXXXXX");
750   t = mkdtemp (temp_obj_dir_name);
751   assert (t == temp_obj_dir_name);
752   return LDPS_OK;
753 }