2012-11-04 Janus Weil <janus@gcc.gnu.org>
[official-gcc.git] / lto-plugin / lto-plugin.c
blob6f31ed273842f1f1cbd01f09150e1123f393aca6
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 #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"
65 /* We need to use I64 instead of ll width-specifier on native Windows.
66 The reason for this is that older MS-runtimes don't support the ll. */
67 #ifdef __MINGW32__
68 #define PRI_LL "I64"
69 #else
70 #define PRI_LL "ll"
71 #endif
73 /* Handle opening elf files on hosts, such as Windows, that may use
74 text file handling that will break binary access. */
75 #ifndef O_BINARY
76 # define O_BINARY 0
77 #endif
79 /* Segment name for LTO sections. This is only used for Mach-O.
80 FIXME: This needs to be kept in sync with darwin.c. */
82 #define LTO_SEGMENT_NAME "__GNU_LTO"
84 /* LTO magic section name. */
86 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
87 #define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
89 /* The part of the symbol table the plugin has to keep track of. Note that we
90 must keep SYMS until all_symbols_read is called to give the linker time to
91 copy the symbol information.
92 The id must be 64bit to minimze collisions. */
94 struct sym_aux
96 uint32_t slot;
97 unsigned long long id;
98 unsigned next_conflict;
101 struct plugin_symtab
103 int nsyms;
104 struct sym_aux *aux;
105 struct ld_plugin_symbol *syms;
106 unsigned long long id;
109 /* Encapsulates object file data during symbol scan. */
110 struct plugin_objfile
112 int found;
113 simple_object_read *objfile;
114 struct plugin_symtab *out;
115 const struct ld_plugin_input_file *file;
118 /* All that we have to remember about a file. */
120 struct plugin_file_info
122 char *name;
123 void *handle;
124 struct plugin_symtab symtab;
125 struct plugin_symtab conflicts;
128 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
129 stdio file streams, we do simple label translation here. */
131 enum symbol_style
133 ss_none, /* No underscore prefix. */
134 ss_win32, /* Underscore prefix any symbol not beginning with '@'. */
135 ss_uscore, /* Underscore prefix all symbols. */
138 static char *arguments_file_name;
139 static ld_plugin_register_claim_file register_claim_file;
140 static ld_plugin_register_all_symbols_read register_all_symbols_read;
141 static ld_plugin_get_symbols get_symbols, get_symbols_v2;
142 static ld_plugin_register_cleanup register_cleanup;
143 static ld_plugin_add_input_file add_input_file;
144 static ld_plugin_add_input_library add_input_library;
145 static ld_plugin_message message;
146 static ld_plugin_add_symbols add_symbols;
148 static struct plugin_file_info *claimed_files = NULL;
149 static unsigned int num_claimed_files = 0;
151 static char **output_files = NULL;
152 static unsigned int num_output_files = 0;
154 static char **lto_wrapper_argv;
155 static int lto_wrapper_num_args;
157 static char **pass_through_items = NULL;
158 static unsigned int num_pass_through_items;
160 static char debug;
161 static char nop;
162 static char *resolution_file = NULL;
164 /* The version of gold being used, or -1 if not gold. The number is
165 MAJOR * 100 + MINOR. */
166 static int gold_version = -1;
168 /* Not used by default, but can be overridden at runtime
169 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
170 (in fact, only first letter of style arg is checked.) */
171 static enum symbol_style sym_style = ss_none;
173 static void
174 check_1 (int gate, enum ld_plugin_level level, const char *text)
176 if (gate)
177 return;
179 if (message)
180 message (level, text);
181 else
183 /* If there is no nicer way to inform the user, fallback to stderr. */
184 fprintf (stderr, "%s\n", text);
185 if (level == LDPL_FATAL)
186 abort ();
190 /* This little wrapper allows check to be called with a non-integer
191 first argument, such as a pointer that must be non-NULL. We can't
192 use c99 bool type to coerce it into range, so we explicitly test. */
193 #define check(GATE, LEVEL, TEXT) check_1 (((GATE) != 0), (LEVEL), (TEXT))
195 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
196 by P and the result is written in ENTRY. The slot number is stored in SLOT.
197 Returns the address of the next entry. */
199 static char *
200 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
201 struct sym_aux *aux)
203 unsigned char t;
204 enum ld_plugin_symbol_kind translate_kind[] =
206 LDPK_DEF,
207 LDPK_WEAKDEF,
208 LDPK_UNDEF,
209 LDPK_WEAKUNDEF,
210 LDPK_COMMON
213 enum ld_plugin_symbol_visibility translate_visibility[] =
215 LDPV_DEFAULT,
216 LDPV_PROTECTED,
217 LDPV_INTERNAL,
218 LDPV_HIDDEN
221 switch (sym_style)
223 case ss_win32:
224 if (p[0] == '@')
226 /* cf. Duff's device. */
227 case ss_none:
228 entry->name = xstrdup (p);
229 break;
231 /* FALL-THROUGH. */
232 case ss_uscore:
233 entry->name = concat ("_", p, NULL);
234 break;
235 default:
236 check (0, LDPL_FATAL, "invalid symbol style requested");
237 break;
239 while (*p)
240 p++;
241 p++;
243 entry->version = NULL;
245 entry->comdat_key = p;
246 while (*p)
247 p++;
248 p++;
250 if (strlen (entry->comdat_key) == 0)
251 entry->comdat_key = NULL;
252 else
253 entry->comdat_key = xstrdup (entry->comdat_key);
255 t = *p;
256 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
257 entry->def = translate_kind[t];
258 p++;
260 t = *p;
261 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
262 entry->visibility = translate_visibility[t];
263 p++;
265 memcpy (&entry->size, p, sizeof (uint64_t));
266 p += 8;
268 memcpy (&aux->slot, p, sizeof (uint32_t));
269 p += 4;
271 entry->resolution = LDPR_UNKNOWN;
273 aux->next_conflict = -1;
275 return p;
278 /* Translate the IL symbol table located between DATA and END. Append the
279 slots and symbols to OUT. */
281 static void
282 translate (char *data, char *end, struct plugin_symtab *out)
284 struct sym_aux *aux;
285 struct ld_plugin_symbol *syms = NULL;
286 int n, len;
288 /* This overestimates the output buffer sizes, but at least
289 the algorithm is O(1) now. */
291 len = (end - data)/8 + out->nsyms + 1;
292 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
293 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
295 for (n = out->nsyms; data < end; n++)
297 aux[n].id = out->id;
298 data = parse_table_entry (data, &syms[n], &aux[n]);
301 assert(n < len);
303 out->nsyms = n;
304 out->syms = syms;
305 out->aux = aux;
308 /* Free all memory that is no longer needed after writing the symbol
309 resolution. */
311 static void
312 free_1 (void)
314 unsigned int i;
315 for (i = 0; i < num_claimed_files; i++)
317 struct plugin_file_info *info = &claimed_files[i];
318 struct plugin_symtab *symtab = &info->symtab;
319 unsigned int j;
320 for (j = 0; j < symtab->nsyms; j++)
322 struct ld_plugin_symbol *s = &symtab->syms[j];
323 free (s->name);
324 free (s->comdat_key);
326 free (symtab->syms);
327 symtab->syms = NULL;
331 /* Free all remaining memory. */
333 static void
334 free_2 (void)
336 unsigned int i;
337 for (i = 0; i < num_claimed_files; i++)
339 struct plugin_file_info *info = &claimed_files[i];
340 struct plugin_symtab *symtab = &info->symtab;
341 free (symtab->aux);
342 free (info->name);
345 for (i = 0; i < num_output_files; i++)
346 free (output_files[i]);
347 free (output_files);
349 free (claimed_files);
350 claimed_files = NULL;
351 num_claimed_files = 0;
353 free (arguments_file_name);
354 arguments_file_name = NULL;
357 /* Dump SYMTAB to resolution file F. */
359 static void
360 dump_symtab (FILE *f, struct plugin_symtab *symtab)
362 unsigned j;
364 for (j = 0; j < symtab->nsyms; j++)
366 uint32_t slot = symtab->aux[j].slot;
367 unsigned int resolution = symtab->syms[j].resolution;
369 assert (resolution != LDPR_UNKNOWN);
371 fprintf (f, "%u %" PRI_LL "x %s %s\n",
372 (unsigned int) slot, symtab->aux[j].id,
373 lto_resolution_str[resolution],
374 symtab->syms[j].name);
378 /* Finish the conflicts' resolution information after the linker resolved
379 the original symbols */
381 static void
382 finish_conflict_resolution (struct plugin_symtab *symtab,
383 struct plugin_symtab *conflicts)
385 int i, j;
387 if (conflicts->nsyms == 0)
388 return;
390 for (i = 0; i < symtab->nsyms; i++)
392 int resolution = LDPR_UNKNOWN;
394 if (symtab->aux[i].next_conflict == -1)
395 continue;
397 switch (symtab->syms[i].def)
399 case LDPK_DEF:
400 case LDPK_COMMON: /* ??? */
401 resolution = LDPR_RESOLVED_IR;
402 break;
403 case LDPK_WEAKDEF:
404 resolution = LDPR_PREEMPTED_IR;
405 break;
406 case LDPK_UNDEF:
407 case LDPK_WEAKUNDEF:
408 resolution = symtab->syms[i].resolution;
409 break;
410 default:
411 assert (0);
414 assert (resolution != LDPR_UNKNOWN);
416 for (j = symtab->aux[i].next_conflict;
417 j != -1;
418 j = conflicts->aux[j].next_conflict)
419 conflicts->syms[j].resolution = resolution;
423 /* Free symbol table SYMTAB. */
425 static void
426 free_symtab (struct plugin_symtab *symtab)
428 free (symtab->syms);
429 symtab->syms = NULL;
430 free (symtab->aux);
431 symtab->aux = NULL;
434 /* Writes the relocations to disk. */
436 static void
437 write_resolution (void)
439 unsigned int i;
440 FILE *f;
442 check (resolution_file, LDPL_FATAL, "resolution file not specified");
443 f = fopen (resolution_file, "w");
444 check (f, LDPL_FATAL, "could not open file");
446 fprintf (f, "%d\n", num_claimed_files);
448 for (i = 0; i < num_claimed_files; i++)
450 struct plugin_file_info *info = &claimed_files[i];
451 struct plugin_symtab *symtab = &info->symtab;
452 struct ld_plugin_symbol *syms = symtab->syms;
454 /* Version 2 of API supports IRONLY_EXP resolution that is
455 accepted by GCC-4.7 and newer. */
456 if (get_symbols_v2)
457 get_symbols_v2 (info->handle, symtab->nsyms, syms);
458 else
459 get_symbols (info->handle, symtab->nsyms, syms);
461 finish_conflict_resolution (symtab, &info->conflicts);
463 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
464 dump_symtab (f, symtab);
465 if (info->conflicts.nsyms)
467 dump_symtab (f, &info->conflicts);
468 free_symtab (&info->conflicts);
471 fclose (f);
474 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
475 stdout. */
477 static void
478 add_output_files (FILE *f)
480 for (;;)
482 const unsigned piece = 32;
483 char *buf, *s = xmalloc (piece);
484 size_t len;
486 buf = s;
487 cont:
488 if (!fgets (buf, piece, f))
490 free (s);
491 break;
493 len = strlen (s);
494 if (s[len - 1] != '\n')
496 s = xrealloc (s, len + piece);
497 buf = s + len;
498 goto cont;
500 s[len - 1] = '\0';
502 num_output_files++;
503 output_files
504 = xrealloc (output_files, num_output_files * sizeof (char *));
505 output_files[num_output_files - 1] = s;
506 add_input_file (output_files[num_output_files - 1]);
510 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
511 argument list. */
513 static void
514 exec_lto_wrapper (char *argv[])
516 int t, i;
517 int status;
518 char *at_args;
519 FILE *args;
520 FILE *wrapper_output;
521 char *new_argv[3];
522 struct pex_obj *pex;
523 const char *errmsg;
525 /* Write argv to a file to avoid a command line that is too long. */
526 arguments_file_name = make_temp_file ("");
527 check (arguments_file_name, LDPL_FATAL,
528 "Failed to generate a temorary file name");
530 args = fopen (arguments_file_name, "w");
531 check (args, LDPL_FATAL, "could not open arguments file");
533 t = writeargv (&argv[1], args);
534 check (t == 0, LDPL_FATAL, "could not write arguments");
535 t = fclose (args);
536 check (t == 0, LDPL_FATAL, "could not close arguments file");
538 at_args = concat ("@", arguments_file_name, NULL);
539 check (at_args, LDPL_FATAL, "could not allocate");
541 for (i = 1; argv[i]; i++)
543 char *a = argv[i];
544 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
546 for (i = 0; argv[i]; i++)
547 fprintf (stderr, "%s ", argv[i]);
548 fprintf (stderr, "\n");
549 break;
553 new_argv[0] = argv[0];
554 new_argv[1] = at_args;
555 new_argv[2] = NULL;
557 if (debug)
559 for (i = 0; new_argv[i]; i++)
560 fprintf (stderr, "%s ", new_argv[i]);
561 fprintf (stderr, "\n");
565 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
566 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
568 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
569 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
570 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
572 wrapper_output = pex_read_output (pex, 0);
573 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
575 add_output_files (wrapper_output);
577 t = pex_get_status (pex, 1, &status);
578 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
579 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
580 "lto-wrapper failed");
582 pex_free (pex);
584 free (at_args);
587 /* Pass the original files back to the linker. */
589 static void
590 use_original_files (void)
592 unsigned i;
593 for (i = 0; i < num_claimed_files; i++)
595 struct plugin_file_info *info = &claimed_files[i];
596 add_input_file (info->name);
601 /* Called by the linker once all symbols have been read. */
603 static enum ld_plugin_status
604 all_symbols_read_handler (void)
606 unsigned i;
607 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
608 char **lto_argv;
609 const char **lto_arg_ptr;
610 if (num_claimed_files == 0)
611 return LDPS_OK;
613 if (nop)
615 use_original_files ();
616 return LDPS_OK;
619 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
620 lto_arg_ptr = (const char **) lto_argv;
621 assert (lto_wrapper_argv);
623 write_resolution ();
625 free_1 ();
627 for (i = 0; i < lto_wrapper_num_args; i++)
628 *lto_arg_ptr++ = lto_wrapper_argv[i];
630 for (i = 0; i < num_claimed_files; i++)
632 struct plugin_file_info *info = &claimed_files[i];
634 *lto_arg_ptr++ = info->name;
637 *lto_arg_ptr++ = NULL;
638 exec_lto_wrapper (lto_argv);
640 free (lto_argv);
642 /* --pass-through is not needed when using gold 1.11 or later. */
643 if (pass_through_items && gold_version < 111)
645 unsigned int i;
646 for (i = 0; i < num_pass_through_items; i++)
648 if (strncmp (pass_through_items[i], "-l", 2) == 0)
649 add_input_library (pass_through_items[i] + 2);
650 else
651 add_input_file (pass_through_items[i]);
652 free (pass_through_items[i]);
653 pass_through_items[i] = NULL;
655 free (pass_through_items);
656 pass_through_items = NULL;
659 return LDPS_OK;
662 /* Remove temporary files at the end of the link. */
664 static enum ld_plugin_status
665 cleanup_handler (void)
667 unsigned int i;
668 int t;
670 if (debug)
671 return LDPS_OK;
673 if (arguments_file_name)
675 t = unlink (arguments_file_name);
676 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
679 for (i = 0; i < num_output_files; i++)
681 t = unlink (output_files[i]);
682 check (t == 0, LDPL_FATAL, "could not unlink output file");
685 free_2 ();
686 return LDPS_OK;
689 #define SWAP(type, a, b) \
690 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
692 /* Compare two hash table entries */
694 static int eq_sym (const void *a, const void *b)
696 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
697 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
699 return !strcmp (as->name, bs->name);
702 /* Hash a symbol */
704 static hashval_t hash_sym (const void *a)
706 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
708 return htab_hash_string (as->name);
711 /* Determine how strong a symbol is */
713 static int symbol_strength (struct ld_plugin_symbol *s)
715 switch (s->def)
717 case LDPK_UNDEF:
718 case LDPK_WEAKUNDEF:
719 return 0;
720 case LDPK_WEAKDEF:
721 return 1;
722 default:
723 return 2;
727 /* In the ld -r case we can get dups in the LTO symbol tables, where
728 the same symbol can have different resolutions (e.g. undefined and defined).
730 We have to keep that in the LTO symbol tables, but the dups confuse
731 gold and then finally gcc by supplying incorrect resolutions.
733 Problem is that the main gold symbol table doesn't know about subids
734 and does not distingush the same symbols in different states.
736 So we drop duplicates from the linker visible symbol table
737 and keep them in a private table. Then later do own symbol
738 resolution for the duplicated based on the results for the
739 originals.
741 Then when writing out the resolution file readd the dropped symbols.
743 XXX how to handle common? */
745 static void
746 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
748 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
749 int i;
750 int out;
751 int outlen;
753 outlen = t->nsyms;
754 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
755 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
757 /* Move all duplicate symbols into the auxiliary conflicts table. */
758 out = 0;
759 for (i = 0; i < t->nsyms; i++)
761 struct ld_plugin_symbol *s = &t->syms[i];
762 struct sym_aux *aux = &t->aux[i];
763 void **slot;
765 slot = htab_find_slot (symtab, s, INSERT);
766 if (*slot != NULL)
768 int cnf;
769 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
770 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
772 /* Always let the linker resolve the strongest symbol */
773 if (symbol_strength (orig) < symbol_strength (s))
775 SWAP (struct ld_plugin_symbol, *orig, *s);
776 SWAP (uint32_t, orig_aux->slot, aux->slot);
777 SWAP (unsigned long long, orig_aux->id, aux->id);
778 /* Don't swap conflict chain pointer */
781 /* Move current symbol into the conflicts table */
782 cnf = conflicts->nsyms++;
783 conflicts->syms[cnf] = *s;
784 conflicts->aux[cnf] = *aux;
785 aux = &conflicts->aux[cnf];
787 /* Update conflicts chain of the original symbol */
788 aux->next_conflict = orig_aux->next_conflict;
789 orig_aux->next_conflict = cnf;
791 continue;
794 /* Remove previous duplicates in the main table */
795 if (out < i)
797 t->syms[out] = *s;
798 t->aux[out] = *aux;
801 /* Put original into the hash table */
802 *slot = &t->syms[out];
803 out++;
806 assert (conflicts->nsyms <= outlen);
807 assert (conflicts->nsyms + out == t->nsyms);
809 t->nsyms = out;
810 htab_delete (symtab);
813 /* Process one section of an object file. */
815 static int
816 process_symtab (void *data, const char *name, off_t offset, off_t length)
818 struct plugin_objfile *obj = (struct plugin_objfile *)data;
819 char *s;
820 char *secdata;
822 if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
823 return 1;
825 s = strrchr (name, '.');
826 if (s)
827 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
828 secdata = xmalloc (length);
829 offset += obj->file->offset;
830 if (offset != lseek (obj->file->fd, offset, SEEK_SET)
831 || length != read (obj->file->fd, secdata, length))
833 if (message)
834 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
835 /* Force claim_file_handler to abandon this file. */
836 obj->found = 0;
837 free (secdata);
838 return 0;
841 translate (secdata, secdata + length, obj->out);
842 obj->found++;
843 free (secdata);
844 return 1;
847 /* Callback used by gold to check if the plugin will claim FILE. Writes
848 the result in CLAIMED. */
850 static enum ld_plugin_status
851 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
853 enum ld_plugin_status status;
854 struct plugin_objfile obj;
855 struct plugin_file_info lto_file;
856 int err;
857 const char *errmsg;
859 memset (&lto_file, 0, sizeof (struct plugin_file_info));
861 if (file->offset != 0)
863 char *objname;
864 /* We pass the offset of the actual file, not the archive header.
865 Can't use PRIx64, because that's C99, so we have to print the
866 64-bit hex int as two 32-bit ones. */
867 int lo, hi, t;
868 lo = file->offset & 0xffffffff;
869 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
870 t = hi ? asprintf (&objname, "%s@0x%x%08x", file->name, lo, hi)
871 : asprintf (&objname, "%s@0x%x", file->name, lo);
872 check (t >= 0, LDPL_FATAL, "asprintf failed");
873 lto_file.name = objname;
875 else
877 lto_file.name = xstrdup (file->name);
879 lto_file.handle = file->handle;
881 *claimed = 0;
882 obj.file = file;
883 obj.found = 0;
884 obj.out = &lto_file.symtab;
885 errmsg = NULL;
886 obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
887 &errmsg, &err);
888 /* No file, but also no error code means unrecognized format; just skip it. */
889 if (!obj.objfile && !err)
890 goto err;
892 if (obj.objfile)
893 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
895 if (!obj.objfile || errmsg)
897 if (err && message)
898 message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
899 xstrerror (err));
900 else if (message)
901 message (LDPL_FATAL, "%s: %s", file->name, errmsg);
902 goto err;
905 if (obj.found == 0)
906 goto err;
908 if (obj.found > 1)
909 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
911 status = add_symbols (file->handle, lto_file.symtab.nsyms,
912 lto_file.symtab.syms);
913 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
915 *claimed = 1;
916 num_claimed_files++;
917 claimed_files =
918 xrealloc (claimed_files,
919 num_claimed_files * sizeof (struct plugin_file_info));
920 claimed_files[num_claimed_files - 1] = lto_file;
922 goto cleanup;
924 err:
925 free (lto_file.name);
927 cleanup:
928 if (obj.objfile)
929 simple_object_release_read (obj.objfile);
931 return LDPS_OK;
934 /* Parse the plugin options. */
936 static void
937 process_option (const char *option)
939 if (strcmp (option, "-debug") == 0)
940 debug = 1;
941 else if (strcmp (option, "-nop") == 0)
942 nop = 1;
943 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
945 num_pass_through_items++;
946 pass_through_items = xrealloc (pass_through_items,
947 num_pass_through_items * sizeof (char *));
948 pass_through_items[num_pass_through_items - 1] =
949 xstrdup (option + strlen ("-pass-through="));
951 else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
953 switch (option[sizeof ("-sym-style=") - 1])
955 case 'w':
956 sym_style = ss_win32;
957 break;
958 case 'u':
959 sym_style = ss_uscore;
960 break;
961 default:
962 sym_style = ss_none;
963 break;
966 else
968 int size;
969 char *opt = xstrdup (option);
970 lto_wrapper_num_args += 1;
971 size = lto_wrapper_num_args * sizeof (char *);
972 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
973 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
974 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
975 resolution_file = opt + sizeof ("-fresolution=") - 1;
979 /* Called by gold after loading the plugin. TV is the transfer vector. */
981 enum ld_plugin_status
982 onload (struct ld_plugin_tv *tv)
984 struct ld_plugin_tv *p;
985 enum ld_plugin_status status;
987 p = tv;
988 while (p->tv_tag)
990 switch (p->tv_tag)
992 case LDPT_MESSAGE:
993 message = p->tv_u.tv_message;
994 break;
995 case LDPT_REGISTER_CLAIM_FILE_HOOK:
996 register_claim_file = p->tv_u.tv_register_claim_file;
997 break;
998 case LDPT_ADD_SYMBOLS:
999 add_symbols = p->tv_u.tv_add_symbols;
1000 break;
1001 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
1002 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
1003 break;
1004 case LDPT_GET_SYMBOLS_V2:
1005 get_symbols_v2 = p->tv_u.tv_get_symbols;
1006 break;
1007 case LDPT_GET_SYMBOLS:
1008 get_symbols = p->tv_u.tv_get_symbols;
1009 break;
1010 case LDPT_REGISTER_CLEANUP_HOOK:
1011 register_cleanup = p->tv_u.tv_register_cleanup;
1012 break;
1013 case LDPT_ADD_INPUT_FILE:
1014 add_input_file = p->tv_u.tv_add_input_file;
1015 break;
1016 case LDPT_ADD_INPUT_LIBRARY:
1017 add_input_library = p->tv_u.tv_add_input_library;
1018 break;
1019 case LDPT_OPTION:
1020 process_option (p->tv_u.tv_string);
1021 break;
1022 case LDPT_GOLD_VERSION:
1023 gold_version = p->tv_u.tv_val;
1024 break;
1025 default:
1026 break;
1028 p++;
1031 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1032 check (add_symbols, LDPL_FATAL, "add_symbols not found");
1033 status = register_claim_file (claim_file_handler);
1034 check (status == LDPS_OK, LDPL_FATAL,
1035 "could not register the claim_file callback");
1037 if (register_cleanup)
1039 status = register_cleanup (cleanup_handler);
1040 check (status == LDPS_OK, LDPL_FATAL,
1041 "could not register the cleanup callback");
1044 if (register_all_symbols_read)
1046 check (get_symbols, LDPL_FATAL, "get_symbols not found");
1047 status = register_all_symbols_read (all_symbols_read_handler);
1048 check (status == LDPS_OK, LDPL_FATAL,
1049 "could not register the all_symbols_read callback");
1052 return LDPS_OK;