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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [lto/] [lto-elf.c] - Blame information for rev 294

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 288 jeremybenn
/* LTO routines for ELF object files.
2
   Copyright 2009, 2010 Free Software Foundation, Inc.
3
   Contributed by CodeSourcery, Inc.
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 "toplev.h"
25
#include <gelf.h>
26
#include "lto.h"
27
#include "tm.h"
28
#include "libiberty.h"
29
#include "ggc.h"
30
#include "lto-streamer.h"
31
 
32
/* Cater to hosts with half-backed <elf.h> file like HP-UX.  */
33
#ifndef EM_SPARC
34
# define EM_SPARC 2
35
#endif
36
 
37
#ifndef EM_SPARC32PLUS
38
# define EM_SPARC32PLUS 18
39
#endif
40
 
41
 
42
/* Handle opening elf files on hosts, such as Windows, that may use
43
   text file handling that will break binary access.  */
44
#ifndef O_BINARY
45
# define O_BINARY 0
46
#endif
47
 
48
 
49
/* Initialize FILE, an LTO file object for FILENAME.  */
50
static void
51
lto_file_init (lto_file *file, const char *filename, off_t offset)
52
{
53
  file->filename = filename;
54
  file->offset = offset;
55
}
56
 
57
/* An ELF file.  */
58
struct lto_elf_file
59
{
60
  /* The base information.  */
61
  lto_file base;
62
 
63
  /* The system file descriptor for the file.  */
64
  int fd;
65
 
66
  /* The libelf descriptor for the file.  */
67
  Elf *elf;
68
 
69
  /* Section number of string table used for section names.  */
70
  size_t sec_strtab;
71
 
72
  /* Writable file members.  */
73
 
74
  /* The currently active section.  */
75
  Elf_Scn *scn;
76
 
77
  /* The output stream for section header names.  */
78
  struct lto_output_stream *shstrtab_stream;
79
 
80
  /* Linked list of data which must be freed *after* the file has been
81
     closed.  This is an annoying limitation of libelf.  */
82
  struct lto_char_ptr_base *data;
83
};
84
typedef struct lto_elf_file lto_elf_file;
85
 
86
/* Stores executable header attributes which must be shared by all ELF files.
87
   This is used for validating input files and populating output files.  */
88
static struct {
89
  bool initialized;
90
  /* 32 or 64 bits?  */
91
  size_t bits;
92
  unsigned char elf_ident[EI_NIDENT];
93
  Elf64_Half elf_machine;
94
} cached_file_attrs;
95
 
96
 
97
/* Return the section header for SECTION.  The return value is never
98
   NULL.  Call lto_elf_free_shdr to release the memory allocated.  */
99
 
100
static Elf64_Shdr *
101
lto_elf_get_shdr (Elf_Scn *section)
102
{
103
  Elf64_Shdr *shdr;
104
 
105
  switch (cached_file_attrs.bits)
106
    {
107
    case 32:
108
      {
109
        Elf32_Shdr *shdr32;
110
 
111
        /* Read the 32-bit section header.  */
112
        shdr32 = elf32_getshdr (section);
113
        if (!shdr32)
114
          fatal_error ("could not read section header: %s", elf_errmsg (0));
115
 
116
        /* Transform it into a 64-bit section header.  */
117
        shdr = XNEW (Elf64_Shdr);
118
        shdr->sh_name = shdr32->sh_name;
119
        shdr->sh_type = shdr32->sh_type;
120
        shdr->sh_flags = shdr32->sh_flags;
121
        shdr->sh_addr = shdr32->sh_addr;
122
        shdr->sh_offset = shdr32->sh_offset;
123
        shdr->sh_size = shdr32->sh_size;
124
        shdr->sh_link = shdr32->sh_link;
125
        shdr->sh_info = shdr32->sh_info;
126
        shdr->sh_addralign = shdr32->sh_addralign;
127
        shdr->sh_entsize  = shdr32->sh_entsize;
128
        break;
129
      }
130
      break;
131
 
132
    case 64:
133
      shdr = elf64_getshdr (section);
134
      if (!shdr)
135
        fatal_error ("could not read section header: %s", elf_errmsg (0));
136
      break;
137
 
138
    default:
139
      gcc_unreachable ();
140
    }
141
 
142
  return shdr;
143
}
144
 
