OSDN Git Service

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