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