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 (<o_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 = <o_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 (<o_file.symtab, <o_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