]> git.ipfire.org Git - thirdparty/gcc.git/blame - lto-plugin/lto-plugin.c
* lto-plugin.c: Fix typo.
[thirdparty/gcc.git] / lto-plugin / lto-plugin.c
CommitLineData
1cd0b716
DK
1/* LTO plugin for gold and/or GNU ld.
2 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
d7f09764
DN
3 Contributed by Rafael Avila de Espindola (espindola@google.com).
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 3, or (at your option)
8any later version.
9
10This program is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; see the file COPYING3. If not see
17<http://www.gnu.org/licenses/>. */
18
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.
21
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.
26
27 More information at http://gcc.gnu.org/wiki/whopr/driver.
28
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. */
34
48215350
DK
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
d19e0f01
DK
38#if HAVE_STDINT_H
39#include <stdint.h>
40#endif
d7f09764
DN
41#include <assert.h>
42#include <string.h>
43#include <stdlib.h>
44#include <stdio.h>
45#include <inttypes.h>
d7f09764
DN
46#include <sys/stat.h>
47#include <unistd.h>
48#include <fcntl.h>
49#include <sys/types.h>
a2254c5d 50#ifdef HAVE_SYS_WAIT_H
d7f09764 51#include <sys/wait.h>
a2254c5d 52#endif
ec692d5f
KT
53#ifndef WIFEXITED
54#define WIFEXITED(S) (((S) & 0xff) == 0)
55#endif
56#ifndef WEXITSTATUS
57#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
58#endif
d7f09764 59#include <libiberty.h>
d2c57fe9 60#include <hashtab.h>
d7f09764 61#include "../gcc/lto/common.h"
48215350
DK
62#include "simple-object.h"
63#include "plugin-api.h"
d7f09764 64
8cfa7899
KT
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
72
48215350
DK
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
78
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. */
81
82#define LTO_SEGMENT_NAME "__GNU_LTO"
83
84/* LTO magic section name. */
85
86#define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
87#define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
88
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
ad7715f3
L
91 copy the symbol information.
92 The id must be 64bit to minimze collisions. */
48215350
DK
93
94struct sym_aux
95{
96 uint32_t slot;
ad7715f3 97 unsigned long long id;
48215350
DK
98 unsigned next_conflict;
99};
100
101struct plugin_symtab
102{
103 int nsyms;
104 struct sym_aux *aux;
105 struct ld_plugin_symbol *syms;
ad7715f3 106 unsigned long long id;
48215350
DK
107};
108
109/* Encapsulates object file data during symbol scan. */
110struct plugin_objfile
111{
112 int found;
113 simple_object_read *objfile;
114 struct plugin_symtab *out;
115 const struct ld_plugin_input_file *file;
116};
117
118/* All that we have to remember about a file. */
119
120struct plugin_file_info
121{
122 char *name;
123 void *handle;
124 struct plugin_symtab symtab;
125 struct plugin_symtab conflicts;
126};
127
128/* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
129 stdio file streams, we do simple label translation here. */
130
131enum symbol_style
132{
133 ss_none, /* No underscore prefix. */
134 ss_win32, /* Underscore prefix any symbol not beginning with '@'. */
135 ss_uscore, /* Underscore prefix all symbols. */
136};
d7f09764 137
94086ef6 138static char *arguments_file_name;
d7f09764 139static ld_plugin_register_claim_file register_claim_file;
d7f09764 140static ld_plugin_register_all_symbols_read register_all_symbols_read;
ed0d2da0 141static ld_plugin_get_symbols get_symbols, get_symbols_v2;
d7f09764
DN
142static ld_plugin_register_cleanup register_cleanup;
143static ld_plugin_add_input_file add_input_file;
d520c7fb 144static ld_plugin_add_input_library add_input_library;
33662270 145static ld_plugin_message message;
48215350 146static ld_plugin_add_symbols add_symbols;
d7f09764 147
48215350
DK
148static struct plugin_file_info *claimed_files = NULL;
149static unsigned int num_claimed_files = 0;
d7f09764
DN
150
151static char **output_files = NULL;
152static unsigned int num_output_files = 0;
153
154static char **lto_wrapper_argv;
155static int lto_wrapper_num_args;
156
157static char **pass_through_items = NULL;
158static unsigned int num_pass_through_items;
159
d19e0f01
DK
160static char debug;
161static char nop;
b10071c5 162static char *resolution_file = NULL;
d7f09764 163
e3bb089d
ILT
164/* The version of gold being used, or -1 if not gold. The number is
165 MAJOR * 100 + MINOR. */
166static int gold_version = -1;
167
77754180 168/* Not used by default, but can be overridden at runtime
48215350
DK
169 by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
170 (in fact, only first letter of style arg is checked.) */
77754180 171static enum symbol_style sym_style = ss_none;
48215350
DK
172
173static void
d19e0f01 174check_1 (int gate, enum ld_plugin_level level, const char *text)
33662270
RAE
175{
176 if (gate)
177 return;
178
179 if (message)
180 message (level, text);
181 else
182 {
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 ();
187 }
188}
189
d19e0f01
DK
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))
194
d7f09764
DN
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. */
198
48215350 199static char *
73ce4d1e
AK
200parse_table_entry (char *p, struct ld_plugin_symbol *entry,
201 struct sym_aux *aux)
d7f09764
DN
202{
203 unsigned char t;
204 enum ld_plugin_symbol_kind translate_kind[] =
205 {
206 LDPK_DEF,
207 LDPK_WEAKDEF,
208 LDPK_UNDEF,
209 LDPK_WEAKUNDEF,
210 LDPK_COMMON
211 };
212
213 enum ld_plugin_symbol_visibility translate_visibility[] =
214 {
215 LDPV_DEFAULT,
216 LDPV_PROTECTED,
217 LDPV_INTERNAL,
218 LDPV_HIDDEN
219 };
220
48215350
DK
221 switch (sym_style)
222 {
223 case ss_win32:
224 if (p[0] == '@')
225 {
226 /* cf. Duff's device. */
227 case ss_none:
228 entry->name = xstrdup (p);
229 break;
230 }
231 /* FALL-THROUGH. */
232 case ss_uscore:
233 entry->name = concat ("_", p, NULL);
234 break;
235 default:
d19e0f01 236 check (0, LDPL_FATAL, "invalid symbol style requested");
48215350
DK
237 break;
238 }
d7f09764
DN
239 while (*p)
240 p++;
241 p++;
242
243 entry->version = NULL;
244
245 entry->comdat_key = p;
246 while (*p)
247 p++;
248 p++;
249
250 if (strlen (entry->comdat_key) == 0)
251 entry->comdat_key = NULL;
252 else
ed0f0c0f 253 entry->comdat_key = xstrdup (entry->comdat_key);
d7f09764
DN
254
255 t = *p;
33662270 256 check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
d7f09764
DN
257 entry->def = translate_kind[t];
258 p++;
259
260 t = *p;
33662270 261 check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
d7f09764
DN
262 entry->visibility = translate_visibility[t];
263 p++;
264
47782a9d 265 memcpy (&entry->size, p, sizeof (uint64_t));
d7f09764
DN
266 p += 8;
267
47782a9d 268 memcpy (&aux->slot, p, sizeof (uint32_t));
d7f09764
DN
269 p += 4;
270
271 entry->resolution = LDPR_UNKNOWN;
272
d2c57fe9
AK
273 aux->next_conflict = -1;
274
d7f09764
DN
275 return p;
276}
277
1cd0b716
DK
278/* Translate the IL symbol table located between DATA and END. Append the
279 slots and symbols to OUT. */
73ce4d1e 280
48215350 281static void
1cd0b716 282translate (char *data, char *end, struct plugin_symtab *out)
73ce4d1e
AK
283{
284 struct sym_aux *aux;
73ce4d1e
AK
285 struct ld_plugin_symbol *syms = NULL;
286 int n, len;
287
288 /* This overestimates the output buffer sizes, but at least
289 the algorithm is O(1) now. */
290
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));
294
295 for (n = out->nsyms; data < end; n++)
296 {
297 aux[n].id = out->id;
298 data = parse_table_entry (data, &syms[n], &aux[n]);
299 }
300
73ce4d1e
AK
301 assert(n < len);
302
303 out->nsyms = n;
304 out->syms = syms;
305 out->aux = aux;
306}
307
b10071c5
RAE
308/* Free all memory that is no longer needed after writing the symbol
309 resolution. */
d7f09764
DN
310
311static void
312free_1 (void)
313{
314 unsigned int i;
315 for (i = 0; i < num_claimed_files; i++)
316 {
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++)
321 {
322 struct ld_plugin_symbol *s = &symtab->syms[j];
323 free (s->name);
04695783 324 free (s->comdat_key);
d7f09764
DN
325 }
326 free (symtab->syms);
327 symtab->syms = NULL;
328 }
329}
330
331/* Free all remaining memory. */
332
333static void
334free_2 (void)
335{
336 unsigned int i;
337 for (i = 0; i < num_claimed_files; i++)
338 {
339 struct plugin_file_info *info = &claimed_files[i];
340 struct plugin_symtab *symtab = &info->symtab;
73ce4d1e 341 free (symtab->aux);
d7f09764
DN
342 free (info->name);
343 }
344
345 for (i = 0; i < num_output_files; i++)
346 free (output_files[i]);
347 free (output_files);
348
349 free (claimed_files);
350 claimed_files = NULL;
351 num_claimed_files = 0;
352
04695783 353 free (arguments_file_name);
94086ef6 354 arguments_file_name = NULL;
d7f09764
DN
355}
356
d2c57fe9
AK
357/* Dump SYMTAB to resolution file F. */
358
359static void
360dump_symtab (FILE *f, struct plugin_symtab *symtab)
361{
362 unsigned j;
363
364 for (j = 0; j < symtab->nsyms; j++)
365 {
366 uint32_t slot = symtab->aux[j].slot;
367 unsigned int resolution = symtab->syms[j].resolution;
368
369 assert (resolution != LDPR_UNKNOWN);
370
8cfa7899 371 fprintf (f, "%u %" PRI_LL "x %s %s\n",
ad7715f3 372 (unsigned int) slot, symtab->aux[j].id,
d2c57fe9
AK
373 lto_resolution_str[resolution],
374 symtab->syms[j].name);
375 }
376}
377
378/* Finish the conflicts' resolution information after the linker resolved
379 the original symbols */
380
381static void
382finish_conflict_resolution (struct plugin_symtab *symtab,
383 struct plugin_symtab *conflicts)
384{
385 int i, j;
386
387 if (conflicts->nsyms == 0)
388 return;
389
390 for (i = 0; i < symtab->nsyms; i++)
391 {
9df2493c 392 int resolution = LDPR_UNKNOWN;
d2c57fe9
AK
393
394 if (symtab->aux[i].next_conflict == -1)
395 continue;
396
397 switch (symtab->syms[i].def)
398 {
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);
412 }
413
414 assert (resolution != LDPR_UNKNOWN);
415
416 for (j = symtab->aux[i].next_conflict;
417 j != -1;
418 j = conflicts->aux[j].next_conflict)
419 conflicts->syms[j].resolution = resolution;
420 }
421}
422
423/* Free symbol table SYMTAB. */
424
425static void
426free_symtab (struct plugin_symtab *symtab)
427{
428 free (symtab->syms);
429 symtab->syms = NULL;
430 free (symtab->aux);
431 symtab->aux = NULL;
432}
433
d7f09764
DN
434/* Writes the relocations to disk. */
435
436static void
437write_resolution (void)
438{
439 unsigned int i;
440 FILE *f;
d7f09764 441
5cd0e96b 442 check (resolution_file, LDPL_FATAL, "resolution file not specified");
b10071c5 443 f = fopen (resolution_file, "w");
33662270 444 check (f, LDPL_FATAL, "could not open file");
d7f09764
DN
445
446 fprintf (f, "%d\n", num_claimed_files);
447
448 for (i = 0; i < num_claimed_files; i++)
449 {
450 struct plugin_file_info *info = &claimed_files[i];
451 struct plugin_symtab *symtab = &info->symtab;
b10071c5 452 struct ld_plugin_symbol *syms = symtab->syms;
d7f09764 453
ed0d2da0
JH
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);
d7f09764 460
d2c57fe9 461 finish_conflict_resolution (symtab, &info->conflicts);
d7f09764 462
d2c57fe9
AK
463 fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
464 dump_symtab (f, symtab);
465 if (info->conflicts.nsyms)
d7f09764 466 {
d2c57fe9
AK
467 dump_symtab (f, &info->conflicts);
468 free_symtab (&info->conflicts);
d7f09764 469 }
d7f09764
DN
470 }
471 fclose (f);
472}
473
474/* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
475 stdout. */
476
477static void
478add_output_files (FILE *f)
479{
d7f09764
DN
480 for (;;)
481 {
ed0f0c0f
RG
482 const unsigned piece = 32;
483 char *buf, *s = xmalloc (piece);
d7f09764 484 size_t len;
d7f09764 485
ed0f0c0f
RG
486 buf = s;
487cont:
488 if (!fgets (buf, piece, f))
44538c62
KT
489 {
490 free (s);
491 break;
492 }
d7f09764 493 len = strlen (s);
ed0f0c0f
RG
494 if (s[len - 1] != '\n')
495 {
496 s = xrealloc (s, len + piece);
497 buf = s + len;
498 goto cont;
499 }
d7f09764
DN
500 s[len - 1] = '\0';
501
502 num_output_files++;
ed0f0c0f
RG
503 output_files
504 = xrealloc (output_files, num_output_files * sizeof (char *));
505 output_files[num_output_files - 1] = s;
d7f09764
DN
506 add_input_file (output_files[num_output_files - 1]);
507 }
508}
509
510/* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
511 argument list. */
512
513static void
514exec_lto_wrapper (char *argv[])
515{
f0d61983 516 int t, i;
d7f09764
DN
517 int status;
518 char *at_args;
d7f09764
DN
519 FILE *args;
520 FILE *wrapper_output;
521 char *new_argv[3];
522 struct pex_obj *pex;
523 const char *errmsg;
524
525 /* Write argv to a file to avoid a command line that is too long. */
94086ef6
RAE
526 arguments_file_name = make_temp_file ("");
527 check (arguments_file_name, LDPL_FATAL,
528 "Failed to generate a temorary file name");
d7f09764 529
94086ef6 530 args = fopen (arguments_file_name, "w");
33662270 531 check (args, LDPL_FATAL, "could not open arguments file");
d7f09764
DN
532
533 t = writeargv (&argv[1], args);
33662270 534 check (t == 0, LDPL_FATAL, "could not write arguments");
d7f09764 535 t = fclose (args);
33662270 536 check (t == 0, LDPL_FATAL, "could not close arguments file");
d7f09764 537
94086ef6
RAE
538 at_args = concat ("@", arguments_file_name, NULL);
539 check (at_args, LDPL_FATAL, "could not allocate");
540
f0d61983
L
541 for (i = 1; argv[i]; i++)
542 {
543 char *a = argv[i];
544 if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
545 {
546 for (i = 0; argv[i]; i++)
547 fprintf (stderr, "%s ", argv[i]);
548 fprintf (stderr, "\n");
549 break;
550 }
551 }
552
d7f09764
DN
553 new_argv[0] = argv[0];
554 new_argv[1] = at_args;
555 new_argv[2] = NULL;
556
557 if (debug)
558 {
d7f09764
DN
559 for (i = 0; new_argv[i]; i++)
560 fprintf (stderr, "%s ", new_argv[i]);
561 fprintf (stderr, "\n");
562 }
563
564
565 pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
33662270 566 check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
d7f09764
DN
567
568 errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
33662270
RAE
569 check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
570 check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
d7f09764
DN
571
572 wrapper_output = pex_read_output (pex, 0);
33662270 573 check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
d7f09764
DN
574
575 add_output_files (wrapper_output);
576
577 t = pex_get_status (pex, 1, &status);
33662270
RAE
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");
d7f09764
DN
581
582 pex_free (pex);
583
d7f09764
DN
584 free (at_args);
585}
586
587/* Pass the original files back to the linker. */
588
589static void
590use_original_files (void)
591{
592 unsigned i;
593 for (i = 0; i < num_claimed_files; i++)
594 {
595 struct plugin_file_info *info = &claimed_files[i];
596 add_input_file (info->name);
597 }
598}
599
600
601/* Called by the linker once all symbols have been read. */
602
603static enum ld_plugin_status
604all_symbols_read_handler (void)
605{
606 unsigned i;
5cd0e96b 607 unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
d7f09764
DN
608 char **lto_argv;
609 const char **lto_arg_ptr;
610 if (num_claimed_files == 0)
611 return LDPS_OK;
612
d7f09764
DN
613 if (nop)
614 {
615 use_original_files ();
616 return LDPS_OK;
617 }
618
ed0f0c0f 619 lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
d7f09764
DN
620 lto_arg_ptr = (const char **) lto_argv;
621 assert (lto_wrapper_argv);
622
623 write_resolution ();
624
b10071c5
RAE
625 free_1 ();
626
d7f09764
DN
627 for (i = 0; i < lto_wrapper_num_args; i++)
628 *lto_arg_ptr++ = lto_wrapper_argv[i];
629
630 for (i = 0; i < num_claimed_files; i++)
631 {
632 struct plugin_file_info *info = &claimed_files[i];
633
634 *lto_arg_ptr++ = info->name;
635 }
636
637 *lto_arg_ptr++ = NULL;
638 exec_lto_wrapper (lto_argv);
639
640 free (lto_argv);
641
e3bb089d
ILT
642 /* --pass-through is not needed when using gold 1.11 or later. */
643 if (pass_through_items && gold_version < 111)
d7f09764
DN
644 {
645 unsigned int i;
646 for (i = 0; i < num_pass_through_items; i++)
647 {
d520c7fb
RAE
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]);
d7f09764
DN
652 free (pass_through_items[i]);
653 pass_through_items[i] = NULL;
654 }
655 free (pass_through_items);
656 pass_through_items = NULL;
657 }
658
659 return LDPS_OK;
660}
661
662/* Remove temporary files at the end of the link. */
663
664static enum ld_plugin_status
665cleanup_handler (void)
666{
a8a5ac48 667 unsigned int i;
d7f09764 668 int t;
d7f09764 669
1cddcdca
RAE
670 if (debug)
671 return LDPS_OK;
672
94086ef6 673 if (arguments_file_name)
33662270 674 {
94086ef6 675 t = unlink (arguments_file_name);
aff4273c 676 check (t == 0, LDPL_FATAL, "could not unlink arguments file");
33662270 677 }
d7f09764 678
a8a5ac48
DG
679 for (i = 0; i < num_output_files; i++)
680 {
681 t = unlink (output_files[i]);
682 check (t == 0, LDPL_FATAL, "could not unlink output file");
683 }
684
d7f09764
DN
685 free_2 ();
686 return LDPS_OK;
687}
688
d2c57fe9
AK
689#define SWAP(type, a, b) \
690 do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
691
692/* Compare two hash table entries */
693
694static int eq_sym (const void *a, const void *b)
695{
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;
698
699 return !strcmp (as->name, bs->name);
700}
701
702/* Hash a symbol */
703
704static hashval_t hash_sym (const void *a)
705{
706 const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
707
708 return htab_hash_string (as->name);
709}
710
711/* Determine how strong a symbol is */
712
713static int symbol_strength (struct ld_plugin_symbol *s)
714{
715 switch (s->def)
716 {
717 case LDPK_UNDEF:
718 case LDPK_WEAKUNDEF:
719 return 0;
720 case LDPK_WEAKDEF:
721 return 1;
722 default:
723 return 2;
724 }
725}
726
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).
729
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.
732
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.
735
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.
740
741 Then when writing out the resolution file readd the dropped symbols.
742
743 XXX how to handle common? */
744
48215350 745static void
d2c57fe9
AK
746resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
747{
748 htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
749 int i;
750 int out;
751 int outlen;
752
753 outlen = t->nsyms;
754 conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
755 conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
756
3f417959 757 /* Move all duplicate symbols into the auxiliary conflicts table. */
d2c57fe9
AK
758 out = 0;
759 for (i = 0; i < t->nsyms; i++)
760 {
761 struct ld_plugin_symbol *s = &t->syms[i];
762 struct sym_aux *aux = &t->aux[i];
763 void **slot;
764
765 slot = htab_find_slot (symtab, s, INSERT);
766 if (*slot != NULL)
767 {
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];
771
772 /* Always let the linker resolve the strongest symbol */
773 if (symbol_strength (orig) < symbol_strength (s))
774 {
775 SWAP (struct ld_plugin_symbol, *orig, *s);
776 SWAP (uint32_t, orig_aux->slot, aux->slot);
ad7715f3 777 SWAP (unsigned long long, orig_aux->id, aux->id);
d2c57fe9
AK
778 /* Don't swap conflict chain pointer */
779 }
780
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];
786
787 /* Update conflicts chain of the original symbol */
788 aux->next_conflict = orig_aux->next_conflict;
789 orig_aux->next_conflict = cnf;
790
791 continue;
792 }
793
794 /* Remove previous duplicates in the main table */
795 if (out < i)
796 {
797 t->syms[out] = *s;
798 t->aux[out] = *aux;
799 }
800
801 /* Put original into the hash table */
802 *slot = &t->syms[out];
803 out++;
804 }
805
806 assert (conflicts->nsyms <= outlen);
807 assert (conflicts->nsyms + out == t->nsyms);
808
809 t->nsyms = out;
810 htab_delete (symtab);
811}
812
48215350
DK
813/* Process one section of an object file. */
814
815static int
816process_symtab (void *data, const char *name, off_t offset, off_t length)
817{
818 struct plugin_objfile *obj = (struct plugin_objfile *)data;
819 char *s;
820 char *secdata;
821
822 if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
823 return 1;
824
825 s = strrchr (name, '.');
826 if (s)
8cfa7899 827 sscanf (s, ".%" PRI_LL "x", &obj->out->id);
48215350
DK
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))
832 {
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;
839 }
840
841 translate (secdata, secdata + length, obj->out);
842 obj->found++;
843 free (secdata);
844 return 1;
845}
846
847/* Callback used by gold to check if the plugin will claim FILE. Writes
848 the result in CLAIMED. */
849
850static enum ld_plugin_status
851claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
852{
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;
858
859 memset (&lto_file, 0, sizeof (struct plugin_file_info));
860
861 if (file->offset != 0)
862 {
863 char *objname;
d19e0f01
DK
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. */
3b8c1a3f 867 int lo, hi, t;
d19e0f01
DK
868 lo = file->offset & 0xffffffff;
869 hi = ((int64_t)file->offset >> 32) & 0xffffffff;
3b8c1a3f
RG
870 t = hi ? asprintf (&objname, "%s@0x%x%08x", file->name, lo, hi)
871 : asprintf (&objname, "%s@0x%x", file->name, lo);
48215350
DK
872 check (t >= 0, LDPL_FATAL, "asprintf failed");
873 lto_file.name = objname;
874 }
875 else
876 {
877 lto_file.name = xstrdup (file->name);
878 }
879 lto_file.handle = file->handle;
880
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;
891
892 if (obj.objfile)
893 errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
894
895 if (!obj.objfile || errmsg)
896 {
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;
903 }
904
905 if (obj.found == 0)
906 goto err;
907
908 if (obj.found > 1)
909 resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
910
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");
914
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;
921
922 goto cleanup;
923
924 err:
925 free (lto_file.name);
926
927 cleanup:
928 if (obj.objfile)
929 simple_object_release_read (obj.objfile);
48215350
DK
930
931 return LDPS_OK;
932}
933
d7f09764
DN
934/* Parse the plugin options. */
935
936static void
937process_option (const char *option)
938{
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=")))
944 {
945 num_pass_through_items++;
ed0f0c0f
RG
946 pass_through_items = xrealloc (pass_through_items,
947 num_pass_through_items * sizeof (char *));
d520c7fb 948 pass_through_items[num_pass_through_items - 1] =
ed0f0c0f 949 xstrdup (option + strlen ("-pass-through="));
d7f09764 950 }
48215350
DK
951 else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
952 {
953 switch (option[sizeof ("-sym-style=") - 1])
954 {
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;
964 }
965 }
d7f09764
DN
966 else
967 {
968 int size;
5cd0e96b 969 char *opt = xstrdup (option);
d7f09764
DN
970 lto_wrapper_num_args += 1;
971 size = lto_wrapper_num_args * sizeof (char *);
ed0f0c0f 972 lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
5cd0e96b
RG
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;
d7f09764
DN
976 }
977}
978
979/* Called by gold after loading the plugin. TV is the transfer vector. */
980
981enum ld_plugin_status
982onload (struct ld_plugin_tv *tv)
983{
984 struct ld_plugin_tv *p;
985 enum ld_plugin_status status;
d7f09764 986
d7f09764
DN
987 p = tv;
988 while (p->tv_tag)
989 {
990 switch (p->tv_tag)
991 {
33662270
RAE
992 case LDPT_MESSAGE:
993 message = p->tv_u.tv_message;
994 break;
d7f09764
DN
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;
ed0d2da0
JH
1004 case LDPT_GET_SYMBOLS_V2:
1005 get_symbols_v2 = p->tv_u.tv_get_symbols;
1006 break;
d7f09764
DN
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;
d520c7fb
RAE
1016 case LDPT_ADD_INPUT_LIBRARY:
1017 add_input_library = p->tv_u.tv_add_input_library;
1018 break;
d7f09764
DN
1019 case LDPT_OPTION:
1020 process_option (p->tv_u.tv_string);
1021 break;
e3bb089d
ILT
1022 case LDPT_GOLD_VERSION:
1023 gold_version = p->tv_u.tv_val;
1024 break;
d7f09764
DN
1025 default:
1026 break;
1027 }
1028 p++;
1029 }
1030
33662270
RAE
1031 check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1032 check (add_symbols, LDPL_FATAL, "add_symbols not found");
d7f09764 1033 status = register_claim_file (claim_file_handler);
33662270
RAE
1034 check (status == LDPS_OK, LDPL_FATAL,
1035 "could not register the claim_file callback");
d7f09764
DN
1036
1037 if (register_cleanup)
1038 {
1039 status = register_cleanup (cleanup_handler);
33662270
RAE
1040 check (status == LDPS_OK, LDPL_FATAL,
1041 "could not register the cleanup callback");
d7f09764
DN
1042 }
1043
1044 if (register_all_symbols_read)
1045 {
33662270 1046 check (get_symbols, LDPL_FATAL, "get_symbols not found");
d7f09764 1047 status = register_all_symbols_read (all_symbols_read_handler);
33662270
RAE
1048 check (status == LDPS_OK, LDPL_FATAL,
1049 "could not register the all_symbols_read callback");
d7f09764
DN
1050 }
1051
d7f09764
DN
1052 return LDPS_OK;
1053}