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