OSDN Git Service

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