OSDN Git Service

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