1*e4b17023SJohn Marino /* LTO routines to use object files.
2*e4b17023SJohn Marino Copyright 2010 Free Software Foundation, Inc.
3*e4b17023SJohn Marino Written by Ian Lance Taylor, Google.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
8*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
9*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
10*e4b17023SJohn Marino version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "diagnostic-core.h"
25*e4b17023SJohn Marino #include "lto.h"
26*e4b17023SJohn Marino #include "tm.h"
27*e4b17023SJohn Marino #include "lto-streamer.h"
28*e4b17023SJohn Marino #include "simple-object.h"
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino /* Segment name for LTO sections. This is only used for Mach-O.
31*e4b17023SJohn Marino FIXME: This needs to be kept in sync with darwin.c. */
32*e4b17023SJohn Marino
33*e4b17023SJohn Marino #define LTO_SEGMENT_NAME "__GNU_LTO"
34*e4b17023SJohn Marino
35*e4b17023SJohn Marino /* An LTO file wrapped around an simple_object. */
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino struct lto_simple_object
38*e4b17023SJohn Marino {
39*e4b17023SJohn Marino /* The base information. */
40*e4b17023SJohn Marino lto_file base;
41*e4b17023SJohn Marino
42*e4b17023SJohn Marino /* The system file descriptor. */
43*e4b17023SJohn Marino int fd;
44*e4b17023SJohn Marino
45*e4b17023SJohn Marino /* The simple_object if we are reading the file. */
46*e4b17023SJohn Marino simple_object_read *sobj_r;
47*e4b17023SJohn Marino
48*e4b17023SJohn Marino /* The simple_object if we are writing the file. */
49*e4b17023SJohn Marino simple_object_write *sobj_w;
50*e4b17023SJohn Marino
51*e4b17023SJohn Marino /* The currently active section. */
52*e4b17023SJohn Marino simple_object_write_section *section;
53*e4b17023SJohn Marino };
54*e4b17023SJohn Marino
55*e4b17023SJohn Marino /* Saved simple_object attributes. FIXME: Once set, this is never
56*e4b17023SJohn Marino cleared. */
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino static simple_object_attributes *saved_attributes;
59*e4b17023SJohn Marino
60*e4b17023SJohn Marino /* Initialize FILE, an LTO file object for FILENAME. */
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino static void
lto_file_init(lto_file * file,const char * filename,off_t offset)63*e4b17023SJohn Marino lto_file_init (lto_file *file, const char *filename, off_t offset)
64*e4b17023SJohn Marino {
65*e4b17023SJohn Marino file->filename = filename;
66*e4b17023SJohn Marino file->offset = offset;
67*e4b17023SJohn Marino }
68*e4b17023SJohn Marino
69*e4b17023SJohn Marino /* Open the file FILENAME. It WRITABLE is true, the file is opened
70*e4b17023SJohn Marino for write and, if necessary, created. Otherwise, the file is
71*e4b17023SJohn Marino opened for reading. Returns the opened file. */
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino lto_file *
lto_obj_file_open(const char * filename,bool writable)74*e4b17023SJohn Marino lto_obj_file_open (const char *filename, bool writable)
75*e4b17023SJohn Marino {
76*e4b17023SJohn Marino const char *offset_p;
77*e4b17023SJohn Marino long loffset;
78*e4b17023SJohn Marino int consumed;
79*e4b17023SJohn Marino char *fname;
80*e4b17023SJohn Marino off_t offset;
81*e4b17023SJohn Marino struct lto_simple_object *lo;
82*e4b17023SJohn Marino const char *errmsg;
83*e4b17023SJohn Marino int err;
84*e4b17023SJohn Marino
85*e4b17023SJohn Marino offset_p = strrchr (filename, '@');
86*e4b17023SJohn Marino if (offset_p != NULL
87*e4b17023SJohn Marino && offset_p != filename
88*e4b17023SJohn Marino && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1
89*e4b17023SJohn Marino && strlen (offset_p) == (unsigned int) consumed)
90*e4b17023SJohn Marino {
91*e4b17023SJohn Marino fname = XNEWVEC (char, offset_p - filename + 1);
92*e4b17023SJohn Marino memcpy (fname, filename, offset_p - filename);
93*e4b17023SJohn Marino fname[offset_p - filename] = '\0';
94*e4b17023SJohn Marino offset = (off_t) loffset;
95*e4b17023SJohn Marino }
96*e4b17023SJohn Marino else
97*e4b17023SJohn Marino {
98*e4b17023SJohn Marino fname = xstrdup (filename);
99*e4b17023SJohn Marino offset = 0;
100*e4b17023SJohn Marino }
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino lo = XCNEW (struct lto_simple_object);
103*e4b17023SJohn Marino lto_file_init ((lto_file *) lo, fname, offset);
104*e4b17023SJohn Marino
105*e4b17023SJohn Marino lo->fd = open (fname,
106*e4b17023SJohn Marino (writable
107*e4b17023SJohn Marino ? O_WRONLY | O_CREAT | O_BINARY
108*e4b17023SJohn Marino : O_RDONLY | O_BINARY),
109*e4b17023SJohn Marino 0666);
110*e4b17023SJohn Marino if (lo->fd == -1)
111*e4b17023SJohn Marino {
112*e4b17023SJohn Marino error ("open %s failed: %s", fname, xstrerror (errno));
113*e4b17023SJohn Marino goto fail;
114*e4b17023SJohn Marino }
115*e4b17023SJohn Marino
116*e4b17023SJohn Marino if (!writable)
117*e4b17023SJohn Marino {
118*e4b17023SJohn Marino simple_object_attributes *attrs;
119*e4b17023SJohn Marino
120*e4b17023SJohn Marino lo->sobj_r = simple_object_start_read (lo->fd, offset, LTO_SEGMENT_NAME,
121*e4b17023SJohn Marino &errmsg, &err);
122*e4b17023SJohn Marino if (lo->sobj_r == NULL)
123*e4b17023SJohn Marino goto fail_errmsg;
124*e4b17023SJohn Marino
125*e4b17023SJohn Marino attrs = simple_object_fetch_attributes (lo->sobj_r, &errmsg, &err);
126*e4b17023SJohn Marino if (attrs == NULL)
127*e4b17023SJohn Marino goto fail_errmsg;
128*e4b17023SJohn Marino
129*e4b17023SJohn Marino if (saved_attributes == NULL)
130*e4b17023SJohn Marino saved_attributes = attrs;
131*e4b17023SJohn Marino else
132*e4b17023SJohn Marino {
133*e4b17023SJohn Marino errmsg = simple_object_attributes_merge (saved_attributes, attrs,
134*e4b17023SJohn Marino &err);
135*e4b17023SJohn Marino if (errmsg != NULL)
136*e4b17023SJohn Marino goto fail_errmsg;
137*e4b17023SJohn Marino }
138*e4b17023SJohn Marino }
139*e4b17023SJohn Marino else
140*e4b17023SJohn Marino {
141*e4b17023SJohn Marino gcc_assert (saved_attributes != NULL);
142*e4b17023SJohn Marino lo->sobj_w = simple_object_start_write (saved_attributes,
143*e4b17023SJohn Marino LTO_SEGMENT_NAME,
144*e4b17023SJohn Marino &errmsg, &err);
145*e4b17023SJohn Marino if (lo->sobj_w == NULL)
146*e4b17023SJohn Marino goto fail_errmsg;
147*e4b17023SJohn Marino }
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino return &lo->base;
150*e4b17023SJohn Marino
151*e4b17023SJohn Marino fail_errmsg:
152*e4b17023SJohn Marino if (err == 0)
153*e4b17023SJohn Marino error ("%s: %s", fname, errmsg);
154*e4b17023SJohn Marino else
155*e4b17023SJohn Marino error ("%s: %s: %s", fname, errmsg, xstrerror (err));
156*e4b17023SJohn Marino
157*e4b17023SJohn Marino fail:
158*e4b17023SJohn Marino if (lo != NULL)
159*e4b17023SJohn Marino lto_obj_file_close ((lto_file *) lo);
160*e4b17023SJohn Marino return NULL;
161*e4b17023SJohn Marino }
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino /* Close FILE. If FILE was opened for writing, it is written out
164*e4b17023SJohn Marino now. */
165*e4b17023SJohn Marino
166*e4b17023SJohn Marino void
lto_obj_file_close(lto_file * file)167*e4b17023SJohn Marino lto_obj_file_close (lto_file *file)
168*e4b17023SJohn Marino {
169*e4b17023SJohn Marino struct lto_simple_object *lo = (struct lto_simple_object *) file;
170*e4b17023SJohn Marino
171*e4b17023SJohn Marino if (lo->sobj_r != NULL)
172*e4b17023SJohn Marino simple_object_release_read (lo->sobj_r);
173*e4b17023SJohn Marino else if (lo->sobj_w != NULL)
174*e4b17023SJohn Marino {
175*e4b17023SJohn Marino const char *errmsg;
176*e4b17023SJohn Marino int err;
177*e4b17023SJohn Marino
178*e4b17023SJohn Marino gcc_assert (lo->base.offset == 0);
179*e4b17023SJohn Marino
180*e4b17023SJohn Marino errmsg = simple_object_write_to_file (lo->sobj_w, lo->fd, &err);
181*e4b17023SJohn Marino if (errmsg != NULL)
182*e4b17023SJohn Marino {
183*e4b17023SJohn Marino if (err == 0)
184*e4b17023SJohn Marino fatal_error ("%s", errmsg);
185*e4b17023SJohn Marino else
186*e4b17023SJohn Marino fatal_error ("%s: %s", errmsg, xstrerror (err));
187*e4b17023SJohn Marino }
188*e4b17023SJohn Marino
189*e4b17023SJohn Marino simple_object_release_write (lo->sobj_w);
190*e4b17023SJohn Marino }
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino if (lo->fd != -1)
193*e4b17023SJohn Marino {
194*e4b17023SJohn Marino if (close (lo->fd) < 0)
195*e4b17023SJohn Marino fatal_error ("close: %s", xstrerror (errno));
196*e4b17023SJohn Marino }
197*e4b17023SJohn Marino }
198*e4b17023SJohn Marino
199*e4b17023SJohn Marino /* This is passed to lto_obj_add_section. */
200*e4b17023SJohn Marino
201*e4b17023SJohn Marino struct lto_obj_add_section_data
202*e4b17023SJohn Marino {
203*e4b17023SJohn Marino /* The hash table of sections. */
204*e4b17023SJohn Marino htab_t section_hash_table;
205*e4b17023SJohn Marino /* The offset of this file. */
206*e4b17023SJohn Marino off_t base_offset;
207*e4b17023SJohn Marino /* List in linker order */
208*e4b17023SJohn Marino struct lto_section_list *list;
209*e4b17023SJohn Marino };
210*e4b17023SJohn Marino
211*e4b17023SJohn Marino /* This is called for each section in the file. */
212*e4b17023SJohn Marino
213*e4b17023SJohn Marino static int
lto_obj_add_section(void * data,const char * name,off_t offset,off_t length)214*e4b17023SJohn Marino lto_obj_add_section (void *data, const char *name, off_t offset,
215*e4b17023SJohn Marino off_t length)
216*e4b17023SJohn Marino {
217*e4b17023SJohn Marino struct lto_obj_add_section_data *loasd =
218*e4b17023SJohn Marino (struct lto_obj_add_section_data *) data;
219*e4b17023SJohn Marino htab_t section_hash_table = (htab_t) loasd->section_hash_table;
220*e4b17023SJohn Marino char *new_name;
221*e4b17023SJohn Marino struct lto_section_slot s_slot;
222*e4b17023SJohn Marino void **slot;
223*e4b17023SJohn Marino struct lto_section_list *list = loasd->list;
224*e4b17023SJohn Marino
225*e4b17023SJohn Marino if (strncmp (name, LTO_SECTION_NAME_PREFIX,
226*e4b17023SJohn Marino strlen (LTO_SECTION_NAME_PREFIX)) != 0)
227*e4b17023SJohn Marino return 1;
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino new_name = xstrdup (name);
230*e4b17023SJohn Marino s_slot.name = new_name;
231*e4b17023SJohn Marino slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
232*e4b17023SJohn Marino if (*slot == NULL)
233*e4b17023SJohn Marino {
234*e4b17023SJohn Marino struct lto_section_slot *new_slot = XCNEW (struct lto_section_slot);
235*e4b17023SJohn Marino
236*e4b17023SJohn Marino new_slot->name = new_name;
237*e4b17023SJohn Marino new_slot->start = loasd->base_offset + offset;
238*e4b17023SJohn Marino new_slot->len = length;
239*e4b17023SJohn Marino *slot = new_slot;
240*e4b17023SJohn Marino
241*e4b17023SJohn Marino if (list != NULL)
242*e4b17023SJohn Marino {
243*e4b17023SJohn Marino if (!list->first)
244*e4b17023SJohn Marino list->first = new_slot;
245*e4b17023SJohn Marino if (list->last)
246*e4b17023SJohn Marino list->last->next = new_slot;
247*e4b17023SJohn Marino list->last = new_slot;
248*e4b17023SJohn Marino }
249*e4b17023SJohn Marino }
250*e4b17023SJohn Marino else
251*e4b17023SJohn Marino {
252*e4b17023SJohn Marino error ("two or more sections for %s", new_name);
253*e4b17023SJohn Marino return 0;
254*e4b17023SJohn Marino }
255*e4b17023SJohn Marino
256*e4b17023SJohn Marino return 1;
257*e4b17023SJohn Marino }
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino /* Build a hash table whose key is the section name and whose data is
260*e4b17023SJohn Marino the start and size of each section in the .o file. */
261*e4b17023SJohn Marino
262*e4b17023SJohn Marino htab_t
lto_obj_build_section_table(lto_file * lto_file,struct lto_section_list * list)263*e4b17023SJohn Marino lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list)
264*e4b17023SJohn Marino {
265*e4b17023SJohn Marino struct lto_simple_object *lo = (struct lto_simple_object *) lto_file;
266*e4b17023SJohn Marino htab_t section_hash_table;
267*e4b17023SJohn Marino struct lto_obj_add_section_data loasd;
268*e4b17023SJohn Marino const char *errmsg;
269*e4b17023SJohn Marino int err;
270*e4b17023SJohn Marino
271*e4b17023SJohn Marino section_hash_table = lto_obj_create_section_hash_table ();
272*e4b17023SJohn Marino
273*e4b17023SJohn Marino gcc_assert (lo->sobj_r != NULL && lo->sobj_w == NULL);
274*e4b17023SJohn Marino loasd.section_hash_table = section_hash_table;
275*e4b17023SJohn Marino loasd.base_offset = lo->base.offset;
276*e4b17023SJohn Marino loasd.list = list;
277*e4b17023SJohn Marino errmsg = simple_object_find_sections (lo->sobj_r, lto_obj_add_section,
278*e4b17023SJohn Marino &loasd, &err);
279*e4b17023SJohn Marino if (errmsg != NULL)
280*e4b17023SJohn Marino {
281*e4b17023SJohn Marino if (err == 0)
282*e4b17023SJohn Marino error ("%s", errmsg);
283*e4b17023SJohn Marino else
284*e4b17023SJohn Marino error ("%s: %s", errmsg, xstrerror (err));
285*e4b17023SJohn Marino htab_delete (section_hash_table);
286*e4b17023SJohn Marino return NULL;
287*e4b17023SJohn Marino }
288*e4b17023SJohn Marino
289*e4b17023SJohn Marino return section_hash_table;
290*e4b17023SJohn Marino }
291*e4b17023SJohn Marino
292*e4b17023SJohn Marino /* The current output file. */
293*e4b17023SJohn Marino
294*e4b17023SJohn Marino static lto_file *current_out_file;
295*e4b17023SJohn Marino
296*e4b17023SJohn Marino /* Set the current output file. Return the old one. */
297*e4b17023SJohn Marino
298*e4b17023SJohn Marino lto_file *
lto_set_current_out_file(lto_file * file)299*e4b17023SJohn Marino lto_set_current_out_file (lto_file *file)
300*e4b17023SJohn Marino {
301*e4b17023SJohn Marino lto_file *old_file;
302*e4b17023SJohn Marino
303*e4b17023SJohn Marino old_file = current_out_file;
304*e4b17023SJohn Marino current_out_file = file;
305*e4b17023SJohn Marino return old_file;
306*e4b17023SJohn Marino }
307*e4b17023SJohn Marino
308*e4b17023SJohn Marino /* Return the current output file. */
309*e4b17023SJohn Marino
310*e4b17023SJohn Marino lto_file *
lto_get_current_out_file(void)311*e4b17023SJohn Marino lto_get_current_out_file (void)
312*e4b17023SJohn Marino {
313*e4b17023SJohn Marino return current_out_file;
314*e4b17023SJohn Marino }
315*e4b17023SJohn Marino
316*e4b17023SJohn Marino /* Begin writing a new section named NAME in the current output
317*e4b17023SJohn Marino file. */
318*e4b17023SJohn Marino
319*e4b17023SJohn Marino void
lto_obj_begin_section(const char * name)320*e4b17023SJohn Marino lto_obj_begin_section (const char *name)
321*e4b17023SJohn Marino {
322*e4b17023SJohn Marino struct lto_simple_object *lo;
323*e4b17023SJohn Marino int align;
324*e4b17023SJohn Marino const char *errmsg;
325*e4b17023SJohn Marino int err;
326*e4b17023SJohn Marino
327*e4b17023SJohn Marino lo = (struct lto_simple_object *) current_out_file;
328*e4b17023SJohn Marino gcc_assert (lo != NULL
329*e4b17023SJohn Marino && lo->sobj_r == NULL
330*e4b17023SJohn Marino && lo->sobj_w != NULL
331*e4b17023SJohn Marino && lo->section == NULL);
332*e4b17023SJohn Marino
333*e4b17023SJohn Marino align = exact_log2 (POINTER_SIZE / BITS_PER_UNIT);
334*e4b17023SJohn Marino lo->section = simple_object_write_create_section (lo->sobj_w, name, align,
335*e4b17023SJohn Marino &errmsg, &err);
336*e4b17023SJohn Marino if (lo->section == NULL)
337*e4b17023SJohn Marino {
338*e4b17023SJohn Marino if (err == 0)
339*e4b17023SJohn Marino fatal_error ("%s", errmsg);
340*e4b17023SJohn Marino else
341*e4b17023SJohn Marino fatal_error ("%s: %s", errmsg, xstrerror (errno));
342*e4b17023SJohn Marino }
343*e4b17023SJohn Marino }
344*e4b17023SJohn Marino
345*e4b17023SJohn Marino /* Add data to a section. BLOCK is a pointer to memory containing
346*e4b17023SJohn Marino DATA. */
347*e4b17023SJohn Marino
348*e4b17023SJohn Marino void
lto_obj_append_data(const void * data,size_t len,void * block)349*e4b17023SJohn Marino lto_obj_append_data (const void *data, size_t len, void *block)
350*e4b17023SJohn Marino {
351*e4b17023SJohn Marino struct lto_simple_object *lo;
352*e4b17023SJohn Marino const char *errmsg;
353*e4b17023SJohn Marino int err;
354*e4b17023SJohn Marino
355*e4b17023SJohn Marino lo = (struct lto_simple_object *) current_out_file;
356*e4b17023SJohn Marino gcc_assert (lo != NULL && lo->section != NULL);
357*e4b17023SJohn Marino
358*e4b17023SJohn Marino errmsg = simple_object_write_add_data (lo->sobj_w, lo->section, data, len,
359*e4b17023SJohn Marino 1, &err);
360*e4b17023SJohn Marino if (errmsg != NULL)
361*e4b17023SJohn Marino {
362*e4b17023SJohn Marino if (err == 0)
363*e4b17023SJohn Marino fatal_error ("%s", errmsg);
364*e4b17023SJohn Marino else
365*e4b17023SJohn Marino fatal_error ("%s: %s", errmsg, xstrerror (errno));
366*e4b17023SJohn Marino }
367*e4b17023SJohn Marino
368*e4b17023SJohn Marino free (block);
369*e4b17023SJohn Marino }
370*e4b17023SJohn Marino
371*e4b17023SJohn Marino /* Stop writing to the current output section. */
372*e4b17023SJohn Marino
373*e4b17023SJohn Marino void
lto_obj_end_section(void)374*e4b17023SJohn Marino lto_obj_end_section (void)
375*e4b17023SJohn Marino {
376*e4b17023SJohn Marino struct lto_simple_object *lo;
377*e4b17023SJohn Marino
378*e4b17023SJohn Marino lo = (struct lto_simple_object *) current_out_file;
379*e4b17023SJohn Marino gcc_assert (lo != NULL && lo->section != NULL);
380*e4b17023SJohn Marino lo->section = NULL;
381*e4b17023SJohn Marino }
382