145
/* Free SHDR, previously allocated by lto_elf_get_shdr.  */
146
static void
147
lto_elf_free_shdr (Elf64_Shdr *shdr)
148
{
149
  if (cached_file_attrs.bits != 64)
150
    free (shdr);
151
}
152
 
153
 
154
/* Returns a hash code for P.  */
155
 
156
static hashval_t
157
hash_name (const void *p)
158
{
159
  const struct lto_section_slot *ds = (const struct lto_section_slot *) p;
160
  return (hashval_t) htab_hash_string (ds->name);
161
}
162
 
163
 
164
/* Returns nonzero if P1 and P2 are equal.  */
165
 
166
static int
167
eq_name (const void *p1, const void *p2)
168
{
169
  const struct lto_section_slot *s1 =
170
    (const struct lto_section_slot *) p1;
171
  const struct lto_section_slot *s2 =
172
    (const struct lto_section_slot *) p2;
173
 
174
  return strcmp (s1->name, s2->name) == 0;
175
}
176
 
177
 
178
/* Build a hash table whose key is the section names and whose data is
179
   the start and size of each section in the .o file.  */
180
 
181
htab_t
182
lto_obj_build_section_table (lto_file *lto_file)
183
{
184
  lto_elf_file *elf_file = (lto_elf_file *)lto_file;
185
  htab_t section_hash_table;
186
  Elf_Scn *section;
187
  size_t base_offset;
188
 
189
  section_hash_table = htab_create (37, hash_name, eq_name, free);
190
 
191
  base_offset = elf_getbase (elf_file->elf);
192
  /* We are reasonably sure that elf_getbase does not fail at this
193
     point.  So assume that we run into the incompatibility with
194
     the FreeBSD libelf implementation that has a non-working
195
     elf_getbase for non-archive members in which case the offset
196
     should be zero.  */
197
  if (base_offset == (size_t)-1)
198
    base_offset = 0;
199
  for (section = elf_getscn (elf_file->elf, 0);
200
       section;
201
       section = elf_nextscn (elf_file->elf, section))
202
    {
203
      Elf64_Shdr *shdr;
204
      const char *name;
205
      size_t offset;
206
      char *new_name;
207
      void **slot;
208
      struct lto_section_slot s_slot;
209
 
210
      /* Get the name of this section.  */
211
      shdr = lto_elf_get_shdr (section);
212
      offset = shdr->sh_name;
213
      name = elf_strptr (elf_file->elf,
214
                         elf_file->sec_strtab,
215
                         offset);
216
 
217
      /* Only put lto stuff into the symtab.  */
218
      if (strncmp (name, LTO_SECTION_NAME_PREFIX,
219
                   strlen (LTO_SECTION_NAME_PREFIX)) != 0)
220
        {
221
          lto_elf_free_shdr (shdr);
222
          continue;
223
        }
224
 
225
      new_name = XNEWVEC (char, strlen (name) + 1);
226
      strcpy (new_name, name);
227
      s_slot.name = new_name;
228
      slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
229
      if (*slot == NULL)
230
        {
231
          struct lto_section_slot *new_slot = XNEW (struct lto_section_slot);
232
 
233
          new_slot->name = new_name;
234
          /* The offset into the file for this section.  */
235
          new_slot->start = base_offset + shdr->sh_offset;
236
          new_slot->len = shdr->sh_size;
237
          *slot = new_slot;
238
        }
239
      else
240
        {
241
          error ("two or more sections for %s:", new_name);
242
          return NULL;
243
        }
244
 
245
      lto_elf_free_shdr (shdr);
246
    }
247
 
248
  return section_hash_table;
249
}
250
 
251
 
