OSDN Git Service

ChangeLog:
[pf3gnuchains/gcc-fork.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   if (file->fd >= 0)
890     close (file->fd);
891
892   return LDPS_OK;
893 }
894
895 /* Parse the plugin options. */
896
897 static void
898 process_option (const char *option)
899 {
900   if (strcmp (option, "-debug") == 0)
901     debug = 1;
902   else if (strcmp (option, "-nop") == 0)
903     nop = 1;
904   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
905     {
906       num_pass_through_items++;
907       pass_through_items = xrealloc (pass_through_items,
908                                      num_pass_through_items * sizeof (char *));
909       pass_through_items[num_pass_through_items - 1] =
910           xstrdup (option + strlen ("-pass-through="));
911     }
912   else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
913     {
914       switch (option[sizeof ("-sym-style=") - 1])
915         {
916         case 'w':
917           sym_style = ss_win32;
918           break;
919         case 'u':
920           sym_style = ss_uscore;
921           break;
922         default:
923           sym_style = ss_none;
924           break;
925         }
926     }
927   else
928     {
929       int size;
930       char *opt = xstrdup (option);
931       lto_wrapper_num_args += 1;
932       size = lto_wrapper_num_args * sizeof (char *);
933       lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
934       lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
935       if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
936         resolution_file = opt + sizeof ("-fresolution=") - 1;
937     }
938 }
939
940 /* Called by gold after loading the plugin. TV is the transfer vector. */
941
942 enum ld_plugin_status
943 onload (struct ld_plugin_tv *tv)
944 {
945   struct ld_plugin_tv *p;
946   enum ld_plugin_status status;
947
948   p = tv;
949   while (p->tv_tag)
950     {
951       switch (p->tv_tag)
952         {
953         case LDPT_MESSAGE:
954           message = p->tv_u.tv_message;
955           break;
956         case LDPT_REGISTER_CLAIM_FILE_HOOK:
957           register_claim_file = p->tv_u.tv_register_claim_file;
958           break;
959         case LDPT_ADD_SYMBOLS:
960           add_symbols = p->tv_u.tv_add_symbols;
961           break;
962         case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
963           register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
964           break;
965         case LDPT_GET_SYMBOLS:
966           get_symbols = p->tv_u.tv_get_symbols;
967           break;
968         case LDPT_REGISTER_CLEANUP_HOOK:
969           register_cleanup = p->tv_u.tv_register_cleanup;
970           break;
971         case LDPT_ADD_INPUT_FILE:
972           add_input_file = p->tv_u.tv_add_input_file;
973           break;
974         case LDPT_ADD_INPUT_LIBRARY:
975           add_input_library = p->tv_u.tv_add_input_library;
976           break;
977         case LDPT_OPTION:
978           process_option (p->tv_u.tv_string);
979           break;
980         default:
981           break;
982         }
983       p++;
984     }
985
986   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
987   check (add_symbols, LDPL_FATAL, "add_symbols not found");
988   status = register_claim_file (claim_file_handler);
989   check (status == LDPS_OK, LDPL_FATAL,
990          "could not register the claim_file callback");
991
992   if (register_cleanup)
993     {
994       status = register_cleanup (cleanup_handler);
995       check (status == LDPS_OK, LDPL_FATAL,
996              "could not register the cleanup callback");
997     }
998
999   if (register_all_symbols_read)
1000     {
1001       check (get_symbols, LDPL_FATAL, "get_symbols not found");
1002       status = register_all_symbols_read (all_symbols_read_handler);
1003       check (status == LDPS_OK, LDPL_FATAL,
1004              "could not register the all_symbols_read callback");
1005     }
1006
1007   return LDPS_OK;
1008 }