OSDN Git Service

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