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)
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. */
50 #include <sys/types.h>
51 #ifdef HAVE_SYS_WAIT_H
55 #define WIFEXITED(S) (((S) & 0xff) == 0)
58 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
60 #include <libiberty.h>
62 #include "../gcc/lto/common.h"
63 #include "simple-object.h"
64 #include "plugin-api.h"
66 /* We need to use I64 instead of ll width-specifier on native Windows.
67 The reason for this is that older MS-runtimes don't support the ll. */
74 /* Handle opening elf files on hosts, such as Windows, that may use
75 text file handling that will break binary access. */
80 /* Segment name for LTO sections. This is only used for Mach-O.
81 FIXME: This needs to be kept in sync with darwin.c. */
83 #define LTO_SEGMENT_NAME "__GNU_LTO"
85 /* LTO magic section name. */
87 #define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
88 #define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
90 /* The part of the symbol table the plugin has to keep track of. Note that we
91 must keep SYMS until all_symbols_read is called to give the linker time to
92 copy the symbol information.
93 The id must be 64bit to minimze collisions. */
98 unsigned long long id
;
99 unsigned next_conflict
;
106 struct ld_plugin_symbol
*syms
;
107 unsigned long long id
;
110 /* Encapsulates object file data during symbol scan. */
111 struct plugin_objfile
114 simple_object_read
*objfile
;
115 struct plugin_symtab
*out
;
116 const struct ld_plugin_input_file
*file
;
119 /* All that we have to remember about a file. */
121 struct plugin_file_info
125 struct plugin_symtab symtab
;
126 struct plugin_symtab conflicts
;
129 /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
130 stdio file streams, we do simple label translation here. */
134 ss_none
, /* No underscore prefix. */
135 ss_win32
, /* Underscore prefix any symbol not beginning with '@'. */
136 ss_uscore
, /* Underscore prefix all symbols. */
139 static char *arguments_file_name
;
140 static ld_plugin_register_claim_file register_claim_file
;
141 static ld_plugin_register_all_symbols_read register_all_symbols_read
;
142 static ld_plugin_get_symbols get_symbols
, get_symbols_v2
;
143 static ld_plugin_register_cleanup register_cleanup
;
144 static ld_plugin_add_input_file add_input_file
;
145 static ld_plugin_add_input_library add_input_library
;
146 static ld_plugin_message message
;
147 static ld_plugin_add_symbols add_symbols
;
149 static struct plugin_file_info
*claimed_files
= NULL
;
150 static unsigned int num_claimed_files
= 0;
152 static char **output_files
= NULL
;
153 static unsigned int num_output_files
= 0;
155 static char **lto_wrapper_argv
;
156 static int lto_wrapper_num_args
;
158 static char **pass_through_items
= NULL
;
159 static unsigned int num_pass_through_items
;
163 static char *resolution_file
= NULL
;
165 /* The version of gold being used, or -1 if not gold. The number is
166 MAJOR * 100 + MINOR. */
167 static int gold_version
= -1;
169 /* Not used by default, but can be overridden at runtime
170 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
171 (in fact, only first letter of style arg is checked.) */
172 static enum symbol_style sym_style
= ss_none
;
175 check_1 (int gate
, enum ld_plugin_level level
, const char *text
)
181 message (level
, text
);
184 /* If there is no nicer way to inform the user, fallback to stderr. */
185 fprintf (stderr
, "%s\n", text
);
186 if (level
== LDPL_FATAL
)
191 /* This little wrapper allows check to be called with a non-integer
192 first argument, such as a pointer that must be non-NULL. We can't
193 use c99 bool type to coerce it into range, so we explicitly test. */
194 #define check(GATE, LEVEL, TEXT) check_1 (((GATE) != 0), (LEVEL), (TEXT))
196 /* Parse an entry of the IL symbol table. The data to be parsed is pointed
197 by P and the result is written in ENTRY. The slot number is stored in SLOT.
198 Returns the address of the next entry. */
201 parse_table_entry (char *p
, struct ld_plugin_symbol
*entry
,
205 enum ld_plugin_symbol_kind translate_kind
[] =
214 enum ld_plugin_symbol_visibility translate_visibility
[] =
227 /* cf. Duff's device. */
229 entry
->name
= xstrdup (p
);
234 entry
->name
= concat ("_", p
, NULL
);
237 check (0, LDPL_FATAL
, "invalid symbol style requested");
244 entry
->version
= NULL
;
246 entry
->comdat_key
= p
;
251 if (strlen (entry
->comdat_key
) == 0)
252 entry
->comdat_key
= NULL
;
254 entry
->comdat_key
= xstrdup (entry
->comdat_key
);
257 check (t
<= 4, LDPL_FATAL
, "invalid symbol kind found");
258 entry
->def
= translate_kind
[t
];
262 check (t
<= 3, LDPL_FATAL
, "invalid symbol visibility found");
263 entry
->visibility
= translate_visibility
[t
];
266 memcpy (&entry
->size
, p
, sizeof (uint64_t));
269 memcpy (&aux
->slot
, p
, sizeof (uint32_t));
272 entry
->resolution
= LDPR_UNKNOWN
;
274 aux
->next_conflict
= -1;
279 /* Translate the IL symbol table located between DATA and END. Append the
280 slots and symbols to OUT. */
283 translate (char *data
, char *end
, struct plugin_symtab
*out
)
286 struct ld_plugin_symbol
*syms
= NULL
;
289 /* This overestimates the output buffer sizes, but at least
290 the algorithm is O(1) now. */
292 len
= (end
- data
)/8 + out
->nsyms
+ 1;
293 syms
= xrealloc (out
->syms
, len
* sizeof (struct ld_plugin_symbol
));
294 aux
= xrealloc (out
->aux
, len
* sizeof (struct sym_aux
));
296 for (n
= out
->nsyms
; data
< end
; n
++)
299 data
= parse_table_entry (data
, &syms
[n
], &aux
[n
]);
309 /* Free all memory that is no longer needed after writing the symbol
316 for (i
= 0; i
< num_claimed_files
; i
++)
318 struct plugin_file_info
*info
= &claimed_files
[i
];
319 struct plugin_symtab
*symtab
= &info
->symtab
;
321 for (j
= 0; j
< symtab
->nsyms
; j
++)
323 struct ld_plugin_symbol
*s
= &symtab
->syms
[j
];
325 free (s
->comdat_key
);
332 /* Free all remaining memory. */
338 for (i
= 0; i
< num_claimed_files
; i
++)
340 struct plugin_file_info
*info
= &claimed_files
[i
];
341 struct plugin_symtab
*symtab
= &info
->symtab
;
346 for (i
= 0; i
< num_output_files
; i
++)
347 free (output_files
[i
]);
350 free (claimed_files
);
351 claimed_files
= NULL
;
352 num_claimed_files
= 0;
354 free (arguments_file_name
);
355 arguments_file_name
= NULL
;
358 /* Dump SYMTAB to resolution file F. */
361 dump_symtab (FILE *f
, struct plugin_symtab
*symtab
)
365 for (j
= 0; j
< symtab
->nsyms
; j
++)
367 uint32_t slot
= symtab
->aux
[j
].slot
;
368 unsigned int resolution
= symtab
->syms
[j
].resolution
;
370 assert (resolution
!= LDPR_UNKNOWN
);
372 fprintf (f
, "%u %" PRI_LL
"x %s %s\n",
373 (unsigned int) slot
, symtab
->aux
[j
].id
,
374 lto_resolution_str
[resolution
],
375 symtab
->syms
[j
].name
);
379 /* Finish the conflicts' resolution information after the linker resolved
380 the original symbols */
383 finish_conflict_resolution (struct plugin_symtab
*symtab
,
384 struct plugin_symtab
*conflicts
)
388 if (conflicts
->nsyms
== 0)
391 for (i
= 0; i
< symtab
->nsyms
; i
++)
393 int resolution
= LDPR_UNKNOWN
;
395 if (symtab
->aux
[i
].next_conflict
== -1)
398 switch (symtab
->syms
[i
].def
)
401 case LDPK_COMMON
: /* ??? */
402 resolution
= LDPR_RESOLVED_IR
;
405 resolution
= LDPR_PREEMPTED_IR
;
409 resolution
= symtab
->syms
[i
].resolution
;
415 assert (resolution
!= LDPR_UNKNOWN
);
417 for (j
= symtab
->aux
[i
].next_conflict
;
419 j
= conflicts
->aux
[j
].next_conflict
)
420 conflicts
->syms
[j
].resolution
= resolution
;
424 /* Free symbol table SYMTAB. */
427 free_symtab (struct plugin_symtab
*symtab
)
435 /* Writes the relocations to disk. */
438 write_resolution (void)
443 check (resolution_file
, LDPL_FATAL
, "resolution file not specified");
444 f
= fopen (resolution_file
, "w");
445 check (f
, LDPL_FATAL
, "could not open file");
447 fprintf (f
, "%d\n", num_claimed_files
);
449 for (i
= 0; i
< num_claimed_files
; i
++)
451 struct plugin_file_info
*info
= &claimed_files
[i
];
452 struct plugin_symtab
*symtab
= &info
->symtab
;
453 struct ld_plugin_symbol
*syms
= symtab
->syms
;
455 /* Version 2 of API supports IRONLY_EXP resolution that is
456 accepted by GCC-4.7 and newer. */
458 get_symbols_v2 (info
->handle
, symtab
->nsyms
, syms
);
460 get_symbols (info
->handle
, symtab
->nsyms
, syms
);
462 finish_conflict_resolution (symtab
, &info
->conflicts
);
464 fprintf (f
, "%s %d\n", info
->name
, symtab
->nsyms
+ info
->conflicts
.nsyms
);
465 dump_symtab (f
, symtab
);
466 if (info
->conflicts
.nsyms
)
468 dump_symtab (f
, &info
->conflicts
);
469 free_symtab (&info
->conflicts
);
475 /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
479 add_output_files (FILE *f
)
483 const unsigned piece
= 32;
484 char *buf
, *s
= xmalloc (piece
);
489 if (!fgets (buf
, piece
, f
))
495 if (s
[len
- 1] != '\n')
497 s
= xrealloc (s
, len
+ piece
);
505 = xrealloc (output_files
, num_output_files
* sizeof (char *));
506 output_files
[num_output_files
- 1] = s
;
507 add_input_file (output_files
[num_output_files
- 1]);
511 /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
515 exec_lto_wrapper (char *argv
[])
521 FILE *wrapper_output
;
526 /* Write argv to a file to avoid a command line that is too long. */
527 arguments_file_name
= make_temp_file ("");
528 check (arguments_file_name
, LDPL_FATAL
,
529 "Failed to generate a temorary file name");
531 args
= fopen (arguments_file_name
, "w");
532 check (args
, LDPL_FATAL
, "could not open arguments file");
534 t
= writeargv (&argv
[1], args
);
535 check (t
== 0, LDPL_FATAL
, "could not write arguments");
537 check (t
== 0, LDPL_FATAL
, "could not close arguments file");
539 at_args
= concat ("@", arguments_file_name
, NULL
);
540 check (at_args
, LDPL_FATAL
, "could not allocate");
542 for (i
= 1; argv
[i
]; i
++)
545 if (a
[0] == '-' && a
[1] == 'v' && a
[2] == '\0')
547 for (i
= 0; argv
[i
]; i
++)
548 fprintf (stderr
, "%s ", argv
[i
]);
549 fprintf (stderr
, "\n");
554 new_argv
[0] = argv
[0];
555 new_argv
[1] = at_args
;
560 for (i
= 0; new_argv
[i
]; i
++)
561 fprintf (stderr
, "%s ", new_argv
[i
]);
562 fprintf (stderr
, "\n");
566 pex
= pex_init (PEX_USE_PIPES
, "lto-wrapper", NULL
);
567 check (pex
!= NULL
, LDPL_FATAL
, "could not pex_init lto-wrapper");
569 errmsg
= pex_run (pex
, 0, new_argv
[0], new_argv
, NULL
, NULL
, &t
);
570 check (errmsg
== NULL
, LDPL_FATAL
, "could not run lto-wrapper");
571 check (t
== 0, LDPL_FATAL
, "could not run lto-wrapper");
573 wrapper_output
= pex_read_output (pex
, 0);
574 check (wrapper_output
, LDPL_FATAL
, "could not read lto-wrapper output");
576 add_output_files (wrapper_output
);
578 t
= pex_get_status (pex
, 1, &status
);
579 check (t
== 1, LDPL_FATAL
, "could not get lto-wrapper exit status");
580 check (WIFEXITED (status
) && WEXITSTATUS (status
) == 0, LDPL_FATAL
,
581 "lto-wrapper failed");
588 /* Pass the original files back to the linker. */
591 use_original_files (void)
594 for (i
= 0; i
< num_claimed_files
; i
++)
596 struct plugin_file_info
*info
= &claimed_files
[i
];
597 add_input_file (info
->name
);
602 /* Called by the linker once all symbols have been read. */
604 static enum ld_plugin_status
605 all_symbols_read_handler (void)
608 unsigned num_lto_args
= num_claimed_files
+ lto_wrapper_num_args
+ 1;
610 const char **lto_arg_ptr
;
611 if (num_claimed_files
== 0)
616 use_original_files ();
620 lto_argv
= (char **) xcalloc (sizeof (char *), num_lto_args
);
621 lto_arg_ptr
= (const char **) lto_argv
;
622 assert (lto_wrapper_argv
);
628 for (i
= 0; i
< lto_wrapper_num_args
; i
++)
629 *lto_arg_ptr
++ = lto_wrapper_argv
[i
];
631 for (i
= 0; i
< num_claimed_files
; i
++)
633 struct plugin_file_info
*info
= &claimed_files
[i
];
635 *lto_arg_ptr
++ = info
->name
;
638 *lto_arg_ptr
++ = NULL
;
639 exec_lto_wrapper (lto_argv
);
643 /* --pass-through is not needed when using gold 1.11 or later. */
644 if (pass_through_items
&& gold_version
< 111)
647 for (i
= 0; i
< num_pass_through_items
; i
++)
649 if (strncmp (pass_through_items
[i
], "-l", 2) == 0)
650 add_input_library (pass_through_items
[i
] + 2);
652 add_input_file (pass_through_items
[i
]);
653 free (pass_through_items
[i
]);
654 pass_through_items
[i
] = NULL
;
656 free (pass_through_items
);
657 pass_through_items
= NULL
;
663 /* Remove temporary files at the end of the link. */
665 static enum ld_plugin_status
666 cleanup_handler (void)
674 if (arguments_file_name
)
676 t
= unlink (arguments_file_name
);
677 check (t
== 0, LDPL_FATAL
, "could not unlink arguments file");
680 for (i
= 0; i
< num_output_files
; i
++)
682 t
= unlink (output_files
[i
]);
683 check (t
== 0, LDPL_FATAL
, "could not unlink output file");
690 #define SWAP(type, a, b) \
691 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
693 /* Compare two hash table entries */
695 static int eq_sym (const void *a
, const void *b
)
697 const struct ld_plugin_symbol
*as
= (const struct ld_plugin_symbol
*)a
;
698 const struct ld_plugin_symbol
*bs
= (const struct ld_plugin_symbol
*)b
;
700 return !strcmp (as
->name
, bs
->name
);
705 static hashval_t
hash_sym (const void *a
)
707 const struct ld_plugin_symbol
*as
= (const struct ld_plugin_symbol
*)a
;
709 return htab_hash_string (as
->name
);
712 /* Determine how strong a symbol is */
714 static int symbol_strength (struct ld_plugin_symbol
*s
)
728 /* In the ld -r case we can get dups in the LTO symbol tables, where
729 the same symbol can have different resolutions (e.g. undefined and defined).
731 We have to keep that in the LTO symbol tables, but the dups confuse
732 gold and then finally gcc by supplying incorrect resolutions.
734 Problem is that the main gold symbol table doesn't know about subids
735 and does not distingush the same symbols in different states.
737 So we drop duplicates from the linker visible symbol table
738 and keep them in a private table. Then later do own symbol
739 resolution for the duplicated based on the results for the
742 Then when writing out the resolution file readd the dropped symbols.
744 XXX how to handle common? */
747 resolve_conflicts (struct plugin_symtab
*t
, struct plugin_symtab
*conflicts
)
749 htab_t symtab
= htab_create (t
->nsyms
, hash_sym
, eq_sym
, NULL
);
755 conflicts
->syms
= xmalloc (sizeof (struct ld_plugin_symbol
) * outlen
);
756 conflicts
->aux
= xmalloc (sizeof (struct sym_aux
) * outlen
);
758 /* Move all duplicate symbols into the auxiliary conflicts table. */
760 for (i
= 0; i
< t
->nsyms
; i
++)
762 struct ld_plugin_symbol
*s
= &t
->syms
[i
];
763 struct sym_aux
*aux
= &t
->aux
[i
];
766 slot
= htab_find_slot (symtab
, s
, INSERT
);
770 struct ld_plugin_symbol
*orig
= (struct ld_plugin_symbol
*)*slot
;
771 struct sym_aux
*orig_aux
= &t
->aux
[orig
- t
->syms
];
773 /* Always let the linker resolve the strongest symbol */
774 if (symbol_strength (orig
) < symbol_strength (s
))
776 SWAP (struct ld_plugin_symbol
, *orig
, *s
);
777 SWAP (uint32_t, orig_aux
->slot
, aux
->slot
);
778 SWAP (unsigned long long, orig_aux
->id
, aux
->id
);
779 /* Don't swap conflict chain pointer */
782 /* Move current symbol into the conflicts table */
783 cnf
= conflicts
->nsyms
++;
784 conflicts
->syms
[cnf
] = *s
;
785 conflicts
->aux
[cnf
] = *aux
;
786 aux
= &conflicts
->aux
[cnf
];
788 /* Update conflicts chain of the original symbol */
789 aux
->next_conflict
= orig_aux
->next_conflict
;
790 orig_aux
->next_conflict
= cnf
;
795 /* Remove previous duplicates in the main table */
802 /* Put original into the hash table */
803 *slot
= &t
->syms
[out
];
807 assert (conflicts
->nsyms
<= outlen
);
808 assert (conflicts
->nsyms
+ out
== t
->nsyms
);
811 htab_delete (symtab
);
814 /* Process one section of an object file. */
817 process_symtab (void *data
, const char *name
, off_t offset
, off_t length
)
819 struct plugin_objfile
*obj
= (struct plugin_objfile
*)data
;
821 char *secdatastart
, *secdata
;
823 if (strncmp (name
, LTO_SECTION_PREFIX
, LTO_SECTION_PREFIX_LEN
) != 0)
826 s
= strrchr (name
, '.');
828 sscanf (s
, ".%" PRI_LL
"x", &obj
->out
->id
);
829 secdata
= secdatastart
= xmalloc (length
);
830 offset
+= obj
->file
->offset
;
831 if (offset
!= lseek (obj
->file
->fd
, offset
, SEEK_SET
))
836 ssize_t got
= read (obj
->file
->fd
, secdata
, length
);
844 else if (errno
!= EINTR
)
851 translate (secdatastart
, secdata
, obj
->out
);
858 message (LDPL_FATAL
, "%s: corrupt object file", obj
->file
->name
);
859 /* Force claim_file_handler to abandon this file. */
865 /* Callback used by gold to check if the plugin will claim FILE. Writes
866 the result in CLAIMED. */
868 static enum ld_plugin_status
869 claim_file_handler (const struct ld_plugin_input_file
*file
, int *claimed
)
871 enum ld_plugin_status status
;
872 struct plugin_objfile obj
;
873 struct plugin_file_info lto_file
;
877 memset (<o_file
, 0, sizeof (struct plugin_file_info
));
879 if (file
->offset
!= 0)
882 /* We pass the offset of the actual file, not the archive header.
883 Can't use PRIx64, because that's C99, so we have to print the
884 64-bit hex int as two 32-bit ones. */
886 lo
= file
->offset
& 0xffffffff;
887 hi
= ((int64_t)file
->offset
>> 32) & 0xffffffff;
888 t
= hi
? asprintf (&objname
, "%s@0x%x%08x", file
->name
, lo
, hi
)
889 : asprintf (&objname
, "%s@0x%x", file
->name
, lo
);
890 check (t
>= 0, LDPL_FATAL
, "asprintf failed");
891 lto_file
.name
= objname
;
895 lto_file
.name
= xstrdup (file
->name
);
897 lto_file
.handle
= file
->handle
;
902 obj
.out
= <o_file
.symtab
;
904 obj
.objfile
= simple_object_start_read (file
->fd
, file
->offset
, LTO_SEGMENT_NAME
,
906 /* No file, but also no error code means unrecognized format; just skip it. */
907 if (!obj
.objfile
&& !err
)
911 errmsg
= simple_object_find_sections (obj
.objfile
, process_symtab
, &obj
, &err
);
913 if (!obj
.objfile
|| errmsg
)
916 message (LDPL_FATAL
, "%s: %s: %s", file
->name
, errmsg
,
919 message (LDPL_FATAL
, "%s: %s", file
->name
, errmsg
);
927 resolve_conflicts (<o_file
.symtab
, <o_file
.conflicts
);
929 status
= add_symbols (file
->handle
, lto_file
.symtab
.nsyms
,
930 lto_file
.symtab
.syms
);
931 check (status
== LDPS_OK
, LDPL_FATAL
, "could not add symbols");
936 xrealloc (claimed_files
,
937 num_claimed_files
* sizeof (struct plugin_file_info
));
938 claimed_files
[num_claimed_files
- 1] = lto_file
;
943 free (lto_file
.name
);
947 simple_object_release_read (obj
.objfile
);
952 /* Parse the plugin options. */
955 process_option (const char *option
)
957 if (strcmp (option
, "-debug") == 0)
959 else if (strcmp (option
, "-nop") == 0)
961 else if (!strncmp (option
, "-pass-through=", strlen("-pass-through=")))
963 num_pass_through_items
++;
964 pass_through_items
= xrealloc (pass_through_items
,
965 num_pass_through_items
* sizeof (char *));
966 pass_through_items
[num_pass_through_items
- 1] =
967 xstrdup (option
+ strlen ("-pass-through="));
969 else if (!strncmp (option
, "-sym-style=", sizeof ("-sym-style=") - 1))
971 switch (option
[sizeof ("-sym-style=") - 1])
974 sym_style
= ss_win32
;
977 sym_style
= ss_uscore
;
987 char *opt
= xstrdup (option
);
988 lto_wrapper_num_args
+= 1;
989 size
= lto_wrapper_num_args
* sizeof (char *);
990 lto_wrapper_argv
= (char **) xrealloc (lto_wrapper_argv
, size
);
991 lto_wrapper_argv
[lto_wrapper_num_args
- 1] = opt
;
992 if (strncmp (option
, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
993 resolution_file
= opt
+ sizeof ("-fresolution=") - 1;
997 /* Called by gold after loading the plugin. TV is the transfer vector. */
999 enum ld_plugin_status
1000 onload (struct ld_plugin_tv
*tv
)
1002 struct ld_plugin_tv
*p
;
1003 enum ld_plugin_status status
;
1011 message
= p
->tv_u
.tv_message
;
1013 case LDPT_REGISTER_CLAIM_FILE_HOOK
:
1014 register_claim_file
= p
->tv_u
.tv_register_claim_file
;
1016 case LDPT_ADD_SYMBOLS
:
1017 add_symbols
= p
->tv_u
.tv_add_symbols
;
1019 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
:
1020 register_all_symbols_read
= p
->tv_u
.tv_register_all_symbols_read
;
1022 case LDPT_GET_SYMBOLS_V2
:
1023 get_symbols_v2
= p
->tv_u
.tv_get_symbols
;
1025 case LDPT_GET_SYMBOLS
:
1026 get_symbols
= p
->tv_u
.tv_get_symbols
;
1028 case LDPT_REGISTER_CLEANUP_HOOK
:
1029 register_cleanup
= p
->tv_u
.tv_register_cleanup
;
1031 case LDPT_ADD_INPUT_FILE
:
1032 add_input_file
= p
->tv_u
.tv_add_input_file
;
1034 case LDPT_ADD_INPUT_LIBRARY
:
1035 add_input_library
= p
->tv_u
.tv_add_input_library
;
1038 process_option (p
->tv_u
.tv_string
);
1040 case LDPT_GOLD_VERSION
:
1041 gold_version
= p
->tv_u
.tv_val
;
1049 check (register_claim_file
, LDPL_FATAL
, "register_claim_file not found");
1050 check (add_symbols
, LDPL_FATAL
, "add_symbols not found");
1051 status
= register_claim_file (claim_file_handler
);
1052 check (status
== LDPS_OK
, LDPL_FATAL
,
1053 "could not register the claim_file callback");
1055 if (register_cleanup
)
1057 status
= register_cleanup (cleanup_handler
);
1058 check (status
== LDPS_OK
, LDPL_FATAL
,
1059 "could not register the cleanup callback");
1062 if (register_all_symbols_read
)
1064 check (get_symbols
, LDPL_FATAL
, "get_symbols not found");
1065 status
= register_all_symbols_read (all_symbols_read_handler
);
1066 check (status
== LDPS_OK
, LDPL_FATAL
,
1067 "could not register the all_symbols_read callback");
1070 /* Support -fno-use-linker-plugin by failing to load the plugin
1071 for the case where it is auto-loaded by BFD. */
1072 char *collect_gcc_options
= getenv ("COLLECT_GCC_OPTIONS");
1073 if (collect_gcc_options
1074 && strstr (collect_gcc_options
, "'-fno-use-linker-plugin'"))