2010-11-14 Paolo Bonzini <bonzini@gnu.org>
[official-gcc.git] / lto-plugin / lto-plugin.c
blobd2830283f6f52d83dd002bcc4ab93fca8cd99f5e
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).
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.
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.
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/>. */
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.
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.
27 More information at http://gcc.gnu.org/wiki/whopr/driver.
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. */
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38 #if HAVE_STDINT_H
39 #include <stdint.h>
40 #endif
41 #include <assert.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <inttypes.h>
46 #include <sys/stat.h>
47 #include <unistd.h>
48 #include <fcntl.h>
49 #include <sys/types.h>
50 #include <sys/wait.h>
51 #include <libiberty.h>
52 #include <hashtab.h>
53 #include "../gcc/lto/common.h"
54 #include "simple-object.h"
55 #include "plugin-api.h"
57 /* Handle opening elf files on hosts, such as Windows, that may use
58 text file handling that will break binary access. */
59 #ifndef O_BINARY
60 # define O_BINARY 0
61 #endif
63 /* Segment name for LTO sections. This is only used for Mach-O.
64 FIXME: This needs to be kept in sync with darwin.c. */
66 #define LTO_SEGMENT_NAME "__GNU_LTO"
68 /* LTO magic section name. */
70 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
71 #define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
73 /* The part of the symbol table the plugin has to keep track of. Note that we
74 must keep SYMS until all_symbols_read is called to give the linker time to
75 copy the symbol information. */
77 struct sym_aux
79 uint32_t slot;
80 unsigned id;
81 unsigned next_conflict;
84 struct plugin_symtab
86 int nsyms;
87 struct sym_aux *aux;
88 struct ld_plugin_symbol *syms;
89 unsigned id;
92 /* Encapsulates object file data during symbol scan. */
93 struct plugin_objfile
95 int found;
96 simple_object_read *objfile;
97 struct plugin_symtab *out;
98 const struct ld_plugin_input_file *file;
101 /* All that we have to remember about a file. */
103 struct plugin_file_info
105 char *name;
106 void *handle;
107 struct plugin_symtab symtab;
108 struct plugin_symtab conflicts;
111 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
112 stdio file streams, we do simple label translation here. */
114 enum symbol_style
116 ss_none, /* No underscore prefix. */
117 ss_win32, /* Underscore prefix any symbol not beginning with '@'. */
118 ss_uscore, /* Underscore prefix all symbols. */
121 static char *arguments_file_name;
122 static ld_plugin_register_claim_file register_claim_file;
123 static ld_plugin_register_all_symbols_read register_all_symbols_read;
124 static ld_plugin_get_symbols get_symbols;
125 static ld_plugin_register_cleanup register_cleanup;
126 static ld_plugin_add_input_file add_input_file;
127 static ld_plugin_add_input_library add_input_library;
128 static ld_plugin_message message;
129 static ld_plugin_add_symbols add_symbols;
131 static struct plugin_file_info *claimed_files = NULL;
132 static unsigned int num_claimed_files = 0;
134 static char **output_files = NULL;
135 static unsigned int num_output_files = 0;
137 static char **lto_wrapper_argv;
138 static int lto_wrapper_num_args;
140 static char **pass_through_items = NULL;
141 static unsigned int num_pass_through_items;
143 static char debug;
144 static char nop;
145 static char *resolution_file = NULL;
147 /* Set by default from configure.ac, but can be overridden at runtime
148 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
149 (in fact, only first letter of style arg is checked.) */
150 static enum symbol_style sym_style = SYM_STYLE;
152 static void
153 check_1 (int gate, enum ld_plugin_level level, const char *text)
155 if (gate)
156 return;
158 if (message)
159 message (level, text);
160 else
162 /* If there is no nicer way to inform the user, fallback to stderr. */
163 fprintf (stderr, "%s\n", text);
164 if (level == LDPL_FATAL)
165 abort ();
169 /* This little wrapper allows check to be called with a non-integer
170 first argument, such as a pointer that must be non-NULL. We can't
171 use c99 bool type to coerce it into range, so we explicitly test. */
172 #define check(GATE, LEVEL, TEXT) check_1 (((GATE) != 0), (LEVEL), (TEXT))
174 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
175 by P and the result is written in ENTRY. The slot number is stored in SLOT.
176 Returns the address of the next entry. */
178 static char *
179 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
180 struct sym_aux *aux)
182 unsigned char t;
183 enum ld_plugin_symbol_kind translate_kind[] =
185 LDPK_DEF,
186 LDPK_WEAKDEF,
187 LDPK_UNDEF,
188 LDPK_WEAKUNDEF,
189 LDPK_COMMON
192 enum ld_plugin_symbol_visibility translate_visibility[] =
194 LDPV_DEFAULT,
195 LDPV_PROTECTED,
196 LDPV_INTERNAL,
197 LDPV_HIDDEN
200 switch (sym_style)
202 case ss_win32:
203 if (p[0] == '@')
205 /* cf. Duff's device. */
206 case ss_none:
207 entry->name = xstrdup (p);
208 break;
210 /* FALL-THROUGH. */
211 case ss_uscore:
212 entry->name = concat ("_", p, NULL);
213 break;
214 default:
215 check (0, LDPL_FATAL, "invalid symbol style requested");
216 break;
218 while (*p)
219 p++;
220 p++;
222 entry->version = NULL;
224 entry->comdat_key = p;
225 while (*p)
226 p++;
227 p++;
229 if (strlen (entry->comdat_key) == 0)
230 entry->comdat_key = NULL;
231 else
232 entry->comdat_key = xstrdup (entry->comdat_key);
234 t = *p;
235 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
236 entry->def = translate_kind[t];
237 p++;
239 t = *p;
240 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
241 entry->visibility = translate_visibility[t];
242 p++;
244 entry->size = *(uint64_t *) p;
245 p += 8;
247 aux->slot = *(uint32_t *) p;
248 p += 4;
250 entry->resolution = LDPR_UNKNOWN;
252 aux->next_conflict = -1;
254 return p;
257 /* Translate the IL symbol table located between DATA and END. Append the
258 slots and symbols to OUT. */
260 static void
261 translate (char *data, char *end, struct plugin_symtab *out)
263 struct sym_aux *aux;
264 struct ld_plugin_symbol *syms = NULL;
265 int n, len;
267 /* This overestimates the output buffer sizes, but at least
268 the algorithm is O(1) now. */
270 len = (end - data)/8 + out->nsyms + 1;
271 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
272 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
274 for (n = out->nsyms; data < end; n++)
276 aux[n].id = out->id;
277 data = parse_table_entry (data, &syms[n], &aux[n]);
280 assert(n < len);
282 out->nsyms = n;
283 out->syms = syms;
284 out->aux = aux;
287 /* Free all memory that is no longer needed after writing the symbol
288 resolution. */
290 static void
291 free_1 (void)
293 unsigned int i;
294 for (i = 0; i < num_claimed_files; i++)
296 struct plugin_file_info *info = &claimed_files[i];
297 struct plugin_symtab *symtab = &info->symtab;
298 unsigned int j;
299 for (j = 0; j < symtab->nsyms; j++)
301 struct ld_plugin_symbol *s = &symtab->syms[j];
302 free (s->name);
303 if (s->comdat_key)
304 free (s->comdat_key);
306 free (symtab->syms);
307 symtab->syms = NULL;
311 /* Free all remaining memory. */
313 static void
314 free_2 (void)
316 unsigned int i;
317 for (i = 0; i < num_claimed_files; i++)
319 struct plugin_file_info *info = &claimed_files[i];
320 struct plugin_symtab *symtab = &info->symtab;
321 free (symtab->aux);
322 free (info->name);
325 for (i = 0; i < num_output_files; i++)
326 free (output_files[i]);
327 free (output_files);
329 free (claimed_files);
330 claimed_files = NULL;
331 num_claimed_files = 0;
333 if (arguments_file_name)
334 free (arguments_file_name);
335 arguments_file_name = NULL;
338 /* Dump SYMTAB to resolution file F. */
340 static void
341 dump_symtab (FILE *f, struct plugin_symtab *symtab)
343 unsigned j;
345 for (j = 0; j < symtab->nsyms; j++)
347 uint32_t slot = symtab->aux[j].slot;
348 unsigned int resolution = symtab->syms[j].resolution;
350 assert (resolution != LDPR_UNKNOWN);
352 fprintf (f, "%u %x %s %s\n", (unsigned int) slot, symtab->aux[j].id,
353 lto_resolution_str[resolution],
354 symtab->syms[j].name);
358 /* Finish the conflicts' resolution information after the linker resolved
359 the original symbols */
361 static void
362 finish_conflict_resolution (struct plugin_symtab *symtab,
363 struct plugin_symtab *conflicts)
365 int i, j;
367 if (conflicts->nsyms == 0)
368 return;
370 for (i = 0; i < symtab->nsyms; i++)
372 int resolution = LDPR_UNKNOWN;
374 if (symtab->aux[i].next_conflict == -1)
375 continue;
377 switch (symtab->syms[i].def)
379 case LDPK_DEF:
380 case LDPK_COMMON: /* ??? */
381 resolution = LDPR_RESOLVED_IR;
382 break;
383 case LDPK_WEAKDEF:
384 resolution = LDPR_PREEMPTED_IR;
385 break;
386 case LDPK_UNDEF:
387 case LDPK_WEAKUNDEF:
388 resolution = symtab->syms[i].resolution;
389 break;
390 default:
391 assert (0);
394 assert (resolution != LDPR_UNKNOWN);
396 for (j = symtab->aux[i].next_conflict;
397 j != -1;
398 j = conflicts->aux[j].next_conflict)
399 conflicts->syms[j].resolution = resolution;
403 /* Free symbol table SYMTAB. */
405 static void
406 free_symtab (struct plugin_symtab *symtab)
408 free (symtab->syms);
409 symtab->syms = NULL;
410 free (symtab->aux);
411 symtab->aux = NULL;
414 /* Writes the relocations to disk. */
416 static void
417 write_resolution (void)
419 unsigned int i;
420 FILE *f;
422 check (resolution_file, LDPL_FATAL, "resolution file not specified");
423 f = fopen (resolution_file, "w");
424 check (f, LDPL_FATAL, "could not open file");
426 fprintf (f, "%d\n", num_claimed_files);
428 for (i = 0; i < num_claimed_files; i++)
430 struct plugin_file_info *info = &claimed_files[i];
431 struct plugin_symtab *symtab = &info->symtab;
432 struct ld_plugin_symbol *syms = symtab->syms;
434 get_symbols (info->handle, symtab->nsyms, syms);
436 finish_conflict_resolution (symtab, &info->conflicts);
438 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
439 dump_symtab (f, symtab);
440 if (info->conflicts.nsyms)
442 dump_symtab (f, &info->conflicts);
443 free_symtab (&info->conflicts);
446 fclose (f);
449 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
450 stdout. */
452 static void
453 add_output_files (FILE *f)
455 for (;;)
457 const unsigned piece = 32;
458 char *buf, *s = xmalloc (piece);
459 size_t len;
461 buf = s;
462 cont:
463 if (!fgets (buf, piece, f))
465 free (s);
466 break;
468 len = strlen (s);
469 if (s[len - 1] != '\n')
471 s = xrealloc (s, len + piece);
472 buf = s + len;
473 goto cont;
475 s[len - 1] = '\0';
477 num_output_files++;
478 output_files
479 = xrealloc (output_files, num_output_files * sizeof (char *));
480 output_files[num_output_files - 1] = s;
481 add_input_file (output_files[num_output_files - 1]);
485 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
486 argument list. */
488 static void
489 exec_lto_wrapper (char *argv[])
491 int t, i;
492 int status;
493 char *at_args;
494 FILE *args;
495 FILE *wrapper_output;
496 char *new_argv[3];
497 struct pex_obj *pex;
498 const char *errmsg;
500 /* Write argv to a file to avoid a command line that is too long. */
501 arguments_file_name = make_temp_file ("");
502 check (arguments_file_name, LDPL_FATAL,
503 "Failed to generate a temorary file name");
505 args = fopen (arguments_file_name, "w");
506 check (args, LDPL_FATAL, "could not open arguments file");
508 t = writeargv (&argv[1], args);
509 check (t == 0, LDPL_FATAL, "could not write arguments");
510 t = fclose (args);
511 check (t == 0, LDPL_FATAL, "could not close arguments file");
513 at_args = concat ("@", arguments_file_name, NULL);
514 check (at_args, LDPL_FATAL, "could not allocate");
516 for (i = 1; argv[i]; i++)
518 char *a = argv[i];
519 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
521 for (i = 0; argv[i]; i++)
522 fprintf (stderr, "%s ", argv[i]);
523 fprintf (stderr, "\n");
524 break;
528 new_argv[0] = argv[0];
529 new_argv[1] = at_args;
530 new_argv[2] = NULL;
532 if (debug)
534 for (i = 0; new_argv[i]; i++)
535 fprintf (stderr, "%s ", new_argv[i]);
536 fprintf (stderr, "\n");
540 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
541 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
543 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
544 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
545 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
547 wrapper_output = pex_read_output (pex, 0);
548 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
550 add_output_files (wrapper_output);
552 t = pex_get_status (pex, 1, &status);
553 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
554 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
555 "lto-wrapper failed");
557 pex_free (pex);
559 free (at_args);
562 /* Pass the original files back to the linker. */
564 static void
565 use_original_files (void)
567 unsigned i;
568 for (i = 0; i < num_claimed_files; i++)
570 struct plugin_file_info *info = &claimed_files[i];
571 add_input_file (info->name);
576 /* Called by the linker once all symbols have been read. */
578 static enum ld_plugin_status
579 all_symbols_read_handler (void)
581 unsigned i;
582 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
583 char **lto_argv;
584 const char **lto_arg_ptr;
585 if (num_claimed_files == 0)
586 return LDPS_OK;
588 if (nop)
590 use_original_files ();
591 return LDPS_OK;
594 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
595 lto_arg_ptr = (const char **) lto_argv;
596 assert (lto_wrapper_argv);
598 write_resolution ();
600 free_1 ();
602 for (i = 0; i < lto_wrapper_num_args; i++)
603 *lto_arg_ptr++ = lto_wrapper_argv[i];
605 for (i = 0; i < num_claimed_files; i++)
607 struct plugin_file_info *info = &claimed_files[i];
609 *lto_arg_ptr++ = info->name;
612 *lto_arg_ptr++ = NULL;
613 exec_lto_wrapper (lto_argv);
615 free (lto_argv);
617 if (pass_through_items)
619 unsigned int i;
620 for (i = 0; i < num_pass_through_items; i++)
622 if (strncmp (pass_through_items[i], "-l", 2) == 0)
623 add_input_library (pass_through_items[i] + 2);
624 else
625 add_input_file (pass_through_items[i]);
626 free (pass_through_items[i]);
627 pass_through_items[i] = NULL;
629 free (pass_through_items);
630 pass_through_items = NULL;
633 return LDPS_OK;
636 /* Remove temporary files at the end of the link. */
638 static enum ld_plugin_status
639 cleanup_handler (void)
641 unsigned int i;
642 int t;
644 if (debug)
645 return LDPS_OK;
647 if (arguments_file_name)
649 t = unlink (arguments_file_name);
650 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
653 for (i = 0; i < num_output_files; i++)
655 t = unlink (output_files[i]);
656 check (t == 0, LDPL_FATAL, "could not unlink output file");
659 free_2 ();
660 return LDPS_OK;
663 #define SWAP(type, a, b) \
664 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
666 /* Compare two hash table entries */
668 static int eq_sym (const void *a, const void *b)
670 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
671 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
673 return !strcmp (as->name, bs->name);
676 /* Hash a symbol */
678 static hashval_t hash_sym (const void *a)
680 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
682 return htab_hash_string (as->name);
685 /* Determine how strong a symbol is */
687 static int symbol_strength (struct ld_plugin_symbol *s)
689 switch (s->def)
691 case LDPK_UNDEF:
692 case LDPK_WEAKUNDEF:
693 return 0;
694 case LDPK_WEAKDEF:
695 return 1;
696 default:
697 return 2;
701 /* In the ld -r case we can get dups in the LTO symbol tables, where
702 the same symbol can have different resolutions (e.g. undefined and defined).
704 We have to keep that in the LTO symbol tables, but the dups confuse
705 gold and then finally gcc by supplying incorrect resolutions.
707 Problem is that the main gold symbol table doesn't know about subids
708 and does not distingush the same symbols in different states.
710 So we drop duplicates from the linker visible symbol table
711 and keep them in a private table. Then later do own symbol
712 resolution for the duplicated based on the results for the
713 originals.
715 Then when writing out the resolution file readd the dropped symbols.
717 XXX how to handle common? */
719 static void
720 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
722 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
723 int i;
724 int out;
725 int outlen;
727 outlen = t->nsyms;
728 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
729 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
731 /* Move all duplicate symbols into the auxillary conflicts table. */
732 out = 0;
733 for (i = 0; i < t->nsyms; i++)
735 struct ld_plugin_symbol *s = &t->syms[i];
736 struct sym_aux *aux = &t->aux[i];
737 void **slot;
739 slot = htab_find_slot (symtab, s, INSERT);
740 if (*slot != NULL)
742 int cnf;
743 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
744 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
746 /* Always let the linker resolve the strongest symbol */
747 if (symbol_strength (orig) < symbol_strength (s))
749 SWAP (struct ld_plugin_symbol, *orig, *s);
750 SWAP (uint32_t, orig_aux->slot, aux->slot);
751 SWAP (unsigned, orig_aux->id, aux->id);
752 /* Don't swap conflict chain pointer */
755 /* Move current symbol into the conflicts table */
756 cnf = conflicts->nsyms++;
757 conflicts->syms[cnf] = *s;
758 conflicts->aux[cnf] = *aux;
759 aux = &conflicts->aux[cnf];
761 /* Update conflicts chain of the original symbol */
762 aux->next_conflict = orig_aux->next_conflict;
763 orig_aux->next_conflict = cnf;
765 continue;
768 /* Remove previous duplicates in the main table */
769 if (out < i)
771 t->syms[out] = *s;
772 t->aux[out] = *aux;
775 /* Put original into the hash table */
776 *slot = &t->syms[out];
777 out++;
780 assert (conflicts->nsyms <= outlen);
781 assert (conflicts->nsyms + out == t->nsyms);
783 t->nsyms = out;
784 htab_delete (symtab);
787 /* Process one section of an object file. */
789 static int
790 process_symtab (void *data, const char *name, off_t offset, off_t length)
792 struct plugin_objfile *obj = (struct plugin_objfile *)data;
793 char *s;
794 char *secdata;
796 if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
797 return 1;
799 s = strrchr (name, '.');
800 if (s)
801 sscanf (s, ".%x", &obj->out->id);
802 secdata = xmalloc (length);
803 offset += obj->file->offset;
804 if (offset != lseek (obj->file->fd, offset, SEEK_SET)
805 || length != read (obj->file->fd, secdata, length))
807 if (message)
808 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
809 /* Force claim_file_handler to abandon this file. */
810 obj->found = 0;
811 free (secdata);
812 return 0;
815 translate (secdata, secdata + length, obj->out);
816 obj->found++;
817 free (secdata);
818 return 1;
821 /* Callback used by gold to check if the plugin will claim FILE. Writes
822 the result in CLAIMED. */
824 static enum ld_plugin_status
825 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
827 enum ld_plugin_status status;
828 struct plugin_objfile obj;
829 struct plugin_file_info lto_file;
830 int err;
831 const char *errmsg;
833 memset (&lto_file, 0, sizeof (struct plugin_file_info));
835 if (file->offset != 0)
837 char *objname;
838 /* We pass the offset of the actual file, not the archive header.
839 Can't use PRIx64, because that's C99, so we have to print the
840 64-bit hex int as two 32-bit ones. */
841 int lo, hi;
842 lo = file->offset & 0xffffffff;
843 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
844 int t = hi ? asprintf (&objname, "%s@0x%x%08x", file->name, lo, hi)
845 : asprintf (&objname, "%s@0x%x", file->name, lo);
846 check (t >= 0, LDPL_FATAL, "asprintf failed");
847 lto_file.name = objname;
849 else
851 lto_file.name = xstrdup (file->name);
853 lto_file.handle = file->handle;
855 *claimed = 0;
856 obj.file = file;
857 obj.found = 0;
858 obj.out = &lto_file.symtab;
859 errmsg = NULL;
860 obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
861 &errmsg, &err);
862 /* No file, but also no error code means unrecognized format; just skip it. */
863 if (!obj.objfile && !err)
864 goto err;
866 if (obj.objfile)
867 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
869 if (!obj.objfile || errmsg)
871 if (err && message)
872 message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
873 xstrerror (err));
874 else if (message)
875 message (LDPL_FATAL, "%s: %s", file->name, errmsg);
876 goto err;
879 if (obj.found == 0)
880 goto err;
882 if (obj.found > 1)
883 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
885 status = add_symbols (file->handle, lto_file.symtab.nsyms,
886 lto_file.symtab.syms);
887 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
889 *claimed = 1;
890 num_claimed_files++;
891 claimed_files =
892 xrealloc (claimed_files,
893 num_claimed_files * sizeof (struct plugin_file_info));
894 claimed_files[num_claimed_files - 1] = lto_file;
896 goto cleanup;
898 err:
899 free (lto_file.name);
901 cleanup:
902 if (obj.objfile)
903 simple_object_release_read (obj.objfile);
905 return LDPS_OK;
908 /* Parse the plugin options. */
910 static void
911 process_option (const char *option)
913 if (strcmp (option, "-debug") == 0)
914 debug = 1;
915 else if (strcmp (option, "-nop") == 0)
916 nop = 1;
917 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
919 num_pass_through_items++;
920 pass_through_items = xrealloc (pass_through_items,
921 num_pass_through_items * sizeof (char *));
922 pass_through_items[num_pass_through_items - 1] =
923 xstrdup (option + strlen ("-pass-through="));
925 else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
927 switch (option[sizeof ("-sym-style=") - 1])
929 case 'w':
930 sym_style = ss_win32;
931 break;
932 case 'u':
933 sym_style = ss_uscore;
934 break;
935 default:
936 sym_style = ss_none;
937 break;
940 else
942 int size;
943 char *opt = xstrdup (option);
944 lto_wrapper_num_args += 1;
945 size = lto_wrapper_num_args * sizeof (char *);
946 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
947 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
948 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
949 resolution_file = opt + sizeof ("-fresolution=") - 1;
953 /* Called by gold after loading the plugin. TV is the transfer vector. */
955 enum ld_plugin_status
956 onload (struct ld_plugin_tv *tv)
958 struct ld_plugin_tv *p;
959 enum ld_plugin_status status;
961 p = tv;
962 while (p->tv_tag)
964 switch (p->tv_tag)
966 case LDPT_MESSAGE:
967 message = p->tv_u.tv_message;
968 break;
969 case LDPT_REGISTER_CLAIM_FILE_HOOK:
970 register_claim_file = p->tv_u.tv_register_claim_file;
971 break;
972 case LDPT_ADD_SYMBOLS:
973 add_symbols = p->tv_u.tv_add_symbols;
974 break;
975 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
976 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
977 break;
978 case LDPT_GET_SYMBOLS:
979 get_symbols = p->tv_u.tv_get_symbols;
980 break;
981 case LDPT_REGISTER_CLEANUP_HOOK:
982 register_cleanup = p->tv_u.tv_register_cleanup;
983 break;
984 case LDPT_ADD_INPUT_FILE:
985 add_input_file = p->tv_u.tv_add_input_file;
986 break;
987 case LDPT_ADD_INPUT_LIBRARY:
988 add_input_library = p->tv_u.tv_add_input_library;
989 break;
990 case LDPT_OPTION:
991 process_option (p->tv_u.tv_string);
992 break;
993 default:
994 break;
996 p++;
999 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1000 check (add_symbols, LDPL_FATAL, "add_symbols not found");
1001 status = register_claim_file (claim_file_handler);
1002 check (status == LDPS_OK, LDPL_FATAL,
1003 "could not register the claim_file callback");
1005 if (register_cleanup)
1007 status = register_cleanup (cleanup_handler);
1008 check (status == LDPS_OK, LDPL_FATAL,
1009 "could not register the cleanup callback");
1012 if (register_all_symbols_read)
1014 check (get_symbols, LDPL_FATAL, "get_symbols not found");
1015 status = register_all_symbols_read (all_symbols_read_handler);
1016 check (status == LDPS_OK, LDPL_FATAL,
1017 "could not register the all_symbols_read callback");
1020 return LDPS_OK;