xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/lto/lto-object.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* LTO routines to use object files.
2    Copyright (C) 2010-2015 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 "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "fold-const.h"
36 #include "predict.h"
37 #include "tm.h"
38 #include "hard-reg-set.h"
39 #include "input.h"
40 #include "function.h"
41 #include "basic-block.h"
42 #include "tree-ssa-alias.h"
43 #include "internal-fn.h"
44 #include "gimple-expr.h"
45 #include "is-a.h"
46 #include "gimple.h"
47 #include "diagnostic-core.h"
48 #include "lto.h"
49 #include "hash-map.h"
50 #include "plugin-api.h"
51 #include "ipa-ref.h"
52 #include "cgraph.h"
53 #include "lto-streamer.h"
54 #include "lto-section-names.h"
55 #include "simple-object.h"
56 
57 /* An LTO file wrapped around an simple_object.  */
58 
59 struct lto_simple_object
60 {
61   /* The base information.  */
62   lto_file base;
63 
64   /* The system file descriptor.  */
65   int fd;
66 
67   /* The simple_object if we are reading the file.  */
68   simple_object_read *sobj_r;
69 
70   /* The simple_object if we are writing the file.  */
71   simple_object_write *sobj_w;
72 
73   /* The currently active section.  */
74   simple_object_write_section *section;
75 };
76 
77 /* Saved simple_object attributes.  FIXME: Once set, this is never
78    cleared.  */
79 
80 static simple_object_attributes *saved_attributes;
81 
82 /* Initialize FILE, an LTO file object for FILENAME.  */
83 
84 static void
85 lto_file_init (lto_file *file, const char *filename, off_t offset)
86 {
87   file->filename = filename;
88   file->offset = offset;
89 }
90 
91 /* Open the file FILENAME.  It WRITABLE is true, the file is opened
92    for write and, if necessary, created.  Otherwise, the file is
93    opened for reading.  Returns the opened file.  */
94 
95 lto_file *
96 lto_obj_file_open (const char *filename, bool writable)
97 {
98   const char *offset_p;
99   long loffset;
100   int consumed;
101   char *fname;
102   off_t offset;
103   struct lto_simple_object *lo;
104   const char *errmsg;
105   int err;
106 
107   offset_p = strrchr (filename, '@');
108   if (offset_p != NULL
109       && offset_p != filename
110       && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1
111       && strlen (offset_p) == (unsigned int) consumed)
112     {
113       fname = XNEWVEC (char, offset_p - filename + 1);
114       memcpy (fname, filename, offset_p - filename);
115       fname[offset_p - filename] = '\0';
116       offset = (off_t) loffset;
117     }
118   else
119     {
120       fname = xstrdup (filename);
121       offset = 0;
122     }
123 
124   lo = XCNEW (struct lto_simple_object);
125   lto_file_init ((lto_file *) lo, fname, offset);
126 
127   lo->fd = open (fname,
128 		 (writable
129 		  ? O_WRONLY | O_CREAT | O_BINARY
130 		  : O_RDONLY | O_BINARY),
131 		 0666);
132   if (lo->fd == -1)
133     {
134       error ("open %s failed: %s", fname, xstrerror (errno));
135       goto fail;
136     }
137 
138   if (!writable)
139     {
140       simple_object_attributes *attrs;
141 
142       lo->sobj_r = simple_object_start_read (lo->fd, offset, LTO_SEGMENT_NAME,
143 					     &errmsg, &err);
144       if (lo->sobj_r == NULL)
145 	goto fail_errmsg;
146 
147       attrs = simple_object_fetch_attributes (lo->sobj_r, &errmsg, &err);
148       if (attrs == NULL)
149 	goto fail_errmsg;
150 
151       if (saved_attributes == NULL)
152 	saved_attributes = attrs;
153       else
154 	{
155 	  errmsg = simple_object_attributes_merge (saved_attributes, attrs,
156 						   &err);
157 	  if (errmsg != NULL)
158 	    {
159 	      free (attrs);
160 	      goto fail_errmsg;
161 	    }
162 	}
163     }
164   else
165     {
166       gcc_assert (saved_attributes != NULL);
167       lo->sobj_w = simple_object_start_write (saved_attributes,
168 					      LTO_SEGMENT_NAME,
169 					      &errmsg, &err);
170       if (lo->sobj_w == NULL)
171 	goto fail_errmsg;
172     }
173 
174   return &lo->base;
175 
176  fail_errmsg:
177   if (err == 0)
178     error ("%s: %s", fname, errmsg);
179   else
180     error ("%s: %s: %s", fname, errmsg, xstrerror (err));
181 
182  fail:
183   if (lo->fd != -1)
184     lto_obj_file_close ((lto_file *) lo);
185   free (lo);
186   return NULL;
187 }
188 
189 
190 /* Close FILE.  If FILE was opened for writing, it is written out
191    now.  */
192 
193 void
194 lto_obj_file_close (lto_file *file)
195 {
196   struct lto_simple_object *lo = (struct lto_simple_object *) file;
197 
198   if (lo->sobj_r != NULL)
199     simple_object_release_read (lo->sobj_r);
200   else if (lo->sobj_w != NULL)
201     {
202       const char *errmsg;
203       int err;
204 
205       gcc_assert (lo->base.offset == 0);
206 
207       errmsg = simple_object_write_to_file (lo->sobj_w, lo->fd, &err);
208       if (errmsg != NULL)
209 	{
210 	  if (err == 0)
211 	    fatal_error (input_location, "%s", errmsg);
212 	  else
213 	    fatal_error (input_location, "%s: %s", errmsg, xstrerror (err));
214 	}
215 
216       simple_object_release_write (lo->sobj_w);
217     }
218 
219   if (lo->fd != -1)
220     {
221       if (close (lo->fd) < 0)
222 	fatal_error (input_location, "close: %s", xstrerror (errno));
223     }
224 }
225 
226 /* This is passed to lto_obj_add_section.  */
227 
228 struct lto_obj_add_section_data
229 {
230   /* The hash table of sections.  */
231   htab_t section_hash_table;
232   /* The offset of this file.  */
233   off_t base_offset;
234   /* List in linker order */
235   struct lto_section_list *list;
236 };
237 
238 /* This is called for each section in the file.  */
239 
240 static int
241 lto_obj_add_section (void *data, const char *name, off_t offset,
242 		     off_t length)
243 {
244   struct lto_obj_add_section_data *loasd =
245     (struct lto_obj_add_section_data *) data;
246   htab_t section_hash_table = (htab_t) loasd->section_hash_table;
247   char *new_name;
248   struct lto_section_slot s_slot;
249   void **slot;
250   struct lto_section_list *list = loasd->list;
251 
252   if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
253     return 1;
254 
255   new_name = xstrdup (name);
256   s_slot.name = new_name;
257   slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
258   if (*slot == NULL)
259     {
260       struct lto_section_slot *new_slot = XCNEW (struct lto_section_slot);
261 
262       new_slot->name = new_name;
263       new_slot->start = loasd->base_offset + offset;
264       new_slot->len = length;
265       *slot = new_slot;
266 
267       if (list != NULL)
268         {
269           if (!list->first)
270             list->first = new_slot;
271           if (list->last)
272             list->last->next = new_slot;
273           list->last = new_slot;
274         }
275     }
276   else
277     {
278       error ("two or more sections for %s", new_name);
279       return 0;
280     }
281 
282   return 1;
283 }
284 
285 /* Build a hash table whose key is the section name and whose data is
286    the start and size of each section in the .o file.  */
287 
288 htab_t
289 lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list)
290 {
291   struct lto_simple_object *lo = (struct lto_simple_object *) lto_file;
292   htab_t section_hash_table;
293   struct lto_obj_add_section_data loasd;
294   const char *errmsg;
295   int err;
296 
297   section_hash_table = lto_obj_create_section_hash_table ();
298 
299   gcc_assert (lo->sobj_r != NULL && lo->sobj_w == NULL);
300   loasd.section_hash_table = section_hash_table;
301   loasd.base_offset = lo->base.offset;
302   loasd.list = list;
303   errmsg = simple_object_find_sections (lo->sobj_r, lto_obj_add_section,
304 					&loasd, &err);
305   if (errmsg != NULL)
306     {
307       if (err == 0)
308 	error ("%s", errmsg);
309       else
310 	error ("%s: %s", errmsg, xstrerror (err));
311       htab_delete (section_hash_table);
312       return NULL;
313     }
314 
315   return section_hash_table;
316 }
317 
318 /* The current output file.  */
319 
320 static lto_file *current_out_file;
321 
322 /* Set the current output file.  Return the old one.  */
323 
324 lto_file *
325 lto_set_current_out_file (lto_file *file)
326 {
327   lto_file *old_file;
328 
329   old_file = current_out_file;
330   current_out_file = file;
331   return old_file;
332 }
333 
334 /* Return the current output file.  */
335 
336 lto_file *
337 lto_get_current_out_file (void)
338 {
339   return current_out_file;
340 }
341 
342 /* Begin writing a new section named NAME in the current output
343    file.  */
344 
345 void
346 lto_obj_begin_section (const char *name)
347 {
348   struct lto_simple_object *lo;
349   int align;
350   const char *errmsg;
351   int err;
352 
353   lo = (struct lto_simple_object *) current_out_file;
354   gcc_assert (lo != NULL
355 	      && lo->sobj_r == NULL
356 	      && lo->sobj_w != NULL
357 	      && lo->section == NULL);
358 
359   align = ceil_log2 (POINTER_SIZE_UNITS);
360   lo->section = simple_object_write_create_section (lo->sobj_w, name, align,
361 						    &errmsg, &err);
362   if (lo->section == NULL)
363     {
364       if (err == 0)
365 	fatal_error (input_location, "%s", errmsg);
366       else
367 	fatal_error (input_location, "%s: %s", errmsg, xstrerror (errno));
368     }
369 }
370 
371 /* Add data to a section.  BLOCK is a pointer to memory containing
372    DATA.  */
373 
374 void
375 lto_obj_append_data (const void *data, size_t len, void *)
376 {
377   struct lto_simple_object *lo;
378   const char *errmsg;
379   int err;
380 
381   lo = (struct lto_simple_object *) current_out_file;
382   gcc_assert (lo != NULL && lo->section != NULL);
383 
384   errmsg = simple_object_write_add_data (lo->sobj_w, lo->section, data, len,
385 					 1, &err);
386   if (errmsg != NULL)
387     {
388       if (err == 0)
389 	fatal_error (input_location, "%s", errmsg);
390       else
391 	fatal_error (input_location, "%s: %s", errmsg, xstrerror (errno));
392     }
393 }
394 
395 /* Stop writing to the current output section.  */
396 
397 void
398 lto_obj_end_section (void)
399 {
400   struct lto_simple_object *lo;
401 
402   lo = (struct lto_simple_object *) current_out_file;
403   gcc_assert (lo != NULL && lo->section != NULL);
404   lo->section = NULL;
405 }
406