OSDN Git Service

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