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