OSDN Git Service

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