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