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