OSDN Git Service

missing changelog
[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   /* Note: we cannot use LDPL_FATAL in here as that would produce
516      an infinite loop. */
517   int t;
518   unsigned i;
519   char *arguments;
520   struct stat buf;
521
522   for (i = 0; i < num_claimed_files; i++)
523     {
524       struct plugin_file_info *info = &claimed_files[i];
525       if (info->temp)
526         {
527           t = unlink (info->name);
528           check (t == 0, LDPL_ERROR, "could not unlink temporary file");
529         }
530     }
531
532   /* If we are being called from an error handler, it is possible
533      that the arguments file is still exists. */
534   t = asprintf (&arguments, "%s/arguments", temp_obj_dir_name);
535   check (t >= 0, LDPL_ERROR, "asprintf failed");
536   if (stat(arguments, &buf) == 0)
537     {
538       t = unlink (arguments);
539       check (t == 0, LDPL_ERROR, "could not unlink arguments file");
540     }
541   free (arguments);
542
543   t = rmdir (temp_obj_dir_name);
544   check (t == 0, LDPL_ERROR, "could not remove temporary directory");
545
546   free_2 ();
547   return LDPS_OK;
548 }
549
550 /* Callback used by gold to check if the plugin will claim FILE. Writes
551    the result in CLAIMED. */
552
553 static enum ld_plugin_status
554 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
555 {
556   enum ld_plugin_status status;
557   Elf *elf;
558   struct plugin_file_info lto_file;
559   Elf_Data *symtab;
560   int lto_file_fd;
561
562   if (file->offset != 0)
563     {
564       /* FIXME lto: lto1 should know how to handle archives. */
565       int fd;
566       off_t size = file->filesize;
567       off_t offset;
568
569       static int objnum = 0;
570       char *objname;
571       int t = asprintf (&objname, "%s/obj%d.o",
572                         temp_obj_dir_name, objnum);
573       check (t >= 0, LDPL_FATAL, "asprintf failed");
574       objnum++;
575
576       fd = open (objname, O_RDWR | O_CREAT, 0666);
577       check (fd > 0, LDPL_FATAL, "could not open/create temporary file");
578       offset = lseek (file->fd, file->offset, SEEK_SET);
579       check (offset == file->offset, LDPL_FATAL, "could not seek");
580       while (size > 0)
581         {
582           ssize_t r, written;
583           char buf[1000];
584           off_t s = sizeof (buf) < size ? sizeof (buf) : size;
585           r = read (file->fd, buf, s);
586           written = write (fd, buf, r);
587           check (written == r, LDPL_FATAL, "could not write to temporary file");
588           size -= r;
589         }
590       lto_file.name = objname;
591       lto_file_fd = fd;
592       lto_file.handle = file->handle;
593       lto_file.temp = 1;
594     }
595   else
596     {
597       lto_file.name = strdup (file->name);
598       lto_file_fd = file->fd;
599       lto_file.handle = file->handle;
600       lto_file.temp = 0;
601     }
602   elf = elf_begin (lto_file_fd, ELF_C_READ, NULL);
603
604   *claimed = 0;
605
606   if (!elf)
607     goto err;
608
609   symtab = get_symtab (elf);
610   if (!symtab)
611     goto err;
612
613   translate (symtab, &lto_file.symtab);
614
615   status = add_symbols (file->handle, lto_file.symtab.nsyms,
616                         lto_file.symtab.syms);
617   check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
618
619   *claimed = 1;
620   num_claimed_files++;
621   claimed_files =
622     realloc (claimed_files,
623              num_claimed_files * sizeof (struct plugin_file_info));
624   claimed_files[num_claimed_files - 1] = lto_file;
625
626   goto cleanup;
627
628  err:
629   if (file->offset != 0)
630     {
631       int t = unlink (lto_file.name);
632       check (t == 0, LDPL_FATAL, "could not unlink file");
633     }
634   free (lto_file.name);
635
636  cleanup:
637   if (elf)
638     elf_end (elf);
639
640   return LDPS_OK;
641 }
642
643 /* Parse the plugin options. */
644
645 static void
646 process_option (const char *option)
647 {
648   if (strcmp (option, "-debug") == 0)
649     debug = 1;
650   else if (strcmp (option, "-nop") == 0)
651     nop = 1;
652   else if (!strncmp (option, "-resolution=", strlen("-resolution=")))
653     {
654       resolution_file = strdup (option + strlen("-resolution="));
655     }
656   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
657     {
658       num_pass_through_items++;
659       pass_through_items = realloc (pass_through_items,
660                                     num_pass_through_items * sizeof (char *));
661       pass_through_items[num_pass_through_items - 1] =
662           strdup (option + strlen ("-pass-through="));
663     }
664   else
665     {
666       int size;
667       lto_wrapper_num_args += 1;
668       size = lto_wrapper_num_args * sizeof (char *);
669       lto_wrapper_argv = (char **) realloc (lto_wrapper_argv, size);
670       lto_wrapper_argv[lto_wrapper_num_args - 1] = strdup(option);
671     }
672 }
673
674 /* Called by gold after loading the plugin. TV is the transfer vector. */
675
676 enum ld_plugin_status
677 onload (struct ld_plugin_tv *tv)
678 {
679   struct ld_plugin_tv *p;
680   enum ld_plugin_status status;
681   char *t;
682
683   unsigned version = elf_version (EV_CURRENT);
684   check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
685
686   p = tv;
687   while (p->tv_tag)
688     {
689       switch (p->tv_tag)
690         {
691         case LDPT_MESSAGE:
692           message = p->tv_u.tv_message;
693           break;
694         case LDPT_REGISTER_CLAIM_FILE_HOOK:
695           register_claim_file = p->tv_u.tv_register_claim_file;
696           break;
697         case LDPT_ADD_SYMBOLS:
698           add_symbols = p->tv_u.tv_add_symbols;
699           break;
700         case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
701           register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
702           break;
703         case LDPT_GET_SYMBOLS:
704           get_symbols = p->tv_u.tv_get_symbols;
705           break;
706         case LDPT_REGISTER_CLEANUP_HOOK:
707           register_cleanup = p->tv_u.tv_register_cleanup;
708           break;
709         case LDPT_ADD_INPUT_FILE:
710           add_input_file = p->tv_u.tv_add_input_file;
711           break;
712         case LDPT_ADD_INPUT_LIBRARY:
713           add_input_library = p->tv_u.tv_add_input_library;
714           break;
715         case LDPT_OPTION:
716           process_option (p->tv_u.tv_string);
717           break;
718         default:
719           break;
720         }
721       p++;
722     }
723
724   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
725   check (add_symbols, LDPL_FATAL, "add_symbols not found");
726   status = register_claim_file (claim_file_handler);
727   check (status == LDPS_OK, LDPL_FATAL,
728          "could not register the claim_file callback");
729
730   if (register_cleanup)
731     {
732       status = register_cleanup (cleanup_handler);
733       check (status == LDPS_OK, LDPL_FATAL,
734              "could not register the cleanup callback");
735     }
736
737   if (register_all_symbols_read)
738     {
739       check (get_symbols, LDPL_FATAL, "get_symbols not found");
740       status = register_all_symbols_read (all_symbols_read_handler);
741       check (status == LDPS_OK, LDPL_FATAL,
742              "could not register the all_symbols_read callback");
743     }
744
745   temp_obj_dir_name = strdup ("tmp_objectsXXXXXX");
746   t = mkdtemp (temp_obj_dir_name);
747   assert (t == temp_obj_dir_name);
748   return LDPS_OK;
749 }