252
/* Initialize the section header of section SCN.  SH_NAME is the section name
253
   as an index into the section header string table.  SH_TYPE is the section
254
   type, an SHT_* macro from libelf headers.  */
255
 
256
#define DEFINE_INIT_SHDR(BITS)                                        \
257
static void                                                           \
258
init_shdr##BITS (Elf_Scn *scn, size_t sh_name, size_t sh_type)        \
259
{                                                                     \
260
  Elf##BITS##_Shdr *shdr;                                             \
261
                                                                      \
262
  shdr = elf##BITS##_getshdr (scn);                                   \
263
  if (!shdr)                                                          \
264
    {                                                                 \
265
      if (BITS == 32)                                                 \
266
        fatal_error ("elf32_getshdr() failed: %s", elf_errmsg (-1));  \
267
      else                                                            \
268
        fatal_error ("elf64_getshdr() failed: %s", elf_errmsg (-1));  \
269
    }                                                                 \
270
                                                                      \
271
  shdr->sh_name = sh_name;                                            \
272
  shdr->sh_type = sh_type;                                            \
273
  shdr->sh_addralign = POINTER_SIZE / BITS_PER_UNIT;                  \
274
  shdr->sh_flags = 0;                                                  \
275
  shdr->sh_entsize = 0;                                                \
276
}
277
 
278
DEFINE_INIT_SHDR (32)
279
DEFINE_INIT_SHDR (64)
280
 
281
static bool first_data_block;
282
 
283
/* Begin a new ELF section named NAME with type TYPE in the current output
284
   file.  TYPE is an SHT_* macro from the libelf headers.  */
285
 
286
static void
287
lto_elf_begin_section_with_type (const char *name, size_t type)
288
{
289
  lto_elf_file *file;
290
  Elf_Scn *scn;
291
  size_t sh_name;
292
 
293
  /* Grab the current output file and do some basic assertion checking.  */
294
  file = (lto_elf_file *) lto_get_current_out_file (),
295
  gcc_assert (file);
296
  gcc_assert (file->elf);
297
  gcc_assert (!file->scn);
298
 
299
  /* Create a new section.  */
300
  scn = elf_newscn (file->elf);
301
  if (!scn)
302
    fatal_error ("could not create a new ELF section: %s", elf_errmsg (-1));
303
  file->scn = scn;
304
 
305
  /* Add a string table entry and record the offset.  */
306
  gcc_assert (file->shstrtab_stream);
307
  sh_name = file->shstrtab_stream->total_size;
308
  lto_output_data_stream (file->shstrtab_stream, name, strlen (name) + 1);
309
 
310
  /* Initialize the section header.  */
311
  switch (cached_file_attrs.bits)
312
    {
313
    case 32:
314
      init_shdr32 (scn, sh_name, type);
315
      break;
316
 
317
    case 64:
318
      init_shdr64 (scn, sh_name, type);
319
      break;
320
 
321
    default:
322
      gcc_unreachable ();
323
    }
324
 
325
  first_data_block = true;
326
}
327
 
328
 
329
/* Begin a new ELF section named NAME in the current output file.  */
330
 
331
void
332
lto_obj_begin_section (const char *name)
333
{
334
  lto_elf_begin_section_with_type (name, SHT_PROGBITS);
335
}
336
 
337
 
338
/* Append DATA of length LEN to the current output section.  BASE is a pointer
339
   to the output page containing DATA.  It is freed once the output file has
340
   been written.  */
341
 
