xref: /dragonfly/contrib/gcc-8.0/gcc/lto/lto-object.c (revision abf903a5)
1 /* LTO routines to use object files.
2    Copyright (C) 2010-2018 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 "tm.h"
25 #include "diagnostic-core.h"
26 #include "lto.h"
27 #include "lto-section-names.h"
28 #include "simple-object.h"
29 
30 /* An LTO file wrapped around an simple_object.  */
31 
32 struct 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 
53 static simple_object_attributes *saved_attributes;
54 
55 /* Initialize FILE, an LTO file object for FILENAME.  */
56 
57 static void
58 lto_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 
68 lto_file *
69 lto_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 	{
128 	  errmsg = simple_object_attributes_merge (saved_attributes, attrs,
129 						   &err);
130 	  if (errmsg != NULL)
131 	    {
132 	      free (attrs);
133 	      goto fail_errmsg;
134 	    }
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:
156   if (lo->fd != -1)
157     lto_obj_file_close ((lto_file *) lo);
158   free (lo);
159   return NULL;
160 }
161 
162 
163 /* Close FILE.  If FILE was opened for writing, it is written out
164    now.  */
165 
166 void
167 lto_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)
184 	    fatal_error (input_location, "%s", errmsg);
185 	  else
186 	    fatal_error (input_location, "%s: %s", errmsg, xstrerror (err));
187 	}
188 
189       simple_object_release_write (lo->sobj_w);
190     }
191 
192   if (lo->fd != -1)
193     {
194       if (close (lo->fd) < 0)
195 	fatal_error (input_location, "close: %s", xstrerror (errno));
196     }
197 }
198 
199 /* This is passed to lto_obj_add_section.  */
200 
201 struct 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;
207   /* List in linker order */
208   struct lto_section_list *list;
209 };
210 
211 /* This is called for each section in the file.  */
212 
213 static int
214 lto_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;
223   struct lto_section_list *list = loasd->list;
224 
225   if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
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     {
233       struct lto_section_slot *new_slot = XCNEW (struct lto_section_slot);
234 
235       new_slot->name = new_name;
236       new_slot->start = loasd->base_offset + offset;
237       new_slot->len = length;
238       *slot = new_slot;
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         }
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 
261 htab_t
262 lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list)
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;
275   loasd.list = list;
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 
293 static lto_file *current_out_file;
294 
295 /* Set the current output file.  Return the old one.  */
296 
297 lto_file *
298 lto_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 
309 lto_file *
310 lto_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 
318 void
319 lto_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 
332   align = ceil_log2 (POINTER_SIZE_UNITS);
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)
338 	fatal_error (input_location, "%s", errmsg);
339       else
340 	fatal_error (input_location, "%s: %s", errmsg, xstrerror (errno));
341     }
342 }
343 
344 /* Add data to a section.  BLOCK is a pointer to memory containing
345    DATA.  */
346 
347 void
348 lto_obj_append_data (const void *data, size_t len, void *)
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)
362 	fatal_error (input_location, "%s", errmsg);
363       else
364 	fatal_error (input_location, "%s: %s", errmsg, xstrerror (errno));
365     }
366 }
367 
368 /* Stop writing to the current output section.  */
369 
370 void
371 lto_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 }
379