comparison gcc/lto/lto-macho.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents
children
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
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