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