* emultempl/armelf.em (arm_elf_after_open): Move check for using a
[binutils.git] / bfd / mach-o.c
blobd3d3abc365b1e10c10b4afe7735e5bba4738c789
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "sysdep.h"
23 #include "mach-o.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "libiberty.h"
27 #include <ctype.h>
29 #ifndef BFD_IO_FUNCS
30 #define BFD_IO_FUNCS 0
31 #endif
33 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
34 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
35 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
36 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
37 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
38 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
39 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
40 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
41 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
42 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
43 #define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup
44 #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
45 #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
46 #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
47 #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
48 #define bfd_mach_o_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
49 #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
50 #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
51 #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
52 #define bfd_mach_o_find_inliner_info _bfd_nosymbols_find_inliner_info
53 #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
54 #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
55 #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
56 #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
57 #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
58 #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
59 #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
60 #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
61 #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
62 #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
63 #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
64 #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach
65 #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
66 #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
67 #define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
68 #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
69 #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
70 #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
71 #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
72 #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section
73 #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
74 #define bfd_mach_o_section_already_linked _bfd_generic_section_already_linked
75 #define bfd_mach_o_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
76 #define bfd_mach_o_core_file_matches_executable_p generic_core_file_matches_executable_p
79 /* The flags field of a section structure is separated into two parts a section
80 type and section attributes. The section types are mutually exclusive (it
81 can only have one type) but the section attributes are not (it may have more
82 than one attribute). */
84 #define SECTION_TYPE 0x000000ff /* 256 section types. */
85 #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes. */
87 /* Constants for the section attributes part of the flags field of a section
88 structure. */
90 #define SECTION_ATTRIBUTES_USR 0xff000000 /* User-settable attributes. */
91 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* Section contains only true machine instructions. */
92 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* System setable attributes. */
93 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* Section contains some machine instructions. */
94 #define S_ATTR_EXT_RELOC 0x00000200 /* Section has external relocation entries. */
95 #define S_ATTR_LOC_RELOC 0x00000100 /* Section has local relocation entries. */
97 #define N_STAB 0xe0
98 #define N_TYPE 0x1e
99 #define N_EXT 0x01
101 #define N_UNDF 0x0
102 #define N_ABS 0x2
103 #define N_TEXT 0x4
104 #define N_DATA 0x6
105 #define N_BSS 0x8
106 #define N_SECT 0xe
107 #define N_INDR 0xa
109 static unsigned int
110 bfd_mach_o_version (bfd *abfd)
112 bfd_mach_o_data_struct *mdata = NULL;
114 BFD_ASSERT (bfd_mach_o_valid (abfd));
115 mdata = abfd->tdata.mach_o_data;
117 return mdata->header.version;
120 bfd_boolean
121 bfd_mach_o_valid (bfd *abfd)
123 if (abfd == NULL || abfd->xvec == NULL)
124 return 0;
126 if (! ((abfd->xvec == &mach_o_be_vec)
127 || (abfd->xvec == &mach_o_le_vec)
128 || (abfd->xvec == &mach_o_fat_vec)))
129 return 0;
131 if (abfd->tdata.mach_o_data == NULL)
132 return 0;
133 return 1;
136 /* Copy any private info we understand from the input symbol
137 to the output symbol. */
139 static bfd_boolean
140 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
141 asymbol *isymbol ATTRIBUTE_UNUSED,
142 bfd *obfd ATTRIBUTE_UNUSED,
143 asymbol *osymbol ATTRIBUTE_UNUSED)
145 return TRUE;
148 /* Copy any private info we understand from the input section
149 to the output section. */
151 static bfd_boolean
152 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
153 asection *isection ATTRIBUTE_UNUSED,
154 bfd *obfd ATTRIBUTE_UNUSED,
155 asection *osection ATTRIBUTE_UNUSED)
157 return TRUE;
160 /* Copy any private info we understand from the input bfd
161 to the output bfd. */
163 static bfd_boolean
164 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
166 BFD_ASSERT (bfd_mach_o_valid (ibfd));
167 BFD_ASSERT (bfd_mach_o_valid (obfd));
169 obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
170 obfd->tdata.mach_o_data->ibfd = ibfd;
171 return TRUE;
174 static long
175 bfd_mach_o_count_symbols (bfd *abfd)
177 bfd_mach_o_data_struct *mdata = NULL;
178 long nsyms = 0;
179 unsigned long i;
181 BFD_ASSERT (bfd_mach_o_valid (abfd));
182 mdata = abfd->tdata.mach_o_data;
184 for (i = 0; i < mdata->header.ncmds; i++)
185 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
187 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
188 nsyms += sym->nsyms;
191 return nsyms;
194 static long
195 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
197 long nsyms = bfd_mach_o_count_symbols (abfd);
199 if (nsyms < 0)
200 return nsyms;
202 return ((nsyms + 1) * sizeof (asymbol *));
205 static long
206 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
208 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
209 long nsyms = bfd_mach_o_count_symbols (abfd);
210 asymbol **csym = alocation;
211 unsigned long i, j;
213 if (nsyms < 0)
214 return nsyms;
216 for (i = 0; i < mdata->header.ncmds; i++)
218 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
220 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
222 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
224 fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
225 return 0;
228 BFD_ASSERT (sym->symbols != NULL);
230 for (j = 0; j < sym->nsyms; j++)
232 BFD_ASSERT (csym < (alocation + nsyms));
233 *csym++ = &sym->symbols[j];
238 *csym++ = NULL;
240 return nsyms;
243 static void
244 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
245 asymbol *symbol,
246 symbol_info *ret)
248 bfd_symbol_info (symbol, ret);
251 static void
252 bfd_mach_o_print_symbol (bfd *abfd,
253 PTR afile,
254 asymbol *symbol,
255 bfd_print_symbol_type how)
257 FILE *file = (FILE *) afile;
259 switch (how)
261 case bfd_print_symbol_name:
262 fprintf (file, "%s", symbol->name);
263 break;
264 default:
265 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
266 fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
270 static void
271 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
272 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
273 enum bfd_architecture *type,
274 unsigned long *subtype)
276 *subtype = bfd_arch_unknown;
278 switch (mtype)
280 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
281 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
282 case BFD_MACH_O_CPU_TYPE_I386:
283 *type = bfd_arch_i386;
284 *subtype = bfd_mach_i386_i386;
285 break;
286 case BFD_MACH_O_CPU_TYPE_X86_64:
287 *type = bfd_arch_i386;
288 *subtype = bfd_mach_x86_64;
289 break;
290 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
291 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
292 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
293 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
294 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
295 case BFD_MACH_O_CPU_TYPE_SPARC:
296 *type = bfd_arch_sparc;
297 *subtype = bfd_mach_sparc;
298 break;
299 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
300 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
301 case BFD_MACH_O_CPU_TYPE_POWERPC:
302 *type = bfd_arch_powerpc;
303 *subtype = bfd_mach_ppc;
304 break;
305 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
306 *type = bfd_arch_powerpc;
307 *subtype = bfd_mach_ppc64;
308 break;
309 default:
310 *type = bfd_arch_unknown;
311 break;
315 static int
316 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
318 unsigned char buf[32];
319 unsigned int size;
321 size = (header->version == 2) ? 32 : 28;
323 bfd_h_put_32 (abfd, header->magic, buf + 0);
324 bfd_h_put_32 (abfd, header->cputype, buf + 4);
325 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
326 bfd_h_put_32 (abfd, header->filetype, buf + 12);
327 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
328 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
329 bfd_h_put_32 (abfd, header->flags, buf + 24);
331 if (header->version == 2)
332 bfd_h_put_32 (abfd, header->reserved, buf + 28);
334 bfd_seek (abfd, 0, SEEK_SET);
335 if (bfd_bwrite ((PTR) buf, size, abfd) != size)
336 return -1;
338 return 0;
341 static int
342 bfd_mach_o_scan_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
344 bfd_mach_o_thread_command *cmd = &command->command.thread;
345 unsigned int i;
346 unsigned char buf[8];
347 bfd_vma offset;
348 unsigned int nflavours;
350 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
351 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
353 offset = 8;
354 nflavours = 0;
355 for (i = 0; i < cmd->nflavours; i++)
357 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
358 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
360 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
361 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
363 bfd_seek (abfd, command->offset + offset, SEEK_SET);
364 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
365 return -1;
367 offset += cmd->flavours[i].size + 8;
370 return 0;
373 static int
374 bfd_mach_o_scan_write_section_32 (bfd *abfd,
375 bfd_mach_o_section *section,
376 bfd_vma offset)
378 unsigned char buf[68];
380 memcpy (buf, section->sectname, 16);
381 memcpy (buf + 16, section->segname, 16);
382 bfd_h_put_32 (abfd, section->addr, buf + 32);
383 bfd_h_put_32 (abfd, section->size, buf + 36);
384 bfd_h_put_32 (abfd, section->offset, buf + 40);
385 bfd_h_put_32 (abfd, section->align, buf + 44);
386 bfd_h_put_32 (abfd, section->reloff, buf + 48);
387 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
388 bfd_h_put_32 (abfd, section->flags, buf + 56);
389 bfd_h_put_32 (abfd, section->reserved1, buf + 60);
390 bfd_h_put_32 (abfd, section->reserved2, buf + 64);
392 bfd_seek (abfd, offset, SEEK_SET);
393 if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
394 return -1;
396 return 0;
399 static int
400 bfd_mach_o_scan_write_section_64 (bfd *abfd,
401 bfd_mach_o_section *section,
402 bfd_vma offset)
404 unsigned char buf[80];
406 memcpy (buf, section->sectname, 16);
407 memcpy (buf + 16, section->segname, 16);
408 bfd_h_put_64 (abfd, section->addr, buf + 32);
409 bfd_h_put_64 (abfd, section->size, buf + 40);
410 bfd_h_put_32 (abfd, section->offset, buf + 48);
411 bfd_h_put_32 (abfd, section->align, buf + 52);
412 bfd_h_put_32 (abfd, section->reloff, buf + 56);
413 bfd_h_put_32 (abfd, section->nreloc, buf + 60);
414 bfd_h_put_32 (abfd, section->flags, buf + 64);
415 bfd_h_put_32 (abfd, section->reserved1, buf + 68);
416 bfd_h_put_32 (abfd, section->reserved2, buf + 72);
417 bfd_h_put_32 (abfd, section->reserved3, buf + 76);
419 bfd_seek (abfd, offset, SEEK_SET);
420 if (bfd_bwrite ((PTR) buf, 80, abfd) != 80)
421 return -1;
423 return 0;
426 static int
427 bfd_mach_o_scan_write_section (bfd *abfd,
428 bfd_mach_o_section *section,
429 bfd_vma offset,
430 unsigned int wide)
432 if (wide)
433 return bfd_mach_o_scan_write_section_64 (abfd, section, offset);
434 else
435 return bfd_mach_o_scan_write_section_32 (abfd, section, offset);
438 static int
439 bfd_mach_o_scan_write_segment (bfd *abfd,
440 bfd_mach_o_load_command *command,
441 unsigned int wide)
443 unsigned char buf[64];
444 bfd_mach_o_segment_command *seg = &command->command.segment;
445 unsigned long i;
447 if (wide)
449 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
451 memcpy (buf, seg->segname, 16);
453 bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
454 bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
455 bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
456 bfd_h_put_64 (abfd, seg->filesize, buf + 40);
457 bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
458 bfd_h_put_32 (abfd, seg->initprot, buf + 52);
459 bfd_h_put_32 (abfd, seg->nsects, buf + 56);
460 bfd_h_put_32 (abfd, seg->flags, buf + 60);
462 bfd_seek (abfd, command->offset + 8, SEEK_SET);
463 if (bfd_bwrite ((PTR) buf, 64, abfd) != 64)
464 return -1;
466 else
468 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
470 memcpy (buf, seg->segname, 16);
472 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
473 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
474 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
475 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
476 bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
477 bfd_h_put_32 (abfd, seg->initprot, buf + 36);
478 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
479 bfd_h_put_32 (abfd, seg->flags, buf + 44);
481 bfd_seek (abfd, command->offset + 8, SEEK_SET);
482 if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
483 return -1;
487 char buf[1024];
488 bfd_vma nbytes = seg->filesize;
489 bfd_vma curoff = seg->fileoff;
491 while (nbytes > 0)
493 bfd_vma thiswrite = nbytes;
495 if (thiswrite > 1024)
496 thiswrite = 1024;
498 bfd_seek (abfd, curoff, SEEK_SET);
499 if (bfd_bread ((PTR) buf, thiswrite, abfd) != thiswrite)
500 return -1;
502 bfd_seek (abfd, curoff, SEEK_SET);
503 if (bfd_bwrite ((PTR) buf, thiswrite, abfd) != thiswrite)
504 return -1;
506 nbytes -= thiswrite;
507 curoff += thiswrite;
511 for (i = 0; i < seg->nsects; i++)
513 bfd_vma segoff;
514 if (wide)
515 segoff = command->offset + 64 + 8 + (i * 80);
516 else
517 segoff = command->offset + 48 + 8 + (i * 68);
519 if (bfd_mach_o_scan_write_section
520 (abfd, &seg->sections[i], segoff, wide) != 0)
521 return -1;
524 return 0;
527 static int
528 bfd_mach_o_scan_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
530 return bfd_mach_o_scan_write_segment (abfd, command, 0);
533 static int
534 bfd_mach_o_scan_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
536 return bfd_mach_o_scan_write_segment (abfd, command, 1);
539 static int
540 bfd_mach_o_scan_write_symtab_symbols (bfd *abfd, bfd_mach_o_load_command *command)
542 bfd_mach_o_symtab_command *sym = &command->command.symtab;
543 asymbol *s = NULL;
544 unsigned long i;
546 for (i = 0; i < sym->nsyms; i++)
548 unsigned char buf[12];
549 bfd_vma symoff = sym->symoff + (i * 12);
550 unsigned char ntype = 0;
551 unsigned char nsect = 0;
552 short ndesc = 0;
554 s = &sym->symbols[i];
556 /* Instead just set from the stored values. */
557 ntype = (s->udata.i >> 24) & 0xff;
558 nsect = (s->udata.i >> 16) & 0xff;
559 ndesc = s->udata.i & 0xffff;
561 bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
562 bfd_h_put_8 (abfd, ntype, buf + 4);
563 bfd_h_put_8 (abfd, nsect, buf + 5);
564 bfd_h_put_16 (abfd, ndesc, buf + 6);
565 bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
567 bfd_seek (abfd, symoff, SEEK_SET);
568 if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
570 fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
571 12, (unsigned long) symoff);
572 return -1;
576 return 0;
579 static int
580 bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
582 bfd_mach_o_symtab_command *seg = &command->command.symtab;
583 unsigned char buf[16];
585 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
587 bfd_h_put_32 (abfd, seg->symoff, buf);
588 bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
589 bfd_h_put_32 (abfd, seg->stroff, buf + 8);
590 bfd_h_put_32 (abfd, seg->strsize, buf + 12);
592 bfd_seek (abfd, command->offset + 8, SEEK_SET);
593 if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
594 return -1;
596 if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
597 return -1;
599 return 0;
602 static bfd_boolean
603 bfd_mach_o_write_contents (bfd *abfd)
605 unsigned int i;
606 asection *s;
608 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
610 /* Write data sections first in case they overlap header data to be
611 written later. */
613 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
616 /* Now write header information. */
617 if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
618 return FALSE;
620 for (i = 0; i < mdata->header.ncmds; i++)
622 unsigned char buf[8];
623 bfd_mach_o_load_command *cur = &mdata->commands[i];
624 unsigned long typeflag;
626 typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
628 bfd_h_put_32 (abfd, typeflag, buf);
629 bfd_h_put_32 (abfd, cur->len, buf + 4);
631 bfd_seek (abfd, cur->offset, SEEK_SET);
632 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
633 return FALSE;
635 switch (cur->type)
637 case BFD_MACH_O_LC_SEGMENT:
638 if (bfd_mach_o_scan_write_segment_32 (abfd, cur) != 0)
639 return FALSE;
640 break;
641 case BFD_MACH_O_LC_SEGMENT_64:
642 if (bfd_mach_o_scan_write_segment_64 (abfd, cur) != 0)
643 return FALSE;
644 break;
645 case BFD_MACH_O_LC_SYMTAB:
646 if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
647 return FALSE;
648 break;
649 case BFD_MACH_O_LC_SYMSEG:
650 break;
651 case BFD_MACH_O_LC_THREAD:
652 case BFD_MACH_O_LC_UNIXTHREAD:
653 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
654 return FALSE;
655 break;
656 case BFD_MACH_O_LC_LOADFVMLIB:
657 case BFD_MACH_O_LC_IDFVMLIB:
658 case BFD_MACH_O_LC_IDENT:
659 case BFD_MACH_O_LC_FVMFILE:
660 case BFD_MACH_O_LC_PREPAGE:
661 case BFD_MACH_O_LC_DYSYMTAB:
662 case BFD_MACH_O_LC_LOAD_DYLIB:
663 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
664 case BFD_MACH_O_LC_ID_DYLIB:
665 case BFD_MACH_O_LC_LOAD_DYLINKER:
666 case BFD_MACH_O_LC_ID_DYLINKER:
667 case BFD_MACH_O_LC_PREBOUND_DYLIB:
668 case BFD_MACH_O_LC_ROUTINES:
669 case BFD_MACH_O_LC_SUB_FRAMEWORK:
670 break;
671 default:
672 fprintf (stderr,
673 "unable to write unknown load command 0x%lx\n",
674 (unsigned long) cur->type);
675 return FALSE;
679 return TRUE;
682 static int
683 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
684 struct bfd_link_info *info ATTRIBUTE_UNUSED)
686 return 0;
689 /* Make an empty symbol. This is required only because
690 bfd_make_section_anyway wants to create a symbol for the section. */
692 static asymbol *
693 bfd_mach_o_make_empty_symbol (bfd *abfd)
695 asymbol *new;
697 new = bfd_zalloc (abfd, sizeof (* new));
698 if (new == NULL)
699 return new;
700 new->the_bfd = abfd;
701 return new;
704 static int
705 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
707 unsigned char buf[32];
708 unsigned int size;
709 bfd_vma (*get32) (const void *) = NULL;
711 bfd_seek (abfd, 0, SEEK_SET);
713 /* Just read the magic number. */
714 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
715 return -1;
717 if (bfd_getb32 (buf) == 0xfeedface)
719 header->byteorder = BFD_ENDIAN_BIG;
720 header->magic = 0xfeedface;
721 header->version = 1;
722 get32 = bfd_getb32;
724 else if (bfd_getl32 (buf) == 0xfeedface)
726 header->byteorder = BFD_ENDIAN_LITTLE;
727 header->magic = 0xfeedface;
728 header->version = 1;
729 get32 = bfd_getl32;
731 else if (bfd_getb32 (buf) == 0xfeedfacf)
733 header->byteorder = BFD_ENDIAN_BIG;
734 header->magic = 0xfeedfacf;
735 header->version = 2;
736 get32 = bfd_getb32;
738 else if (bfd_getl32 (buf) == 0xfeedfacf)
740 header->byteorder = BFD_ENDIAN_LITTLE;
741 header->magic = 0xfeedfacf;
742 header->version = 2;
743 get32 = bfd_getl32;
745 else
747 header->byteorder = BFD_ENDIAN_UNKNOWN;
748 return -1;
751 /* Once the size of the header is known, read the full header. */
752 size = (header->version == 2) ? 32 : 28;
754 bfd_seek (abfd, 0, SEEK_SET);
755 if (bfd_bread ((PTR) buf, size, abfd) != size)
756 return -1;
758 header->cputype = (*get32) (buf + 4);
759 header->cpusubtype = (*get32) (buf + 8);
760 header->filetype = (*get32) (buf + 12);
761 header->ncmds = (*get32) (buf + 16);
762 header->sizeofcmds = (*get32) (buf + 20);
763 header->flags = (*get32) (buf + 24);
765 if (header->version == 2)
766 header->reserved = (*get32) (buf + 28);
768 return 0;
771 static asection *
772 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section)
774 asection *bfdsec;
775 char *sname;
776 const char *prefix = "LC_SEGMENT";
777 unsigned int snamelen;
778 flagword flags;
780 snamelen = strlen (prefix) + 1
781 + strlen (section->segname) + 1
782 + strlen (section->sectname) + 1;
784 sname = bfd_alloc (abfd, snamelen);
785 if (sname == NULL)
786 return NULL;
787 sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
789 flags = SEC_ALLOC;
790 if ((section->flags & SECTION_TYPE) != BFD_MACH_O_S_ZEROFILL)
791 flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
792 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
793 if (bfdsec == NULL)
794 return NULL;
796 bfdsec->vma = section->addr;
797 bfdsec->lma = section->addr;
798 bfdsec->size = section->size;
799 bfdsec->filepos = section->offset;
800 bfdsec->alignment_power = section->align;
801 bfdsec->segment_mark = 0;
803 return bfdsec;
806 static int
807 bfd_mach_o_scan_read_section_32 (bfd *abfd,
808 bfd_mach_o_section *section,
809 bfd_vma offset)
811 unsigned char buf[68];
813 bfd_seek (abfd, offset, SEEK_SET);
814 if (bfd_bread ((PTR) buf, 68, abfd) != 68)
815 return -1;
817 memcpy (section->sectname, buf, 16);
818 section->sectname[16] = '\0';
819 memcpy (section->segname, buf + 16, 16);
820 section->segname[16] = '\0';
821 section->addr = bfd_h_get_32 (abfd, buf + 32);
822 section->size = bfd_h_get_32 (abfd, buf + 36);
823 section->offset = bfd_h_get_32 (abfd, buf + 40);
824 section->align = bfd_h_get_32 (abfd, buf + 44);
825 section->reloff = bfd_h_get_32 (abfd, buf + 48);
826 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
827 section->flags = bfd_h_get_32 (abfd, buf + 56);
828 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
829 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
830 section->reserved3 = 0;
831 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
833 if (section->bfdsection == NULL)
834 return -1;
836 return 0;
839 static int
840 bfd_mach_o_scan_read_section_64 (bfd *abfd,
841 bfd_mach_o_section *section,
842 bfd_vma offset)
844 unsigned char buf[80];
846 bfd_seek (abfd, offset, SEEK_SET);
847 if (bfd_bread ((PTR) buf, 80, abfd) != 80)
848 return -1;
850 memcpy (section->sectname, buf, 16);
851 section->sectname[16] = '\0';
852 memcpy (section->segname, buf + 16, 16);
853 section->segname[16] = '\0';
854 section->addr = bfd_h_get_64 (abfd, buf + 32);
855 section->size = bfd_h_get_64 (abfd, buf + 40);
856 section->offset = bfd_h_get_32 (abfd, buf + 48);
857 section->align = bfd_h_get_32 (abfd, buf + 52);
858 section->reloff = bfd_h_get_32 (abfd, buf + 56);
859 section->nreloc = bfd_h_get_32 (abfd, buf + 60);
860 section->flags = bfd_h_get_32 (abfd, buf + 64);
861 section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
862 section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
863 section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
864 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
866 if (section->bfdsection == NULL)
867 return -1;
869 return 0;
872 static int
873 bfd_mach_o_scan_read_section (bfd *abfd,
874 bfd_mach_o_section *section,
875 bfd_vma offset,
876 unsigned int wide)
878 if (wide)
879 return bfd_mach_o_scan_read_section_64 (abfd, section, offset);
880 else
881 return bfd_mach_o_scan_read_section_32 (abfd, section, offset);
885 bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
886 bfd_mach_o_symtab_command *sym,
887 asymbol *s,
888 unsigned long i)
890 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
891 unsigned int wide = (mdata->header.version == 2);
892 unsigned int symwidth = wide ? 16 : 12;
893 bfd_vma symoff = sym->symoff + (i * symwidth);
894 unsigned char buf[16];
895 unsigned char type = -1;
896 unsigned char section = -1;
897 short desc = -1;
898 symvalue value = -1;
899 unsigned long stroff = -1;
900 unsigned int symtype = -1;
902 BFD_ASSERT (sym->strtab != NULL);
904 bfd_seek (abfd, symoff, SEEK_SET);
905 if (bfd_bread ((PTR) buf, symwidth, abfd) != symwidth)
907 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
908 symwidth, (unsigned long) symoff);
909 return -1;
912 stroff = bfd_h_get_32 (abfd, buf);
913 type = bfd_h_get_8 (abfd, buf + 4);
914 symtype = (type & 0x0e);
915 section = bfd_h_get_8 (abfd, buf + 5) - 1;
916 desc = bfd_h_get_16 (abfd, buf + 6);
917 if (wide)
918 value = bfd_h_get_64 (abfd, buf + 8);
919 else
920 value = bfd_h_get_32 (abfd, buf + 8);
922 if (stroff >= sym->strsize)
924 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
925 (unsigned long) stroff, (unsigned long) sym->strsize);
926 return -1;
929 s->the_bfd = abfd;
930 s->name = sym->strtab + stroff;
931 s->value = value;
932 s->udata.i = (type << 24) | (section << 16) | desc;
933 s->flags = 0x0;
935 if (type & BFD_MACH_O_N_STAB)
937 s->flags |= BSF_DEBUGGING;
938 s->section = bfd_und_section_ptr;
940 else
942 if (type & BFD_MACH_O_N_PEXT)
944 type &= ~BFD_MACH_O_N_PEXT;
945 s->flags |= BSF_GLOBAL;
948 if (type & BFD_MACH_O_N_EXT)
950 type &= ~BFD_MACH_O_N_EXT;
951 s->flags |= BSF_GLOBAL;
954 switch (symtype)
956 case BFD_MACH_O_N_UNDF:
957 s->section = bfd_und_section_ptr;
958 break;
959 case BFD_MACH_O_N_PBUD:
960 s->section = bfd_und_section_ptr;
961 break;
962 case BFD_MACH_O_N_ABS:
963 s->section = bfd_abs_section_ptr;
964 break;
965 case BFD_MACH_O_N_SECT:
966 if ((section > 0) && (section <= mdata->nsects))
968 s->section = mdata->sections[section]->bfdsection;
969 s->value = s->value - mdata->sections[section]->addr;
971 else
973 /* Mach-O uses 0 to mean "no section"; not an error. */
974 if (section != 0)
976 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
977 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
978 s->name, section, mdata->nsects);
980 s->section = bfd_und_section_ptr;
982 break;
983 case BFD_MACH_O_N_INDR:
984 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
985 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
986 s->name);
987 s->section = bfd_und_section_ptr;
988 break;
989 default:
990 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
991 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
992 s->name, symtype);
993 s->section = bfd_und_section_ptr;
994 break;
998 return 0;
1002 bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
1003 bfd_mach_o_symtab_command *sym)
1005 BFD_ASSERT (sym->strtab == NULL);
1007 if (abfd->flags & BFD_IN_MEMORY)
1009 struct bfd_in_memory *b;
1011 b = (struct bfd_in_memory *) abfd->iostream;
1013 if ((sym->stroff + sym->strsize) > b->size)
1015 bfd_set_error (bfd_error_file_truncated);
1016 return -1;
1018 sym->strtab = (char *) b->buffer + sym->stroff;
1019 return 0;
1022 sym->strtab = bfd_alloc (abfd, sym->strsize);
1023 if (sym->strtab == NULL)
1024 return -1;
1026 bfd_seek (abfd, sym->stroff, SEEK_SET);
1027 if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
1029 fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
1030 sym->strsize, sym->stroff);
1031 return -1;
1034 return 0;
1038 bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
1039 bfd_mach_o_symtab_command *sym)
1041 unsigned long i;
1042 int ret;
1044 BFD_ASSERT (sym->symbols == NULL);
1045 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
1047 if (sym->symbols == NULL)
1049 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
1050 return -1;
1053 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
1054 if (ret != 0)
1055 return ret;
1057 for (i = 0; i < sym->nsyms; i++)
1059 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1060 if (ret != 0)
1061 return ret;
1064 return 0;
1068 bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
1069 bfd_mach_o_dysymtab_command *dysym,
1070 bfd_mach_o_symtab_command *sym,
1071 asymbol *s,
1072 unsigned long i)
1074 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1075 unsigned long symindex;
1076 unsigned char buf[4];
1078 BFD_ASSERT (i < dysym->nindirectsyms);
1080 bfd_seek (abfd, isymoff, SEEK_SET);
1081 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
1083 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
1084 (unsigned long) 4, isymoff);
1085 return -1;
1087 symindex = bfd_h_get_32 (abfd, buf);
1089 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
1092 static const char *
1093 bfd_mach_o_i386_flavour_string (unsigned int flavour)
1095 switch ((int) flavour)
1097 case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
1098 case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
1099 case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
1100 case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
1101 case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
1102 case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
1103 case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
1104 case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
1105 case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
1106 case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
1107 case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
1108 case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
1109 default: return "UNKNOWN";
1113 static const char *
1114 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1116 switch ((int) flavour)
1118 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1119 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1120 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1121 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1122 default: return "UNKNOWN";
1126 static int
1127 bfd_mach_o_scan_read_dylinker (bfd *abfd,
1128 bfd_mach_o_load_command *command)
1130 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1131 unsigned char buf[4];
1132 unsigned int nameoff;
1133 asection *bfdsec;
1134 char *sname;
1135 const char *prefix;
1137 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1138 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1140 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1141 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
1142 return -1;
1144 nameoff = bfd_h_get_32 (abfd, buf + 0);
1146 cmd->name_offset = command->offset + nameoff;
1147 cmd->name_len = command->len - nameoff;
1149 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
1150 prefix = "LC_LOAD_DYLINKER";
1151 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
1152 prefix = "LC_ID_DYLINKER";
1153 else
1154 abort ();
1156 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1157 if (sname == NULL)
1158 return -1;
1159 strcpy (sname, prefix);
1161 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1162 if (bfdsec == NULL)
1163 return -1;
1165 bfdsec->vma = 0;
1166 bfdsec->lma = 0;
1167 bfdsec->size = command->len - 8;
1168 bfdsec->filepos = command->offset + 8;
1169 bfdsec->alignment_power = 0;
1171 cmd->section = bfdsec;
1173 return 0;
1176 static int
1177 bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1179 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1180 unsigned char buf[16];
1181 unsigned int nameoff;
1182 asection *bfdsec;
1183 char *sname;
1184 const char *prefix;
1186 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1187 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1188 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1190 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1191 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1192 return -1;
1194 nameoff = bfd_h_get_32 (abfd, buf + 0);
1195 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1196 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1197 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1199 cmd->name_offset = command->offset + nameoff;
1200 cmd->name_len = command->len - nameoff;
1202 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1203 prefix = "LC_LOAD_DYLIB";
1204 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1205 prefix = "LC_LOAD_WEAK_DYLIB";
1206 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1207 prefix = "LC_ID_DYLIB";
1208 else
1209 abort ();
1211 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1212 if (sname == NULL)
1213 return -1;
1214 strcpy (sname, prefix);
1216 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1217 if (bfdsec == NULL)
1218 return -1;
1220 bfdsec->vma = 0;
1221 bfdsec->lma = 0;
1222 bfdsec->size = command->len - 8;
1223 bfdsec->filepos = command->offset + 8;
1224 bfdsec->alignment_power = 0;
1226 cmd->section = bfdsec;
1228 return 0;
1231 static int
1232 bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1233 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1235 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1237 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1238 return 0;
1241 static int
1242 bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1244 bfd_mach_o_data_struct *mdata = NULL;
1245 bfd_mach_o_thread_command *cmd = &command->command.thread;
1246 unsigned char buf[8];
1247 bfd_vma offset;
1248 unsigned int nflavours;
1249 unsigned int i;
1251 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1252 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1254 BFD_ASSERT (bfd_mach_o_valid (abfd));
1255 mdata = abfd->tdata.mach_o_data;
1257 offset = 8;
1258 nflavours = 0;
1259 while (offset != command->len)
1261 if (offset >= command->len)
1262 return -1;
1264 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1266 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1267 return -1;
1269 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1270 nflavours++;
1273 cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
1274 if (cmd->flavours == NULL)
1275 return -1;
1276 cmd->nflavours = nflavours;
1278 offset = 8;
1279 nflavours = 0;
1280 while (offset != command->len)
1282 if (offset >= command->len)
1283 return -1;
1285 if (nflavours >= cmd->nflavours)
1286 return -1;
1288 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1290 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1291 return -1;
1293 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1294 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1295 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1296 offset += cmd->flavours[nflavours].size + 8;
1297 nflavours++;
1300 for (i = 0; i < nflavours; i++)
1302 asection *bfdsec;
1303 unsigned int snamelen;
1304 char *sname;
1305 const char *flavourstr;
1306 const char *prefix = "LC_THREAD";
1307 unsigned int j = 0;
1309 switch (mdata->header.cputype)
1311 case BFD_MACH_O_CPU_TYPE_POWERPC:
1312 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
1313 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1314 break;
1315 case BFD_MACH_O_CPU_TYPE_I386:
1316 case BFD_MACH_O_CPU_TYPE_X86_64:
1317 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1318 break;
1319 default:
1320 flavourstr = "UNKNOWN_ARCHITECTURE";
1321 break;
1324 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1325 sname = bfd_alloc (abfd, snamelen);
1326 if (sname == NULL)
1327 return -1;
1329 for (;;)
1331 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1332 if (bfd_get_section_by_name (abfd, sname) == NULL)
1333 break;
1334 j++;
1337 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1339 bfdsec->vma = 0;
1340 bfdsec->lma = 0;
1341 bfdsec->size = cmd->flavours[i].size;
1342 bfdsec->filepos = cmd->flavours[i].offset;
1343 bfdsec->alignment_power = 0x0;
1345 cmd->section = bfdsec;
1348 return 0;
1351 static int
1352 bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1354 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1355 unsigned char buf[72];
1357 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1359 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1360 if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1361 return -1;
1363 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1364 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1365 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1366 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1367 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1368 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1369 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1370 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1371 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1372 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1373 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1374 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1375 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1376 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1377 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1378 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1379 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1380 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1382 return 0;
1385 static int
1386 bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1388 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1389 unsigned char buf[16];
1390 asection *bfdsec;
1391 char *sname;
1392 const char *prefix = "LC_SYMTAB.stabs";
1393 int nlist_size = (bfd_mach_o_version (abfd) > 1) ? 16 : 12;
1395 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1397 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1398 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1399 return -1;
1401 seg->symoff = bfd_h_get_32 (abfd, buf);
1402 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1403 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1404 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1405 seg->symbols = NULL;
1406 seg->strtab = NULL;
1408 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1409 if (sname == NULL)
1410 return -1;
1411 strcpy (sname, prefix);
1413 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1414 if (bfdsec == NULL)
1415 return -1;
1417 bfdsec->vma = 0;
1418 bfdsec->lma = 0;
1419 bfdsec->size = seg->nsyms * nlist_size;
1420 bfdsec->filepos = seg->symoff;
1421 bfdsec->alignment_power = 0;
1423 seg->stabs_segment = bfdsec;
1425 prefix = "LC_SYMTAB.stabstr";
1426 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1427 if (sname == NULL)
1428 return -1;
1429 strcpy (sname, prefix);
1431 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1432 if (bfdsec == NULL)
1433 return -1;
1435 bfdsec->vma = 0;
1436 bfdsec->lma = 0;
1437 bfdsec->size = seg->strsize;
1438 bfdsec->filepos = seg->stroff;
1439 bfdsec->alignment_power = 0;
1441 seg->stabstr_segment = bfdsec;
1443 return 0;
1446 static int
1447 bfd_mach_o_scan_read_segment (bfd *abfd,
1448 bfd_mach_o_load_command *command,
1449 unsigned int wide)
1451 unsigned char buf[64];
1452 bfd_mach_o_segment_command *seg = &command->command.segment;
1453 unsigned long i;
1454 asection *bfdsec;
1455 char *sname;
1456 const char *prefix = "LC_SEGMENT";
1457 unsigned int snamelen;
1459 if (wide)
1461 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1463 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1464 if (bfd_bread ((PTR) buf, 64, abfd) != 64)
1465 return -1;
1467 memcpy (seg->segname, buf, 16);
1469 seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
1470 seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
1471 seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
1472 seg->filesize = bfd_h_get_64 (abfd, buf + 40);
1473 seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
1474 seg->initprot = bfd_h_get_32 (abfd, buf + 52);
1475 seg->nsects = bfd_h_get_32 (abfd, buf + 56);
1476 seg->flags = bfd_h_get_32 (abfd, buf + 60);
1478 else
1480 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1482 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1483 if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1484 return -1;
1486 memcpy (seg->segname, buf, 16);
1488 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1489 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1490 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1491 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
1492 seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
1493 seg->initprot = bfd_h_get_32 (abfd, buf + 36);
1494 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1495 seg->flags = bfd_h_get_32 (abfd, buf + 44);
1498 snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1499 sname = bfd_alloc (abfd, snamelen);
1500 if (sname == NULL)
1501 return -1;
1502 sprintf (sname, "%s.%s", prefix, seg->segname);
1504 bfdsec = bfd_make_section_anyway (abfd, sname);
1505 if (bfdsec == NULL)
1506 return -1;
1508 bfdsec->vma = seg->vmaddr;
1509 bfdsec->lma = seg->vmaddr;
1510 bfdsec->size = seg->filesize;
1511 bfdsec->filepos = seg->fileoff;
1512 bfdsec->alignment_power = 0x0;
1513 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1514 bfdsec->segment_mark = 1;
1516 seg->segment = bfdsec;
1518 if (seg->nsects != 0)
1520 seg->sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1521 if (seg->sections == NULL)
1522 return -1;
1524 for (i = 0; i < seg->nsects; i++)
1526 bfd_vma segoff;
1527 if (wide)
1528 segoff = command->offset + 64 + 8 + (i * 80);
1529 else
1530 segoff = command->offset + 48 + 8 + (i * 68);
1532 if (bfd_mach_o_scan_read_section
1533 (abfd, &seg->sections[i], segoff, wide) != 0)
1534 return -1;
1538 return 0;
1541 static int
1542 bfd_mach_o_scan_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1544 return bfd_mach_o_scan_read_segment (abfd, command, 0);
1547 static int
1548 bfd_mach_o_scan_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1550 return bfd_mach_o_scan_read_segment (abfd, command, 1);
1553 static int
1554 bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
1556 unsigned char buf[8];
1558 bfd_seek (abfd, command->offset, SEEK_SET);
1559 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1560 return -1;
1562 command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1563 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1564 ? 1 : 0);
1565 command->len = bfd_h_get_32 (abfd, buf + 4);
1567 switch (command->type)
1569 case BFD_MACH_O_LC_SEGMENT:
1570 if (bfd_mach_o_scan_read_segment_32 (abfd, command) != 0)
1571 return -1;
1572 break;
1573 case BFD_MACH_O_LC_SEGMENT_64:
1574 if (bfd_mach_o_scan_read_segment_64 (abfd, command) != 0)
1575 return -1;
1576 break;
1577 case BFD_MACH_O_LC_SYMTAB:
1578 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1579 return -1;
1580 break;
1581 case BFD_MACH_O_LC_SYMSEG:
1582 break;
1583 case BFD_MACH_O_LC_THREAD:
1584 case BFD_MACH_O_LC_UNIXTHREAD:
1585 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1586 return -1;
1587 break;
1588 case BFD_MACH_O_LC_LOAD_DYLINKER:
1589 case BFD_MACH_O_LC_ID_DYLINKER:
1590 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1591 return -1;
1592 break;
1593 case BFD_MACH_O_LC_LOAD_DYLIB:
1594 case BFD_MACH_O_LC_ID_DYLIB:
1595 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1596 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1597 return -1;
1598 break;
1599 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1600 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1601 return -1;
1602 break;
1603 case BFD_MACH_O_LC_LOADFVMLIB:
1604 case BFD_MACH_O_LC_IDFVMLIB:
1605 case BFD_MACH_O_LC_IDENT:
1606 case BFD_MACH_O_LC_FVMFILE:
1607 case BFD_MACH_O_LC_PREPAGE:
1608 case BFD_MACH_O_LC_ROUTINES:
1609 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1610 break;
1611 case BFD_MACH_O_LC_DYSYMTAB:
1612 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1613 return -1;
1614 break;
1615 case BFD_MACH_O_LC_SUB_UMBRELLA:
1616 case BFD_MACH_O_LC_SUB_CLIENT:
1617 case BFD_MACH_O_LC_SUB_LIBRARY:
1618 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1619 case BFD_MACH_O_LC_PREBIND_CKSUM:
1620 break;
1621 default:
1622 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1623 (unsigned long) command->type);
1624 break;
1627 return 0;
1630 static void
1631 bfd_mach_o_flatten_sections (bfd *abfd)
1633 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1634 long csect = 0;
1635 unsigned long i, j;
1637 mdata->nsects = 0;
1639 for (i = 0; i < mdata->header.ncmds; i++)
1641 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
1642 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
1644 bfd_mach_o_segment_command *seg;
1646 seg = &mdata->commands[i].command.segment;
1647 mdata->nsects += seg->nsects;
1651 mdata->sections = bfd_alloc (abfd,
1652 mdata->nsects * sizeof (bfd_mach_o_section *));
1653 csect = 0;
1655 for (i = 0; i < mdata->header.ncmds; i++)
1657 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
1658 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
1660 bfd_mach_o_segment_command *seg;
1662 seg = &mdata->commands[i].command.segment;
1663 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1665 for (j = 0; j < seg->nsects; j++)
1666 mdata->sections[csect++] = &seg->sections[j];
1672 bfd_mach_o_scan_start_address (bfd *abfd)
1674 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1675 bfd_mach_o_thread_command *cmd = NULL;
1676 unsigned long i;
1678 for (i = 0; i < mdata->header.ncmds; i++)
1680 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1681 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1683 if (cmd == NULL)
1684 cmd = &mdata->commands[i].command.thread;
1685 else
1686 return 0;
1690 if (cmd == NULL)
1691 return 0;
1693 for (i = 0; i < cmd->nflavours; i++)
1695 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1696 && (cmd->flavours[i].flavour
1697 == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1699 unsigned char buf[4];
1701 bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1703 if (bfd_bread (buf, 4, abfd) != 4)
1704 return -1;
1706 abfd->start_address = bfd_h_get_32 (abfd, buf);
1708 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1709 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1711 unsigned char buf[4];
1713 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1715 if (bfd_bread (buf, 4, abfd) != 4)
1716 return -1;
1718 abfd->start_address = bfd_h_get_32 (abfd, buf);
1720 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
1721 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE_64))
1723 unsigned char buf[8];
1725 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1727 if (bfd_bread (buf, 8, abfd) != 8)
1728 return -1;
1730 abfd->start_address = bfd_h_get_64 (abfd, buf);
1732 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
1733 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
1735 unsigned char buf[8];
1737 bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET);
1739 if (bfd_bread (buf, 8, abfd) != 8)
1740 return -1;
1742 abfd->start_address = bfd_h_get_64 (abfd, buf);
1746 return 0;
1750 bfd_mach_o_scan (bfd *abfd,
1751 bfd_mach_o_header *header,
1752 bfd_mach_o_data_struct *mdata)
1754 unsigned int i;
1755 enum bfd_architecture cputype;
1756 unsigned long cpusubtype;
1757 unsigned int hdrsize;
1759 hdrsize = (header->version == 2) ? 32 : 28;
1761 mdata->header = *header;
1762 mdata->symbols = NULL;
1764 abfd->flags = (abfd->xvec->object_flags
1765 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1766 abfd->tdata.mach_o_data = mdata;
1768 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1769 &cputype, &cpusubtype);
1770 if (cputype == bfd_arch_unknown)
1772 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1773 header->cputype, header->cpusubtype);
1774 return -1;
1777 bfd_set_arch_mach (abfd, cputype, cpusubtype);
1779 if (header->ncmds != 0)
1781 mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
1782 if (mdata->commands == NULL)
1783 return -1;
1785 for (i = 0; i < header->ncmds; i++)
1787 bfd_mach_o_load_command *cur = &mdata->commands[i];
1789 if (i == 0)
1790 cur->offset = hdrsize;
1791 else
1793 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1794 cur->offset = prev->offset + prev->len;
1797 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1798 return -1;
1802 if (bfd_mach_o_scan_start_address (abfd) < 0)
1803 return -1;
1805 bfd_mach_o_flatten_sections (abfd);
1806 return 0;
1809 bfd_boolean
1810 bfd_mach_o_mkobject (bfd *abfd)
1812 bfd_mach_o_data_struct *mdata = NULL;
1814 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
1815 if (mdata == NULL)
1816 return FALSE;
1817 abfd->tdata.mach_o_data = mdata;
1819 mdata->header.magic = 0;
1820 mdata->header.cputype = 0;
1821 mdata->header.cpusubtype = 0;
1822 mdata->header.filetype = 0;
1823 mdata->header.ncmds = 0;
1824 mdata->header.sizeofcmds = 0;
1825 mdata->header.flags = 0;
1826 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1827 mdata->commands = NULL;
1828 mdata->nsymbols = 0;
1829 mdata->symbols = NULL;
1830 mdata->nsects = 0;
1831 mdata->sections = NULL;
1832 mdata->ibfd = NULL;
1834 return TRUE;
1837 const bfd_target *
1838 bfd_mach_o_object_p (bfd *abfd)
1840 struct bfd_preserve preserve;
1841 bfd_mach_o_header header;
1843 preserve.marker = NULL;
1844 if (bfd_mach_o_read_header (abfd, &header) != 0)
1845 goto wrong;
1847 if (! (header.byteorder == BFD_ENDIAN_BIG
1848 || header.byteorder == BFD_ENDIAN_LITTLE))
1850 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1851 (unsigned long) header.byteorder);
1852 goto wrong;
1855 if (! ((header.byteorder == BFD_ENDIAN_BIG
1856 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1857 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1858 || (header.byteorder == BFD_ENDIAN_LITTLE
1859 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1860 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1861 goto wrong;
1863 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1864 if (preserve.marker == NULL
1865 || !bfd_preserve_save (abfd, &preserve))
1866 goto fail;
1868 if (bfd_mach_o_scan (abfd, &header,
1869 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1870 goto wrong;
1872 bfd_preserve_finish (abfd, &preserve);
1873 return abfd->xvec;
1875 wrong:
1876 bfd_set_error (bfd_error_wrong_format);
1878 fail:
1879 if (preserve.marker != NULL)
1880 bfd_preserve_restore (abfd, &preserve);
1881 return NULL;
1884 const bfd_target *
1885 bfd_mach_o_core_p (bfd *abfd)
1887 struct bfd_preserve preserve;
1888 bfd_mach_o_header header;
1890 preserve.marker = NULL;
1891 if (bfd_mach_o_read_header (abfd, &header) != 0)
1892 goto wrong;
1894 if (! (header.byteorder == BFD_ENDIAN_BIG
1895 || header.byteorder == BFD_ENDIAN_LITTLE))
1897 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1898 (unsigned long) header.byteorder);
1899 abort ();
1902 if (! ((header.byteorder == BFD_ENDIAN_BIG
1903 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1904 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1905 || (header.byteorder == BFD_ENDIAN_LITTLE
1906 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1907 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1908 goto wrong;
1910 if (header.filetype != BFD_MACH_O_MH_CORE)
1911 goto wrong;
1913 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1914 if (preserve.marker == NULL
1915 || !bfd_preserve_save (abfd, &preserve))
1916 goto fail;
1918 if (bfd_mach_o_scan (abfd, &header,
1919 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1920 goto wrong;
1922 bfd_preserve_finish (abfd, &preserve);
1923 return abfd->xvec;
1925 wrong:
1926 bfd_set_error (bfd_error_wrong_format);
1928 fail:
1929 if (preserve.marker != NULL)
1930 bfd_preserve_restore (abfd, &preserve);
1931 return NULL;
1934 typedef struct mach_o_fat_archentry
1936 unsigned long cputype;
1937 unsigned long cpusubtype;
1938 unsigned long offset;
1939 unsigned long size;
1940 unsigned long align;
1941 bfd *abfd;
1942 } mach_o_fat_archentry;
1944 typedef struct mach_o_fat_data_struct
1946 unsigned long magic;
1947 unsigned long nfat_arch;
1948 mach_o_fat_archentry *archentries;
1949 } mach_o_fat_data_struct;
1951 const bfd_target *
1952 bfd_mach_o_archive_p (bfd *abfd)
1954 mach_o_fat_data_struct *adata = NULL;
1955 unsigned char buf[20];
1956 unsigned long i;
1958 bfd_seek (abfd, 0, SEEK_SET);
1959 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1960 goto error;
1962 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1963 if (adata == NULL)
1964 goto error;
1966 adata->magic = bfd_getb32 (buf);
1967 adata->nfat_arch = bfd_getb32 (buf + 4);
1968 if (adata->magic != 0xcafebabe)
1969 goto error;
1971 adata->archentries =
1972 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1973 if (adata->archentries == NULL)
1974 goto error;
1976 for (i = 0; i < adata->nfat_arch; i++)
1978 bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1980 if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1981 goto error;
1982 adata->archentries[i].cputype = bfd_getb32 (buf);
1983 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1984 adata->archentries[i].offset = bfd_getb32 (buf + 8);
1985 adata->archentries[i].size = bfd_getb32 (buf + 12);
1986 adata->archentries[i].align = bfd_getb32 (buf + 16);
1987 adata->archentries[i].abfd = NULL;
1990 abfd->tdata.mach_o_fat_data = adata;
1991 return abfd->xvec;
1993 error:
1994 if (adata != NULL)
1995 bfd_release (abfd, adata);
1996 bfd_set_error (bfd_error_wrong_format);
1997 return NULL;
2000 bfd *
2001 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
2003 mach_o_fat_data_struct *adata;
2004 mach_o_fat_archentry *entry = NULL;
2005 unsigned long i;
2007 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
2008 BFD_ASSERT (adata != NULL);
2010 /* Find index of previous entry. */
2011 if (prev == NULL)
2012 i = 0; /* Start at first one. */
2013 else
2015 for (i = 0; i < adata->nfat_arch; i++)
2017 if (adata->archentries[i].abfd == prev)
2018 break;
2021 if (i == adata->nfat_arch)
2023 /* Not found. */
2024 bfd_set_error (bfd_error_bad_value);
2025 return NULL;
2027 i++; /* Get next entry. */
2030 if (i >= adata->nfat_arch)
2032 bfd_set_error (bfd_error_no_more_archived_files);
2033 return NULL;
2036 entry = &adata->archentries[i];
2037 if (entry->abfd == NULL)
2039 bfd *nbfd = _bfd_new_bfd_contained_in (archive);
2040 char *s = NULL;
2042 if (nbfd == NULL)
2043 return NULL;
2045 nbfd->origin = entry->offset;
2046 s = bfd_malloc (strlen (archive->filename) + 1);
2047 if (s == NULL)
2048 return NULL;
2049 strcpy (s, archive->filename);
2050 nbfd->filename = s;
2051 nbfd->iostream = NULL;
2052 entry->abfd = nbfd;
2055 return entry->abfd;
2059 bfd_mach_o_lookup_section (bfd *abfd,
2060 asection *section,
2061 bfd_mach_o_load_command **mcommand,
2062 bfd_mach_o_section **msection)
2064 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
2065 unsigned int i, j, num;
2067 bfd_mach_o_load_command *ncmd = NULL;
2068 bfd_mach_o_section *nsect = NULL;
2070 BFD_ASSERT (mcommand != NULL);
2071 BFD_ASSERT (msection != NULL);
2073 num = 0;
2074 for (i = 0; i < md->header.ncmds; i++)
2076 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2077 struct bfd_mach_o_segment_command *seg = NULL;
2079 if (cmd->type != BFD_MACH_O_LC_SEGMENT
2080 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
2081 continue;
2082 seg = &cmd->command.segment;
2084 if (seg->segment == section)
2086 if (num == 0)
2087 ncmd = cmd;
2088 num++;
2091 for (j = 0; j < seg->nsects; j++)
2093 struct bfd_mach_o_section *sect = &seg->sections[j];
2095 if (sect->bfdsection == section)
2097 if (num == 0)
2098 nsect = sect;
2099 num++;
2104 *mcommand = ncmd;
2105 *msection = nsect;
2106 return num;
2110 bfd_mach_o_lookup_command (bfd *abfd,
2111 bfd_mach_o_load_command_type type,
2112 bfd_mach_o_load_command **mcommand)
2114 struct mach_o_data_struct *md = NULL;
2115 bfd_mach_o_load_command *ncmd = NULL;
2116 unsigned int i, num;
2118 md = abfd->tdata.mach_o_data;
2120 BFD_ASSERT (md != NULL);
2121 BFD_ASSERT (mcommand != NULL);
2123 num = 0;
2124 for (i = 0; i < md->header.ncmds; i++)
2126 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2128 if (cmd->type != type)
2129 continue;
2131 if (num == 0)
2132 ncmd = cmd;
2133 num++;
2136 *mcommand = ncmd;
2137 return num;
2140 unsigned long
2141 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
2143 switch (type)
2145 case BFD_MACH_O_CPU_TYPE_MC680x0:
2146 return 0x04000000;
2147 case BFD_MACH_O_CPU_TYPE_MC88000:
2148 return 0xffffe000;
2149 case BFD_MACH_O_CPU_TYPE_POWERPC:
2150 return 0xc0000000;
2151 case BFD_MACH_O_CPU_TYPE_I386:
2152 return 0xc0000000;
2153 case BFD_MACH_O_CPU_TYPE_SPARC:
2154 return 0xf0000000;
2155 case BFD_MACH_O_CPU_TYPE_I860:
2156 return 0;
2157 case BFD_MACH_O_CPU_TYPE_HPPA:
2158 return 0xc0000000 - 0x04000000;
2159 default:
2160 return 0;
2165 bfd_mach_o_core_fetch_environment (bfd *abfd,
2166 unsigned char **rbuf,
2167 unsigned int *rlen)
2169 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2170 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2171 unsigned int i = 0;
2173 for (i = 0; i < mdata->header.ncmds; i++)
2175 bfd_mach_o_load_command *cur = &mdata->commands[i];
2176 bfd_mach_o_segment_command *seg = NULL;
2178 if (cur->type != BFD_MACH_O_LC_SEGMENT)
2179 continue;
2181 seg = &cur->command.segment;
2183 if ((seg->vmaddr + seg->vmsize) == stackaddr)
2185 unsigned long start = seg->fileoff;
2186 unsigned long end = seg->fileoff + seg->filesize;
2187 unsigned char *buf = bfd_malloc (1024);
2188 unsigned long size = 1024;
2190 for (;;)
2192 bfd_size_type nread = 0;
2193 unsigned long offset;
2194 int found_nonnull = 0;
2196 if (size > (end - start))
2197 size = (end - start);
2199 buf = bfd_realloc_or_free (buf, size);
2200 if (buf == NULL)
2201 return -1;
2203 bfd_seek (abfd, end - size, SEEK_SET);
2204 nread = bfd_bread (buf, size, abfd);
2206 if (nread != size)
2208 free (buf);
2209 return -1;
2212 for (offset = 4; offset <= size; offset += 4)
2214 unsigned long val;
2216 val = *((unsigned long *) (buf + size - offset));
2217 if (! found_nonnull)
2219 if (val != 0)
2220 found_nonnull = 1;
2222 else if (val == 0x0)
2224 unsigned long bottom;
2225 unsigned long top;
2227 bottom = seg->fileoff + seg->filesize - offset;
2228 top = seg->fileoff + seg->filesize - 4;
2229 *rbuf = bfd_malloc (top - bottom);
2230 *rlen = top - bottom;
2232 memcpy (*rbuf, buf + size - *rlen, *rlen);
2233 free (buf);
2234 return 0;
2238 if (size == (end - start))
2239 break;
2241 size *= 2;
2244 free (buf);
2248 return -1;
2251 char *
2252 bfd_mach_o_core_file_failing_command (bfd *abfd)
2254 unsigned char *buf = NULL;
2255 unsigned int len = 0;
2256 int ret = -1;
2258 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
2259 if (ret < 0)
2260 return NULL;
2262 return (char *) buf;
2266 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
2268 return 0;
2271 #define TARGET_NAME mach_o_be_vec
2272 #define TARGET_STRING "mach-o-be"
2273 #define TARGET_BIG_ENDIAN 1
2274 #define TARGET_ARCHIVE 0
2276 #include "mach-o-target.c"
2278 #undef TARGET_NAME
2279 #undef TARGET_STRING
2280 #undef TARGET_BIG_ENDIAN
2281 #undef TARGET_ARCHIVE
2283 #define TARGET_NAME mach_o_le_vec
2284 #define TARGET_STRING "mach-o-le"
2285 #define TARGET_BIG_ENDIAN 0
2286 #define TARGET_ARCHIVE 0
2288 #include "mach-o-target.c"
2290 #undef TARGET_NAME
2291 #undef TARGET_STRING
2292 #undef TARGET_BIG_ENDIAN
2293 #undef TARGET_ARCHIVE
2295 #define TARGET_NAME mach_o_fat_vec
2296 #define TARGET_STRING "mach-o-fat"
2297 #define TARGET_BIG_ENDIAN 1
2298 #define TARGET_ARCHIVE 1
2300 #include "mach-o-target.c"
2302 #undef TARGET_NAME
2303 #undef TARGET_STRING
2304 #undef TARGET_BIG_ENDIAN
2305 #undef TARGET_ARCHIVE