xref: /openbsd-src/gnu/usr.bin/binutils/bfd/mach-o.c (revision cf2f2c5620d6d9a4fd01930983c4b9a1f76d7aa3)
1d2201f2fSdrahn /* Mach-O support for BFD.
2*cf2f2c56Smiod    Copyright 1999, 2000, 2001, 2002, 2003
3d2201f2fSdrahn    Free Software Foundation, Inc.
4d2201f2fSdrahn 
5d2201f2fSdrahn    This file is part of BFD, the Binary File Descriptor library.
6d2201f2fSdrahn 
7d2201f2fSdrahn    This program is free software; you can redistribute it and/or modify
8d2201f2fSdrahn    it under the terms of the GNU General Public License as published by
9d2201f2fSdrahn    the Free Software Foundation; either version 2 of the License, or
10d2201f2fSdrahn    (at your option) any later version.
11d2201f2fSdrahn 
12d2201f2fSdrahn    This program is distributed in the hope that it will be useful,
13d2201f2fSdrahn    but WITHOUT ANY WARRANTY; without even the implied warranty of
14d2201f2fSdrahn    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15d2201f2fSdrahn    GNU General Public License for more details.
16d2201f2fSdrahn 
17d2201f2fSdrahn    You should have received a copy of the GNU General Public License
18d2201f2fSdrahn    along with this program; if not, write to the Free Software
19d2201f2fSdrahn    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20d2201f2fSdrahn 
21d2201f2fSdrahn #include "mach-o.h"
22d2201f2fSdrahn #include "bfd.h"
23d2201f2fSdrahn #include "sysdep.h"
24d2201f2fSdrahn #include "libbfd.h"
25d2201f2fSdrahn #include "libiberty.h"
26d2201f2fSdrahn #include <ctype.h>
27d2201f2fSdrahn 
28d2201f2fSdrahn #ifndef BFD_IO_FUNCS
29d2201f2fSdrahn #define BFD_IO_FUNCS 0
30d2201f2fSdrahn #endif
31d2201f2fSdrahn 
32d2201f2fSdrahn #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
33d2201f2fSdrahn #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
34d2201f2fSdrahn #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
35d2201f2fSdrahn #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
36d2201f2fSdrahn #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
37d2201f2fSdrahn #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
38d2201f2fSdrahn #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
39d2201f2fSdrahn #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
40d2201f2fSdrahn #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
41d2201f2fSdrahn #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
42d2201f2fSdrahn #define	bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup
43d2201f2fSdrahn #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
44d2201f2fSdrahn #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
45d2201f2fSdrahn #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
46d2201f2fSdrahn #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
47d2201f2fSdrahn #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
48d2201f2fSdrahn #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
49d2201f2fSdrahn #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
50d2201f2fSdrahn #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
51d2201f2fSdrahn #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
52d2201f2fSdrahn #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
53d2201f2fSdrahn #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
54d2201f2fSdrahn #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
55d2201f2fSdrahn #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
56d2201f2fSdrahn #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
57d2201f2fSdrahn #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
58d2201f2fSdrahn #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
59d2201f2fSdrahn #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
60d2201f2fSdrahn #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
61d2201f2fSdrahn #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
62d2201f2fSdrahn #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
63d2201f2fSdrahn #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach
64d2201f2fSdrahn #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
65d2201f2fSdrahn #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
66d2201f2fSdrahn #define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
67d2201f2fSdrahn #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
68d2201f2fSdrahn #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
69d2201f2fSdrahn #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
70d2201f2fSdrahn #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
71d2201f2fSdrahn #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
72d2201f2fSdrahn 
73d2201f2fSdrahn static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data
74d2201f2fSdrahn   PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
75d2201f2fSdrahn static bfd_boolean bfd_mach_o_bfd_copy_private_section_data
76d2201f2fSdrahn   PARAMS ((bfd *, asection *, bfd *, asection *));
77d2201f2fSdrahn static bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data
78d2201f2fSdrahn   PARAMS ((bfd *, bfd *));
79d2201f2fSdrahn static long bfd_mach_o_count_symbols
80d2201f2fSdrahn   PARAMS ((bfd *));
81d2201f2fSdrahn static long bfd_mach_o_get_symtab_upper_bound
82d2201f2fSdrahn   PARAMS ((bfd *));
83*cf2f2c56Smiod static long bfd_mach_o_canonicalize_symtab
84d2201f2fSdrahn   PARAMS ((bfd *, asymbol **));
85d2201f2fSdrahn static void bfd_mach_o_get_symbol_info
86d2201f2fSdrahn   PARAMS ((bfd *, asymbol *, symbol_info *));
87d2201f2fSdrahn static void bfd_mach_o_print_symbol
88d2201f2fSdrahn   PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
89d2201f2fSdrahn static void bfd_mach_o_convert_architecture
90d2201f2fSdrahn   PARAMS ((bfd_mach_o_cpu_type, bfd_mach_o_cpu_subtype,
91d2201f2fSdrahn 	   enum bfd_architecture *, unsigned long *));
92d2201f2fSdrahn static bfd_boolean bfd_mach_o_write_contents
93d2201f2fSdrahn   PARAMS ((bfd *));
94d2201f2fSdrahn static int bfd_mach_o_sizeof_headers
95d2201f2fSdrahn   PARAMS ((bfd *, bfd_boolean));
96d2201f2fSdrahn static asymbol * bfd_mach_o_make_empty_symbol
97d2201f2fSdrahn   PARAMS ((bfd *));
98d2201f2fSdrahn static int bfd_mach_o_write_header
99d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_header *));
100d2201f2fSdrahn static int bfd_mach_o_read_header
101d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_header *));
102d2201f2fSdrahn static asection * bfd_mach_o_make_bfd_section
103d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_section *));
104d2201f2fSdrahn static int bfd_mach_o_scan_read_section
105d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
106d2201f2fSdrahn static int bfd_mach_o_scan_write_section
107d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
108d2201f2fSdrahn static int bfd_mach_o_scan_write_symtab_symbols
109d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
110d2201f2fSdrahn static int bfd_mach_o_scan_write_thread
111d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
112d2201f2fSdrahn static int bfd_mach_o_scan_read_dylinker
113d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
114d2201f2fSdrahn static int bfd_mach_o_scan_read_dylib
115d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
116d2201f2fSdrahn static int bfd_mach_o_scan_read_prebound_dylib
117d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
118d2201f2fSdrahn static int bfd_mach_o_scan_read_thread
119d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
120d2201f2fSdrahn static int bfd_mach_o_scan_write_symtab
121d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
122d2201f2fSdrahn static int bfd_mach_o_scan_read_dysymtab
123d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
124d2201f2fSdrahn static int bfd_mach_o_scan_read_symtab
125d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
126d2201f2fSdrahn static int bfd_mach_o_scan_read_segment
127d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
128d2201f2fSdrahn static int bfd_mach_o_scan_write_segment
129d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
130d2201f2fSdrahn static int bfd_mach_o_scan_read_command
131d2201f2fSdrahn   PARAMS ((bfd *, bfd_mach_o_load_command *));
132d2201f2fSdrahn static void bfd_mach_o_flatten_sections
133d2201f2fSdrahn   PARAMS ((bfd *));
134d2201f2fSdrahn static const char * bfd_mach_o_i386_flavour_string
135d2201f2fSdrahn   PARAMS ((unsigned int));
136d2201f2fSdrahn static const char * bfd_mach_o_ppc_flavour_string
137d2201f2fSdrahn   PARAMS ((unsigned int));
138d2201f2fSdrahn 
139d2201f2fSdrahn /* The flags field of a section structure is separated into two parts a section
140d2201f2fSdrahn    type and section attributes.  The section types are mutually exclusive (it
141d2201f2fSdrahn    can only have one type) but the section attributes are not (it may have more
142d2201f2fSdrahn    than one attribute).  */
143d2201f2fSdrahn 
144d2201f2fSdrahn #define SECTION_TYPE             0x000000ff     /* 256 section types.  */
145d2201f2fSdrahn #define SECTION_ATTRIBUTES       0xffffff00     /*  24 section attributes.  */
146d2201f2fSdrahn 
147d2201f2fSdrahn /* Constants for the section attributes part of the flags field of a section
148d2201f2fSdrahn    structure.  */
149d2201f2fSdrahn 
150d2201f2fSdrahn #define SECTION_ATTRIBUTES_USR   0xff000000     /* User-settable attributes.  */
151d2201f2fSdrahn #define S_ATTR_PURE_INSTRUCTIONS 0x80000000     /* Section contains only true machine instructions.  */
152d2201f2fSdrahn #define SECTION_ATTRIBUTES_SYS   0x00ffff00     /* System setable attributes.  */
153d2201f2fSdrahn #define S_ATTR_SOME_INSTRUCTIONS 0x00000400     /* Section contains some machine instructions.  */
154d2201f2fSdrahn #define S_ATTR_EXT_RELOC         0x00000200     /* Section has external relocation entries.  */
155d2201f2fSdrahn #define S_ATTR_LOC_RELOC         0x00000100     /* Section has local relocation entries.  */
156d2201f2fSdrahn 
157d2201f2fSdrahn #define N_STAB 0xe0
158d2201f2fSdrahn #define N_TYPE 0x1e
159d2201f2fSdrahn #define N_EXT  0x01
160d2201f2fSdrahn #define N_UNDF 0x0
161d2201f2fSdrahn #define N_ABS  0x2
162d2201f2fSdrahn #define N_SECT 0xe
163d2201f2fSdrahn #define N_INDR 0xa
164d2201f2fSdrahn 
165d2201f2fSdrahn bfd_boolean
bfd_mach_o_valid(abfd)166d2201f2fSdrahn bfd_mach_o_valid (abfd)
167d2201f2fSdrahn      bfd *abfd;
168d2201f2fSdrahn {
169d2201f2fSdrahn   if (abfd == NULL || abfd->xvec == NULL)
170d2201f2fSdrahn     return 0;
171d2201f2fSdrahn 
172d2201f2fSdrahn   if (! ((abfd->xvec == &mach_o_be_vec)
173d2201f2fSdrahn 	 || (abfd->xvec == &mach_o_le_vec)
174d2201f2fSdrahn 	 || (abfd->xvec == &mach_o_fat_vec)))
175d2201f2fSdrahn     return 0;
176d2201f2fSdrahn 
177d2201f2fSdrahn   if (abfd->tdata.mach_o_data == NULL)
178d2201f2fSdrahn     return 0;
179d2201f2fSdrahn   return 1;
180d2201f2fSdrahn }
181d2201f2fSdrahn 
182d2201f2fSdrahn /* Copy any private info we understand from the input symbol
183d2201f2fSdrahn    to the output symbol.  */
184d2201f2fSdrahn 
185d2201f2fSdrahn static bfd_boolean
bfd_mach_o_bfd_copy_private_symbol_data(ibfd,isymbol,obfd,osymbol)186d2201f2fSdrahn bfd_mach_o_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
187d2201f2fSdrahn      bfd *ibfd ATTRIBUTE_UNUSED;
188d2201f2fSdrahn      asymbol *isymbol ATTRIBUTE_UNUSED;
189d2201f2fSdrahn      bfd *obfd ATTRIBUTE_UNUSED;
190d2201f2fSdrahn      asymbol *osymbol ATTRIBUTE_UNUSED;
191d2201f2fSdrahn {
192d2201f2fSdrahn   return TRUE;
193d2201f2fSdrahn }
194d2201f2fSdrahn 
195d2201f2fSdrahn /* Copy any private info we understand from the input section
196d2201f2fSdrahn    to the output section.  */
197d2201f2fSdrahn 
198d2201f2fSdrahn static bfd_boolean
bfd_mach_o_bfd_copy_private_section_data(ibfd,isection,obfd,osection)199d2201f2fSdrahn bfd_mach_o_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
200d2201f2fSdrahn      bfd *ibfd ATTRIBUTE_UNUSED;
201d2201f2fSdrahn      asection *isection ATTRIBUTE_UNUSED;
202d2201f2fSdrahn      bfd *obfd ATTRIBUTE_UNUSED;
203d2201f2fSdrahn      asection *osection ATTRIBUTE_UNUSED;
204d2201f2fSdrahn {
205d2201f2fSdrahn   return TRUE;
206d2201f2fSdrahn }
207d2201f2fSdrahn 
208d2201f2fSdrahn /* Copy any private info we understand from the input bfd
209d2201f2fSdrahn    to the output bfd.  */
210d2201f2fSdrahn 
211d2201f2fSdrahn static bfd_boolean
bfd_mach_o_bfd_copy_private_bfd_data(ibfd,obfd)212d2201f2fSdrahn bfd_mach_o_bfd_copy_private_bfd_data (ibfd, obfd)
213d2201f2fSdrahn      bfd *ibfd;
214d2201f2fSdrahn      bfd *obfd;
215d2201f2fSdrahn {
216d2201f2fSdrahn   BFD_ASSERT (bfd_mach_o_valid (ibfd));
217d2201f2fSdrahn   BFD_ASSERT (bfd_mach_o_valid (obfd));
218d2201f2fSdrahn 
219d2201f2fSdrahn   obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
220d2201f2fSdrahn   obfd->tdata.mach_o_data->ibfd = ibfd;
221d2201f2fSdrahn   return TRUE;
222d2201f2fSdrahn }
223d2201f2fSdrahn 
224d2201f2fSdrahn static long
bfd_mach_o_count_symbols(abfd)225d2201f2fSdrahn bfd_mach_o_count_symbols (abfd)
226d2201f2fSdrahn      bfd *abfd;
227d2201f2fSdrahn {
228d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = NULL;
229d2201f2fSdrahn   long nsyms = 0;
230d2201f2fSdrahn   unsigned long i;
231d2201f2fSdrahn 
232d2201f2fSdrahn   BFD_ASSERT (bfd_mach_o_valid (abfd));
233d2201f2fSdrahn   mdata = abfd->tdata.mach_o_data;
234d2201f2fSdrahn 
235d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
236d2201f2fSdrahn     if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
237d2201f2fSdrahn       {
238d2201f2fSdrahn 	bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
239d2201f2fSdrahn 	nsyms += sym->nsyms;
240d2201f2fSdrahn       }
241d2201f2fSdrahn 
242d2201f2fSdrahn   return nsyms;
243d2201f2fSdrahn }
244d2201f2fSdrahn 
245d2201f2fSdrahn static long
bfd_mach_o_get_symtab_upper_bound(abfd)246d2201f2fSdrahn bfd_mach_o_get_symtab_upper_bound (abfd)
247d2201f2fSdrahn      bfd *abfd;
248d2201f2fSdrahn {
249d2201f2fSdrahn   long nsyms = bfd_mach_o_count_symbols (abfd);
250d2201f2fSdrahn 
251d2201f2fSdrahn   if (nsyms < 0)
252d2201f2fSdrahn     return nsyms;
253d2201f2fSdrahn 
254d2201f2fSdrahn   return ((nsyms + 1) * sizeof (asymbol *));
255d2201f2fSdrahn }
256d2201f2fSdrahn 
257d2201f2fSdrahn static long
bfd_mach_o_canonicalize_symtab(abfd,alocation)258*cf2f2c56Smiod bfd_mach_o_canonicalize_symtab (abfd, alocation)
259d2201f2fSdrahn      bfd *abfd;
260d2201f2fSdrahn      asymbol **alocation;
261d2201f2fSdrahn {
262d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
263d2201f2fSdrahn   long nsyms = bfd_mach_o_count_symbols (abfd);
264d2201f2fSdrahn   asymbol **csym = alocation;
265d2201f2fSdrahn   unsigned long i, j;
266d2201f2fSdrahn 
267d2201f2fSdrahn   if (nsyms < 0)
268d2201f2fSdrahn     return nsyms;
269d2201f2fSdrahn 
270d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
271d2201f2fSdrahn     {
272d2201f2fSdrahn       if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
273d2201f2fSdrahn 	{
274d2201f2fSdrahn 	  bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
275d2201f2fSdrahn 
276d2201f2fSdrahn 	  if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
277d2201f2fSdrahn 	    {
278*cf2f2c56Smiod 	      fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
279d2201f2fSdrahn 	      return 0;
280d2201f2fSdrahn 	    }
281d2201f2fSdrahn 
282d2201f2fSdrahn 	  BFD_ASSERT (sym->symbols != NULL);
283d2201f2fSdrahn 
284d2201f2fSdrahn 	  for (j = 0; j < sym->nsyms; j++)
285d2201f2fSdrahn 	    {
286d2201f2fSdrahn 	      BFD_ASSERT (csym < (alocation + nsyms));
287d2201f2fSdrahn 	      *csym++ = &sym->symbols[j];
288d2201f2fSdrahn 	    }
289d2201f2fSdrahn 	}
290d2201f2fSdrahn     }
291d2201f2fSdrahn 
292d2201f2fSdrahn   *csym++ = NULL;
293d2201f2fSdrahn 
294d2201f2fSdrahn   return nsyms;
295d2201f2fSdrahn }
296d2201f2fSdrahn 
297d2201f2fSdrahn static void
bfd_mach_o_get_symbol_info(abfd,symbol,ret)298d2201f2fSdrahn bfd_mach_o_get_symbol_info (abfd, symbol, ret)
299d2201f2fSdrahn      bfd *abfd ATTRIBUTE_UNUSED;
300d2201f2fSdrahn      asymbol *symbol;
301d2201f2fSdrahn      symbol_info *ret;
302d2201f2fSdrahn {
303d2201f2fSdrahn   bfd_symbol_info (symbol, ret);
304d2201f2fSdrahn }
305d2201f2fSdrahn 
306d2201f2fSdrahn static void
bfd_mach_o_print_symbol(abfd,afile,symbol,how)307d2201f2fSdrahn bfd_mach_o_print_symbol (abfd, afile, symbol, how)
308d2201f2fSdrahn      bfd *abfd;
309d2201f2fSdrahn      PTR afile;
310d2201f2fSdrahn      asymbol *symbol;
311d2201f2fSdrahn      bfd_print_symbol_type how;
312d2201f2fSdrahn {
313d2201f2fSdrahn   FILE *file = (FILE *) afile;
314d2201f2fSdrahn 
315d2201f2fSdrahn   switch (how)
316d2201f2fSdrahn     {
317d2201f2fSdrahn     case bfd_print_symbol_name:
318d2201f2fSdrahn       fprintf (file, "%s", symbol->name);
319d2201f2fSdrahn       break;
320d2201f2fSdrahn     default:
321d2201f2fSdrahn       bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
322d2201f2fSdrahn       fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
323d2201f2fSdrahn     }
324d2201f2fSdrahn }
325d2201f2fSdrahn 
326d2201f2fSdrahn static void
bfd_mach_o_convert_architecture(mtype,msubtype,type,subtype)327d2201f2fSdrahn bfd_mach_o_convert_architecture (mtype, msubtype, type, subtype)
328d2201f2fSdrahn      bfd_mach_o_cpu_type mtype;
329d2201f2fSdrahn      bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED;
330d2201f2fSdrahn      enum bfd_architecture *type;
331d2201f2fSdrahn      unsigned long *subtype;
332d2201f2fSdrahn {
333d2201f2fSdrahn   *subtype = bfd_arch_unknown;
334d2201f2fSdrahn 
335d2201f2fSdrahn   switch (mtype)
336d2201f2fSdrahn     {
337d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
338d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
339d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
340d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
341d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
342d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
343d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
344d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
345d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
346d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
347d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
348d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
349d2201f2fSdrahn     default: *type = bfd_arch_unknown; break;
350d2201f2fSdrahn     }
351d2201f2fSdrahn 
352d2201f2fSdrahn   switch (*type)
353d2201f2fSdrahn     {
354d2201f2fSdrahn     case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
355d2201f2fSdrahn     case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
356d2201f2fSdrahn     default:
357d2201f2fSdrahn       *subtype = bfd_arch_unknown;
358d2201f2fSdrahn     }
359d2201f2fSdrahn }
360d2201f2fSdrahn 
361d2201f2fSdrahn static bfd_boolean
bfd_mach_o_write_contents(abfd)362d2201f2fSdrahn bfd_mach_o_write_contents (abfd)
363d2201f2fSdrahn      bfd *abfd;
364d2201f2fSdrahn {
365d2201f2fSdrahn   unsigned int i;
366d2201f2fSdrahn   asection *s;
367d2201f2fSdrahn 
368d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
369d2201f2fSdrahn 
370d2201f2fSdrahn   /* Write data sections first in case they overlap header data to be
371d2201f2fSdrahn      written later.  */
372d2201f2fSdrahn 
373d2201f2fSdrahn   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
374d2201f2fSdrahn     ;
375d2201f2fSdrahn 
376d2201f2fSdrahn #if 0
377d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
378d2201f2fSdrahn     {
379d2201f2fSdrahn       bfd_mach_o_load_command *cur = &mdata->commands[i];
380d2201f2fSdrahn       if (cur->type != BFD_MACH_O_LC_SEGMENT)
381d2201f2fSdrahn 	break;
382d2201f2fSdrahn 
383d2201f2fSdrahn       {
384d2201f2fSdrahn 	bfd_mach_o_segment_command *seg = &cur->command.segment;
385d2201f2fSdrahn 	char buf[1024];
386d2201f2fSdrahn 	bfd_vma nbytes = seg->filesize;
387d2201f2fSdrahn 	bfd_vma curoff = seg->fileoff;
388d2201f2fSdrahn 
389d2201f2fSdrahn 	while (nbytes > 0)
390d2201f2fSdrahn 	  {
391d2201f2fSdrahn 	    bfd_vma thisread = nbytes;
392d2201f2fSdrahn 
393d2201f2fSdrahn 	    if (thisread > 1024)
394d2201f2fSdrahn 	      thisread = 1024;
395d2201f2fSdrahn 
396d2201f2fSdrahn 	    bfd_seek (abfd, curoff, SEEK_SET);
397d2201f2fSdrahn 	    if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
398d2201f2fSdrahn 	      return FALSE;
399d2201f2fSdrahn 
400d2201f2fSdrahn 	    bfd_seek (abfd, curoff, SEEK_SET);
401d2201f2fSdrahn 	    if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
402d2201f2fSdrahn 	      return FALSE;
403d2201f2fSdrahn 
404d2201f2fSdrahn 	    nbytes -= thisread;
405d2201f2fSdrahn 	    curoff += thisread;
406d2201f2fSdrahn 	  }
407d2201f2fSdrahn       }
408d2201f2fSdrahn   }
409d2201f2fSdrahn #endif
410d2201f2fSdrahn 
411d2201f2fSdrahn   /* Now write header information.  */
412d2201f2fSdrahn   if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
413d2201f2fSdrahn     return FALSE;
414d2201f2fSdrahn 
415d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
416d2201f2fSdrahn     {
417d2201f2fSdrahn       unsigned char buf[8];
418d2201f2fSdrahn       bfd_mach_o_load_command *cur = &mdata->commands[i];
419d2201f2fSdrahn       unsigned long typeflag;
420d2201f2fSdrahn 
421d2201f2fSdrahn       typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
422d2201f2fSdrahn 
423d2201f2fSdrahn       bfd_h_put_32 (abfd, typeflag, buf);
424d2201f2fSdrahn       bfd_h_put_32 (abfd, cur->len, buf + 4);
425d2201f2fSdrahn 
426d2201f2fSdrahn       bfd_seek (abfd, cur->offset, SEEK_SET);
427d2201f2fSdrahn       if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
428d2201f2fSdrahn 	return FALSE;
429d2201f2fSdrahn 
430d2201f2fSdrahn       switch (cur->type)
431d2201f2fSdrahn 	{
432d2201f2fSdrahn 	case BFD_MACH_O_LC_SEGMENT:
433d2201f2fSdrahn 	  if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
434d2201f2fSdrahn 	    return FALSE;
435d2201f2fSdrahn 	  break;
436d2201f2fSdrahn 	case BFD_MACH_O_LC_SYMTAB:
437d2201f2fSdrahn 	  if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
438d2201f2fSdrahn 	    return FALSE;
439d2201f2fSdrahn 	  break;
440d2201f2fSdrahn 	case BFD_MACH_O_LC_SYMSEG:
441d2201f2fSdrahn 	  break;
442d2201f2fSdrahn 	case BFD_MACH_O_LC_THREAD:
443d2201f2fSdrahn 	case BFD_MACH_O_LC_UNIXTHREAD:
444d2201f2fSdrahn 	  if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
445d2201f2fSdrahn 	    return FALSE;
446d2201f2fSdrahn 	  break;
447d2201f2fSdrahn 	case BFD_MACH_O_LC_LOADFVMLIB:
448d2201f2fSdrahn 	case BFD_MACH_O_LC_IDFVMLIB:
449d2201f2fSdrahn 	case BFD_MACH_O_LC_IDENT:
450d2201f2fSdrahn 	case BFD_MACH_O_LC_FVMFILE:
451d2201f2fSdrahn 	case BFD_MACH_O_LC_PREPAGE:
452d2201f2fSdrahn 	case BFD_MACH_O_LC_DYSYMTAB:
453d2201f2fSdrahn 	case BFD_MACH_O_LC_LOAD_DYLIB:
454d2201f2fSdrahn 	case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
455d2201f2fSdrahn 	case BFD_MACH_O_LC_ID_DYLIB:
456d2201f2fSdrahn 	case BFD_MACH_O_LC_LOAD_DYLINKER:
457d2201f2fSdrahn 	case BFD_MACH_O_LC_ID_DYLINKER:
458d2201f2fSdrahn 	case BFD_MACH_O_LC_PREBOUND_DYLIB:
459d2201f2fSdrahn 	case BFD_MACH_O_LC_ROUTINES:
460d2201f2fSdrahn 	case BFD_MACH_O_LC_SUB_FRAMEWORK:
461d2201f2fSdrahn 	  break;
462d2201f2fSdrahn 	default:
463d2201f2fSdrahn 	  fprintf (stderr,
464d2201f2fSdrahn 		   "unable to write unknown load command 0x%lx\n",
465d2201f2fSdrahn 		   (long) cur->type);
466d2201f2fSdrahn 	  return FALSE;
467d2201f2fSdrahn 	}
468d2201f2fSdrahn     }
469d2201f2fSdrahn 
470d2201f2fSdrahn   return TRUE;
471d2201f2fSdrahn }
472d2201f2fSdrahn 
473d2201f2fSdrahn static int
bfd_mach_o_sizeof_headers(a,b)474d2201f2fSdrahn bfd_mach_o_sizeof_headers (a, b)
475d2201f2fSdrahn      bfd *a ATTRIBUTE_UNUSED;
476d2201f2fSdrahn      bfd_boolean b ATTRIBUTE_UNUSED;
477d2201f2fSdrahn {
478d2201f2fSdrahn   return 0;
479d2201f2fSdrahn }
480d2201f2fSdrahn 
481d2201f2fSdrahn /* Make an empty symbol.  This is required only because
482d2201f2fSdrahn    bfd_make_section_anyway wants to create a symbol for the section.  */
483d2201f2fSdrahn 
484d2201f2fSdrahn static asymbol *
bfd_mach_o_make_empty_symbol(abfd)485d2201f2fSdrahn bfd_mach_o_make_empty_symbol (abfd)
486d2201f2fSdrahn      bfd *abfd;
487d2201f2fSdrahn {
488d2201f2fSdrahn   asymbol *new;
489d2201f2fSdrahn 
490d2201f2fSdrahn   new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
491d2201f2fSdrahn   if (new == NULL)
492d2201f2fSdrahn     return new;
493d2201f2fSdrahn   new->the_bfd = abfd;
494d2201f2fSdrahn   return new;
495d2201f2fSdrahn }
496d2201f2fSdrahn 
497d2201f2fSdrahn static int
bfd_mach_o_write_header(abfd,header)498d2201f2fSdrahn bfd_mach_o_write_header (abfd, header)
499d2201f2fSdrahn      bfd *abfd;
500d2201f2fSdrahn      bfd_mach_o_header *header;
501d2201f2fSdrahn {
502d2201f2fSdrahn   unsigned char buf[28];
503d2201f2fSdrahn 
504d2201f2fSdrahn   bfd_h_put_32 (abfd, header->magic, buf + 0);
505d2201f2fSdrahn   bfd_h_put_32 (abfd, header->cputype, buf + 4);
506d2201f2fSdrahn   bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
507d2201f2fSdrahn   bfd_h_put_32 (abfd, header->filetype, buf + 12);
508d2201f2fSdrahn   bfd_h_put_32 (abfd, header->ncmds, buf + 16);
509d2201f2fSdrahn   bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
510d2201f2fSdrahn   bfd_h_put_32 (abfd, header->flags, buf + 24);
511d2201f2fSdrahn 
512d2201f2fSdrahn   bfd_seek (abfd, 0, SEEK_SET);
513d2201f2fSdrahn   if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
514d2201f2fSdrahn     return -1;
515d2201f2fSdrahn 
516d2201f2fSdrahn   return 0;
517d2201f2fSdrahn }
518d2201f2fSdrahn 
519d2201f2fSdrahn static int
bfd_mach_o_read_header(abfd,header)520d2201f2fSdrahn bfd_mach_o_read_header (abfd, header)
521d2201f2fSdrahn      bfd *abfd;
522d2201f2fSdrahn      bfd_mach_o_header *header;
523d2201f2fSdrahn {
524d2201f2fSdrahn   unsigned char buf[28];
525*cf2f2c56Smiod   bfd_vma (*get32) (const void *) = NULL;
526d2201f2fSdrahn 
527d2201f2fSdrahn   bfd_seek (abfd, 0, SEEK_SET);
528d2201f2fSdrahn 
529d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 28, abfd) != 28)
530d2201f2fSdrahn     return -1;
531d2201f2fSdrahn 
532d2201f2fSdrahn   if (bfd_getb32 (buf) == 0xfeedface)
533d2201f2fSdrahn     {
534d2201f2fSdrahn       header->byteorder = BFD_ENDIAN_BIG;
535d2201f2fSdrahn       header->magic = 0xfeedface;
536d2201f2fSdrahn       get32 = bfd_getb32;
537d2201f2fSdrahn     }
538d2201f2fSdrahn   else if (bfd_getl32 (buf) == 0xfeedface)
539d2201f2fSdrahn     {
540d2201f2fSdrahn       header->byteorder = BFD_ENDIAN_LITTLE;
541d2201f2fSdrahn       header->magic = 0xfeedface;
542d2201f2fSdrahn       get32 = bfd_getl32;
543d2201f2fSdrahn     }
544d2201f2fSdrahn   else
545d2201f2fSdrahn     {
546d2201f2fSdrahn       header->byteorder = BFD_ENDIAN_UNKNOWN;
547d2201f2fSdrahn       return -1;
548d2201f2fSdrahn     }
549d2201f2fSdrahn 
550d2201f2fSdrahn   header->cputype = (*get32) (buf + 4);
551d2201f2fSdrahn   header->cpusubtype = (*get32) (buf + 8);
552d2201f2fSdrahn   header->filetype = (*get32) (buf + 12);
553d2201f2fSdrahn   header->ncmds = (*get32) (buf + 16);
554d2201f2fSdrahn   header->sizeofcmds = (*get32) (buf + 20);
555d2201f2fSdrahn   header->flags = (*get32) (buf + 24);
556d2201f2fSdrahn 
557d2201f2fSdrahn   return 0;
558d2201f2fSdrahn }
559d2201f2fSdrahn 
560d2201f2fSdrahn static asection *
bfd_mach_o_make_bfd_section(abfd,section)561d2201f2fSdrahn bfd_mach_o_make_bfd_section (abfd, section)
562d2201f2fSdrahn      bfd *abfd;
563d2201f2fSdrahn      bfd_mach_o_section *section;
564d2201f2fSdrahn {
565d2201f2fSdrahn   asection *bfdsec;
566d2201f2fSdrahn   char *sname;
567d2201f2fSdrahn   const char *prefix = "LC_SEGMENT";
568d2201f2fSdrahn   unsigned int snamelen;
569d2201f2fSdrahn 
570d2201f2fSdrahn   snamelen = strlen (prefix) + 1
571d2201f2fSdrahn     + strlen (section->segname) + 1
572d2201f2fSdrahn     + strlen (section->sectname) + 1;
573d2201f2fSdrahn 
574d2201f2fSdrahn   sname = (char *) bfd_alloc (abfd, snamelen);
575d2201f2fSdrahn   if (sname == NULL)
576d2201f2fSdrahn     return NULL;
577d2201f2fSdrahn   sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
578d2201f2fSdrahn 
579d2201f2fSdrahn   bfdsec = bfd_make_section_anyway (abfd, sname);
580d2201f2fSdrahn   if (bfdsec == NULL)
581d2201f2fSdrahn     return NULL;
582d2201f2fSdrahn 
583d2201f2fSdrahn   bfdsec->vma = section->addr;
584d2201f2fSdrahn   bfdsec->lma = section->addr;
585d2201f2fSdrahn   bfdsec->_raw_size = section->size;
586d2201f2fSdrahn   bfdsec->filepos = section->offset;
587d2201f2fSdrahn   bfdsec->alignment_power = section->align;
588d2201f2fSdrahn 
589d2201f2fSdrahn   if (section->flags & BFD_MACH_O_S_ZEROFILL)
590d2201f2fSdrahn     bfdsec->flags = SEC_ALLOC;
591d2201f2fSdrahn   else
592d2201f2fSdrahn     bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
593d2201f2fSdrahn 
594d2201f2fSdrahn   return bfdsec;
595d2201f2fSdrahn }
596d2201f2fSdrahn 
597d2201f2fSdrahn static int
bfd_mach_o_scan_read_section(abfd,section,offset)598d2201f2fSdrahn bfd_mach_o_scan_read_section (abfd, section, offset)
599d2201f2fSdrahn      bfd *abfd;
600d2201f2fSdrahn      bfd_mach_o_section *section;
601d2201f2fSdrahn      bfd_vma offset;
602d2201f2fSdrahn {
603d2201f2fSdrahn   unsigned char buf[68];
604d2201f2fSdrahn 
605d2201f2fSdrahn   bfd_seek (abfd, offset, SEEK_SET);
606d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 68, abfd) != 68)
607d2201f2fSdrahn     return -1;
608d2201f2fSdrahn 
609d2201f2fSdrahn   memcpy (section->sectname, buf, 16);
610d2201f2fSdrahn   section->sectname[16] = '\0';
611d2201f2fSdrahn   memcpy (section->segname, buf + 16, 16);
612d2201f2fSdrahn   section->segname[16] = '\0';
613d2201f2fSdrahn   section->addr = bfd_h_get_32 (abfd, buf + 32);
614d2201f2fSdrahn   section->size = bfd_h_get_32 (abfd, buf + 36);
615d2201f2fSdrahn   section->offset = bfd_h_get_32 (abfd, buf + 40);
616d2201f2fSdrahn   section->align = bfd_h_get_32 (abfd, buf + 44);
617d2201f2fSdrahn   section->reloff = bfd_h_get_32 (abfd, buf + 48);
618d2201f2fSdrahn   section->nreloc = bfd_h_get_32 (abfd, buf + 52);
619d2201f2fSdrahn   section->flags = bfd_h_get_32 (abfd, buf + 56);
620d2201f2fSdrahn   section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
621d2201f2fSdrahn   section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
622d2201f2fSdrahn   section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
623d2201f2fSdrahn 
624d2201f2fSdrahn   if (section->bfdsection == NULL)
625d2201f2fSdrahn     return -1;
626d2201f2fSdrahn 
627d2201f2fSdrahn   return 0;
628d2201f2fSdrahn }
629d2201f2fSdrahn 
630d2201f2fSdrahn static int
bfd_mach_o_scan_write_section(abfd,section,offset)631d2201f2fSdrahn bfd_mach_o_scan_write_section (abfd, section, offset)
632d2201f2fSdrahn      bfd *abfd;
633d2201f2fSdrahn      bfd_mach_o_section *section;
634d2201f2fSdrahn      bfd_vma offset;
635d2201f2fSdrahn {
636d2201f2fSdrahn   unsigned char buf[68];
637d2201f2fSdrahn 
638d2201f2fSdrahn   memcpy (buf, section->sectname, 16);
639d2201f2fSdrahn   memcpy (buf + 16, section->segname, 16);
640d2201f2fSdrahn   bfd_h_put_32 (abfd, section->addr, buf + 32);
641d2201f2fSdrahn   bfd_h_put_32 (abfd, section->size, buf + 36);
642d2201f2fSdrahn   bfd_h_put_32 (abfd, section->offset, buf + 40);
643d2201f2fSdrahn   bfd_h_put_32 (abfd, section->align, buf + 44);
644d2201f2fSdrahn   bfd_h_put_32 (abfd, section->reloff, buf + 48);
645d2201f2fSdrahn   bfd_h_put_32 (abfd, section->nreloc, buf + 52);
646d2201f2fSdrahn   bfd_h_put_32 (abfd, section->flags, buf + 56);
647d2201f2fSdrahn   /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
648d2201f2fSdrahn   /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
649d2201f2fSdrahn 
650d2201f2fSdrahn   bfd_seek (abfd, offset, SEEK_SET);
651d2201f2fSdrahn   if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
652d2201f2fSdrahn     return -1;
653d2201f2fSdrahn 
654d2201f2fSdrahn   return 0;
655d2201f2fSdrahn }
656d2201f2fSdrahn 
657d2201f2fSdrahn static int
bfd_mach_o_scan_write_symtab_symbols(abfd,command)658d2201f2fSdrahn bfd_mach_o_scan_write_symtab_symbols (abfd, command)
659d2201f2fSdrahn      bfd *abfd;
660d2201f2fSdrahn      bfd_mach_o_load_command *command;
661d2201f2fSdrahn {
662d2201f2fSdrahn   bfd_mach_o_symtab_command *sym = &command->command.symtab;
663d2201f2fSdrahn   asymbol *s = NULL;
664d2201f2fSdrahn   unsigned long i;
665d2201f2fSdrahn 
666d2201f2fSdrahn   for (i = 0; i < sym->nsyms; i++)
667d2201f2fSdrahn     {
668d2201f2fSdrahn       unsigned char buf[12];
669d2201f2fSdrahn       bfd_vma symoff = sym->symoff + (i * 12);
670d2201f2fSdrahn       unsigned char ntype = 0;
671d2201f2fSdrahn       unsigned char nsect = 0;
672d2201f2fSdrahn       short ndesc = 0;
673d2201f2fSdrahn 
674d2201f2fSdrahn       s = &sym->symbols[i];
675d2201f2fSdrahn 
676d2201f2fSdrahn       /* Don't set this from the symbol information; use stored values.  */
677d2201f2fSdrahn #if 0
678d2201f2fSdrahn       if (s->flags & BSF_GLOBAL)
679d2201f2fSdrahn 	ntype |= N_EXT;
680d2201f2fSdrahn       if (s->flags & BSF_DEBUGGING)
681d2201f2fSdrahn 	ntype |= N_STAB;
682d2201f2fSdrahn 
683d2201f2fSdrahn       if (s->section == bfd_und_section_ptr)
684d2201f2fSdrahn 	ntype |= N_UNDF;
685d2201f2fSdrahn       else if (s->section == bfd_abs_section_ptr)
686d2201f2fSdrahn 	ntype |= N_ABS;
687d2201f2fSdrahn       else
688d2201f2fSdrahn 	ntype |= N_SECT;
689d2201f2fSdrahn #endif
690d2201f2fSdrahn 
691d2201f2fSdrahn       /* Instead just set from the stored values.  */
692d2201f2fSdrahn       ntype = (s->udata.i >> 24) & 0xff;
693d2201f2fSdrahn       nsect = (s->udata.i >> 16) & 0xff;
694d2201f2fSdrahn       ndesc = s->udata.i & 0xffff;
695d2201f2fSdrahn 
696d2201f2fSdrahn       bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
697d2201f2fSdrahn       bfd_h_put_8 (abfd, ntype, buf + 4);
698d2201f2fSdrahn       bfd_h_put_8 (abfd, nsect, buf + 5);
699d2201f2fSdrahn       bfd_h_put_16 (abfd, ndesc, buf + 6);
700d2201f2fSdrahn       bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
701d2201f2fSdrahn 
702d2201f2fSdrahn       bfd_seek (abfd, symoff, SEEK_SET);
703d2201f2fSdrahn       if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
704d2201f2fSdrahn 	{
705d2201f2fSdrahn 	  fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
706d2201f2fSdrahn 		   12, (unsigned long) symoff);
707d2201f2fSdrahn 	  return -1;
708d2201f2fSdrahn 	}
709d2201f2fSdrahn     }
710d2201f2fSdrahn 
711d2201f2fSdrahn   return 0;
712d2201f2fSdrahn }
713d2201f2fSdrahn 
714d2201f2fSdrahn int
bfd_mach_o_scan_read_symtab_symbol(abfd,sym,s,i)715d2201f2fSdrahn bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)
716d2201f2fSdrahn      bfd *abfd;
717d2201f2fSdrahn      bfd_mach_o_symtab_command *sym;
718d2201f2fSdrahn      asymbol *s;
719d2201f2fSdrahn      unsigned long i;
720d2201f2fSdrahn {
721d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
722d2201f2fSdrahn   bfd_vma symoff = sym->symoff + (i * 12);
723d2201f2fSdrahn   unsigned char buf[12];
724d2201f2fSdrahn   unsigned char type = -1;
725d2201f2fSdrahn   unsigned char section = -1;
726d2201f2fSdrahn   short desc = -1;
727d2201f2fSdrahn   unsigned long value = -1;
728d2201f2fSdrahn   unsigned long stroff = -1;
729d2201f2fSdrahn   unsigned int symtype = -1;
730d2201f2fSdrahn 
731d2201f2fSdrahn   BFD_ASSERT (sym->strtab != NULL);
732d2201f2fSdrahn 
733d2201f2fSdrahn   bfd_seek (abfd, symoff, SEEK_SET);
734d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 12, abfd) != 12)
735d2201f2fSdrahn     {
736d2201f2fSdrahn       fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
737d2201f2fSdrahn 	       12, (unsigned long) symoff);
738d2201f2fSdrahn       return -1;
739d2201f2fSdrahn     }
740d2201f2fSdrahn 
741d2201f2fSdrahn   stroff = bfd_h_get_32 (abfd, buf);
742d2201f2fSdrahn   type = bfd_h_get_8 (abfd, buf + 4);
743d2201f2fSdrahn   symtype = (type & 0x0e);
744d2201f2fSdrahn   section = bfd_h_get_8 (abfd, buf + 5) - 1;
745d2201f2fSdrahn   desc = bfd_h_get_16 (abfd, buf + 6);
746d2201f2fSdrahn   value = bfd_h_get_32 (abfd, buf + 8);
747d2201f2fSdrahn 
748d2201f2fSdrahn   if (stroff >= sym->strsize)
749d2201f2fSdrahn     {
750d2201f2fSdrahn       fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
751d2201f2fSdrahn 	       (unsigned long) stroff, (unsigned long) sym->strsize);
752d2201f2fSdrahn       return -1;
753d2201f2fSdrahn     }
754d2201f2fSdrahn 
755d2201f2fSdrahn   s->the_bfd = abfd;
756d2201f2fSdrahn   s->name = sym->strtab + stroff;
757d2201f2fSdrahn   s->value = value;
758d2201f2fSdrahn   s->udata.i = (type << 24) | (section << 16) | desc;
759d2201f2fSdrahn   s->flags = 0x0;
760d2201f2fSdrahn 
761d2201f2fSdrahn   if (type & BFD_MACH_O_N_STAB)
762d2201f2fSdrahn     {
763d2201f2fSdrahn       s->flags |= BSF_DEBUGGING;
764d2201f2fSdrahn       s->section = bfd_und_section_ptr;
765d2201f2fSdrahn     }
766d2201f2fSdrahn   else
767d2201f2fSdrahn     {
768d2201f2fSdrahn       if (type & BFD_MACH_O_N_PEXT)
769d2201f2fSdrahn 	{
770d2201f2fSdrahn 	  type &= ~BFD_MACH_O_N_PEXT;
771d2201f2fSdrahn 	  s->flags |= BSF_GLOBAL;
772d2201f2fSdrahn 	}
773d2201f2fSdrahn 
774d2201f2fSdrahn       if (type & BFD_MACH_O_N_EXT)
775d2201f2fSdrahn 	{
776d2201f2fSdrahn 	  type &= ~BFD_MACH_O_N_EXT;
777d2201f2fSdrahn 	  s->flags |= BSF_GLOBAL;
778d2201f2fSdrahn 	}
779d2201f2fSdrahn 
780d2201f2fSdrahn       switch (symtype)
781d2201f2fSdrahn 	{
782d2201f2fSdrahn 	case BFD_MACH_O_N_UNDF:
783d2201f2fSdrahn 	  s->section = bfd_und_section_ptr;
784d2201f2fSdrahn 	  break;
785d2201f2fSdrahn 	case BFD_MACH_O_N_PBUD:
786d2201f2fSdrahn 	  s->section = bfd_und_section_ptr;
787d2201f2fSdrahn 	  break;
788d2201f2fSdrahn 	case BFD_MACH_O_N_ABS:
789d2201f2fSdrahn 	  s->section = bfd_abs_section_ptr;
790d2201f2fSdrahn 	  break;
791d2201f2fSdrahn 	case BFD_MACH_O_N_SECT:
792d2201f2fSdrahn 	  if ((section > 0) && (section <= mdata->nsects))
793d2201f2fSdrahn 	    {
794d2201f2fSdrahn 	      s->section = mdata->sections[section - 1]->bfdsection;
795d2201f2fSdrahn 	      s->value = s->value - mdata->sections[section - 1]->addr;
796d2201f2fSdrahn 	    }
797d2201f2fSdrahn 	  else
798d2201f2fSdrahn 	    {
799d2201f2fSdrahn 	      /* Mach-O uses 0 to mean "no section"; not an error.  */
800d2201f2fSdrahn 	      if (section != 0)
801d2201f2fSdrahn 		{
802d2201f2fSdrahn 		  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
803d2201f2fSdrahn 			   "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
804d2201f2fSdrahn 			   s->name, section, mdata->nsects);
805d2201f2fSdrahn 		}
806d2201f2fSdrahn 	      s->section = bfd_und_section_ptr;
807d2201f2fSdrahn 	    }
808d2201f2fSdrahn 	  break;
809d2201f2fSdrahn 	case BFD_MACH_O_N_INDR:
810d2201f2fSdrahn 	  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
811d2201f2fSdrahn 		   "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
812d2201f2fSdrahn 		   s->name);
813d2201f2fSdrahn 	  s->section = bfd_und_section_ptr;
814d2201f2fSdrahn 	  break;
815d2201f2fSdrahn 	default:
816d2201f2fSdrahn 	  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
817d2201f2fSdrahn 		   "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
818d2201f2fSdrahn 		   s->name, symtype);
819d2201f2fSdrahn 	  s->section = bfd_und_section_ptr;
820d2201f2fSdrahn 	  break;
821d2201f2fSdrahn 	}
822d2201f2fSdrahn     }
823d2201f2fSdrahn 
824d2201f2fSdrahn   return 0;
825d2201f2fSdrahn }
826d2201f2fSdrahn 
827d2201f2fSdrahn int
bfd_mach_o_scan_read_symtab_strtab(abfd,sym)828d2201f2fSdrahn bfd_mach_o_scan_read_symtab_strtab (abfd, sym)
829d2201f2fSdrahn      bfd *abfd;
830d2201f2fSdrahn      bfd_mach_o_symtab_command *sym;
831d2201f2fSdrahn {
832d2201f2fSdrahn   BFD_ASSERT (sym->strtab == NULL);
833d2201f2fSdrahn 
834d2201f2fSdrahn   if (abfd->flags & BFD_IN_MEMORY)
835d2201f2fSdrahn     {
836d2201f2fSdrahn       struct bfd_in_memory *b;
837d2201f2fSdrahn 
838d2201f2fSdrahn       b = (struct bfd_in_memory *) abfd->iostream;
839d2201f2fSdrahn 
840d2201f2fSdrahn       if ((sym->stroff + sym->strsize) > b->size)
841d2201f2fSdrahn 	{
842d2201f2fSdrahn 	  bfd_set_error (bfd_error_file_truncated);
843d2201f2fSdrahn 	  return -1;
844d2201f2fSdrahn 	}
845d2201f2fSdrahn       sym->strtab = b->buffer + sym->stroff;
846d2201f2fSdrahn       return 0;
847d2201f2fSdrahn     }
848d2201f2fSdrahn 
849d2201f2fSdrahn   sym->strtab = bfd_alloc (abfd, sym->strsize);
850d2201f2fSdrahn   if (sym->strtab == NULL)
851d2201f2fSdrahn     return -1;
852d2201f2fSdrahn 
853d2201f2fSdrahn   bfd_seek (abfd, sym->stroff, SEEK_SET);
854d2201f2fSdrahn   if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
855d2201f2fSdrahn     {
856d2201f2fSdrahn       fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
857d2201f2fSdrahn 	       sym->strsize, sym->stroff);
858d2201f2fSdrahn       return -1;
859d2201f2fSdrahn     }
860d2201f2fSdrahn 
861d2201f2fSdrahn   return 0;
862d2201f2fSdrahn }
863d2201f2fSdrahn 
864d2201f2fSdrahn int
bfd_mach_o_scan_read_symtab_symbols(abfd,sym)865d2201f2fSdrahn bfd_mach_o_scan_read_symtab_symbols (abfd, sym)
866d2201f2fSdrahn      bfd *abfd;
867d2201f2fSdrahn      bfd_mach_o_symtab_command *sym;
868d2201f2fSdrahn {
869d2201f2fSdrahn   unsigned long i;
870d2201f2fSdrahn   int ret;
871d2201f2fSdrahn 
872d2201f2fSdrahn   BFD_ASSERT (sym->symbols == NULL);
873d2201f2fSdrahn   sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
874d2201f2fSdrahn 
875d2201f2fSdrahn   if (sym->symbols == NULL)
876d2201f2fSdrahn     {
877d2201f2fSdrahn       fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
878d2201f2fSdrahn       return -1;
879d2201f2fSdrahn     }
880d2201f2fSdrahn 
881d2201f2fSdrahn   ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
882d2201f2fSdrahn   if (ret != 0)
883d2201f2fSdrahn     return ret;
884d2201f2fSdrahn 
885d2201f2fSdrahn   for (i = 0; i < sym->nsyms; i++)
886d2201f2fSdrahn     {
887d2201f2fSdrahn       ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
888d2201f2fSdrahn       if (ret != 0)
889d2201f2fSdrahn 	return ret;
890d2201f2fSdrahn     }
891d2201f2fSdrahn 
892d2201f2fSdrahn   return 0;
893d2201f2fSdrahn }
894d2201f2fSdrahn 
895d2201f2fSdrahn int
bfd_mach_o_scan_read_dysymtab_symbol(abfd,dysym,sym,s,i)896d2201f2fSdrahn bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, s, i)
897d2201f2fSdrahn      bfd *abfd;
898d2201f2fSdrahn      bfd_mach_o_dysymtab_command *dysym;
899d2201f2fSdrahn      bfd_mach_o_symtab_command *sym;
900d2201f2fSdrahn      asymbol *s;
901d2201f2fSdrahn      unsigned long i;
902d2201f2fSdrahn {
903d2201f2fSdrahn   unsigned long isymoff = dysym->indirectsymoff + (i * 4);
904d2201f2fSdrahn   unsigned long symindex;
905d2201f2fSdrahn   unsigned char buf[4];
906d2201f2fSdrahn 
907d2201f2fSdrahn   BFD_ASSERT (i < dysym->nindirectsyms);
908d2201f2fSdrahn 
909d2201f2fSdrahn   bfd_seek (abfd, isymoff, SEEK_SET);
910d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 4, abfd) != 4)
911d2201f2fSdrahn     {
912d2201f2fSdrahn       fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
913d2201f2fSdrahn 	       (unsigned long) 4, isymoff);
914d2201f2fSdrahn       return -1;
915d2201f2fSdrahn     }
916d2201f2fSdrahn   symindex = bfd_h_get_32 (abfd, buf);
917d2201f2fSdrahn 
918d2201f2fSdrahn   return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
919d2201f2fSdrahn }
920d2201f2fSdrahn 
921d2201f2fSdrahn static const char *
bfd_mach_o_i386_flavour_string(flavour)922d2201f2fSdrahn bfd_mach_o_i386_flavour_string (flavour)
923d2201f2fSdrahn      unsigned int flavour;
924d2201f2fSdrahn {
925d2201f2fSdrahn   switch ((int) flavour)
926d2201f2fSdrahn     {
927d2201f2fSdrahn     case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
928d2201f2fSdrahn     case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
929d2201f2fSdrahn     case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
930d2201f2fSdrahn     case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
931d2201f2fSdrahn     case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
932d2201f2fSdrahn     case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
933d2201f2fSdrahn     case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
934d2201f2fSdrahn     case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
935d2201f2fSdrahn     case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
936d2201f2fSdrahn     case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
937d2201f2fSdrahn     case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
938d2201f2fSdrahn     case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
939d2201f2fSdrahn     default: return "UNKNOWN";
940d2201f2fSdrahn     }
941d2201f2fSdrahn }
942d2201f2fSdrahn 
943d2201f2fSdrahn static const char *
bfd_mach_o_ppc_flavour_string(flavour)944d2201f2fSdrahn bfd_mach_o_ppc_flavour_string (flavour)
945d2201f2fSdrahn      unsigned int flavour;
946d2201f2fSdrahn {
947d2201f2fSdrahn   switch ((int) flavour)
948d2201f2fSdrahn     {
949d2201f2fSdrahn     case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
950d2201f2fSdrahn     case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
951d2201f2fSdrahn     case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
952d2201f2fSdrahn     case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
953d2201f2fSdrahn     default: return "UNKNOWN";
954d2201f2fSdrahn     }
955d2201f2fSdrahn }
956d2201f2fSdrahn 
957d2201f2fSdrahn static int
bfd_mach_o_scan_write_thread(abfd,command)958d2201f2fSdrahn bfd_mach_o_scan_write_thread (abfd, command)
959d2201f2fSdrahn      bfd *abfd;
960d2201f2fSdrahn      bfd_mach_o_load_command *command;
961d2201f2fSdrahn {
962d2201f2fSdrahn   bfd_mach_o_thread_command *cmd = &command->command.thread;
963d2201f2fSdrahn   unsigned int i;
964d2201f2fSdrahn   unsigned char buf[8];
965d2201f2fSdrahn   bfd_vma offset;
966d2201f2fSdrahn   unsigned int nflavours;
967d2201f2fSdrahn 
968d2201f2fSdrahn   BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
969d2201f2fSdrahn 	      || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
970d2201f2fSdrahn 
971d2201f2fSdrahn   offset = 8;
972d2201f2fSdrahn   nflavours = 0;
973d2201f2fSdrahn   for (i = 0; i < cmd->nflavours; i++)
974d2201f2fSdrahn     {
975d2201f2fSdrahn       BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
976d2201f2fSdrahn       BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
977d2201f2fSdrahn 
978d2201f2fSdrahn       bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
979d2201f2fSdrahn       bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
980d2201f2fSdrahn 
981d2201f2fSdrahn       bfd_seek (abfd, command->offset + offset, SEEK_SET);
982d2201f2fSdrahn       if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
983d2201f2fSdrahn 	return -1;
984d2201f2fSdrahn 
985d2201f2fSdrahn       offset += cmd->flavours[i].size + 8;
986d2201f2fSdrahn     }
987d2201f2fSdrahn 
988d2201f2fSdrahn   return 0;
989d2201f2fSdrahn }
990d2201f2fSdrahn 
991d2201f2fSdrahn static int
bfd_mach_o_scan_read_dylinker(abfd,command)992d2201f2fSdrahn bfd_mach_o_scan_read_dylinker (abfd, command)
993d2201f2fSdrahn      bfd *abfd;
994d2201f2fSdrahn      bfd_mach_o_load_command *command;
995d2201f2fSdrahn {
996d2201f2fSdrahn   bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
997d2201f2fSdrahn   unsigned char buf[4];
998d2201f2fSdrahn   unsigned int nameoff;
999d2201f2fSdrahn   asection *bfdsec;
1000d2201f2fSdrahn   char *sname;
1001d2201f2fSdrahn   const char *prefix;
1002d2201f2fSdrahn 
1003d2201f2fSdrahn   BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1004d2201f2fSdrahn 	      || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1005d2201f2fSdrahn 
1006d2201f2fSdrahn   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1007d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 4, abfd) != 4)
1008d2201f2fSdrahn     return -1;
1009d2201f2fSdrahn 
1010d2201f2fSdrahn   nameoff = bfd_h_get_32 (abfd, buf + 0);
1011d2201f2fSdrahn 
1012d2201f2fSdrahn   cmd->name_offset = command->offset + nameoff;
1013d2201f2fSdrahn   cmd->name_len = command->len - nameoff;
1014d2201f2fSdrahn 
1015d2201f2fSdrahn   if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
1016d2201f2fSdrahn     prefix = "LC_LOAD_DYLINKER";
1017d2201f2fSdrahn   else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
1018d2201f2fSdrahn     prefix = "LC_ID_DYLINKER";
1019d2201f2fSdrahn   else
1020d2201f2fSdrahn     abort ();
1021d2201f2fSdrahn 
1022d2201f2fSdrahn   sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1023d2201f2fSdrahn   if (sname == NULL)
1024d2201f2fSdrahn     return -1;
1025d2201f2fSdrahn   strcpy (sname, prefix);
1026d2201f2fSdrahn 
1027d2201f2fSdrahn   bfdsec = bfd_make_section_anyway (abfd, sname);
1028d2201f2fSdrahn   if (bfdsec == NULL)
1029d2201f2fSdrahn     return -1;
1030d2201f2fSdrahn 
1031d2201f2fSdrahn   bfdsec->vma = 0;
1032d2201f2fSdrahn   bfdsec->lma = 0;
1033d2201f2fSdrahn   bfdsec->_raw_size = command->len - 8;
1034d2201f2fSdrahn   bfdsec->filepos = command->offset + 8;
1035d2201f2fSdrahn   bfdsec->alignment_power = 0;
1036d2201f2fSdrahn   bfdsec->flags = SEC_HAS_CONTENTS;
1037d2201f2fSdrahn 
1038d2201f2fSdrahn   cmd->section = bfdsec;
1039d2201f2fSdrahn 
1040d2201f2fSdrahn   return 0;
1041d2201f2fSdrahn }
1042d2201f2fSdrahn 
1043d2201f2fSdrahn static int
bfd_mach_o_scan_read_dylib(abfd,command)1044d2201f2fSdrahn bfd_mach_o_scan_read_dylib (abfd, command)
1045d2201f2fSdrahn      bfd *abfd;
1046d2201f2fSdrahn      bfd_mach_o_load_command *command;
1047d2201f2fSdrahn {
1048d2201f2fSdrahn   bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1049d2201f2fSdrahn   unsigned char buf[16];
1050d2201f2fSdrahn   unsigned int nameoff;
1051d2201f2fSdrahn   asection *bfdsec;
1052d2201f2fSdrahn   char *sname;
1053d2201f2fSdrahn   const char *prefix;
1054d2201f2fSdrahn 
1055d2201f2fSdrahn   BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1056d2201f2fSdrahn 	      || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1057d2201f2fSdrahn 	      || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1058d2201f2fSdrahn 
1059d2201f2fSdrahn   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1060d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1061d2201f2fSdrahn     return -1;
1062d2201f2fSdrahn 
1063d2201f2fSdrahn   nameoff = bfd_h_get_32 (abfd, buf + 0);
1064d2201f2fSdrahn   cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1065d2201f2fSdrahn   cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1066d2201f2fSdrahn   cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1067d2201f2fSdrahn 
1068d2201f2fSdrahn   cmd->name_offset = command->offset + nameoff;
1069d2201f2fSdrahn   cmd->name_len = command->len - nameoff;
1070d2201f2fSdrahn 
1071d2201f2fSdrahn   if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1072d2201f2fSdrahn     prefix = "LC_LOAD_DYLIB";
1073d2201f2fSdrahn   else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1074d2201f2fSdrahn     prefix = "LC_LOAD_WEAK_DYLIB";
1075d2201f2fSdrahn   else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1076d2201f2fSdrahn     prefix = "LC_ID_DYLIB";
1077d2201f2fSdrahn   else
1078d2201f2fSdrahn     abort ();
1079d2201f2fSdrahn 
1080d2201f2fSdrahn   sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1081d2201f2fSdrahn   if (sname == NULL)
1082d2201f2fSdrahn     return -1;
1083d2201f2fSdrahn   strcpy (sname, prefix);
1084d2201f2fSdrahn 
1085d2201f2fSdrahn   bfdsec = bfd_make_section_anyway (abfd, sname);
1086d2201f2fSdrahn   if (bfdsec == NULL)
1087d2201f2fSdrahn     return -1;
1088d2201f2fSdrahn 
1089d2201f2fSdrahn   bfdsec->vma = 0;
1090d2201f2fSdrahn   bfdsec->lma = 0;
1091d2201f2fSdrahn   bfdsec->_raw_size = command->len - 8;
1092d2201f2fSdrahn   bfdsec->filepos = command->offset + 8;
1093d2201f2fSdrahn   bfdsec->alignment_power = 0;
1094d2201f2fSdrahn   bfdsec->flags = SEC_HAS_CONTENTS;
1095d2201f2fSdrahn 
1096d2201f2fSdrahn   cmd->section = bfdsec;
1097d2201f2fSdrahn 
1098d2201f2fSdrahn   return 0;
1099d2201f2fSdrahn }
1100d2201f2fSdrahn 
1101d2201f2fSdrahn static int
bfd_mach_o_scan_read_prebound_dylib(abfd,command)1102d2201f2fSdrahn bfd_mach_o_scan_read_prebound_dylib (abfd, command)
1103d2201f2fSdrahn      bfd *abfd ATTRIBUTE_UNUSED;
1104d2201f2fSdrahn      bfd_mach_o_load_command *command ATTRIBUTE_UNUSED;
1105d2201f2fSdrahn {
1106d2201f2fSdrahn   /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1107d2201f2fSdrahn 
1108d2201f2fSdrahn   BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1109d2201f2fSdrahn   return 0;
1110d2201f2fSdrahn }
1111d2201f2fSdrahn 
1112d2201f2fSdrahn static int
bfd_mach_o_scan_read_thread(abfd,command)1113d2201f2fSdrahn bfd_mach_o_scan_read_thread (abfd, command)
1114d2201f2fSdrahn      bfd *abfd;
1115d2201f2fSdrahn      bfd_mach_o_load_command *command;
1116d2201f2fSdrahn {
1117d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = NULL;
1118d2201f2fSdrahn   bfd_mach_o_thread_command *cmd = &command->command.thread;
1119d2201f2fSdrahn   unsigned char buf[8];
1120d2201f2fSdrahn   bfd_vma offset;
1121d2201f2fSdrahn   unsigned int nflavours;
1122d2201f2fSdrahn   unsigned int i;
1123d2201f2fSdrahn 
1124d2201f2fSdrahn   BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1125d2201f2fSdrahn 	      || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1126d2201f2fSdrahn 
1127d2201f2fSdrahn   BFD_ASSERT (bfd_mach_o_valid (abfd));
1128d2201f2fSdrahn   mdata = abfd->tdata.mach_o_data;
1129d2201f2fSdrahn 
1130d2201f2fSdrahn   offset = 8;
1131d2201f2fSdrahn   nflavours = 0;
1132d2201f2fSdrahn   while (offset != command->len)
1133d2201f2fSdrahn     {
1134d2201f2fSdrahn       if (offset >= command->len)
1135d2201f2fSdrahn 	return -1;
1136d2201f2fSdrahn 
1137d2201f2fSdrahn       bfd_seek (abfd, command->offset + offset, SEEK_SET);
1138d2201f2fSdrahn 
1139d2201f2fSdrahn       if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1140d2201f2fSdrahn 	return -1;
1141d2201f2fSdrahn 
1142d2201f2fSdrahn       offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1143d2201f2fSdrahn       nflavours++;
1144d2201f2fSdrahn     }
1145d2201f2fSdrahn 
1146d2201f2fSdrahn   cmd->flavours =
1147d2201f2fSdrahn     ((bfd_mach_o_thread_flavour *)
1148d2201f2fSdrahn      bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour)));
1149d2201f2fSdrahn   if (cmd->flavours == NULL)
1150d2201f2fSdrahn     return -1;
1151d2201f2fSdrahn   cmd->nflavours = nflavours;
1152d2201f2fSdrahn 
1153d2201f2fSdrahn   offset = 8;
1154d2201f2fSdrahn   nflavours = 0;
1155d2201f2fSdrahn   while (offset != command->len)
1156d2201f2fSdrahn     {
1157d2201f2fSdrahn       if (offset >= command->len)
1158d2201f2fSdrahn 	return -1;
1159d2201f2fSdrahn 
1160d2201f2fSdrahn       if (nflavours >= cmd->nflavours)
1161d2201f2fSdrahn 	return -1;
1162d2201f2fSdrahn 
1163d2201f2fSdrahn       bfd_seek (abfd, command->offset + offset, SEEK_SET);
1164d2201f2fSdrahn 
1165d2201f2fSdrahn       if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1166d2201f2fSdrahn 	return -1;
1167d2201f2fSdrahn 
1168d2201f2fSdrahn       cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1169d2201f2fSdrahn       cmd->flavours[nflavours].offset = command->offset + offset + 8;
1170d2201f2fSdrahn       cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1171d2201f2fSdrahn       offset += cmd->flavours[nflavours].size + 8;
1172d2201f2fSdrahn       nflavours++;
1173d2201f2fSdrahn     }
1174d2201f2fSdrahn 
1175d2201f2fSdrahn   for (i = 0; i < nflavours; i++)
1176d2201f2fSdrahn     {
1177d2201f2fSdrahn       asection *bfdsec;
1178d2201f2fSdrahn       unsigned int snamelen;
1179d2201f2fSdrahn       char *sname;
1180d2201f2fSdrahn       const char *flavourstr;
1181d2201f2fSdrahn       const char *prefix = "LC_THREAD";
1182d2201f2fSdrahn       unsigned int j = 0;
1183d2201f2fSdrahn 
1184d2201f2fSdrahn       switch (mdata->header.cputype)
1185d2201f2fSdrahn 	{
1186d2201f2fSdrahn 	case BFD_MACH_O_CPU_TYPE_POWERPC:
1187d2201f2fSdrahn 	  flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1188d2201f2fSdrahn 	  break;
1189d2201f2fSdrahn 	case BFD_MACH_O_CPU_TYPE_I386:
1190d2201f2fSdrahn 	  flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1191d2201f2fSdrahn 	  break;
1192d2201f2fSdrahn 	default:
1193d2201f2fSdrahn 	  flavourstr = "UNKNOWN_ARCHITECTURE";
1194d2201f2fSdrahn 	  break;
1195d2201f2fSdrahn 	}
1196d2201f2fSdrahn 
1197d2201f2fSdrahn       snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1198d2201f2fSdrahn       sname = (char *) bfd_alloc (abfd, snamelen);
1199d2201f2fSdrahn       if (sname == NULL)
1200d2201f2fSdrahn 	return -1;
1201d2201f2fSdrahn 
1202d2201f2fSdrahn       for (;;)
1203d2201f2fSdrahn 	{
1204d2201f2fSdrahn 	  sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1205d2201f2fSdrahn 	  if (bfd_get_section_by_name (abfd, sname) == NULL)
1206d2201f2fSdrahn 	    break;
1207d2201f2fSdrahn 	  j++;
1208d2201f2fSdrahn 	}
1209d2201f2fSdrahn 
1210d2201f2fSdrahn       bfdsec = bfd_make_section (abfd, sname);
1211d2201f2fSdrahn 
1212d2201f2fSdrahn       bfdsec->vma = 0;
1213d2201f2fSdrahn       bfdsec->lma = 0;
1214d2201f2fSdrahn       bfdsec->_raw_size = cmd->flavours[i].size;
1215d2201f2fSdrahn       bfdsec->filepos = cmd->flavours[i].offset;
1216d2201f2fSdrahn       bfdsec->alignment_power = 0x0;
1217d2201f2fSdrahn       bfdsec->flags = SEC_HAS_CONTENTS;
1218d2201f2fSdrahn 
1219d2201f2fSdrahn       cmd->section = bfdsec;
1220d2201f2fSdrahn     }
1221d2201f2fSdrahn 
1222d2201f2fSdrahn   return 0;
1223d2201f2fSdrahn }
1224d2201f2fSdrahn 
1225d2201f2fSdrahn static int
bfd_mach_o_scan_write_symtab(abfd,command)1226d2201f2fSdrahn bfd_mach_o_scan_write_symtab (abfd, command)
1227d2201f2fSdrahn      bfd *abfd;
1228d2201f2fSdrahn      bfd_mach_o_load_command *command;
1229d2201f2fSdrahn {
1230d2201f2fSdrahn   bfd_mach_o_symtab_command *seg = &command->command.symtab;
1231d2201f2fSdrahn   unsigned char buf[16];
1232d2201f2fSdrahn 
1233d2201f2fSdrahn   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1234d2201f2fSdrahn 
1235d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->symoff, buf);
1236d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
1237d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->stroff, buf + 8);
1238d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->strsize, buf + 12);
1239d2201f2fSdrahn 
1240d2201f2fSdrahn   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1241d2201f2fSdrahn   if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
1242d2201f2fSdrahn     return -1;
1243d2201f2fSdrahn 
1244d2201f2fSdrahn   if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
1245d2201f2fSdrahn     return -1;
1246d2201f2fSdrahn 
1247d2201f2fSdrahn   return 0;
1248d2201f2fSdrahn }
1249d2201f2fSdrahn 
1250d2201f2fSdrahn static int
bfd_mach_o_scan_read_dysymtab(abfd,command)1251d2201f2fSdrahn bfd_mach_o_scan_read_dysymtab (abfd, command)
1252d2201f2fSdrahn      bfd *abfd;
1253d2201f2fSdrahn      bfd_mach_o_load_command *command;
1254d2201f2fSdrahn {
1255d2201f2fSdrahn   bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1256d2201f2fSdrahn   unsigned char buf[72];
1257d2201f2fSdrahn 
1258d2201f2fSdrahn   BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1259d2201f2fSdrahn 
1260d2201f2fSdrahn   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1261d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1262d2201f2fSdrahn     return -1;
1263d2201f2fSdrahn 
1264d2201f2fSdrahn   seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1265d2201f2fSdrahn   seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1266d2201f2fSdrahn   seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1267d2201f2fSdrahn   seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1268d2201f2fSdrahn   seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1269d2201f2fSdrahn   seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1270d2201f2fSdrahn   seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1271d2201f2fSdrahn   seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1272d2201f2fSdrahn   seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1273d2201f2fSdrahn   seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1274d2201f2fSdrahn   seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1275d2201f2fSdrahn   seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1276d2201f2fSdrahn   seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1277d2201f2fSdrahn   seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1278d2201f2fSdrahn   seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1279d2201f2fSdrahn   seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1280d2201f2fSdrahn   seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1281d2201f2fSdrahn   seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1282d2201f2fSdrahn 
1283d2201f2fSdrahn   return 0;
1284d2201f2fSdrahn }
1285d2201f2fSdrahn 
1286d2201f2fSdrahn static int
bfd_mach_o_scan_read_symtab(abfd,command)1287d2201f2fSdrahn bfd_mach_o_scan_read_symtab (abfd, command)
1288d2201f2fSdrahn      bfd *abfd;
1289d2201f2fSdrahn      bfd_mach_o_load_command *command;
1290d2201f2fSdrahn {
1291d2201f2fSdrahn   bfd_mach_o_symtab_command *seg = &command->command.symtab;
1292d2201f2fSdrahn   unsigned char buf[16];
1293d2201f2fSdrahn   asection *bfdsec;
1294d2201f2fSdrahn   char *sname;
1295d2201f2fSdrahn   const char *prefix = "LC_SYMTAB.stabs";
1296d2201f2fSdrahn 
1297d2201f2fSdrahn   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1298d2201f2fSdrahn 
1299d2201f2fSdrahn   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1300d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1301d2201f2fSdrahn     return -1;
1302d2201f2fSdrahn 
1303d2201f2fSdrahn   seg->symoff = bfd_h_get_32 (abfd, buf);
1304d2201f2fSdrahn   seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1305d2201f2fSdrahn   seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1306d2201f2fSdrahn   seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1307d2201f2fSdrahn   seg->symbols = NULL;
1308d2201f2fSdrahn   seg->strtab = NULL;
1309d2201f2fSdrahn 
1310d2201f2fSdrahn   sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1311d2201f2fSdrahn   if (sname == NULL)
1312d2201f2fSdrahn     return -1;
1313d2201f2fSdrahn   strcpy (sname, prefix);
1314d2201f2fSdrahn 
1315d2201f2fSdrahn   bfdsec = bfd_make_section_anyway (abfd, sname);
1316d2201f2fSdrahn   if (bfdsec == NULL)
1317d2201f2fSdrahn     return -1;
1318d2201f2fSdrahn 
1319d2201f2fSdrahn   bfdsec->vma = 0;
1320d2201f2fSdrahn   bfdsec->lma = 0;
1321d2201f2fSdrahn   bfdsec->_raw_size = seg->nsyms * 12;
1322d2201f2fSdrahn   bfdsec->filepos = seg->symoff;
1323d2201f2fSdrahn   bfdsec->alignment_power = 0;
1324d2201f2fSdrahn   bfdsec->flags = SEC_HAS_CONTENTS;
1325d2201f2fSdrahn 
1326d2201f2fSdrahn   seg->stabs_segment = bfdsec;
1327d2201f2fSdrahn 
1328d2201f2fSdrahn   prefix = "LC_SYMTAB.stabstr";
1329d2201f2fSdrahn   sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1330d2201f2fSdrahn   if (sname == NULL)
1331d2201f2fSdrahn     return -1;
1332d2201f2fSdrahn   strcpy (sname, prefix);
1333d2201f2fSdrahn 
1334d2201f2fSdrahn   bfdsec = bfd_make_section_anyway (abfd, sname);
1335d2201f2fSdrahn   if (bfdsec == NULL)
1336d2201f2fSdrahn     return -1;
1337d2201f2fSdrahn 
1338d2201f2fSdrahn   bfdsec->vma = 0;
1339d2201f2fSdrahn   bfdsec->lma = 0;
1340d2201f2fSdrahn   bfdsec->_raw_size = seg->strsize;
1341d2201f2fSdrahn   bfdsec->filepos = seg->stroff;
1342d2201f2fSdrahn   bfdsec->alignment_power = 0;
1343d2201f2fSdrahn   bfdsec->flags = SEC_HAS_CONTENTS;
1344d2201f2fSdrahn 
1345d2201f2fSdrahn   seg->stabstr_segment = bfdsec;
1346d2201f2fSdrahn 
1347d2201f2fSdrahn   return 0;
1348d2201f2fSdrahn }
1349d2201f2fSdrahn 
1350d2201f2fSdrahn static int
bfd_mach_o_scan_read_segment(abfd,command)1351d2201f2fSdrahn bfd_mach_o_scan_read_segment (abfd, command)
1352d2201f2fSdrahn      bfd *abfd;
1353d2201f2fSdrahn      bfd_mach_o_load_command *command;
1354d2201f2fSdrahn {
1355d2201f2fSdrahn   unsigned char buf[48];
1356d2201f2fSdrahn   bfd_mach_o_segment_command *seg = &command->command.segment;
1357d2201f2fSdrahn   unsigned long i;
1358d2201f2fSdrahn   asection *bfdsec;
1359d2201f2fSdrahn   char *sname;
1360d2201f2fSdrahn   const char *prefix = "LC_SEGMENT";
1361d2201f2fSdrahn   unsigned int snamelen;
1362d2201f2fSdrahn 
1363d2201f2fSdrahn   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1364d2201f2fSdrahn 
1365d2201f2fSdrahn   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1366d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1367d2201f2fSdrahn     return -1;
1368d2201f2fSdrahn 
1369d2201f2fSdrahn   memcpy (seg->segname, buf, 16);
1370d2201f2fSdrahn   seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1371d2201f2fSdrahn   seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1372d2201f2fSdrahn   seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1373d2201f2fSdrahn   seg->filesize = bfd_h_get_32 (abfd, buf +  28);
1374d2201f2fSdrahn   /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1375d2201f2fSdrahn   /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1376d2201f2fSdrahn   seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1377d2201f2fSdrahn   seg->flags = bfd_h_get_32 (abfd, buf + 44);
1378d2201f2fSdrahn 
1379d2201f2fSdrahn   snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1380d2201f2fSdrahn   sname = (char *) bfd_alloc (abfd, snamelen);
1381d2201f2fSdrahn   if (sname == NULL)
1382d2201f2fSdrahn     return -1;
1383d2201f2fSdrahn   sprintf (sname, "%s.%s", prefix, seg->segname);
1384d2201f2fSdrahn 
1385d2201f2fSdrahn   bfdsec = bfd_make_section_anyway (abfd, sname);
1386d2201f2fSdrahn   if (bfdsec == NULL)
1387d2201f2fSdrahn     return -1;
1388d2201f2fSdrahn 
1389d2201f2fSdrahn   bfdsec->vma = seg->vmaddr;
1390d2201f2fSdrahn   bfdsec->lma = seg->vmaddr;
1391d2201f2fSdrahn   bfdsec->_raw_size = seg->filesize;
1392d2201f2fSdrahn   bfdsec->filepos = seg->fileoff;
1393d2201f2fSdrahn   bfdsec->alignment_power = 0x0;
1394d2201f2fSdrahn   bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1395d2201f2fSdrahn 
1396d2201f2fSdrahn   seg->segment = bfdsec;
1397d2201f2fSdrahn 
1398d2201f2fSdrahn   if (seg->nsects != 0)
1399d2201f2fSdrahn     {
1400d2201f2fSdrahn       seg->sections =
1401d2201f2fSdrahn 	((bfd_mach_o_section *)
1402d2201f2fSdrahn 	 bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)));
1403d2201f2fSdrahn       if (seg->sections == NULL)
1404d2201f2fSdrahn 	return -1;
1405d2201f2fSdrahn 
1406d2201f2fSdrahn       for (i = 0; i < seg->nsects; i++)
1407d2201f2fSdrahn 	{
1408d2201f2fSdrahn 	  bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1409d2201f2fSdrahn 
1410d2201f2fSdrahn 	  if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1411d2201f2fSdrahn 					    segoff) != 0)
1412d2201f2fSdrahn 	    return -1;
1413d2201f2fSdrahn 	}
1414d2201f2fSdrahn     }
1415d2201f2fSdrahn 
1416d2201f2fSdrahn   return 0;
1417d2201f2fSdrahn }
1418d2201f2fSdrahn 
1419d2201f2fSdrahn static int
bfd_mach_o_scan_write_segment(abfd,command)1420d2201f2fSdrahn bfd_mach_o_scan_write_segment (abfd, command)
1421d2201f2fSdrahn      bfd *abfd;
1422d2201f2fSdrahn      bfd_mach_o_load_command *command;
1423d2201f2fSdrahn {
1424d2201f2fSdrahn   unsigned char buf[48];
1425d2201f2fSdrahn   bfd_mach_o_segment_command *seg = &command->command.segment;
1426d2201f2fSdrahn   unsigned long i;
1427d2201f2fSdrahn 
1428d2201f2fSdrahn   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1429d2201f2fSdrahn 
1430d2201f2fSdrahn   memcpy (buf, seg->segname, 16);
1431d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
1432d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
1433d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
1434d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->filesize, buf + 28);
1435d2201f2fSdrahn   bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
1436d2201f2fSdrahn   bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
1437d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->nsects, buf + 40);
1438d2201f2fSdrahn   bfd_h_put_32 (abfd, seg->flags, buf + 44);
1439d2201f2fSdrahn 
1440d2201f2fSdrahn   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1441d2201f2fSdrahn   if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
1442d2201f2fSdrahn     return -1;
1443d2201f2fSdrahn 
1444d2201f2fSdrahn   {
1445d2201f2fSdrahn     char buf[1024];
1446d2201f2fSdrahn     bfd_vma nbytes = seg->filesize;
1447d2201f2fSdrahn     bfd_vma curoff = seg->fileoff;
1448d2201f2fSdrahn 
1449d2201f2fSdrahn     while (nbytes > 0)
1450d2201f2fSdrahn       {
1451d2201f2fSdrahn 	bfd_vma thisread = nbytes;
1452d2201f2fSdrahn 
1453d2201f2fSdrahn 	if (thisread > 1024)
1454d2201f2fSdrahn 	  thisread = 1024;
1455d2201f2fSdrahn 
1456d2201f2fSdrahn 	bfd_seek (abfd, curoff, SEEK_SET);
1457d2201f2fSdrahn 	if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
1458d2201f2fSdrahn 	  return -1;
1459d2201f2fSdrahn 
1460d2201f2fSdrahn 	bfd_seek (abfd, curoff, SEEK_SET);
1461d2201f2fSdrahn 	if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
1462d2201f2fSdrahn 	  return -1;
1463d2201f2fSdrahn 
1464d2201f2fSdrahn 	nbytes -= thisread;
1465d2201f2fSdrahn 	curoff += thisread;
1466d2201f2fSdrahn       }
1467d2201f2fSdrahn   }
1468d2201f2fSdrahn 
1469d2201f2fSdrahn   for (i = 0; i < seg->nsects; i++)
1470d2201f2fSdrahn     {
1471d2201f2fSdrahn       bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1472d2201f2fSdrahn 
1473d2201f2fSdrahn       if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
1474d2201f2fSdrahn 	return -1;
1475d2201f2fSdrahn     }
1476d2201f2fSdrahn 
1477d2201f2fSdrahn   return 0;
1478d2201f2fSdrahn }
1479d2201f2fSdrahn 
1480d2201f2fSdrahn static int
bfd_mach_o_scan_read_command(abfd,command)1481d2201f2fSdrahn bfd_mach_o_scan_read_command (abfd, command)
1482d2201f2fSdrahn      bfd *abfd;
1483d2201f2fSdrahn      bfd_mach_o_load_command *command;
1484d2201f2fSdrahn {
1485d2201f2fSdrahn   unsigned char buf[8];
1486d2201f2fSdrahn 
1487d2201f2fSdrahn   bfd_seek (abfd, command->offset, SEEK_SET);
1488d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1489d2201f2fSdrahn     return -1;
1490d2201f2fSdrahn 
1491d2201f2fSdrahn   command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1492d2201f2fSdrahn   command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1493d2201f2fSdrahn 			    ? 1 : 0);
1494d2201f2fSdrahn   command->len = bfd_h_get_32 (abfd, buf + 4);
1495d2201f2fSdrahn 
1496d2201f2fSdrahn   switch (command->type)
1497d2201f2fSdrahn     {
1498d2201f2fSdrahn     case BFD_MACH_O_LC_SEGMENT:
1499d2201f2fSdrahn       if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1500d2201f2fSdrahn 	return -1;
1501d2201f2fSdrahn       break;
1502d2201f2fSdrahn     case BFD_MACH_O_LC_SYMTAB:
1503d2201f2fSdrahn       if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1504d2201f2fSdrahn 	return -1;
1505d2201f2fSdrahn       break;
1506d2201f2fSdrahn     case BFD_MACH_O_LC_SYMSEG:
1507d2201f2fSdrahn       break;
1508d2201f2fSdrahn     case BFD_MACH_O_LC_THREAD:
1509d2201f2fSdrahn     case BFD_MACH_O_LC_UNIXTHREAD:
1510d2201f2fSdrahn       if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1511d2201f2fSdrahn 	return -1;
1512d2201f2fSdrahn       break;
1513d2201f2fSdrahn     case BFD_MACH_O_LC_LOAD_DYLINKER:
1514d2201f2fSdrahn     case BFD_MACH_O_LC_ID_DYLINKER:
1515d2201f2fSdrahn       if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1516d2201f2fSdrahn 	return -1;
1517d2201f2fSdrahn       break;
1518d2201f2fSdrahn     case BFD_MACH_O_LC_LOAD_DYLIB:
1519d2201f2fSdrahn     case BFD_MACH_O_LC_ID_DYLIB:
1520d2201f2fSdrahn     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1521d2201f2fSdrahn       if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1522d2201f2fSdrahn 	return -1;
1523d2201f2fSdrahn       break;
1524d2201f2fSdrahn     case BFD_MACH_O_LC_PREBOUND_DYLIB:
1525d2201f2fSdrahn       if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1526d2201f2fSdrahn 	return -1;
1527d2201f2fSdrahn       break;
1528d2201f2fSdrahn     case BFD_MACH_O_LC_LOADFVMLIB:
1529d2201f2fSdrahn     case BFD_MACH_O_LC_IDFVMLIB:
1530d2201f2fSdrahn     case BFD_MACH_O_LC_IDENT:
1531d2201f2fSdrahn     case BFD_MACH_O_LC_FVMFILE:
1532d2201f2fSdrahn     case BFD_MACH_O_LC_PREPAGE:
1533d2201f2fSdrahn     case BFD_MACH_O_LC_ROUTINES:
1534d2201f2fSdrahn     case BFD_MACH_O_LC_SUB_FRAMEWORK:
1535d2201f2fSdrahn       break;
1536d2201f2fSdrahn     case BFD_MACH_O_LC_DYSYMTAB:
1537d2201f2fSdrahn       if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1538d2201f2fSdrahn 	return -1;
1539d2201f2fSdrahn       break;
1540d2201f2fSdrahn     case BFD_MACH_O_LC_SUB_UMBRELLA:
1541d2201f2fSdrahn     case BFD_MACH_O_LC_SUB_CLIENT:
1542d2201f2fSdrahn     case BFD_MACH_O_LC_SUB_LIBRARY:
1543d2201f2fSdrahn     case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1544d2201f2fSdrahn     case BFD_MACH_O_LC_PREBIND_CKSUM:
1545d2201f2fSdrahn       break;
1546d2201f2fSdrahn     default:
1547d2201f2fSdrahn       fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1548d2201f2fSdrahn 	       (unsigned long) command->type);
1549d2201f2fSdrahn       break;
1550d2201f2fSdrahn     }
1551d2201f2fSdrahn 
1552d2201f2fSdrahn   return 0;
1553d2201f2fSdrahn }
1554d2201f2fSdrahn 
1555d2201f2fSdrahn static void
bfd_mach_o_flatten_sections(abfd)1556d2201f2fSdrahn bfd_mach_o_flatten_sections (abfd)
1557d2201f2fSdrahn      bfd *abfd;
1558d2201f2fSdrahn {
1559d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1560d2201f2fSdrahn   long csect = 0;
1561d2201f2fSdrahn   unsigned long i, j;
1562d2201f2fSdrahn 
1563d2201f2fSdrahn   mdata->nsects = 0;
1564d2201f2fSdrahn 
1565d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
1566d2201f2fSdrahn     {
1567d2201f2fSdrahn       if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1568d2201f2fSdrahn 	{
1569d2201f2fSdrahn 	  bfd_mach_o_segment_command *seg;
1570d2201f2fSdrahn 
1571d2201f2fSdrahn 	  seg = &mdata->commands[i].command.segment;
1572d2201f2fSdrahn 	  mdata->nsects += seg->nsects;
1573d2201f2fSdrahn 	}
1574d2201f2fSdrahn     }
1575d2201f2fSdrahn 
1576d2201f2fSdrahn   mdata->sections = bfd_alloc (abfd,
1577d2201f2fSdrahn 			       mdata->nsects * sizeof (bfd_mach_o_section *));
1578d2201f2fSdrahn   csect = 0;
1579d2201f2fSdrahn 
1580d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
1581d2201f2fSdrahn     {
1582d2201f2fSdrahn       if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1583d2201f2fSdrahn 	{
1584d2201f2fSdrahn 	  bfd_mach_o_segment_command *seg;
1585d2201f2fSdrahn 
1586d2201f2fSdrahn 	  seg = &mdata->commands[i].command.segment;
1587d2201f2fSdrahn 	  BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1588d2201f2fSdrahn 
1589d2201f2fSdrahn 	  for (j = 0; j < seg->nsects; j++)
1590d2201f2fSdrahn 	    mdata->sections[csect++] = &seg->sections[j];
1591d2201f2fSdrahn 	}
1592d2201f2fSdrahn     }
1593d2201f2fSdrahn }
1594d2201f2fSdrahn 
1595d2201f2fSdrahn int
bfd_mach_o_scan_start_address(abfd)1596d2201f2fSdrahn bfd_mach_o_scan_start_address (abfd)
1597d2201f2fSdrahn      bfd *abfd;
1598d2201f2fSdrahn {
1599d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1600d2201f2fSdrahn   bfd_mach_o_thread_command *cmd = NULL;
1601d2201f2fSdrahn   unsigned long i;
1602d2201f2fSdrahn 
1603d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
1604d2201f2fSdrahn     {
1605d2201f2fSdrahn       if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1606d2201f2fSdrahn 	  (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1607d2201f2fSdrahn 	{
1608d2201f2fSdrahn 	  if (cmd == NULL)
1609d2201f2fSdrahn 	    cmd = &mdata->commands[i].command.thread;
1610d2201f2fSdrahn 	  else
1611d2201f2fSdrahn 	    return 0;
1612d2201f2fSdrahn 	}
1613d2201f2fSdrahn     }
1614d2201f2fSdrahn 
1615d2201f2fSdrahn   if (cmd == NULL)
1616d2201f2fSdrahn     return 0;
1617d2201f2fSdrahn 
1618d2201f2fSdrahn   for (i = 0; i < cmd->nflavours; i++)
1619d2201f2fSdrahn     {
1620d2201f2fSdrahn       if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1621d2201f2fSdrahn 	  && (cmd->flavours[i].flavour
1622d2201f2fSdrahn 	      == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1623d2201f2fSdrahn 	{
1624d2201f2fSdrahn 	  unsigned char buf[4];
1625d2201f2fSdrahn 
1626d2201f2fSdrahn 	  bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1627d2201f2fSdrahn 
1628d2201f2fSdrahn 	  if (bfd_bread (buf, 4, abfd) != 4)
1629d2201f2fSdrahn 	    return -1;
1630d2201f2fSdrahn 
1631d2201f2fSdrahn 	  abfd->start_address = bfd_h_get_32 (abfd, buf);
1632d2201f2fSdrahn 	}
1633d2201f2fSdrahn       else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1634d2201f2fSdrahn 	       && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1635d2201f2fSdrahn 	{
1636d2201f2fSdrahn 	  unsigned char buf[4];
1637d2201f2fSdrahn 
1638d2201f2fSdrahn 	  bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1639d2201f2fSdrahn 
1640d2201f2fSdrahn 	  if (bfd_bread (buf, 4, abfd) != 4)
1641d2201f2fSdrahn 	    return -1;
1642d2201f2fSdrahn 
1643d2201f2fSdrahn 	  abfd->start_address = bfd_h_get_32 (abfd, buf);
1644d2201f2fSdrahn 	}
1645d2201f2fSdrahn     }
1646d2201f2fSdrahn 
1647d2201f2fSdrahn   return 0;
1648d2201f2fSdrahn }
1649d2201f2fSdrahn 
1650d2201f2fSdrahn int
bfd_mach_o_scan(abfd,header,mdata)1651d2201f2fSdrahn bfd_mach_o_scan (abfd, header, mdata)
1652d2201f2fSdrahn      bfd *abfd;
1653d2201f2fSdrahn      bfd_mach_o_header *header;
1654d2201f2fSdrahn      bfd_mach_o_data_struct *mdata;
1655d2201f2fSdrahn {
1656d2201f2fSdrahn   unsigned int i;
1657d2201f2fSdrahn   enum bfd_architecture cputype;
1658d2201f2fSdrahn   unsigned long cpusubtype;
1659d2201f2fSdrahn 
1660d2201f2fSdrahn   mdata->header = *header;
1661d2201f2fSdrahn   mdata->symbols = NULL;
1662d2201f2fSdrahn 
1663d2201f2fSdrahn   abfd->flags = (abfd->xvec->object_flags
1664d2201f2fSdrahn 		 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1665d2201f2fSdrahn   abfd->tdata.mach_o_data = mdata;
1666d2201f2fSdrahn 
1667d2201f2fSdrahn   bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1668d2201f2fSdrahn 				   &cputype, &cpusubtype);
1669d2201f2fSdrahn   if (cputype == bfd_arch_unknown)
1670d2201f2fSdrahn     {
1671d2201f2fSdrahn       fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1672d2201f2fSdrahn 	       header->cputype, header->cpusubtype);
1673d2201f2fSdrahn       return -1;
1674d2201f2fSdrahn     }
1675d2201f2fSdrahn 
1676d2201f2fSdrahn   bfd_set_arch_mach (abfd, cputype, cpusubtype);
1677d2201f2fSdrahn 
1678d2201f2fSdrahn   if (header->ncmds != 0)
1679d2201f2fSdrahn     {
1680d2201f2fSdrahn       mdata->commands =
1681d2201f2fSdrahn 	((bfd_mach_o_load_command *)
1682d2201f2fSdrahn 	 bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));
1683d2201f2fSdrahn       if (mdata->commands == NULL)
1684d2201f2fSdrahn 	return -1;
1685d2201f2fSdrahn 
1686d2201f2fSdrahn       for (i = 0; i < header->ncmds; i++)
1687d2201f2fSdrahn 	{
1688d2201f2fSdrahn 	  bfd_mach_o_load_command *cur = &mdata->commands[i];
1689d2201f2fSdrahn 
1690d2201f2fSdrahn 	  if (i == 0)
1691d2201f2fSdrahn 	    cur->offset = 28;
1692d2201f2fSdrahn 	  else
1693d2201f2fSdrahn 	    {
1694d2201f2fSdrahn 	      bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1695d2201f2fSdrahn 	      cur->offset = prev->offset + prev->len;
1696d2201f2fSdrahn 	    }
1697d2201f2fSdrahn 
1698d2201f2fSdrahn 	  if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1699d2201f2fSdrahn 	    return -1;
1700d2201f2fSdrahn 	}
1701d2201f2fSdrahn     }
1702d2201f2fSdrahn 
1703d2201f2fSdrahn   if (bfd_mach_o_scan_start_address (abfd) < 0)
1704d2201f2fSdrahn     {
1705d2201f2fSdrahn #if 0
1706d2201f2fSdrahn       fprintf (stderr, "bfd_mach_o_scan: unable to scan start address: %s\n",
1707d2201f2fSdrahn 	       bfd_errmsg (bfd_get_error ()));
1708d2201f2fSdrahn       abfd->tdata.mach_o_data = NULL;
1709d2201f2fSdrahn       return -1;
1710d2201f2fSdrahn #endif
1711d2201f2fSdrahn     }
1712d2201f2fSdrahn 
1713d2201f2fSdrahn   bfd_mach_o_flatten_sections (abfd);
1714d2201f2fSdrahn 
1715d2201f2fSdrahn   return 0;
1716d2201f2fSdrahn }
1717d2201f2fSdrahn 
1718d2201f2fSdrahn bfd_boolean
bfd_mach_o_mkobject(abfd)1719d2201f2fSdrahn bfd_mach_o_mkobject (abfd)
1720d2201f2fSdrahn      bfd *abfd;
1721d2201f2fSdrahn {
1722d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = NULL;
1723d2201f2fSdrahn 
1724d2201f2fSdrahn   mdata = ((bfd_mach_o_data_struct *)
1725d2201f2fSdrahn 	   bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
1726d2201f2fSdrahn   if (mdata == NULL)
1727d2201f2fSdrahn     return FALSE;
1728d2201f2fSdrahn   abfd->tdata.mach_o_data = mdata;
1729d2201f2fSdrahn 
1730d2201f2fSdrahn   mdata->header.magic = 0;
1731d2201f2fSdrahn   mdata->header.cputype = 0;
1732d2201f2fSdrahn   mdata->header.cpusubtype = 0;
1733d2201f2fSdrahn   mdata->header.filetype = 0;
1734d2201f2fSdrahn   mdata->header.ncmds = 0;
1735d2201f2fSdrahn   mdata->header.sizeofcmds = 0;
1736d2201f2fSdrahn   mdata->header.flags = 0;
1737d2201f2fSdrahn   mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1738d2201f2fSdrahn   mdata->commands = NULL;
1739d2201f2fSdrahn   mdata->nsymbols = 0;
1740d2201f2fSdrahn   mdata->symbols = NULL;
1741d2201f2fSdrahn   mdata->nsects = 0;
1742d2201f2fSdrahn   mdata->sections = NULL;
1743d2201f2fSdrahn   mdata->ibfd = NULL;
1744d2201f2fSdrahn 
1745d2201f2fSdrahn   return TRUE;
1746d2201f2fSdrahn }
1747d2201f2fSdrahn 
1748d2201f2fSdrahn const bfd_target *
bfd_mach_o_object_p(abfd)1749d2201f2fSdrahn bfd_mach_o_object_p (abfd)
1750d2201f2fSdrahn      bfd *abfd;
1751d2201f2fSdrahn {
1752d2201f2fSdrahn   struct bfd_preserve preserve;
1753d2201f2fSdrahn   bfd_mach_o_header header;
1754d2201f2fSdrahn 
1755d2201f2fSdrahn   preserve.marker = NULL;
1756d2201f2fSdrahn   if (bfd_mach_o_read_header (abfd, &header) != 0)
1757d2201f2fSdrahn     goto wrong;
1758d2201f2fSdrahn 
1759d2201f2fSdrahn   if (! (header.byteorder == BFD_ENDIAN_BIG
1760d2201f2fSdrahn 	 || header.byteorder == BFD_ENDIAN_LITTLE))
1761d2201f2fSdrahn     {
1762d2201f2fSdrahn       fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1763d2201f2fSdrahn 	       (long) header.byteorder);
1764d2201f2fSdrahn       goto wrong;
1765d2201f2fSdrahn     }
1766d2201f2fSdrahn 
1767d2201f2fSdrahn   if (! ((header.byteorder == BFD_ENDIAN_BIG
1768d2201f2fSdrahn 	  && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1769d2201f2fSdrahn 	  && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1770d2201f2fSdrahn 	 || (header.byteorder == BFD_ENDIAN_LITTLE
1771d2201f2fSdrahn 	     && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1772d2201f2fSdrahn 	     && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1773d2201f2fSdrahn     goto wrong;
1774d2201f2fSdrahn 
1775d2201f2fSdrahn   preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1776d2201f2fSdrahn   if (preserve.marker == NULL
1777d2201f2fSdrahn       || !bfd_preserve_save (abfd, &preserve))
1778d2201f2fSdrahn     goto fail;
1779d2201f2fSdrahn 
1780d2201f2fSdrahn   if (bfd_mach_o_scan (abfd, &header,
1781d2201f2fSdrahn 		       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1782d2201f2fSdrahn     goto wrong;
1783d2201f2fSdrahn 
1784d2201f2fSdrahn   bfd_preserve_finish (abfd, &preserve);
1785d2201f2fSdrahn   return abfd->xvec;
1786d2201f2fSdrahn 
1787d2201f2fSdrahn  wrong:
1788d2201f2fSdrahn   bfd_set_error (bfd_error_wrong_format);
1789d2201f2fSdrahn 
1790d2201f2fSdrahn  fail:
1791d2201f2fSdrahn   if (preserve.marker != NULL)
1792d2201f2fSdrahn     bfd_preserve_restore (abfd, &preserve);
1793d2201f2fSdrahn   return NULL;
1794d2201f2fSdrahn }
1795d2201f2fSdrahn 
1796d2201f2fSdrahn const bfd_target *
bfd_mach_o_core_p(abfd)1797d2201f2fSdrahn bfd_mach_o_core_p (abfd)
1798d2201f2fSdrahn      bfd *abfd;
1799d2201f2fSdrahn {
1800d2201f2fSdrahn   struct bfd_preserve preserve;
1801d2201f2fSdrahn   bfd_mach_o_header header;
1802d2201f2fSdrahn 
1803d2201f2fSdrahn   preserve.marker = NULL;
1804d2201f2fSdrahn   if (bfd_mach_o_read_header (abfd, &header) != 0)
1805d2201f2fSdrahn     goto wrong;
1806d2201f2fSdrahn 
1807d2201f2fSdrahn   if (! (header.byteorder == BFD_ENDIAN_BIG
1808d2201f2fSdrahn 	 || header.byteorder == BFD_ENDIAN_LITTLE))
1809d2201f2fSdrahn     {
1810d2201f2fSdrahn       fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1811d2201f2fSdrahn 	       (long) header.byteorder);
1812d2201f2fSdrahn       abort ();
1813d2201f2fSdrahn     }
1814d2201f2fSdrahn 
1815d2201f2fSdrahn   if (! ((header.byteorder == BFD_ENDIAN_BIG
1816d2201f2fSdrahn 	  && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1817d2201f2fSdrahn 	  && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1818d2201f2fSdrahn 	 || (header.byteorder == BFD_ENDIAN_LITTLE
1819d2201f2fSdrahn 	     && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1820d2201f2fSdrahn 	     && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1821d2201f2fSdrahn     goto wrong;
1822d2201f2fSdrahn 
1823d2201f2fSdrahn   if (header.filetype != BFD_MACH_O_MH_CORE)
1824d2201f2fSdrahn     goto wrong;
1825d2201f2fSdrahn 
1826d2201f2fSdrahn   preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1827d2201f2fSdrahn   if (preserve.marker == NULL
1828d2201f2fSdrahn       || !bfd_preserve_save (abfd, &preserve))
1829d2201f2fSdrahn     goto fail;
1830d2201f2fSdrahn 
1831d2201f2fSdrahn   if (bfd_mach_o_scan (abfd, &header,
1832d2201f2fSdrahn 		       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1833d2201f2fSdrahn     goto wrong;
1834d2201f2fSdrahn 
1835d2201f2fSdrahn   bfd_preserve_finish (abfd, &preserve);
1836d2201f2fSdrahn   return abfd->xvec;
1837d2201f2fSdrahn 
1838d2201f2fSdrahn  wrong:
1839d2201f2fSdrahn   bfd_set_error (bfd_error_wrong_format);
1840d2201f2fSdrahn 
1841d2201f2fSdrahn  fail:
1842d2201f2fSdrahn   if (preserve.marker != NULL)
1843d2201f2fSdrahn     bfd_preserve_restore (abfd, &preserve);
1844d2201f2fSdrahn   return NULL;
1845d2201f2fSdrahn }
1846d2201f2fSdrahn 
1847d2201f2fSdrahn typedef struct mach_o_fat_archentry
1848d2201f2fSdrahn {
1849d2201f2fSdrahn   unsigned long cputype;
1850d2201f2fSdrahn   unsigned long cpusubtype;
1851d2201f2fSdrahn   unsigned long offset;
1852d2201f2fSdrahn   unsigned long size;
1853d2201f2fSdrahn   unsigned long align;
1854d2201f2fSdrahn   bfd *abfd;
1855d2201f2fSdrahn } mach_o_fat_archentry;
1856d2201f2fSdrahn 
1857d2201f2fSdrahn typedef struct mach_o_fat_data_struct
1858d2201f2fSdrahn {
1859d2201f2fSdrahn   unsigned long magic;
1860d2201f2fSdrahn   unsigned long nfat_arch;
1861d2201f2fSdrahn   mach_o_fat_archentry *archentries;
1862d2201f2fSdrahn } mach_o_fat_data_struct;
1863d2201f2fSdrahn 
1864d2201f2fSdrahn const bfd_target *
bfd_mach_o_archive_p(abfd)1865d2201f2fSdrahn bfd_mach_o_archive_p (abfd)
1866d2201f2fSdrahn      bfd *abfd;
1867d2201f2fSdrahn {
1868d2201f2fSdrahn   mach_o_fat_data_struct *adata = NULL;
1869d2201f2fSdrahn   unsigned char buf[20];
1870d2201f2fSdrahn   unsigned long i;
1871d2201f2fSdrahn 
1872d2201f2fSdrahn   bfd_seek (abfd, 0, SEEK_SET);
1873d2201f2fSdrahn   if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1874d2201f2fSdrahn     goto error;
1875d2201f2fSdrahn 
1876d2201f2fSdrahn   adata = (mach_o_fat_data_struct *)
1877d2201f2fSdrahn     bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1878d2201f2fSdrahn   if (adata == NULL)
1879d2201f2fSdrahn     goto error;
1880d2201f2fSdrahn 
1881d2201f2fSdrahn   adata->magic = bfd_getb32 (buf);
1882d2201f2fSdrahn   adata->nfat_arch = bfd_getb32 (buf + 4);
1883d2201f2fSdrahn   if (adata->magic != 0xcafebabe)
1884d2201f2fSdrahn     goto error;
1885d2201f2fSdrahn 
1886d2201f2fSdrahn   adata->archentries = (mach_o_fat_archentry *)
1887d2201f2fSdrahn     bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1888d2201f2fSdrahn   if (adata->archentries == NULL)
1889d2201f2fSdrahn     goto error;
1890d2201f2fSdrahn 
1891d2201f2fSdrahn   for (i = 0; i < adata->nfat_arch; i++)
1892d2201f2fSdrahn     {
1893d2201f2fSdrahn       bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1894d2201f2fSdrahn 
1895d2201f2fSdrahn       if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1896d2201f2fSdrahn 	goto error;
1897d2201f2fSdrahn       adata->archentries[i].cputype = bfd_getb32 (buf);
1898d2201f2fSdrahn       adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1899d2201f2fSdrahn       adata->archentries[i].offset = bfd_getb32 (buf + 8);
1900d2201f2fSdrahn       adata->archentries[i].size = bfd_getb32 (buf + 12);
1901d2201f2fSdrahn       adata->archentries[i].align = bfd_getb32 (buf + 16);
1902d2201f2fSdrahn       adata->archentries[i].abfd = NULL;
1903d2201f2fSdrahn     }
1904d2201f2fSdrahn 
1905d2201f2fSdrahn   abfd->tdata.mach_o_fat_data = adata;
1906d2201f2fSdrahn   return abfd->xvec;
1907d2201f2fSdrahn 
1908d2201f2fSdrahn  error:
1909d2201f2fSdrahn   if (adata != NULL)
1910d2201f2fSdrahn     bfd_release (abfd, adata);
1911d2201f2fSdrahn   bfd_set_error (bfd_error_wrong_format);
1912d2201f2fSdrahn   return NULL;
1913d2201f2fSdrahn }
1914d2201f2fSdrahn 
1915d2201f2fSdrahn bfd *
bfd_mach_o_openr_next_archived_file(archive,prev)1916d2201f2fSdrahn bfd_mach_o_openr_next_archived_file (archive, prev)
1917d2201f2fSdrahn   bfd *archive;
1918d2201f2fSdrahn   bfd *prev;
1919d2201f2fSdrahn {
1920d2201f2fSdrahn   mach_o_fat_data_struct *adata;
1921d2201f2fSdrahn   mach_o_fat_archentry *entry = NULL;
1922d2201f2fSdrahn   unsigned long i;
1923d2201f2fSdrahn 
1924d2201f2fSdrahn   adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
1925d2201f2fSdrahn   BFD_ASSERT (adata != NULL);
1926d2201f2fSdrahn 
1927d2201f2fSdrahn   /* Find index of previous entry.  */
1928d2201f2fSdrahn   if (prev == NULL)
1929d2201f2fSdrahn     i = 0;	/* Start at first one.  */
1930d2201f2fSdrahn   else
1931d2201f2fSdrahn     {
1932d2201f2fSdrahn       for (i = 0; i < adata->nfat_arch; i++)
1933d2201f2fSdrahn 	{
1934d2201f2fSdrahn 	  if (adata->archentries[i].abfd == prev)
1935d2201f2fSdrahn 	    break;
1936d2201f2fSdrahn 	}
1937d2201f2fSdrahn 
1938d2201f2fSdrahn       if (i == adata->nfat_arch)
1939d2201f2fSdrahn 	{
1940d2201f2fSdrahn 	  /* Not found.  */
1941d2201f2fSdrahn 	  bfd_set_error (bfd_error_bad_value);
1942d2201f2fSdrahn 	  return NULL;
1943d2201f2fSdrahn 	}
1944d2201f2fSdrahn     i++;	/* Get next entry.  */
1945d2201f2fSdrahn   }
1946d2201f2fSdrahn 
1947d2201f2fSdrahn   if (i >= adata->nfat_arch)
1948d2201f2fSdrahn     {
1949d2201f2fSdrahn       bfd_set_error (bfd_error_no_more_archived_files);
1950d2201f2fSdrahn       return NULL;
1951d2201f2fSdrahn     }
1952d2201f2fSdrahn 
1953d2201f2fSdrahn   entry = &adata->archentries[i];
1954d2201f2fSdrahn   if (entry->abfd == NULL)
1955d2201f2fSdrahn     {
1956d2201f2fSdrahn       bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1957d2201f2fSdrahn       char *s = NULL;
1958d2201f2fSdrahn 
1959d2201f2fSdrahn       if (nbfd == NULL)
1960d2201f2fSdrahn 	return NULL;
1961d2201f2fSdrahn 
1962d2201f2fSdrahn       nbfd->origin = entry->offset;
1963d2201f2fSdrahn       s = bfd_malloc (strlen (archive->filename) + 1);
1964d2201f2fSdrahn       if (s == NULL)
1965d2201f2fSdrahn 	return NULL;
1966d2201f2fSdrahn       strcpy (s, archive->filename);
1967d2201f2fSdrahn       nbfd->filename = s;
1968d2201f2fSdrahn       nbfd->iostream = NULL;
1969d2201f2fSdrahn       entry->abfd = nbfd;
1970d2201f2fSdrahn     }
1971d2201f2fSdrahn 
1972d2201f2fSdrahn   return entry->abfd;
1973d2201f2fSdrahn }
1974d2201f2fSdrahn 
1975d2201f2fSdrahn int
bfd_mach_o_lookup_section(abfd,section,mcommand,msection)1976d2201f2fSdrahn bfd_mach_o_lookup_section (abfd, section, mcommand, msection)
1977d2201f2fSdrahn      bfd *abfd;
1978d2201f2fSdrahn      asection *section;
1979d2201f2fSdrahn      bfd_mach_o_load_command **mcommand;
1980d2201f2fSdrahn      bfd_mach_o_section **msection;
1981d2201f2fSdrahn {
1982d2201f2fSdrahn   struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1983d2201f2fSdrahn   unsigned int i, j, num;
1984d2201f2fSdrahn 
1985d2201f2fSdrahn   bfd_mach_o_load_command *ncmd = NULL;
1986d2201f2fSdrahn   bfd_mach_o_section *nsect = NULL;
1987d2201f2fSdrahn 
1988d2201f2fSdrahn   BFD_ASSERT (mcommand != NULL);
1989d2201f2fSdrahn   BFD_ASSERT (msection != NULL);
1990d2201f2fSdrahn 
1991d2201f2fSdrahn   num = 0;
1992d2201f2fSdrahn   for (i = 0; i < md->header.ncmds; i++)
1993d2201f2fSdrahn     {
1994d2201f2fSdrahn       struct bfd_mach_o_load_command *cmd = &md->commands[i];
1995d2201f2fSdrahn       struct bfd_mach_o_segment_command *seg = NULL;
1996d2201f2fSdrahn 
1997d2201f2fSdrahn       if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1998d2201f2fSdrahn 	continue;
1999d2201f2fSdrahn       seg = &cmd->command.segment;
2000d2201f2fSdrahn 
2001d2201f2fSdrahn       if (seg->segment == section)
2002d2201f2fSdrahn 	{
2003d2201f2fSdrahn 	  if (num == 0)
2004d2201f2fSdrahn 	    ncmd = cmd;
2005d2201f2fSdrahn 	  num++;
2006d2201f2fSdrahn 	}
2007d2201f2fSdrahn 
2008d2201f2fSdrahn       for (j = 0; j < seg->nsects; j++)
2009d2201f2fSdrahn 	{
2010d2201f2fSdrahn 	  struct bfd_mach_o_section *sect = &seg->sections[j];
2011d2201f2fSdrahn 
2012d2201f2fSdrahn 	  if (sect->bfdsection == section)
2013d2201f2fSdrahn 	    {
2014d2201f2fSdrahn 	      if (num == 0)
2015d2201f2fSdrahn 		nsect = sect;
2016d2201f2fSdrahn 	      num++;
2017d2201f2fSdrahn 	    }
2018d2201f2fSdrahn 	}
2019d2201f2fSdrahn     }
2020d2201f2fSdrahn 
2021d2201f2fSdrahn   *mcommand = ncmd;
2022d2201f2fSdrahn   *msection = nsect;
2023d2201f2fSdrahn   return num;
2024d2201f2fSdrahn }
2025d2201f2fSdrahn 
2026d2201f2fSdrahn int
bfd_mach_o_lookup_command(abfd,type,mcommand)2027d2201f2fSdrahn bfd_mach_o_lookup_command (abfd, type, mcommand)
2028d2201f2fSdrahn      bfd *abfd;
2029d2201f2fSdrahn      bfd_mach_o_load_command_type type;
2030d2201f2fSdrahn      bfd_mach_o_load_command **mcommand;
2031d2201f2fSdrahn {
2032d2201f2fSdrahn   struct mach_o_data_struct *md = NULL;
2033d2201f2fSdrahn   bfd_mach_o_load_command *ncmd = NULL;
2034d2201f2fSdrahn   unsigned int i, num;
2035d2201f2fSdrahn 
2036d2201f2fSdrahn   md = abfd->tdata.mach_o_data;
2037d2201f2fSdrahn 
2038d2201f2fSdrahn   BFD_ASSERT (md != NULL);
2039d2201f2fSdrahn   BFD_ASSERT (mcommand != NULL);
2040d2201f2fSdrahn 
2041d2201f2fSdrahn   num = 0;
2042d2201f2fSdrahn   for (i = 0; i < md->header.ncmds; i++)
2043d2201f2fSdrahn     {
2044d2201f2fSdrahn       struct bfd_mach_o_load_command *cmd = &md->commands[i];
2045d2201f2fSdrahn 
2046d2201f2fSdrahn       if (cmd->type != type)
2047d2201f2fSdrahn 	continue;
2048d2201f2fSdrahn 
2049d2201f2fSdrahn       if (num == 0)
2050d2201f2fSdrahn 	ncmd = cmd;
2051d2201f2fSdrahn       num++;
2052d2201f2fSdrahn     }
2053d2201f2fSdrahn 
2054d2201f2fSdrahn   *mcommand = ncmd;
2055d2201f2fSdrahn   return num;
2056d2201f2fSdrahn }
2057d2201f2fSdrahn 
2058d2201f2fSdrahn unsigned long
bfd_mach_o_stack_addr(type)2059d2201f2fSdrahn bfd_mach_o_stack_addr (type)
2060d2201f2fSdrahn      enum bfd_mach_o_cpu_type type;
2061d2201f2fSdrahn {
2062d2201f2fSdrahn   switch (type)
2063d2201f2fSdrahn     {
2064d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_MC680x0:
2065d2201f2fSdrahn       return 0x04000000;
2066d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_MC88000:
2067d2201f2fSdrahn       return 0xffffe000;
2068d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_POWERPC:
2069d2201f2fSdrahn       return 0xc0000000;
2070d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_I386:
2071d2201f2fSdrahn       return 0xc0000000;
2072d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_SPARC:
2073d2201f2fSdrahn       return 0xf0000000;
2074d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_I860:
2075d2201f2fSdrahn       return 0;
2076d2201f2fSdrahn     case BFD_MACH_O_CPU_TYPE_HPPA:
2077d2201f2fSdrahn       return 0xc0000000 - 0x04000000;
2078d2201f2fSdrahn     default:
2079d2201f2fSdrahn       return 0;
2080d2201f2fSdrahn     }
2081d2201f2fSdrahn }
2082d2201f2fSdrahn 
2083d2201f2fSdrahn int
bfd_mach_o_core_fetch_environment(abfd,rbuf,rlen)2084d2201f2fSdrahn bfd_mach_o_core_fetch_environment (abfd, rbuf, rlen)
2085d2201f2fSdrahn      bfd *abfd;
2086d2201f2fSdrahn      unsigned char **rbuf;
2087d2201f2fSdrahn      unsigned int *rlen;
2088d2201f2fSdrahn {
2089d2201f2fSdrahn   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2090d2201f2fSdrahn   unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2091d2201f2fSdrahn   unsigned int i = 0;
2092d2201f2fSdrahn 
2093d2201f2fSdrahn   for (i = 0; i < mdata->header.ncmds; i++)
2094d2201f2fSdrahn     {
2095d2201f2fSdrahn       bfd_mach_o_load_command *cur = &mdata->commands[i];
2096d2201f2fSdrahn       bfd_mach_o_segment_command *seg = NULL;
2097d2201f2fSdrahn 
2098d2201f2fSdrahn       if (cur->type != BFD_MACH_O_LC_SEGMENT)
2099d2201f2fSdrahn 	continue;
2100d2201f2fSdrahn 
2101d2201f2fSdrahn       seg = &cur->command.segment;
2102d2201f2fSdrahn 
2103d2201f2fSdrahn       if ((seg->vmaddr + seg->vmsize) == stackaddr)
2104d2201f2fSdrahn 	{
2105d2201f2fSdrahn 	  unsigned long start = seg->fileoff;
2106d2201f2fSdrahn 	  unsigned long end = seg->fileoff + seg->filesize;
2107d2201f2fSdrahn 	  unsigned char *buf = bfd_malloc (1024);
2108d2201f2fSdrahn 	  unsigned long size = 1024;
2109d2201f2fSdrahn 
2110d2201f2fSdrahn 	  for (;;)
2111d2201f2fSdrahn 	    {
2112d2201f2fSdrahn 	      bfd_size_type nread = 0;
2113d2201f2fSdrahn 	      unsigned long offset;
2114d2201f2fSdrahn 	      int found_nonnull = 0;
2115d2201f2fSdrahn 
2116d2201f2fSdrahn 	      if (size > (end - start))
2117d2201f2fSdrahn 		size = (end - start);
2118d2201f2fSdrahn 
2119d2201f2fSdrahn 	      buf = bfd_realloc (buf, size);
2120d2201f2fSdrahn 
2121d2201f2fSdrahn 	      bfd_seek (abfd, end - size, SEEK_SET);
2122d2201f2fSdrahn 	      nread = bfd_bread (buf, size, abfd);
2123d2201f2fSdrahn 
2124d2201f2fSdrahn 	      if (nread != size)
2125d2201f2fSdrahn 		return -1;
2126d2201f2fSdrahn 
2127d2201f2fSdrahn 	      for (offset = 4; offset <= size; offset += 4)
2128d2201f2fSdrahn 		{
2129d2201f2fSdrahn 		  unsigned long val;
2130d2201f2fSdrahn 
2131d2201f2fSdrahn 		  val = *((unsigned long *) (buf + size - offset));
2132d2201f2fSdrahn 		  if (! found_nonnull)
2133d2201f2fSdrahn 		    {
2134d2201f2fSdrahn 		      if (val != 0)
2135d2201f2fSdrahn 			found_nonnull = 1;
2136d2201f2fSdrahn 		    }
2137d2201f2fSdrahn 		  else if (val == 0x0)
2138d2201f2fSdrahn 		    {
2139d2201f2fSdrahn 		      unsigned long bottom;
2140d2201f2fSdrahn 		      unsigned long top;
2141d2201f2fSdrahn 
2142d2201f2fSdrahn 		      bottom = seg->fileoff + seg->filesize - offset;
2143d2201f2fSdrahn 		      top = seg->fileoff + seg->filesize - 4;
2144d2201f2fSdrahn 		      *rbuf = bfd_malloc (top - bottom);
2145d2201f2fSdrahn 		      *rlen = top - bottom;
2146d2201f2fSdrahn 
2147d2201f2fSdrahn 		      memcpy (*rbuf, buf + size - *rlen, *rlen);
2148d2201f2fSdrahn 		      return 0;
2149d2201f2fSdrahn 		    }
2150d2201f2fSdrahn 		}
2151d2201f2fSdrahn 
2152d2201f2fSdrahn 	      if (size == (end - start))
2153d2201f2fSdrahn 		break;
2154d2201f2fSdrahn 
2155d2201f2fSdrahn 	      size *= 2;
2156d2201f2fSdrahn 	    }
2157d2201f2fSdrahn 	}
2158d2201f2fSdrahn     }
2159d2201f2fSdrahn 
2160d2201f2fSdrahn   return -1;
2161d2201f2fSdrahn }
2162d2201f2fSdrahn 
2163d2201f2fSdrahn char *
bfd_mach_o_core_file_failing_command(abfd)2164d2201f2fSdrahn bfd_mach_o_core_file_failing_command (abfd)
2165d2201f2fSdrahn      bfd *abfd;
2166d2201f2fSdrahn {
2167d2201f2fSdrahn   unsigned char *buf = NULL;
2168d2201f2fSdrahn   unsigned int len = 0;
2169d2201f2fSdrahn   int ret = -1;
2170d2201f2fSdrahn 
2171d2201f2fSdrahn   ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
2172d2201f2fSdrahn   if (ret < 0)
2173d2201f2fSdrahn     return NULL;
2174d2201f2fSdrahn 
2175d2201f2fSdrahn   return buf;
2176d2201f2fSdrahn }
2177d2201f2fSdrahn 
2178d2201f2fSdrahn int
bfd_mach_o_core_file_failing_signal(abfd)2179d2201f2fSdrahn bfd_mach_o_core_file_failing_signal (abfd)
2180d2201f2fSdrahn      bfd *abfd ATTRIBUTE_UNUSED;
2181d2201f2fSdrahn {
2182d2201f2fSdrahn   return 0;
2183d2201f2fSdrahn }
2184d2201f2fSdrahn 
2185d2201f2fSdrahn bfd_boolean
bfd_mach_o_core_file_matches_executable_p(core_bfd,exec_bfd)2186d2201f2fSdrahn bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)
2187d2201f2fSdrahn      bfd *core_bfd ATTRIBUTE_UNUSED;
2188d2201f2fSdrahn      bfd *exec_bfd ATTRIBUTE_UNUSED;
2189d2201f2fSdrahn {
2190d2201f2fSdrahn   return TRUE;
2191d2201f2fSdrahn }
2192d2201f2fSdrahn 
2193d2201f2fSdrahn #define TARGET_NAME mach_o_be_vec
2194d2201f2fSdrahn #define TARGET_STRING "mach-o-be"
2195d2201f2fSdrahn #define TARGET_BIG_ENDIAN 1
2196d2201f2fSdrahn #define TARGET_ARCHIVE 0
2197d2201f2fSdrahn 
2198d2201f2fSdrahn #include "mach-o-target.c"
2199d2201f2fSdrahn 
2200d2201f2fSdrahn #undef TARGET_NAME
2201d2201f2fSdrahn #undef TARGET_STRING
2202d2201f2fSdrahn #undef TARGET_BIG_ENDIAN
2203d2201f2fSdrahn #undef TARGET_ARCHIVE
2204d2201f2fSdrahn 
2205d2201f2fSdrahn #define TARGET_NAME mach_o_le_vec
2206d2201f2fSdrahn #define TARGET_STRING "mach-o-le"
2207d2201f2fSdrahn #define TARGET_BIG_ENDIAN 0
2208d2201f2fSdrahn #define TARGET_ARCHIVE 0
2209d2201f2fSdrahn 
2210d2201f2fSdrahn #include "mach-o-target.c"
2211d2201f2fSdrahn 
2212d2201f2fSdrahn #undef TARGET_NAME
2213d2201f2fSdrahn #undef TARGET_STRING
2214d2201f2fSdrahn #undef TARGET_BIG_ENDIAN
2215d2201f2fSdrahn #undef TARGET_ARCHIVE
2216d2201f2fSdrahn 
2217d2201f2fSdrahn #define TARGET_NAME mach_o_fat_vec
2218d2201f2fSdrahn #define TARGET_STRING "mach-o-fat"
2219d2201f2fSdrahn #define TARGET_BIG_ENDIAN 1
2220d2201f2fSdrahn #define TARGET_ARCHIVE 1
2221d2201f2fSdrahn 
2222d2201f2fSdrahn #include "mach-o-target.c"
2223d2201f2fSdrahn 
2224d2201f2fSdrahn #undef TARGET_NAME
2225d2201f2fSdrahn #undef TARGET_STRING
2226d2201f2fSdrahn #undef TARGET_BIG_ENDIAN
2227d2201f2fSdrahn #undef TARGET_ARCHIVE
2228