OSDN Git Service

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