1 /* LTO routines for COFF object files.
2 Copyright 2009, 2010 Free Software Foundation, Inc.
3 Contributed by Dave Korn.
5 This file is part of GCC.
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
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
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/>. */
23 #include "coretypes.h"
27 #include "libiberty.h"
29 #include "lto-streamer.h"
30 #include "lto/lto-coff.h"
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. */
39 /* Handle opening elf files on hosts, such as Windows, that may use
40 text file handling that will break binary access. */
46 /* Known header magics for validation, as an array. */
48 static const unsigned int coff_machine_array[] = COFF_KNOWN_MACHINES;
50 /* Number of valid entries (no sentinel) in array. */
52 #define NUM_COFF_KNOWN_MACHINES \
53 (sizeof (coff_machine_array) / sizeof (coff_machine_array[0]))
55 /* Cached object file header. */
57 static Coff_header cached_coff_hdr;
59 /* Flag to indicate if we have read and cached any header yet. */
61 static bool cached_coff_hdr_valid = false;
63 /* The current output file. */
65 static lto_file *current_out_file;
68 /* Sets the current output file to FILE. Returns the old output file or
72 lto_set_current_out_file (lto_file *file)
74 lto_file *old_file = current_out_file;
75 current_out_file = file;
80 /* Returns the current output file. */
83 lto_get_current_out_file (void)
85 return current_out_file;
89 /* COFF section structure constructor. */
91 static lto_coff_section *
92 coff_newsection (lto_coff_file *file, const char *name, size_t type)
94 lto_coff_section *ptr, **chain_ptr_ptr;
96 ptr = XCNEW (lto_coff_section);
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;
109 /* COFF section data block structure constructor. */
111 static lto_coff_data *
112 coff_newdata (lto_coff_section *sec)
114 lto_coff_data *ptr, **chain_ptr_ptr;
116 ptr = XCNEW (lto_coff_data);
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;
127 /* Initialize FILE, an LTO file object for FILENAME. */
130 lto_file_init (lto_file *file, const char *filename, off_t offset)
132 file->filename = filename;
133 file->offset = offset;
136 /* Returns a hash code for P. */
139 hash_name (const void *p)
141 const struct lto_section_slot *ds = (const struct lto_section_slot *) p;
142 return (hashval_t) htab_hash_string (ds->name);
145 /* Returns nonzero if P1 and P2 are equal. */
148 eq_name (const void *p1, const void *p2)
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;
155 return strcmp (s1->name, s2->name) == 0;
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. */
163 lto_obj_build_section_table (lto_file *lto_file)
165 lto_coff_file *coff_file = (lto_coff_file *)lto_file;
166 lto_coff_section *sec;
167 htab_t section_hash_table;
171 section_hash_table = htab_create (37, hash_name, eq_name, free);
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))
177 error ("altered or invalid COFF object file");
178 return section_hash_table;
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)
185 error ("invalid COFF object file string table");
186 return section_hash_table;
189 /* Scan sections looking at names. */
190 COFF_FOR_ALL_SECTIONS(coff_file, sec)
192 struct lto_section_slot s_slot;
196 char *name = (char *) &sec->coffsec.Name[0];
198 /* Skip dummy string section if by any chance we see it. */
204 if (1 != sscanf (&name[1], "%d", &stringoffset)
205 || stringoffset < 0 || stringoffset >= strtab_size)
207 error ("invalid COFF section name string");
210 name = strtab + stringoffset;
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. */
219 if (strncmp (name, LTO_SECTION_NAME_PREFIX,
220 strlen (LTO_SECTION_NAME_PREFIX)) != 0)
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);
229 struct lto_section_slot *new_slot = XNEW (struct lto_section_slot);
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);
240 error ("two or more sections for %s:", new_name);
246 return section_hash_table;
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. */
254 lto_coff_begin_section_with_type (const char *name, size_t type)
259 /* Grab the current output file and do some basic assertion checking. */
260 file = (lto_coff_file *) lto_get_current_out_file (),
262 gcc_assert (!file->scn);
264 /* Create a new section. */
265 file->scn = coff_newsection (file, name, type);
267 fatal_error ("could not create a new COFF section: %m");
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);
274 /* Initialize the section header. */
275 file->scn->strtab_offs = sh_name;
279 /* Begin a new COFF section named NAME in the current output file. */
282 lto_obj_begin_section (const char *name)
284 lto_coff_begin_section_with_type (name, 0);
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
293 lto_obj_append_data (const void *data, size_t len, void *block)
296 lto_coff_data *coff_data;
297 struct lto_char_ptr_base *base = (struct lto_char_ptr_base *) block;
299 /* Grab the current output file and do some basic assertion checking. */
300 file = (lto_coff_file *) lto_get_current_out_file ();
302 gcc_assert (file->scn);
304 coff_data = coff_newdata (file->scn);
306 fatal_error ("could not append data to COFF section: %m");
308 coff_data->d_buf = CONST_CAST (void *, data);
309 coff_data->d_size = len;
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;
318 /* End the current output section. This just does some assertion checking
319 and sets the current output file's scn member to NULL. */
322 lto_obj_end_section (void)
326 /* Grab the current output file and validate some basic assertions. */
327 file = (lto_coff_file *) lto_get_current_out_file ();
329 gcc_assert (file->scn);
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. */
340 validate_file (lto_coff_file *coff_file)
343 unsigned int numsections, secheaderssize, numsyms;
344 off_t sectionsstart, symbolsstart, stringsstart;
345 unsigned int mach, charact;
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))
351 error ("not a COFF object file");
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])
359 if (n == NUM_COFF_KNOWN_MACHINES)
361 error ("not a recognized COFF object file");
365 charact = COFF_GET(&coff_file->coffhdr, Characteristics);
366 if (COFF_NOT_CHARACTERISTICS & charact)
368 /* DLL, EXE or SYS file. */
369 error ("not a relocatable COFF object file");
373 if (mach != IMAGE_FILE_MACHINE_AMD64
374 && COFF_CHARACTERISTICS != (COFF_CHARACTERISTICS & charact))
376 /* ECOFF/XCOFF support not implemented. */
377 error ("not a 32-bit COFF object file");
381 /* It validated OK, so cached it if we don't already have one. */
382 if (!cached_coff_hdr_valid)
384 cached_coff_hdr_valid = true;
385 memcpy (&cached_coff_hdr, &coff_file->coffhdr, sizeof (cached_coff_hdr));
388 if (mach != COFF_GET(&cached_coff_hdr, Machine))
390 error ("inconsistent file architecture detected");
394 /* Read section headers and string table? */
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);
403 #define CVOFFSETTTED(x) (coff_file->base.offset + (x))
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))
410 error ("not a valid COFF object file");
416 /* Record start of string table. */
417 coff_file->strtab_offs = stringsstart;
419 /* Validate section table entries. */
420 for (secnum = 0; secnum < numsections; secnum++)
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;
427 n = read (coff_file->fd, &coffsec, sizeof (coffsec));
428 if (n != sizeof (coffsec))
430 error ("short/missing COFF section table");
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);
441 if (size_raw < 0 || num_relocs < 0 || num_lines < 0
443 && ((COFF_GET(&coffsec, Characteristics)
444 & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
446 : (offs_raw < sectionsstart || offs_raw >= coff_file->file_size)))
448 && (offs_relocs < sectionsstart
449 || offs_relocs >= coff_file->file_size))
451 && (offs_lines < sectionsstart
452 || offs_lines >= coff_file->file_size)))
454 error ("invalid COFF section table");
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 (<osec->coffsec, &coffsec, sizeof (ltosec->coffsec));
468 /* Initialize COFF_FILE's executable header using cached data from previously
472 init_coffhdr (lto_coff_file *coff_file)
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));
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. */
485 lto_obj_file_open (const char *filename, bool writable)
487 lto_coff_file *coff_file;
488 lto_file *result = NULL;
490 const char *offset_p;
494 offset_p = strchr (filename, '@');
497 fname = xstrdup (filename);
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",
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);
516 coff_file = XCNEW (lto_coff_file);
517 result = (lto_file *) coff_file;
518 lto_file_init (result, fname, offset);
522 coff_file->fd = open (fname,
523 O_BINARY | (writable ? O_WRONLY | O_CREAT | O_TRUNC : O_RDONLY), 0666);
525 if (coff_file->fd == -1)
527 error ("could not open file %s", fname);
531 if (stat (fname, &statbuf) < 0)
533 error ("could not stat file %s", fname);
537 coff_file->file_size = statbuf.st_size;
545 gcc_assert (!writable);
547 /* Seek to offset, or error. */
548 if (lseek (coff_file->fd, offset, SEEK_SET) != (ssize_t) offset)
550 error ("could not find archive member @0x%lx", (long) offset);
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')
561 error ("could not find archive header @0x%lx", (long) offset);
566 if (sscanf (ar_tail, "%d", &size) != 1)
568 error ("invalid archive header @0x%lx", (long) offset);
571 coff_file->file_size = size;
576 init_coffhdr (coff_file);
577 coff_file->shstrtab_stream = XCNEW (struct lto_output_stream);
580 if (!validate_file (coff_file))
587 lto_obj_file_close (result);
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. */
597 coff_write_object_file (lto_coff_file *coff_file)
599 lto_coff_section *cursec, *stringsec;
601 size_t fileoffset, numsections, totalsecsize, numsyms, stringssize;
602 bool write_err = false;
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)
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);
623 /* Layout the file. Count sections (not dummy string section) and calculate
624 data size for all of them. */
629 COFF_FOR_ALL_SECTIONS(coff_file, cursec)
634 COFF_FOR_ALL_DATA(cursec,data)
635 cursecsize += data->d_size;
636 if (cursec->type == 0)
639 totalsecsize += COFF_ALIGN(cursecsize);
640 #if COFF_ALIGNMENT > 1
641 cursec->pad_needed = COFF_ALIGN(cursecsize) - cursecsize;
646 stringssize = cursecsize;
649 COFF_PUT(&cursec->coffsec, SizeOfRawData, cursecsize);
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);
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. */
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)
668 /* Skip dummy string section. */
669 if (cursec->type == 1)
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);
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. */
681 /* Write the COFF header. */
682 write_err = (write (coff_file->fd, &coff_file->coffhdr,
683 sizeof (coff_file->coffhdr)) != sizeof (coff_file->coffhdr));
685 /* Write the COFF section headers. */
686 COFF_FOR_ALL_SECTIONS(coff_file, cursec)
687 if (cursec->type == 1) /* Skip dummy string section. */
690 write_err = (write (coff_file->fd, &cursec->coffsec,
691 sizeof (cursec->coffsec)) != sizeof (cursec->coffsec));
695 /* Write the COFF sections. */
696 COFF_FOR_ALL_SECTIONS(coff_file, cursec)
698 #if COFF_ALIGNMENT > 1
699 static const char padzeros[COFF_ALIGNMENT] = { 0 };
701 /* Skip dummy string section. */
702 if (cursec->type == 1)
704 COFF_FOR_ALL_DATA(cursec, data)
706 write_err = (write (coff_file->fd, data->d_buf, data->d_size)
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);
717 /* Write the COFF symbol table. */
723 Coff_aux_sym_file file;
724 Coff_aux_sym_section sec;
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));
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;
746 COFF_FOR_ALL_SECTIONS(coff_file, cursec)
748 /* Skip dummy string section. */
749 if (cursec->type == 1)
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));
758 write_err = (write (coff_file->fd, &symbols[0], sizeof (symbols))
759 != (2 * COFF_SYMBOL_SIZE));
765 /* Write the COFF string table. */
768 unsigned char outlen[4];
769 COFF_PUT4(outlen, stringssize + 4);
771 write_err = (write (coff_file->fd, outlen, 4) != 4);
774 COFF_FOR_ALL_DATA(stringsec, data)
776 write_err = (write (coff_file->fd, data->d_buf, data->d_size)
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. */
791 lto_obj_file_close (lto_file *file)
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;
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);
803 /* Close the file, we're done. */
804 if (coff_file->fd != -1)
805 close (coff_file->fd);
807 /* Free any data buffers. */
808 cur = coff_file->data;
812 cur = (struct lto_char_ptr_base *) cur->ptr;
816 /* Free any sections and their data chains. */
817 cursec = coff_file->section_chain;
820 lto_coff_data *curdata, *nextdata;
821 nextsec = cursec->next;
822 curdata = cursec->data_chain;
825 nextdata = curdata->next;
835 /* If there was an error, mention it. */
837 error ("I/O error writing COFF output file");