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