342
void
343
lto_obj_append_data (const void *data, size_t len, void *block)
344
{
345
  lto_elf_file *file;
346
  Elf_Data *elf_data;
347
  struct lto_char_ptr_base *base = (struct lto_char_ptr_base *) block;
348
 
349
  /* Grab the current output file and do some basic assertion checking.  */
350
  file = (lto_elf_file *) lto_get_current_out_file ();
351
  gcc_assert (file);
352
  gcc_assert (file->scn);
353
 
354
  elf_data = elf_newdata (file->scn);
355
  if (!elf_data)
356
    fatal_error ("could not append data to ELF section: %s", elf_errmsg (-1));
357
 
358
  if (first_data_block)
359
    {
360
      elf_data->d_align = POINTER_SIZE / BITS_PER_UNIT;
361
      first_data_block = false;
362
    }
363
  else
364
    elf_data->d_align = 1;
365
  elf_data->d_buf = CONST_CAST (void *, data);
366
  elf_data->d_off = 0LL;
367
  elf_data->d_size = len;
368
  elf_data->d_type = ELF_T_BYTE;
369
  elf_data->d_version = EV_CURRENT;
370
 
371
  base->ptr = (char *)file->data;
372
  file->data = base;
373
}
374
 
375
 
376
/* End the current output section.  This just does some assertion checking
377
   and sets the current output file's scn member to NULL.  */
378
 
379
void
380
lto_obj_end_section (void)
381
{
382
  lto_elf_file *file;
383
 
384
  /* Grab the current output file and validate some basic assertions.  */
385
  file = (lto_elf_file *) lto_get_current_out_file ();
386
  gcc_assert (file);
387
  gcc_assert (file->scn);
388
 
389
  file->scn = NULL;
390
}
391
 
392
 
393
/* Return true if ELF_MACHINE is compatible with the cached value of the
394
   architecture and possibly update the latter.  Return false otherwise.
395
 
396
   Note: if you want to add more EM_* cases, you'll need to provide the
397
   corresponding definitions at the beginning of the file.  */
398
 
399
static bool
400
is_compatible_architecture (Elf64_Half elf_machine)
401
{
402
  if (cached_file_attrs.elf_machine == elf_machine)
403
    return true;
404
 
405
  switch (cached_file_attrs.elf_machine)
406
    {
407
    case EM_SPARC:
408
      if (elf_machine == EM_SPARC32PLUS)
409
        {
410
          cached_file_attrs.elf_machine = elf_machine;
411
          return true;
412
        }
413
      break;
414
 
415
    case EM_SPARC32PLUS:
416
      if (elf_machine == EM_SPARC)
417
        return true;
418
      break;
419
 
420
    default:
421
      break;
422
    }
423
 
424
  return false;
425
}
426
 
427
 
428
/* Validate's ELF_FILE's executable header and, if cached_file_attrs is
429
   uninitialized, caches the architecture.  */
430
 
431
#define DEFINE_VALIDATE_EHDR(BITS)                              \
432
static bool                                                     \
433
validate_ehdr##BITS (lto_elf_file *elf_file)                    \
434
{                                                               \
435
  Elf##BITS##_Ehdr *elf_header;                                 \
436
                                                                \
437
  elf_header = elf##BITS##_getehdr (elf_file->elf);             \
438
  if (!elf_header)                                              \
439
    {                                                           \
440
      error ("could not read ELF header: %s", elf_errmsg (0));   \
441
      return false;                                             \
442
    }                                                           \
443
                                                                \
444
  if (elf_header->e_type != ET_REL)                             \
445
    {                                                           \
446
      error ("not a relocatable ELF object file");              \
447
      return false;                                             \
448
    }                                                           \
449
                                                                \
450
  if (!cached_file_attrs.initialized)                           \
451
    cached_file_attrs.elf_machine = elf_header->e_machine;      \
452
  else if (!is_compatible_architecture (elf_header->e_machine)) \
453
    {                                                           \
454
      error ("inconsistent file architecture detected");        \
455
      return false;                                             \
456
    }                                                           \
457
                                                                \
458
  return true;                                                  \
459
}
460
 
461
DEFINE_VALIDATE_EHDR (32)
462
DEFINE_VALIDATE_EHDR (64)
463
 
464
 
465
#ifndef HAVE_ELF_GETSHDRSTRNDX
466
/* elf_getshdrstrndx replacement for systems that lack it, but provide
467
   either the gABI conformant or Solaris 2 variant of elf_getshstrndx
468
   instead.  */
469
 
