OSDN Git Service

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