OSDN Git Service

* lto.h (lto_elf_file_open): Rename prototype from this ...
[pf3gnuchains/gcc-fork.git] / gcc / lto / lto-macho.c
1 /* LTO routines for Mach-O object files.
2    Copyright 2010 Free Software Foundation, Inc.
3    Contributed by Steven Bosscher.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "toplev.h"
25 #include "lto.h"
26 #include "tm.h"
27 #include "libiberty.h"
28 #include "lto-streamer.h"
29 #include "lto/lto-endian.h"
30 #include "lto/lto-macho.h"
31
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
37    for section names.  */
38
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.*
41    and lto-elf.*.  */
42
43 /* Segment name for LTO sections.  */
44 #define LTO_SEGMENT_NAME "__GNU_LTO"
45
46 /* Section name for LTO section names section.  */
47 #define LTO_NAMES_SECTION "__section_names"
48
49 /* Handle opening elf files on hosts, such as Windows, that may use 
50    text file handling that will break binary access.  */
51 #ifndef O_BINARY
52 # define O_BINARY 0
53 #endif
54
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;
59
60 /* The current output file.  */
61 static lto_file *current_out_file;
62
63
64 /* Is this a 32-bits or 64-bits Mach-O object file?  */
65 static int
66 mach_o_word_size (void)
67 {
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;
71 }
72
73 /* Sets the current output file to FILE.  Returns the old output file or
74    NULL.  */
75
76 lto_file *
77 lto_set_current_out_file (lto_file *file)
78 {
79   lto_file *old_file = current_out_file;
80   current_out_file = file;
81   return old_file;
82 }
83
84
85 /* Returns the current output file.  */
86
87 lto_file *
88 lto_get_current_out_file (void)
89 {
90   return current_out_file;
91 }
92
93 /* Mach-O section structure constructor.  */
94
95 static lto_mach_o_section
96 mach_o_new_section (lto_mach_o_file *mach_o_file, const char *name)
97 {
98   lto_mach_o_section ptr;
99
100   /* FIXME We could allocate these things on an obstack.  */
101   ptr = XCNEW (struct lto_mach_o_section_d);
102   if (name)
103     {
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);
108     }
109
110   VEC_safe_push (lto_mach_o_section, heap, mach_o_file->section_vec, ptr);
111
112   return ptr;
113 }
114
115 /* Mach-O section data block structure constructor.  */
116
117 static lto_mach_o_data
118 mach_o_new_data (lto_mach_o_section sec)
119 {
120   lto_mach_o_data ptr, *chain_ptr_ptr;
121
122   /* FIXME We could allocate these things on an obstack.  */
123   ptr = XCNEW (struct lto_mach_o_data_d);
124
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;
129
130   return ptr;
131 }
132
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).  */
135
136 static void
137 lto_file_init (lto_file *file, const char *filename, off_t offset)
138 {
139   file->filename = filename;
140   file->offset = offset;
141 }
142
143 /* Return an error string after an error, or a predetermined one
144    if ERRCODE is not -1.  */
145
146 static const char *
147 mach_o_errmsg (int errcode)
148 {
149   return strerror (errcode == -1 ? errno : errcode);
150 }
151
152 /* Returns a hash code for P.  */
153
154 static hashval_t
155 hash_name (const void *p)
156 {
157   const struct lto_section_slot *s = (const struct lto_section_slot *) p;
158   return (hashval_t) htab_hash_string (s->name);
159 }
160
161 /* Returns nonzero if P1 and P2 are equal.  */
162
163 static int
164 eq_name (const void *p1, const void *p2)
165 {
166   const struct lto_section_slot *s1 =
167     (const struct lto_section_slot *) p1;
168   const struct lto_section_slot *s2 =
169     (const struct lto_section_slot *) p2;
170
171   return strcmp (s1->name, s2->name) == 0;
172 }
173
174 /* Build a hash table whose key is the section names and whose data is
175    the start and size of each section in the .o file.  */
176
177 htab_t
178 lto_obj_build_section_table (lto_file *lto_file) 
179 {
180   lto_mach_o_file *mach_o_file = (lto_mach_o_file *)lto_file;
181   lto_mach_o_section sec;
182   htab_t section_hash_table;
183   off_t strtab_offs;
184   ssize_t strtab_size;
185   char *strtab = NULL;
186   int i;
187
188   section_hash_table = htab_create (37, hash_name, eq_name, free);
189
190   /* Seek the string table.  */
191   /* FIXME The segment name should be in darwin.h, but can we include it
192      here in this file?  */
193   for (i = 0;
194        VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
195        i++)
196     {
197       if (strncmp (sec->u.section.segname, "__GNU_LTO", 16) != 0)
198         continue;
199       if (strncmp (sec->u.section.sectname, "__section_names", 16) == 0)
200         break;
201     }
202   if (! sec)
203     {
204       error ("invalid Mach-O LTO object file: no __section_names section found");
205       goto done;
206     }
207   mach_o_file->section_names_section = sec;
208
209   if (mach_o_word_size () == 64)
210     {
211       strtab_offs = (off_t) get_uint32 (&sec->u.section_64.offset[0]);
212       strtab_size = (size_t) get_uint64 (&sec->u.section_64.size[0]);
213     }
214   else
215     {
216       strtab_offs = (off_t) get_uint32 (&sec->u.section_32.offset[0]);
217       strtab_size = (size_t) get_uint32 (&sec->u.section_32.size[0]);
218     }
219
220   /* Seek to start of string table.  */
221   if (strtab_offs != lseek (mach_o_file->fd,
222                             mach_o_file->base.offset + strtab_offs,
223                             SEEK_SET))
224     {
225       error ("altered or invalid Mach-O object file");
226       goto done;
227     }
228
229   strtab = XNEWVEC (char, strtab_size);
230   if (read (mach_o_file->fd, strtab, strtab_size) != strtab_size)
231     {
232       error ("invalid Mach-O LTO object file __section_names section");
233       goto done;
234     }
235
236   /* Scan sections looking at names.  */
237   for (i = 0;
238        VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
239        i++)
240     {
241       struct lto_section_slot s_slot;
242       void **slot;
243       char *new_name;
244       unsigned long stringoffset;
245       char name[17];
246
247       /* Ignore non-LTO sections.  Also ignore the __section_names section
248          which does not need renaming.  */
249       if (strncmp (sec->u.section.segname, "__GNU_LTO", 16) != 0)
250         continue;
251       if (sec == mach_o_file->section_names_section)
252         continue;
253
254       /* Try to extract the offset of the real name for this section from
255          __section_names.  */
256       memcpy (&name[0], sec->u.section.sectname, 16);
257       name[16] = '\0';
258       if (name[0] != '_' || name[1] != '_'
259           || sscanf (&name[2], "%08lX", &stringoffset) != 1
260           || strtab_size < (ssize_t) stringoffset)
261         {
262           error ("invalid Mach-O LTO section name string: %s", name);
263           continue;
264         }
265
266       new_name = XNEWVEC (char, strlen (strtab + stringoffset) + 1);
267       strcpy (new_name, strtab + stringoffset);
268       s_slot.name = new_name;
269       slot = htab_find_slot (section_hash_table, &s_slot, INSERT);
270       if (*slot == NULL)
271         {
272           struct lto_section_slot *new_slot = XNEW (struct lto_section_slot);
273
274           new_slot->name = new_name;
275           if (mach_o_word_size() == 64)
276             {
277               new_slot->start =
278                 (intptr_t) get_uint32 (&sec->u.section_64.offset[0]);
279               new_slot->len =
280                 (size_t) get_uint64 (&sec->u.section_64.size[0]);
281             }
282           else
283             {
284               new_slot->start =
285                 (intptr_t) get_uint32 (&sec->u.section_32.offset[0]);
286               new_slot->len =
287                 (size_t) get_uint32 (&sec->u.section_32.size[0]);
288             }
289
290           *slot = new_slot;
291         }
292       else
293         {
294           error ("two or more sections for %s:", new_name);
295           goto done;
296         }
297     }
298
299  done:
300   if (strtab)
301     free (strtab);
302   return section_hash_table;
303 }
304
305
306 /* Begin a new Mach-O section named NAME in the current output file.  */
307
308 void
309 lto_obj_begin_section (const char *name)
310 {
311   lto_mach_o_file *file;
312
313   if (strncmp (name, LTO_SECTION_NAME_PREFIX,
314                strlen(LTO_SECTION_NAME_PREFIX)) != 0)
315     sorry ("not implemented: Mach-O writer for non-LTO sections");
316
317   /* Grab the current output file and do some basic assertion checking.  */
318   file = (lto_mach_o_file *) lto_get_current_out_file (),
319   gcc_assert (file && file->writable && !file->scn);
320
321   /* Create a new section.  */
322   file->scn = mach_o_new_section (file, name);
323   if (!file->scn)
324     fatal_error ("could not create a new Mach-O section: %s", mach_o_errmsg (-1));
325 }
326
327
328 /* Append DATA of length LEN to the current output section.  BASE is a pointer
329    to the output page containing DATA.  It is freed once the output file has
330    been written.  */
331
332 void
333 lto_obj_append_data (const void *data, size_t len, void *block)
334 {
335   lto_mach_o_file *file;
336   lto_mach_o_data mach_o_data;
337   struct lto_char_ptr_base *base = (struct lto_char_ptr_base *) block;
338
339   /* Grab the current output file and do some basic assertion checking.  */
340   file = (lto_mach_o_file *) lto_get_current_out_file ();
341   gcc_assert (file);
342   gcc_assert (file->scn);
343
344   mach_o_data = mach_o_new_data (file->scn);
345   if (!mach_o_data)
346     fatal_error ("could not append data to Mach-O section: %s", mach_o_errmsg (-1));
347
348   mach_o_data->d_buf = CONST_CAST (void *, data);
349   mach_o_data->d_size = len;
350
351   /* Chain all data blocks (from all sections) on one singly-linked
352      list for freeing en masse after the file is closed.  */
353   base->ptr = (char *)file->data;
354   file->data = base;
355 }
356
357
358 /* End the current output section.  This just does some assertion checking
359    and sets the current output file's scn member to NULL.  */
360
361 void
362 lto_obj_end_section (void)
363 {
364   lto_mach_o_file *file;
365
366   /* Grab the current output file and validate some basic assertions.  */
367   file = (lto_mach_o_file *) lto_get_current_out_file ();
368   gcc_assert (file);
369   gcc_assert (file->scn);
370
371   file->scn = NULL;
372 }
373
374
375 /* Read a Mach-O header from MACH_O_FILE and validate it.
376    The file descriptor in MACH_O_FILE points at the start of the file.
377    If cached_mach_o_header is uninitialized, caches the results.
378    On succes, returns true and moves file pointer to the start of the
379    load commands.  On failure, returns false.  */
380
381 static bool
382 validate_mach_o_header (lto_mach_o_file *mach_o_file)
383 {
384   ssize_t i, n;
385   unsigned char magic[4];
386   uint32_t cputype;
387   off_t startpos;
388
389   /* Known header magics for validation, as an array.  */
390   static const unsigned int mach_o_known_formats[] = {
391     MACH_O_MH_MAGIC,
392     MACH_O_MH_CIGAM,
393     MACH_O_MH_MAGIC_64,
394     MACH_O_MH_CIGAM_64,
395   };
396 #define MACH_O_NUM_KNOWN_FORMATS \
397   ((ssize_t) ARRAY_SIZE (mach_o_known_formats))
398
399   startpos = lseek (mach_o_file->fd, 0, SEEK_CUR);
400   if (read (mach_o_file->fd, &magic, sizeof (magic)) != 4
401       || lseek (mach_o_file->fd, -4, SEEK_CUR) != startpos)
402     {
403       error ("cannot read file %s", mach_o_file->base.filename);
404       return false;
405     }
406
407   for (i = 0; i < MACH_O_NUM_KNOWN_FORMATS; ++i)
408     if (get_uint32 (&magic[0]) == mach_o_known_formats[i])
409       break;
410   if (i == MACH_O_NUM_KNOWN_FORMATS)
411     goto not_for_target;
412
413   /* Check the endian-ness.  */
414   if (BYTES_BIG_ENDIAN && magic[0] != 0xfe)
415     goto not_for_target;
416
417   /* Set or check cached magic number.  */
418   if (cached_mach_o_magic == 0)
419     cached_mach_o_magic = get_uint32 (&magic[0]);
420   else if (cached_mach_o_magic != get_uint32 (&magic[0]))
421     goto not_for_target;
422  
423   n = mach_o_word_size () == 64
424       ? sizeof (mach_o_header_64) : sizeof (mach_o_header_32);
425   if (read (mach_o_file->fd, &mach_o_file->u.header, n) != n)
426     goto not_for_target;
427
428   /* Is this a supported CPU?  */
429   /* ??? Would be nice to validate the exact target architecture.  */
430   cputype = get_uint32 (&mach_o_file->u.header.cputype[0]);
431   if (cputype == MACH_O_CPU_TYPE_I386
432       || cputype == MACH_O_CPU_TYPE_POWERPC)
433     {
434       if (mach_o_word_size () != 32)
435         goto not_for_target;
436     }
437   else if (cputype == MACH_O_CPU_TYPE_X86_64
438            || cputype == MACH_O_CPU_TYPE_POWERPC_64)
439     {
440       if (mach_o_word_size () != 64)
441         goto not_for_target;
442     }
443
444   /* Is this an MH_OBJECT file?  */
445   if (get_uint32 (&mach_o_file->u.header.filetype[0]) != MACH_O_MH_OBJECT)
446     error ("Mach-O file %s is not an MH_OBJECT file",
447            mach_o_file->base.filename);
448
449   /* Save the header for future use.  */
450   memcpy (&cached_mach_o_header, &mach_o_file->u.header,
451           sizeof (cached_mach_o_header));
452
453   return true;
454
455  not_for_target:
456   error ("file %s is not a Mach-O object file for target",
457          mach_o_file->base.filename);
458   return false;
459 }
460
461
462 /* Read a Mach-O LC_SEGMENT command (32 bits) from MACH_O_FILE and
463    validate it.
464    The file descriptor in MACH_O_FILE points at the start of the load
465    command.  On sucess, returns true and advances the file pointer
466    past the end of the load command.  On failure, returns false.  */
467
468 static bool
469 validate_mach_o_segment_command_32 (lto_mach_o_file *mach_o_file)
470 {
471   mach_o_segment_command_32 seg_cmd_32;
472   unsigned int i;
473   ssize_t n;
474   off_t startpos;
475
476   /* Fields we're interested in.  */
477   uint32_t cmd;
478   uint32_t cmdsize;
479   uint32_t nsects;
480
481   startpos = lseek (mach_o_file->fd, 0, SEEK_CUR);
482
483   n = sizeof (mach_o_segment_command_32);
484   if (read (mach_o_file->fd, (void *) &seg_cmd_32, n) != n)
485     goto fail;
486
487   cmd = get_uint32 (&seg_cmd_32.cmd[0]);
488   cmdsize = get_uint32 (&seg_cmd_32.cmdsize[0]);
489   nsects = get_uint32 (&seg_cmd_32.nsects[0]);
490   gcc_assert (cmd == MACH_O_LC_SEGMENT);
491
492   /* Validate section table entries.  */
493   for (i = 0; i < nsects; i++)
494     {
495       mach_o_section_32 sec_32;
496       lto_mach_o_section ltosec;
497
498       n = sizeof (mach_o_section_32);
499       if (read (mach_o_file->fd, &sec_32, n) != n)
500         goto fail;
501
502       /* ??? Perform some checks.  */
503
504       /* Looks ok, so record its details.  We don't read the 
505          string table or set up names yet; we'll do that when
506          we build the hash table.  */
507       ltosec = mach_o_new_section (mach_o_file, NULL);
508       memcpy (&ltosec->u.section_32, &sec_32, sizeof (sec_32));
509     }
510
511   if (lseek (mach_o_file->fd, 0, SEEK_CUR) != startpos + cmdsize)
512     goto fail;
513
514   return true;
515
516  fail:
517   error ("could not read LC_SEGMENT command in Mach-O file %s",
518          mach_o_file->base.filename);
519   return false;
520 }
521
522
523 /* Read a Mach-O LC_SEGMENT_64 command from MACH_O_FILE and validate it.
524    The file descriptor in MACH_O_FILE points at the start of the load
525    command.  On sucess, returns true and advances the file pointer
526    past the end of the load command.  On failure, returns false.  */
527
528 static bool
529 validate_mach_o_segment_command_64 (lto_mach_o_file *mach_o_file)
530 {
531   mach_o_segment_command_64 seg_cmd_64;
532   unsigned int i;
533   ssize_t n;
534   off_t startpos;
535
536   /* Fields we're interested in.  */
537   uint32_t cmd;
538   uint32_t cmdsize;
539   uint32_t nsects;
540
541   startpos = lseek (mach_o_file->fd, 0, SEEK_CUR);
542
543   n = sizeof (mach_o_segment_command_64);
544   if (read (mach_o_file->fd, (void *) &seg_cmd_64, n) != n)
545     goto fail;
546
547   cmd = get_uint32 (&seg_cmd_64.cmd[0]);
548   cmdsize = get_uint32 (&seg_cmd_64.cmdsize[0]);
549   nsects = get_uint32 (&seg_cmd_64.nsects[0]);
550   gcc_assert (cmd == MACH_O_LC_SEGMENT_64);
551
552   /* Validate section table entries.  */
553   for (i = 0; i < nsects; i++)
554     {
555       mach_o_section_64 sec_64;
556       lto_mach_o_section ltosec;
557
558       n = sizeof (mach_o_section_64);
559       if (read (mach_o_file->fd, &sec_64, n) != n)
560         goto fail;
561
562       /* ??? Perform some checks.  */
563
564       /* Looks ok, so record its details.  We don't read the 
565          string table or set up names yet; we'll do that when
566          we build the hash table.  */
567       ltosec = mach_o_new_section (mach_o_file, NULL);
568       memcpy (&ltosec->u.section_64, &sec_64, sizeof (sec_64));
569     }
570
571   if (lseek (mach_o_file->fd, 0, SEEK_CUR) != startpos + cmdsize)
572     goto fail;
573
574   return true;
575
576  fail:
577   error ("could not read LC_SEGMENT_64 command in Mach-O file %s",
578          mach_o_file->base.filename);
579   return false;
580 }
581
582 /* Read a Mach-O load commands from MACH_O_FILE and validate it.
583    The file descriptor in MACH_O_FILE points at the start of the load
584    command.  On sucess, returns true and advances the file pointer
585    past the end of the load command.  On failure, returns false.  */
586
587 static bool
588 validate_mach_o_load_command (lto_mach_o_file *mach_o_file)
589 {
590   mach_o_load_command load_command;
591   uint32_t cmd;
592   uint32_t cmdsize;
593   ssize_t n;
594
595   n = sizeof (load_command);
596   if (read (mach_o_file->fd, &load_command, n) != n)
597     {
598       error ("could not read load commands in Mach-O file %s",
599              mach_o_file->base.filename);
600       return false;
601     }
602   lseek (mach_o_file->fd, -1 * (off_t) sizeof (load_command), SEEK_CUR);
603
604   cmd = get_uint32 (&load_command.cmd[0]);
605   cmdsize = get_uint32 (&load_command.cmdsize[0]);
606   switch (cmd)
607     {
608     case MACH_O_LC_SEGMENT:
609       return validate_mach_o_segment_command_32 (mach_o_file);
610     case MACH_O_LC_SEGMENT_64:
611       return validate_mach_o_segment_command_64 (mach_o_file);
612
613     default:
614       /* Just skip over it.  */
615       lseek (mach_o_file->fd, cmdsize, SEEK_CUR);
616       return true;
617     }
618 }
619
620 /* Validate's MACH_O_FILE's executable header and, if cached_mach_o_header is
621    uninitialized, caches the results.  Also records the section header string
622    table's section index.  Returns true on success, false on failure.  */
623
624 static bool
625 validate_file (lto_mach_o_file *mach_o_file)
626 {
627   uint32_t i, ncmds;
628
629   /* Read and sanity check the raw header.  */
630   if (! validate_mach_o_header (mach_o_file))
631     return false;
632
633   ncmds = get_uint32 (&mach_o_file->u.header.ncmds[0]);
634   for (i = 0; i < ncmds; ++i)
635     if (! validate_mach_o_load_command (mach_o_file))
636       return false;
637
638   return true;
639 }
640
641 /* Initialize MACH_O_FILE's executable header using cached data from previously
642    read files.  */
643
644 static void
645 init_mach_o_header (lto_mach_o_file *mach_o_file)
646 {
647   gcc_assert (cached_mach_o_magic != 0);
648   memcpy (&mach_o_file->u.header,
649           &cached_mach_o_header,
650           sizeof (mach_o_file->u.header));
651   put_uint32 (&mach_o_file->u.header.ncmds[0], 0);
652   put_uint32 (&mach_o_file->u.header.sizeofcmds[0], 0);
653 }
654
655 /* Open Mach-O file FILENAME.  If WRITABLE is true, the file is opened for write
656    and, if necessary, created.  Otherwise, the file is opened for reading.
657    Returns the opened file.  */
658
659 lto_file *
660 lto_obj_file_open (const char *filename, bool writable)
661 {
662   lto_mach_o_file *mach_o_file;
663   lto_file *result = NULL;
664   off_t offset;
665   const char *offset_p;
666   char *fname;
667   struct stat statbuf;
668
669   offset_p = strchr (filename, '@');
670   if (!offset_p)
671     {
672       fname = xstrdup (filename);
673       offset = 0;
674     }
675   else
676     {
677       /* The file started with '@' is a file containing command line
678          options.  Stop if it doesn't exist.  */
679       if (offset_p == filename)
680         fatal_error ("command line option file '%s' does not exist",
681                      filename);
682
683       fname = (char *) xmalloc (offset_p - filename + 1);
684       memcpy (fname, filename, offset_p - filename);
685       fname[offset_p - filename] = '\0';
686       offset_p += 3; /* skip the @0x */
687       offset = lto_parse_hex (offset_p);
688     }
689
690   /* Set up.  */
691   mach_o_file = XCNEW (lto_mach_o_file);
692   result = (lto_file *) mach_o_file;
693   lto_file_init (result, fname, offset);
694   mach_o_file->fd = -1;
695   mach_o_file->writable = writable;
696
697   /* Open the file.  */
698   mach_o_file->fd = open (fname,
699     O_BINARY | (writable ? O_WRONLY | O_CREAT | O_TRUNC : O_RDONLY), 0666);
700
701   if (mach_o_file->fd == -1)
702     {
703       error ("could not open file %s", fname);
704       goto fail;
705     }
706
707   if (stat (fname, &statbuf) < 0)
708     {
709       error ("could not stat file %s", fname);
710       goto fail;
711     }
712
713   mach_o_file->file_size = statbuf.st_size;
714
715   /* If the object is in an archive, get it out.  */
716   if (offset != 0)
717     {
718       char ar_tail[12];
719       int size;
720
721       /* Surely not?  */
722       gcc_assert (!writable);
723
724       /* Seek to offset, or error.  */
725       if (lseek (mach_o_file->fd, offset, SEEK_SET) != (ssize_t) offset)
726         {
727           error ("could not find archive member @0x%lx", (long) offset);
728           goto fail;
729         }
730
731       /* Now seek back 12 chars and read the tail of the AR header to
732          find the length of the member file.  */
733       if (lseek (mach_o_file->fd, -12, SEEK_CUR) < 0
734           || read (mach_o_file->fd, ar_tail, 12) != 12
735           || lseek (mach_o_file->fd, 0, SEEK_CUR) != (ssize_t) offset
736           || ar_tail[10] != '`' || ar_tail[11] != '\n')
737         {
738           error ("could not find archive header @0x%lx", (long) offset);
739           goto fail;
740         }
741
742       ar_tail[11] = 0;
743       if (sscanf (ar_tail, "%d", &size) != 1)
744         {
745           error ("invalid archive header @0x%lx", (long) offset);
746           goto fail;
747         }
748       mach_o_file->file_size = size;
749     }
750
751   if (writable)
752     {
753       init_mach_o_header (mach_o_file);
754     }
755   else
756     if (! validate_file (mach_o_file))
757       goto fail;
758
759   return result;
760
761  fail:
762   if (result)
763     lto_obj_file_close (result);
764   return NULL;
765 }
766
767
768 /* Write the data in MACH_O_FILE to a real Mach-O binary object.
769    We write a header, a segment load command, and section data.  */
770
771 static bool
772 mach_o_write_object_file (lto_mach_o_file *mach_o_file)
773 {
774   lto_mach_o_section sec, snsec;
775   lto_mach_o_data snsec_data;
776   ssize_t hdrsize, cmdsize, secsize;
777   size_t num_sections, snsec_size, total_sec_size;
778   unsigned int sec_offs, strtab_offs;
779   int i;
780   bool write_err = false;
781
782   /* The number of sections we will write is the number of sections added by
783      the streamer, plus 1 for the section names section.  */
784   num_sections = VEC_length (lto_mach_o_section, mach_o_file->section_vec) + 1;
785
786   /* Calculate the size of the basic data structures on disk.  */
787   if (mach_o_word_size () == 64)
788     {
789       hdrsize = sizeof (mach_o_header_64);
790       secsize = sizeof (mach_o_section_64);
791       cmdsize = sizeof (mach_o_segment_command_64) + num_sections * secsize;
792     }
793   else
794     {
795       hdrsize = sizeof (mach_o_header_32);
796       secsize = sizeof (mach_o_section_32);
797       cmdsize = sizeof (mach_o_segment_command_32) + num_sections * secsize;
798     }
799  
800   /* Allocate the section names section.  */
801   snsec_size = 0;
802   for (i = 0;
803        VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
804        i++)
805     snsec_size += strlen (sec->name) + 1;
806   snsec = mach_o_new_section (mach_o_file, NULL);
807   snsec->name = LTO_NAMES_SECTION;
808   snsec_data = mach_o_new_data (snsec);
809   snsec_data->d_buf = XCNEWVEC (char, snsec_size);
810   snsec_data->d_size = snsec_size;
811
812   /* Position all the sections, and fill out their headers.  */
813   sec_offs = hdrsize + cmdsize;
814   strtab_offs = 0;
815   total_sec_size = 0;
816   for (i = 0;
817        VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
818        i++)
819     {
820       lto_mach_o_data data;
821       size_t data_size;
822       /* Put the section and segment names.  Add the section name to the
823          section names section (unless, of course, this *is* the section
824          names section).  */
825       if (sec == snsec)
826         snprintf (sec->u.section.sectname, 16, "%s", LTO_NAMES_SECTION);
827       else
828         {
829           sprintf (sec->u.section.sectname, "__%08X", strtab_offs);
830           memcpy ((char *) snsec_data->d_buf + strtab_offs, sec->name, strlen (sec->name));
831         }
832       memcpy (&sec->u.section.segname[0],
833               LTO_SEGMENT_NAME, strlen (LTO_SEGMENT_NAME));
834
835       /* Add layout and attributes.  */
836       for (data = sec->data_chain, data_size = 0; data; data = data->next)
837         data_size += data->d_size;
838       if (mach_o_word_size () == 64)
839         {
840           put_uint64 (&sec->u.section_64.addr[0], total_sec_size); 
841           put_uint64 (&sec->u.section_64.size[0], data_size); 
842           put_uint32 (&sec->u.section_64.offset[0], sec_offs); 
843           put_uint32 (&sec->u.section_64.flags[0], MACH_O_S_ATTR_DEBUG);
844         }
845       else
846         {
847           put_uint32 (&sec->u.section_64.addr[0], total_sec_size); 
848           put_uint32 (&sec->u.section_32.size[0], data_size); 
849           put_uint32 (&sec->u.section_32.offset[0], sec_offs); 
850           put_uint32 (&sec->u.section_32.flags[0], MACH_O_S_ATTR_DEBUG);
851         }
852
853       sec_offs += data_size;
854       total_sec_size += data_size;
855       strtab_offs += strlen (sec->name) + 1;
856     }
857
858   /* We can write the data now.  As there's no way to indicate an error return
859      from this hook, error handling is limited to not wasting our time doing
860      any more writes in the event that any one fails.  */
861
862   /* Write the header.  */
863   put_uint32 (&mach_o_file->u.header.ncmds[0], 1);
864   put_uint32 (&mach_o_file->u.header.sizeofcmds[0], cmdsize);
865   write_err = (write (mach_o_file->fd,
866                       &mach_o_file->u.header, hdrsize) != hdrsize);
867   /* Write the segment load command.  */
868   if (mach_o_word_size () == 64)
869     {
870       mach_o_segment_command_64 lc;
871       ssize_t lc_size = sizeof (lc);
872       memset (&lc, 0, lc_size);
873       put_uint32 (&lc.cmd[0], MACH_O_LC_SEGMENT_64);
874       put_uint32 (&lc.cmdsize[0], cmdsize);
875       put_uint64 (&lc.fileoff[0], hdrsize + cmdsize);
876       put_uint64 (&lc.filesize[0], total_sec_size);
877       put_uint32 (&lc.nsects[0], num_sections);
878       write_err = (write (mach_o_file->fd, &lc, lc_size) != lc_size);
879     }
880   else
881     {
882       mach_o_segment_command_32 lc;
883       ssize_t lc_size = sizeof (lc);
884       memset (&lc, 0, lc_size);
885       put_uint32 (&lc.cmd[0], MACH_O_LC_SEGMENT);
886       put_uint32 (&lc.cmdsize[0], cmdsize);
887       put_uint32 (&lc.fileoff[0], hdrsize + cmdsize);
888       put_uint32 (&lc.filesize[0], total_sec_size);
889       put_uint32 (&lc.nsects[0], num_sections);
890       write_err = (write (mach_o_file->fd, &lc, lc_size) != lc_size);
891     }
892   for (i = 0;
893        !write_err
894        && VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
895        i++)
896     write_err = (write (mach_o_file->fd,
897                         &sec->u.section, secsize) != secsize);
898
899   gcc_assert (lseek (mach_o_file->fd, 0, SEEK_CUR) == hdrsize + cmdsize);
900
901   /* Write the section data.  */
902   for (i = 0;
903        !write_err
904        && VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
905        i++)
906     {
907       lto_mach_o_data data;
908
909       for (data = sec->data_chain; data; data = data->next)
910         {
911           if (!write_err)
912             write_err = (write (mach_o_file->fd, data->d_buf, data->d_size)
913                          != data->d_size);
914           else
915             break;
916         }
917     }
918
919   return !write_err;
920 }
921
922 /* Close Mach-O file FILE and clean up any associated data structures.  If FILE
923    was opened for writing, the file's Mach-O data is written at this time.  Any
924    cached data buffers are freed.  */
925
926 void
927 lto_obj_file_close (lto_file *file)
928 {
929   lto_mach_o_file *mach_o_file = (lto_mach_o_file *) file;
930   struct lto_char_ptr_base *cur, *tmp;
931   lto_mach_o_section sec;
932   bool write_err = false;
933   int i;
934
935   /* If this file is open for writing, write a Mach-O object file.  */
936   if (mach_o_file->writable)
937     {
938       if (! mach_o_write_object_file (mach_o_file))
939         fatal_error ("cannot write Mach-O object file");
940     }
941
942   /* Close the file, we're done.  */
943   if (mach_o_file->fd != -1)
944     close (mach_o_file->fd);
945
946   /* Free any data buffers.  */
947   cur = mach_o_file->data;
948   while (cur)
949     {
950       tmp = cur;
951       cur = (struct lto_char_ptr_base *) cur->ptr;
952       free (tmp);
953     }
954
955   /* Free any sections and their data chains.  */
956   for (i = 0;
957        VEC_iterate (lto_mach_o_section, mach_o_file->section_vec, i, sec);
958        i++)
959     {
960       lto_mach_o_data curdata, nextdata;
961       curdata = sec->data_chain;
962       while (curdata)
963         {
964           nextdata = curdata->next;
965           free (curdata);
966           curdata = nextdata;
967         }
968       free (sec);
969     }
970   VEC_free (lto_mach_o_section, heap, mach_o_file->section_vec);
971
972   free (file);
973
974   /* If there was an error, mention it.  */
975   if (write_err)
976     error ("I/O error writing Mach-O output file");
977 }
978