470
static int
471
elf_getshdrstrndx (Elf *elf, size_t *dst)
472
{
473
#ifdef HAVE_ELF_GETSHSTRNDX_GABI
474
  return elf_getshstrndx (elf, dst);
475
#else
476
  return elf_getshstrndx (elf, dst) ? 0 : -1;
477
#endif
478
}
479
#endif
480
 
481
/* Validate's ELF_FILE's executable header and, if cached_file_attrs is
482
   uninitialized, caches the results.  Also records the section header string
483
   table's section index.  Returns true on success or false on failure.  */
484
 
485
static bool
486
validate_file (lto_elf_file *elf_file)
487
{
488
  const char *elf_ident;
489
 
490
  /* Some aspects of the libelf API are dependent on whether the
491
     object file is a 32-bit or 64-bit file.  Determine which kind of
492
     file this is now.  */
493
  elf_ident = elf_getident (elf_file->elf, NULL);
494
  if (!elf_ident)
495
    {
496
      error ("could not read ELF identification information: %s",
497
              elf_errmsg (0));
498
      return false;
499
 
500
    }
501
 
502
  if (!cached_file_attrs.initialized)
503
    {
504
      switch (elf_ident[EI_CLASS])
505
        {
506
        case ELFCLASS32:
507
          cached_file_attrs.bits = 32;
508
          break;
509
 
510
        case ELFCLASS64:
511
          cached_file_attrs.bits = 64;
512
          break;
513
 
514
        default:
515
          error ("unsupported ELF file class");
516
          return false;
517
        }
518
 
519
      memcpy (cached_file_attrs.elf_ident, elf_ident,
520
              sizeof cached_file_attrs.elf_ident);
521
    }
522
 
523
  if (memcmp (elf_ident, cached_file_attrs.elf_ident,
524
              sizeof cached_file_attrs.elf_ident))
525
    return false;
526
 
527
  /* Check that the input file is a relocatable object file with the correct
528
     architecture.  */
529
  switch (cached_file_attrs.bits)
530
    {
531
    case 32:
532
      if (!validate_ehdr32 (elf_file))
533
        return false;
534
      break;
535
 
536
    case 64:
537
      if (!validate_ehdr64 (elf_file))
538
        return false;
539
      break;
540
 
541
    default:
542
      gcc_unreachable ();
543
    }
544
 
545
  /* Read the string table used for section header names.  */
546
  if (elf_getshdrstrndx (elf_file->elf, &elf_file->sec_strtab) == -1)
547
    {
548
      error ("could not locate ELF string table: %s", elf_errmsg (0));
549
      return false;
550
    }
551
 
552
  cached_file_attrs.initialized = true;
553
  return true;
554
}
555
 
556
 
557
/* Helper functions used by init_ehdr.  Initialize ELF_FILE's executable
558
   header using cached data from previously read files.  */
559
 
560
#define DEFINE_INIT_EHDR(BITS)                                        \
561
static void                                                           \
562
init_ehdr##BITS (lto_elf_file *elf_file)                              \
563
{                                                                     \
564
  Elf##BITS##_Ehdr *ehdr;                                             \
565
                                                                      \
566
  gcc_assert (cached_file_attrs.bits);                                \
567
                                                                      \
568
  ehdr = elf##BITS##_newehdr (elf_file->elf);                         \
569
  if (!ehdr)                                                          \
570
    {                                                                 \
571
      if (BITS == 32)                                                 \
572
        fatal_error ("elf32_newehdr() failed: %s", elf_errmsg (-1));  \
573
      else                                                            \
574
        fatal_error ("elf64_newehdr() failed: %s", elf_errmsg (-1));  \
575
    }                                                                 \
576
                                                                      \
577
  memcpy (ehdr->e_ident, cached_file_attrs.elf_ident,                 \
578
          sizeof cached_file_attrs.elf_ident);                        \
579
  ehdr->e_type = ET_REL;                                              \
580
  ehdr->e_version = EV_CURRENT;                                       \
581
  ehdr->e_machine = cached_file_attrs.elf_machine;                    \
582
}
583
 
