OSDN Git Service

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