Fix unused warnings.
[official-gcc/graphite-test-results.git] / gcc / lto / lto-macho.c
blob9f89e8e9bb31cd5e0eab246f1111f71957cc444c
1 /* LTO routines for Mach-O object files.
2 Copyright 2010 Free Software Foundation, Inc.
3 Contributed by Steven Bosscher.
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
10 version.
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.
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/>. */
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 "lto-streamer.h"
30 #include "lto/lto-endian.h"
31 #include "lto/lto-macho.h"
33 /* Rather than implementing a libmacho to match libelf, or attempting to
34 integrate libbfd into GCC, this file is a self-contained (and very
35 minimal) Mach-O format object file reader/writer. The generated files
36 will contain a Mach-O header, a number of Mach-O load commands an
37 section headers, the section data itself, and a trailing string table
38 for section names. */
40 /* This needs to be kept in sync with darwin.c. Better yet, lto-macho.c
41 and lto-macho.h should be moved to config/, and likewise for lto-coff.*
42 and lto-elf.*. */
44 /* Segment name for LTO sections. */
45 #define LTO_SEGMENT_NAME "__GNU_LTO"
47 /* Section name for LTO section names section. */
48 #define LTO_NAMES_SECTION "__section_names"
50 /* Handle opening elf files on hosts, such as Windows, that may use
51 text file handling that will break binary access. */
52 #ifndef O_BINARY
53 # define O_BINARY 0
54 #endif
56 /* Cached object file header. We use a header_64 for this, since all
57 the fields we need are in there, in the same position as header_32. */
58 mach_o_header_64 cached_mach_o_header;
59 uint32_t cached_mach_o_magic;
61 /* The current output file. */
62 static lto_file *current_out_file;
65 /* Is this a 32-bits or 64-bits Mach-O object file? */
66 static int
67 mach_o_word_size (void)
69 gcc_assert (cached_mach_o_magic != 0);
70 return (cached_mach_o_magic == MACH_O_MH_MAGIC_64
71 || cached_mach_o_magic == MACH_O_MH_CIGAM_64) ? 64 : 32;
74 /* Sets the current output file to FILE. Returns the old output file or
75 NULL. */
77 lto_file *
78 lto_set_current_out_file (lto_file *file)
80 lto_file *old_file = current_out_file;
81 current_out_file = file;
82 return old_file;
86 /* Returns the current output file. */
88 lto_file *
89 lto_get_current_out_file (void)
91 return current_out_file;
94 /* Mach-O section structure constructor. */
96 static lto_mach_o_section
97 mach_o_new_section (lto_mach_o_file *mach_o_file, const char *name)
99 lto_mach_o_section ptr;
101 /* FIXME We could allocate these things on an obstack. */
102 ptr = XCNEW (struct lto_mach_o_section_d);
103 if (name)
105 if (strncmp (name, LTO_SECTION_NAME_PREFIX,
106 strlen(LTO_SECTION_NAME_PREFIX)) != 0)
107 sorry ("not implemented: Mach-O writer for non-LTO sections");
108 ptr->name = xstrdup (name);
111 VEC_safe_push (lto_mach_o_section, heap, mach_o_file->section_vec, ptr);
113 return ptr;
116 /* Mach-O section data block structure constructor. */
118 static lto_mach_o_data
119 mach_o_new_data (lto_mach_o_section sec)
121 lto_mach_o_data ptr, *chain_ptr_ptr;
123 /* FIXME We could allocate these things on an obstack. */
124 ptr = XCNEW (struct lto_mach_o_data_d);
126 chain_ptr_ptr = &sec->data_chain;
127 while (*chain_ptr_ptr)
128 chain_ptr_ptr = &(*chain_ptr_ptr)->next;
129 *chain_ptr_ptr = ptr;
131 return ptr;
134 /* Initialize FILE, an LTO file object for FILENAME. Offset is the
135 offset into FILE where the object is located (e.g. in an archive). */
137 static void
138 lto_file_init (lto_file *file, const char *filename, off_t offset)
140 file->filename = filename;
141 file->offset = offset;
144 /* Build a hash table whose key is the section names and whose data is
145 the start and size of each section in the .o file. */
147 htab_t
148 lto_obj_build_section_table (lto_file *lto_file)
150 lto_mach_o_file *mach_o_file = (lto_mach_o_file *)lto_file;
151 lto_mach_o_section sec;
152 htab_t section_hash_table;
153 off_t strtab_offs;
154 ssize_t strtab_size;
155 char *strtab = NULL;
156 int i;
158 section_hash_table = lto_obj_create_section_hash_table ();
160 /* Seek the string table. */
161 /* FIXME The segment name should be in darwin.h, but can we include it
162 here in this file? */
163 for (i = 0;
164 VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
165 i++)
167 if (strncmp (sec->u.section.segname, "__GNU_LTO", 16) != 0)
168 continue;
169 if (strncmp (sec->u.section.sectname, "__section_names", 16) == 0)
170 break;
172 if (! sec)
174 error ("invalid Mach-O LTO object file: no __section_names section found");
175 goto done;
177 mach_o_file->section_names_section = sec;
179 if (mach_o_word_size () == 64)
181 strtab_offs = (off_t) get_uint32 (&sec->u.section_64.offset[0]);
182 strtab_size = (size_t) get_uint64 (&sec->u.section_64.size[0]);
184 else
186 strtab_offs = (off_t) get_uint32 (&sec->u.section_32.offset[0]);
187 strtab_size = (size_t) get_uint32 (&sec->u.section_32.size[0]);
190 /* Seek to start of string table. */
191 if (strtab_offs != lseek (mach_o_file->fd,
192 mach_o_file->base.offset + strtab_offs,
193 SEEK_SET))
195 error ("altered or invalid Mach-O object file");
196 goto done;
199 strtab = XNEWVEC (char, strtab_size);
200 if (read (mach_o_file->fd, strtab, strtab_size) != strtab_size)
202 error ("invalid Mach-O LTO object file __section_names section");
203 goto done;
206 /* Scan sections looking at names. */
207 for (i = 0;
208 VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
209 i++)
211 struct lto_section_slot s_slot;
212 void **slot;
213 char *new_name;
214 unsigned long stringoffset;
215 char name[17];
217 /* Ignore non-LTO sections. Also ignore the __section_names section
218 which does not need renaming. */
219 if (strncmp (sec->u.section.segname, "__GNU_LTO", 16) != 0)
220 continue;
221 if (sec == mach_o_file->section_names_section)
222 continue;
224 /* Try to extract the offset of the real name for this section from
225 __section_names. */
226 memcpy (&name[0], sec->u.section.sectname, 16);
227 name[16] = '\0';
228 if (name[0] != '_' || name[1] != '_'
229 || sscanf (&name[2], "%08lX", &stringoffset) != 1
230 || strtab_size < (ssize_t) stringoffset)
232 error ("invalid Mach-O LTO section name string: %s", name);
233 continue;
236 new_name = XNEWVEC (char, strlen (strtab + stringoffset) + 1);
237 strcpy (new_name, strtab + stringoffset);
238 s_slot.name = new_name;
239 slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
240 if (*slot == NULL)
242 struct lto_section_slot *new_slot = XNEW (struct lto_section_slot);
244 new_slot->name = new_name;
245 if (mach_o_word_size() == 64)
247 new_slot->start =
248 (intptr_t) get_uint32 (&sec->u.section_64.offset[0]);
249 new_slot->len =
250 (size_t) get_uint64 (&sec->u.section_64.size[0]);
252 else
254 new_slot->start =
255 (intptr_t) get_uint32 (&sec->u.section_32.offset[0]);
256 new_slot->len =
257 (size_t) get_uint32 (&sec->u.section_32.size[0]);
260 *slot = new_slot;
262 else
264 error ("two or more sections for %s:", new_name);
265 goto done;
269 done:
270 if (strtab)
271 free (strtab);
272 return section_hash_table;
276 /* Begin a new Mach-O section named NAME in the current output file. */
278 void
279 lto_obj_begin_section (const char *name)
281 lto_mach_o_file *file;
283 if (strncmp (name, LTO_SECTION_NAME_PREFIX,
284 strlen(LTO_SECTION_NAME_PREFIX)) != 0)
285 sorry ("not implemented: Mach-O writer for non-LTO sections");
287 /* Grab the current output file and do some basic assertion checking. */
288 file = (lto_mach_o_file *) lto_get_current_out_file (),
289 gcc_assert (file && file->writable && !file->scn);
291 /* Create a new section. */
292 file->scn = mach_o_new_section (file, name);
293 if (!file->scn)
294 fatal_error ("could not create a new Mach-O section: %m");
298 /* Append DATA of length LEN to the current output section. BASE is a pointer
299 to the output page containing DATA. It is freed once the output file has
300 been written. */
302 void
303 lto_obj_append_data (const void *data, size_t len, void *block)
305 lto_mach_o_file *file;
306 lto_mach_o_data mach_o_data;
307 struct lto_char_ptr_base *base = (struct lto_char_ptr_base *) block;
309 /* Grab the current output file and do some basic assertion checking. */
310 file = (lto_mach_o_file *) lto_get_current_out_file ();
311 gcc_assert (file);
312 gcc_assert (file->scn);
314 mach_o_data = mach_o_new_data (file->scn);
315 if (!mach_o_data)
316 fatal_error ("could not append data to Mach-O section: %m");
318 mach_o_data->d_buf = CONST_CAST (void *, data);
319 mach_o_data->d_size = len;
321 /* Chain all data blocks (from all sections) on one singly-linked
322 list for freeing en masse after the file is closed. */
323 base->ptr = (char *)file->data;
324 file->data = base;
328 /* End the current output section. This just does some assertion checking
329 and sets the current output file's scn member to NULL. */
331 void
332 lto_obj_end_section (void)
334 lto_mach_o_file *file;
336 /* Grab the current output file and validate some basic assertions. */
337 file = (lto_mach_o_file *) lto_get_current_out_file ();
338 gcc_assert (file);
339 gcc_assert (file->scn);
341 file->scn = NULL;
345 /* Read a Mach-O header from MACH_O_FILE and validate it.
346 The file descriptor in MACH_O_FILE points at the start of the file.
347 If cached_mach_o_header is uninitialized, caches the results.
348 On succes, returns true and moves file pointer to the start of the
349 load commands. On failure, returns false. */
351 static bool
352 validate_mach_o_header (lto_mach_o_file *mach_o_file)
354 ssize_t i, n;
355 unsigned char magic[4];
356 uint32_t cputype;
357 off_t startpos;
359 /* Known header magics for validation, as an array. */
360 static const unsigned int mach_o_known_formats[] = {
361 MACH_O_MH_MAGIC,
362 MACH_O_MH_CIGAM,
363 MACH_O_MH_MAGIC_64,
364 MACH_O_MH_CIGAM_64,
366 #define MACH_O_NUM_KNOWN_FORMATS \
367 ((ssize_t) ARRAY_SIZE (mach_o_known_formats))
369 startpos = lseek (mach_o_file->fd, 0, SEEK_CUR);
370 if (read (mach_o_file->fd, &magic, sizeof (magic)) != 4
371 || lseek (mach_o_file->fd, -4, SEEK_CUR) != startpos)
373 error ("cannot read file %s", mach_o_file->base.filename);
374 return false;
377 for (i = 0; i < MACH_O_NUM_KNOWN_FORMATS; ++i)
378 if (get_uint32 (&magic[0]) == mach_o_known_formats[i])
379 break;
380 if (i == MACH_O_NUM_KNOWN_FORMATS)
381 goto not_for_target;
383 /* Check the endian-ness. */
384 if (BYTES_BIG_ENDIAN && magic[0] != 0xfe)
385 goto not_for_target;
387 /* Set or check cached magic number. */
388 if (cached_mach_o_magic == 0)
389 cached_mach_o_magic = get_uint32 (&magic[0]);
390 else if (cached_mach_o_magic != get_uint32 (&magic[0]))
391 goto not_for_target;
393 n = mach_o_word_size () == 64
394 ? sizeof (mach_o_header_64) : sizeof (mach_o_header_32);
395 if (read (mach_o_file->fd, &mach_o_file->u.header, n) != n)
396 goto not_for_target;
398 /* Is this a supported CPU? */
399 /* ??? Would be nice to validate the exact target architecture. */
400 cputype = get_uint32 (&mach_o_file->u.header.cputype[0]);
401 if (cputype == MACH_O_CPU_TYPE_I386
402 || cputype == MACH_O_CPU_TYPE_POWERPC)
404 if (mach_o_word_size () != 32)
405 goto not_for_target;
407 else if (cputype == MACH_O_CPU_TYPE_X86_64
408 || cputype == MACH_O_CPU_TYPE_POWERPC_64)
410 if (mach_o_word_size () != 64)
411 goto not_for_target;
414 /* Is this an MH_OBJECT file? */
415 if (get_uint32 (&mach_o_file->u.header.filetype[0]) != MACH_O_MH_OBJECT)
416 error ("Mach-O file %s is not an MH_OBJECT file",
417 mach_o_file->base.filename);
419 /* Save the header for future use. */
420 memcpy (&cached_mach_o_header, &mach_o_file->u.header,
421 sizeof (cached_mach_o_header));
423 return true;
425 not_for_target:
426 error ("file %s is not a Mach-O object file for target",
427 mach_o_file->base.filename);
428 return false;
432 /* Read a Mach-O LC_SEGMENT command (32 bits) from MACH_O_FILE and
433 validate it.
434 The file descriptor in MACH_O_FILE points at the start of the load
435 command. On sucess, returns true and advances the file pointer
436 past the end of the load command. On failure, returns false. */
438 static bool
439 validate_mach_o_segment_command_32 (lto_mach_o_file *mach_o_file)
441 mach_o_segment_command_32 seg_cmd_32;
442 unsigned int i;
443 ssize_t n;
444 off_t startpos;
446 /* Fields we're interested in. */
447 uint32_t cmd;
448 uint32_t cmdsize;
449 uint32_t nsects;
451 startpos = lseek (mach_o_file->fd, 0, SEEK_CUR);
453 n = sizeof (mach_o_segment_command_32);
454 if (read (mach_o_file->fd, (void *) &seg_cmd_32, n) != n)
455 goto fail;
457 cmd = get_uint32 (&seg_cmd_32.cmd[0]);
458 cmdsize = get_uint32 (&seg_cmd_32.cmdsize[0]);
459 nsects = get_uint32 (&seg_cmd_32.nsects[0]);
460 gcc_assert (cmd == MACH_O_LC_SEGMENT);
462 /* Validate section table entries. */
463 for (i = 0; i < nsects; i++)
465 mach_o_section_32 sec_32;
466 lto_mach_o_section ltosec;
468 n = sizeof (mach_o_section_32);
469 if (read (mach_o_file->fd, &sec_32, n) != n)
470 goto fail;
472 /* ??? Perform some checks. */
474 /* Looks ok, so record its details. We don't read the
475 string table or set up names yet; we'll do that when
476 we build the hash table. */
477 ltosec = mach_o_new_section (mach_o_file, NULL);
478 memcpy (&ltosec->u.section_32, &sec_32, sizeof (sec_32));
481 if (lseek (mach_o_file->fd, 0, SEEK_CUR) != startpos + cmdsize)
482 goto fail;
484 return true;
486 fail:
487 error ("could not read LC_SEGMENT command in Mach-O file %s",
488 mach_o_file->base.filename);
489 return false;
493 /* Read a Mach-O LC_SEGMENT_64 command from MACH_O_FILE and validate it.
494 The file descriptor in MACH_O_FILE points at the start of the load
495 command. On sucess, returns true and advances the file pointer
496 past the end of the load command. On failure, returns false. */
498 static bool
499 validate_mach_o_segment_command_64 (lto_mach_o_file *mach_o_file)
501 mach_o_segment_command_64 seg_cmd_64;
502 unsigned int i;
503 ssize_t n;
504 off_t startpos;
506 /* Fields we're interested in. */
507 uint32_t cmd;
508 uint32_t cmdsize;
509 uint32_t nsects;
511 startpos = lseek (mach_o_file->fd, 0, SEEK_CUR);
513 n = sizeof (mach_o_segment_command_64);
514 if (read (mach_o_file->fd, (void *) &seg_cmd_64, n) != n)
515 goto fail;
517 cmd = get_uint32 (&seg_cmd_64.cmd[0]);
518 cmdsize = get_uint32 (&seg_cmd_64.cmdsize[0]);
519 nsects = get_uint32 (&seg_cmd_64.nsects[0]);
520 gcc_assert (cmd == MACH_O_LC_SEGMENT_64);
522 /* Validate section table entries. */
523 for (i = 0; i < nsects; i++)
525 mach_o_section_64 sec_64;
526 lto_mach_o_section ltosec;
528 n = sizeof (mach_o_section_64);
529 if (read (mach_o_file->fd, &sec_64, n) != n)
530 goto fail;
532 /* ??? Perform some checks. */
534 /* Looks ok, so record its details. We don't read the
535 string table or set up names yet; we'll do that when
536 we build the hash table. */
537 ltosec = mach_o_new_section (mach_o_file, NULL);
538 memcpy (&ltosec->u.section_64, &sec_64, sizeof (sec_64));
541 if (lseek (mach_o_file->fd, 0, SEEK_CUR) != startpos + cmdsize)
542 goto fail;
544 return true;
546 fail:
547 error ("could not read LC_SEGMENT_64 command in Mach-O file %s",
548 mach_o_file->base.filename);
549 return false;
552 /* Read a Mach-O load commands from MACH_O_FILE and validate it.
553 The file descriptor in MACH_O_FILE points at the start of the load
554 command. On sucess, returns true and advances the file pointer
555 past the end of the load command. On failure, returns false. */
557 static bool
558 validate_mach_o_load_command (lto_mach_o_file *mach_o_file)
560 mach_o_load_command load_command;
561 uint32_t cmd;
562 uint32_t cmdsize;
563 ssize_t n;
565 n = sizeof (load_command);
566 if (read (mach_o_file->fd, &load_command, n) != n)
568 error ("could not read load commands in Mach-O file %s",
569 mach_o_file->base.filename);
570 return false;
572 lseek (mach_o_file->fd, -1 * (off_t) sizeof (load_command), SEEK_CUR);
574 cmd = get_uint32 (&load_command.cmd[0]);
575 cmdsize = get_uint32 (&load_command.cmdsize[0]);
576 switch (cmd)
578 case MACH_O_LC_SEGMENT:
579 return validate_mach_o_segment_command_32 (mach_o_file);
580 case MACH_O_LC_SEGMENT_64:
581 return validate_mach_o_segment_command_64 (mach_o_file);
583 default:
584 /* Just skip over it. */
585 lseek (mach_o_file->fd, cmdsize, SEEK_CUR);
586 return true;
590 /* Validate's MACH_O_FILE's executable header and, if cached_mach_o_header is
591 uninitialized, caches the results. Also records the section header string
592 table's section index. Returns true on success, false on failure. */
594 static bool
595 validate_file (lto_mach_o_file *mach_o_file)
597 uint32_t i, ncmds;
599 /* Read and sanity check the raw header. */
600 if (! validate_mach_o_header (mach_o_file))
601 return false;
603 ncmds = get_uint32 (&mach_o_file->u.header.ncmds[0]);
604 for (i = 0; i < ncmds; ++i)
605 if (! validate_mach_o_load_command (mach_o_file))
606 return false;
608 return true;
611 /* Initialize MACH_O_FILE's executable header using cached data from previously
612 read files. */
614 static void
615 init_mach_o_header (lto_mach_o_file *mach_o_file)
617 gcc_assert (cached_mach_o_magic != 0);
618 memcpy (&mach_o_file->u.header,
619 &cached_mach_o_header,
620 sizeof (mach_o_file->u.header));
621 put_uint32 (&mach_o_file->u.header.ncmds[0], 0);
622 put_uint32 (&mach_o_file->u.header.sizeofcmds[0], 0);
625 /* Open Mach-O file FILENAME. If WRITABLE is true, the file is opened for write
626 and, if necessary, created. Otherwise, the file is opened for reading.
627 Returns the opened file. */
629 lto_file *
630 lto_obj_file_open (const char *filename, bool writable)
632 lto_mach_o_file *mach_o_file;
633 lto_file *result = NULL;
634 off_t offset;
635 const char *offset_p;
636 char *fname;
637 struct stat statbuf;
639 offset_p = strchr (filename, '@');
640 if (!offset_p)
642 fname = xstrdup (filename);
643 offset = 0;
645 else
647 /* The file started with '@' is a file containing command line
648 options. Stop if it doesn't exist. */
649 if (offset_p == filename)
650 fatal_error ("command line option file '%s' does not exist",
651 filename);
653 fname = (char *) xmalloc (offset_p - filename + 1);
654 memcpy (fname, filename, offset_p - filename);
655 fname[offset_p - filename] = '\0';
656 offset_p += 3; /* skip the @0x */
657 offset = lto_parse_hex (offset_p);
660 /* Set up. */
661 mach_o_file = XCNEW (lto_mach_o_file);
662 result = (lto_file *) mach_o_file;
663 lto_file_init (result, fname, offset);
664 mach_o_file->fd = -1;
665 mach_o_file->writable = writable;
667 /* Open the file. */
668 mach_o_file->fd = open (fname,
669 O_BINARY | (writable ? O_WRONLY | O_CREAT | O_TRUNC : O_RDONLY), 0666);
671 if (mach_o_file->fd == -1)
673 error ("could not open file %s", fname);
674 goto fail;
677 if (stat (fname, &statbuf) < 0)
679 error ("could not stat file %s", fname);
680 goto fail;
683 mach_o_file->file_size = statbuf.st_size;
685 /* If the object is in an archive, get it out. */
686 if (offset != 0)
688 char ar_tail[12];
689 int size;
691 /* Surely not? */
692 gcc_assert (!writable);
694 /* Seek to offset, or error. */
695 if (lseek (mach_o_file->fd, offset, SEEK_SET) != (ssize_t) offset)
697 error ("could not find archive member @0x%lx", (long) offset);
698 goto fail;
701 /* Now seek back 12 chars and read the tail of the AR header to
702 find the length of the member file. */
703 if (lseek (mach_o_file->fd, -12, SEEK_CUR) < 0
704 || read (mach_o_file->fd, ar_tail, 12) != 12
705 || lseek (mach_o_file->fd, 0, SEEK_CUR) != (ssize_t) offset
706 || ar_tail[10] != '`' || ar_tail[11] != '\n')
708 error ("could not find archive header @0x%lx", (long) offset);
709 goto fail;
712 ar_tail[11] = 0;
713 if (sscanf (ar_tail, "%d", &size) != 1)
715 error ("invalid archive header @0x%lx", (long) offset);
716 goto fail;
718 mach_o_file->file_size = size;
721 if (writable)
723 init_mach_o_header (mach_o_file);
725 else
726 if (! validate_file (mach_o_file))
727 goto fail;
729 return result;
731 fail:
732 if (result)
733 lto_obj_file_close (result);
734 return NULL;
738 /* Write the data in MACH_O_FILE to a real Mach-O binary object.
739 We write a header, a segment load command, and section data. */
741 static bool
742 mach_o_write_object_file (lto_mach_o_file *mach_o_file)
744 lto_mach_o_section sec, snsec;
745 lto_mach_o_data snsec_data;
746 ssize_t hdrsize, cmdsize, secsize;
747 size_t num_sections, snsec_size, total_sec_size;
748 unsigned int sec_offs, strtab_offs;
749 int i;
750 bool write_err = false;
752 /* The number of sections we will write is the number of sections added by
753 the streamer, plus 1 for the section names section. */
754 num_sections = VEC_length (lto_mach_o_section, mach_o_file->section_vec) + 1;
756 /* Calculate the size of the basic data structures on disk. */
757 if (mach_o_word_size () == 64)
759 hdrsize = sizeof (mach_o_header_64);
760 secsize = sizeof (mach_o_section_64);
761 cmdsize = sizeof (mach_o_segment_command_64) + num_sections * secsize;
763 else
765 hdrsize = sizeof (mach_o_header_32);
766 secsize = sizeof (mach_o_section_32);
767 cmdsize = sizeof (mach_o_segment_command_32) + num_sections * secsize;
770 /* Allocate the section names section. */
771 snsec_size = 0;
772 for (i = 0;
773 VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
774 i++)
775 snsec_size += strlen (sec->name) + 1;
776 snsec = mach_o_new_section (mach_o_file, NULL);
777 snsec->name = LTO_NAMES_SECTION;
778 snsec_data = mach_o_new_data (snsec);
779 snsec_data->d_buf = XCNEWVEC (char, snsec_size);
780 snsec_data->d_size = snsec_size;
782 /* Position all the sections, and fill out their headers. */
783 sec_offs = hdrsize + cmdsize;
784 strtab_offs = 0;
785 total_sec_size = 0;
786 for (i = 0;
787 VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
788 i++)
790 lto_mach_o_data data;
791 size_t data_size;
792 /* Put the section and segment names. Add the section name to the
793 section names section (unless, of course, this *is* the section
794 names section). */
795 if (sec == snsec)
796 snprintf (sec->u.section.sectname, 16, "%s", LTO_NAMES_SECTION);
797 else
799 sprintf (sec->u.section.sectname, "__%08X", strtab_offs);
800 memcpy ((char *) snsec_data->d_buf + strtab_offs, sec->name, strlen (sec->name));
802 memcpy (&sec->u.section.segname[0],
803 LTO_SEGMENT_NAME, strlen (LTO_SEGMENT_NAME));
805 /* Add layout and attributes. */
806 for (data = sec->data_chain, data_size = 0; data; data = data->next)
807 data_size += data->d_size;
808 if (mach_o_word_size () == 64)
810 put_uint64 (&sec->u.section_64.addr[0], total_sec_size);
811 put_uint64 (&sec->u.section_64.size[0], data_size);
812 put_uint32 (&sec->u.section_64.offset[0], sec_offs);
813 put_uint32 (&sec->u.section_64.flags[0], MACH_O_S_ATTR_DEBUG);
815 else
817 put_uint32 (&sec->u.section_64.addr[0], total_sec_size);
818 put_uint32 (&sec->u.section_32.size[0], data_size);
819 put_uint32 (&sec->u.section_32.offset[0], sec_offs);
820 put_uint32 (&sec->u.section_32.flags[0], MACH_O_S_ATTR_DEBUG);
823 sec_offs += data_size;
824 total_sec_size += data_size;
825 strtab_offs += strlen (sec->name) + 1;
828 /* We can write the data now. As there's no way to indicate an error return
829 from this hook, error handling is limited to not wasting our time doing
830 any more writes in the event that any one fails. */
832 /* Write the header. */
833 put_uint32 (&mach_o_file->u.header.ncmds[0], 1);
834 put_uint32 (&mach_o_file->u.header.sizeofcmds[0], cmdsize);
835 write_err = (write (mach_o_file->fd,
836 &mach_o_file->u.header, hdrsize) != hdrsize);
837 /* Write the segment load command. */
838 if (mach_o_word_size () == 64)
840 mach_o_segment_command_64 lc;
841 ssize_t lc_size = sizeof (lc);
842 memset (&lc, 0, lc_size);
843 put_uint32 (&lc.cmd[0], MACH_O_LC_SEGMENT_64);
844 put_uint32 (&lc.cmdsize[0], cmdsize);
845 put_uint64 (&lc.fileoff[0], hdrsize + cmdsize);
846 put_uint64 (&lc.filesize[0], total_sec_size);
847 put_uint32 (&lc.nsects[0], num_sections);
848 write_err = (write (mach_o_file->fd, &lc, lc_size) != lc_size);
850 else
852 mach_o_segment_command_32 lc;
853 ssize_t lc_size = sizeof (lc);
854 memset (&lc, 0, lc_size);
855 put_uint32 (&lc.cmd[0], MACH_O_LC_SEGMENT);
856 put_uint32 (&lc.cmdsize[0], cmdsize);
857 put_uint32 (&lc.fileoff[0], hdrsize + cmdsize);
858 put_uint32 (&lc.filesize[0], total_sec_size);
859 put_uint32 (&lc.nsects[0], num_sections);
860 write_err = (write (mach_o_file->fd, &lc, lc_size) != lc_size);
862 for (i = 0;
863 !write_err
864 && VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
865 i++)
866 write_err = (write (mach_o_file->fd,
867 &sec->u.section, secsize) != secsize);
869 gcc_assert (lseek (mach_o_file->fd, 0, SEEK_CUR) == hdrsize + cmdsize);
871 /* Write the section data. */
872 for (i = 0;
873 !write_err
874 && VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
875 i++)
877 lto_mach_o_data data;
879 for (data = sec->data_chain; data; data = data->next)
881 if (!write_err)
882 write_err = (write (mach_o_file->fd, data->d_buf, data->d_size)
883 != data->d_size);
884 else
885 break;
889 return !write_err;
892 /* Close Mach-O file FILE and clean up any associated data structures. If FILE
893 was opened for writing, the file's Mach-O data is written at this time. Any
894 cached data buffers are freed. */
896 void
897 lto_obj_file_close (lto_file *file)
899 lto_mach_o_file *mach_o_file = (lto_mach_o_file *) file;
900 struct lto_char_ptr_base *cur, *tmp;
901 lto_mach_o_section sec;
902 bool write_err = false;
903 int i;
905 /* If this file is open for writing, write a Mach-O object file. */
906 if (mach_o_file->writable)
908 if (! mach_o_write_object_file (mach_o_file))
909 fatal_error ("cannot write Mach-O object file");
912 /* Close the file, we're done. */
913 if (mach_o_file->fd != -1)
914 close (mach_o_file->fd);
916 /* Free any data buffers. */
917 cur = mach_o_file->data;
918 while (cur)
920 tmp = cur;
921 cur = (struct lto_char_ptr_base *) cur->ptr;
922 free (tmp);
925 /* Free any sections and their data chains. */
926 for (i = 0;
927 VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
928 i++)
930 lto_mach_o_data curdata, nextdata;
931 curdata = sec->data_chain;
932 while (curdata)
934 nextdata = curdata->next;
935 free (curdata);
936 curdata = nextdata;
938 free (sec);
940 VEC_free (lto_mach_o_section, heap, mach_o_file->section_vec);
942 free (file);
944 /* If there was an error, mention it. */
945 if (write_err)
946 error ("I/O error writing Mach-O output file");