* config/rs6000/rs6000.c (rs6000_expand_ternop_builtin): Rewrite
[official-gcc.git] / lto-plugin / lto-plugin.c
blobdc51b48bc5ace84878a653d73e466ca4fd42d2eb
1 /* LTO plugin for gold.
2 Copyright (C) 2009 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 #include <assert.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <inttypes.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42 #include <fcntl.h>
43 #include <sys/types.h>
44 #include <sys/wait.h>
45 #include <stdbool.h>
46 #include <libiberty.h>
47 #include <hashtab.h>
49 /* The presence of gelf.h is checked by the toplevel configure script. */
50 #include <gelf.h>
52 #include "plugin-api.h"
53 #include "../gcc/lto/common.h"
55 /* The part of the symbol table the plugin has to keep track of. Note that we
56 must keep SYMS until all_symbols_read is called to give the linker time to
57 copy the symbol information. */
59 struct sym_aux
61 uint32_t slot;
62 unsigned id;
63 unsigned next_conflict;
66 struct plugin_symtab
68 int nsyms;
69 struct sym_aux *aux;
70 struct ld_plugin_symbol *syms;
71 unsigned id;
74 /* All that we have to remember about a file. */
76 struct plugin_file_info
78 char *name;
79 void *handle;
80 struct plugin_symtab symtab;
81 struct plugin_symtab conflicts;
85 static char *arguments_file_name;
86 static ld_plugin_register_claim_file register_claim_file;
87 static ld_plugin_add_symbols add_symbols;
88 static ld_plugin_register_all_symbols_read register_all_symbols_read;
89 static ld_plugin_get_symbols get_symbols;
90 static ld_plugin_register_cleanup register_cleanup;
91 static ld_plugin_add_input_file add_input_file;
92 static ld_plugin_add_input_library add_input_library;
93 static ld_plugin_message message;
95 static struct plugin_file_info *claimed_files = NULL;
96 static unsigned int num_claimed_files = 0;
98 static char **output_files = NULL;
99 static unsigned int num_output_files = 0;
101 static char **lto_wrapper_argv;
102 static int lto_wrapper_num_args;
104 static char **pass_through_items = NULL;
105 static unsigned int num_pass_through_items;
107 static bool debug;
108 static bool nop;
109 static char *resolution_file = NULL;
111 static void
112 check (bool gate, enum ld_plugin_level level, const char *text)
114 if (gate)
115 return;
117 if (message)
118 message (level, text);
119 else
121 /* If there is no nicer way to inform the user, fallback to stderr. */
122 fprintf (stderr, "%s\n", text);
123 if (level == LDPL_FATAL)
124 abort ();
128 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
129 by P and the result is written in ENTRY. The slot number is stored in SLOT.
130 Returns the address of the next entry. */
132 static char *
133 parse_table_entry (char *p, struct ld_plugin_symbol *entry,
134 struct sym_aux *aux)
136 unsigned char t;
137 enum ld_plugin_symbol_kind translate_kind[] =
139 LDPK_DEF,
140 LDPK_WEAKDEF,
141 LDPK_UNDEF,
142 LDPK_WEAKUNDEF,
143 LDPK_COMMON
146 enum ld_plugin_symbol_visibility translate_visibility[] =
148 LDPV_DEFAULT,
149 LDPV_PROTECTED,
150 LDPV_INTERNAL,
151 LDPV_HIDDEN
154 entry->name = xstrdup (p);
155 while (*p)
156 p++;
157 p++;
159 entry->version = NULL;
161 entry->comdat_key = p;
162 while (*p)
163 p++;
164 p++;
166 if (strlen (entry->comdat_key) == 0)
167 entry->comdat_key = NULL;
168 else
169 entry->comdat_key = xstrdup (entry->comdat_key);
171 t = *p;
172 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
173 entry->def = translate_kind[t];
174 p++;
176 t = *p;
177 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
178 entry->visibility = translate_visibility[t];
179 p++;
181 entry->size = *(uint64_t *) p;
182 p += 8;
184 aux->slot = *(uint32_t *) p;
185 p += 4;
187 entry->resolution = LDPR_UNKNOWN;
189 aux->next_conflict = -1;
191 return p;
194 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
196 /* Translate the IL symbol table SYMTAB. Append the slots and symbols to OUT. */
198 static void
199 translate (Elf_Data *symtab, struct plugin_symtab *out)
201 struct sym_aux *aux;
202 char *data = symtab->d_buf;
203 char *end = data + symtab->d_size;
204 struct ld_plugin_symbol *syms = NULL;
205 int n, len;
207 /* This overestimates the output buffer sizes, but at least
208 the algorithm is O(1) now. */
210 len = (end - data)/8 + out->nsyms + 1;
211 syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
212 aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
214 for (n = out->nsyms; data < end; n++)
216 aux[n].id = out->id;
217 data = parse_table_entry (data, &syms[n], &aux[n]);
220 assert(n < len);
222 out->nsyms = n;
223 out->syms = syms;
224 out->aux = aux;
227 /* Process all lto symtabs of file ELF. */
229 static int
230 process_symtab (Elf *elf, struct plugin_symtab *out)
232 int found = 0;
233 Elf_Scn *section = 0;
234 GElf_Ehdr header;
235 GElf_Ehdr *t = gelf_getehdr (elf, &header);
236 if (t == NULL)
237 return 0;
238 assert (t == &header);
240 while ((section = elf_nextscn(elf, section)) != 0)
242 GElf_Shdr shdr;
243 GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
244 const char *t;
245 assert (tshdr == &shdr);
246 t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
247 assert (t != NULL);
248 if (strncmp (t, LTO_SECTION_PREFIX, strlen (LTO_SECTION_PREFIX)) == 0)
250 char *s = strrchr (t, '.');
251 if (s)
252 sscanf (s, ".%x", &out->id);
253 translate (elf_getdata (section, NULL), out);
254 found++;
257 return found;
260 /* Free all memory that is no longer needed after writing the symbol
261 resolution. */
263 static void
264 free_1 (void)
266 unsigned int i;
267 for (i = 0; i < num_claimed_files; i++)
269 struct plugin_file_info *info = &claimed_files[i];
270 struct plugin_symtab *symtab = &info->symtab;
271 unsigned int j;
272 for (j = 0; j < symtab->nsyms; j++)
274 struct ld_plugin_symbol *s = &symtab->syms[j];
275 free (s->name);
276 if (s->comdat_key)
277 free (s->comdat_key);
279 free (symtab->syms);
280 symtab->syms = NULL;
284 /* Free all remaining memory. */
286 static void
287 free_2 (void)
289 unsigned int i;
290 for (i = 0; i < num_claimed_files; i++)
292 struct plugin_file_info *info = &claimed_files[i];
293 struct plugin_symtab *symtab = &info->symtab;
294 free (symtab->aux);
295 free (info->name);
298 for (i = 0; i < num_output_files; i++)
299 free (output_files[i]);
300 free (output_files);
302 free (claimed_files);
303 claimed_files = NULL;
304 num_claimed_files = 0;
306 if (arguments_file_name)
307 free (arguments_file_name);
308 arguments_file_name = NULL;
311 /* Dump SYMTAB to resolution file F. */
313 static void
314 dump_symtab (FILE *f, struct plugin_symtab *symtab)
316 unsigned j;
318 for (j = 0; j < symtab->nsyms; j++)
320 uint32_t slot = symtab->aux[j].slot;
321 unsigned int resolution = symtab->syms[j].resolution;
323 assert (resolution != LDPR_UNKNOWN);
325 fprintf (f, "%d %x %s %s\n", slot, symtab->aux[j].id,
326 lto_resolution_str[resolution],
327 symtab->syms[j].name);
331 /* Finish the conflicts' resolution information after the linker resolved
332 the original symbols */
334 static void
335 finish_conflict_resolution (struct plugin_symtab *symtab,
336 struct plugin_symtab *conflicts)
338 int i, j;
340 if (conflicts->nsyms == 0)
341 return;
343 for (i = 0; i < symtab->nsyms; i++)
345 int resolution;
347 if (symtab->aux[i].next_conflict == -1)
348 continue;
350 switch (symtab->syms[i].def)
352 case LDPK_DEF:
353 case LDPK_COMMON: /* ??? */
354 resolution = LDPR_RESOLVED_IR;
355 break;
356 case LDPK_WEAKDEF:
357 resolution = LDPR_PREEMPTED_IR;
358 break;
359 case LDPK_UNDEF:
360 case LDPK_WEAKUNDEF:
361 resolution = symtab->syms[i].resolution;
362 break;
363 default:
364 assert (0);
367 assert (resolution != LDPR_UNKNOWN);
369 for (j = symtab->aux[i].next_conflict;
370 j != -1;
371 j = conflicts->aux[j].next_conflict)
372 conflicts->syms[j].resolution = resolution;
376 /* Free symbol table SYMTAB. */
378 static void
379 free_symtab (struct plugin_symtab *symtab)
381 free (symtab->syms);
382 symtab->syms = NULL;
383 free (symtab->aux);
384 symtab->aux = NULL;
387 /* Writes the relocations to disk. */
389 static void
390 write_resolution (void)
392 unsigned int i;
393 FILE *f;
395 check (resolution_file, LDPL_FATAL, "resolution file not specified");
396 f = fopen (resolution_file, "w");
397 check (f, LDPL_FATAL, "could not open file");
399 fprintf (f, "%d\n", num_claimed_files);
401 for (i = 0; i < num_claimed_files; i++)
403 struct plugin_file_info *info = &claimed_files[i];
404 struct plugin_symtab *symtab = &info->symtab;
405 struct ld_plugin_symbol *syms = symtab->syms;
407 get_symbols (info->handle, symtab->nsyms, syms);
409 finish_conflict_resolution (symtab, &info->conflicts);
411 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
412 dump_symtab (f, symtab);
413 if (info->conflicts.nsyms)
415 dump_symtab (f, &info->conflicts);
416 free_symtab (&info->conflicts);
419 fclose (f);
422 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
423 stdout. */
425 static void
426 add_output_files (FILE *f)
428 for (;;)
430 const unsigned piece = 32;
431 char *buf, *s = xmalloc (piece);
432 size_t len;
434 buf = s;
435 cont:
436 if (!fgets (buf, piece, f))
437 break;
438 len = strlen (s);
439 if (s[len - 1] != '\n')
441 s = xrealloc (s, len + piece);
442 buf = s + len;
443 goto cont;
445 s[len - 1] = '\0';
447 num_output_files++;
448 output_files
449 = xrealloc (output_files, num_output_files * sizeof (char *));
450 output_files[num_output_files - 1] = s;
451 add_input_file (output_files[num_output_files - 1]);
455 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
456 argument list. */
458 static void
459 exec_lto_wrapper (char *argv[])
461 int t, i;
462 int status;
463 char *at_args;
464 FILE *args;
465 FILE *wrapper_output;
466 char *new_argv[3];
467 struct pex_obj *pex;
468 const char *errmsg;
470 /* Write argv to a file to avoid a command line that is too long. */
471 arguments_file_name = make_temp_file ("");
472 check (arguments_file_name, LDPL_FATAL,
473 "Failed to generate a temorary file name");
475 args = fopen (arguments_file_name, "w");
476 check (args, LDPL_FATAL, "could not open arguments file");
478 t = writeargv (&argv[1], args);
479 check (t == 0, LDPL_FATAL, "could not write arguments");
480 t = fclose (args);
481 check (t == 0, LDPL_FATAL, "could not close arguments file");
483 at_args = concat ("@", arguments_file_name, NULL);
484 check (at_args, LDPL_FATAL, "could not allocate");
486 for (i = 1; argv[i]; i++)
488 char *a = argv[i];
489 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
491 for (i = 0; argv[i]; i++)
492 fprintf (stderr, "%s ", argv[i]);
493 fprintf (stderr, "\n");
494 break;
498 new_argv[0] = argv[0];
499 new_argv[1] = at_args;
500 new_argv[2] = NULL;
502 if (debug)
504 for (i = 0; new_argv[i]; i++)
505 fprintf (stderr, "%s ", new_argv[i]);
506 fprintf (stderr, "\n");
510 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
511 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
513 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
514 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
515 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
517 wrapper_output = pex_read_output (pex, 0);
518 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
520 add_output_files (wrapper_output);
522 t = pex_get_status (pex, 1, &status);
523 check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
524 check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
525 "lto-wrapper failed");
527 pex_free (pex);
529 free (at_args);
532 /* Pass the original files back to the linker. */
534 static void
535 use_original_files (void)
537 unsigned i;
538 for (i = 0; i < num_claimed_files; i++)
540 struct plugin_file_info *info = &claimed_files[i];
541 add_input_file (info->name);
546 /* Called by the linker once all symbols have been read. */
548 static enum ld_plugin_status
549 all_symbols_read_handler (void)
551 unsigned i;
552 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
553 char **lto_argv;
554 const char **lto_arg_ptr;
555 if (num_claimed_files == 0)
556 return LDPS_OK;
558 if (nop)
560 use_original_files ();
561 return LDPS_OK;
564 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
565 lto_arg_ptr = (const char **) lto_argv;
566 assert (lto_wrapper_argv);
568 write_resolution ();
570 free_1 ();
572 for (i = 0; i < lto_wrapper_num_args; i++)
573 *lto_arg_ptr++ = lto_wrapper_argv[i];
575 for (i = 0; i < num_claimed_files; i++)
577 struct plugin_file_info *info = &claimed_files[i];
579 *lto_arg_ptr++ = info->name;
582 *lto_arg_ptr++ = NULL;
583 exec_lto_wrapper (lto_argv);
585 free (lto_argv);
587 if (pass_through_items)
589 unsigned int i;
590 for (i = 0; i < num_pass_through_items; i++)
592 if (strncmp (pass_through_items[i], "-l", 2) == 0)
593 add_input_library (pass_through_items[i] + 2);
594 else
595 add_input_file (pass_through_items[i]);
596 free (pass_through_items[i]);
597 pass_through_items[i] = NULL;
599 free (pass_through_items);
600 pass_through_items = NULL;
603 return LDPS_OK;
606 /* Remove temporary files at the end of the link. */
608 static enum ld_plugin_status
609 cleanup_handler (void)
611 unsigned int i;
612 int t;
614 if (debug)
615 return LDPS_OK;
617 if (arguments_file_name)
619 t = unlink (arguments_file_name);
620 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
623 for (i = 0; i < num_output_files; i++)
625 t = unlink (output_files[i]);
626 check (t == 0, LDPL_FATAL, "could not unlink output file");
629 free_2 ();
630 return LDPS_OK;
633 #define SWAP(type, a, b) \
634 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
636 /* Compare two hash table entries */
638 static int eq_sym (const void *a, const void *b)
640 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
641 const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
643 return !strcmp (as->name, bs->name);
646 /* Hash a symbol */
648 static hashval_t hash_sym (const void *a)
650 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
652 return htab_hash_string (as->name);
655 /* Determine how strong a symbol is */
657 static int symbol_strength (struct ld_plugin_symbol *s)
659 switch (s->def)
661 case LDPK_UNDEF:
662 case LDPK_WEAKUNDEF:
663 return 0;
664 case LDPK_WEAKDEF:
665 return 1;
666 default:
667 return 2;
671 /* In the ld -r case we can get dups in the LTO symbol tables, where
672 the same symbol can have different resolutions (e.g. undefined and defined).
674 We have to keep that in the LTO symbol tables, but the dups confuse
675 gold and then finally gcc by supplying incorrect resolutions.
677 Problem is that the main gold symbol table doesn't know about subids
678 and does not distingush the same symbols in different states.
680 So we drop duplicates from the linker visible symbol table
681 and keep them in a private table. Then later do own symbol
682 resolution for the duplicated based on the results for the
683 originals.
685 Then when writing out the resolution file readd the dropped symbols.
687 XXX how to handle common? */
689 static void
690 resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
692 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
693 int i;
694 int out;
695 int outlen;
697 outlen = t->nsyms;
698 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
699 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
701 /* Move all duplicate symbols into the auxillary conflicts table. */
702 out = 0;
703 for (i = 0; i < t->nsyms; i++)
705 struct ld_plugin_symbol *s = &t->syms[i];
706 struct sym_aux *aux = &t->aux[i];
707 void **slot;
709 slot = htab_find_slot (symtab, s, INSERT);
710 if (*slot != NULL)
712 int cnf;
713 struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
714 struct sym_aux *orig_aux = &t->aux[orig - t->syms];
716 /* Always let the linker resolve the strongest symbol */
717 if (symbol_strength (orig) < symbol_strength (s))
719 SWAP (struct ld_plugin_symbol, *orig, *s);
720 SWAP (uint32_t, orig_aux->slot, aux->slot);
721 SWAP (unsigned, orig_aux->id, aux->id);
722 /* Don't swap conflict chain pointer */
725 /* Move current symbol into the conflicts table */
726 cnf = conflicts->nsyms++;
727 conflicts->syms[cnf] = *s;
728 conflicts->aux[cnf] = *aux;
729 aux = &conflicts->aux[cnf];
731 /* Update conflicts chain of the original symbol */
732 aux->next_conflict = orig_aux->next_conflict;
733 orig_aux->next_conflict = cnf;
735 continue;
738 /* Remove previous duplicates in the main table */
739 if (out < i)
741 t->syms[out] = *s;
742 t->aux[out] = *aux;
745 /* Put original into the hash table */
746 *slot = &t->syms[out];
747 out++;
750 assert (conflicts->nsyms <= outlen);
751 assert (conflicts->nsyms + out == t->nsyms);
753 t->nsyms = out;
754 htab_delete (symtab);
757 /* Callback used by gold to check if the plugin will claim FILE. Writes
758 the result in CLAIMED. */
760 static enum ld_plugin_status
761 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
763 enum ld_plugin_status status;
764 Elf *elf;
765 struct plugin_file_info lto_file;
766 int n;
768 memset (&lto_file, 0, sizeof (struct plugin_file_info));
770 if (file->offset != 0)
772 char *objname;
773 Elf *archive;
774 off_t offset;
775 /* We pass the offset of the actual file, not the archive header. */
776 int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
777 (int64_t) file->offset);
778 check (t >= 0, LDPL_FATAL, "asprintf failed");
779 lto_file.name = objname;
781 archive = elf_begin (file->fd, ELF_C_READ, NULL);
782 check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
783 "Not an archive and offset not 0");
785 /* elf_rand expects the offset to point to the ar header, not the
786 object itself. Subtract the size of the ar header (60 bytes).
787 We don't uses sizeof (struct ar_hd) to avoid including ar.h */
789 offset = file->offset - 60;
790 check (offset == elf_rand (archive, offset), LDPL_FATAL,
791 "could not seek in archive");
792 elf = elf_begin (file->fd, ELF_C_READ, archive);
793 check (elf != NULL, LDPL_FATAL, "could not find archive member");
794 elf_end (archive);
796 else
798 lto_file.name = xstrdup (file->name);
799 elf = elf_begin (file->fd, ELF_C_READ, NULL);
801 lto_file.handle = file->handle;
803 *claimed = 0;
805 if (!elf)
806 goto err;
808 n = process_symtab (elf, &lto_file.symtab);
809 if (n == 0)
810 goto err;
812 if (n > 1)
813 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
815 status = add_symbols (file->handle, lto_file.symtab.nsyms,
816 lto_file.symtab.syms);
817 check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
819 *claimed = 1;
820 num_claimed_files++;
821 claimed_files =
822 xrealloc (claimed_files,
823 num_claimed_files * sizeof (struct plugin_file_info));
824 claimed_files[num_claimed_files - 1] = lto_file;
826 goto cleanup;
828 err:
829 free (lto_file.name);
831 cleanup:
832 if (elf)
833 elf_end (elf);
835 return LDPS_OK;
838 /* Parse the plugin options. */
840 static void
841 process_option (const char *option)
843 if (strcmp (option, "-debug") == 0)
844 debug = 1;
845 else if (strcmp (option, "-nop") == 0)
846 nop = 1;
847 else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
849 num_pass_through_items++;
850 pass_through_items = xrealloc (pass_through_items,
851 num_pass_through_items * sizeof (char *));
852 pass_through_items[num_pass_through_items - 1] =
853 xstrdup (option + strlen ("-pass-through="));
855 else
857 int size;
858 char *opt = xstrdup (option);
859 lto_wrapper_num_args += 1;
860 size = lto_wrapper_num_args * sizeof (char *);
861 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
862 lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
863 if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
864 resolution_file = opt + sizeof ("-fresolution=") - 1;
868 /* Called by gold after loading the plugin. TV is the transfer vector. */
870 enum ld_plugin_status
871 onload (struct ld_plugin_tv *tv)
873 struct ld_plugin_tv *p;
874 enum ld_plugin_status status;
876 unsigned version = elf_version (EV_CURRENT);
877 check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
879 p = tv;
880 while (p->tv_tag)
882 switch (p->tv_tag)
884 case LDPT_MESSAGE:
885 message = p->tv_u.tv_message;
886 break;
887 case LDPT_REGISTER_CLAIM_FILE_HOOK:
888 register_claim_file = p->tv_u.tv_register_claim_file;
889 break;
890 case LDPT_ADD_SYMBOLS:
891 add_symbols = p->tv_u.tv_add_symbols;
892 break;
893 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
894 register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
895 break;
896 case LDPT_GET_SYMBOLS:
897 get_symbols = p->tv_u.tv_get_symbols;
898 break;
899 case LDPT_REGISTER_CLEANUP_HOOK:
900 register_cleanup = p->tv_u.tv_register_cleanup;
901 break;
902 case LDPT_ADD_INPUT_FILE:
903 add_input_file = p->tv_u.tv_add_input_file;
904 break;
905 case LDPT_ADD_INPUT_LIBRARY:
906 add_input_library = p->tv_u.tv_add_input_library;
907 break;
908 case LDPT_OPTION:
909 process_option (p->tv_u.tv_string);
910 break;
911 default:
912 break;
914 p++;
917 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
918 check (add_symbols, LDPL_FATAL, "add_symbols not found");
919 status = register_claim_file (claim_file_handler);
920 check (status == LDPS_OK, LDPL_FATAL,
921 "could not register the claim_file callback");
923 if (register_cleanup)
925 status = register_cleanup (cleanup_handler);
926 check (status == LDPS_OK, LDPL_FATAL,
927 "could not register the cleanup callback");
930 if (register_all_symbols_read)
932 check (get_symbols, LDPL_FATAL, "get_symbols not found");
933 status = register_all_symbols_read (all_symbols_read_handler);
934 check (status == LDPS_OK, LDPL_FATAL,
935 "could not register the all_symbols_read callback");
938 return LDPS_OK;