OSDN Git Service

* lto-plugin.c (translate): Remove debug fprintf.
[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 sym_aux
59 {
60   uint32_t slot;
61   unsigned id;
62 };
63
64 struct plugin_symtab
65 {
66   int nsyms;
67   struct sym_aux *aux;
68   struct ld_plugin_symbol *syms;
69   unsigned id;
70 };
71
72 /* All that we have to remember about a file. */
73
74 struct plugin_file_info
75 {
76   char *name;
77   void *handle;
78   struct plugin_symtab symtab;
79 };
80
81
82 static char *arguments_file_name;
83 static ld_plugin_register_claim_file register_claim_file;
84 static ld_plugin_add_symbols add_symbols;
85 static ld_plugin_register_all_symbols_read register_all_symbols_read;
86 static ld_plugin_get_symbols get_symbols;
87 static ld_plugin_register_cleanup register_cleanup;
88 static ld_plugin_add_input_file add_input_file;
89 static ld_plugin_add_input_library add_input_library;
90 static ld_plugin_message message;
91
92 static struct plugin_file_info *claimed_files = NULL;
93 static unsigned int num_claimed_files = 0;
94
95 static char **output_files = NULL;
96 static unsigned int num_output_files = 0;
97
98 static char **lto_wrapper_argv;
99 static int lto_wrapper_num_args;
100
101 static char **pass_through_items = NULL;
102 static unsigned int num_pass_through_items;
103
104 static bool debug;
105 static bool nop;
106 static char *resolution_file = NULL;
107
108 static void
109 check (bool gate, enum ld_plugin_level level, const char *text)
110 {
111   if (gate)
112     return;
113
114   if (message)
115     message (level, text);
116   else
117     {
118       /* If there is no nicer way to inform the user, fallback to stderr. */
119       fprintf (stderr, "%s\n", text);
120       if (level == LDPL_FATAL)
121         abort ();
122     }
123 }
124
125 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
126    by P and the result is written in ENTRY. The slot number is stored in SLOT.
127    Returns the address of the next entry. */
128
129 static char *
130 parse_table_entry (char *p, struct ld_plugin_symbol *entry, 
131                    struct sym_aux *aux)
132 {
133   unsigned char t;
134   enum ld_plugin_symbol_kind translate_kind[] =
135     {
136       LDPK_DEF,
137       LDPK_WEAKDEF,
138       LDPK_UNDEF,
139       LDPK_WEAKUNDEF,
140       LDPK_COMMON
141     };
142
143   enum ld_plugin_symbol_visibility translate_visibility[] =
144     {
145       LDPV_DEFAULT,
146       LDPV_PROTECTED,
147       LDPV_INTERNAL,
148       LDPV_HIDDEN
149     };
150
151   entry->name = xstrdup (p);
152   while (*p)
153     p++;
154   p++;
155
156   entry->version = NULL;
157
158   entry->comdat_key = p;
159   while (*p)
160     p++;
161   p++;
162
163   if (strlen (entry->comdat_key) == 0)
164     entry->comdat_key = NULL;
165   else
166     entry->comdat_key = xstrdup (entry->comdat_key);
167
168   t = *p;
169   check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
170   entry->def = translate_kind[t];
171   p++;
172
173   t = *p;
174   check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
175   entry->visibility = translate_visibility[t];
176   p++;
177
178   entry->size = *(uint64_t *) p;
179   p += 8;
180
181   aux->slot = *(uint32_t *) p;
182   p += 4;
183
184   entry->resolution = LDPR_UNKNOWN;
185
186   return p;
187 }
188
189 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
190
191 /* Translate the IL symbol table SYMTAB. Append the slots and symbols to OUT. */
192
193 static void
194 translate (Elf_Data *symtab, struct plugin_symtab *out)
195 {
196   struct sym_aux *aux;
197   char *data = symtab->d_buf;
198   char *end = data + symtab->d_size;
199   struct ld_plugin_symbol *syms = NULL;
200   int n, len;
201
202   /* This overestimates the output buffer sizes, but at least 
203      the algorithm is O(1) now. */
204
205   len = (end - data)/8 + out->nsyms + 1;
206   syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
207   aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
208   
209   for (n = out->nsyms; data < end; n++) 
210     { 
211       aux[n].id = out->id; 
212       data = parse_table_entry (data, &syms[n], &aux[n]);
213     }
214
215   assert(n < len);
216
217   out->nsyms = n;
218   out->syms = syms;
219   out->aux = aux;
220 }
221
222 /* Process all lto symtabs of file ELF. */
223
224 static int
225 process_symtab (Elf *elf, struct plugin_symtab *out)
226 {
227   int found = 0;
228   Elf_Scn *section = 0;
229   GElf_Ehdr header;
230   GElf_Ehdr *t = gelf_getehdr (elf, &header);
231   if (t == NULL)
232     return 0;
233   assert (t == &header);
234
235   while ((section = elf_nextscn(elf, section)) != 0)
236     {
237       GElf_Shdr shdr;
238       GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
239       const char *t;
240       assert (tshdr == &shdr);
241       t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
242       assert (t != NULL);
243       if (strncmp (t, LTO_SECTION_PREFIX, strlen (LTO_SECTION_PREFIX)) == 0) 
244         {
245           char *s = strrchr (t, '.');
246           if (s)
247               sscanf (s, ".%x", &out->id);
248           translate (elf_getdata (section, NULL), out);
249           found = 1;
250         }
251     }
252   return found;
253 }
254
255 /* Free all memory that is no longer needed after writing the symbol
256    resolution. */
257
258 static void
259 free_1 (void)
260 {
261   unsigned int i;
262   for (i = 0; i < num_claimed_files; i++)
263     {
264       struct plugin_file_info *info = &claimed_files[i];
265       struct plugin_symtab *symtab = &info->symtab;
266       unsigned int j;
267       for (j = 0; j < symtab->nsyms; j++)
268         {
269           struct ld_plugin_symbol *s = &symtab->syms[j];
270           free (s->name);
271           if (s->comdat_key)
272             free (s->comdat_key);
273         }
274       free (symtab->syms);
275       symtab->syms = NULL;
276     }
277 }
278
279 /* Free all remaining memory. */
280
281 static void
282 free_2 (void)
283 {
284   unsigned int i;
285   for (i = 0; i < num_claimed_files; i++)
286     {
287       struct plugin_file_info *info = &claimed_files[i];
288       struct plugin_symtab *symtab = &info->symtab;
289       free (symtab->aux);
290       free (info->name);
291     }
292
293   for (i = 0; i < num_output_files; i++)
294     free (output_files[i]);
295   free (output_files);
296
297   free (claimed_files);
298   claimed_files = NULL;
299   num_claimed_files = 0;
300
301   if (arguments_file_name)
302     free (arguments_file_name);
303   arguments_file_name = NULL;
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   check (resolution_file, LDPL_FATAL, "resolution file not specified");
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       get_symbols (info->handle, symtab->nsyms, syms);
328
329       fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
330
331       for (j = 0; j < info->symtab.nsyms; j++)
332         {
333           uint32_t slot = symtab->aux[j].slot;
334           unsigned int resolution = syms[j].resolution;
335           fprintf (f, "%d %x %s %s\n", slot, symtab->aux[j].id,
336                    lto_resolution_str[resolution], syms[j].name);
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   for (;;)
349     {
350       const unsigned piece = 32;
351       char *buf, *s = xmalloc (piece);
352       size_t len;
353
354       buf = s;
355 cont:
356       if (!fgets (buf, piece, f))
357         break;
358       len = strlen (s);
359       if (s[len - 1] != '\n')
360         {
361           s = xrealloc (s, len + piece);
362           buf = s + len;
363           goto cont;
364         }
365       s[len - 1] = '\0';
366
367       num_output_files++;
368       output_files
369         = xrealloc (output_files, num_output_files * sizeof (char *));
370       output_files[num_output_files - 1] = s;
371       add_input_file (output_files[num_output_files - 1]);
372     }
373 }
374
375 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
376    argument list. */
377
378 static void
379 exec_lto_wrapper (char *argv[])
380 {
381   int t, i;
382   int status;
383   char *at_args;
384   FILE *args;
385   FILE *wrapper_output;
386   char *new_argv[3];
387   struct pex_obj *pex;
388   const char *errmsg;
389
390   /* Write argv to a file to avoid a command line that is too long. */
391   arguments_file_name = make_temp_file ("");
392   check (arguments_file_name, LDPL_FATAL,
393          "Failed to generate a temorary file name");
394
395   args = fopen (arguments_file_name, "w");
396   check (args, LDPL_FATAL, "could not open arguments file");
397
398   t = writeargv (&argv[1], args);
399   check (t == 0, LDPL_FATAL, "could not write arguments");
400   t = fclose (args);
401   check (t == 0, LDPL_FATAL, "could not close arguments file");
402
403   at_args = concat ("@", arguments_file_name, NULL);
404   check (at_args, LDPL_FATAL, "could not allocate");
405
406   for (i = 1; argv[i]; i++)
407     {
408       char *a = argv[i];
409       if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
410         {
411           for (i = 0; argv[i]; i++)
412             fprintf (stderr, "%s ", argv[i]);
413           fprintf (stderr, "\n");
414           break;
415         }
416     }
417
418   new_argv[0] = argv[0];
419   new_argv[1] = at_args;
420   new_argv[2] = NULL;
421
422   if (debug)
423     {
424       for (i = 0; new_argv[i]; i++)
425         fprintf (stderr, "%s ", new_argv[i]);
426       fprintf (stderr, "\n");
427     }
428
429
430   pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
431   check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
432
433   errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
434   check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
435   check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
436
437   wrapper_output = pex_read_output (pex, 0);
438   check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
439
440   add_output_files (wrapper_output);
441
442   t = pex_get_status (pex, 1, &status);
443   check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
444   check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
445          "lto-wrapper failed");
446
447   pex_free (pex);
448
449   free (at_args);
450 }
451
452 /* Pass the original files back to the linker. */
453
454 static void
455 use_original_files (void)
456 {
457   unsigned i;
458   for (i = 0; i < num_claimed_files; i++)
459     {
460       struct plugin_file_info *info = &claimed_files[i];
461       add_input_file (info->name);
462     }
463 }
464
465
466 /* Called by the linker once all symbols have been read. */
467
468 static enum ld_plugin_status
469 all_symbols_read_handler (void)
470 {
471   unsigned i;
472   unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
473   char **lto_argv;
474   const char **lto_arg_ptr;
475   if (num_claimed_files == 0)
476     return LDPS_OK;
477
478   if (nop)
479     {
480       use_original_files ();
481       return LDPS_OK;
482     }
483
484   lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
485   lto_arg_ptr = (const char **) lto_argv;
486   assert (lto_wrapper_argv);
487
488   write_resolution ();
489
490   free_1 ();
491
492   for (i = 0; i < lto_wrapper_num_args; i++)
493     *lto_arg_ptr++ = lto_wrapper_argv[i];
494
495   for (i = 0; i < num_claimed_files; i++)
496     {
497       struct plugin_file_info *info = &claimed_files[i];
498
499       *lto_arg_ptr++ = info->name;
500     }
501
502   *lto_arg_ptr++ = NULL;
503   exec_lto_wrapper (lto_argv);
504
505   free (lto_argv);
506
507   if (pass_through_items)
508     {
509       unsigned int i;
510       for (i = 0; i < num_pass_through_items; i++)
511         {
512           if (strncmp (pass_through_items[i], "-l", 2) == 0)
513             add_input_library (pass_through_items[i] + 2);
514           else
515             add_input_file (pass_through_items[i]);
516           free (pass_through_items[i]);
517           pass_through_items[i] = NULL;
518         }
519       free (pass_through_items);
520       pass_through_items = NULL;
521     }
522
523   return LDPS_OK;
524 }
525
526 /* Remove temporary files at the end of the link. */
527
528 static enum ld_plugin_status
529 cleanup_handler (void)
530 {
531   unsigned int i;
532   int t;
533
534   if (debug)
535     return LDPS_OK;
536
537   if (arguments_file_name)
538     {
539       t = unlink (arguments_file_name);
540       check (t == 0, LDPL_FATAL, "could not unlink arguments file");
541     }
542
543   for (i = 0; i < num_output_files; i++)
544     {
545       t = unlink (output_files[i]);
546       check (t == 0, LDPL_FATAL, "could not unlink output file");
547     }
548
549   free_2 ();
550   return LDPS_OK;
551 }
552
553 /* Callback used by gold to check if the plugin will claim FILE. Writes
554    the result in CLAIMED. */
555
556 static enum ld_plugin_status
557 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
558 {
559   enum ld_plugin_status status;
560   Elf *elf;
561   struct plugin_file_info lto_file;
562
563   memset (&lto_file, 0, sizeof (struct plugin_file_info));
564
565   if (file->offset != 0)
566     {
567       char *objname;
568       Elf *archive;
569       off_t offset;
570       /* We pass the offset of the actual file, not the archive header. */
571       int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
572                         (int64_t) file->offset);
573       check (t >= 0, LDPL_FATAL, "asprintf failed");
574       lto_file.name = objname;
575
576       archive = elf_begin (file->fd, ELF_C_READ, NULL);
577       check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
578              "Not an archive and offset not 0");
579
580       /* elf_rand expects the offset to point to the ar header, not the
581          object itself. Subtract the size of the ar header (60 bytes).
582          We don't uses sizeof (struct ar_hd) to avoid including ar.h */
583
584       offset = file->offset - 60;
585       check (offset == elf_rand (archive, offset), LDPL_FATAL,
586              "could not seek in archive");
587       elf = elf_begin (file->fd, ELF_C_READ, archive);
588       check (elf != NULL, LDPL_FATAL, "could not find archive member");
589       elf_end (archive);
590     }
591   else
592     {
593       lto_file.name = xstrdup (file->name);
594       elf = elf_begin (file->fd, ELF_C_READ, NULL);
595     }
596   lto_file.handle = file->handle;
597
598   *claimed = 0;
599
600   if (!elf || !process_symtab (elf, &lto_file.symtab))
601     goto err;
602
603   status = add_symbols (file->handle, lto_file.symtab.nsyms,
604                         lto_file.symtab.syms);
605   check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
606
607   *claimed = 1;
608   num_claimed_files++;
609   claimed_files =
610     xrealloc (claimed_files,
611               num_claimed_files * sizeof (struct plugin_file_info));
612   claimed_files[num_claimed_files - 1] = lto_file;
613
614   goto cleanup;
615
616  err:
617   free (lto_file.name);
618
619  cleanup:
620   if (elf)
621     elf_end (elf);
622
623   return LDPS_OK;
624 }
625
626 /* Parse the plugin options. */
627
628 static void
629 process_option (const char *option)
630 {
631   if (strcmp (option, "-debug") == 0)
632     debug = 1;
633   else if (strcmp (option, "-nop") == 0)
634     nop = 1;
635   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
636     {
637       num_pass_through_items++;
638       pass_through_items = xrealloc (pass_through_items,
639                                      num_pass_through_items * sizeof (char *));
640       pass_through_items[num_pass_through_items - 1] =
641           xstrdup (option + strlen ("-pass-through="));
642     }
643   else
644     {
645       int size;
646       char *opt = xstrdup (option);
647       lto_wrapper_num_args += 1;
648       size = lto_wrapper_num_args * sizeof (char *);
649       lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
650       lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
651       if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
652         resolution_file = opt + sizeof ("-fresolution=") - 1;
653     }
654 }
655
656 /* Called by gold after loading the plugin. TV is the transfer vector. */
657
658 enum ld_plugin_status
659 onload (struct ld_plugin_tv *tv)
660 {
661   struct ld_plugin_tv *p;
662   enum ld_plugin_status status;
663
664   unsigned version = elf_version (EV_CURRENT);
665   check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
666
667   p = tv;
668   while (p->tv_tag)
669     {
670       switch (p->tv_tag)
671         {
672         case LDPT_MESSAGE:
673           message = p->tv_u.tv_message;
674           break;
675         case LDPT_REGISTER_CLAIM_FILE_HOOK:
676           register_claim_file = p->tv_u.tv_register_claim_file;
677           break;
678         case LDPT_ADD_SYMBOLS:
679           add_symbols = p->tv_u.tv_add_symbols;
680           break;
681         case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
682           register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
683           break;
684         case LDPT_GET_SYMBOLS:
685           get_symbols = p->tv_u.tv_get_symbols;
686           break;
687         case LDPT_REGISTER_CLEANUP_HOOK:
688           register_cleanup = p->tv_u.tv_register_cleanup;
689           break;
690         case LDPT_ADD_INPUT_FILE:
691           add_input_file = p->tv_u.tv_add_input_file;
692           break;
693         case LDPT_ADD_INPUT_LIBRARY:
694           add_input_library = p->tv_u.tv_add_input_library;
695           break;
696         case LDPT_OPTION:
697           process_option (p->tv_u.tv_string);
698           break;
699         default:
700           break;
701         }
702       p++;
703     }
704
705   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
706   check (add_symbols, LDPL_FATAL, "add_symbols not found");
707   status = register_claim_file (claim_file_handler);
708   check (status == LDPS_OK, LDPL_FATAL,
709          "could not register the claim_file callback");
710
711   if (register_cleanup)
712     {
713       status = register_cleanup (cleanup_handler);
714       check (status == LDPS_OK, LDPL_FATAL,
715              "could not register the cleanup callback");
716     }
717
718   if (register_all_symbols_read)
719     {
720       check (get_symbols, LDPL_FATAL, "get_symbols not found");
721       status = register_all_symbols_read (all_symbols_read_handler);
722       check (status == LDPS_OK, LDPL_FATAL,
723              "could not register the all_symbols_read callback");
724     }
725
726   return LDPS_OK;
727 }