Merge lto branch into trunk.
[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 <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
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
100 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
101 by P and the result is written in ENTRY. The slot number is stored in SLOT.
102 Returns the address of the next entry. */
103
104 static char *
105 parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
106 {
107 unsigned char t;
108 enum ld_plugin_symbol_kind translate_kind[] =
109 {
110 LDPK_DEF,
111 LDPK_WEAKDEF,
112 LDPK_UNDEF,
113 LDPK_WEAKUNDEF,
114 LDPK_COMMON
115 };
116
117 enum ld_plugin_symbol_visibility translate_visibility[] =
118 {
119 LDPV_DEFAULT,
120 LDPV_PROTECTED,
121 LDPV_INTERNAL,
122 LDPV_HIDDEN
123 };
124
125 entry->name = strdup (p);
126 while (*p)
127 p++;
128 p++;
129
130 entry->version = NULL;
131
132 entry->comdat_key = p;
133 while (*p)
134 p++;
135 p++;
136
137 if (strlen (entry->comdat_key) == 0)
138 entry->comdat_key = NULL;
139 else
140 entry->comdat_key = strdup (entry->comdat_key);
141
142 t = *p;
143 assert (t <= 4);
144 entry->def = translate_kind[t];
145 p++;
146
147 t = *p;
148 assert (t <= 3);
149 entry->visibility = translate_visibility[t];
150 p++;
151
152 entry->size = *(uint64_t *) p;
153 p += 8;
154
155 *slot = *(uint32_t *) p;
156 p += 4;
157
158 entry->resolution = LDPR_UNKNOWN;
159
160 return p;
161 }
162
163 /* Return the section in ELF that is named NAME. */
164
165 static Elf_Scn *
166 get_section (Elf *elf, const char *name)
167 {
168 Elf_Scn *section = 0;
169 GElf_Ehdr header;
170 GElf_Ehdr *t = gelf_getehdr (elf, &header);
171 if (t == NULL)
172 return NULL;
173 assert (t == &header);
174
175 while ((section = elf_nextscn(elf, section)) != 0)
176 {
177 GElf_Shdr shdr;
178 GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
179 const char *t;
180 assert (tshdr == &shdr);
181 t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
182 assert (t != NULL);
183 if (strcmp (t, name) == 0)
184 return section;
185 }
186 return NULL;
187 }
188
189 /* Returns the IL symbol table of file ELF. */
190
191 static Elf_Data *
192 get_symtab (Elf *elf)
193 {
194 Elf_Data *data = 0;
195 Elf_Scn *section = get_section (elf, ".gnu.lto_.symtab");
196 if (!section)
197 return NULL;
198
199 data = elf_getdata (section, data);
200 assert (data);
201 return data;
202 }
203
204 /* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
205
206 static void
207 translate (Elf_Data *symtab, struct plugin_symtab *out)
208 {
209 uint32_t *slots = NULL;
210 char *data = symtab->d_buf;
211 char *end = data + symtab->d_size;
212 struct ld_plugin_symbol *syms = NULL;
213 int n = 0;
214
215 while (data < end)
216 {
217 n++;
218 syms = realloc (syms, n * sizeof (struct ld_plugin_symbol));
219 assert (syms);
220 slots = realloc (slots, n * sizeof (uint32_t));
221 assert (slots);
222 data = parse_table_entry (data, &syms[n - 1], &slots[n - 1]);
223 }
224
225 out->nsyms = n;
226 out->syms = syms;
227 out->slots = slots;
228 }
229
230 /* Free all memory that is no longer needed at the beginning of all_symbols_read. */
231
232 static void
233 free_1 (void)
234 {
235 unsigned int i;
236 for (i = 0; i < num_claimed_files; i++)
237 {
238 struct plugin_file_info *info = &claimed_files[i];
239 struct plugin_symtab *symtab = &info->symtab;
240 unsigned int j;
241 for (j = 0; j < symtab->nsyms; j++)
242 {
243 struct ld_plugin_symbol *s = &symtab->syms[j];
244 free (s->name);
245 if (s->comdat_key)
246 free (s->comdat_key);
247 }
248 free (symtab->syms);
249 symtab->syms = NULL;
250 }
251 }
252
253 /* Free all remaining memory. */
254
255 static void
256 free_2 (void)
257 {
258 unsigned int i;
259 for (i = 0; i < num_claimed_files; i++)
260 {
261 struct plugin_file_info *info = &claimed_files[i];
262 struct plugin_symtab *symtab = &info->symtab;
263 free (symtab->slots);
264 free (info->name);
265 }
266
267 for (i = 0; i < num_output_files; i++)
268 free (output_files[i]);
269 free (output_files);
270
271 free (claimed_files);
272 claimed_files = NULL;
273 num_claimed_files = 0;
274
275 free (temp_obj_dir_name);
276 temp_obj_dir_name = NULL;
277 }
278
279 /* Writes the relocations to disk. */
280
281 static void
282 write_resolution (void)
283 {
284 unsigned int i;
285 FILE *f;
286 /* FIXME: Disabled for now since we are not using the resolution file. */
287 return;
288
289
290 /* FIXME: This should be a temporary file. */
291 f = fopen ("resolution", "w");
292
293 fprintf (f, "%d\n", num_claimed_files);
294
295 for (i = 0; i < num_claimed_files; i++)
296 {
297 struct plugin_file_info *info = &claimed_files[i];
298 struct plugin_symtab *symtab = &info->symtab;
299 struct ld_plugin_symbol *syms = calloc (symtab->nsyms,
300 sizeof (struct ld_plugin_symbol));
301 unsigned j;
302
303 assert (syms);
304 get_symbols (info->handle, symtab->nsyms, syms);
305
306 fprintf (f, "%s %d\n", info->name, info->symtab.nsyms);
307
308 for (j = 0; j < info->symtab.nsyms; j++)
309 {
310 uint32_t slot = symtab->slots[j];
311 unsigned int resolution = syms[j].resolution;
312 fprintf (f, "%d %s\n", slot, lto_resolution_str[resolution]);
313 }
314 free (syms);
315 }
316 fclose (f);
317 }
318
319 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
320 stdout. */
321
322 static void
323 add_output_files (FILE *f)
324 {
325 char fname[1000]; /* FIXME: Is this big enough? */
326
327 for (;;)
328 {
329 size_t len;
330 char *s = fgets (fname, sizeof (fname), f);
331 if (!s)
332 break;
333
334 len = strlen (s);
335 assert (s[len - 1] == '\n');
336 s[len - 1] = '\0';
337
338 num_output_files++;
339 output_files = realloc (output_files, num_output_files * sizeof (char *));
340 output_files[num_output_files - 1] = strdup (s);
341 add_input_file (output_files[num_output_files - 1]);
342 }
343 }
344
345 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
346 argument list. */
347
348 static void
349 exec_lto_wrapper (char *argv[])
350 {
351 int t;
352 int status;
353 char *at_args;
354 char *args_name;
355 FILE *args;
356 FILE *wrapper_output;
357 char *new_argv[3];
358 struct pex_obj *pex;
359 const char *errmsg;
360
361 /* Write argv to a file to avoid a command line that is too long. */
362 t = asprintf (&at_args, "@%s/arguments", temp_obj_dir_name);
363 assert (t >= 0);
364
365 args_name = at_args + 1;
366 args = fopen (args_name, "w");
367 assert (args);
368
369 t = writeargv (&argv[1], args);
370 assert (t == 0);
371 t = fclose (args);
372 assert (t == 0);
373
374 new_argv[0] = argv[0];
375 new_argv[1] = at_args;
376 new_argv[2] = NULL;
377
378 if (debug)
379 {
380 int i;
381 for (i = 0; new_argv[i]; i++)
382 fprintf (stderr, "%s ", new_argv[i]);
383 fprintf (stderr, "\n");
384 }
385
386
387 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
388 assert (pex != NULL);
389
390 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
391 assert (errmsg == NULL);
392 assert (t == 0);
393
394 wrapper_output = pex_read_output (pex, 0);
395 assert (wrapper_output);
396
397 add_output_files (wrapper_output);
398
399 t = pex_get_status (pex, 1, &status);
400 assert (t == 1);
401 assert (WIFEXITED (status) && WEXITSTATUS (status) == 0);
402
403 pex_free (pex);
404
405 t = unlink (args_name);
406 assert (t == 0);
407 free (at_args);
408 }
409
410 /* Pass the original files back to the linker. */
411
412 static void
413 use_original_files (void)
414 {
415 unsigned i;
416 for (i = 0; i < num_claimed_files; i++)
417 {
418 struct plugin_file_info *info = &claimed_files[i];
419 add_input_file (info->name);
420 }
421 }
422
423
424 /* Called by the linker once all symbols have been read. */
425
426 static enum ld_plugin_status
427 all_symbols_read_handler (void)
428 {
429 unsigned i;
430 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
431 char **lto_argv;
432 const char **lto_arg_ptr;
433 if (num_claimed_files == 0)
434 return LDPS_OK;
435
436 free_1 ();
437
438 if (nop)
439 {
440 use_original_files ();
441 return LDPS_OK;
442 }
443
444 lto_argv = (char **) calloc (sizeof (char *), num_lto_args);
445 lto_arg_ptr = (const char **) lto_argv;
446 assert (lto_wrapper_argv);
447
448 write_resolution ();
449
450 for (i = 0; i < lto_wrapper_num_args; i++)
451 *lto_arg_ptr++ = lto_wrapper_argv[i];
452
453 for (i = 0; i < num_claimed_files; i++)
454 {
455 struct plugin_file_info *info = &claimed_files[i];
456
457 *lto_arg_ptr++ = info->name;
458 }
459
460 *lto_arg_ptr++ = NULL;
461 exec_lto_wrapper (lto_argv);
462
463 free (lto_argv);
464
465 if (pass_through_items)
466 {
467 unsigned int i;
468 for (i = 0; i < num_pass_through_items; i++)
469 {
470 add_input_file (pass_through_items[i]);
471 free (pass_through_items[i]);
472 pass_through_items[i] = NULL;
473 }
474 free (pass_through_items);
475 pass_through_items = NULL;
476 }
477
478 return LDPS_OK;
479 }
480
481 /* Remove temporary files at the end of the link. */
482
483 static enum ld_plugin_status
484 cleanup_handler (void)
485 {
486 int t;
487 unsigned i;
488
489 for (i = 0; i < num_claimed_files; i++)
490 {
491 struct plugin_file_info *info = &claimed_files[i];
492 if (info->temp)
493 {
494 t = unlink (info->name);
495 assert (t == 0);
496 }
497 }
498 t = rmdir (temp_obj_dir_name);
499 assert (t == 0);
500
501 free_2 ();
502 return LDPS_OK;
503 }
504
505 /* Callback used by gold to check if the plugin will claim FILE. Writes
506 the result in CLAIMED. */
507
508 static enum ld_plugin_status
509 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
510 {
511 enum ld_plugin_status status;
512 Elf *elf;
513 struct plugin_file_info lto_file;
514 Elf_Data *symtab;
515 int lto_file_fd;
516
517 if (file->offset != 0)
518 {
519 /* FIXME lto: lto1 should know how to handle archives. */
520 int fd;
521 off_t size = file->filesize;
522 off_t offset;
523
524 static int objnum = 0;
525 char *objname;
526 int t = asprintf (&objname, "%s/obj%d.o",
527 temp_obj_dir_name, objnum);
528 assert (t >= 0);
529 objnum++;
530
531 fd = open (objname, O_RDWR | O_CREAT, 0666);
532 assert (fd > 0);
533 offset = lseek (file->fd, file->offset, SEEK_SET);
534 assert (offset == file->offset);
535 while (size > 0)
536 {
537 ssize_t r, written;
538 char buf[1000];
539 off_t s = sizeof (buf) < size ? sizeof (buf) : size;
540 r = read (file->fd, buf, s);
541 written = write (fd, buf, r);
542 assert (written = r);
543 size -= r;
544 }
545 lto_file.name = objname;
546 lto_file_fd = fd;
547 lto_file.handle = file->handle;
548 lto_file.temp = 1;
549 }
550 else
551 {
552 lto_file.name = strdup (file->name);
553 lto_file_fd = file->fd;
554 lto_file.handle = file->handle;
555 lto_file.temp = 0;
556 }
557 elf = elf_begin (lto_file_fd, ELF_C_READ, NULL);
558
559 *claimed = 0;
560
561 if (!elf)
562 goto err;
563
564 symtab = get_symtab (elf);
565 if (!symtab)
566 goto err;
567
568 translate (symtab, &lto_file.symtab);
569
570 status = add_symbols (file->handle, lto_file.symtab.nsyms,
571 lto_file.symtab.syms);
572 assert (status == LDPS_OK);
573
574 *claimed = 1;
575 num_claimed_files++;
576 claimed_files =
577 realloc (claimed_files,
578 num_claimed_files * sizeof (struct plugin_file_info));
579 claimed_files[num_claimed_files - 1] = lto_file;
580
581 goto cleanup;
582
583 err:
584 if (file->offset != 0)
585 {
586 int t = unlink (lto_file.name);
587 assert (t == 0);
588 }
589 free (lto_file.name);
590
591 cleanup:
592 if (elf)
593 elf_end (elf);
594
595 return LDPS_OK;
596 }
597
598 /* Parse the plugin options. */
599
600 static void
601 process_option (const char *option)
602 {
603 if (strcmp (option, "-debug") == 0)
604 debug = 1;
605 else if (strcmp (option, "-nop") == 0)
606 nop = 1;
607 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
608 {
609 num_pass_through_items++;
610 pass_through_items = realloc (pass_through_items, num_pass_through_items * sizeof (char *));
611 pass_through_items[num_pass_through_items - 1] = strdup (option + strlen ("-pass-through="));
612 }
613 else
614 {
615 int size;
616 lto_wrapper_num_args += 1;
617 size = lto_wrapper_num_args * sizeof (char *);
618 lto_wrapper_argv = (char **) realloc (lto_wrapper_argv, size);
619 lto_wrapper_argv[lto_wrapper_num_args - 1] = strdup(option);
620 }
621 }
622
623 /* Called by gold after loading the plugin. TV is the transfer vector. */
624
625 enum ld_plugin_status
626 onload (struct ld_plugin_tv *tv)
627 {
628 struct ld_plugin_tv *p;
629 enum ld_plugin_status status;
630 char *t;
631
632 unsigned version = elf_version (EV_CURRENT);
633 assert (version != EV_NONE);
634
635 p = tv;
636 while (p->tv_tag)
637 {
638 switch (p->tv_tag)
639 {
640 case LDPT_REGISTER_CLAIM_FILE_HOOK:
641 register_claim_file = p->tv_u.tv_register_claim_file;
642 break;
643 case LDPT_ADD_SYMBOLS:
644 add_symbols = p->tv_u.tv_add_symbols;
645 break;
646 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
647 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
648 break;
649 case LDPT_GET_SYMBOLS:
650 get_symbols = p->tv_u.tv_get_symbols;
651 break;
652 case LDPT_REGISTER_CLEANUP_HOOK:
653 register_cleanup = p->tv_u.tv_register_cleanup;
654 break;
655 case LDPT_ADD_INPUT_FILE:
656 add_input_file = p->tv_u.tv_add_input_file;
657 break;
658 case LDPT_OPTION:
659 process_option (p->tv_u.tv_string);
660 break;
661 default:
662 break;
663 }
664 p++;
665 }
666
667 assert (register_claim_file);
668 assert (add_symbols);
669 status = register_claim_file (claim_file_handler);
670 assert (status == LDPS_OK);
671
672 if (register_cleanup)
673 {
674 status = register_cleanup (cleanup_handler);
675 assert (status == LDPS_OK);
676 }
677
678 if (register_all_symbols_read)
679 {
680 assert (get_symbols);
681 status = register_all_symbols_read (all_symbols_read_handler);
682 assert (status == LDPS_OK);
683 }
684
685 temp_obj_dir_name = strdup ("tmp_objectsXXXXXX");
686 t = mkdtemp (temp_obj_dir_name);
687 assert (t == temp_obj_dir_name);
688 return LDPS_OK;
689 }