584
DEFINE_INIT_EHDR (32)
585
DEFINE_INIT_EHDR (64)
586
 
587
 
588
/* Initialize ELF_FILE's executable header using cached data from previously
589
   read files.  */
590
 
591
static void
592
init_ehdr (lto_elf_file *elf_file)
593
{
594
  switch (cached_file_attrs.bits)
595
    {
596
    case 32:
597
      init_ehdr32 (elf_file);
598
      break;
599
 
600
    case 64:
601
      init_ehdr64 (elf_file);
602
      break;
603
 
604
    default:
605
      gcc_unreachable ();
606
    }
607
}
608
 
609
/* Open ELF file FILENAME.  If WRITABLE is true, the file is opened for write
610
   and, if necessary, created.  Otherwise, the file is opened for reading.
611
   Returns the opened file.  */
612
 
613
lto_file *
614
lto_obj_file_open (const char *filename, bool writable)
615
{
616
  lto_elf_file *elf_file;
617
  lto_file *result = NULL;
618
  off_t offset;
619
  long loffset;
620
  off_t header_offset;
621
  const char *offset_p;
622
  char *fname;
623
  int consumed;
624
 
625
  offset_p = strrchr (filename, '@');
626
  if (offset_p
627
      && offset_p != filename
628
      && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1
629
      && strlen (offset_p) == (unsigned int)consumed)
630
    {
631
      fname = (char *) xmalloc (offset_p - filename + 1);
632
      memcpy (fname, filename, offset_p - filename);
633
      fname[offset_p - filename] = '\0';
634
      offset = (off_t)loffset;
635
      /* elf_rand expects the offset to point to the ar header, not the
636
         object itself. Subtract the size of the ar header (60 bytes).
637
         We don't uses sizeof (struct ar_hd) to avoid including ar.h */
638
      header_offset = offset - 60;
639
    }
640
  else
641
    {
642
      fname = xstrdup (filename);
643
      offset = 0;
644
      header_offset = 0;
645
    }
646
 
647
  /* Set up.  */
648
  elf_file = XCNEW (lto_elf_file);
649
  result = (lto_file *) elf_file;
650
  lto_file_init (result, fname, offset);
651
  elf_file->fd = -1;
652
 
653
  /* Open the file.  */
654
  elf_file->fd = open (fname, writable ? O_WRONLY|O_CREAT|O_BINARY
655
                                       : O_RDONLY|O_BINARY, 0666);
656
  if (elf_file->fd == -1)
657
    {
658
      error ("could not open file %s", fname);
659
      goto fail;
660
    }
661
 
662
  /* Initialize the ELF library.  */
663
  if (elf_version (EV_CURRENT) == EV_NONE)
664
    {
665
      error ("ELF library is older than that used when building GCC");
666
      goto fail;
667
    }
668
 
669
  /* Open the ELF file descriptor.  */
670
  elf_file->elf = elf_begin (elf_file->fd, writable ? ELF_C_WRITE : ELF_C_READ,
671
                             NULL);
672
  if (!elf_file->elf)
673
    {
674
      error ("could not open ELF file: %s", elf_errmsg (0));
675
      goto fail;
676
    }
677
 
678
  if (offset != 0)
679
    {
680
      Elf *e;
681
      off_t t = elf_rand (elf_file->elf, header_offset);
682
      if (t != header_offset)
683
        {
684
          error ("could not seek in archive");
685
          goto fail;
686
        }
687
 
688
      e = elf_begin (elf_file->fd, ELF_C_READ, elf_file->elf);
689
      if (e == NULL)
690
        {
691
          error("could not find archive member");
692
          goto fail;
693
        }
694
      elf_end (elf_file->elf);
695
      elf_file->elf = e;
696
    }
697
 
698
  if (writable)
699
    {
700
      init_ehdr (elf_file);
701
      elf_file->shstrtab_stream = XCNEW (struct lto_output_stream);
702
      /* Output an empty string to the section header table.  This becomes the
703
         name of the initial NULL section.  */
704
      lto_output_1_stream (elf_file->shstrtab_stream, '\0');
705
    }
706
  else
707
    if (!validate_file (elf_file))
708
      goto fail;
709
 
710
  return result;
711
 
712
 fail:
713
  if (result)
714
    lto_obj_file_close (result);
715
  return NULL;
716
}
717
 
