OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [lto/] [lto-object.c] - Blame information for rev 716

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 716 jeremybenn
/* LTO routines to use object files.
2
   Copyright 2010 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
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 *
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
            goto fail_errmsg;
137
        }
138
    }
139
  else
140
    {
141
      gcc_assert (saved_attributes != NULL);
142
      lo->sobj_w = simple_object_start_write (saved_attributes,
143
                                              LTO_SEGMENT_NAME,
144
                                              &errmsg, &err);
145
      if (lo->sobj_w == NULL)
146
        goto fail_errmsg;
147
    }
148
 
149
  return &lo->base;
150
 
151
 fail_errmsg:
152
  if (err == 0)
153
    error ("%s: %s", fname, errmsg);
154
  else
155
    error ("%s: %s: %s", fname, errmsg, xstrerror (err));
156
 
157
 fail:
158
  if (lo != NULL)
159
    lto_obj_file_close ((lto_file *) lo);
160
  return NULL;
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 ("%s", errmsg);
185
          else
186
            fatal_error ("%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 ("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, LTO_SECTION_NAME_PREFIX,
226
               strlen (LTO_SECTION_NAME_PREFIX)) != 0)
227
    return 1;
228
 
229
  new_name = xstrdup (name);
230
  s_slot.name = new_name;
231
  slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
232
  if (*slot == NULL)
233
    {
234
      struct lto_section_slot *new_slot = XCNEW (struct lto_section_slot);
235
 
236
      new_slot->name = new_name;
237
      new_slot->start = loasd->base_offset + offset;
238
      new_slot->len = length;
239
      *slot = new_slot;
240
 
241
      if (list != NULL)
242
        {
243
          if (!list->first)
244
            list->first = new_slot;
245
          if (list->last)
246
            list->last->next = new_slot;
247
          list->last = new_slot;
248
        }
249
    }
250
  else
251
    {
252
      error ("two or more sections for %s", new_name);
253
      return 0;
254
    }
255
 
256
  return 1;
257
}
258
 
259
/* Build a hash table whose key is the section name and whose data is
260
   the start and size of each section in the .o file.  */
261
 
262
htab_t
263
lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list)
264
{
265
  struct lto_simple_object *lo = (struct lto_simple_object *) lto_file;
266
  htab_t section_hash_table;
267
  struct lto_obj_add_section_data loasd;
268
  const char *errmsg;
269
  int err;
270
 
271
  section_hash_table = lto_obj_create_section_hash_table ();
272
 
273
  gcc_assert (lo->sobj_r != NULL && lo->sobj_w == NULL);
274
  loasd.section_hash_table = section_hash_table;
275
  loasd.base_offset = lo->base.offset;
276
  loasd.list = list;
277
  errmsg = simple_object_find_sections (lo->sobj_r, lto_obj_add_section,
278
                                        &loasd, &err);
279
  if (errmsg != NULL)
280
    {
281
      if (err == 0)
282
        error ("%s", errmsg);
283
      else
284
        error ("%s: %s", errmsg, xstrerror (err));
285
      htab_delete (section_hash_table);
286
      return NULL;
287
    }
288
 
289
  return section_hash_table;
290
}
291
 
292
/* The current output file.  */
293
 
294
static lto_file *current_out_file;
295
 
296
/* Set the current output file.  Return the old one.  */
297
 
298
lto_file *
299
lto_set_current_out_file (lto_file *file)
300
{
301
  lto_file *old_file;
302
 
303
  old_file = current_out_file;
304
  current_out_file = file;
305
  return old_file;
306
}
307
 
308
/* Return the current output file.  */
309
 
310
lto_file *
311
lto_get_current_out_file (void)
312
{
313
  return current_out_file;
314
}
315
 
316
/* Begin writing a new section named NAME in the current output
317
   file.  */
318
 
319
void
320
lto_obj_begin_section (const char *name)
321
{
322
  struct lto_simple_object *lo;
323
  int align;
324
  const char *errmsg;
325
  int err;
326
 
327
  lo = (struct lto_simple_object *) current_out_file;
328
  gcc_assert (lo != NULL
329
              && lo->sobj_r == NULL
330
              && lo->sobj_w != NULL
331
              && lo->section == NULL);
332
 
333
  align = exact_log2 (POINTER_SIZE / BITS_PER_UNIT);
334
  lo->section = simple_object_write_create_section (lo->sobj_w, name, align,
335
                                                    &errmsg, &err);
336
  if (lo->section == NULL)
337
    {
338
      if (err == 0)
339
        fatal_error ("%s", errmsg);
340
      else
341
        fatal_error ("%s: %s", errmsg, xstrerror (errno));
342
    }
343
}
344
 
345
/* Add data to a section.  BLOCK is a pointer to memory containing
346
   DATA.  */
347
 
348
void
349
lto_obj_append_data (const void *data, size_t len, void *block)
350
{
351
  struct lto_simple_object *lo;
352
  const char *errmsg;
353
  int err;
354
 
355
  lo = (struct lto_simple_object *) current_out_file;
356
  gcc_assert (lo != NULL && lo->section != NULL);
357
 
358
  errmsg = simple_object_write_add_data (lo->sobj_w, lo->section, data, len,
359
                                         1, &err);
360
  if (errmsg != NULL)
361
    {
362
      if (err == 0)
363
        fatal_error ("%s", errmsg);
364
      else
365
        fatal_error ("%s: %s", errmsg, xstrerror (errno));
366
    }
367
 
368
  free (block);
369
}
370
 
371
/* Stop writing to the current output section.  */
372
 
373
void
374
lto_obj_end_section (void)
375
{
376
  struct lto_simple_object *lo;
377
 
378
  lo = (struct lto_simple_object *) current_out_file;
379
  gcc_assert (lo != NULL && lo->section != NULL);
380
  lo->section = NULL;
381
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.