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