2011-11-01 Andrew Stubbs <ams@codesourcery.com>
[official-gcc.git] / lto-plugin / lto-plugin.c
blobd7a78136827866038d69e9cb154dec7202d87ee3
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 /* 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
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. */
74 #define LTO_SEGMENT_NAME "__GNU_LTO"
76 /* LTO magic section name. */
78 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
79 #define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
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. */
86 struct sym_aux
88 uint32_t slot;
89 unsigned long long id;
90 unsigned next_conflict;
93 struct plugin_symtab
95 int nsyms;
96 struct sym_aux *aux;
97 struct ld_plugin_symbol *syms;
98 unsigned long long id;
101 /* Encapsulates object file data during symbol scan. */
102 struct plugin_objfile
104 int found;
105 simple_object_read *objfile;
106 struct plugin_symtab *out;
107 const struct ld_plugin_input_file *file;
110 /* All that we have to remember about a file. */
112 struct plugin_file_info
114 char *name;
115 void *handle;
116 struct plugin_symtab symtab;
117 struct plugin_symtab conflicts;
120 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
121 stdio file streams, we do simple label translation here. */
123 enum symbol_style
125 ss_none, /* No underscore prefix. */
126 ss_win32, /* Underscore prefix any symbol not beginning with '@'. */
127 ss_uscore, /* Underscore prefix all symbols. */
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, get_symbols_v2;
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;
140 static struct plugin_file_info *claimed_files = NULL;
141 static unsigned int num_claimed_files = 0;
143 static char **output_files = NULL;
144 static unsigned int num_output_files = 0;
146 static char **lto_wrapper_argv;
147 static int lto_wrapper_num_args;
149 static char **pass_through_items = NULL;
150 static unsigned int num_pass_through_items;
152 static char debug;
153 static char nop;
154 static char *resolution_file = NULL;
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;
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;
165 static void
166 check_1 (int gate, enum ld_plugin_level level, const char *text)
168 if (gate)
169 return;
171 if (message)
172 message (level, text);
173 else
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 ();
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))
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. */
191 static char *
192 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
193 struct sym_aux *aux)
195 unsigned char t;
196 enum ld_plugin_symbol_kind translate_kind[] =
198 LDPK_DEF,
199 LDPK_WEAKDEF,
200 LDPK_UNDEF,
201 LDPK_WEAKUNDEF,
202 LDPK_COMMON
205 enum ld_plugin_symbol_visibility translate_visibility[] =
207 LDPV_DEFAULT,
208 LDPV_PROTECTED,
209 LDPV_INTERNAL,
210 LDPV_HIDDEN
213 switch (sym_style)
215 case ss_win32:
216 if (p[0] == '@')
218 /* cf. Duff's device. */
219 case ss_none:
220 entry->name = xstrdup (p);
221 break;
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;
231 while (*p)
232 p++;
233 p++;
235 entry->version = NULL;
237 entry->comdat_key = p;
238 while (*p)
239 p++;
240 p++;
242 if (strlen (entry->comdat_key) == 0)
243 entry->comdat_key = NULL;
244 else
245 entry->comdat_key = xstrdup (entry->comdat_key);
247 t = *p;
248 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
249 entry->def = translate_kind[t];
250 p++;
252 t = *p;
253 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
254 entry->visibility = translate_visibility[t];
255 p++;
257 memcpy (&entry->size, p, sizeof (uint64_t));
258 p += 8;
260 memcpy (&aux->slot, p, sizeof (uint32_t));
261 p += 4;
263 entry->resolution = LDPR_UNKNOWN;
265 aux->next_conflict = -1;
267 return p;
270 /* Translate the IL symbol table located between DATA and END. Append the
271 slots and symbols to OUT. */
273 static void
274 translate (char *data, char *end, struct plugin_symtab *out)
276 struct sym_aux *aux;
277 struct ld_plugin_symbol *syms = NULL;
278 int n, len;
280 /* This overestimates the output buffer sizes, but at least
281 the algorithm is O(1) now. */
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));
287 for (n = out->nsyms; data < end; n++)
289 aux[n].id = out->id;
290 data = parse_table_entry (data, &syms[n], &aux[n]);
293 assert(n < len);
295 out->nsyms = n;
296 out->syms = syms;
297 out->aux = aux;
300 /* Free all memory that is no longer needed after writing the symbol
301 resolution. */
303 static void
304 free_1 (void)
306 unsigned int i;
307 for (i = 0; i < num_claimed_files; i++)
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++)
314 struct ld_plugin_symbol *s = &symtab->syms[j];
315 free (s->name);
316 free (s->comdat_key);
318 free (symtab->syms);
319 symtab->syms = NULL;
323 /* Free all remaining memory. */
325 static void
326 free_2 (void)
328 unsigned int i;
329 for (i = 0; i < num_claimed_files; i++)
331 struct plugin_file_info *info = &claimed_files[i];
332 struct plugin_symtab *symtab = &info->symtab;
333 free (symtab->aux);
334 free (info->name);
337 for (i = 0; i < num_output_files; i++)
338 free (output_files[i]);
339 free (output_files);
341 free (claimed_files);
342 claimed_files = NULL;
343 num_claimed_files = 0;
345 free (arguments_file_name);
346 arguments_file_name = NULL;
349 /* Dump SYMTAB to resolution file F. */
351 static void
352 dump_symtab (FILE *f, struct plugin_symtab *symtab)
354 unsigned j;
356 for (j = 0; j < symtab->nsyms; j++)
358 uint32_t slot = symtab->aux[j].slot;
359 unsigned int resolution = symtab->syms[j].resolution;
361 assert (resolution != LDPR_UNKNOWN);
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);
370 /* Finish the conflicts' resolution information after the linker resolved
371 the original symbols */
373 static void
374 finish_conflict_resolution (struct plugin_symtab *symtab,
375 struct plugin_symtab *conflicts)
377 int i, j;
379 if (conflicts->nsyms == 0)
380 return;
382 for (i = 0; i < symtab->nsyms; i++)
384 int resolution = LDPR_UNKNOWN;
386 if (symtab->aux[i].next_conflict == -1)
387 continue;
389 switch (symtab->syms[i].def)
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);
406 assert (resolution != LDPR_UNKNOWN);
408 for (j = symtab->aux[i].next_conflict;
409 j != -1;
410 j = conflicts->aux[j].next_conflict)
411 conflicts->syms[j].resolution = resolution;
415 /* Free symbol table SYMTAB. */
417 static void
418 free_symtab (struct plugin_symtab *symtab)
420 free (symtab->syms);
421 symtab->syms = NULL;
422 free (symtab->aux);
423 symtab->aux = NULL;
426 /* Writes the relocations to disk. */
428 static void
429 write_resolution (void)
431 unsigned int i;
432 FILE *f;
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");
438 fprintf (f, "%d\n", num_claimed_files);
440 for (i = 0; i < num_claimed_files; i++)
442 struct plugin_file_info *info = &claimed_files[i];
443 struct plugin_symtab *symtab = &info->symtab;
444 struct ld_plugin_symbol *syms = symtab->syms;
446 /* Version 2 of API supports IRONLY_EXP resolution that is
447 accepted by GCC-4.7 and newer. */
448 if (get_symbols_v2)
449 get_symbols_v2 (info->handle, symtab->nsyms, syms);
450 else
451 get_symbols (info->handle, symtab->nsyms, syms);
453 finish_conflict_resolution (symtab, &info->conflicts);
455 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
456 dump_symtab (f, symtab);
457 if (info->conflicts.nsyms)
459 dump_symtab (f, &info->conflicts);
460 free_symtab (&info->conflicts);
463 fclose (f);
466 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
467 stdout. */
469 static void
470 add_output_files (FILE *f)
472 for (;;)
474 const unsigned piece = 32;
475 char *buf, *s = xmalloc (piece);
476 size_t len;
478 buf = s;
479 cont:
480 if (!fgets (buf, piece, f))
482 free (s);
483 break;
485 len = strlen (s);
486 if (s[len - 1] != '\n')
488 s = xrealloc (s, len + piece);
489 buf = s + len;
490 goto cont;
492 s[len - 1] = '\0';
494 num_output_files++;
495 output_files
496 = xrealloc (output_files, num_output_files * sizeof (char *));
497 output_files[num_output_files - 1] = s;
498 add_input_file (output_files[num_output_files - 1]);
502 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
503 argument list. */
505 static void
506 exec_lto_wrapper (char *argv[])
508 int t, i;
509 int status;
510 char *at_args;
511 FILE *args;
512 FILE *wrapper_output;
513 char *new_argv[3];
514 struct pex_obj *pex;
515 const char *errmsg;
517 /* Write argv to a file to avoid a command line that is too long. */
518 arguments_file_name = make_temp_file ("");
519 check (arguments_file_name, LDPL_FATAL,
520 "Failed to generate a temorary file name");
522 args = fopen (arguments_file_name, "w");
523 check (args, LDPL_FATAL, "could not open arguments file");
525 t = writeargv (&argv[1], args);
526 check (t == 0, LDPL_FATAL, "could not write arguments");
527 t = fclose (args);
528 check (t == 0, LDPL_FATAL, "could not close arguments file");
530 at_args = concat ("@", arguments_file_name, NULL);
531 check (at_args, LDPL_FATAL, "could not allocate");
533 for (i = 1; argv[i]; i++)
535 char *a = argv[i];
536 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
538 for (i = 0; argv[i]; i++)
539 fprintf (stderr, "%s ", argv[i]);
540 fprintf (stderr, "\n");
541 break;
545 new_argv[0] = argv[0];
546 new_argv[1] = at_args;
547 new_argv[2] = NULL;
549 if (debug)
551 for (i = 0; new_argv[i]; i++)
552 fprintf (stderr, "%s ", new_argv[i]);
553 fprintf (stderr, "\n");
557 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
558 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
560 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
561 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
562 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
564 wrapper_output = pex_read_output (pex, 0);
565 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
567 add_output_files (wrapper_output);
569 t = pex_get_status (pex, 1, &status);
570 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
571 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
572 "lto-wrapper failed");
574 pex_free (pex);
576 free (at_args);
579 /* Pass the original files back to the linker. */
581 static void
582 use_original_files (void)
584 unsigned i;
585 for (i = 0; i < num_claimed_files; i++)
587 struct plugin_file_info *info = &claimed_files[i];
588 add_input_file (info->name);
593 /* Called by the linker once all symbols have been read. */
595 static enum ld_plugin_status
596 all_symbols_read_handler (void)
598 unsigned i;
599 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
600 char **lto_argv;
601 const char **lto_arg_ptr;
602 if (num_claimed_files == 0)
603 return LDPS_OK;
605 if (nop)
607 use_original_files ();
608 return LDPS_OK;
611 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
612 lto_arg_ptr = (const char **) lto_argv;
613 assert (lto_wrapper_argv);
615 write_resolution ();
617 free_1 ();
619 for (i = 0; i < lto_wrapper_num_args; i++)
620 *lto_arg_ptr++ = lto_wrapper_argv[i];
622 for (i = 0; i < num_claimed_files; i++)
624 struct plugin_file_info *info = &claimed_files[i];
626 *lto_arg_ptr++ = info->name;
629 *lto_arg_ptr++ = NULL;
630 exec_lto_wrapper (lto_argv);
632 free (lto_argv);
634 /* --pass-through is not needed when using gold 1.11 or later. */
635 if (pass_through_items && gold_version < 111)
637 unsigned int i;
638 for (i = 0; i < num_pass_through_items; i++)
640 if (strncmp (pass_through_items[i], "-l", 2) == 0)
641 add_input_library (pass_through_items[i] + 2);
642 else
643 add_input_file (pass_through_items[i]);
644 free (pass_through_items[i]);
645 pass_through_items[i] = NULL;
647 free (pass_through_items);
648 pass_through_items = NULL;
651 return LDPS_OK;
654 /* Remove temporary files at the end of the link. */
656 static enum ld_plugin_status
657 cleanup_handler (void)
659 unsigned int i;
660 int t;
662 if (debug)
663 return LDPS_OK;
665 if (arguments_file_name)
667 t = unlink (arguments_file_name);
668 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
671 for (i = 0; i < num_output_files; i++)
673 t = unlink (output_files[i]);
674 check (t == 0, LDPL_FATAL, "could not unlink output file");
677 free_2 ();
678 return LDPS_OK;
681 #define SWAP(type, a, b) \
682 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
684 /* Compare two hash table entries */
686 static int eq_sym (const void *a, const void *b)
688 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
689 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
691 return !strcmp (as->name, bs->name);
694 /* Hash a symbol */
696 static hashval_t hash_sym (const void *a)
698 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
700 return htab_hash_string (as->name);
703 /* Determine how strong a symbol is */
705 static int symbol_strength (struct ld_plugin_symbol *s)
707 switch (s->def)
709 case LDPK_UNDEF:
710 case LDPK_WEAKUNDEF:
711 return 0;
712 case LDPK_WEAKDEF:
713 return 1;
714 default:
715 return 2;
719 /* In the ld -r case we can get dups in the LTO symbol tables, where
720 the same symbol can have different resolutions (e.g. undefined and defined).
722 We have to keep that in the LTO symbol tables, but the dups confuse
723 gold and then finally gcc by supplying incorrect resolutions.
725 Problem is that the main gold symbol table doesn't know about subids
726 and does not distingush the same symbols in different states.
728 So we drop duplicates from the linker visible symbol table
729 and keep them in a private table. Then later do own symbol
730 resolution for the duplicated based on the results for the
731 originals.
733 Then when writing out the resolution file readd the dropped symbols.
735 XXX how to handle common? */
737 static void
738 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
740 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
741 int i;
742 int out;
743 int outlen;
745 outlen = t->nsyms;
746 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
747 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
749 /* Move all duplicate symbols into the auxillary conflicts table. */
750 out = 0;
751 for (i = 0; i < t->nsyms; i++)
753 struct ld_plugin_symbol *s = &t->syms[i];
754 struct sym_aux *aux = &t->aux[i];
755 void **slot;
757 slot = htab_find_slot (symtab, s, INSERT);
758 if (*slot != NULL)
760 int cnf;
761 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
762 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
764 /* Always let the linker resolve the strongest symbol */
765 if (symbol_strength (orig) < symbol_strength (s))
767 SWAP (struct ld_plugin_symbol, *orig, *s);
768 SWAP (uint32_t, orig_aux->slot, aux->slot);
769 SWAP (unsigned long long, orig_aux->id, aux->id);
770 /* Don't swap conflict chain pointer */
773 /* Move current symbol into the conflicts table */
774 cnf = conflicts->nsyms++;
775 conflicts->syms[cnf] = *s;
776 conflicts->aux[cnf] = *aux;
777 aux = &conflicts->aux[cnf];
779 /* Update conflicts chain of the original symbol */
780 aux->next_conflict = orig_aux->next_conflict;
781 orig_aux->next_conflict = cnf;
783 continue;
786 /* Remove previous duplicates in the main table */
787 if (out < i)
789 t->syms[out] = *s;
790 t->aux[out] = *aux;
793 /* Put original into the hash table */
794 *slot = &t->syms[out];
795 out++;
798 assert (conflicts->nsyms <= outlen);
799 assert (conflicts->nsyms + out == t->nsyms);
801 t->nsyms = out;
802 htab_delete (symtab);
805 /* Process one section of an object file. */
807 static int
808 process_symtab (void *data, const char *name, off_t offset, off_t length)
810 struct plugin_objfile *obj = (struct plugin_objfile *)data;
811 char *s;
812 char *secdata;
814 if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
815 return 1;
817 s = strrchr (name, '.');
818 if (s)
819 sscanf (s, ".%llx", &obj->out->id);
820 secdata = xmalloc (length);
821 offset += obj->file->offset;
822 if (offset != lseek (obj->file->fd, offset, SEEK_SET)
823 || length != read (obj->file->fd, secdata, length))
825 if (message)
826 message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
827 /* Force claim_file_handler to abandon this file. */
828 obj->found = 0;
829 free (secdata);
830 return 0;
833 translate (secdata, secdata + length, obj->out);
834 obj->found++;
835 free (secdata);
836 return 1;
839 /* Callback used by gold to check if the plugin will claim FILE. Writes
840 the result in CLAIMED. */
842 static enum ld_plugin_status
843 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
845 enum ld_plugin_status status;
846 struct plugin_objfile obj;
847 struct plugin_file_info lto_file;
848 int err;
849 const char *errmsg;
851 memset (&lto_file, 0, sizeof (struct plugin_file_info));
853 if (file->offset != 0)
855 char *objname;
856 /* We pass the offset of the actual file, not the archive header.
857 Can't use PRIx64, because that's C99, so we have to print the
858 64-bit hex int as two 32-bit ones. */
859 int lo, hi, t;
860 lo = file->offset & 0xffffffff;
861 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
862 t = hi ? asprintf (&objname, "%s@0x%x%08x", file->name, lo, hi)
863 : asprintf (&objname, "%s@0x%x", file->name, lo);
864 check (t >= 0, LDPL_FATAL, "asprintf failed");
865 lto_file.name = objname;
867 else
869 lto_file.name = xstrdup (file->name);
871 lto_file.handle = file->handle;
873 *claimed = 0;
874 obj.file = file;
875 obj.found = 0;
876 obj.out = &lto_file.symtab;
877 errmsg = NULL;
878 obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
879 &errmsg, &err);
880 /* No file, but also no error code means unrecognized format; just skip it. */
881 if (!obj.objfile && !err)
882 goto err;
884 if (obj.objfile)
885 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
887 if (!obj.objfile || errmsg)
889 if (err && message)
890 message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
891 xstrerror (err));
892 else if (message)
893 message (LDPL_FATAL, "%s: %s", file->name, errmsg);
894 goto err;
897 if (obj.found == 0)
898 goto err;
900 if (obj.found > 1)
901 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
903 status = add_symbols (file->handle, lto_file.symtab.nsyms,
904 lto_file.symtab.syms);
905 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
907 *claimed = 1;
908 num_claimed_files++;
909 claimed_files =
910 xrealloc (claimed_files,
911 num_claimed_files * sizeof (struct plugin_file_info));
912 claimed_files[num_claimed_files - 1] = lto_file;
914 goto cleanup;
916 err:
917 free (lto_file.name);
919 cleanup:
920 if (obj.objfile)
921 simple_object_release_read (obj.objfile);
923 return LDPS_OK;
926 /* Parse the plugin options. */
928 static void
929 process_option (const char *option)
931 if (strcmp (option, "-debug") == 0)
932 debug = 1;
933 else if (strcmp (option, "-nop") == 0)
934 nop = 1;
935 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
937 num_pass_through_items++;
938 pass_through_items = xrealloc (pass_through_items,
939 num_pass_through_items * sizeof (char *));
940 pass_through_items[num_pass_through_items - 1] =
941 xstrdup (option + strlen ("-pass-through="));
943 else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
945 switch (option[sizeof ("-sym-style=") - 1])
947 case 'w':
948 sym_style = ss_win32;
949 break;
950 case 'u':
951 sym_style = ss_uscore;
952 break;
953 default:
954 sym_style = ss_none;
955 break;
958 else
960 int size;
961 char *opt = xstrdup (option);
962 lto_wrapper_num_args += 1;
963 size = lto_wrapper_num_args * sizeof (char *);
964 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
965 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
966 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
967 resolution_file = opt + sizeof ("-fresolution=") - 1;
971 /* Called by gold after loading the plugin. TV is the transfer vector. */
973 enum ld_plugin_status
974 onload (struct ld_plugin_tv *tv)
976 struct ld_plugin_tv *p;
977 enum ld_plugin_status status;
979 p = tv;
980 while (p->tv_tag)
982 switch (p->tv_tag)
984 case LDPT_MESSAGE:
985 message = p->tv_u.tv_message;
986 break;
987 case LDPT_REGISTER_CLAIM_FILE_HOOK:
988 register_claim_file = p->tv_u.tv_register_claim_file;
989 break;
990 case LDPT_ADD_SYMBOLS:
991 add_symbols = p->tv_u.tv_add_symbols;
992 break;
993 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
994 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
995 break;
996 case LDPT_GET_SYMBOLS_V2:
997 get_symbols_v2 = p->tv_u.tv_get_symbols;
998 break;
999 case LDPT_GET_SYMBOLS:
1000 get_symbols = p->tv_u.tv_get_symbols;
1001 break;
1002 case LDPT_REGISTER_CLEANUP_HOOK:
1003 register_cleanup = p->tv_u.tv_register_cleanup;
1004 break;
1005 case LDPT_ADD_INPUT_FILE:
1006 add_input_file = p->tv_u.tv_add_input_file;
1007 break;
1008 case LDPT_ADD_INPUT_LIBRARY:
1009 add_input_library = p->tv_u.tv_add_input_library;
1010 break;
1011 case LDPT_OPTION:
1012 process_option (p->tv_u.tv_string);
1013 break;
1014 case LDPT_GOLD_VERSION:
1015 gold_version = p->tv_u.tv_val;
1016 break;
1017 default:
1018 break;
1020 p++;
1023 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1024 check (add_symbols, LDPL_FATAL, "add_symbols not found");
1025 status = register_claim_file (claim_file_handler);
1026 check (status == LDPS_OK, LDPL_FATAL,
1027 "could not register the claim_file callback");
1029 if (register_cleanup)
1031 status = register_cleanup (cleanup_handler);
1032 check (status == LDPS_OK, LDPL_FATAL,
1033 "could not register the cleanup callback");
1036 if (register_all_symbols_read)
1038 check (get_symbols, LDPL_FATAL, "get_symbols not found");
1039 status = register_all_symbols_read (all_symbols_read_handler);
1040 check (status == LDPS_OK, LDPL_FATAL,
1041 "could not register the all_symbols_read callback");
1044 return LDPS_OK;