1*38fd1498Szrj /* LTO plugin for gold and/or GNU ld.
2*38fd1498Szrj    Copyright (C) 2009-2018 Free Software Foundation, Inc.
3*38fd1498Szrj    Contributed by Rafael Avila de Espindola (espindola@google.com).
4*38fd1498Szrj 
5*38fd1498Szrj This program is free software; you can redistribute it and/or modify
6*38fd1498Szrj it under the terms of the GNU General Public License as published by
7*38fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
8*38fd1498Szrj any later version.
9*38fd1498Szrj 
10*38fd1498Szrj This program is distributed in the hope that it will be useful, but
11*38fd1498Szrj WITHOUT ANY WARRANTY; without even the implied warranty of
12*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*38fd1498Szrj General Public License for more details.
14*38fd1498Szrj 
15*38fd1498Szrj You should have received a copy of the GNU General Public License
16*38fd1498Szrj along with this program; see the file COPYING3.  If not see
17*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
18*38fd1498Szrj 
19*38fd1498Szrj /* The plugin has only one external function: onload. Gold passes it an array of
20*38fd1498Szrj    function that the plugin uses to communicate back to gold.
21*38fd1498Szrj 
22*38fd1498Szrj    With the functions provided by gold, the plugin can be notified when
23*38fd1498Szrj    gold first analyzes a file and pass a symbol table back to gold. The plugin
24*38fd1498Szrj    is also notified when all symbols have been read and it is time to generate
25*38fd1498Szrj    machine code for the necessary symbols.
26*38fd1498Szrj 
27*38fd1498Szrj    More information at http://gcc.gnu.org/wiki/whopr/driver.
28*38fd1498Szrj 
29*38fd1498Szrj    This plugin should be passed the lto-wrapper options and will forward them.
30*38fd1498Szrj    It also has 2 options of its own:
31*38fd1498Szrj    -debug: Print the command line used to run lto-wrapper.
32*38fd1498Szrj    -nop: Instead of running lto-wrapper, pass the original to the plugin. This
33*38fd1498Szrj    only works if the input files are hybrid.  */
34*38fd1498Szrj 
35*38fd1498Szrj #ifdef HAVE_CONFIG_H
36*38fd1498Szrj #include "config.h"
37*38fd1498Szrj #endif
38*38fd1498Szrj #if HAVE_STDINT_H
39*38fd1498Szrj #include <stdint.h>
40*38fd1498Szrj #endif
41*38fd1498Szrj #include <assert.h>
42*38fd1498Szrj #include <errno.h>
43*38fd1498Szrj #include <string.h>
44*38fd1498Szrj #include <stdlib.h>
45*38fd1498Szrj #include <stdio.h>
46*38fd1498Szrj #include <inttypes.h>
47*38fd1498Szrj #include <sys/stat.h>
48*38fd1498Szrj #include <unistd.h>
49*38fd1498Szrj #include <fcntl.h>
50*38fd1498Szrj #include <sys/types.h>
51*38fd1498Szrj #ifdef HAVE_SYS_WAIT_H
52*38fd1498Szrj #include <sys/wait.h>
53*38fd1498Szrj #endif
54*38fd1498Szrj #ifndef WIFEXITED
55*38fd1498Szrj #define WIFEXITED(S) (((S) & 0xff) == 0)
56*38fd1498Szrj #endif
57*38fd1498Szrj #ifndef WEXITSTATUS
58*38fd1498Szrj #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
59*38fd1498Szrj #endif
60*38fd1498Szrj #include <libiberty.h>
61*38fd1498Szrj #include <hashtab.h>
62*38fd1498Szrj #include "../gcc/lto/common.h"
63*38fd1498Szrj #include "simple-object.h"
64*38fd1498Szrj #include "plugin-api.h"
65*38fd1498Szrj 
66*38fd1498Szrj /* We need to use I64 instead of ll width-specifier on native Windows.
67*38fd1498Szrj    The reason for this is that older MS-runtimes don't support the ll.  */
68*38fd1498Szrj #ifdef __MINGW32__
69*38fd1498Szrj #define PRI_LL "I64"
70*38fd1498Szrj #else
71*38fd1498Szrj #define PRI_LL "ll"
72*38fd1498Szrj #endif
73*38fd1498Szrj 
74*38fd1498Szrj /* Handle opening elf files on hosts, such as Windows, that may use
75*38fd1498Szrj    text file handling that will break binary access.  */
76*38fd1498Szrj #ifndef O_BINARY
77*38fd1498Szrj # define O_BINARY 0
78*38fd1498Szrj #endif
79*38fd1498Szrj 
80*38fd1498Szrj /* Segment name for LTO sections.  This is only used for Mach-O.
81*38fd1498Szrj    FIXME: This needs to be kept in sync with darwin.c.  */
82*38fd1498Szrj 
83*38fd1498Szrj #define LTO_SEGMENT_NAME "__GNU_LTO"
84*38fd1498Szrj 
85*38fd1498Szrj /* LTO magic section name.  */
86*38fd1498Szrj 
87*38fd1498Szrj #define LTO_SECTION_PREFIX	".gnu.lto_.symtab"
88*38fd1498Szrj #define LTO_SECTION_PREFIX_LEN	(sizeof (LTO_SECTION_PREFIX) - 1)
89*38fd1498Szrj #define OFFLOAD_SECTION		".gnu.offload_lto_.opts"
90*38fd1498Szrj #define OFFLOAD_SECTION_LEN	(sizeof (OFFLOAD_SECTION) - 1)
91*38fd1498Szrj 
92*38fd1498Szrj /* The part of the symbol table the plugin has to keep track of. Note that we
93*38fd1498Szrj    must keep SYMS until all_symbols_read is called to give the linker time to
94*38fd1498Szrj    copy the symbol information.
95*38fd1498Szrj    The id must be 64bit to minimze collisions. */
96*38fd1498Szrj 
97*38fd1498Szrj struct sym_aux
98*38fd1498Szrj {
99*38fd1498Szrj   uint32_t slot;
100*38fd1498Szrj   unsigned long long id;
101*38fd1498Szrj   unsigned next_conflict;
102*38fd1498Szrj };
103*38fd1498Szrj 
104*38fd1498Szrj struct plugin_symtab
105*38fd1498Szrj {
106*38fd1498Szrj   int nsyms;
107*38fd1498Szrj   struct sym_aux *aux;
108*38fd1498Szrj   struct ld_plugin_symbol *syms;
109*38fd1498Szrj   unsigned long long id;
110*38fd1498Szrj };
111*38fd1498Szrj 
112*38fd1498Szrj /* Encapsulates object file data during symbol scan.  */
113*38fd1498Szrj struct plugin_objfile
114*38fd1498Szrj {
115*38fd1498Szrj   int found;
116*38fd1498Szrj   int offload;
117*38fd1498Szrj   simple_object_read *objfile;
118*38fd1498Szrj   struct plugin_symtab *out;
119*38fd1498Szrj   const struct ld_plugin_input_file *file;
120*38fd1498Szrj };
121*38fd1498Szrj 
122*38fd1498Szrj /* All that we have to remember about a file. */
123*38fd1498Szrj 
124*38fd1498Szrj struct plugin_file_info
125*38fd1498Szrj {
126*38fd1498Szrj   char *name;
127*38fd1498Szrj   void *handle;
128*38fd1498Szrj   struct plugin_symtab symtab;
129*38fd1498Szrj   struct plugin_symtab conflicts;
130*38fd1498Szrj };
131*38fd1498Szrj 
132*38fd1498Szrj /* List item with name of the file with offloading.  */
133*38fd1498Szrj 
134*38fd1498Szrj struct plugin_offload_file
135*38fd1498Szrj {
136*38fd1498Szrj   char *name;
137*38fd1498Szrj   struct plugin_offload_file *next;
138*38fd1498Szrj };
139*38fd1498Szrj 
140*38fd1498Szrj /* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from
141*38fd1498Szrj    stdio file streams, we do simple label translation here.  */
142*38fd1498Szrj 
143*38fd1498Szrj enum symbol_style
144*38fd1498Szrj {
145*38fd1498Szrj   ss_none,	/* No underscore prefix. */
146*38fd1498Szrj   ss_win32,	/* Underscore prefix any symbol not beginning with '@'.  */
147*38fd1498Szrj   ss_uscore,	/* Underscore prefix all symbols.  */
148*38fd1498Szrj };
149*38fd1498Szrj 
150*38fd1498Szrj static char *arguments_file_name;
151*38fd1498Szrj static ld_plugin_register_claim_file register_claim_file;
152*38fd1498Szrj static ld_plugin_register_all_symbols_read register_all_symbols_read;
153*38fd1498Szrj static ld_plugin_get_symbols get_symbols, get_symbols_v2;
154*38fd1498Szrj static ld_plugin_register_cleanup register_cleanup;
155*38fd1498Szrj static ld_plugin_add_input_file add_input_file;
156*38fd1498Szrj static ld_plugin_add_input_library add_input_library;
157*38fd1498Szrj static ld_plugin_message message;
158*38fd1498Szrj static ld_plugin_add_symbols add_symbols;
159*38fd1498Szrj 
160*38fd1498Szrj static struct plugin_file_info *claimed_files = NULL;
161*38fd1498Szrj static unsigned int num_claimed_files = 0;
162*38fd1498Szrj 
163*38fd1498Szrj /* List of files with offloading.  */
164*38fd1498Szrj static struct plugin_offload_file *offload_files;
165*38fd1498Szrj /* Last file in the list.  */
166*38fd1498Szrj static struct plugin_offload_file *offload_files_last;
167*38fd1498Szrj /* Last non-archive file in the list.  */
168*38fd1498Szrj static struct plugin_offload_file *offload_files_last_obj;
169*38fd1498Szrj /* Last LTO file in the list.  */
170*38fd1498Szrj static struct plugin_offload_file *offload_files_last_lto;
171*38fd1498Szrj /* Total number of files with offloading.  */
172*38fd1498Szrj static unsigned num_offload_files;
173*38fd1498Szrj 
174*38fd1498Szrj static char **output_files = NULL;
175*38fd1498Szrj static unsigned int num_output_files = 0;
176*38fd1498Szrj 
177*38fd1498Szrj static char **lto_wrapper_argv;
178*38fd1498Szrj static int lto_wrapper_num_args;
179*38fd1498Szrj 
180*38fd1498Szrj static char **pass_through_items = NULL;
181*38fd1498Szrj static unsigned int num_pass_through_items;
182*38fd1498Szrj 
183*38fd1498Szrj static char debug;
184*38fd1498Szrj static char nop;
185*38fd1498Szrj static char *resolution_file = NULL;
186*38fd1498Szrj static enum ld_plugin_output_file_type linker_output;
187*38fd1498Szrj static int linker_output_set;
188*38fd1498Szrj 
189*38fd1498Szrj /* The version of gold being used, or -1 if not gold.  The number is
190*38fd1498Szrj    MAJOR * 100 + MINOR.  */
191*38fd1498Szrj static int gold_version = -1;
192*38fd1498Szrj 
193*38fd1498Szrj /* Not used by default, but can be overridden at runtime
194*38fd1498Szrj    by using -plugin-opt=-sym-style={none,win32,underscore|uscore}
195*38fd1498Szrj    (in fact, only first letter of style arg is checked.)  */
196*38fd1498Szrj static enum symbol_style sym_style = ss_none;
197*38fd1498Szrj 
198*38fd1498Szrj static void
check_1(int gate,enum ld_plugin_level level,const char * text)199*38fd1498Szrj check_1 (int gate, enum ld_plugin_level level, const char *text)
200*38fd1498Szrj {
201*38fd1498Szrj   if (gate)
202*38fd1498Szrj     return;
203*38fd1498Szrj 
204*38fd1498Szrj   if (message)
205*38fd1498Szrj     message (level, text);
206*38fd1498Szrj   else
207*38fd1498Szrj     {
208*38fd1498Szrj       /* If there is no nicer way to inform the user, fallback to stderr. */
209*38fd1498Szrj       fprintf (stderr, "%s\n", text);
210*38fd1498Szrj       if (level == LDPL_FATAL)
211*38fd1498Szrj 	abort ();
212*38fd1498Szrj     }
213*38fd1498Szrj }
214*38fd1498Szrj 
215*38fd1498Szrj /* This little wrapper allows check to be called with a non-integer
216*38fd1498Szrj    first argument, such as a pointer that must be non-NULL.  We can't
217*38fd1498Szrj    use c99 bool type to coerce it into range, so we explicitly test.  */
218*38fd1498Szrj #define check(GATE, LEVEL, TEXT) check_1 (((GATE) != 0), (LEVEL), (TEXT))
219*38fd1498Szrj 
220*38fd1498Szrj /* Parse an entry of the IL symbol table. The data to be parsed is pointed
221*38fd1498Szrj    by P and the result is written in ENTRY. The slot number is stored in SLOT.
222*38fd1498Szrj    Returns the address of the next entry. */
223*38fd1498Szrj 
224*38fd1498Szrj static char *
parse_table_entry(char * p,struct ld_plugin_symbol * entry,struct sym_aux * aux)225*38fd1498Szrj parse_table_entry (char *p, struct ld_plugin_symbol *entry,
226*38fd1498Szrj 		   struct sym_aux *aux)
227*38fd1498Szrj {
228*38fd1498Szrj   unsigned char t;
229*38fd1498Szrj   enum ld_plugin_symbol_kind translate_kind[] =
230*38fd1498Szrj     {
231*38fd1498Szrj       LDPK_DEF,
232*38fd1498Szrj       LDPK_WEAKDEF,
233*38fd1498Szrj       LDPK_UNDEF,
234*38fd1498Szrj       LDPK_WEAKUNDEF,
235*38fd1498Szrj       LDPK_COMMON
236*38fd1498Szrj     };
237*38fd1498Szrj 
238*38fd1498Szrj   enum ld_plugin_symbol_visibility translate_visibility[] =
239*38fd1498Szrj     {
240*38fd1498Szrj       LDPV_DEFAULT,
241*38fd1498Szrj       LDPV_PROTECTED,
242*38fd1498Szrj       LDPV_INTERNAL,
243*38fd1498Szrj       LDPV_HIDDEN
244*38fd1498Szrj     };
245*38fd1498Szrj 
246*38fd1498Szrj   switch (sym_style)
247*38fd1498Szrj     {
248*38fd1498Szrj     case ss_win32:
249*38fd1498Szrj       if (p[0] == '@')
250*38fd1498Szrj 	{
251*38fd1498Szrj     /* cf. Duff's device.  */
252*38fd1498Szrj     case ss_none:
253*38fd1498Szrj 	  entry->name = xstrdup (p);
254*38fd1498Szrj 	  break;
255*38fd1498Szrj 	}
256*38fd1498Szrj     /* FALL-THROUGH.  */
257*38fd1498Szrj     case ss_uscore:
258*38fd1498Szrj       entry->name = concat ("_", p, NULL);
259*38fd1498Szrj       break;
260*38fd1498Szrj     default:
261*38fd1498Szrj       check (0, LDPL_FATAL, "invalid symbol style requested");
262*38fd1498Szrj       break;
263*38fd1498Szrj     }
264*38fd1498Szrj   while (*p)
265*38fd1498Szrj     p++;
266*38fd1498Szrj   p++;
267*38fd1498Szrj 
268*38fd1498Szrj   entry->version = NULL;
269*38fd1498Szrj 
270*38fd1498Szrj   entry->comdat_key = p;
271*38fd1498Szrj   while (*p)
272*38fd1498Szrj     p++;
273*38fd1498Szrj   p++;
274*38fd1498Szrj 
275*38fd1498Szrj   if (strlen (entry->comdat_key) == 0)
276*38fd1498Szrj     entry->comdat_key = NULL;
277*38fd1498Szrj   else
278*38fd1498Szrj     entry->comdat_key = xstrdup (entry->comdat_key);
279*38fd1498Szrj 
280*38fd1498Szrj   t = *p;
281*38fd1498Szrj   check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
282*38fd1498Szrj   entry->def = translate_kind[t];
283*38fd1498Szrj   p++;
284*38fd1498Szrj 
285*38fd1498Szrj   t = *p;
286*38fd1498Szrj   check (t <= 3, LDPL_FATAL, "invalid symbol visibility found");
287*38fd1498Szrj   entry->visibility = translate_visibility[t];
288*38fd1498Szrj   p++;
289*38fd1498Szrj 
290*38fd1498Szrj   memcpy (&entry->size, p, sizeof (uint64_t));
291*38fd1498Szrj   p += 8;
292*38fd1498Szrj 
293*38fd1498Szrj   memcpy (&aux->slot, p, sizeof (uint32_t));
294*38fd1498Szrj   p += 4;
295*38fd1498Szrj 
296*38fd1498Szrj   entry->resolution = LDPR_UNKNOWN;
297*38fd1498Szrj 
298*38fd1498Szrj   aux->next_conflict = -1;
299*38fd1498Szrj 
300*38fd1498Szrj   return p;
301*38fd1498Szrj }
302*38fd1498Szrj 
303*38fd1498Szrj /* Translate the IL symbol table located between DATA and END. Append the
304*38fd1498Szrj    slots and symbols to OUT. */
305*38fd1498Szrj 
306*38fd1498Szrj static void
translate(char * data,char * end,struct plugin_symtab * out)307*38fd1498Szrj translate (char *data, char *end, struct plugin_symtab *out)
308*38fd1498Szrj {
309*38fd1498Szrj   struct sym_aux *aux;
310*38fd1498Szrj   struct ld_plugin_symbol *syms = NULL;
311*38fd1498Szrj   int n, len;
312*38fd1498Szrj 
313*38fd1498Szrj   /* This overestimates the output buffer sizes, but at least
314*38fd1498Szrj      the algorithm is O(1) now. */
315*38fd1498Szrj 
316*38fd1498Szrj   len = (end - data)/8 + out->nsyms + 1;
317*38fd1498Szrj   syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
318*38fd1498Szrj   aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
319*38fd1498Szrj 
320*38fd1498Szrj   for (n = out->nsyms; data < end; n++)
321*38fd1498Szrj     {
322*38fd1498Szrj       aux[n].id = out->id;
323*38fd1498Szrj       data = parse_table_entry (data, &syms[n], &aux[n]);
324*38fd1498Szrj     }
325*38fd1498Szrj 
326*38fd1498Szrj   assert(n < len);
327*38fd1498Szrj 
328*38fd1498Szrj   out->nsyms = n;
329*38fd1498Szrj   out->syms = syms;
330*38fd1498Szrj   out->aux = aux;
331*38fd1498Szrj }
332*38fd1498Szrj 
333*38fd1498Szrj /* Free all memory that is no longer needed after writing the symbol
334*38fd1498Szrj    resolution. */
335*38fd1498Szrj 
336*38fd1498Szrj static void
free_1(struct plugin_file_info * files,unsigned num_files)337*38fd1498Szrj free_1 (struct plugin_file_info *files, unsigned num_files)
338*38fd1498Szrj {
339*38fd1498Szrj   unsigned int i;
340*38fd1498Szrj   for (i = 0; i < num_files; i++)
341*38fd1498Szrj     {
342*38fd1498Szrj       struct plugin_file_info *info = &files[i];
343*38fd1498Szrj       struct plugin_symtab *symtab = &info->symtab;
344*38fd1498Szrj       unsigned int j;
345*38fd1498Szrj       for (j = 0; j < symtab->nsyms; j++)
346*38fd1498Szrj 	{
347*38fd1498Szrj 	  struct ld_plugin_symbol *s = &symtab->syms[j];
348*38fd1498Szrj 	  free (s->name);
349*38fd1498Szrj 	  free (s->comdat_key);
350*38fd1498Szrj 	}
351*38fd1498Szrj       free (symtab->syms);
352*38fd1498Szrj       symtab->syms = NULL;
353*38fd1498Szrj     }
354*38fd1498Szrj }
355*38fd1498Szrj 
356*38fd1498Szrj /* Free all remaining memory. */
357*38fd1498Szrj 
358*38fd1498Szrj static void
free_2(void)359*38fd1498Szrj free_2 (void)
360*38fd1498Szrj {
361*38fd1498Szrj   unsigned int i;
362*38fd1498Szrj   for (i = 0; i < num_claimed_files; i++)
363*38fd1498Szrj     {
364*38fd1498Szrj       struct plugin_file_info *info = &claimed_files[i];
365*38fd1498Szrj       struct plugin_symtab *symtab = &info->symtab;
366*38fd1498Szrj       free (symtab->aux);
367*38fd1498Szrj       free (info->name);
368*38fd1498Szrj     }
369*38fd1498Szrj 
370*38fd1498Szrj   for (i = 0; i < num_output_files; i++)
371*38fd1498Szrj     free (output_files[i]);
372*38fd1498Szrj   free (output_files);
373*38fd1498Szrj 
374*38fd1498Szrj   free (claimed_files);
375*38fd1498Szrj   claimed_files = NULL;
376*38fd1498Szrj   num_claimed_files = 0;
377*38fd1498Szrj 
378*38fd1498Szrj   while (offload_files)
379*38fd1498Szrj     {
380*38fd1498Szrj       struct plugin_offload_file *ofld = offload_files;
381*38fd1498Szrj       offload_files = offload_files->next;
382*38fd1498Szrj       free (ofld);
383*38fd1498Szrj     }
384*38fd1498Szrj   num_offload_files = 0;
385*38fd1498Szrj 
386*38fd1498Szrj   free (arguments_file_name);
387*38fd1498Szrj   arguments_file_name = NULL;
388*38fd1498Szrj }
389*38fd1498Szrj 
390*38fd1498Szrj /* Dump SYMTAB to resolution file F. */
391*38fd1498Szrj 
392*38fd1498Szrj static void
dump_symtab(FILE * f,struct plugin_symtab * symtab)393*38fd1498Szrj dump_symtab (FILE *f, struct plugin_symtab *symtab)
394*38fd1498Szrj {
395*38fd1498Szrj   unsigned j;
396*38fd1498Szrj 
397*38fd1498Szrj   for (j = 0; j < symtab->nsyms; j++)
398*38fd1498Szrj     {
399*38fd1498Szrj       uint32_t slot = symtab->aux[j].slot;
400*38fd1498Szrj       unsigned int resolution = symtab->syms[j].resolution;
401*38fd1498Szrj 
402*38fd1498Szrj       assert (resolution != LDPR_UNKNOWN);
403*38fd1498Szrj 
404*38fd1498Szrj       fprintf (f, "%u %" PRI_LL "x %s %s\n",
405*38fd1498Szrj                (unsigned int) slot, symtab->aux[j].id,
406*38fd1498Szrj 	       lto_resolution_str[resolution],
407*38fd1498Szrj 	       symtab->syms[j].name);
408*38fd1498Szrj     }
409*38fd1498Szrj }
410*38fd1498Szrj 
411*38fd1498Szrj /* Finish the conflicts' resolution information after the linker resolved
412*38fd1498Szrj    the original symbols */
413*38fd1498Szrj 
414*38fd1498Szrj static void
finish_conflict_resolution(struct plugin_symtab * symtab,struct plugin_symtab * conflicts)415*38fd1498Szrj finish_conflict_resolution (struct plugin_symtab *symtab,
416*38fd1498Szrj 			   struct plugin_symtab *conflicts)
417*38fd1498Szrj {
418*38fd1498Szrj   int i, j;
419*38fd1498Szrj 
420*38fd1498Szrj   if (conflicts->nsyms == 0)
421*38fd1498Szrj     return;
422*38fd1498Szrj 
423*38fd1498Szrj   for (i = 0; i < symtab->nsyms; i++)
424*38fd1498Szrj     {
425*38fd1498Szrj       int resolution = LDPR_UNKNOWN;
426*38fd1498Szrj 
427*38fd1498Szrj       if (symtab->aux[i].next_conflict == -1)
428*38fd1498Szrj 	continue;
429*38fd1498Szrj 
430*38fd1498Szrj       switch (symtab->syms[i].def)
431*38fd1498Szrj 	{
432*38fd1498Szrj 	case LDPK_DEF:
433*38fd1498Szrj 	case LDPK_COMMON: /* ??? */
434*38fd1498Szrj 	  resolution = LDPR_RESOLVED_IR;
435*38fd1498Szrj 	  break;
436*38fd1498Szrj 	case LDPK_WEAKDEF:
437*38fd1498Szrj 	  resolution = LDPR_PREEMPTED_IR;
438*38fd1498Szrj 	  break;
439*38fd1498Szrj 	case LDPK_UNDEF:
440*38fd1498Szrj 	case LDPK_WEAKUNDEF:
441*38fd1498Szrj 	  resolution = symtab->syms[i].resolution;
442*38fd1498Szrj 	  break;
443*38fd1498Szrj 	default:
444*38fd1498Szrj 	  assert (0);
445*38fd1498Szrj 	}
446*38fd1498Szrj 
447*38fd1498Szrj       assert (resolution != LDPR_UNKNOWN);
448*38fd1498Szrj 
449*38fd1498Szrj       for (j = symtab->aux[i].next_conflict;
450*38fd1498Szrj 	   j != -1;
451*38fd1498Szrj 	   j = conflicts->aux[j].next_conflict)
452*38fd1498Szrj 	conflicts->syms[j].resolution = resolution;
453*38fd1498Szrj     }
454*38fd1498Szrj }
455*38fd1498Szrj 
456*38fd1498Szrj /* Free symbol table SYMTAB. */
457*38fd1498Szrj 
458*38fd1498Szrj static void
free_symtab(struct plugin_symtab * symtab)459*38fd1498Szrj free_symtab (struct plugin_symtab *symtab)
460*38fd1498Szrj {
461*38fd1498Szrj   free (symtab->syms);
462*38fd1498Szrj   symtab->syms = NULL;
463*38fd1498Szrj   free (symtab->aux);
464*38fd1498Szrj   symtab->aux = NULL;
465*38fd1498Szrj }
466*38fd1498Szrj 
467*38fd1498Szrj /*  Writes the relocations to disk. */
468*38fd1498Szrj 
469*38fd1498Szrj static void
write_resolution(void)470*38fd1498Szrj write_resolution (void)
471*38fd1498Szrj {
472*38fd1498Szrj   unsigned int i;
473*38fd1498Szrj   FILE *f;
474*38fd1498Szrj 
475*38fd1498Szrj   check (resolution_file, LDPL_FATAL, "resolution file not specified");
476*38fd1498Szrj   f = fopen (resolution_file, "w");
477*38fd1498Szrj   check (f, LDPL_FATAL, "could not open file");
478*38fd1498Szrj 
479*38fd1498Szrj   fprintf (f, "%d\n", num_claimed_files);
480*38fd1498Szrj 
481*38fd1498Szrj   for (i = 0; i < num_claimed_files; i++)
482*38fd1498Szrj     {
483*38fd1498Szrj       struct plugin_file_info *info = &claimed_files[i];
484*38fd1498Szrj       struct plugin_symtab *symtab = &info->symtab;
485*38fd1498Szrj       struct ld_plugin_symbol *syms = symtab->syms;
486*38fd1498Szrj 
487*38fd1498Szrj       /* Version 2 of API supports IRONLY_EXP resolution that is
488*38fd1498Szrj          accepted by GCC-4.7 and newer.  */
489*38fd1498Szrj       if (get_symbols_v2)
490*38fd1498Szrj         get_symbols_v2 (info->handle, symtab->nsyms, syms);
491*38fd1498Szrj       else
492*38fd1498Szrj         get_symbols (info->handle, symtab->nsyms, syms);
493*38fd1498Szrj 
494*38fd1498Szrj       finish_conflict_resolution (symtab, &info->conflicts);
495*38fd1498Szrj 
496*38fd1498Szrj       fprintf (f, "%s %d\n", info->name, symtab->nsyms + info->conflicts.nsyms);
497*38fd1498Szrj       dump_symtab (f, symtab);
498*38fd1498Szrj       if (info->conflicts.nsyms)
499*38fd1498Szrj 	{
500*38fd1498Szrj 	  dump_symtab (f, &info->conflicts);
501*38fd1498Szrj 	  free_symtab (&info->conflicts);
502*38fd1498Szrj 	}
503*38fd1498Szrj     }
504*38fd1498Szrj   fclose (f);
505*38fd1498Szrj }
506*38fd1498Szrj 
507*38fd1498Szrj /* Pass files generated by the lto-wrapper to the linker. FD is lto-wrapper's
508*38fd1498Szrj    stdout. */
509*38fd1498Szrj 
510*38fd1498Szrj static void
add_output_files(FILE * f)511*38fd1498Szrj add_output_files (FILE *f)
512*38fd1498Szrj {
513*38fd1498Szrj   for (;;)
514*38fd1498Szrj     {
515*38fd1498Szrj       const unsigned piece = 32;
516*38fd1498Szrj       char *buf, *s = xmalloc (piece);
517*38fd1498Szrj       size_t len;
518*38fd1498Szrj 
519*38fd1498Szrj       buf = s;
520*38fd1498Szrj cont:
521*38fd1498Szrj       if (!fgets (buf, piece, f))
522*38fd1498Szrj 	{
523*38fd1498Szrj 	  free (s);
524*38fd1498Szrj 	  break;
525*38fd1498Szrj 	}
526*38fd1498Szrj       len = strlen (s);
527*38fd1498Szrj       if (s[len - 1] != '\n')
528*38fd1498Szrj 	{
529*38fd1498Szrj 	  s = xrealloc (s, len + piece);
530*38fd1498Szrj 	  buf = s + len;
531*38fd1498Szrj 	  goto cont;
532*38fd1498Szrj 	}
533*38fd1498Szrj       s[len - 1] = '\0';
534*38fd1498Szrj 
535*38fd1498Szrj       num_output_files++;
536*38fd1498Szrj       output_files
537*38fd1498Szrj 	= xrealloc (output_files, num_output_files * sizeof (char *));
538*38fd1498Szrj       output_files[num_output_files - 1] = s;
539*38fd1498Szrj       add_input_file (output_files[num_output_files - 1]);
540*38fd1498Szrj     }
541*38fd1498Szrj }
542*38fd1498Szrj 
543*38fd1498Szrj /* Execute the lto-wrapper. ARGV[0] is the binary. The rest of ARGV is the
544*38fd1498Szrj    argument list. */
545*38fd1498Szrj 
546*38fd1498Szrj static void
exec_lto_wrapper(char * argv[])547*38fd1498Szrj exec_lto_wrapper (char *argv[])
548*38fd1498Szrj {
549*38fd1498Szrj   int t, i;
550*38fd1498Szrj   int status;
551*38fd1498Szrj   char *at_args;
552*38fd1498Szrj   FILE *args;
553*38fd1498Szrj   FILE *wrapper_output;
554*38fd1498Szrj   char *new_argv[3];
555*38fd1498Szrj   struct pex_obj *pex;
556*38fd1498Szrj   const char *errmsg;
557*38fd1498Szrj 
558*38fd1498Szrj   /* Write argv to a file to avoid a command line that is too long. */
559*38fd1498Szrj   arguments_file_name = make_temp_file ("");
560*38fd1498Szrj   check (arguments_file_name, LDPL_FATAL,
561*38fd1498Szrj          "Failed to generate a temorary file name");
562*38fd1498Szrj 
563*38fd1498Szrj   args = fopen (arguments_file_name, "w");
564*38fd1498Szrj   check (args, LDPL_FATAL, "could not open arguments file");
565*38fd1498Szrj 
566*38fd1498Szrj   t = writeargv (&argv[1], args);
567*38fd1498Szrj   check (t == 0, LDPL_FATAL, "could not write arguments");
568*38fd1498Szrj   t = fclose (args);
569*38fd1498Szrj   check (t == 0, LDPL_FATAL, "could not close arguments file");
570*38fd1498Szrj 
571*38fd1498Szrj   at_args = concat ("@", arguments_file_name, NULL);
572*38fd1498Szrj   check (at_args, LDPL_FATAL, "could not allocate");
573*38fd1498Szrj 
574*38fd1498Szrj   for (i = 1; argv[i]; i++)
575*38fd1498Szrj     {
576*38fd1498Szrj       char *a = argv[i];
577*38fd1498Szrj       if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
578*38fd1498Szrj 	{
579*38fd1498Szrj 	  for (i = 0; argv[i]; i++)
580*38fd1498Szrj 	    fprintf (stderr, "%s ", argv[i]);
581*38fd1498Szrj 	  fprintf (stderr, "\n");
582*38fd1498Szrj 	  break;
583*38fd1498Szrj 	}
584*38fd1498Szrj     }
585*38fd1498Szrj 
586*38fd1498Szrj   new_argv[0] = argv[0];
587*38fd1498Szrj   new_argv[1] = at_args;
588*38fd1498Szrj   new_argv[2] = NULL;
589*38fd1498Szrj 
590*38fd1498Szrj   if (debug)
591*38fd1498Szrj     {
592*38fd1498Szrj       for (i = 0; new_argv[i]; i++)
593*38fd1498Szrj 	fprintf (stderr, "%s ", new_argv[i]);
594*38fd1498Szrj       fprintf (stderr, "\n");
595*38fd1498Szrj     }
596*38fd1498Szrj 
597*38fd1498Szrj 
598*38fd1498Szrj   pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
599*38fd1498Szrj   check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
600*38fd1498Szrj 
601*38fd1498Szrj   errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
602*38fd1498Szrj   check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
603*38fd1498Szrj   check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
604*38fd1498Szrj 
605*38fd1498Szrj   wrapper_output = pex_read_output (pex, 0);
606*38fd1498Szrj   check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
607*38fd1498Szrj 
608*38fd1498Szrj   add_output_files (wrapper_output);
609*38fd1498Szrj 
610*38fd1498Szrj   t = pex_get_status (pex, 1, &status);
611*38fd1498Szrj   check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
612*38fd1498Szrj   check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
613*38fd1498Szrj          "lto-wrapper failed");
614*38fd1498Szrj 
615*38fd1498Szrj   pex_free (pex);
616*38fd1498Szrj 
617*38fd1498Szrj   free (at_args);
618*38fd1498Szrj }
619*38fd1498Szrj 
620*38fd1498Szrj /* Pass the original files back to the linker. */
621*38fd1498Szrj 
622*38fd1498Szrj static void
use_original_files(void)623*38fd1498Szrj use_original_files (void)
624*38fd1498Szrj {
625*38fd1498Szrj   unsigned i;
626*38fd1498Szrj   for (i = 0; i < num_claimed_files; i++)
627*38fd1498Szrj     {
628*38fd1498Szrj       struct plugin_file_info *info = &claimed_files[i];
629*38fd1498Szrj       add_input_file (info->name);
630*38fd1498Szrj     }
631*38fd1498Szrj }
632*38fd1498Szrj 
633*38fd1498Szrj 
634*38fd1498Szrj /* Called by the linker once all symbols have been read. */
635*38fd1498Szrj 
636*38fd1498Szrj static enum ld_plugin_status
all_symbols_read_handler(void)637*38fd1498Szrj all_symbols_read_handler (void)
638*38fd1498Szrj {
639*38fd1498Szrj   unsigned i;
640*38fd1498Szrj   unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 3;
641*38fd1498Szrj   char **lto_argv;
642*38fd1498Szrj   const char *linker_output_str = NULL;
643*38fd1498Szrj   const char **lto_arg_ptr;
644*38fd1498Szrj   if (num_claimed_files + num_offload_files == 0)
645*38fd1498Szrj     return LDPS_OK;
646*38fd1498Szrj 
647*38fd1498Szrj   if (nop)
648*38fd1498Szrj     {
649*38fd1498Szrj       use_original_files ();
650*38fd1498Szrj       return LDPS_OK;
651*38fd1498Szrj     }
652*38fd1498Szrj 
653*38fd1498Szrj   lto_argv = (char **) xcalloc (sizeof (char *), num_lto_args);
654*38fd1498Szrj   lto_arg_ptr = (const char **) lto_argv;
655*38fd1498Szrj   assert (lto_wrapper_argv);
656*38fd1498Szrj 
657*38fd1498Szrj   write_resolution ();
658*38fd1498Szrj 
659*38fd1498Szrj   free_1 (claimed_files, num_claimed_files);
660*38fd1498Szrj 
661*38fd1498Szrj   for (i = 0; i < lto_wrapper_num_args; i++)
662*38fd1498Szrj     *lto_arg_ptr++ = lto_wrapper_argv[i];
663*38fd1498Szrj 
664*38fd1498Szrj   assert (linker_output_set);
665*38fd1498Szrj   switch (linker_output)
666*38fd1498Szrj     {
667*38fd1498Szrj     case LDPO_REL:
668*38fd1498Szrj       linker_output_str = "-flinker-output=rel";
669*38fd1498Szrj       break;
670*38fd1498Szrj     case LDPO_DYN:
671*38fd1498Szrj       linker_output_str = "-flinker-output=dyn";
672*38fd1498Szrj       break;
673*38fd1498Szrj     case LDPO_PIE:
674*38fd1498Szrj       linker_output_str = "-flinker-output=pie";
675*38fd1498Szrj       break;
676*38fd1498Szrj     case LDPO_EXEC:
677*38fd1498Szrj       linker_output_str = "-flinker-output=exec";
678*38fd1498Szrj       break;
679*38fd1498Szrj     default:
680*38fd1498Szrj       message (LDPL_FATAL, "unsupported linker output %i", linker_output);
681*38fd1498Szrj       break;
682*38fd1498Szrj     }
683*38fd1498Szrj   *lto_arg_ptr++ = xstrdup (linker_output_str);
684*38fd1498Szrj 
685*38fd1498Szrj   if (num_offload_files > 0)
686*38fd1498Szrj     {
687*38fd1498Szrj       FILE *f;
688*38fd1498Szrj       char *arg;
689*38fd1498Szrj       char *offload_objects_file_name;
690*38fd1498Szrj       struct plugin_offload_file *ofld;
691*38fd1498Szrj 
692*38fd1498Szrj       offload_objects_file_name = make_temp_file (".ofldlist");
693*38fd1498Szrj       check (offload_objects_file_name, LDPL_FATAL,
694*38fd1498Szrj 	     "Failed to generate a temporary file name");
695*38fd1498Szrj       f = fopen (offload_objects_file_name, "w");
696*38fd1498Szrj       check (f, LDPL_FATAL, "could not open file with offload objects");
697*38fd1498Szrj       fprintf (f, "%u\n", num_offload_files);
698*38fd1498Szrj 
699*38fd1498Szrj       /* Skip the dummy item at the start of the list.  */
700*38fd1498Szrj       ofld = offload_files->next;
701*38fd1498Szrj       while (ofld)
702*38fd1498Szrj 	{
703*38fd1498Szrj 	  fprintf (f, "%s\n", ofld->name);
704*38fd1498Szrj 	  ofld = ofld->next;
705*38fd1498Szrj 	}
706*38fd1498Szrj       fclose (f);
707*38fd1498Szrj 
708*38fd1498Szrj       arg = concat ("-foffload-objects=", offload_objects_file_name, NULL);
709*38fd1498Szrj       check (arg, LDPL_FATAL, "could not allocate");
710*38fd1498Szrj       *lto_arg_ptr++ = arg;
711*38fd1498Szrj     }
712*38fd1498Szrj 
713*38fd1498Szrj   for (i = 0; i < num_claimed_files; i++)
714*38fd1498Szrj     {
715*38fd1498Szrj       struct plugin_file_info *info = &claimed_files[i];
716*38fd1498Szrj 
717*38fd1498Szrj       *lto_arg_ptr++ = info->name;
718*38fd1498Szrj     }
719*38fd1498Szrj 
720*38fd1498Szrj   *lto_arg_ptr++ = NULL;
721*38fd1498Szrj   exec_lto_wrapper (lto_argv);
722*38fd1498Szrj 
723*38fd1498Szrj   free (lto_argv);
724*38fd1498Szrj 
725*38fd1498Szrj   /* --pass-through is not needed when using gold 1.11 or later.  */
726*38fd1498Szrj   if (pass_through_items && gold_version < 111)
727*38fd1498Szrj     {
728*38fd1498Szrj       unsigned int i;
729*38fd1498Szrj       for (i = 0; i < num_pass_through_items; i++)
730*38fd1498Szrj         {
731*38fd1498Szrj           if (strncmp (pass_through_items[i], "-l", 2) == 0)
732*38fd1498Szrj             add_input_library (pass_through_items[i] + 2);
733*38fd1498Szrj           else
734*38fd1498Szrj             add_input_file (pass_through_items[i]);
735*38fd1498Szrj           free (pass_through_items[i]);
736*38fd1498Szrj           pass_through_items[i] = NULL;
737*38fd1498Szrj         }
738*38fd1498Szrj       free (pass_through_items);
739*38fd1498Szrj       pass_through_items = NULL;
740*38fd1498Szrj     }
741*38fd1498Szrj 
742*38fd1498Szrj   return LDPS_OK;
743*38fd1498Szrj }
744*38fd1498Szrj 
745*38fd1498Szrj /* Remove temporary files at the end of the link. */
746*38fd1498Szrj 
747*38fd1498Szrj static enum ld_plugin_status
cleanup_handler(void)748*38fd1498Szrj cleanup_handler (void)
749*38fd1498Szrj {
750*38fd1498Szrj   unsigned int i;
751*38fd1498Szrj   int t;
752*38fd1498Szrj 
753*38fd1498Szrj   if (debug)
754*38fd1498Szrj     return LDPS_OK;
755*38fd1498Szrj 
756*38fd1498Szrj   if (arguments_file_name)
757*38fd1498Szrj     {
758*38fd1498Szrj       t = unlink (arguments_file_name);
759*38fd1498Szrj       check (t == 0, LDPL_FATAL, "could not unlink arguments file");
760*38fd1498Szrj     }
761*38fd1498Szrj 
762*38fd1498Szrj   for (i = 0; i < num_output_files; i++)
763*38fd1498Szrj     {
764*38fd1498Szrj       t = unlink (output_files[i]);
765*38fd1498Szrj       check (t == 0, LDPL_FATAL, "could not unlink output file");
766*38fd1498Szrj     }
767*38fd1498Szrj 
768*38fd1498Szrj   free_2 ();
769*38fd1498Szrj   return LDPS_OK;
770*38fd1498Szrj }
771*38fd1498Szrj 
772*38fd1498Szrj #define SWAP(type, a, b) \
773*38fd1498Szrj   do { type tmp_; tmp_ = (a); (a) = (b); (b) = tmp_; } while(0)
774*38fd1498Szrj 
775*38fd1498Szrj /* Compare two hash table entries */
776*38fd1498Szrj 
eq_sym(const void * a,const void * b)777*38fd1498Szrj static int eq_sym (const void *a, const void *b)
778*38fd1498Szrj {
779*38fd1498Szrj   const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
780*38fd1498Szrj   const struct ld_plugin_symbol *bs = (const struct ld_plugin_symbol *)b;
781*38fd1498Szrj 
782*38fd1498Szrj   return !strcmp (as->name, bs->name);
783*38fd1498Szrj }
784*38fd1498Szrj 
785*38fd1498Szrj /* Hash a symbol */
786*38fd1498Szrj 
hash_sym(const void * a)787*38fd1498Szrj static hashval_t hash_sym (const void *a)
788*38fd1498Szrj {
789*38fd1498Szrj   const struct ld_plugin_symbol *as = (const struct ld_plugin_symbol *)a;
790*38fd1498Szrj 
791*38fd1498Szrj   return htab_hash_string (as->name);
792*38fd1498Szrj }
793*38fd1498Szrj 
794*38fd1498Szrj /* Determine how strong a symbol is */
795*38fd1498Szrj 
symbol_strength(struct ld_plugin_symbol * s)796*38fd1498Szrj static int symbol_strength (struct ld_plugin_symbol *s)
797*38fd1498Szrj {
798*38fd1498Szrj   switch (s->def)
799*38fd1498Szrj     {
800*38fd1498Szrj     case LDPK_UNDEF:
801*38fd1498Szrj     case LDPK_WEAKUNDEF:
802*38fd1498Szrj       return 0;
803*38fd1498Szrj     case LDPK_WEAKDEF:
804*38fd1498Szrj       return 1;
805*38fd1498Szrj     default:
806*38fd1498Szrj       return 2;
807*38fd1498Szrj     }
808*38fd1498Szrj }
809*38fd1498Szrj 
810*38fd1498Szrj /* In the ld -r case we can get dups in the LTO symbol tables, where
811*38fd1498Szrj    the same symbol can have different resolutions (e.g. undefined and defined).
812*38fd1498Szrj 
813*38fd1498Szrj    We have to keep that in the LTO symbol tables, but the dups confuse
814*38fd1498Szrj    gold and then finally gcc by supplying incorrect resolutions.
815*38fd1498Szrj 
816*38fd1498Szrj    Problem is that the main gold symbol table doesn't know about subids
817*38fd1498Szrj    and does not distingush the same symbols in different states.
818*38fd1498Szrj 
819*38fd1498Szrj    So we drop duplicates from the linker visible symbol table
820*38fd1498Szrj    and keep them in a private table. Then later do own symbol
821*38fd1498Szrj    resolution for the duplicated based on the results for the
822*38fd1498Szrj    originals.
823*38fd1498Szrj 
824*38fd1498Szrj    Then when writing out the resolution file readd the dropped symbols.
825*38fd1498Szrj 
826*38fd1498Szrj    XXX how to handle common? */
827*38fd1498Szrj 
828*38fd1498Szrj static void
resolve_conflicts(struct plugin_symtab * t,struct plugin_symtab * conflicts)829*38fd1498Szrj resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
830*38fd1498Szrj {
831*38fd1498Szrj   htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
832*38fd1498Szrj   int i;
833*38fd1498Szrj   int out;
834*38fd1498Szrj   int outlen;
835*38fd1498Szrj 
836*38fd1498Szrj   outlen = t->nsyms;
837*38fd1498Szrj   conflicts->syms = xmalloc (sizeof (struct ld_plugin_symbol) * outlen);
838*38fd1498Szrj   conflicts->aux = xmalloc (sizeof (struct sym_aux) * outlen);
839*38fd1498Szrj 
840*38fd1498Szrj   /* Move all duplicate symbols into the auxiliary conflicts table. */
841*38fd1498Szrj   out = 0;
842*38fd1498Szrj   for (i = 0; i < t->nsyms; i++)
843*38fd1498Szrj     {
844*38fd1498Szrj       struct ld_plugin_symbol *s = &t->syms[i];
845*38fd1498Szrj       struct sym_aux *aux = &t->aux[i];
846*38fd1498Szrj       void **slot;
847*38fd1498Szrj 
848*38fd1498Szrj       slot = htab_find_slot (symtab, s, INSERT);
849*38fd1498Szrj       if (*slot != NULL)
850*38fd1498Szrj 	{
851*38fd1498Szrj 	  int cnf;
852*38fd1498Szrj 	  struct ld_plugin_symbol *orig = (struct ld_plugin_symbol *)*slot;
853*38fd1498Szrj 	  struct sym_aux *orig_aux = &t->aux[orig - t->syms];
854*38fd1498Szrj 
855*38fd1498Szrj 	  /* Always let the linker resolve the strongest symbol */
856*38fd1498Szrj 	  if (symbol_strength (orig) < symbol_strength (s))
857*38fd1498Szrj 	    {
858*38fd1498Szrj 	      SWAP (struct ld_plugin_symbol, *orig, *s);
859*38fd1498Szrj 	      SWAP (uint32_t, orig_aux->slot, aux->slot);
860*38fd1498Szrj 	      SWAP (unsigned long long, orig_aux->id, aux->id);
861*38fd1498Szrj 	      /* Don't swap conflict chain pointer */
862*38fd1498Szrj 	    }
863*38fd1498Szrj 
864*38fd1498Szrj 	  /* Move current symbol into the conflicts table */
865*38fd1498Szrj 	  cnf = conflicts->nsyms++;
866*38fd1498Szrj 	  conflicts->syms[cnf] = *s;
867*38fd1498Szrj 	  conflicts->aux[cnf] = *aux;
868*38fd1498Szrj 	  aux = &conflicts->aux[cnf];
869*38fd1498Szrj 
870*38fd1498Szrj 	  /* Update conflicts chain of the original symbol */
871*38fd1498Szrj 	  aux->next_conflict = orig_aux->next_conflict;
872*38fd1498Szrj 	  orig_aux->next_conflict = cnf;
873*38fd1498Szrj 
874*38fd1498Szrj 	  continue;
875*38fd1498Szrj 	}
876*38fd1498Szrj 
877*38fd1498Szrj       /* Remove previous duplicates in the main table */
878*38fd1498Szrj       if (out < i)
879*38fd1498Szrj 	{
880*38fd1498Szrj 	  t->syms[out] = *s;
881*38fd1498Szrj 	  t->aux[out] = *aux;
882*38fd1498Szrj 	}
883*38fd1498Szrj 
884*38fd1498Szrj       /* Put original into the hash table */
885*38fd1498Szrj       *slot = &t->syms[out];
886*38fd1498Szrj       out++;
887*38fd1498Szrj     }
888*38fd1498Szrj 
889*38fd1498Szrj   assert (conflicts->nsyms <= outlen);
890*38fd1498Szrj   assert (conflicts->nsyms + out == t->nsyms);
891*38fd1498Szrj 
892*38fd1498Szrj   t->nsyms = out;
893*38fd1498Szrj   htab_delete (symtab);
894*38fd1498Szrj }
895*38fd1498Szrj 
896*38fd1498Szrj /* Process one section of an object file.  */
897*38fd1498Szrj 
898*38fd1498Szrj static int
process_symtab(void * data,const char * name,off_t offset,off_t length)899*38fd1498Szrj process_symtab (void *data, const char *name, off_t offset, off_t length)
900*38fd1498Szrj {
901*38fd1498Szrj   struct plugin_objfile *obj = (struct plugin_objfile *)data;
902*38fd1498Szrj   char *s;
903*38fd1498Szrj   char *secdatastart, *secdata;
904*38fd1498Szrj 
905*38fd1498Szrj   if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
906*38fd1498Szrj     return 1;
907*38fd1498Szrj 
908*38fd1498Szrj   s = strrchr (name, '.');
909*38fd1498Szrj   if (s)
910*38fd1498Szrj     sscanf (s, ".%" PRI_LL "x", &obj->out->id);
911*38fd1498Szrj   secdata = secdatastart = xmalloc (length);
912*38fd1498Szrj   offset += obj->file->offset;
913*38fd1498Szrj   if (offset != lseek (obj->file->fd, offset, SEEK_SET))
914*38fd1498Szrj     goto err;
915*38fd1498Szrj 
916*38fd1498Szrj   do
917*38fd1498Szrj     {
918*38fd1498Szrj       ssize_t got = read (obj->file->fd, secdata, length);
919*38fd1498Szrj       if (got == 0)
920*38fd1498Szrj 	break;
921*38fd1498Szrj       else if (got > 0)
922*38fd1498Szrj 	{
923*38fd1498Szrj 	  secdata += got;
924*38fd1498Szrj 	  length -= got;
925*38fd1498Szrj 	}
926*38fd1498Szrj       else if (errno != EINTR)
927*38fd1498Szrj 	goto err;
928*38fd1498Szrj     }
929*38fd1498Szrj   while (length > 0);
930*38fd1498Szrj   if (length > 0)
931*38fd1498Szrj     goto err;
932*38fd1498Szrj 
933*38fd1498Szrj   translate (secdatastart, secdata, obj->out);
934*38fd1498Szrj   obj->found++;
935*38fd1498Szrj   free (secdatastart);
936*38fd1498Szrj   return 1;
937*38fd1498Szrj 
938*38fd1498Szrj err:
939*38fd1498Szrj   if (message)
940*38fd1498Szrj     message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
941*38fd1498Szrj   /* Force claim_file_handler to abandon this file.  */
942*38fd1498Szrj   obj->found = 0;
943*38fd1498Szrj   free (secdatastart);
944*38fd1498Szrj   return 0;
945*38fd1498Szrj }
946*38fd1498Szrj 
947*38fd1498Szrj /* Find an offload section of an object file.  */
948*38fd1498Szrj 
949*38fd1498Szrj static int
process_offload_section(void * data,const char * name,off_t offset,off_t len)950*38fd1498Szrj process_offload_section (void *data, const char *name, off_t offset, off_t len)
951*38fd1498Szrj {
952*38fd1498Szrj   if (!strncmp (name, OFFLOAD_SECTION, OFFLOAD_SECTION_LEN))
953*38fd1498Szrj     {
954*38fd1498Szrj       struct plugin_objfile *obj = (struct plugin_objfile *) data;
955*38fd1498Szrj       obj->offload = 1;
956*38fd1498Szrj       return 0;
957*38fd1498Szrj     }
958*38fd1498Szrj 
959*38fd1498Szrj   return 1;
960*38fd1498Szrj }
961*38fd1498Szrj 
962*38fd1498Szrj /* Callback used by gold to check if the plugin will claim FILE. Writes
963*38fd1498Szrj    the result in CLAIMED. */
964*38fd1498Szrj 
965*38fd1498Szrj static enum ld_plugin_status
claim_file_handler(const struct ld_plugin_input_file * file,int * claimed)966*38fd1498Szrj claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
967*38fd1498Szrj {
968*38fd1498Szrj   enum ld_plugin_status status;
969*38fd1498Szrj   struct plugin_objfile obj;
970*38fd1498Szrj   struct plugin_file_info lto_file;
971*38fd1498Szrj   int err;
972*38fd1498Szrj   const char *errmsg;
973*38fd1498Szrj 
974*38fd1498Szrj   memset (&lto_file, 0, sizeof (struct plugin_file_info));
975*38fd1498Szrj 
976*38fd1498Szrj   if (file->offset != 0)
977*38fd1498Szrj     {
978*38fd1498Szrj       /* We pass the offset of the actual file, not the archive header.
979*38fd1498Szrj          Can't use PRIx64, because that's C99, so we have to print the
980*38fd1498Szrj 	 64-bit hex int as two 32-bit ones.  Use xasprintf instead of
981*38fd1498Szrj 	 asprintf because asprintf doesn't work as expected on some older
982*38fd1498Szrj 	 mingw32 hosts.  */
983*38fd1498Szrj       int lo, hi;
984*38fd1498Szrj       lo = file->offset & 0xffffffff;
985*38fd1498Szrj       hi = ((int64_t)file->offset >> 32) & 0xffffffff;
986*38fd1498Szrj       lto_file.name = hi ? xasprintf ("%s@0x%x%08x", file->name, hi, lo)
987*38fd1498Szrj       			 : xasprintf ("%s@0x%x", file->name, lo);
988*38fd1498Szrj     }
989*38fd1498Szrj   else
990*38fd1498Szrj     {
991*38fd1498Szrj       lto_file.name = xstrdup (file->name);
992*38fd1498Szrj     }
993*38fd1498Szrj   lto_file.handle = file->handle;
994*38fd1498Szrj 
995*38fd1498Szrj   *claimed = 0;
996*38fd1498Szrj   obj.file = file;
997*38fd1498Szrj   obj.found = 0;
998*38fd1498Szrj   obj.offload = 0;
999*38fd1498Szrj   obj.out = &lto_file.symtab;
1000*38fd1498Szrj   errmsg = NULL;
1001*38fd1498Szrj   obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME,
1002*38fd1498Szrj 			&errmsg, &err);
1003*38fd1498Szrj   /* No file, but also no error code means unrecognized format; just skip it.  */
1004*38fd1498Szrj   if (!obj.objfile && !err)
1005*38fd1498Szrj     goto err;
1006*38fd1498Szrj 
1007*38fd1498Szrj   if (obj.objfile)
1008*38fd1498Szrj     errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
1009*38fd1498Szrj 
1010*38fd1498Szrj   if (!obj.objfile || errmsg)
1011*38fd1498Szrj     {
1012*38fd1498Szrj       if (err && message)
1013*38fd1498Szrj 	message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg,
1014*38fd1498Szrj 		xstrerror (err));
1015*38fd1498Szrj       else if (message)
1016*38fd1498Szrj 	message (LDPL_FATAL, "%s: %s", file->name, errmsg);
1017*38fd1498Szrj       goto err;
1018*38fd1498Szrj     }
1019*38fd1498Szrj 
1020*38fd1498Szrj   if (obj.objfile)
1021*38fd1498Szrj     simple_object_find_sections (obj.objfile, process_offload_section,
1022*38fd1498Szrj 				 &obj, &err);
1023*38fd1498Szrj 
1024*38fd1498Szrj   if (obj.found == 0 && obj.offload == 0)
1025*38fd1498Szrj     goto err;
1026*38fd1498Szrj 
1027*38fd1498Szrj   if (obj.found > 1)
1028*38fd1498Szrj     resolve_conflicts (&lto_file.symtab, &lto_file.conflicts);
1029*38fd1498Szrj 
1030*38fd1498Szrj   if (obj.found > 0)
1031*38fd1498Szrj     {
1032*38fd1498Szrj       status = add_symbols (file->handle, lto_file.symtab.nsyms,
1033*38fd1498Szrj 			    lto_file.symtab.syms);
1034*38fd1498Szrj       check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
1035*38fd1498Szrj 
1036*38fd1498Szrj       num_claimed_files++;
1037*38fd1498Szrj       claimed_files =
1038*38fd1498Szrj 	xrealloc (claimed_files,
1039*38fd1498Szrj 		  num_claimed_files * sizeof (struct plugin_file_info));
1040*38fd1498Szrj       claimed_files[num_claimed_files - 1] = lto_file;
1041*38fd1498Szrj 
1042*38fd1498Szrj       *claimed = 1;
1043*38fd1498Szrj     }
1044*38fd1498Szrj 
1045*38fd1498Szrj   if (offload_files == NULL)
1046*38fd1498Szrj     {
1047*38fd1498Szrj       /* Add dummy item to the start of the list.  */
1048*38fd1498Szrj       offload_files = xmalloc (sizeof (struct plugin_offload_file));
1049*38fd1498Szrj       offload_files->name = NULL;
1050*38fd1498Szrj       offload_files->next = NULL;
1051*38fd1498Szrj       offload_files_last = offload_files;
1052*38fd1498Szrj     }
1053*38fd1498Szrj 
1054*38fd1498Szrj   /* If this is an LTO file without offload, and it is the first LTO file, save
1055*38fd1498Szrj      the pointer to the last offload file in the list.  Further offload LTO
1056*38fd1498Szrj      files will be inserted after it, if any.  */
1057*38fd1498Szrj   if (*claimed && obj.offload == 0 && offload_files_last_lto == NULL)
1058*38fd1498Szrj     offload_files_last_lto = offload_files_last;
1059*38fd1498Szrj 
1060*38fd1498Szrj   if (obj.offload == 1)
1061*38fd1498Szrj     {
1062*38fd1498Szrj       /* Add file to the list.  The order must be exactly the same as the final
1063*38fd1498Szrj 	 order after recompilation and linking, otherwise host and target tables
1064*38fd1498Szrj 	 with addresses wouldn't match.  If a static library contains both LTO
1065*38fd1498Szrj 	 and non-LTO objects, ld and gold link them in a different order.  */
1066*38fd1498Szrj       struct plugin_offload_file *ofld
1067*38fd1498Szrj 	= xmalloc (sizeof (struct plugin_offload_file));
1068*38fd1498Szrj       ofld->name = lto_file.name;
1069*38fd1498Szrj       ofld->next = NULL;
1070*38fd1498Szrj 
1071*38fd1498Szrj       if (*claimed && offload_files_last_lto == NULL && file->offset != 0
1072*38fd1498Szrj 	  && gold_version == -1)
1073*38fd1498Szrj 	{
1074*38fd1498Szrj 	  /* ld only: insert first LTO file from the archive after the last real
1075*38fd1498Szrj 	     object file immediately preceding the archive, or at the begin of
1076*38fd1498Szrj 	     the list if there was no real objects before archives.  */
1077*38fd1498Szrj 	  if (offload_files_last_obj != NULL)
1078*38fd1498Szrj 	    {
1079*38fd1498Szrj 	      ofld->next = offload_files_last_obj->next;
1080*38fd1498Szrj 	      offload_files_last_obj->next = ofld;
1081*38fd1498Szrj 	    }
1082*38fd1498Szrj 	  else
1083*38fd1498Szrj 	    {
1084*38fd1498Szrj 	      ofld->next = offload_files->next;
1085*38fd1498Szrj 	      offload_files->next = ofld;
1086*38fd1498Szrj 	    }
1087*38fd1498Szrj 	}
1088*38fd1498Szrj       else if (*claimed && offload_files_last_lto != NULL)
1089*38fd1498Szrj 	{
1090*38fd1498Szrj 	  /* Insert LTO file after the last LTO file in the list.  */
1091*38fd1498Szrj 	  ofld->next = offload_files_last_lto->next;
1092*38fd1498Szrj 	  offload_files_last_lto->next = ofld;
1093*38fd1498Szrj 	}
1094*38fd1498Szrj       else
1095*38fd1498Szrj 	/* Add non-LTO file or first non-archive LTO file to the end of the
1096*38fd1498Szrj 	   list.  */
1097*38fd1498Szrj 	offload_files_last->next = ofld;
1098*38fd1498Szrj 
1099*38fd1498Szrj       if (ofld->next == NULL)
1100*38fd1498Szrj 	offload_files_last = ofld;
1101*38fd1498Szrj       if (file->offset == 0)
1102*38fd1498Szrj 	offload_files_last_obj = ofld;
1103*38fd1498Szrj       if (*claimed)
1104*38fd1498Szrj 	offload_files_last_lto = ofld;
1105*38fd1498Szrj       num_offload_files++;
1106*38fd1498Szrj     }
1107*38fd1498Szrj 
1108*38fd1498Szrj   goto cleanup;
1109*38fd1498Szrj 
1110*38fd1498Szrj  err:
1111*38fd1498Szrj   free (lto_file.name);
1112*38fd1498Szrj 
1113*38fd1498Szrj  cleanup:
1114*38fd1498Szrj   if (obj.objfile)
1115*38fd1498Szrj     simple_object_release_read (obj.objfile);
1116*38fd1498Szrj 
1117*38fd1498Szrj   return LDPS_OK;
1118*38fd1498Szrj }
1119*38fd1498Szrj 
1120*38fd1498Szrj /* Parse the plugin options. */
1121*38fd1498Szrj 
1122*38fd1498Szrj static void
process_option(const char * option)1123*38fd1498Szrj process_option (const char *option)
1124*38fd1498Szrj {
1125*38fd1498Szrj   if (strcmp (option, "-debug") == 0)
1126*38fd1498Szrj     debug = 1;
1127*38fd1498Szrj   else if (strcmp (option, "-nop") == 0)
1128*38fd1498Szrj     nop = 1;
1129*38fd1498Szrj   else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
1130*38fd1498Szrj     {
1131*38fd1498Szrj       num_pass_through_items++;
1132*38fd1498Szrj       pass_through_items = xrealloc (pass_through_items,
1133*38fd1498Szrj 				     num_pass_through_items * sizeof (char *));
1134*38fd1498Szrj       pass_through_items[num_pass_through_items - 1] =
1135*38fd1498Szrj           xstrdup (option + strlen ("-pass-through="));
1136*38fd1498Szrj     }
1137*38fd1498Szrj   else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1))
1138*38fd1498Szrj     {
1139*38fd1498Szrj       switch (option[sizeof ("-sym-style=") - 1])
1140*38fd1498Szrj 	{
1141*38fd1498Szrj 	case 'w':
1142*38fd1498Szrj 	  sym_style = ss_win32;
1143*38fd1498Szrj 	  break;
1144*38fd1498Szrj 	case 'u':
1145*38fd1498Szrj 	  sym_style = ss_uscore;
1146*38fd1498Szrj 	  break;
1147*38fd1498Szrj 	default:
1148*38fd1498Szrj 	  sym_style = ss_none;
1149*38fd1498Szrj 	  break;
1150*38fd1498Szrj 	}
1151*38fd1498Szrj     }
1152*38fd1498Szrj   else
1153*38fd1498Szrj     {
1154*38fd1498Szrj       int size;
1155*38fd1498Szrj       char *opt = xstrdup (option);
1156*38fd1498Szrj       lto_wrapper_num_args += 1;
1157*38fd1498Szrj       size = lto_wrapper_num_args * sizeof (char *);
1158*38fd1498Szrj       lto_wrapper_argv = (char **) xrealloc (lto_wrapper_argv, size);
1159*38fd1498Szrj       lto_wrapper_argv[lto_wrapper_num_args - 1] = opt;
1160*38fd1498Szrj       if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
1161*38fd1498Szrj 	resolution_file = opt + sizeof ("-fresolution=") - 1;
1162*38fd1498Szrj     }
1163*38fd1498Szrj }
1164*38fd1498Szrj 
1165*38fd1498Szrj /* Called by gold after loading the plugin. TV is the transfer vector. */
1166*38fd1498Szrj 
1167*38fd1498Szrj enum ld_plugin_status
onload(struct ld_plugin_tv * tv)1168*38fd1498Szrj onload (struct ld_plugin_tv *tv)
1169*38fd1498Szrj {
1170*38fd1498Szrj   struct ld_plugin_tv *p;
1171*38fd1498Szrj   enum ld_plugin_status status;
1172*38fd1498Szrj 
1173*38fd1498Szrj   p = tv;
1174*38fd1498Szrj   while (p->tv_tag)
1175*38fd1498Szrj     {
1176*38fd1498Szrj       switch (p->tv_tag)
1177*38fd1498Szrj 	{
1178*38fd1498Szrj         case LDPT_MESSAGE:
1179*38fd1498Szrj           message = p->tv_u.tv_message;
1180*38fd1498Szrj           break;
1181*38fd1498Szrj 	case LDPT_REGISTER_CLAIM_FILE_HOOK:
1182*38fd1498Szrj 	  register_claim_file = p->tv_u.tv_register_claim_file;
1183*38fd1498Szrj 	  break;
1184*38fd1498Szrj 	case LDPT_ADD_SYMBOLS:
1185*38fd1498Szrj 	  add_symbols = p->tv_u.tv_add_symbols;
1186*38fd1498Szrj 	  break;
1187*38fd1498Szrj 	case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
1188*38fd1498Szrj 	  register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
1189*38fd1498Szrj 	  break;
1190*38fd1498Szrj 	case LDPT_GET_SYMBOLS_V2:
1191*38fd1498Szrj 	  get_symbols_v2 = p->tv_u.tv_get_symbols;
1192*38fd1498Szrj 	  break;
1193*38fd1498Szrj 	case LDPT_GET_SYMBOLS:
1194*38fd1498Szrj 	  get_symbols = p->tv_u.tv_get_symbols;
1195*38fd1498Szrj 	  break;
1196*38fd1498Szrj 	case LDPT_REGISTER_CLEANUP_HOOK:
1197*38fd1498Szrj 	  register_cleanup = p->tv_u.tv_register_cleanup;
1198*38fd1498Szrj 	  break;
1199*38fd1498Szrj 	case LDPT_ADD_INPUT_FILE:
1200*38fd1498Szrj 	  add_input_file = p->tv_u.tv_add_input_file;
1201*38fd1498Szrj 	  break;
1202*38fd1498Szrj 	case LDPT_ADD_INPUT_LIBRARY:
1203*38fd1498Szrj 	  add_input_library = p->tv_u.tv_add_input_library;
1204*38fd1498Szrj 	  break;
1205*38fd1498Szrj 	case LDPT_OPTION:
1206*38fd1498Szrj 	  process_option (p->tv_u.tv_string);
1207*38fd1498Szrj 	  break;
1208*38fd1498Szrj 	case LDPT_GOLD_VERSION:
1209*38fd1498Szrj 	  gold_version = p->tv_u.tv_val;
1210*38fd1498Szrj 	  break;
1211*38fd1498Szrj 	case LDPT_LINKER_OUTPUT:
1212*38fd1498Szrj 	  linker_output = (enum ld_plugin_output_file_type) p->tv_u.tv_val;
1213*38fd1498Szrj 	  linker_output_set = 1;
1214*38fd1498Szrj 	  break;
1215*38fd1498Szrj 	default:
1216*38fd1498Szrj 	  break;
1217*38fd1498Szrj 	}
1218*38fd1498Szrj       p++;
1219*38fd1498Szrj     }
1220*38fd1498Szrj 
1221*38fd1498Szrj   check (register_claim_file, LDPL_FATAL, "register_claim_file not found");
1222*38fd1498Szrj   check (add_symbols, LDPL_FATAL, "add_symbols not found");
1223*38fd1498Szrj   status = register_claim_file (claim_file_handler);
1224*38fd1498Szrj   check (status == LDPS_OK, LDPL_FATAL,
1225*38fd1498Szrj 	 "could not register the claim_file callback");
1226*38fd1498Szrj 
1227*38fd1498Szrj   if (register_cleanup)
1228*38fd1498Szrj     {
1229*38fd1498Szrj       status = register_cleanup (cleanup_handler);
1230*38fd1498Szrj       check (status == LDPS_OK, LDPL_FATAL,
1231*38fd1498Szrj 	     "could not register the cleanup callback");
1232*38fd1498Szrj     }
1233*38fd1498Szrj 
1234*38fd1498Szrj   if (register_all_symbols_read)
1235*38fd1498Szrj     {
1236*38fd1498Szrj       check (get_symbols, LDPL_FATAL, "get_symbols not found");
1237*38fd1498Szrj       status = register_all_symbols_read (all_symbols_read_handler);
1238*38fd1498Szrj       check (status == LDPS_OK, LDPL_FATAL,
1239*38fd1498Szrj 	     "could not register the all_symbols_read callback");
1240*38fd1498Szrj     }
1241*38fd1498Szrj 
1242*38fd1498Szrj   /* Support -fno-use-linker-plugin by failing to load the plugin
1243*38fd1498Szrj      for the case where it is auto-loaded by BFD.  */
1244*38fd1498Szrj   char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
1245*38fd1498Szrj   if (collect_gcc_options
1246*38fd1498Szrj       && strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
1247*38fd1498Szrj     return LDPS_ERR;
1248*38fd1498Szrj 
1249*38fd1498Szrj   return LDPS_OK;
1250*38fd1498Szrj }
1251