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