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
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"
28 #include "lto-streamer.h"
29 #include "lto/lto-endian.h"
30 #include "lto/lto-macho.h"
32 /* Rather than implementing a libmacho to match libelf, or attempting to
33 integrate libbfd into GCC, this file is a self-contained (and very
34 minimal) Mach-O format object file reader/writer. The generated files
35 will contain a Mach-O header, a number of Mach-O load commands an
36 section headers, the section data itself, and a trailing string table
39 /* This needs to be kept in sync with darwin.c. Better yet, lto-macho.c
40 and lto-macho.h should be moved to config/, and likewise for lto-coff.*
43 /* Segment name for LTO sections. */
44 #define LTO_SEGMENT_NAME "__GNU_LTO"
46 /* Section name for LTO section names section. */
47 #define LTO_NAMES_SECTION "__section_names"
49 /* Handle opening elf files on hosts, such as Windows, that may use
50 text file handling that will break binary access. */
55 /* Cached object file header. We use a header_64 for this, since all
56 the fields we need are in there, in the same position as header_32. */
57 mach_o_header_64 cached_mach_o_header
;
58 uint32_t cached_mach_o_magic
;
60 /* The current output file. */
61 static lto_file
*current_out_file
;
64 /* Is this a 32-bits or 64-bits Mach-O object file? */
66 mach_o_word_size (void)
68 gcc_assert (cached_mach_o_magic
!= 0);
69 return (cached_mach_o_magic
== MACH_O_MH_MAGIC_64
70 || cached_mach_o_magic
== MACH_O_MH_CIGAM_64
) ? 64 : 32;
73 /* Sets the current output file to FILE. Returns the old output file or
77 lto_set_current_out_file (lto_file
*file
)
79 lto_file
*old_file
= current_out_file
;
80 current_out_file
= file
;
85 /* Returns the current output file. */
88 lto_get_current_out_file (void)
90 return current_out_file
;
93 /* Mach-O section structure constructor. */
95 static lto_mach_o_section
96 mach_o_new_section (lto_mach_o_file
*mach_o_file
, const char *name
)
98 lto_mach_o_section ptr
;
100 /* FIXME We could allocate these things on an obstack. */
101 ptr
= XCNEW (struct lto_mach_o_section_d
);
104 if (strncmp (name
, LTO_SECTION_NAME_PREFIX
,
105 strlen(LTO_SECTION_NAME_PREFIX
)) != 0)
106 sorry ("not implemented: Mach-O writer for non-LTO sections");
107 ptr
->name
= xstrdup (name
);
110 VEC_safe_push (lto_mach_o_section
, heap
, mach_o_file
->section_vec
, ptr
);
115 /* Mach-O section data block structure constructor. */
117 static lto_mach_o_data
118 mach_o_new_data (lto_mach_o_section sec
)
120 lto_mach_o_data ptr
, *chain_ptr_ptr
;
122 /* FIXME We could allocate these things on an obstack. */
123 ptr
= XCNEW (struct lto_mach_o_data_d
);
125 chain_ptr_ptr
= &sec
->data_chain
;
126 while (*chain_ptr_ptr
)
127 chain_ptr_ptr
= &(*chain_ptr_ptr
)->next
;
128 *chain_ptr_ptr
= ptr
;
133 /* Initialize FILE, an LTO file object for FILENAME. Offset is the
134 offset into FILE where the object is located (e.g. in an archive). */
137 lto_file_init (lto_file
*file
, const char *filename
, off_t offset
)
139 file
->filename
= filename
;
140 file
->offset
= offset
;
143 /* Returns a hash code for P. */
146 hash_name (const void *p
)
148 const struct lto_section_slot
*s
= (const struct lto_section_slot
*) p
;
149 return (hashval_t
) htab_hash_string (s
->name
);
152 /* Returns nonzero if P1 and P2 are equal. */
155 eq_name (const void *p1
, const void *p2
)
157 const struct lto_section_slot
*s1
=
158 (const struct lto_section_slot
*) p1
;
159 const struct lto_section_slot
*s2
=
160 (const struct lto_section_slot
*) p2
;
162 return strcmp (s1
->name
, s2
->name
) == 0;
165 /* Build a hash table whose key is the section names and whose data is
166 the start and size of each section in the .o file. */
169 lto_obj_build_section_table (lto_file
*lto_file
)
171 lto_mach_o_file
*mach_o_file
= (lto_mach_o_file
*)lto_file
;
172 lto_mach_o_section sec
;
173 htab_t section_hash_table
;
179 section_hash_table
= htab_create (37, hash_name
, eq_name
, free
);
181 /* Seek the string table. */
182 /* FIXME The segment name should be in darwin.h, but can we include it
183 here in this file? */
185 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
188 if (strncmp (sec
->u
.section
.segname
, "__GNU_LTO", 16) != 0)
190 if (strncmp (sec
->u
.section
.sectname
, "__section_names", 16) == 0)
195 error ("invalid Mach-O LTO object file: no __section_names section found");
198 mach_o_file
->section_names_section
= sec
;
200 if (mach_o_word_size () == 64)
202 strtab_offs
= (off_t
) get_uint32 (&sec
->u
.section_64
.offset
[0]);
203 strtab_size
= (size_t) get_uint64 (&sec
->u
.section_64
.size
[0]);
207 strtab_offs
= (off_t
) get_uint32 (&sec
->u
.section_32
.offset
[0]);
208 strtab_size
= (size_t) get_uint32 (&sec
->u
.section_32
.size
[0]);
211 /* Seek to start of string table. */
212 if (strtab_offs
!= lseek (mach_o_file
->fd
,
213 mach_o_file
->base
.offset
+ strtab_offs
,
216 error ("altered or invalid Mach-O object file");
220 strtab
= XNEWVEC (char, strtab_size
);
221 if (read (mach_o_file
->fd
, strtab
, strtab_size
) != strtab_size
)
223 error ("invalid Mach-O LTO object file __section_names section");
227 /* Scan sections looking at names. */
229 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
232 struct lto_section_slot s_slot
;
235 unsigned long stringoffset
;
238 /* Ignore non-LTO sections. Also ignore the __section_names section
239 which does not need renaming. */
240 if (strncmp (sec
->u
.section
.segname
, "__GNU_LTO", 16) != 0)
242 if (sec
== mach_o_file
->section_names_section
)
245 /* Try to extract the offset of the real name for this section from
247 memcpy (&name
[0], sec
->u
.section
.sectname
, 16);
249 if (name
[0] != '_' || name
[1] != '_'
250 || sscanf (&name
[2], "%08lX", &stringoffset
) != 1
251 || strtab_size
< (ssize_t
) stringoffset
)
253 error ("invalid Mach-O LTO section name string: %s", name
);
257 new_name
= XNEWVEC (char, strlen (strtab
+ stringoffset
) + 1);
258 strcpy (new_name
, strtab
+ stringoffset
);
259 s_slot
.name
= new_name
;
260 slot
= htab_find_slot (section_hash_table
, &s_slot
, INSERT
);
263 struct lto_section_slot
*new_slot
= XNEW (struct lto_section_slot
);
265 new_slot
->name
= new_name
;
266 if (mach_o_word_size() == 64)
269 (intptr_t) get_uint32 (&sec
->u
.section_64
.offset
[0]);
271 (size_t) get_uint64 (&sec
->u
.section_64
.size
[0]);
276 (intptr_t) get_uint32 (&sec
->u
.section_32
.offset
[0]);
278 (size_t) get_uint32 (&sec
->u
.section_32
.size
[0]);
285 error ("two or more sections for %s:", new_name
);
293 return section_hash_table
;
297 /* Begin a new Mach-O section named NAME in the current output file. */
300 lto_obj_begin_section (const char *name
)
302 lto_mach_o_file
*file
;
304 if (strncmp (name
, LTO_SECTION_NAME_PREFIX
,
305 strlen(LTO_SECTION_NAME_PREFIX
)) != 0)
306 sorry ("not implemented: Mach-O writer for non-LTO sections");
308 /* Grab the current output file and do some basic assertion checking. */
309 file
= (lto_mach_o_file
*) lto_get_current_out_file (),
310 gcc_assert (file
&& file
->writable
&& !file
->scn
);
312 /* Create a new section. */
313 file
->scn
= mach_o_new_section (file
, name
);
315 fatal_error ("could not create a new Mach-O section: %m");
319 /* Append DATA of length LEN to the current output section. BASE is a pointer
320 to the output page containing DATA. It is freed once the output file has
324 lto_obj_append_data (const void *data
, size_t len
, void *block
)
326 lto_mach_o_file
*file
;
327 lto_mach_o_data mach_o_data
;
328 struct lto_char_ptr_base
*base
= (struct lto_char_ptr_base
*) block
;
330 /* Grab the current output file and do some basic assertion checking. */
331 file
= (lto_mach_o_file
*) lto_get_current_out_file ();
333 gcc_assert (file
->scn
);
335 mach_o_data
= mach_o_new_data (file
->scn
);
337 fatal_error ("could not append data to Mach-O section: %m");
339 mach_o_data
->d_buf
= CONST_CAST (void *, data
);
340 mach_o_data
->d_size
= len
;
342 /* Chain all data blocks (from all sections) on one singly-linked
343 list for freeing en masse after the file is closed. */
344 base
->ptr
= (char *)file
->data
;
349 /* End the current output section. This just does some assertion checking
350 and sets the current output file's scn member to NULL. */
353 lto_obj_end_section (void)
355 lto_mach_o_file
*file
;
357 /* Grab the current output file and validate some basic assertions. */
358 file
= (lto_mach_o_file
*) lto_get_current_out_file ();
360 gcc_assert (file
->scn
);
366 /* Read a Mach-O header from MACH_O_FILE and validate it.
367 The file descriptor in MACH_O_FILE points at the start of the file.
368 If cached_mach_o_header is uninitialized, caches the results.
369 On succes, returns true and moves file pointer to the start of the
370 load commands. On failure, returns false. */
373 validate_mach_o_header (lto_mach_o_file
*mach_o_file
)
376 unsigned char magic
[4];
380 /* Known header magics for validation, as an array. */
381 static const unsigned int mach_o_known_formats
[] = {
387 #define MACH_O_NUM_KNOWN_FORMATS \
388 ((ssize_t) ARRAY_SIZE (mach_o_known_formats))
390 startpos
= lseek (mach_o_file
->fd
, 0, SEEK_CUR
);
391 if (read (mach_o_file
->fd
, &magic
, sizeof (magic
)) != 4
392 || lseek (mach_o_file
->fd
, -4, SEEK_CUR
) != startpos
)
394 error ("cannot read file %s", mach_o_file
->base
.filename
);
398 for (i
= 0; i
< MACH_O_NUM_KNOWN_FORMATS
; ++i
)
399 if (get_uint32 (&magic
[0]) == mach_o_known_formats
[i
])
401 if (i
== MACH_O_NUM_KNOWN_FORMATS
)
404 /* Check the endian-ness. */
405 if (BYTES_BIG_ENDIAN
&& magic
[0] != 0xfe)
408 /* Set or check cached magic number. */
409 if (cached_mach_o_magic
== 0)
410 cached_mach_o_magic
= get_uint32 (&magic
[0]);
411 else if (cached_mach_o_magic
!= get_uint32 (&magic
[0]))
414 n
= mach_o_word_size () == 64
415 ? sizeof (mach_o_header_64
) : sizeof (mach_o_header_32
);
416 if (read (mach_o_file
->fd
, &mach_o_file
->u
.header
, n
) != n
)
419 /* Is this a supported CPU? */
420 /* ??? Would be nice to validate the exact target architecture. */
421 cputype
= get_uint32 (&mach_o_file
->u
.header
.cputype
[0]);
422 if (cputype
== MACH_O_CPU_TYPE_I386
423 || cputype
== MACH_O_CPU_TYPE_POWERPC
)
425 if (mach_o_word_size () != 32)
428 else if (cputype
== MACH_O_CPU_TYPE_X86_64
429 || cputype
== MACH_O_CPU_TYPE_POWERPC_64
)
431 if (mach_o_word_size () != 64)
435 /* Is this an MH_OBJECT file? */
436 if (get_uint32 (&mach_o_file
->u
.header
.filetype
[0]) != MACH_O_MH_OBJECT
)
437 error ("Mach-O file %s is not an MH_OBJECT file",
438 mach_o_file
->base
.filename
);
440 /* Save the header for future use. */
441 memcpy (&cached_mach_o_header
, &mach_o_file
->u
.header
,
442 sizeof (cached_mach_o_header
));
447 error ("file %s is not a Mach-O object file for target",
448 mach_o_file
->base
.filename
);
453 /* Read a Mach-O LC_SEGMENT command (32 bits) from MACH_O_FILE and
455 The file descriptor in MACH_O_FILE points at the start of the load
456 command. On sucess, returns true and advances the file pointer
457 past the end of the load command. On failure, returns false. */
460 validate_mach_o_segment_command_32 (lto_mach_o_file
*mach_o_file
)
462 mach_o_segment_command_32 seg_cmd_32
;
467 /* Fields we're interested in. */
472 startpos
= lseek (mach_o_file
->fd
, 0, SEEK_CUR
);
474 n
= sizeof (mach_o_segment_command_32
);
475 if (read (mach_o_file
->fd
, (void *) &seg_cmd_32
, n
) != n
)
478 cmd
= get_uint32 (&seg_cmd_32
.cmd
[0]);
479 cmdsize
= get_uint32 (&seg_cmd_32
.cmdsize
[0]);
480 nsects
= get_uint32 (&seg_cmd_32
.nsects
[0]);
481 gcc_assert (cmd
== MACH_O_LC_SEGMENT
);
483 /* Validate section table entries. */
484 for (i
= 0; i
< nsects
; i
++)
486 mach_o_section_32 sec_32
;
487 lto_mach_o_section ltosec
;
489 n
= sizeof (mach_o_section_32
);
490 if (read (mach_o_file
->fd
, &sec_32
, n
) != n
)
493 /* ??? Perform some checks. */
495 /* Looks ok, so record its details. We don't read the
496 string table or set up names yet; we'll do that when
497 we build the hash table. */
498 ltosec
= mach_o_new_section (mach_o_file
, NULL
);
499 memcpy (<osec
->u
.section_32
, &sec_32
, sizeof (sec_32
));
502 if (lseek (mach_o_file
->fd
, 0, SEEK_CUR
) != startpos
+ cmdsize
)
508 error ("could not read LC_SEGMENT command in Mach-O file %s",
509 mach_o_file
->base
.filename
);
514 /* Read a Mach-O LC_SEGMENT_64 command from MACH_O_FILE and validate it.
515 The file descriptor in MACH_O_FILE points at the start of the load
516 command. On sucess, returns true and advances the file pointer
517 past the end of the load command. On failure, returns false. */
520 validate_mach_o_segment_command_64 (lto_mach_o_file
*mach_o_file
)
522 mach_o_segment_command_64 seg_cmd_64
;
527 /* Fields we're interested in. */
532 startpos
= lseek (mach_o_file
->fd
, 0, SEEK_CUR
);
534 n
= sizeof (mach_o_segment_command_64
);
535 if (read (mach_o_file
->fd
, (void *) &seg_cmd_64
, n
) != n
)
538 cmd
= get_uint32 (&seg_cmd_64
.cmd
[0]);
539 cmdsize
= get_uint32 (&seg_cmd_64
.cmdsize
[0]);
540 nsects
= get_uint32 (&seg_cmd_64
.nsects
[0]);
541 gcc_assert (cmd
== MACH_O_LC_SEGMENT_64
);
543 /* Validate section table entries. */
544 for (i
= 0; i
< nsects
; i
++)
546 mach_o_section_64 sec_64
;
547 lto_mach_o_section ltosec
;
549 n
= sizeof (mach_o_section_64
);
550 if (read (mach_o_file
->fd
, &sec_64
, n
) != n
)
553 /* ??? Perform some checks. */
555 /* Looks ok, so record its details. We don't read the
556 string table or set up names yet; we'll do that when
557 we build the hash table. */
558 ltosec
= mach_o_new_section (mach_o_file
, NULL
);
559 memcpy (<osec
->u
.section_64
, &sec_64
, sizeof (sec_64
));
562 if (lseek (mach_o_file
->fd
, 0, SEEK_CUR
) != startpos
+ cmdsize
)
568 error ("could not read LC_SEGMENT_64 command in Mach-O file %s",
569 mach_o_file
->base
.filename
);
573 /* Read a Mach-O load commands from MACH_O_FILE and validate it.
574 The file descriptor in MACH_O_FILE points at the start of the load
575 command. On sucess, returns true and advances the file pointer
576 past the end of the load command. On failure, returns false. */
579 validate_mach_o_load_command (lto_mach_o_file
*mach_o_file
)
581 mach_o_load_command load_command
;
586 n
= sizeof (load_command
);
587 if (read (mach_o_file
->fd
, &load_command
, n
) != n
)
589 error ("could not read load commands in Mach-O file %s",
590 mach_o_file
->base
.filename
);
593 lseek (mach_o_file
->fd
, -1 * (off_t
) sizeof (load_command
), SEEK_CUR
);
595 cmd
= get_uint32 (&load_command
.cmd
[0]);
596 cmdsize
= get_uint32 (&load_command
.cmdsize
[0]);
599 case MACH_O_LC_SEGMENT
:
600 return validate_mach_o_segment_command_32 (mach_o_file
);
601 case MACH_O_LC_SEGMENT_64
:
602 return validate_mach_o_segment_command_64 (mach_o_file
);
605 /* Just skip over it. */
606 lseek (mach_o_file
->fd
, cmdsize
, SEEK_CUR
);
611 /* Validate's MACH_O_FILE's executable header and, if cached_mach_o_header is
612 uninitialized, caches the results. Also records the section header string
613 table's section index. Returns true on success, false on failure. */
616 validate_file (lto_mach_o_file
*mach_o_file
)
620 /* Read and sanity check the raw header. */
621 if (! validate_mach_o_header (mach_o_file
))
624 ncmds
= get_uint32 (&mach_o_file
->u
.header
.ncmds
[0]);
625 for (i
= 0; i
< ncmds
; ++i
)
626 if (! validate_mach_o_load_command (mach_o_file
))
632 /* Initialize MACH_O_FILE's executable header using cached data from previously
636 init_mach_o_header (lto_mach_o_file
*mach_o_file
)
638 gcc_assert (cached_mach_o_magic
!= 0);
639 memcpy (&mach_o_file
->u
.header
,
640 &cached_mach_o_header
,
641 sizeof (mach_o_file
->u
.header
));
642 put_uint32 (&mach_o_file
->u
.header
.ncmds
[0], 0);
643 put_uint32 (&mach_o_file
->u
.header
.sizeofcmds
[0], 0);
646 /* Open Mach-O file FILENAME. If WRITABLE is true, the file is opened for write
647 and, if necessary, created. Otherwise, the file is opened for reading.
648 Returns the opened file. */
651 lto_obj_file_open (const char *filename
, bool writable
)
653 lto_mach_o_file
*mach_o_file
;
654 lto_file
*result
= NULL
;
656 const char *offset_p
;
660 offset_p
= strchr (filename
, '@');
663 fname
= xstrdup (filename
);
668 /* The file started with '@' is a file containing command line
669 options. Stop if it doesn't exist. */
670 if (offset_p
== filename
)
671 fatal_error ("command line option file '%s' does not exist",
674 fname
= (char *) xmalloc (offset_p
- filename
+ 1);
675 memcpy (fname
, filename
, offset_p
- filename
);
676 fname
[offset_p
- filename
] = '\0';
677 offset_p
+= 3; /* skip the @0x */
678 offset
= lto_parse_hex (offset_p
);
682 mach_o_file
= XCNEW (lto_mach_o_file
);
683 result
= (lto_file
*) mach_o_file
;
684 lto_file_init (result
, fname
, offset
);
685 mach_o_file
->fd
= -1;
686 mach_o_file
->writable
= writable
;
689 mach_o_file
->fd
= open (fname
,
690 O_BINARY
| (writable
? O_WRONLY
| O_CREAT
| O_TRUNC
: O_RDONLY
), 0666);
692 if (mach_o_file
->fd
== -1)
694 error ("could not open file %s", fname
);
698 if (stat (fname
, &statbuf
) < 0)
700 error ("could not stat file %s", fname
);
704 mach_o_file
->file_size
= statbuf
.st_size
;
706 /* If the object is in an archive, get it out. */
713 gcc_assert (!writable
);
715 /* Seek to offset, or error. */
716 if (lseek (mach_o_file
->fd
, offset
, SEEK_SET
) != (ssize_t
) offset
)
718 error ("could not find archive member @0x%lx", (long) offset
);
722 /* Now seek back 12 chars and read the tail of the AR header to
723 find the length of the member file. */
724 if (lseek (mach_o_file
->fd
, -12, SEEK_CUR
) < 0
725 || read (mach_o_file
->fd
, ar_tail
, 12) != 12
726 || lseek (mach_o_file
->fd
, 0, SEEK_CUR
) != (ssize_t
) offset
727 || ar_tail
[10] != '`' || ar_tail
[11] != '\n')
729 error ("could not find archive header @0x%lx", (long) offset
);
734 if (sscanf (ar_tail
, "%d", &size
) != 1)
736 error ("invalid archive header @0x%lx", (long) offset
);
739 mach_o_file
->file_size
= size
;
744 init_mach_o_header (mach_o_file
);
747 if (! validate_file (mach_o_file
))
754 lto_obj_file_close (result
);
759 /* Write the data in MACH_O_FILE to a real Mach-O binary object.
760 We write a header, a segment load command, and section data. */
763 mach_o_write_object_file (lto_mach_o_file
*mach_o_file
)
765 lto_mach_o_section sec
, snsec
;
766 lto_mach_o_data snsec_data
;
767 ssize_t hdrsize
, cmdsize
, secsize
;
768 size_t num_sections
, snsec_size
, total_sec_size
;
769 unsigned int sec_offs
, strtab_offs
;
771 bool write_err
= false;
773 /* The number of sections we will write is the number of sections added by
774 the streamer, plus 1 for the section names section. */
775 num_sections
= VEC_length (lto_mach_o_section
, mach_o_file
->section_vec
) + 1;
777 /* Calculate the size of the basic data structures on disk. */
778 if (mach_o_word_size () == 64)
780 hdrsize
= sizeof (mach_o_header_64
);
781 secsize
= sizeof (mach_o_section_64
);
782 cmdsize
= sizeof (mach_o_segment_command_64
) + num_sections
* secsize
;
786 hdrsize
= sizeof (mach_o_header_32
);
787 secsize
= sizeof (mach_o_section_32
);
788 cmdsize
= sizeof (mach_o_segment_command_32
) + num_sections
* secsize
;
791 /* Allocate the section names section. */
794 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
796 snsec_size
+= strlen (sec
->name
) + 1;
797 snsec
= mach_o_new_section (mach_o_file
, NULL
);
798 snsec
->name
= LTO_NAMES_SECTION
;
799 snsec_data
= mach_o_new_data (snsec
);
800 snsec_data
->d_buf
= XCNEWVEC (char, snsec_size
);
801 snsec_data
->d_size
= snsec_size
;
803 /* Position all the sections, and fill out their headers. */
804 sec_offs
= hdrsize
+ cmdsize
;
808 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
811 lto_mach_o_data data
;
813 /* Put the section and segment names. Add the section name to the
814 section names section (unless, of course, this *is* the section
817 snprintf (sec
->u
.section
.sectname
, 16, "%s", LTO_NAMES_SECTION
);
820 sprintf (sec
->u
.section
.sectname
, "__%08X", strtab_offs
);
821 memcpy ((char *) snsec_data
->d_buf
+ strtab_offs
, sec
->name
, strlen (sec
->name
));
823 memcpy (&sec
->u
.section
.segname
[0],
824 LTO_SEGMENT_NAME
, strlen (LTO_SEGMENT_NAME
));
826 /* Add layout and attributes. */
827 for (data
= sec
->data_chain
, data_size
= 0; data
; data
= data
->next
)
828 data_size
+= data
->d_size
;
829 if (mach_o_word_size () == 64)
831 put_uint64 (&sec
->u
.section_64
.addr
[0], total_sec_size
);
832 put_uint64 (&sec
->u
.section_64
.size
[0], data_size
);
833 put_uint32 (&sec
->u
.section_64
.offset
[0], sec_offs
);
834 put_uint32 (&sec
->u
.section_64
.flags
[0], MACH_O_S_ATTR_DEBUG
);
838 put_uint32 (&sec
->u
.section_64
.addr
[0], total_sec_size
);
839 put_uint32 (&sec
->u
.section_32
.size
[0], data_size
);
840 put_uint32 (&sec
->u
.section_32
.offset
[0], sec_offs
);
841 put_uint32 (&sec
->u
.section_32
.flags
[0], MACH_O_S_ATTR_DEBUG
);
844 sec_offs
+= data_size
;
845 total_sec_size
+= data_size
;
846 strtab_offs
+= strlen (sec
->name
) + 1;
849 /* We can write the data now. As there's no way to indicate an error return
850 from this hook, error handling is limited to not wasting our time doing
851 any more writes in the event that any one fails. */
853 /* Write the header. */
854 put_uint32 (&mach_o_file
->u
.header
.ncmds
[0], 1);
855 put_uint32 (&mach_o_file
->u
.header
.sizeofcmds
[0], cmdsize
);
856 write_err
= (write (mach_o_file
->fd
,
857 &mach_o_file
->u
.header
, hdrsize
) != hdrsize
);
858 /* Write the segment load command. */
859 if (mach_o_word_size () == 64)
861 mach_o_segment_command_64 lc
;
862 ssize_t lc_size
= sizeof (lc
);
863 memset (&lc
, 0, lc_size
);
864 put_uint32 (&lc
.cmd
[0], MACH_O_LC_SEGMENT_64
);
865 put_uint32 (&lc
.cmdsize
[0], cmdsize
);
866 put_uint64 (&lc
.fileoff
[0], hdrsize
+ cmdsize
);
867 put_uint64 (&lc
.filesize
[0], total_sec_size
);
868 put_uint32 (&lc
.nsects
[0], num_sections
);
869 write_err
= (write (mach_o_file
->fd
, &lc
, lc_size
) != lc_size
);
873 mach_o_segment_command_32 lc
;
874 ssize_t lc_size
= sizeof (lc
);
875 memset (&lc
, 0, lc_size
);
876 put_uint32 (&lc
.cmd
[0], MACH_O_LC_SEGMENT
);
877 put_uint32 (&lc
.cmdsize
[0], cmdsize
);
878 put_uint32 (&lc
.fileoff
[0], hdrsize
+ cmdsize
);
879 put_uint32 (&lc
.filesize
[0], total_sec_size
);
880 put_uint32 (&lc
.nsects
[0], num_sections
);
881 write_err
= (write (mach_o_file
->fd
, &lc
, lc_size
) != lc_size
);
885 && VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
887 write_err
= (write (mach_o_file
->fd
,
888 &sec
->u
.section
, secsize
) != secsize
);
890 gcc_assert (lseek (mach_o_file
->fd
, 0, SEEK_CUR
) == hdrsize
+ cmdsize
);
892 /* Write the section data. */
895 && VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
898 lto_mach_o_data data
;
900 for (data
= sec
->data_chain
; data
; data
= data
->next
)
903 write_err
= (write (mach_o_file
->fd
, data
->d_buf
, data
->d_size
)
913 /* Close Mach-O file FILE and clean up any associated data structures. If FILE
914 was opened for writing, the file's Mach-O data is written at this time. Any
915 cached data buffers are freed. */
918 lto_obj_file_close (lto_file
*file
)
920 lto_mach_o_file
*mach_o_file
= (lto_mach_o_file
*) file
;
921 struct lto_char_ptr_base
*cur
, *tmp
;
922 lto_mach_o_section sec
;
923 bool write_err
= false;
926 /* If this file is open for writing, write a Mach-O object file. */
927 if (mach_o_file
->writable
)
929 if (! mach_o_write_object_file (mach_o_file
))
930 fatal_error ("cannot write Mach-O object file");
933 /* Close the file, we're done. */
934 if (mach_o_file
->fd
!= -1)
935 close (mach_o_file
->fd
);
937 /* Free any data buffers. */
938 cur
= mach_o_file
->data
;
942 cur
= (struct lto_char_ptr_base
*) cur
->ptr
;
946 /* Free any sections and their data chains. */
948 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
951 lto_mach_o_data curdata
, nextdata
;
952 curdata
= sec
->data_chain
;
955 nextdata
= curdata
->next
;
961 VEC_free (lto_mach_o_section
, heap
, mach_o_file
->section_vec
);
965 /* If there was an error, mention it. */
967 error ("I/O error writing Mach-O output file");