re PR lto/46291 (Failed to bootstrap-lto)
[gcc.git] / lto-plugin / lto-plugin.c
1 /* LTO plugin for gold and/or GNU ld.
2 Copyright (C) 2009, 2010 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 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38 #include <assert.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <inttypes.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <fcntl.h>
46 #include <sys/types.h>
47 #include <sys/wait.h>
48 #include <stdbool.h>
49 #include <libiberty.h>
50 #include <hashtab.h>
51 #include "../gcc/lto/common.h"
52 #include "simple-object.h"
53 #include "plugin-api.h"
54
55 /* Handle opening elf files on hosts, such as Windows, that may use
56 text file handling that will break binary access. */
57 #ifndef O_BINARY
58 # define O_BINARY 0
59 #endif
60
61 /* Segment name for LTO sections. This is only used for Mach-O.
62 FIXME: This needs to be kept in sync with darwin.c. */
63
64 #define LTO_SEGMENT_NAME "__GNU_LTO"
65
66 /* LTO magic section name. */
67
68 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
69 #define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
70
71 /* The part of the symbol table the plugin has to keep track of. Note that we
72 must keep SYMS until all_symbols_read is called to give the linker time to
73 copy the symbol information. */
74
75 struct sym_aux
76 {
77 uint32_t slot;
78 unsigned id;
79 unsigned next_conflict;
80 };
81
82 struct plugin_symtab
83 {
84 int nsyms;
85 struct sym_aux *aux;
86 struct ld_plugin_symbol *syms;
87 unsigned id;
88 };
89
90 /* Encapsulates object file data during symbol scan. */
91 struct plugin_objfile
92 {
93 int found;
94 simple_object_read *objfile;
95 struct plugin_symtab *out;
96 const struct ld_plugin_input_file *file;
97 };
98
99 /* All that we have to remember about a file. */
100
101 struct plugin_file_info
102 {
103 char *name;
104 void *handle;
105 struct plugin_symtab symtab;
106 struct plugin_symtab conflicts;
107 };
108
109 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
110 stdio file streams, we do simple label translation here. */
111
112 enum symbol_style
113 {
114 ss_none, /* No underscore prefix. */
115 ss_win32, /* Underscore prefix any symbol not beginning with '@'. */
116 ss_uscore, /* Underscore prefix all symbols. */
117 };
118
119 static char *arguments_file_name;
120 static ld_plugin_register_claim_file register_claim_file;
121 static ld_plugin_register_all_symbols_read register_all_symbols_read;
122 static ld_plugin_get_symbols get_symbols;
123 static ld_plugin_register_cleanup register_cleanup;
124 static ld_plugin_add_input_file add_input_file;
125 static ld_plugin_add_input_library add_input_library;
126 static ld_plugin_message message;
127 static ld_plugin_add_symbols add_symbols;
128
129 static struct plugin_file_info *claimed_files = NULL;
130 static unsigned int num_claimed_files = 0;
131
132 static char **output_files = NULL;
133 static unsigned int num_output_files = 0;
134
135 static char **lto_wrapper_argv;
136 static int lto_wrapper_num_args;
137
138 static char **pass_through_items = NULL;
139 static unsigned int num_pass_through_items;
140
141 static bool debug;
142 static bool nop;
143 static char *resolution_file = NULL;
144
145 /* Set by default from configure.ac, but can be overridden at runtime
146 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
147 (in fact, only first letter of style arg is checked.) */
148 static enum symbol_style sym_style = SYM_STYLE;
149
150 static void
151 check (bool gate, enum ld_plugin_level level, const char *text)
152 {
153 if (gate)
154 return;
155
156 if (message)
157 message (level, text);
158 else
159 {
160 /* If there is no nicer way to inform the user, fallback to stderr. */
161 fprintf (stderr, "%s\n", text);
162 if (level == LDPL_FATAL)
163 abort ();
164 }
165 }
166
167 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
168 by P and the result is written in ENTRY. The slot number is stored in SLOT.
169 Returns the address of the next entry. */
170
171 static char *
172 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
173 struct sym_aux *aux)
174 {
175 unsigned char t;
176 enum ld_plugin_symbol_kind translate_kind[] =
177 {
178 LDPK_DEF,
179 LDPK_WEAKDEF,
180 LDPK_UNDEF,
181 LDPK_WEAKUNDEF,
182 LDPK_COMMON
183 };
184
185 enum ld_plugin_symbol_visibility translate_visibility[] =
186 {
187 LDPV_DEFAULT,
188 LDPV_PROTECTED,
189 LDPV_INTERNAL,
190 LDPV_HIDDEN
191 };
192
193 switch (sym_style)
194 {
195 case ss_win32:
196 if (p[0] == '@')
197 {
198 /* cf. Duff's device. */
199 case ss_none:
200 entry->name = xstrdup (p);
201 break;
202 }
203 /* FALL-THROUGH. */
204 case ss_uscore:
205 entry->name = concat ("_", p, NULL);
206 break;
207 default:
208 check (false, LDPL_FATAL, "invalid symbol style requested");
209 break;
210 }
211 while (*p)
212 p++;
213 p++;
214
215 entry->version = NULL;
216
217 entry->comdat_key = p;
218 while (*p)
219 p++;
220 p++;
221
222 if (strlen (entry->comdat_key) == 0)
223 entry->comdat_key = NULL;
224 else
225 entry->comdat_key = xstrdup (entry->comdat_key);
226
227 t = *p;
228 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
229 entry->def = translate_kind[t];
230 p++;
231
232 t = *p;
233 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
234 entry->visibility = translate_visibility[t];
235 p++;
236
237 entry->size = *(uint64_t *) p;
238 p += 8;
239
240 aux->slot = *(uint32_t *) p;
241 p += 4;
242
243 entry->resolution = LDPR_UNKNOWN;
244
245 aux->next_conflict = -1;
246
247 return p;
248 }
249
250 /* Translate the IL symbol table located between DATA and END. Append the
251 slots and symbols to OUT. */
252
253 static void
254 translate (char *data, char *end, struct plugin_symtab *out)
255 {
256 struct sym_aux *aux;
257 struct ld_plugin_symbol *syms = NULL;
258 int n, len;
259
260 /* This overestimates the output buffer sizes, but at least
261 the algorithm is O(1) now. */
262
263 len = (end - data)/8 + out->nsyms + 1;
264 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
265 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
266
267 for (n = out->nsyms; data < end; n++)
268 {
269 aux[n].id = out->id;
270 data = parse_table_entry (data, &syms[n], &aux[n]);
271 }
272
273 assert(n < len);
274
275 out->nsyms = n;
276 out->syms = syms;
277 out->aux = aux;
278 }
279
280 /* Free all memory that is no longer needed after writing the symbol
281 resolution. */
282
283 static void
284 free_1 (void)
285 {
286 unsigned int i;
287 for (i = 0; i < num_claimed_files; i++)
288 {
289 struct plugin_file_info *info = &claimed_files[i];
290 struct plugin_symtab *symtab = &info->symtab;
291 unsigned int j;
292 for (j = 0; j < symtab->nsyms; j++)
293 {
294 struct ld_plugin_symbol *s = &symtab->syms[j];
295 free (s->name);
296 if (s->comdat_key)
297 free (s->comdat_key);
298 }
299 free (symtab->syms);
300 symtab->syms = NULL;
301 }
302 }
303
304 /* Free all remaining memory. */
305
306 static void
307 free_2 (void)
308 {
309 unsigned int i;
310 for (i = 0; i < num_claimed_files; i++)
311 {
312 struct plugin_file_info *info = &claimed_files[i];
313 struct plugin_symtab *symtab = &info->symtab;
314 free (symtab->aux);
315 free (info->name);
316 }
317
318 for (i = 0; i < num_output_files; i++)
319 free (output_files[i]);
320 free (output_files);
321
322 free (claimed_files);
323 claimed_files = NULL;
324 num_claimed_files = 0;
325
326 if (arguments_file_name)
327 free (arguments_file_name);
328 arguments_file_name = NULL;
329 }
330
331 /* Dump SYMTAB to resolution file F. */
332
333 static void
334 dump_symtab (FILE *f, struct plugin_symtab *symtab)
335 {
336 unsigned j;
337
338 for (j = 0; j < symtab->nsyms; j++)
339 {
340 uint32_t slot = symtab->aux[j].slot;
341 unsigned int resolution = symtab->syms[j].resolution;
342
343 assert (resolution != LDPR_UNKNOWN);
344
345 fprintf (f, "%u %x %s %s\n", (unsigned int) slot, symtab->aux[j].id,
346 lto_resolution_str[resolution],
347 symtab->syms[j].name);
348 }
349 }
350
351 /* Finish the conflicts' resolution information after the linker resolved
352 the original symbols */
353
354 static void
355 finish_conflict_resolution (struct plugin_symtab *symtab,
356 struct plugin_symtab *conflicts)
357 {
358 int i, j;
359
360 if (conflicts->nsyms == 0)
361 return;
362
363 for (i = 0; i < symtab->nsyms; i++)
364 {
365 int resolution = LDPR_UNKNOWN;
366
367 if (symtab->aux[i].next_conflict == -1)
368 continue;
369
370 switch (symtab->syms[i].def)
371 {
372 case LDPK_DEF:
373 case LDPK_COMMON: /* ??? */
374 resolution = LDPR_RESOLVED_IR;
375 break;
376 case LDPK_WEAKDEF:
377 resolution = LDPR_PREEMPTED_IR;
378 break;
379 case LDPK_UNDEF:
380 case LDPK_WEAKUNDEF:
381 resolution = symtab->syms[i].resolution;
382 break;
383 default:
384 assert (0);
385 }
386
387 assert (resolution != LDPR_UNKNOWN);
388
389 for (j = symtab->aux[i].next_conflict;
390 j != -1;
391 j = conflicts->aux[j].next_conflict)
392 conflicts->syms[j].resolution = resolution;
393 }
394 }
395
396 /* Free symbol table SYMTAB. */
397
398 static void
399 free_symtab (struct plugin_symtab *symtab)
400 {
401 free (symtab->syms);
402 symtab->syms = NULL;
403 free (symtab->aux);
404 symtab->aux = NULL;
405 }
406
407 /* Writes the relocations to disk. */
408
409 static void
410 write_resolution (void)
411 {
412 unsigned int i;
413 FILE *f;
414
415 check (resolution_file, LDPL_FATAL, "resolution file not specified");
416 f = fopen (resolution_file, "w");
417 check (f, LDPL_FATAL, "could not open file");
418
419 fprintf (f, "%d\n", num_claimed_files);
420
421 for (i = 0; i < num_claimed_files; i++)
422 {
423 struct plugin_file_info *info = &claimed_files[i];
424 struct plugin_symtab *symtab = &info->symtab;
425 struct ld_plugin_symbol *syms = symtab->syms;
426
427 get_symbols (info->handle, symtab->nsyms, syms);
428
429 finish_conflict_resolution (symtab, &info->conflicts);
430
431 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
432 dump_symtab (f, symtab);
433 if (info->conflicts.nsyms)
434 {
435 dump_symtab (f, &info->conflicts);
436 free_symtab (&info->conflicts);
437 }
438 }
439 fclose (f);
440 }
441
442 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
443 stdout. */
444
445 static void
446 add_output_files (FILE *f)
447 {
448 for (;;)
449 {
450 const unsigned piece = 32;
451 char *buf, *s = xmalloc (piece);
452 size_t len;
453
454 buf = s;
455 cont:
456 if (!fgets (buf, piece, f))
457 break;
458 len = strlen (s);
459 if (s[len - 1] != '\n')
460 {
461 s = xrealloc (s, len + piece);
462 buf = s + len;
463 goto cont;
464 }
465 s[len - 1] = '\0';
466
467 num_output_files++;
468 output_files
469 = xrealloc (output_files, num_output_files * sizeof (char *));
470 output_files[num_output_files - 1] = s;
471 add_input_file (output_files[num_output_files - 1]);
472 }
473 }
474
475 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
476 argument list. */
477
478 static void
479 exec_lto_wrapper (char *argv[])
480 {
481 int t, i;
482 int status;
483 char *at_args;
484 FILE *args;
485 FILE *wrapper_output;
486 char *new_argv[3];
487 struct pex_obj *pex;
488 const char *errmsg;
489
490 /* Write argv to a file to avoid a command line that is too long. */
491 arguments_file_name = make_temp_file ("");
492 check (arguments_file_name, LDPL_FATAL,
493 "Failed to generate a temorary file name");
494
495 args = fopen (arguments_file_name, "w");
496 check (args, LDPL_FATAL, "could not open arguments file");
497
498 t = writeargv (&argv[1], args);
499 check (t == 0, LDPL_FATAL, "could not write arguments");
500 t = fclose (args);
501 check (t == 0, LDPL_FATAL, "could not close arguments file");
502
503 at_args = concat ("@", arguments_file_name, NULL);
504 check (at_args, LDPL_FATAL, "could not allocate");
505
506 for (i = 1; argv[i]; i++)
507 {
508 char *a = argv[i];
509 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
510 {
511 for (i = 0; argv[i]; i++)
512 fprintf (stderr, "%s ", argv[i]);
513 fprintf (stderr, "\n");
514 break;
515 }
516 }
517
518 new_argv[0] = argv[0];
519 new_argv[1] = at_args;
520 new_argv[2] = NULL;
521
522 if (debug)
523 {
524 for (i = 0; new_argv[i]; i++)
525 fprintf (stderr, "%s ", new_argv[i]);
526 fprintf (stderr, "\n");
527 }
528
529
530 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
531 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
532
533 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
534 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
535 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
536
537 wrapper_output = pex_read_output (pex, 0);
538 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
539
540 add_output_files (wrapper_output);
541
542 t = pex_get_status (pex, 1, &status);
543 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
544 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
545 "lto-wrapper failed");
546
547 pex_free (pex);
548
549 free (at_args);
550 }
551
552 /* Pass the original files back to the linker. */
553
554 static void
555 use_original_files (void)
556 {
557 unsigned i;
558 for (i = 0; i < num_claimed_files; i++)
559 {
560 struct plugin_file_info *info = &claimed_files[i];
561 add_input_file (info->name);
562 }
563 }
564
565
566 /* Called by the linker once all symbols have been read. */
567
568 static enum ld_plugin_status
569 all_symbols_read_handler (void)
570 {
571 unsigned i;
572 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
573 char **lto_argv;
574 const char **lto_arg_ptr;
575 if (num_claimed_files == 0)
576 return LDPS_OK;
577
578 if (nop)
579 {
580 use_original_files ();
581 return LDPS_OK;
582 }
583
584 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
585 lto_arg_ptr = (const char **) lto_argv;
586 assert (lto_wrapper_argv);
587
588 write_resolution ();
589
590 free_1 ();
591
592 for (i = 0; i < lto_wrapper_num_args; i++)
593 *lto_arg_ptr++ = lto_wrapper_argv[i];
594
595 for (i = 0; i < num_claimed_files; i++)
596 {
597 struct plugin_file_info *info = &claimed_files[i];
598
599 *lto_arg_ptr++ = info->name;
600 }
601
602 *lto_arg_ptr++ = NULL;
603 exec_lto_wrapper (lto_argv);
604
605 free (lto_argv);
606
607 if (pass_through_items)
608 {
609 unsigned int i;
610 for (i = 0; i < num_pass_through_items; i++)
611 {
612 if (strncmp (pass_through_items[i], "-l", 2) == 0)
613 add_input_library (pass_through_items[i] + 2);
614 else
615 add_input_file (pass_through_items[i]);
616 free (pass_through_items[i]);
617 pass_through_items[i] = NULL;
618 }
619 free (pass_through_items);
620 pass_through_items = NULL;
621 }
622
623 return LDPS_OK;
624 }
625
626 /* Remove temporary files at the end of the link. */
627
628 static enum ld_plugin_status
629 cleanup_handler (void)
630 {
631 unsigned int i;
632 int t;
633
634 if (debug)
635 return LDPS_OK;
636
637 if (arguments_file_name)
638 {
639 t = unlink (arguments_file_name);
640 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
641 }
642
643 for (i = 0; i < num_output_files; i++)
644 {
645 t = unlink (output_files[i]);
646 check (t == 0, LDPL_FATAL, "could not unlink output file");
647 }
648
649 free_2 ();
650 return LDPS_OK;
651 }
652
653 #define SWAP(type, a, b) \
654 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
655
656 /* Compare two hash table entries */
657
658 static int eq_sym (const void *a, const void *b)
659 {
660 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
661 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
662
663 return !strcmp (as->name, bs->name);
664 }
665
666 /* Hash a symbol */
667
668 static hashval_t hash_sym (const void *a)
669 {
670 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
671
672 return htab_hash_string (as->name);
673 }
674
675 /* Determine how strong a symbol is */
676
677 static int symbol_strength (struct ld_plugin_symbol *s)
678 {
679 switch (s->def)
680 {
681 case LDPK_UNDEF:
682 case LDPK_WEAKUNDEF:
683 return 0;
684 case LDPK_WEAKDEF:
685 return 1;
686 default:
687 return 2;
688 }
689 }
690
691 /* In the ld -r case we can get dups in the LTO symbol tables, where
692 the same symbol can have different resolutions (e.g. undefined and defined).
693
694 We have to keep that in the LTO symbol tables, but the dups confuse
695 gold and then finally gcc by supplying incorrect resolutions.
696
697 Problem is that the main gold symbol table doesn't know about subids
698 and does not distingush the same symbols in different states.
699
700 So we drop duplicates from the linker visible symbol table
701 and keep them in a private table. Then later do own symbol
702 resolution for the duplicated based on the results for the
703 originals.
704
705 Then when writing out the resolution file readd the dropped symbols.
706
707 XXX how to handle common? */
708
709 static void
710 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
711 {
712 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
713 int i;
714 int out;
715 int outlen;
716
717 outlen = t->nsyms;
718 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
719 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
720
721 /* Move all duplicate symbols into the auxillary conflicts table. */
722 out = 0;
723 for (i = 0; i < t->nsyms; i++)
724 {
725 struct ld_plugin_symbol *s = &t->syms[i];
726 struct sym_aux *aux = &t->aux[i];
727 void **slot;
728
729 slot = htab_find_slot (symtab, s, INSERT);
730 if (*slot != NULL)
731 {
732 int cnf;
733 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
734 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
735
736 /* Always let the linker resolve the strongest symbol */
737 if (symbol_strength (orig) < symbol_strength (s))
738 {
739 SWAP (struct ld_plugin_symbol, *orig, *s);
740 SWAP (uint32_t, orig_aux->slot, aux->slot);
741 SWAP (unsigned, orig_aux->id, aux->id);
742 /* Don't swap conflict chain pointer */
743 }
744
745 /* Move current symbol into the conflicts table */
746 cnf = conflicts->nsyms++;
747 conflicts->syms[cnf] = *s;
748 conflicts->aux[cnf] = *aux;
749 aux = &conflicts->aux[cnf];
750
751 /* Update conflicts chain of the original symbol */
752 aux->next_conflict = orig_aux->next_conflict;
753 orig_aux->next_conflict = cnf;
754
755 continue;
756 }
757
758 /* Remove previous duplicates in the main table */
759 if (out < i)
760 {
761 t->syms[out] = *s;
762 t->aux[out] = *aux;
763 }
764
765 /* Put original into the hash table */
766 *slot = &t->syms[out];
767 out++;
768 }
769
770 assert (conflicts->nsyms <= outlen);
771 assert (conflicts->nsyms + out == t->nsyms);
772
773 t->nsyms = out;
774 htab_delete (symtab);
775 }
776
777 /* Process one section of an object file. */
778
779 static int
780 process_symtab (void *data, const char *name, off_t offset, off_t length)
781 {
782 struct plugin_objfile *obj = (struct plugin_objfile *)data;
783 char *s;
784 char *secdata;
785
786 if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
787 return 1;
788
789 s = strrchr (name, '.');
790 if (s)
791 sscanf (s, ".%x", &obj->out->id);
792 secdata = xmalloc (length);
793 offset += obj->file->offset;
794 if (offset != lseek (obj->file->fd, offset, SEEK_SET)
795 || length != read (obj->file->fd, secdata, length))
796 {
797 if (message)
798 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
799 /* Force claim_file_handler to abandon this file. */
800 obj->found = 0;
801 free (secdata);
802 return 0;
803 }
804
805 translate (secdata, secdata + length, obj->out);
806 obj->found++;
807 free (secdata);
808 return 1;
809 }
810
811 /* Callback used by gold to check if the plugin will claim FILE. Writes
812 the result in CLAIMED. */
813
814 static enum ld_plugin_status
815 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
816 {
817 enum ld_plugin_status status;
818 struct plugin_objfile obj;
819 struct plugin_file_info lto_file;
820 int err;
821 const char *errmsg;
822
823 memset (&lto_file, 0, sizeof (struct plugin_file_info));
824
825 if (file->offset != 0)
826 {
827 char *objname;
828 /* We pass the offset of the actual file, not the archive header. */
829 int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
830 (int64_t) file->offset);
831 check (t >= 0, LDPL_FATAL, "asprintf failed");
832 lto_file.name = objname;
833 }
834 else
835 {
836 lto_file.name = xstrdup (file->name);
837 }
838 lto_file.handle = file->handle;
839
840 *claimed = 0;
841 obj.file = file;
842 obj.found = 0;
843 obj.out = &lto_file.symtab;
844 errmsg = NULL;
845 obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
846 &errmsg, &err);
847 /* No file, but also no error code means unrecognized format; just skip it. */
848 if (!obj.objfile && !err)
849 goto err;
850
851 if (obj.objfile)
852 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
853
854 if (!obj.objfile || errmsg)
855 {
856 if (err && message)
857 message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
858 xstrerror (err));
859 else if (message)
860 message (LDPL_FATAL, "%s: %s", file->name, errmsg);
861 goto err;
862 }
863
864 if (obj.found == 0)
865 goto err;
866
867 if (obj.found > 1)
868 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
869
870 status = add_symbols (file->handle, lto_file.symtab.nsyms,
871 lto_file.symtab.syms);
872 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
873
874 *claimed = 1;
875 num_claimed_files++;
876 claimed_files =
877 xrealloc (claimed_files,
878 num_claimed_files * sizeof (struct plugin_file_info));
879 claimed_files[num_claimed_files - 1] = lto_file;
880
881 goto cleanup;
882
883 err:
884 free (lto_file.name);
885
886 cleanup:
887 if (obj.objfile)
888 simple_object_release_read (obj.objfile);
889
890 return LDPS_OK;
891 }
892
893 /* Parse the plugin options. */
894
895 static void
896 process_option (const char *option)
897 {
898 if (strcmp (option, "-debug") == 0)
899 debug = 1;
900 else if (strcmp (option, "-nop") == 0)
901 nop = 1;
902 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
903 {
904 num_pass_through_items++;
905 pass_through_items = xrealloc (pass_through_items,
906 num_pass_through_items * sizeof (char *));
907 pass_through_items[num_pass_through_items - 1] =
908 xstrdup (option + strlen ("-pass-through="));
909 }
910 else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
911 {
912 switch (option[sizeof ("-sym-style=") - 1])
913 {
914 case 'w':
915 sym_style = ss_win32;
916 break;
917 case 'u':
918 sym_style = ss_uscore;
919 break;
920 default:
921 sym_style = ss_none;
922 break;
923 }
924 }
925 else
926 {
927 int size;
928 char *opt = xstrdup (option);
929 lto_wrapper_num_args += 1;
930 size = lto_wrapper_num_args * sizeof (char *);
931 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
932 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
933 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
934 resolution_file = opt + sizeof ("-fresolution=") - 1;
935 }
936 }
937
938 /* Called by gold after loading the plugin. TV is the transfer vector. */
939
940 enum ld_plugin_status
941 onload (struct ld_plugin_tv *tv)
942 {
943 struct ld_plugin_tv *p;
944 enum ld_plugin_status status;
945
946 p = tv;
947 while (p->tv_tag)
948 {
949 switch (p->tv_tag)
950 {
951 case LDPT_MESSAGE:
952 message = p->tv_u.tv_message;
953 break;
954 case LDPT_REGISTER_CLAIM_FILE_HOOK:
955 register_claim_file = p->tv_u.tv_register_claim_file;
956 break;
957 case LDPT_ADD_SYMBOLS:
958 add_symbols = p->tv_u.tv_add_symbols;
959 break;
960 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
961 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
962 break;
963 case LDPT_GET_SYMBOLS:
964 get_symbols = p->tv_u.tv_get_symbols;
965 break;
966 case LDPT_REGISTER_CLEANUP_HOOK:
967 register_cleanup = p->tv_u.tv_register_cleanup;
968 break;
969 case LDPT_ADD_INPUT_FILE:
970 add_input_file = p->tv_u.tv_add_input_file;
971 break;
972 case LDPT_ADD_INPUT_LIBRARY:
973 add_input_library = p->tv_u.tv_add_input_library;
974 break;
975 case LDPT_OPTION:
976 process_option (p->tv_u.tv_string);
977 break;
978 default:
979 break;
980 }
981 p++;
982 }
983
984 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
985 check (add_symbols, LDPL_FATAL, "add_symbols not found");
986 status = register_claim_file (claim_file_handler);
987 check (status == LDPS_OK, LDPL_FATAL,
988 "could not register the claim_file callback");
989
990 if (register_cleanup)
991 {
992 status = register_cleanup (cleanup_handler);
993 check (status == LDPS_OK, LDPL_FATAL,
994 "could not register the cleanup callback");
995 }
996
997 if (register_all_symbols_read)
998 {
999 check (get_symbols, LDPL_FATAL, "get_symbols not found");
1000 status = register_all_symbols_read (all_symbols_read_handler);
1001 check (status == LDPS_OK, LDPL_FATAL,
1002 "could not register the all_symbols_read callback");
1003 }
1004
1005 return LDPS_OK;
1006 }