718
 
719
/* Close ELF file FILE and clean up any associated data structures.  If FILE
720
   was opened for writing, the file's ELF data is written at this time, and
721
   any cached data buffers are freed.  */
722
 
723
void
724
lto_obj_file_close (lto_file *file)
725
{
726
  lto_elf_file *elf_file = (lto_elf_file *) file;
727
  struct lto_char_ptr_base *cur, *tmp;
728
 
729
  /* Write the ELF section header string table.  */
730
  if (elf_file->shstrtab_stream)
731
    {
732
      size_t strtab;
733
      GElf_Ehdr *ehdr_p, ehdr_buf;
734
      lto_file *old_file = lto_set_current_out_file (file);
735
 
736
      lto_elf_begin_section_with_type (".shstrtab", SHT_STRTAB);
737
      ehdr_p = gelf_getehdr (elf_file->elf, &ehdr_buf);
738
      if (ehdr_p == NULL)
739
        fatal_error ("gelf_getehdr() failed: %s", elf_errmsg (-1));
740
      strtab = elf_ndxscn (elf_file->scn);
741
      if (strtab < SHN_LORESERVE)
742
        ehdr_p->e_shstrndx = strtab;
743
      else
744
        {
745
          GElf_Shdr *shdr_p, shdr_buf;
746
          Elf_Scn *scn_p = elf_getscn (elf_file->elf, 0);
747
          if (scn_p == NULL)
748
            fatal_error ("elf_getscn() failed: %s", elf_errmsg (-1));
749
          shdr_p = gelf_getshdr (scn_p, &shdr_buf);
750
          if (shdr_p == NULL)
751
            fatal_error ("gelf_getshdr() failed: %s", elf_errmsg (-1));
752
          shdr_p->sh_link = strtab;
753
          if (gelf_update_shdr (scn_p, shdr_p) == 0)
754
            fatal_error ("gelf_update_shdr() failed: %s", elf_errmsg (-1));
755
          ehdr_p->e_shstrndx = SHN_XINDEX;
756
        }
757
      if (gelf_update_ehdr (elf_file->elf, ehdr_p) == 0)
758
        fatal_error ("gelf_update_ehdr() failed: %s", elf_errmsg (-1));
759
      lto_write_stream (elf_file->shstrtab_stream);
760
      lto_obj_end_section ();
761
 
762
      lto_set_current_out_file (old_file);
763
      free (elf_file->shstrtab_stream);
764
 
765
      if (elf_update (elf_file->elf, ELF_C_WRITE) < 0)
766
        fatal_error ("elf_update() failed: %s", elf_errmsg (-1));
767
    }
768
 
769
  if (elf_file->elf)
770
    elf_end (elf_file->elf);
771
  if (elf_file->fd != -1)
772
    close (elf_file->fd);
773
 
774
  /* Free any ELF data buffers.  */
775
  cur = elf_file->data;
776
  while (cur)
777
    {
778
      tmp = cur;
779
      cur = (struct lto_char_ptr_base *) cur->ptr;
780
      free (tmp);
781
    }
782
 
783
  free (file);
784
}
785
 
786
 
787
/* The current output file.  */
788
static lto_file *current_out_file;
789
 
790
 
791
/* Sets the current output file to FILE.  Returns the old output file or
792
   NULL.  */
793
 
794
lto_file *
795
lto_set_current_out_file (lto_file *file)
796
{
797
  lto_file *old_file = current_out_file;
798
  current_out_file = file;
799
  return old_file;
800
}
801
 
802
 
803
/* Returns the current output file.  */
804
 
805
lto_file *
806
lto_get_current_out_file (void)
807
{
808
  return current_out_file;
809
}

powered by: WebSVN 2.1.0

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