OSDN Git Service

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