OSDN Git Service

* lto.c (has_analyzed_clone_p): New function
[pf3gnuchains/gcc-fork.git] / gcc / lto / lto-coff.c
1 /* LTO routines for COFF object files.
2    Copyright 2009, 2010 Free Software Foundation, Inc.
3    Contributed by Dave Korn.
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 "toplev.h"
26 #include "lto.h"
27 #include "tm.h"
28 #include "libiberty.h"
29 #include "ggc.h"
30 #include "lto-streamer.h"
31 #include "lto/lto-coff.h"
32
33
34 /* Rather than implementing a libcoff to match libelf, or attempting to
35    integrate libbfd into GCC, this file is a self-contained (and very
36    minimal) COFF format object file reader/writer.  The generated files
37    will contain a COFF header, a number of COFF section headers, the 
38    section data itself, and a trailing string table for section names.  */
39
40 /* Handle opening elf files on hosts, such as Windows, that may use 
41    text file handling that will break binary access.  */
42
43 #ifndef O_BINARY
44 #define O_BINARY 0
45 #endif
46
47 /* Known header magics for validation, as an array.  */
48
49 static const unsigned int coff_machine_array[] = COFF_KNOWN_MACHINES;
50
51 /* Number of valid entries (no sentinel) in array.  */
52
53 #define NUM_COFF_KNOWN_MACHINES \
54         (sizeof (coff_machine_array) / sizeof (coff_machine_array[0]))
55
56 /* Cached object file header.  */
57
58 static Coff_header cached_coff_hdr;
59
60 /* Flag to indicate if we have read and cached any header yet.  */
61
62 static bool cached_coff_hdr_valid = false;
63
64 /* The current output file.  */
65
66 static lto_file *current_out_file;
67
68
69 /* Sets the current output file to FILE.  Returns the old output file or
70    NULL.  */
71
72 lto_file *
73 lto_set_current_out_file (lto_file *file)
74 {
75   lto_file *old_file = current_out_file;
76   current_out_file = file;
77   return old_file;
78 }
79
80
81 /* Returns the current output file.  */
82
83 lto_file *
84 lto_get_current_out_file (void)
85 {
86   return current_out_file;
87 }
88
89
90 /* COFF section structure constructor.  */
91
92 static lto_coff_section *
93 coff_newsection (lto_coff_file *file, const char *name, size_t type)
94 {
95   lto_coff_section *ptr, **chain_ptr_ptr;
96
97   ptr = XCNEW (lto_coff_section);
98   ptr->name = name;
99   ptr->type = type;
100
101   chain_ptr_ptr = &file->section_chain;
102   while (*chain_ptr_ptr)
103     chain_ptr_ptr = &(*chain_ptr_ptr)->next;
104   *chain_ptr_ptr = ptr;
105
106   return ptr;
107 }
108
109
110 /* COFF section data block structure constructor.  */
111
112 static lto_coff_data *
113 coff_newdata (lto_coff_section *sec)
114 {
115   lto_coff_data *ptr, **chain_ptr_ptr;
116
117   ptr = XCNEW (lto_coff_data);
118
119   chain_ptr_ptr = &sec->data_chain;
120   while (*chain_ptr_ptr)
121     chain_ptr_ptr = &(*chain_ptr_ptr)->next;
122   *chain_ptr_ptr = ptr;
123
124   return ptr;
125 }
126
127
128 /* Initialize FILE, an LTO file object for FILENAME.  */
129
130 static void
131 lto_file_init (lto_file *file, const char *filename, off_t offset)
132 {
133   file->filename = filename;
134   file->offset = offset;
135 }
136
137 /* Build a hash table whose key is the section names and whose data is
138    the start and size of each section in the .o file.  */
139
140 htab_t
141 lto_obj_build_section_table (lto_file *lto_file) 
142 {
143   lto_coff_file *coff_file = (lto_coff_file *)lto_file;
144   lto_coff_section *sec;
145   htab_t section_hash_table;
146   ssize_t strtab_size;
147   char *strtab;
148
149   section_hash_table = lto_obj_create_section_hash_table ();
150
151   /* Seek to start of string table.  */
152   if (coff_file->strtab_offs != lseek (coff_file->fd,
153                 coff_file->base.offset + coff_file->strtab_offs, SEEK_SET))
154     {
155       error ("altered or invalid COFF object file");
156       return section_hash_table;
157     }
158
159   strtab_size = coff_file->file_size - coff_file->strtab_offs;
160   strtab = XNEWVEC (char, strtab_size);
161   if (read (coff_file->fd, strtab, strtab_size) != strtab_size)
162     {
163       error ("invalid COFF object file string table");
164       return section_hash_table;
165     }
166
167   /* Scan sections looking at names.  */
168   COFF_FOR_ALL_SECTIONS(coff_file, sec)
169     {
170       struct lto_section_slot s_slot;
171       void **slot;
172       char *new_name;
173       int stringoffset;
174       char *name = (char *) &sec->coffsec.Name[0];
175
176       /* Skip dummy string section if by any chance we see it.  */
177       if (sec->type == 1)
178         continue;
179
180       if (name[0] == '/')
181         {
182           if (1 != sscanf (&name[1], "%d", &stringoffset)
183                 || stringoffset < 0 || stringoffset >= strtab_size)
184             {
185               error ("invalid COFF section name string");
186               continue;
187             }
188           name = strtab + stringoffset;
189         }
190       else
191         {
192           /* If we cared about the VirtualSize field, we couldn't
193              crudely trash it like this to guarantee nul-termination
194              of the Name field.  But we don't, so we do.  */
195           name[8] = 0;
196         }
197       if (strncmp (name, LTO_SECTION_NAME_PREFIX,
198                         strlen (LTO_SECTION_NAME_PREFIX)) != 0)
199           continue;
200
201       new_name = XNEWVEC (char, strlen (name) + 1);
202       strcpy (new_name, name);
203       s_slot.name = new_name;
204       slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
205       if (*slot == NULL)
206         {
207           struct lto_section_slot *new_slot = XNEW (struct lto_section_slot);
208
209           new_slot->name = new_name;
210           /* The offset into the file for this section.  */
211           new_slot->start = coff_file->base.offset
212                         + COFF_GET(&sec->coffsec,PointerToRawData);
213           new_slot->len = COFF_GET(&sec->coffsec,SizeOfRawData);
214           *slot = new_slot;
215         }
216       else
217         {
218           error ("two or more sections for %s:", new_name);
219           return NULL;
220         }
221     }
222
223   free (strtab);
224   return section_hash_table;
225 }
226
227
228 /* Begin a new COFF section named NAME with type TYPE in the current output
229    file.  TYPE is an SHT_* macro from the libelf headers.  */
230
231 static void
232 lto_coff_begin_section_with_type (const char *name, size_t type)
233 {
234   lto_coff_file *file;
235   size_t sh_name;
236
237   /* Grab the current output file and do some basic assertion checking.  */
238   file = (lto_coff_file *) lto_get_current_out_file (),
239   gcc_assert (file);
240   gcc_assert (!file->scn);
241
242   /* Create a new section.  */
243   file->scn = coff_newsection (file, name, type);
244   if (!file->scn)
245     fatal_error ("could not create a new COFF section: %m");
246
247   /* Add a string table entry and record the offset.  */
248   gcc_assert (file->shstrtab_stream);
249   sh_name = file->shstrtab_stream->total_size;
250   lto_output_data_stream (file->shstrtab_stream, name, strlen (name) + 1);
251
252   /* Initialize the section header.  */
253   file->scn->strtab_offs = sh_name;
254 }
255
256
257 /* Begin a new COFF section named NAME in the current output file.  */
258
259 void
260 lto_obj_begin_section (const char *name)
261 {
262   lto_coff_begin_section_with_type (name, 0);
263 }
264
265
266 /* Append DATA of length LEN to the current output section.  BASE is a pointer
267    to the output page containing DATA.  It is freed once the output file has
268    been written.  */
269
270 void
271 lto_obj_append_data (const void *data, size_t len, void *block)
272 {
273   lto_coff_file *file;
274   lto_coff_data *coff_data;
275   struct lto_char_ptr_base *base = (struct lto_char_ptr_base *) block;
276
277   /* Grab the current output file and do some basic assertion checking.  */
278   file = (lto_coff_file *) lto_get_current_out_file ();
279   gcc_assert (file);
280   gcc_assert (file->scn);
281
282   coff_data = coff_newdata (file->scn);
283   if (!coff_data)
284     fatal_error ("could not append data to COFF section: %m");
285
286   coff_data->d_buf = CONST_CAST (void *, data);
287   coff_data->d_size = len;
288
289   /* Chain all data blocks (from all sections) on one singly-linked
290      list for freeing en masse after the file is closed.  */
291   base->ptr = (char *)file->data;
292   file->data = base;
293 }
294
295
296 /* End the current output section.  This just does some assertion checking
297    and sets the current output file's scn member to NULL.  */
298
299 void
300 lto_obj_end_section (void)
301 {
302   lto_coff_file *file;
303
304   /* Grab the current output file and validate some basic assertions.  */
305   file = (lto_coff_file *) lto_get_current_out_file ();
306   gcc_assert (file);
307   gcc_assert (file->scn);
308
309   file->scn = NULL;
310 }
311
312
313 /* Validate's COFF_FILE's executable header and, if cached_coff_hdr is
314    uninitialized, caches the results.  Also records the section header string
315    table's section index.  Returns true on success or false on failure.  */
316
317 static bool
318 validate_file (lto_coff_file *coff_file)
319 {
320   size_t n, secnum;
321   unsigned int numsections, secheaderssize, numsyms;
322   off_t sectionsstart, symbolsstart, stringsstart;
323   unsigned int mach, charact;
324
325   /* Read and sanity check the raw header.  */
326   n = read (coff_file->fd, &coff_file->coffhdr, sizeof (coff_file->coffhdr));
327   if (n != sizeof (coff_file->coffhdr))
328     {
329       error ("not a COFF object file");
330       return false;
331     }
332
333   mach = COFF_GET(&coff_file->coffhdr, Machine);
334   for (n = 0; n < NUM_COFF_KNOWN_MACHINES; n++)
335     if (mach == coff_machine_array[n])
336       break;
337   if (n == NUM_COFF_KNOWN_MACHINES)
338     {
339       error ("not a recognized COFF object file");
340       return false;
341     }
342
343   charact = COFF_GET(&coff_file->coffhdr, Characteristics);
344   if (COFF_NOT_CHARACTERISTICS & charact)
345     {
346       /* DLL, EXE or SYS file.  */
347       error ("not a relocatable COFF object file");
348       return false;
349     }
350
351   if (mach != IMAGE_FILE_MACHINE_AMD64
352       && COFF_CHARACTERISTICS != (COFF_CHARACTERISTICS & charact))
353     {
354       /* ECOFF/XCOFF support not implemented.  */
355       error ("not a 32-bit COFF object file");
356       return false;
357     }
358
359   /* It validated OK, so cached it if we don't already have one.  */
360   if (!cached_coff_hdr_valid)
361     {
362       cached_coff_hdr_valid = true;
363       memcpy (&cached_coff_hdr, &coff_file->coffhdr, sizeof (cached_coff_hdr));
364     }
365
366   if (mach != COFF_GET(&cached_coff_hdr, Machine))
367     {
368       error ("inconsistent file architecture detected");
369       return false;
370     }
371
372   /* Read section headers and string table? */
373
374   numsections = COFF_GET(&coff_file->coffhdr, NumberOfSections);
375   secheaderssize = numsections * sizeof (Coff_section);
376   sectionsstart = sizeof (Coff_header) + secheaderssize;
377   symbolsstart = COFF_GET(&coff_file->coffhdr, PointerToSymbolTable);
378   numsyms = COFF_GET(&coff_file->coffhdr, NumberOfSymbols);
379   stringsstart = (symbolsstart + COFF_SYMBOL_SIZE * numsyms);
380
381 #define CVOFFSETTTED(x) (coff_file->base.offset + (x))
382
383   if (numsections <= 0 || symbolsstart <= 0 || numsyms <= 0
384         || (CVOFFSETTTED(sectionsstart) >= coff_file->file_size)
385         || (CVOFFSETTTED(symbolsstart) >= coff_file->file_size)
386         || (CVOFFSETTTED(stringsstart) >= coff_file->file_size))
387     {
388       error ("not a valid COFF object file");
389       return false;
390     }
391
392 #undef CVOFFSETTTED
393
394   /* Record start of string table.  */
395   coff_file->strtab_offs = stringsstart;
396
397   /* Validate section table entries.  */
398   for (secnum = 0; secnum < numsections; secnum++)
399     {
400       Coff_section coffsec;
401       lto_coff_section *ltosec;
402       off_t size_raw, offs_raw, offs_relocs, offs_lines;
403       off_t num_relocs, num_lines;
404
405       n = read (coff_file->fd, &coffsec, sizeof (coffsec));
406       if (n != sizeof (coffsec))
407         {
408           error ("short/missing COFF section table");
409           return false;
410         }
411
412       size_raw = COFF_GET(&coffsec, SizeOfRawData);
413       offs_raw = COFF_GET(&coffsec, PointerToRawData);
414       offs_relocs = COFF_GET(&coffsec, PointerToRelocations);
415       offs_lines = COFF_GET(&coffsec, PointerToLinenumbers);
416       num_relocs = COFF_GET(&coffsec, NumberOfRelocations);
417       num_lines = COFF_GET(&coffsec, NumberOfLinenumbers);
418
419       if (size_raw < 0 || num_relocs < 0 || num_lines < 0
420         || (size_raw
421           && ((COFF_GET(&coffsec, Characteristics)
422               & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
423             ? (offs_raw != 0)
424             : (offs_raw < sectionsstart || offs_raw >= coff_file->file_size)))
425         || (num_relocs
426           && (offs_relocs < sectionsstart
427             || offs_relocs >= coff_file->file_size))
428         || (num_lines
429           && (offs_lines < sectionsstart
430             || offs_lines >= coff_file->file_size)))
431         {
432           error ("invalid COFF section table");
433           return false;
434         }
435
436       /* Looks ok, so record its details.  We don't read the 
437          string table or set up names yet; we'll do that when
438          we build the hash table.  */
439       ltosec = coff_newsection (coff_file, NULL, 0);
440       memcpy (&ltosec->coffsec, &coffsec, sizeof (ltosec->coffsec));
441     }
442
443   return true;
444 }
445
446 /* Initialize COFF_FILE's executable header using cached data from previously
447    read files.  */
448
449 static void
450 init_coffhdr (lto_coff_file *coff_file)
451 {
452   gcc_assert (cached_coff_hdr_valid);
453   memset (&coff_file->coffhdr, 0, sizeof (coff_file->coffhdr));
454   COFF_PUT(&coff_file->coffhdr, Machine, COFF_GET(&cached_coff_hdr, Machine));
455   COFF_PUT(&coff_file->coffhdr, Characteristics, COFF_GET(&cached_coff_hdr, Characteristics));
456 }
457
458 /* Open COFF file FILENAME.  If WRITABLE is true, the file is opened for write
459    and, if necessary, created.  Otherwise, the file is opened for reading.
460    Returns the opened file.  */
461
462 lto_file *
463 lto_obj_file_open (const char *filename, bool writable)
464 {
465   lto_coff_file *coff_file;
466   lto_file *result = NULL;
467   off_t offset;
468   const char *offset_p;
469   char *fname;
470   struct stat statbuf;
471
472   offset_p = strchr (filename, '@');
473   if (!offset_p)
474     {
475       fname = xstrdup (filename);
476       offset = 0;
477     }
478   else
479     {
480       /* The file started with '@' is a file containing command line
481          options.  Stop if it doesn't exist.  */
482       if (offset_p == filename)
483         fatal_error ("command line option file '%s' does not exist",
484                      filename);
485
486       fname = (char *) xmalloc (offset_p - filename + 1);
487       memcpy (fname, filename, offset_p - filename);
488       fname[offset_p - filename] = '\0';
489       offset_p += 3; /* skip the @0x */
490       offset = lto_parse_hex (offset_p);
491     }
492
493   /* Set up.  */
494   coff_file = XCNEW (lto_coff_file);
495   result = (lto_file *) coff_file;
496   lto_file_init (result, fname, offset);
497   coff_file->fd = -1;
498
499   /* Open the file.  */
500   coff_file->fd = open (fname,
501     O_BINARY | (writable ? O_WRONLY | O_CREAT | O_TRUNC : O_RDONLY), 0666);
502
503   if (coff_file->fd == -1)
504     {
505       error ("could not open file %s", fname);
506       goto fail;
507     }
508
509   if (stat (fname, &statbuf) < 0)
510     {
511       error ("could not stat file %s", fname);
512       goto fail;
513     }
514
515   coff_file->file_size = statbuf.st_size;
516
517   if (offset != 0)
518     {
519       char ar_tail[12];
520       int size;
521
522       /* Surely not?  */
523       gcc_assert (!writable);
524
525       /* Seek to offset, or error.  */
526       if (lseek (coff_file->fd, offset, SEEK_SET) != (ssize_t) offset)
527         {
528           error ("could not find archive member @0x%lx", (long) offset);
529           goto fail;
530         }
531
532       /* Now seek back 12 chars and read the tail of the AR header to
533          find the length of the member file.  */
534       if (lseek (coff_file->fd, -12, SEEK_CUR) < 0
535           || read (coff_file->fd, ar_tail, 12) != 12
536           || lseek (coff_file->fd, 0, SEEK_CUR) != (ssize_t) offset
537           || ar_tail[10] != '`' || ar_tail[11] != '\n')
538         {
539           error ("could not find archive header @0x%lx", (long) offset);
540           goto fail;
541         }
542
543       ar_tail[11] = 0;
544       if (sscanf (ar_tail, "%d", &size) != 1)
545         {
546           error ("invalid archive header @0x%lx", (long) offset);
547           goto fail;
548         }
549       coff_file->file_size = size;
550     }
551
552   if (writable)
553     {
554       init_coffhdr (coff_file);
555       coff_file->shstrtab_stream = XCNEW (struct lto_output_stream);
556     }
557   else
558     if (!validate_file (coff_file))
559       goto fail;
560
561   return result;
562
563  fail:
564   if (result)
565     lto_obj_file_close (result);
566   return NULL;
567 }
568
569
570 /* Close COFF file FILE and clean up any associated data structures.  If FILE
571    was opened for writing, the file's COFF data is written at this time, and
572    any cached data buffers are freed.  Return TRUE if there was an error.  */
573
574 static bool
575 coff_write_object_file (lto_coff_file *coff_file)
576 {
577   lto_coff_section *cursec, *stringsec;
578   lto_coff_data *data;
579   size_t fileoffset, numsections, totalsecsize, numsyms, stringssize;
580   bool write_err = false;
581   int secnum;
582
583   /* Infer whether this file was opened for reading or writing from the
584      presence or absense of an initialised stream for the string table;
585      do nothing if it was opened for reading.  */
586   if (!coff_file->shstrtab_stream)
587     return false;
588   else
589     {
590       /* Write the COFF string table into a dummy new section that
591          we will not write a header for.  */
592       lto_file *old_file = lto_set_current_out_file (&coff_file->base);
593       /* This recursively feeds in the data to a new section.  */
594       lto_coff_begin_section_with_type (".strtab", 1);
595       lto_write_stream (coff_file->shstrtab_stream);
596       lto_obj_end_section ();
597       lto_set_current_out_file (old_file);
598       free (coff_file->shstrtab_stream);
599     }
600
601   /* Layout the file.  Count sections (not dummy string section) and calculate
602      data size for all of them.  */
603   numsections = 0;
604   totalsecsize = 0;
605   stringssize = 0;
606   stringsec = NULL;
607   COFF_FOR_ALL_SECTIONS(coff_file, cursec)
608     {
609       lto_coff_data *data;
610       size_t cursecsize;
611       cursecsize = 0;
612       COFF_FOR_ALL_DATA(cursec,data)
613         cursecsize += data->d_size;
614       if (cursec->type == 0)
615         {
616           ++numsections;
617           totalsecsize += COFF_ALIGN(cursecsize);
618 #if COFF_ALIGNMENT > 1
619           cursec->pad_needed = COFF_ALIGN(cursecsize) - cursecsize;
620 #endif
621         }
622       else
623         {
624           stringssize = cursecsize;
625           stringsec = cursec;
626         }
627       COFF_PUT(&cursec->coffsec, SizeOfRawData, cursecsize);
628     }
629
630   /* There is a file symbol and a section symbol per section,
631      and each of these has a single auxiliary symbol following.  */
632   numsyms = 2 * (1 + numsections);
633
634   /* Great!  Now we have enough info to fill out the file header.  */
635   COFF_PUT(&coff_file->coffhdr, NumberOfSections, numsections);
636   COFF_PUT(&coff_file->coffhdr, NumberOfSymbols, numsyms);
637   COFF_PUT(&coff_file->coffhdr, PointerToSymbolTable, sizeof (Coff_header)
638                 + numsections * sizeof (Coff_section) + totalsecsize);
639   /* The remaining members were initialised to zero or copied from
640      a cached header, so we leave them alone here.  */
641
642   /* Now position all the sections, and fill out their headers.  */
643   fileoffset = sizeof (Coff_header) + numsections * sizeof (Coff_section);
644   COFF_FOR_ALL_SECTIONS(coff_file, cursec)
645     {
646       /* Skip dummy string section.  */
647       if (cursec->type == 1)
648         continue;
649       COFF_PUT(&cursec->coffsec, PointerToRawData, fileoffset);
650       fileoffset += COFF_ALIGN (COFF_GET(&cursec->coffsec, SizeOfRawData));
651       COFF_PUT(&cursec->coffsec, Characteristics, COFF_SECTION_CHARACTERISTICS);
652       snprintf ((char *)&cursec->coffsec.Name[0], 8, "/%d", cursec->strtab_offs + 4);
653     }
654
655   /* We can write the data now.  As there's no way to indicate an error return
656      from this hook, error handling is limited to not wasting our time doing
657      any more writes in the event that any one fails.  */
658
659   /* Write the COFF header.  */
660   write_err = (write (coff_file->fd, &coff_file->coffhdr,
661                 sizeof (coff_file->coffhdr)) != sizeof (coff_file->coffhdr));
662
663   /* Write the COFF section headers.  */
664   COFF_FOR_ALL_SECTIONS(coff_file, cursec)
665     if (cursec->type == 1)      /* Skip dummy string section.  */
666         continue;
667     else if (!write_err)
668       write_err = (write (coff_file->fd, &cursec->coffsec,
669                 sizeof (cursec->coffsec)) != sizeof (cursec->coffsec));
670     else
671       break;
672
673   /* Write the COFF sections.  */
674   COFF_FOR_ALL_SECTIONS(coff_file, cursec)
675     {
676 #if COFF_ALIGNMENT > 1
677       static const char padzeros[COFF_ALIGNMENT] = { 0 };
678 #endif
679       /* Skip dummy string section.  */
680       if (cursec->type == 1)
681         continue;
682       COFF_FOR_ALL_DATA(cursec, data)
683         if (!write_err)
684           write_err = (write (coff_file->fd, data->d_buf, data->d_size)
685                 != data->d_size);
686         else
687           break;
688 #if COFF_ALIGNMENT > 1
689       if (!write_err && cursec->pad_needed)
690         write_err = (write (coff_file->fd, padzeros, cursec->pad_needed)
691                 != cursec->pad_needed);
692 #endif
693     }
694
695   /* Write the COFF symbol table.  */
696   if (!write_err)
697     {
698       union
699         {
700           Coff_symbol sym;
701           Coff_aux_sym_file file;
702           Coff_aux_sym_section sec;
703         } symbols[2];
704       memset (&symbols[0], 0, sizeof (symbols));
705       strcpy ((char *) &symbols[0].sym.Name[0], ".file");
706       COFF_PUT(&symbols[0].sym, SectionNumber, IMAGE_SYM_DEBUG);
707       COFF_PUT(&symbols[0].sym, Type, IMAGE_SYM_TYPE);
708       symbols[0].sym.StorageClass[0] = IMAGE_SYM_CLASS_FILE;
709       symbols[0].sym.NumberOfAuxSymbols[0] = 1;
710       snprintf ((char *)symbols[1].file.FileName,
711                 sizeof (symbols[1].file.FileName),
712                 "%s", lbasename (coff_file->base.filename));
713       write_err = (write (coff_file->fd, &symbols[0], sizeof (symbols))
714                 != (2 * COFF_SYMBOL_SIZE));
715
716       /* Set up constant parts for section sym loop.  */
717       memset (&symbols[0], 0, sizeof (symbols));
718       COFF_PUT(&symbols[0].sym, Type, IMAGE_SYM_TYPE);
719       symbols[0].sym.StorageClass[0] = IMAGE_SYM_CLASS_STATIC;
720       symbols[0].sym.NumberOfAuxSymbols[0] = 1;
721
722       secnum = 1;
723       if (!write_err)
724         COFF_FOR_ALL_SECTIONS(coff_file, cursec)
725           {
726             /* Skip dummy string section.  */
727             if (cursec->type == 1)
728               continue;
729             /* Reuse section name string for section symbol name.  */
730             COFF_PUT_NDXSZ(&symbols[0].sym, Name, 0, 0, 4);
731             COFF_PUT_NDXSZ(&symbols[0].sym, Name, cursec->strtab_offs + 4, 4, 4);
732             COFF_PUT(&symbols[0].sym, SectionNumber, secnum++);
733             COFF_PUT(&symbols[1].sec, Length,
734                         COFF_GET(&cursec->coffsec, SizeOfRawData));
735             if (!write_err)
736               write_err = (write (coff_file->fd, &symbols[0], sizeof (symbols))
737                         != (2 * COFF_SYMBOL_SIZE));
738             else
739               break;
740           }
741     }
742
743   /* Write the COFF string table.  */
744   if (!write_err)
745     {
746       unsigned char outlen[4];
747       COFF_PUT4(outlen, stringssize + 4);
748       if (!write_err)
749         write_err = (write (coff_file->fd, outlen, 4) != 4);
750       if (stringsec)
751         {
752           COFF_FOR_ALL_DATA(stringsec, data)
753             if (!write_err)
754               write_err = (write (coff_file->fd, data->d_buf, data->d_size)
755                            != data->d_size);
756             else
757               break;
758         }
759     }
760
761   return write_err;
762 }
763
764 /* Close COFF file FILE and clean up any associated data structures.  If FILE
765    was opened for writing, the file's COFF data is written at this time, and
766    any cached data buffers are freed.  */
767
768 void
769 lto_obj_file_close (lto_file *file)
770 {
771   lto_coff_file *coff_file = (lto_coff_file *) file;
772   struct lto_char_ptr_base *cur, *tmp;
773   lto_coff_section *cursec, *nextsec;
774   bool write_err = false;
775
776   /* Write the COFF string table into a dummy new section that
777      we will not write a header for.  */
778   if (coff_file->shstrtab_stream)
779     coff_write_object_file (coff_file);
780
781   /* Close the file, we're done.  */
782   if (coff_file->fd != -1)
783     close (coff_file->fd);
784
785   /* Free any data buffers.  */
786   cur = coff_file->data;
787   while (cur)
788     {
789       tmp = cur;
790       cur = (struct lto_char_ptr_base *) cur->ptr;
791       free (tmp);
792     }
793
794   /* Free any sections and their data chains.  */
795   cursec = coff_file->section_chain;
796   while (cursec)
797     {
798       lto_coff_data *curdata, *nextdata;
799       nextsec = cursec->next;
800       curdata = cursec->data_chain;
801       while (curdata)
802         {
803           nextdata = curdata->next;
804           free (curdata);
805           curdata = nextdata;
806         }
807       free (cursec);
808       cursec = nextsec;
809     }
810
811   free (file);
812
813   /* If there was an error, mention it.  */
814   if (write_err)
815     error ("I/O error writing COFF output file");
816 }
817