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