OSDN Git Service

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