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"
24 #include "diagnostic-core.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
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.*
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. */
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? */
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
78 lto_set_current_out_file (lto_file
*file
)
80 lto_file
*old_file
= current_out_file
;
81 current_out_file
= file
;
86 /* Returns the current output 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
);
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
);
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
;
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). */
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. */
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
;
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? */
164 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
167 if (strncmp (sec
->u
.section
.segname
, "__GNU_LTO", 16) != 0)
169 if (strncmp (sec
->u
.section
.sectname
, "__section_names", 16) == 0)
174 error ("invalid Mach-O LTO object file: no __section_names section found");
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]);
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
,
195 error ("altered or invalid Mach-O object file");
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");
206 /* Scan sections looking at names. */
208 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
211 struct lto_section_slot s_slot
;
214 unsigned long stringoffset
;
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)
221 if (sec
== mach_o_file
->section_names_section
)
224 /* Try to extract the offset of the real name for this section from
226 memcpy (&name
[0], sec
->u
.section
.sectname
, 16);
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
);
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
);
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)
248 (intptr_t) get_uint32 (&sec
->u
.section_64
.offset
[0]);
250 (size_t) get_uint64 (&sec
->u
.section_64
.size
[0]);
255 (intptr_t) get_uint32 (&sec
->u
.section_32
.offset
[0]);
257 (size_t) get_uint32 (&sec
->u
.section_32
.size
[0]);
264 error ("two or more sections for %s:", new_name
);
272 return section_hash_table
;
276 /* Begin a new Mach-O section named NAME in the current output file. */
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
);
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
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 ();
312 gcc_assert (file
->scn
);
314 mach_o_data
= mach_o_new_data (file
->scn
);
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
;
328 /* End the current output section. This just does some assertion checking
329 and sets the current output file's scn member to NULL. */
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 ();
339 gcc_assert (file
->scn
);
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. */
352 validate_mach_o_header (lto_mach_o_file
*mach_o_file
)
355 unsigned char magic
[4];
359 /* Known header magics for validation, as an array. */
360 static const unsigned int mach_o_known_formats
[] = {
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
);
377 for (i
= 0; i
< MACH_O_NUM_KNOWN_FORMATS
; ++i
)
378 if (get_uint32 (&magic
[0]) == mach_o_known_formats
[i
])
380 if (i
== MACH_O_NUM_KNOWN_FORMATS
)
383 /* Check the endian-ness. */
384 if (BYTES_BIG_ENDIAN
&& magic
[0] != 0xfe)
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]))
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
)
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)
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)
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
));
426 error ("file %s is not a Mach-O object file for target",
427 mach_o_file
->base
.filename
);
432 /* Read a Mach-O LC_SEGMENT command (32 bits) from MACH_O_FILE and
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. */
439 validate_mach_o_segment_command_32 (lto_mach_o_file
*mach_o_file
)
441 mach_o_segment_command_32 seg_cmd_32
;
446 /* Fields we're interested in. */
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
)
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
)
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 (<osec
->u
.section_32
, &sec_32
, sizeof (sec_32
));
481 if (lseek (mach_o_file
->fd
, 0, SEEK_CUR
) != startpos
+ cmdsize
)
487 error ("could not read LC_SEGMENT command in Mach-O file %s",
488 mach_o_file
->base
.filename
);
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. */
499 validate_mach_o_segment_command_64 (lto_mach_o_file
*mach_o_file
)
501 mach_o_segment_command_64 seg_cmd_64
;
506 /* Fields we're interested in. */
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
)
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
)
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 (<osec
->u
.section_64
, &sec_64
, sizeof (sec_64
));
541 if (lseek (mach_o_file
->fd
, 0, SEEK_CUR
) != startpos
+ cmdsize
)
547 error ("could not read LC_SEGMENT_64 command in Mach-O file %s",
548 mach_o_file
->base
.filename
);
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. */
558 validate_mach_o_load_command (lto_mach_o_file
*mach_o_file
)
560 mach_o_load_command load_command
;
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
);
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]);
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
);
584 /* Just skip over it. */
585 lseek (mach_o_file
->fd
, cmdsize
, SEEK_CUR
);
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. */
595 validate_file (lto_mach_o_file
*mach_o_file
)
599 /* Read and sanity check the raw header. */
600 if (! validate_mach_o_header (mach_o_file
))
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
))
611 /* Initialize MACH_O_FILE's executable header using cached data from previously
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. */
630 lto_obj_file_open (const char *filename
, bool writable
)
632 lto_mach_o_file
*mach_o_file
;
633 lto_file
*result
= NULL
;
635 const char *offset_p
;
639 offset_p
= strchr (filename
, '@');
642 fname
= xstrdup (filename
);
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",
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
);
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
;
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
);
677 if (stat (fname
, &statbuf
) < 0)
679 error ("could not stat file %s", fname
);
683 mach_o_file
->file_size
= statbuf
.st_size
;
685 /* If the object is in an archive, get it out. */
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
);
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
);
713 if (sscanf (ar_tail
, "%d", &size
) != 1)
715 error ("invalid archive header @0x%lx", (long) offset
);
718 mach_o_file
->file_size
= size
;
723 init_mach_o_header (mach_o_file
);
726 if (! validate_file (mach_o_file
))
733 lto_obj_file_close (result
);
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. */
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
;
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
;
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. */
773 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
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
;
787 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
790 lto_mach_o_data data
;
792 /* Put the section and segment names. Add the section name to the
793 section names section (unless, of course, this *is* the section
796 snprintf (sec
->u
.section
.sectname
, 16, "%s", LTO_NAMES_SECTION
);
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
);
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
);
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
);
864 && VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
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. */
874 && VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
877 lto_mach_o_data data
;
879 for (data
= sec
->data_chain
; data
; data
= data
->next
)
882 write_err
= (write (mach_o_file
->fd
, data
->d_buf
, data
->d_size
)
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. */
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;
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
;
921 cur
= (struct lto_char_ptr_base
*) cur
->ptr
;
925 /* Free any sections and their data chains. */
927 VEC_iterate (lto_mach_o_section
, mach_o_file
->section_vec
, i
, sec
);
930 lto_mach_o_data curdata
, nextdata
;
931 curdata
= sec
->data_chain
;
934 nextdata
= curdata
->next
;
940 VEC_free (lto_mach_o_section
, heap
, mach_o_file
->section_vec
);
944 /* If there was an error, mention it. */
946 error ("I/O error writing Mach-O output file");