1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "libiberty.h"
29 #define BFD_IO_FUNCS 0
32 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
33 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
34 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
35 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
36 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
37 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
38 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
39 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
40 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
41 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
42 #define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup
43 #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
44 #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
45 #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
46 #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
47 #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
48 #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
49 #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
50 #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
51 #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
52 #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
53 #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
54 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
55 #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
56 #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
57 #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
58 #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
59 #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
60 #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
61 #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
62 #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
63 #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach
64 #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
65 #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
66 #define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
67 #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
68 #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
69 #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
70 #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
71 #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
73 static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data
74 PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
75 static bfd_boolean bfd_mach_o_bfd_copy_private_section_data
76 PARAMS ((bfd *, asection *, bfd *, asection *));
77 static bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data
78 PARAMS ((bfd *, bfd *));
79 static long bfd_mach_o_count_symbols
81 static long bfd_mach_o_get_symtab_upper_bound
83 static long bfd_mach_o_canonicalize_symtab
84 PARAMS ((bfd *, asymbol **));
85 static void bfd_mach_o_get_symbol_info
86 PARAMS ((bfd *, asymbol *, symbol_info *));
87 static void bfd_mach_o_print_symbol
88 PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
89 static void bfd_mach_o_convert_architecture
90 PARAMS ((bfd_mach_o_cpu_type, bfd_mach_o_cpu_subtype,
91 enum bfd_architecture *, unsigned long *));
92 static bfd_boolean bfd_mach_o_write_contents
94 static int bfd_mach_o_sizeof_headers
95 PARAMS ((bfd *, bfd_boolean));
96 static asymbol * bfd_mach_o_make_empty_symbol
98 static int bfd_mach_o_write_header
99 PARAMS ((bfd *, bfd_mach_o_header *));
100 static int bfd_mach_o_read_header
101 PARAMS ((bfd *, bfd_mach_o_header *));
102 static asection * bfd_mach_o_make_bfd_section
103 PARAMS ((bfd *, bfd_mach_o_section *));
104 static int bfd_mach_o_scan_read_section
105 PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
106 static int bfd_mach_o_scan_write_section
107 PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
108 static int bfd_mach_o_scan_write_symtab_symbols
109 PARAMS ((bfd *, bfd_mach_o_load_command *));
110 static int bfd_mach_o_scan_write_thread
111 PARAMS ((bfd *, bfd_mach_o_load_command *));
112 static int bfd_mach_o_scan_read_dylinker
113 PARAMS ((bfd *, bfd_mach_o_load_command *));
114 static int bfd_mach_o_scan_read_dylib
115 PARAMS ((bfd *, bfd_mach_o_load_command *));
116 static int bfd_mach_o_scan_read_prebound_dylib
117 PARAMS ((bfd *, bfd_mach_o_load_command *));
118 static int bfd_mach_o_scan_read_thread
119 PARAMS ((bfd *, bfd_mach_o_load_command *));
120 static int bfd_mach_o_scan_write_symtab
121 PARAMS ((bfd *, bfd_mach_o_load_command *));
122 static int bfd_mach_o_scan_read_dysymtab
123 PARAMS ((bfd *, bfd_mach_o_load_command *));
124 static int bfd_mach_o_scan_read_symtab
125 PARAMS ((bfd *, bfd_mach_o_load_command *));
126 static int bfd_mach_o_scan_read_segment
127 PARAMS ((bfd *, bfd_mach_o_load_command *));
128 static int bfd_mach_o_scan_write_segment
129 PARAMS ((bfd *, bfd_mach_o_load_command *));
130 static int bfd_mach_o_scan_read_command
131 PARAMS ((bfd *, bfd_mach_o_load_command *));
132 static void bfd_mach_o_flatten_sections
134 static const char * bfd_mach_o_i386_flavour_string
135 PARAMS ((unsigned int));
136 static const char * bfd_mach_o_ppc_flavour_string
137 PARAMS ((unsigned int));
139 /* The flags field of a section structure is separated into two parts a section
140 type and section attributes. The section types are mutually exclusive (it
141 can only have one type) but the section attributes are not (it may have more
142 than one attribute). */
144 #define SECTION_TYPE 0x000000ff /* 256 section types. */
145 #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes. */
147 /* Constants for the section attributes part of the flags field of a section
150 #define SECTION_ATTRIBUTES_USR 0xff000000 /* User-settable attributes. */
151 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* Section contains only true machine instructions. */
152 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* System setable attributes. */
153 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* Section contains some machine instructions. */
154 #define S_ATTR_EXT_RELOC 0x00000200 /* Section has external relocation entries. */
155 #define S_ATTR_LOC_RELOC 0x00000100 /* Section has local relocation entries. */
166 bfd_mach_o_valid (abfd)
169 if (abfd == NULL || abfd->xvec == NULL)
172 if (! ((abfd->xvec == &mach_o_be_vec)
173 || (abfd->xvec == &mach_o_le_vec)
174 || (abfd->xvec == &mach_o_fat_vec)))
177 if (abfd->tdata.mach_o_data == NULL)
182 /* Copy any private info we understand from the input symbol
183 to the output symbol. */
186 bfd_mach_o_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
187 bfd *ibfd ATTRIBUTE_UNUSED;
188 asymbol *isymbol ATTRIBUTE_UNUSED;
189 bfd *obfd ATTRIBUTE_UNUSED;
190 asymbol *osymbol ATTRIBUTE_UNUSED;
195 /* Copy any private info we understand from the input section
196 to the output section. */
199 bfd_mach_o_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
200 bfd *ibfd ATTRIBUTE_UNUSED;
201 asection *isection ATTRIBUTE_UNUSED;
202 bfd *obfd ATTRIBUTE_UNUSED;
203 asection *osection ATTRIBUTE_UNUSED;
208 /* Copy any private info we understand from the input bfd
209 to the output bfd. */
212 bfd_mach_o_bfd_copy_private_bfd_data (ibfd, obfd)
216 BFD_ASSERT (bfd_mach_o_valid (ibfd));
217 BFD_ASSERT (bfd_mach_o_valid (obfd));
219 obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
220 obfd->tdata.mach_o_data->ibfd = ibfd;
225 bfd_mach_o_count_symbols (abfd)
228 bfd_mach_o_data_struct *mdata = NULL;
232 BFD_ASSERT (bfd_mach_o_valid (abfd));
233 mdata = abfd->tdata.mach_o_data;
235 for (i = 0; i < mdata->header.ncmds; i++)
236 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
238 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
246 bfd_mach_o_get_symtab_upper_bound (abfd)
249 long nsyms = bfd_mach_o_count_symbols (abfd);
254 return ((nsyms + 1) * sizeof (asymbol *));
258 bfd_mach_o_canonicalize_symtab (abfd, alocation)
262 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
263 long nsyms = bfd_mach_o_count_symbols (abfd);
264 asymbol **csym = alocation;
270 for (i = 0; i < mdata->header.ncmds; i++)
272 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
274 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
276 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
278 fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
282 BFD_ASSERT (sym->symbols != NULL);
284 for (j = 0; j < sym->nsyms; j++)
286 BFD_ASSERT (csym < (alocation + nsyms));
287 *csym++ = &sym->symbols[j];
298 bfd_mach_o_get_symbol_info (abfd, symbol, ret)
299 bfd *abfd ATTRIBUTE_UNUSED;
303 bfd_symbol_info (symbol, ret);
307 bfd_mach_o_print_symbol (abfd, afile, symbol, how)
311 bfd_print_symbol_type how;
313 FILE *file = (FILE *) afile;
317 case bfd_print_symbol_name:
318 fprintf (file, "%s", symbol->name);
321 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
322 fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
327 bfd_mach_o_convert_architecture (mtype, msubtype, type, subtype)
328 bfd_mach_o_cpu_type mtype;
329 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED;
330 enum bfd_architecture *type;
331 unsigned long *subtype;
333 *subtype = bfd_arch_unknown;
337 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
338 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
339 case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
340 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
341 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
342 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
343 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
344 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
345 case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
346 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
347 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
348 case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
349 default: *type = bfd_arch_unknown; break;
354 case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
355 case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
357 *subtype = bfd_arch_unknown;
362 bfd_mach_o_write_contents (abfd)
368 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
370 /* Write data sections first in case they overlap header data to be
373 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
377 for (i = 0; i < mdata->header.ncmds; i++)
379 bfd_mach_o_load_command *cur = &mdata->commands[i];
380 if (cur->type != BFD_MACH_O_LC_SEGMENT)
384 bfd_mach_o_segment_command *seg = &cur->command.segment;
386 bfd_vma nbytes = seg->filesize;
387 bfd_vma curoff = seg->fileoff;
391 bfd_vma thisread = nbytes;
396 bfd_seek (abfd, curoff, SEEK_SET);
397 if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
400 bfd_seek (abfd, curoff, SEEK_SET);
401 if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
411 /* Now write header information. */
412 if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
415 for (i = 0; i < mdata->header.ncmds; i++)
417 unsigned char buf[8];
418 bfd_mach_o_load_command *cur = &mdata->commands[i];
419 unsigned long typeflag;
421 typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
423 bfd_h_put_32 (abfd, typeflag, buf);
424 bfd_h_put_32 (abfd, cur->len, buf + 4);
426 bfd_seek (abfd, cur->offset, SEEK_SET);
427 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
432 case BFD_MACH_O_LC_SEGMENT:
433 if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
436 case BFD_MACH_O_LC_SYMTAB:
437 if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
440 case BFD_MACH_O_LC_SYMSEG:
442 case BFD_MACH_O_LC_THREAD:
443 case BFD_MACH_O_LC_UNIXTHREAD:
444 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
447 case BFD_MACH_O_LC_LOADFVMLIB:
448 case BFD_MACH_O_LC_IDFVMLIB:
449 case BFD_MACH_O_LC_IDENT:
450 case BFD_MACH_O_LC_FVMFILE:
451 case BFD_MACH_O_LC_PREPAGE:
452 case BFD_MACH_O_LC_DYSYMTAB:
453 case BFD_MACH_O_LC_LOAD_DYLIB:
454 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
455 case BFD_MACH_O_LC_ID_DYLIB:
456 case BFD_MACH_O_LC_LOAD_DYLINKER:
457 case BFD_MACH_O_LC_ID_DYLINKER:
458 case BFD_MACH_O_LC_PREBOUND_DYLIB:
459 case BFD_MACH_O_LC_ROUTINES:
460 case BFD_MACH_O_LC_SUB_FRAMEWORK:
464 "unable to write unknown load command 0x%lx\n",
474 bfd_mach_o_sizeof_headers (a, b)
475 bfd *a ATTRIBUTE_UNUSED;
476 bfd_boolean b ATTRIBUTE_UNUSED;
481 /* Make an empty symbol. This is required only because
482 bfd_make_section_anyway wants to create a symbol for the section. */
485 bfd_mach_o_make_empty_symbol (abfd)
490 new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
498 bfd_mach_o_write_header (abfd, header)
500 bfd_mach_o_header *header;
502 unsigned char buf[28];
504 bfd_h_put_32 (abfd, header->magic, buf + 0);
505 bfd_h_put_32 (abfd, header->cputype, buf + 4);
506 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
507 bfd_h_put_32 (abfd, header->filetype, buf + 12);
508 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
509 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
510 bfd_h_put_32 (abfd, header->flags, buf + 24);
512 bfd_seek (abfd, 0, SEEK_SET);
513 if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
520 bfd_mach_o_read_header (abfd, header)
522 bfd_mach_o_header *header;
524 unsigned char buf[28];
525 bfd_vma (*get32) PARAMS ((const bfd_byte *)) = NULL;
527 bfd_seek (abfd, 0, SEEK_SET);
529 if (bfd_bread ((PTR) buf, 28, abfd) != 28)
532 if (bfd_getb32 (buf) == 0xfeedface)
534 header->byteorder = BFD_ENDIAN_BIG;
535 header->magic = 0xfeedface;
538 else if (bfd_getl32 (buf) == 0xfeedface)
540 header->byteorder = BFD_ENDIAN_LITTLE;
541 header->magic = 0xfeedface;
546 header->byteorder = BFD_ENDIAN_UNKNOWN;
550 header->cputype = (*get32) (buf + 4);
551 header->cpusubtype = (*get32) (buf + 8);
552 header->filetype = (*get32) (buf + 12);
553 header->ncmds = (*get32) (buf + 16);
554 header->sizeofcmds = (*get32) (buf + 20);
555 header->flags = (*get32) (buf + 24);
561 bfd_mach_o_make_bfd_section (abfd, section)
563 bfd_mach_o_section *section;
567 const char *prefix = "LC_SEGMENT";
568 unsigned int snamelen;
570 snamelen = strlen (prefix) + 1
571 + strlen (section->segname) + 1
572 + strlen (section->sectname) + 1;
574 sname = (char *) bfd_alloc (abfd, snamelen);
577 sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
579 bfdsec = bfd_make_section_anyway (abfd, sname);
583 bfdsec->vma = section->addr;
584 bfdsec->lma = section->addr;
585 bfdsec->_raw_size = section->size;
586 bfdsec->filepos = section->offset;
587 bfdsec->alignment_power = section->align;
589 if (section->flags & BFD_MACH_O_S_ZEROFILL)
590 bfdsec->flags = SEC_ALLOC;
592 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
598 bfd_mach_o_scan_read_section (abfd, section, offset)
600 bfd_mach_o_section *section;
603 unsigned char buf[68];
605 bfd_seek (abfd, offset, SEEK_SET);
606 if (bfd_bread ((PTR) buf, 68, abfd) != 68)
609 memcpy (section->sectname, buf, 16);
610 section->sectname[16] = '\0';
611 memcpy (section->segname, buf + 16, 16);
612 section->segname[16] = '\0';
613 section->addr = bfd_h_get_32 (abfd, buf + 32);
614 section->size = bfd_h_get_32 (abfd, buf + 36);
615 section->offset = bfd_h_get_32 (abfd, buf + 40);
616 section->align = bfd_h_get_32 (abfd, buf + 44);
617 section->reloff = bfd_h_get_32 (abfd, buf + 48);
618 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
619 section->flags = bfd_h_get_32 (abfd, buf + 56);
620 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
621 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
622 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
624 if (section->bfdsection == NULL)
631 bfd_mach_o_scan_write_section (abfd, section, offset)
633 bfd_mach_o_section *section;
636 unsigned char buf[68];
638 memcpy (buf, section->sectname, 16);
639 memcpy (buf + 16, section->segname, 16);
640 bfd_h_put_32 (abfd, section->addr, buf + 32);
641 bfd_h_put_32 (abfd, section->size, buf + 36);
642 bfd_h_put_32 (abfd, section->offset, buf + 40);
643 bfd_h_put_32 (abfd, section->align, buf + 44);
644 bfd_h_put_32 (abfd, section->reloff, buf + 48);
645 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
646 bfd_h_put_32 (abfd, section->flags, buf + 56);
647 /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
648 /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
650 bfd_seek (abfd, offset, SEEK_SET);
651 if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
658 bfd_mach_o_scan_write_symtab_symbols (abfd, command)
660 bfd_mach_o_load_command *command;
662 bfd_mach_o_symtab_command *sym = &command->command.symtab;
666 for (i = 0; i < sym->nsyms; i++)
668 unsigned char buf[12];
669 bfd_vma symoff = sym->symoff + (i * 12);
670 unsigned char ntype = 0;
671 unsigned char nsect = 0;
674 s = &sym->symbols[i];
676 /* Don't set this from the symbol information; use stored values. */
678 if (s->flags & BSF_GLOBAL)
680 if (s->flags & BSF_DEBUGGING)
683 if (s->section == bfd_und_section_ptr)
685 else if (s->section == bfd_abs_section_ptr)
691 /* Instead just set from the stored values. */
692 ntype = (s->udata.i >> 24) & 0xff;
693 nsect = (s->udata.i >> 16) & 0xff;
694 ndesc = s->udata.i & 0xffff;
696 bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
697 bfd_h_put_8 (abfd, ntype, buf + 4);
698 bfd_h_put_8 (abfd, nsect, buf + 5);
699 bfd_h_put_16 (abfd, ndesc, buf + 6);
700 bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
702 bfd_seek (abfd, symoff, SEEK_SET);
703 if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
705 fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
706 12, (unsigned long) symoff);
715 bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)
717 bfd_mach_o_symtab_command *sym;
721 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
722 bfd_vma symoff = sym->symoff + (i * 12);
723 unsigned char buf[12];
724 unsigned char type = -1;
725 unsigned char section = -1;
727 unsigned long value = -1;
728 unsigned long stroff = -1;
729 unsigned int symtype = -1;
731 BFD_ASSERT (sym->strtab != NULL);
733 bfd_seek (abfd, symoff, SEEK_SET);
734 if (bfd_bread ((PTR) buf, 12, abfd) != 12)
736 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
737 12, (unsigned long) symoff);
741 stroff = bfd_h_get_32 (abfd, buf);
742 type = bfd_h_get_8 (abfd, buf + 4);
743 symtype = (type & 0x0e);
744 section = bfd_h_get_8 (abfd, buf + 5) - 1;
745 desc = bfd_h_get_16 (abfd, buf + 6);
746 value = bfd_h_get_32 (abfd, buf + 8);
748 if (stroff >= sym->strsize)
750 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
751 (unsigned long) stroff, (unsigned long) sym->strsize);
756 s->name = sym->strtab + stroff;
758 s->udata.i = (type << 24) | (section << 16) | desc;
761 if (type & BFD_MACH_O_N_STAB)
763 s->flags |= BSF_DEBUGGING;
764 s->section = bfd_und_section_ptr;
768 if (type & BFD_MACH_O_N_PEXT)
770 type &= ~BFD_MACH_O_N_PEXT;
771 s->flags |= BSF_GLOBAL;
774 if (type & BFD_MACH_O_N_EXT)
776 type &= ~BFD_MACH_O_N_EXT;
777 s->flags |= BSF_GLOBAL;
782 case BFD_MACH_O_N_UNDF:
783 s->section = bfd_und_section_ptr;
785 case BFD_MACH_O_N_PBUD:
786 s->section = bfd_und_section_ptr;
788 case BFD_MACH_O_N_ABS:
789 s->section = bfd_abs_section_ptr;
791 case BFD_MACH_O_N_SECT:
792 if ((section > 0) && (section <= mdata->nsects))
794 s->section = mdata->sections[section - 1]->bfdsection;
795 s->value = s->value - mdata->sections[section - 1]->addr;
799 /* Mach-O uses 0 to mean "no section"; not an error. */
802 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
803 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
804 s->name, section, mdata->nsects);
806 s->section = bfd_und_section_ptr;
809 case BFD_MACH_O_N_INDR:
810 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
811 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
813 s->section = bfd_und_section_ptr;
816 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
817 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
819 s->section = bfd_und_section_ptr;
828 bfd_mach_o_scan_read_symtab_strtab (abfd, sym)
830 bfd_mach_o_symtab_command *sym;
832 BFD_ASSERT (sym->strtab == NULL);
834 if (abfd->flags & BFD_IN_MEMORY)
836 struct bfd_in_memory *b;
838 b = (struct bfd_in_memory *) abfd->iostream;
840 if ((sym->stroff + sym->strsize) > b->size)
842 bfd_set_error (bfd_error_file_truncated);
845 sym->strtab = b->buffer + sym->stroff;
849 sym->strtab = bfd_alloc (abfd, sym->strsize);
850 if (sym->strtab == NULL)
853 bfd_seek (abfd, sym->stroff, SEEK_SET);
854 if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
856 fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
857 sym->strsize, sym->stroff);
865 bfd_mach_o_scan_read_symtab_symbols (abfd, sym)
867 bfd_mach_o_symtab_command *sym;
872 BFD_ASSERT (sym->symbols == NULL);
873 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
875 if (sym->symbols == NULL)
877 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
881 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
885 for (i = 0; i < sym->nsyms; i++)
887 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
896 bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, s, i)
898 bfd_mach_o_dysymtab_command *dysym;
899 bfd_mach_o_symtab_command *sym;
903 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
904 unsigned long symindex;
905 unsigned char buf[4];
907 BFD_ASSERT (i < dysym->nindirectsyms);
909 bfd_seek (abfd, isymoff, SEEK_SET);
910 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
912 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
913 (unsigned long) 4, isymoff);
916 symindex = bfd_h_get_32 (abfd, buf);
918 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
922 bfd_mach_o_i386_flavour_string (flavour)
923 unsigned int flavour;
925 switch ((int) flavour)
927 case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
928 case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
929 case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
930 case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
931 case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
932 case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
933 case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
934 case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
935 case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
936 case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
937 case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
938 case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
939 default: return "UNKNOWN";
944 bfd_mach_o_ppc_flavour_string (flavour)
945 unsigned int flavour;
947 switch ((int) flavour)
949 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
950 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
951 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
952 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
953 default: return "UNKNOWN";
958 bfd_mach_o_scan_write_thread (abfd, command)
960 bfd_mach_o_load_command *command;
962 bfd_mach_o_thread_command *cmd = &command->command.thread;
964 unsigned char buf[8];
966 unsigned int nflavours;
968 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
969 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
973 for (i = 0; i < cmd->nflavours; i++)
975 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
976 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
978 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
979 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
981 bfd_seek (abfd, command->offset + offset, SEEK_SET);
982 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
985 offset += cmd->flavours[i].size + 8;
992 bfd_mach_o_scan_read_dylinker (abfd, command)
994 bfd_mach_o_load_command *command;
996 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
997 unsigned char buf[4];
998 unsigned int nameoff;
1003 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1004 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1006 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1007 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
1010 nameoff = bfd_h_get_32 (abfd, buf + 0);
1012 cmd->name_offset = command->offset + nameoff;
1013 cmd->name_len = command->len - nameoff;
1015 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
1016 prefix = "LC_LOAD_DYLINKER";
1017 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
1018 prefix = "LC_ID_DYLINKER";
1022 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1025 strcpy (sname, prefix);
1027 bfdsec = bfd_make_section_anyway (abfd, sname);
1033 bfdsec->_raw_size = command->len - 8;
1034 bfdsec->filepos = command->offset + 8;
1035 bfdsec->alignment_power = 0;
1036 bfdsec->flags = SEC_HAS_CONTENTS;
1038 cmd->section = bfdsec;
1044 bfd_mach_o_scan_read_dylib (abfd, command)
1046 bfd_mach_o_load_command *command;
1048 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1049 unsigned char buf[16];
1050 unsigned int nameoff;
1055 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1056 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1057 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1059 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1060 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1063 nameoff = bfd_h_get_32 (abfd, buf + 0);
1064 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1065 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1066 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1068 cmd->name_offset = command->offset + nameoff;
1069 cmd->name_len = command->len - nameoff;
1071 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1072 prefix = "LC_LOAD_DYLIB";
1073 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1074 prefix = "LC_LOAD_WEAK_DYLIB";
1075 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1076 prefix = "LC_ID_DYLIB";
1080 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1083 strcpy (sname, prefix);
1085 bfdsec = bfd_make_section_anyway (abfd, sname);
1091 bfdsec->_raw_size = command->len - 8;
1092 bfdsec->filepos = command->offset + 8;
1093 bfdsec->alignment_power = 0;
1094 bfdsec->flags = SEC_HAS_CONTENTS;
1096 cmd->section = bfdsec;
1102 bfd_mach_o_scan_read_prebound_dylib (abfd, command)
1103 bfd *abfd ATTRIBUTE_UNUSED;
1104 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED;
1106 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1108 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1113 bfd_mach_o_scan_read_thread (abfd, command)
1115 bfd_mach_o_load_command *command;
1117 bfd_mach_o_data_struct *mdata = NULL;
1118 bfd_mach_o_thread_command *cmd = &command->command.thread;
1119 unsigned char buf[8];
1121 unsigned int nflavours;
1124 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1125 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1127 BFD_ASSERT (bfd_mach_o_valid (abfd));
1128 mdata = abfd->tdata.mach_o_data;
1132 while (offset != command->len)
1134 if (offset >= command->len)
1137 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1139 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1142 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1147 ((bfd_mach_o_thread_flavour *)
1148 bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour)));
1149 if (cmd->flavours == NULL)
1151 cmd->nflavours = nflavours;
1155 while (offset != command->len)
1157 if (offset >= command->len)
1160 if (nflavours >= cmd->nflavours)
1163 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1165 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1168 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1169 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1170 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1171 offset += cmd->flavours[nflavours].size + 8;
1175 for (i = 0; i < nflavours; i++)
1178 unsigned int snamelen;
1180 const char *flavourstr;
1181 const char *prefix = "LC_THREAD";
1184 switch (mdata->header.cputype)
1186 case BFD_MACH_O_CPU_TYPE_POWERPC:
1187 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1189 case BFD_MACH_O_CPU_TYPE_I386:
1190 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1193 flavourstr = "UNKNOWN_ARCHITECTURE";
1197 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1198 sname = (char *) bfd_alloc (abfd, snamelen);
1204 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1205 if (bfd_get_section_by_name (abfd, sname) == NULL)
1210 bfdsec = bfd_make_section (abfd, sname);
1214 bfdsec->_raw_size = cmd->flavours[i].size;
1215 bfdsec->filepos = cmd->flavours[i].offset;
1216 bfdsec->alignment_power = 0x0;
1217 bfdsec->flags = SEC_HAS_CONTENTS;
1219 cmd->section = bfdsec;
1226 bfd_mach_o_scan_write_symtab (abfd, command)
1228 bfd_mach_o_load_command *command;
1230 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1231 unsigned char buf[16];
1233 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1235 bfd_h_put_32 (abfd, seg->symoff, buf);
1236 bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
1237 bfd_h_put_32 (abfd, seg->stroff, buf + 8);
1238 bfd_h_put_32 (abfd, seg->strsize, buf + 12);
1240 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1241 if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
1244 if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
1251 bfd_mach_o_scan_read_dysymtab (abfd, command)
1253 bfd_mach_o_load_command *command;
1255 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1256 unsigned char buf[72];
1258 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1260 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1261 if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1264 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1265 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1266 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1267 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1268 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1269 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1270 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1271 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1272 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1273 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1274 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1275 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1276 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1277 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1278 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1279 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1280 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1281 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1287 bfd_mach_o_scan_read_symtab (abfd, command)
1289 bfd_mach_o_load_command *command;
1291 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1292 unsigned char buf[16];
1295 const char *prefix = "LC_SYMTAB.stabs";
1297 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1299 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1300 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1303 seg->symoff = bfd_h_get_32 (abfd, buf);
1304 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1305 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1306 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1307 seg->symbols = NULL;
1310 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1313 strcpy (sname, prefix);
1315 bfdsec = bfd_make_section_anyway (abfd, sname);
1321 bfdsec->_raw_size = seg->nsyms * 12;
1322 bfdsec->filepos = seg->symoff;
1323 bfdsec->alignment_power = 0;
1324 bfdsec->flags = SEC_HAS_CONTENTS;
1326 seg->stabs_segment = bfdsec;
1328 prefix = "LC_SYMTAB.stabstr";
1329 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1332 strcpy (sname, prefix);
1334 bfdsec = bfd_make_section_anyway (abfd, sname);
1340 bfdsec->_raw_size = seg->strsize;
1341 bfdsec->filepos = seg->stroff;
1342 bfdsec->alignment_power = 0;
1343 bfdsec->flags = SEC_HAS_CONTENTS;
1345 seg->stabstr_segment = bfdsec;
1351 bfd_mach_o_scan_read_segment (abfd, command)
1353 bfd_mach_o_load_command *command;
1355 unsigned char buf[48];
1356 bfd_mach_o_segment_command *seg = &command->command.segment;
1360 const char *prefix = "LC_SEGMENT";
1361 unsigned int snamelen;
1363 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1365 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1366 if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1369 memcpy (seg->segname, buf, 16);
1370 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1371 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1372 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1373 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
1374 /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1375 /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1376 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1377 seg->flags = bfd_h_get_32 (abfd, buf + 44);
1379 snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1380 sname = (char *) bfd_alloc (abfd, snamelen);
1383 sprintf (sname, "%s.%s", prefix, seg->segname);
1385 bfdsec = bfd_make_section_anyway (abfd, sname);
1389 bfdsec->vma = seg->vmaddr;
1390 bfdsec->lma = seg->vmaddr;
1391 bfdsec->_raw_size = seg->filesize;
1392 bfdsec->filepos = seg->fileoff;
1393 bfdsec->alignment_power = 0x0;
1394 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1396 seg->segment = bfdsec;
1398 if (seg->nsects != 0)
1401 ((bfd_mach_o_section *)
1402 bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)));
1403 if (seg->sections == NULL)
1406 for (i = 0; i < seg->nsects; i++)
1408 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1410 if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1420 bfd_mach_o_scan_write_segment (abfd, command)
1422 bfd_mach_o_load_command *command;
1424 unsigned char buf[48];
1425 bfd_mach_o_segment_command *seg = &command->command.segment;
1428 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1430 memcpy (buf, seg->segname, 16);
1431 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
1432 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
1433 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
1434 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
1435 bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
1436 bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
1437 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
1438 bfd_h_put_32 (abfd, seg->flags, buf + 44);
1440 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1441 if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
1446 bfd_vma nbytes = seg->filesize;
1447 bfd_vma curoff = seg->fileoff;
1451 bfd_vma thisread = nbytes;
1453 if (thisread > 1024)
1456 bfd_seek (abfd, curoff, SEEK_SET);
1457 if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
1460 bfd_seek (abfd, curoff, SEEK_SET);
1461 if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
1469 for (i = 0; i < seg->nsects; i++)
1471 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1473 if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
1481 bfd_mach_o_scan_read_command (abfd, command)
1483 bfd_mach_o_load_command *command;
1485 unsigned char buf[8];
1487 bfd_seek (abfd, command->offset, SEEK_SET);
1488 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1491 command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1492 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1494 command->len = bfd_h_get_32 (abfd, buf + 4);
1496 switch (command->type)
1498 case BFD_MACH_O_LC_SEGMENT:
1499 if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1502 case BFD_MACH_O_LC_SYMTAB:
1503 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1506 case BFD_MACH_O_LC_SYMSEG:
1508 case BFD_MACH_O_LC_THREAD:
1509 case BFD_MACH_O_LC_UNIXTHREAD:
1510 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1513 case BFD_MACH_O_LC_LOAD_DYLINKER:
1514 case BFD_MACH_O_LC_ID_DYLINKER:
1515 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1518 case BFD_MACH_O_LC_LOAD_DYLIB:
1519 case BFD_MACH_O_LC_ID_DYLIB:
1520 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1521 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1524 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1525 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1528 case BFD_MACH_O_LC_LOADFVMLIB:
1529 case BFD_MACH_O_LC_IDFVMLIB:
1530 case BFD_MACH_O_LC_IDENT:
1531 case BFD_MACH_O_LC_FVMFILE:
1532 case BFD_MACH_O_LC_PREPAGE:
1533 case BFD_MACH_O_LC_ROUTINES:
1534 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1536 case BFD_MACH_O_LC_DYSYMTAB:
1537 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1540 case BFD_MACH_O_LC_SUB_UMBRELLA:
1541 case BFD_MACH_O_LC_SUB_CLIENT:
1542 case BFD_MACH_O_LC_SUB_LIBRARY:
1543 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1544 case BFD_MACH_O_LC_PREBIND_CKSUM:
1547 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1548 (unsigned long) command->type);
1556 bfd_mach_o_flatten_sections (abfd)
1559 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1565 for (i = 0; i < mdata->header.ncmds; i++)
1567 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1569 bfd_mach_o_segment_command *seg;
1571 seg = &mdata->commands[i].command.segment;
1572 mdata->nsects += seg->nsects;
1576 mdata->sections = bfd_alloc (abfd,
1577 mdata->nsects * sizeof (bfd_mach_o_section *));
1580 for (i = 0; i < mdata->header.ncmds; i++)
1582 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1584 bfd_mach_o_segment_command *seg;
1586 seg = &mdata->commands[i].command.segment;
1587 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1589 for (j = 0; j < seg->nsects; j++)
1590 mdata->sections[csect++] = &seg->sections[j];
1596 bfd_mach_o_scan_start_address (abfd)
1599 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1600 bfd_mach_o_thread_command *cmd = NULL;
1603 for (i = 0; i < mdata->header.ncmds; i++)
1605 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1606 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1609 cmd = &mdata->commands[i].command.thread;
1618 for (i = 0; i < cmd->nflavours; i++)
1620 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1621 && (cmd->flavours[i].flavour
1622 == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1624 unsigned char buf[4];
1626 bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1628 if (bfd_bread (buf, 4, abfd) != 4)
1631 abfd->start_address = bfd_h_get_32 (abfd, buf);
1633 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1634 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1636 unsigned char buf[4];
1638 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1640 if (bfd_bread (buf, 4, abfd) != 4)
1643 abfd->start_address = bfd_h_get_32 (abfd, buf);
1651 bfd_mach_o_scan (abfd, header, mdata)
1653 bfd_mach_o_header *header;
1654 bfd_mach_o_data_struct *mdata;
1657 enum bfd_architecture cputype;
1658 unsigned long cpusubtype;
1660 mdata->header = *header;
1661 mdata->symbols = NULL;
1663 abfd->flags = (abfd->xvec->object_flags
1664 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1665 abfd->tdata.mach_o_data = mdata;
1667 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1668 &cputype, &cpusubtype);
1669 if (cputype == bfd_arch_unknown)
1671 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1672 header->cputype, header->cpusubtype);
1676 bfd_set_arch_mach (abfd, cputype, cpusubtype);
1678 if (header->ncmds != 0)
1681 ((bfd_mach_o_load_command *)
1682 bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));
1683 if (mdata->commands == NULL)
1686 for (i = 0; i < header->ncmds; i++)
1688 bfd_mach_o_load_command *cur = &mdata->commands[i];
1694 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1695 cur->offset = prev->offset + prev->len;
1698 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1703 if (bfd_mach_o_scan_start_address (abfd) < 0)
1706 fprintf (stderr, "bfd_mach_o_scan: unable to scan start address: %s\n",
1707 bfd_errmsg (bfd_get_error ()));
1708 abfd->tdata.mach_o_data = NULL;
1713 bfd_mach_o_flatten_sections (abfd);
1719 bfd_mach_o_mkobject (abfd)
1722 bfd_mach_o_data_struct *mdata = NULL;
1724 mdata = ((bfd_mach_o_data_struct *)
1725 bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
1728 abfd->tdata.mach_o_data = mdata;
1730 mdata->header.magic = 0;
1731 mdata->header.cputype = 0;
1732 mdata->header.cpusubtype = 0;
1733 mdata->header.filetype = 0;
1734 mdata->header.ncmds = 0;
1735 mdata->header.sizeofcmds = 0;
1736 mdata->header.flags = 0;
1737 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1738 mdata->commands = NULL;
1739 mdata->nsymbols = 0;
1740 mdata->symbols = NULL;
1742 mdata->sections = NULL;
1749 bfd_mach_o_object_p (abfd)
1752 struct bfd_preserve preserve;
1753 bfd_mach_o_header header;
1755 preserve.marker = NULL;
1756 if (bfd_mach_o_read_header (abfd, &header) != 0)
1759 if (! (header.byteorder == BFD_ENDIAN_BIG
1760 || header.byteorder == BFD_ENDIAN_LITTLE))
1762 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1763 (long) header.byteorder);
1767 if (! ((header.byteorder == BFD_ENDIAN_BIG
1768 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1769 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1770 || (header.byteorder == BFD_ENDIAN_LITTLE
1771 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1772 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1775 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1776 if (preserve.marker == NULL
1777 || !bfd_preserve_save (abfd, &preserve))
1780 if (bfd_mach_o_scan (abfd, &header,
1781 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1784 bfd_preserve_finish (abfd, &preserve);
1788 bfd_set_error (bfd_error_wrong_format);
1791 if (preserve.marker != NULL)
1792 bfd_preserve_restore (abfd, &preserve);
1797 bfd_mach_o_core_p (abfd)
1800 struct bfd_preserve preserve;
1801 bfd_mach_o_header header;
1803 preserve.marker = NULL;
1804 if (bfd_mach_o_read_header (abfd, &header) != 0)
1807 if (! (header.byteorder == BFD_ENDIAN_BIG
1808 || header.byteorder == BFD_ENDIAN_LITTLE))
1810 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1811 (long) header.byteorder);
1815 if (! ((header.byteorder == BFD_ENDIAN_BIG
1816 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1817 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1818 || (header.byteorder == BFD_ENDIAN_LITTLE
1819 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1820 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1823 if (header.filetype != BFD_MACH_O_MH_CORE)
1826 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1827 if (preserve.marker == NULL
1828 || !bfd_preserve_save (abfd, &preserve))
1831 if (bfd_mach_o_scan (abfd, &header,
1832 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1835 bfd_preserve_finish (abfd, &preserve);
1839 bfd_set_error (bfd_error_wrong_format);
1842 if (preserve.marker != NULL)
1843 bfd_preserve_restore (abfd, &preserve);
1847 typedef struct mach_o_fat_archentry
1849 unsigned long cputype;
1850 unsigned long cpusubtype;
1851 unsigned long offset;
1853 unsigned long align;
1855 } mach_o_fat_archentry;
1857 typedef struct mach_o_fat_data_struct
1859 unsigned long magic;
1860 unsigned long nfat_arch;
1861 mach_o_fat_archentry *archentries;
1862 } mach_o_fat_data_struct;
1865 bfd_mach_o_archive_p (abfd)
1868 mach_o_fat_data_struct *adata = NULL;
1869 unsigned char buf[20];
1872 bfd_seek (abfd, 0, SEEK_SET);
1873 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1876 adata = (mach_o_fat_data_struct *)
1877 bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1881 adata->magic = bfd_getb32 (buf);
1882 adata->nfat_arch = bfd_getb32 (buf + 4);
1883 if (adata->magic != 0xcafebabe)
1886 adata->archentries = (mach_o_fat_archentry *)
1887 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1888 if (adata->archentries == NULL)
1891 for (i = 0; i < adata->nfat_arch; i++)
1893 bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1895 if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1897 adata->archentries[i].cputype = bfd_getb32 (buf);
1898 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1899 adata->archentries[i].offset = bfd_getb32 (buf + 8);
1900 adata->archentries[i].size = bfd_getb32 (buf + 12);
1901 adata->archentries[i].align = bfd_getb32 (buf + 16);
1902 adata->archentries[i].abfd = NULL;
1905 abfd->tdata.mach_o_fat_data = adata;
1910 bfd_release (abfd, adata);
1911 bfd_set_error (bfd_error_wrong_format);
1916 bfd_mach_o_openr_next_archived_file (archive, prev)
1920 mach_o_fat_data_struct *adata;
1921 mach_o_fat_archentry *entry = NULL;
1924 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
1925 BFD_ASSERT (adata != NULL);
1927 /* Find index of previous entry. */
1929 i = 0; /* Start at first one. */
1932 for (i = 0; i < adata->nfat_arch; i++)
1934 if (adata->archentries[i].abfd == prev)
1938 if (i == adata->nfat_arch)
1941 bfd_set_error (bfd_error_bad_value);
1944 i++; /* Get next entry. */
1947 if (i >= adata->nfat_arch)
1949 bfd_set_error (bfd_error_no_more_archived_files);
1953 entry = &adata->archentries[i];
1954 if (entry->abfd == NULL)
1956 bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1962 nbfd->origin = entry->offset;
1963 s = bfd_malloc (strlen (archive->filename) + 1);
1966 strcpy (s, archive->filename);
1968 nbfd->iostream = NULL;
1976 bfd_mach_o_lookup_section (abfd, section, mcommand, msection)
1979 bfd_mach_o_load_command **mcommand;
1980 bfd_mach_o_section **msection;
1982 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1983 unsigned int i, j, num;
1985 bfd_mach_o_load_command *ncmd = NULL;
1986 bfd_mach_o_section *nsect = NULL;
1988 BFD_ASSERT (mcommand != NULL);
1989 BFD_ASSERT (msection != NULL);
1992 for (i = 0; i < md->header.ncmds; i++)
1994 struct bfd_mach_o_load_command *cmd = &md->commands[i];
1995 struct bfd_mach_o_segment_command *seg = NULL;
1997 if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1999 seg = &cmd->command.segment;
2001 if (seg->segment == section)
2008 for (j = 0; j < seg->nsects; j++)
2010 struct bfd_mach_o_section *sect = &seg->sections[j];
2012 if (sect->bfdsection == section)
2027 bfd_mach_o_lookup_command (abfd, type, mcommand)
2029 bfd_mach_o_load_command_type type;
2030 bfd_mach_o_load_command **mcommand;
2032 struct mach_o_data_struct *md = NULL;
2033 bfd_mach_o_load_command *ncmd = NULL;
2034 unsigned int i, num;
2036 md = abfd->tdata.mach_o_data;
2038 BFD_ASSERT (md != NULL);
2039 BFD_ASSERT (mcommand != NULL);
2042 for (i = 0; i < md->header.ncmds; i++)
2044 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2046 if (cmd->type != type)
2059 bfd_mach_o_stack_addr (type)
2060 enum bfd_mach_o_cpu_type type;
2064 case BFD_MACH_O_CPU_TYPE_MC680x0:
2066 case BFD_MACH_O_CPU_TYPE_MC88000:
2068 case BFD_MACH_O_CPU_TYPE_POWERPC:
2070 case BFD_MACH_O_CPU_TYPE_I386:
2072 case BFD_MACH_O_CPU_TYPE_SPARC:
2074 case BFD_MACH_O_CPU_TYPE_I860:
2076 case BFD_MACH_O_CPU_TYPE_HPPA:
2077 return 0xc0000000 - 0x04000000;
2084 bfd_mach_o_core_fetch_environment (abfd, rbuf, rlen)
2086 unsigned char **rbuf;
2089 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2090 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2093 for (i = 0; i < mdata->header.ncmds; i++)
2095 bfd_mach_o_load_command *cur = &mdata->commands[i];
2096 bfd_mach_o_segment_command *seg = NULL;
2098 if (cur->type != BFD_MACH_O_LC_SEGMENT)
2101 seg = &cur->command.segment;
2103 if ((seg->vmaddr + seg->vmsize) == stackaddr)
2105 unsigned long start = seg->fileoff;
2106 unsigned long end = seg->fileoff + seg->filesize;
2107 unsigned char *buf = bfd_malloc (1024);
2108 unsigned long size = 1024;
2112 bfd_size_type nread = 0;
2113 unsigned long offset;
2114 int found_nonnull = 0;
2116 if (size > (end - start))
2117 size = (end - start);
2119 buf = bfd_realloc (buf, size);
2121 bfd_seek (abfd, end - size, SEEK_SET);
2122 nread = bfd_bread (buf, size, abfd);
2127 for (offset = 4; offset <= size; offset += 4)
2131 val = *((unsigned long *) (buf + size - offset));
2132 if (! found_nonnull)
2137 else if (val == 0x0)
2139 unsigned long bottom;
2142 bottom = seg->fileoff + seg->filesize - offset;
2143 top = seg->fileoff + seg->filesize - 4;
2144 *rbuf = bfd_malloc (top - bottom);
2145 *rlen = top - bottom;
2147 memcpy (*rbuf, buf + size - *rlen, *rlen);
2152 if (size == (end - start))
2164 bfd_mach_o_core_file_failing_command (abfd)
2167 unsigned char *buf = NULL;
2168 unsigned int len = 0;
2171 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
2179 bfd_mach_o_core_file_failing_signal (abfd)
2180 bfd *abfd ATTRIBUTE_UNUSED;
2186 bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)
2187 bfd *core_bfd ATTRIBUTE_UNUSED;
2188 bfd *exec_bfd ATTRIBUTE_UNUSED;
2193 #define TARGET_NAME mach_o_be_vec
2194 #define TARGET_STRING "mach-o-be"
2195 #define TARGET_BIG_ENDIAN 1
2196 #define TARGET_ARCHIVE 0
2198 #include "mach-o-target.c"
2201 #undef TARGET_STRING
2202 #undef TARGET_BIG_ENDIAN
2203 #undef TARGET_ARCHIVE
2205 #define TARGET_NAME mach_o_le_vec
2206 #define TARGET_STRING "mach-o-le"
2207 #define TARGET_BIG_ENDIAN 0
2208 #define TARGET_ARCHIVE 0
2210 #include "mach-o-target.c"
2213 #undef TARGET_STRING
2214 #undef TARGET_BIG_ENDIAN
2215 #undef TARGET_ARCHIVE
2217 #define TARGET_NAME mach_o_fat_vec
2218 #define TARGET_STRING "mach-o-fat"
2219 #define TARGET_BIG_ENDIAN 1
2220 #define TARGET_ARCHIVE 1
2222 #include "mach-o-target.c"
2225 #undef TARGET_STRING
2226 #undef TARGET_BIG_ENDIAN
2227 #undef TARGET_ARCHIVE