1/* Mach-O support for BFD.
2   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
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			   struct bfd_link_info *info 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  flagword flags;
638
639  snamelen = strlen (prefix) + 1
640    + strlen (section->segname) + 1
641    + strlen (section->sectname) + 1;
642
643  sname = bfd_alloc (abfd, snamelen);
644  if (sname == NULL)
645    return NULL;
646  sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
647
648  flags = SEC_ALLOC;
649  if (!(section->flags & BFD_MACH_O_S_ZEROFILL))
650    flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
651  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
652  if (bfdsec == NULL)
653    return NULL;
654
655  bfdsec->vma = section->addr;
656  bfdsec->lma = section->addr;
657  bfdsec->size = section->size;
658  bfdsec->filepos = section->offset;
659  bfdsec->alignment_power = section->align;
660
661  return bfdsec;
662}
663
664static int
665bfd_mach_o_scan_read_section (bfd *abfd,
666			      bfd_mach_o_section *section,
667			      bfd_vma offset)
668{
669  unsigned char buf[68];
670
671  bfd_seek (abfd, offset, SEEK_SET);
672  if (bfd_bread ((PTR) buf, 68, abfd) != 68)
673    return -1;
674
675  memcpy (section->sectname, buf, 16);
676  section->sectname[16] = '\0';
677  memcpy (section->segname, buf + 16, 16);
678  section->segname[16] = '\0';
679  section->addr = bfd_h_get_32 (abfd, buf + 32);
680  section->size = bfd_h_get_32 (abfd, buf + 36);
681  section->offset = bfd_h_get_32 (abfd, buf + 40);
682  section->align = bfd_h_get_32 (abfd, buf + 44);
683  section->reloff = bfd_h_get_32 (abfd, buf + 48);
684  section->nreloc = bfd_h_get_32 (abfd, buf + 52);
685  section->flags = bfd_h_get_32 (abfd, buf + 56);
686  section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
687  section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
688  section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
689
690  if (section->bfdsection == NULL)
691    return -1;
692
693  return 0;
694}
695
696int
697bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
698				    bfd_mach_o_symtab_command *sym,
699				    asymbol *s,
700				    unsigned long i)
701{
702  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
703  bfd_vma symoff = sym->symoff + (i * 12);
704  unsigned char buf[12];
705  unsigned char type = -1;
706  unsigned char section = -1;
707  short desc = -1;
708  unsigned long value = -1;
709  unsigned long stroff = -1;
710  unsigned int symtype = -1;
711
712  BFD_ASSERT (sym->strtab != NULL);
713
714  bfd_seek (abfd, symoff, SEEK_SET);
715  if (bfd_bread ((PTR) buf, 12, abfd) != 12)
716    {
717      fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
718	       12, (unsigned long) symoff);
719      return -1;
720    }
721
722  stroff = bfd_h_get_32 (abfd, buf);
723  type = bfd_h_get_8 (abfd, buf + 4);
724  symtype = (type & 0x0e);
725  section = bfd_h_get_8 (abfd, buf + 5) - 1;
726  desc = bfd_h_get_16 (abfd, buf + 6);
727  value = bfd_h_get_32 (abfd, buf + 8);
728
729  if (stroff >= sym->strsize)
730    {
731      fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
732	       (unsigned long) stroff, (unsigned long) sym->strsize);
733      return -1;
734    }
735
736  s->the_bfd = abfd;
737  s->name = sym->strtab + stroff;
738  s->value = value;
739  s->udata.i = (type << 24) | (section << 16) | desc;
740  s->flags = 0x0;
741
742  if (type & BFD_MACH_O_N_STAB)
743    {
744      s->flags |= BSF_DEBUGGING;
745      s->section = bfd_und_section_ptr;
746    }
747  else
748    {
749      if (type & BFD_MACH_O_N_PEXT)
750	{
751	  type &= ~BFD_MACH_O_N_PEXT;
752	  s->flags |= BSF_GLOBAL;
753	}
754
755      if (type & BFD_MACH_O_N_EXT)
756	{
757	  type &= ~BFD_MACH_O_N_EXT;
758	  s->flags |= BSF_GLOBAL;
759	}
760
761      switch (symtype)
762	{
763	case BFD_MACH_O_N_UNDF:
764	  s->section = bfd_und_section_ptr;
765	  break;
766	case BFD_MACH_O_N_PBUD:
767	  s->section = bfd_und_section_ptr;
768	  break;
769	case BFD_MACH_O_N_ABS:
770	  s->section = bfd_abs_section_ptr;
771	  break;
772	case BFD_MACH_O_N_SECT:
773	  if ((section > 0) && (section <= mdata->nsects))
774	    {
775	      s->section = mdata->sections[section - 1]->bfdsection;
776	      s->value = s->value - mdata->sections[section - 1]->addr;
777	    }
778	  else
779	    {
780	      /* Mach-O uses 0 to mean "no section"; not an error.  */
781	      if (section != 0)
782		{
783		  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
784			   "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
785			   s->name, section, mdata->nsects);
786		}
787	      s->section = bfd_und_section_ptr;
788	    }
789	  break;
790	case BFD_MACH_O_N_INDR:
791	  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
792		   "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
793		   s->name);
794	  s->section = bfd_und_section_ptr;
795	  break;
796	default:
797	  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
798		   "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
799		   s->name, symtype);
800	  s->section = bfd_und_section_ptr;
801	  break;
802	}
803    }
804
805  return 0;
806}
807
808int
809bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
810				    bfd_mach_o_symtab_command *sym)
811{
812  BFD_ASSERT (sym->strtab == NULL);
813
814  if (abfd->flags & BFD_IN_MEMORY)
815    {
816      struct bfd_in_memory *b;
817
818      b = (struct bfd_in_memory *) abfd->iostream;
819
820      if ((sym->stroff + sym->strsize) > b->size)
821	{
822	  bfd_set_error (bfd_error_file_truncated);
823	  return -1;
824	}
825      sym->strtab = (char *) b->buffer + sym->stroff;
826      return 0;
827    }
828
829  sym->strtab = bfd_alloc (abfd, sym->strsize);
830  if (sym->strtab == NULL)
831    return -1;
832
833  bfd_seek (abfd, sym->stroff, SEEK_SET);
834  if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
835    {
836      fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
837	       sym->strsize, sym->stroff);
838      return -1;
839    }
840
841  return 0;
842}
843
844int
845bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
846				     bfd_mach_o_symtab_command *sym)
847{
848  unsigned long i;
849  int ret;
850
851  BFD_ASSERT (sym->symbols == NULL);
852  sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
853
854  if (sym->symbols == NULL)
855    {
856      fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
857      return -1;
858    }
859
860  ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
861  if (ret != 0)
862    return ret;
863
864  for (i = 0; i < sym->nsyms; i++)
865    {
866      ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
867      if (ret != 0)
868	return ret;
869    }
870
871  return 0;
872}
873
874int
875bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
876				      bfd_mach_o_dysymtab_command *dysym,
877				      bfd_mach_o_symtab_command *sym,
878				      asymbol *s,
879				      unsigned long i)
880{
881  unsigned long isymoff = dysym->indirectsymoff + (i * 4);
882  unsigned long symindex;
883  unsigned char buf[4];
884
885  BFD_ASSERT (i < dysym->nindirectsyms);
886
887  bfd_seek (abfd, isymoff, SEEK_SET);
888  if (bfd_bread ((PTR) buf, 4, abfd) != 4)
889    {
890      fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
891	       (unsigned long) 4, isymoff);
892      return -1;
893    }
894  symindex = bfd_h_get_32 (abfd, buf);
895
896  return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
897}
898
899static const char *
900bfd_mach_o_i386_flavour_string (unsigned int flavour)
901{
902  switch ((int) flavour)
903    {
904    case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
905    case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
906    case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
907    case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
908    case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
909    case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
910    case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
911    case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
912    case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
913    case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
914    case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
915    case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
916    default: return "UNKNOWN";
917    }
918}
919
920static const char *
921bfd_mach_o_ppc_flavour_string (unsigned int flavour)
922{
923  switch ((int) flavour)
924    {
925    case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
926    case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
927    case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
928    case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
929    default: return "UNKNOWN";
930    }
931}
932
933static int
934bfd_mach_o_scan_read_dylinker (bfd *abfd,
935			       bfd_mach_o_load_command *command)
936{
937  bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
938  unsigned char buf[4];
939  unsigned int nameoff;
940  asection *bfdsec;
941  char *sname;
942  const char *prefix;
943
944  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
945	      || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
946
947  bfd_seek (abfd, command->offset + 8, SEEK_SET);
948  if (bfd_bread ((PTR) buf, 4, abfd) != 4)
949    return -1;
950
951  nameoff = bfd_h_get_32 (abfd, buf + 0);
952
953  cmd->name_offset = command->offset + nameoff;
954  cmd->name_len = command->len - nameoff;
955
956  if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
957    prefix = "LC_LOAD_DYLINKER";
958  else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
959    prefix = "LC_ID_DYLINKER";
960  else
961    abort ();
962
963  sname = bfd_alloc (abfd, strlen (prefix) + 1);
964  if (sname == NULL)
965    return -1;
966  strcpy (sname, prefix);
967
968  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
969  if (bfdsec == NULL)
970    return -1;
971
972  bfdsec->vma = 0;
973  bfdsec->lma = 0;
974  bfdsec->size = command->len - 8;
975  bfdsec->filepos = command->offset + 8;
976  bfdsec->alignment_power = 0;
977
978  cmd->section = bfdsec;
979
980  return 0;
981}
982
983static int
984bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
985{
986  bfd_mach_o_dylib_command *cmd = &command->command.dylib;
987  unsigned char buf[16];
988  unsigned int nameoff;
989  asection *bfdsec;
990  char *sname;
991  const char *prefix;
992
993  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
994	      || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
995	      || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
996
997  bfd_seek (abfd, command->offset + 8, SEEK_SET);
998  if (bfd_bread ((PTR) buf, 16, abfd) != 16)
999    return -1;
1000
1001  nameoff = bfd_h_get_32 (abfd, buf + 0);
1002  cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1003  cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1004  cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1005
1006  cmd->name_offset = command->offset + nameoff;
1007  cmd->name_len = command->len - nameoff;
1008
1009  if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1010    prefix = "LC_LOAD_DYLIB";
1011  else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1012    prefix = "LC_LOAD_WEAK_DYLIB";
1013  else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1014    prefix = "LC_ID_DYLIB";
1015  else
1016    abort ();
1017
1018  sname = bfd_alloc (abfd, strlen (prefix) + 1);
1019  if (sname == NULL)
1020    return -1;
1021  strcpy (sname, prefix);
1022
1023  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1024  if (bfdsec == NULL)
1025    return -1;
1026
1027  bfdsec->vma = 0;
1028  bfdsec->lma = 0;
1029  bfdsec->size = command->len - 8;
1030  bfdsec->filepos = command->offset + 8;
1031  bfdsec->alignment_power = 0;
1032
1033  cmd->section = bfdsec;
1034
1035  return 0;
1036}
1037
1038static int
1039bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1040				     bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1041{
1042  /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1043
1044  BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1045  return 0;
1046}
1047
1048static int
1049bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1050{
1051  bfd_mach_o_data_struct *mdata = NULL;
1052  bfd_mach_o_thread_command *cmd = &command->command.thread;
1053  unsigned char buf[8];
1054  bfd_vma offset;
1055  unsigned int nflavours;
1056  unsigned int i;
1057
1058  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1059	      || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1060
1061  BFD_ASSERT (bfd_mach_o_valid (abfd));
1062  mdata = abfd->tdata.mach_o_data;
1063
1064  offset = 8;
1065  nflavours = 0;
1066  while (offset != command->len)
1067    {
1068      if (offset >= command->len)
1069	return -1;
1070
1071      bfd_seek (abfd, command->offset + offset, SEEK_SET);
1072
1073      if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1074	return -1;
1075
1076      offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1077      nflavours++;
1078    }
1079
1080  cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
1081  if (cmd->flavours == NULL)
1082    return -1;
1083  cmd->nflavours = nflavours;
1084
1085  offset = 8;
1086  nflavours = 0;
1087  while (offset != command->len)
1088    {
1089      if (offset >= command->len)
1090	return -1;
1091
1092      if (nflavours >= cmd->nflavours)
1093	return -1;
1094
1095      bfd_seek (abfd, command->offset + offset, SEEK_SET);
1096
1097      if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1098	return -1;
1099
1100      cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1101      cmd->flavours[nflavours].offset = command->offset + offset + 8;
1102      cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1103      offset += cmd->flavours[nflavours].size + 8;
1104      nflavours++;
1105    }
1106
1107  for (i = 0; i < nflavours; i++)
1108    {
1109      asection *bfdsec;
1110      unsigned int snamelen;
1111      char *sname;
1112      const char *flavourstr;
1113      const char *prefix = "LC_THREAD";
1114      unsigned int j = 0;
1115
1116      switch (mdata->header.cputype)
1117	{
1118	case BFD_MACH_O_CPU_TYPE_POWERPC:
1119	  flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1120	  break;
1121	case BFD_MACH_O_CPU_TYPE_I386:
1122	  flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1123	  break;
1124	default:
1125	  flavourstr = "UNKNOWN_ARCHITECTURE";
1126	  break;
1127	}
1128
1129      snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1130      sname = bfd_alloc (abfd, snamelen);
1131      if (sname == NULL)
1132	return -1;
1133
1134      for (;;)
1135	{
1136	  sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1137	  if (bfd_get_section_by_name (abfd, sname) == NULL)
1138	    break;
1139	  j++;
1140	}
1141
1142      bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1143
1144      bfdsec->vma = 0;
1145      bfdsec->lma = 0;
1146      bfdsec->size = cmd->flavours[i].size;
1147      bfdsec->filepos = cmd->flavours[i].offset;
1148      bfdsec->alignment_power = 0x0;
1149
1150      cmd->section = bfdsec;
1151    }
1152
1153  return 0;
1154}
1155
1156static int
1157bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1158{
1159  bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1160  unsigned char buf[72];
1161
1162  BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1163
1164  bfd_seek (abfd, command->offset + 8, SEEK_SET);
1165  if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1166    return -1;
1167
1168  seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1169  seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1170  seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1171  seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1172  seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1173  seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1174  seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1175  seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1176  seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1177  seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1178  seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1179  seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1180  seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1181  seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1182  seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1183  seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1184  seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1185  seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1186
1187  return 0;
1188}
1189
1190static int
1191bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1192{
1193  bfd_mach_o_symtab_command *seg = &command->command.symtab;
1194  unsigned char buf[16];
1195  asection *bfdsec;
1196  char *sname;
1197  const char *prefix = "LC_SYMTAB.stabs";
1198
1199  BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1200
1201  bfd_seek (abfd, command->offset + 8, SEEK_SET);
1202  if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1203    return -1;
1204
1205  seg->symoff = bfd_h_get_32 (abfd, buf);
1206  seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1207  seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1208  seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1209  seg->symbols = NULL;
1210  seg->strtab = NULL;
1211
1212  sname = bfd_alloc (abfd, strlen (prefix) + 1);
1213  if (sname == NULL)
1214    return -1;
1215  strcpy (sname, prefix);
1216
1217  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1218  if (bfdsec == NULL)
1219    return -1;
1220
1221  bfdsec->vma = 0;
1222  bfdsec->lma = 0;
1223  bfdsec->size = seg->nsyms * 12;
1224  bfdsec->filepos = seg->symoff;
1225  bfdsec->alignment_power = 0;
1226
1227  seg->stabs_segment = bfdsec;
1228
1229  prefix = "LC_SYMTAB.stabstr";
1230  sname = bfd_alloc (abfd, strlen (prefix) + 1);
1231  if (sname == NULL)
1232    return -1;
1233  strcpy (sname, prefix);
1234
1235  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1236  if (bfdsec == NULL)
1237    return -1;
1238
1239  bfdsec->vma = 0;
1240  bfdsec->lma = 0;
1241  bfdsec->size = seg->strsize;
1242  bfdsec->filepos = seg->stroff;
1243  bfdsec->alignment_power = 0;
1244
1245  seg->stabstr_segment = bfdsec;
1246
1247  return 0;
1248}
1249
1250static int
1251bfd_mach_o_scan_read_segment (bfd *abfd, bfd_mach_o_load_command *command)
1252{
1253  unsigned char buf[48];
1254  bfd_mach_o_segment_command *seg = &command->command.segment;
1255  unsigned long i;
1256  asection *bfdsec;
1257  char *sname;
1258  const char *prefix = "LC_SEGMENT";
1259  unsigned int snamelen;
1260  flagword flags;
1261
1262  BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1263
1264  bfd_seek (abfd, command->offset + 8, SEEK_SET);
1265  if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1266    return -1;
1267
1268  memcpy (seg->segname, buf, 16);
1269  seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1270  seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1271  seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1272  seg->filesize = bfd_h_get_32 (abfd, buf +  28);
1273  /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1274  /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1275  seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1276  seg->flags = bfd_h_get_32 (abfd, buf + 44);
1277
1278  snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1279  sname = bfd_alloc (abfd, snamelen);
1280  if (sname == NULL)
1281    return -1;
1282  sprintf (sname, "%s.%s", prefix, seg->segname);
1283
1284  flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1285  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1286  if (bfdsec == NULL)
1287    return -1;
1288
1289  bfdsec->vma = seg->vmaddr;
1290  bfdsec->lma = seg->vmaddr;
1291  bfdsec->size = seg->filesize;
1292  bfdsec->filepos = seg->fileoff;
1293  bfdsec->alignment_power = 0x0;
1294
1295  seg->segment = bfdsec;
1296
1297  if (seg->nsects != 0)
1298    {
1299      seg->sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1300      if (seg->sections == NULL)
1301	return -1;
1302
1303      for (i = 0; i < seg->nsects; i++)
1304	{
1305	  bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1306
1307	  if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1308					    segoff) != 0)
1309	    return -1;
1310	}
1311    }
1312
1313  return 0;
1314}
1315
1316static int
1317bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
1318{
1319  unsigned char buf[8];
1320
1321  bfd_seek (abfd, command->offset, SEEK_SET);
1322  if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1323    return -1;
1324
1325  command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1326  command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1327			    ? 1 : 0);
1328  command->len = bfd_h_get_32 (abfd, buf + 4);
1329
1330  switch (command->type)
1331    {
1332    case BFD_MACH_O_LC_SEGMENT:
1333      if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1334	return -1;
1335      break;
1336    case BFD_MACH_O_LC_SYMTAB:
1337      if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1338	return -1;
1339      break;
1340    case BFD_MACH_O_LC_SYMSEG:
1341      break;
1342    case BFD_MACH_O_LC_THREAD:
1343    case BFD_MACH_O_LC_UNIXTHREAD:
1344      if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1345	return -1;
1346      break;
1347    case BFD_MACH_O_LC_LOAD_DYLINKER:
1348    case BFD_MACH_O_LC_ID_DYLINKER:
1349      if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1350	return -1;
1351      break;
1352    case BFD_MACH_O_LC_LOAD_DYLIB:
1353    case BFD_MACH_O_LC_ID_DYLIB:
1354    case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1355      if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1356	return -1;
1357      break;
1358    case BFD_MACH_O_LC_PREBOUND_DYLIB:
1359      if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1360	return -1;
1361      break;
1362    case BFD_MACH_O_LC_LOADFVMLIB:
1363    case BFD_MACH_O_LC_IDFVMLIB:
1364    case BFD_MACH_O_LC_IDENT:
1365    case BFD_MACH_O_LC_FVMFILE:
1366    case BFD_MACH_O_LC_PREPAGE:
1367    case BFD_MACH_O_LC_ROUTINES:
1368    case BFD_MACH_O_LC_SUB_FRAMEWORK:
1369      break;
1370    case BFD_MACH_O_LC_DYSYMTAB:
1371      if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1372	return -1;
1373      break;
1374    case BFD_MACH_O_LC_SUB_UMBRELLA:
1375    case BFD_MACH_O_LC_SUB_CLIENT:
1376    case BFD_MACH_O_LC_SUB_LIBRARY:
1377    case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1378    case BFD_MACH_O_LC_PREBIND_CKSUM:
1379      break;
1380    default:
1381      fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1382	       (unsigned long) command->type);
1383      break;
1384    }
1385
1386  return 0;
1387}
1388
1389static void
1390bfd_mach_o_flatten_sections (bfd *abfd)
1391{
1392  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1393  long csect = 0;
1394  unsigned long i, j;
1395
1396  mdata->nsects = 0;
1397
1398  for (i = 0; i < mdata->header.ncmds; i++)
1399    {
1400      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1401	{
1402	  bfd_mach_o_segment_command *seg;
1403
1404	  seg = &mdata->commands[i].command.segment;
1405	  mdata->nsects += seg->nsects;
1406	}
1407    }
1408
1409  mdata->sections = bfd_alloc (abfd,
1410			       mdata->nsects * sizeof (bfd_mach_o_section *));
1411  csect = 0;
1412
1413  for (i = 0; i < mdata->header.ncmds; i++)
1414    {
1415      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1416	{
1417	  bfd_mach_o_segment_command *seg;
1418
1419	  seg = &mdata->commands[i].command.segment;
1420	  BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1421
1422	  for (j = 0; j < seg->nsects; j++)
1423	    mdata->sections[csect++] = &seg->sections[j];
1424	}
1425    }
1426}
1427
1428int
1429bfd_mach_o_scan_start_address (bfd *abfd)
1430{
1431  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1432  bfd_mach_o_thread_command *cmd = NULL;
1433  unsigned long i;
1434
1435  for (i = 0; i < mdata->header.ncmds; i++)
1436    {
1437      if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1438	  (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1439	{
1440	  if (cmd == NULL)
1441	    cmd = &mdata->commands[i].command.thread;
1442	  else
1443	    return 0;
1444	}
1445    }
1446
1447  if (cmd == NULL)
1448    return 0;
1449
1450  for (i = 0; i < cmd->nflavours; i++)
1451    {
1452      if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1453	  && (cmd->flavours[i].flavour
1454	      == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1455	{
1456	  unsigned char buf[4];
1457
1458	  bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1459
1460	  if (bfd_bread (buf, 4, abfd) != 4)
1461	    return -1;
1462
1463	  abfd->start_address = bfd_h_get_32 (abfd, buf);
1464	}
1465      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1466	       && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1467	{
1468	  unsigned char buf[4];
1469
1470	  bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1471
1472	  if (bfd_bread (buf, 4, abfd) != 4)
1473	    return -1;
1474
1475	  abfd->start_address = bfd_h_get_32 (abfd, buf);
1476	}
1477    }
1478
1479  return 0;
1480}
1481
1482int
1483bfd_mach_o_scan (bfd *abfd,
1484		 bfd_mach_o_header *header,
1485		 bfd_mach_o_data_struct *mdata)
1486{
1487  unsigned int i;
1488  enum bfd_architecture cputype;
1489  unsigned long cpusubtype;
1490
1491  mdata->header = *header;
1492  mdata->symbols = NULL;
1493
1494  abfd->flags = (abfd->xvec->object_flags
1495		 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1496  abfd->tdata.mach_o_data = mdata;
1497
1498  bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1499				   &cputype, &cpusubtype);
1500  if (cputype == bfd_arch_unknown)
1501    {
1502      fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1503	       header->cputype, header->cpusubtype);
1504      return -1;
1505    }
1506
1507  bfd_set_arch_mach (abfd, cputype, cpusubtype);
1508
1509  if (header->ncmds != 0)
1510    {
1511      mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
1512      if (mdata->commands == NULL)
1513	return -1;
1514
1515      for (i = 0; i < header->ncmds; i++)
1516	{
1517	  bfd_mach_o_load_command *cur = &mdata->commands[i];
1518
1519	  if (i == 0)
1520	    cur->offset = 28;
1521	  else
1522	    {
1523	      bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1524	      cur->offset = prev->offset + prev->len;
1525	    }
1526
1527	  if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1528	    return -1;
1529	}
1530    }
1531
1532  if (bfd_mach_o_scan_start_address (abfd) < 0)
1533    return -1;
1534
1535  bfd_mach_o_flatten_sections (abfd);
1536  return 0;
1537}
1538
1539bfd_boolean
1540bfd_mach_o_mkobject (bfd *abfd)
1541{
1542  bfd_mach_o_data_struct *mdata = NULL;
1543
1544  mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
1545  if (mdata == NULL)
1546    return FALSE;
1547  abfd->tdata.mach_o_data = mdata;
1548
1549  mdata->header.magic = 0;
1550  mdata->header.cputype = 0;
1551  mdata->header.cpusubtype = 0;
1552  mdata->header.filetype = 0;
1553  mdata->header.ncmds = 0;
1554  mdata->header.sizeofcmds = 0;
1555  mdata->header.flags = 0;
1556  mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1557  mdata->commands = NULL;
1558  mdata->nsymbols = 0;
1559  mdata->symbols = NULL;
1560  mdata->nsects = 0;
1561  mdata->sections = NULL;
1562  mdata->ibfd = NULL;
1563
1564  return TRUE;
1565}
1566
1567const bfd_target *
1568bfd_mach_o_object_p (bfd *abfd)
1569{
1570  struct bfd_preserve preserve;
1571  bfd_mach_o_header header;
1572
1573  preserve.marker = NULL;
1574  if (bfd_mach_o_read_header (abfd, &header) != 0)
1575    goto wrong;
1576
1577  if (! (header.byteorder == BFD_ENDIAN_BIG
1578	 || header.byteorder == BFD_ENDIAN_LITTLE))
1579    {
1580      fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1581	       (long) header.byteorder);
1582      goto wrong;
1583    }
1584
1585  if (! ((header.byteorder == BFD_ENDIAN_BIG
1586	  && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1587	  && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1588	 || (header.byteorder == BFD_ENDIAN_LITTLE
1589	     && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1590	     && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1591    goto wrong;
1592
1593  preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1594  if (preserve.marker == NULL
1595      || !bfd_preserve_save (abfd, &preserve))
1596    goto fail;
1597
1598  if (bfd_mach_o_scan (abfd, &header,
1599		       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1600    goto wrong;
1601
1602  bfd_preserve_finish (abfd, &preserve);
1603  return abfd->xvec;
1604
1605 wrong:
1606  bfd_set_error (bfd_error_wrong_format);
1607
1608 fail:
1609  if (preserve.marker != NULL)
1610    bfd_preserve_restore (abfd, &preserve);
1611  return NULL;
1612}
1613
1614const bfd_target *
1615bfd_mach_o_core_p (bfd *abfd)
1616{
1617  struct bfd_preserve preserve;
1618  bfd_mach_o_header header;
1619
1620  preserve.marker = NULL;
1621  if (bfd_mach_o_read_header (abfd, &header) != 0)
1622    goto wrong;
1623
1624  if (! (header.byteorder == BFD_ENDIAN_BIG
1625	 || header.byteorder == BFD_ENDIAN_LITTLE))
1626    {
1627      fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1628	       (long) header.byteorder);
1629      abort ();
1630    }
1631
1632  if (! ((header.byteorder == BFD_ENDIAN_BIG
1633	  && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1634	  && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1635	 || (header.byteorder == BFD_ENDIAN_LITTLE
1636	     && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1637	     && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1638    goto wrong;
1639
1640  if (header.filetype != BFD_MACH_O_MH_CORE)
1641    goto wrong;
1642
1643  preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1644  if (preserve.marker == NULL
1645      || !bfd_preserve_save (abfd, &preserve))
1646    goto fail;
1647
1648  if (bfd_mach_o_scan (abfd, &header,
1649		       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1650    goto wrong;
1651
1652  bfd_preserve_finish (abfd, &preserve);
1653  return abfd->xvec;
1654
1655 wrong:
1656  bfd_set_error (bfd_error_wrong_format);
1657
1658 fail:
1659  if (preserve.marker != NULL)
1660    bfd_preserve_restore (abfd, &preserve);
1661  return NULL;
1662}
1663
1664typedef struct mach_o_fat_archentry
1665{
1666  unsigned long cputype;
1667  unsigned long cpusubtype;
1668  unsigned long offset;
1669  unsigned long size;
1670  unsigned long align;
1671  bfd *abfd;
1672} mach_o_fat_archentry;
1673
1674typedef struct mach_o_fat_data_struct
1675{
1676  unsigned long magic;
1677  unsigned long nfat_arch;
1678  mach_o_fat_archentry *archentries;
1679} mach_o_fat_data_struct;
1680
1681const bfd_target *
1682bfd_mach_o_archive_p (bfd *abfd)
1683{
1684  mach_o_fat_data_struct *adata = NULL;
1685  unsigned char buf[20];
1686  unsigned long i;
1687
1688  bfd_seek (abfd, 0, SEEK_SET);
1689  if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1690    goto error;
1691
1692  adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1693  if (adata == NULL)
1694    goto error;
1695
1696  adata->magic = bfd_getb32 (buf);
1697  adata->nfat_arch = bfd_getb32 (buf + 4);
1698  if (adata->magic != 0xcafebabe)
1699    goto error;
1700
1701  adata->archentries =
1702    bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1703  if (adata->archentries == NULL)
1704    goto error;
1705
1706  for (i = 0; i < adata->nfat_arch; i++)
1707    {
1708      bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1709
1710      if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1711	goto error;
1712      adata->archentries[i].cputype = bfd_getb32 (buf);
1713      adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1714      adata->archentries[i].offset = bfd_getb32 (buf + 8);
1715      adata->archentries[i].size = bfd_getb32 (buf + 12);
1716      adata->archentries[i].align = bfd_getb32 (buf + 16);
1717      adata->archentries[i].abfd = NULL;
1718    }
1719
1720  abfd->tdata.mach_o_fat_data = adata;
1721  return abfd->xvec;
1722
1723 error:
1724  if (adata != NULL)
1725    bfd_release (abfd, adata);
1726  bfd_set_error (bfd_error_wrong_format);
1727  return NULL;
1728}
1729
1730bfd *
1731bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
1732{
1733  mach_o_fat_data_struct *adata;
1734  mach_o_fat_archentry *entry = NULL;
1735  unsigned long i;
1736
1737  adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
1738  BFD_ASSERT (adata != NULL);
1739
1740  /* Find index of previous entry.  */
1741  if (prev == NULL)
1742    i = 0;	/* Start at first one.  */
1743  else
1744    {
1745      for (i = 0; i < adata->nfat_arch; i++)
1746	{
1747	  if (adata->archentries[i].abfd == prev)
1748	    break;
1749	}
1750
1751      if (i == adata->nfat_arch)
1752	{
1753	  /* Not found.  */
1754	  bfd_set_error (bfd_error_bad_value);
1755	  return NULL;
1756	}
1757    i++;	/* Get next entry.  */
1758  }
1759
1760  if (i >= adata->nfat_arch)
1761    {
1762      bfd_set_error (bfd_error_no_more_archived_files);
1763      return NULL;
1764    }
1765
1766  entry = &adata->archentries[i];
1767  if (entry->abfd == NULL)
1768    {
1769      bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1770      char *s = NULL;
1771
1772      if (nbfd == NULL)
1773	return NULL;
1774
1775      nbfd->origin = entry->offset;
1776      s = bfd_malloc (strlen (archive->filename) + 1);
1777      if (s == NULL)
1778	return NULL;
1779      strcpy (s, archive->filename);
1780      nbfd->filename = s;
1781      nbfd->iostream = NULL;
1782      entry->abfd = nbfd;
1783    }
1784
1785  return entry->abfd;
1786}
1787
1788int
1789bfd_mach_o_lookup_section (bfd *abfd,
1790			   asection *section,
1791			   bfd_mach_o_load_command **mcommand,
1792			   bfd_mach_o_section **msection)
1793{
1794  struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1795  unsigned int i, j, num;
1796
1797  bfd_mach_o_load_command *ncmd = NULL;
1798  bfd_mach_o_section *nsect = NULL;
1799
1800  BFD_ASSERT (mcommand != NULL);
1801  BFD_ASSERT (msection != NULL);
1802
1803  num = 0;
1804  for (i = 0; i < md->header.ncmds; i++)
1805    {
1806      struct bfd_mach_o_load_command *cmd = &md->commands[i];
1807      struct bfd_mach_o_segment_command *seg = NULL;
1808
1809      if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1810	continue;
1811      seg = &cmd->command.segment;
1812
1813      if (seg->segment == section)
1814	{
1815	  if (num == 0)
1816	    ncmd = cmd;
1817	  num++;
1818	}
1819
1820      for (j = 0; j < seg->nsects; j++)
1821	{
1822	  struct bfd_mach_o_section *sect = &seg->sections[j];
1823
1824	  if (sect->bfdsection == section)
1825	    {
1826	      if (num == 0)
1827		nsect = sect;
1828	      num++;
1829	    }
1830	}
1831    }
1832
1833  *mcommand = ncmd;
1834  *msection = nsect;
1835  return num;
1836}
1837
1838int
1839bfd_mach_o_lookup_command (bfd *abfd,
1840			   bfd_mach_o_load_command_type type,
1841			   bfd_mach_o_load_command **mcommand)
1842{
1843  struct mach_o_data_struct *md = NULL;
1844  bfd_mach_o_load_command *ncmd = NULL;
1845  unsigned int i, num;
1846
1847  md = abfd->tdata.mach_o_data;
1848
1849  BFD_ASSERT (md != NULL);
1850  BFD_ASSERT (mcommand != NULL);
1851
1852  num = 0;
1853  for (i = 0; i < md->header.ncmds; i++)
1854    {
1855      struct bfd_mach_o_load_command *cmd = &md->commands[i];
1856
1857      if (cmd->type != type)
1858	continue;
1859
1860      if (num == 0)
1861	ncmd = cmd;
1862      num++;
1863    }
1864
1865  *mcommand = ncmd;
1866  return num;
1867}
1868
1869unsigned long
1870bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
1871{
1872  switch (type)
1873    {
1874    case BFD_MACH_O_CPU_TYPE_MC680x0:
1875      return 0x04000000;
1876    case BFD_MACH_O_CPU_TYPE_MC88000:
1877      return 0xffffe000;
1878    case BFD_MACH_O_CPU_TYPE_POWERPC:
1879      return 0xc0000000;
1880    case BFD_MACH_O_CPU_TYPE_I386:
1881      return 0xc0000000;
1882    case BFD_MACH_O_CPU_TYPE_SPARC:
1883      return 0xf0000000;
1884    case BFD_MACH_O_CPU_TYPE_I860:
1885      return 0;
1886    case BFD_MACH_O_CPU_TYPE_HPPA:
1887      return 0xc0000000 - 0x04000000;
1888    default:
1889      return 0;
1890    }
1891}
1892
1893int
1894bfd_mach_o_core_fetch_environment (bfd *abfd,
1895				   unsigned char **rbuf,
1896				   unsigned int *rlen)
1897{
1898  bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1899  unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
1900  unsigned int i = 0;
1901
1902  for (i = 0; i < mdata->header.ncmds; i++)
1903    {
1904      bfd_mach_o_load_command *cur = &mdata->commands[i];
1905      bfd_mach_o_segment_command *seg = NULL;
1906
1907      if (cur->type != BFD_MACH_O_LC_SEGMENT)
1908	continue;
1909
1910      seg = &cur->command.segment;
1911
1912      if ((seg->vmaddr + seg->vmsize) == stackaddr)
1913	{
1914	  unsigned long start = seg->fileoff;
1915	  unsigned long end = seg->fileoff + seg->filesize;
1916	  unsigned char *buf = bfd_malloc (1024);
1917	  unsigned long size = 1024;
1918
1919	  for (;;)
1920	    {
1921	      bfd_size_type nread = 0;
1922	      unsigned long offset;
1923	      int found_nonnull = 0;
1924
1925	      if (size > (end - start))
1926		size = (end - start);
1927
1928	      buf = bfd_realloc (buf, size);
1929
1930	      bfd_seek (abfd, end - size, SEEK_SET);
1931	      nread = bfd_bread (buf, size, abfd);
1932
1933	      if (nread != size)
1934		return -1;
1935
1936	      for (offset = 4; offset <= size; offset += 4)
1937		{
1938		  unsigned long val;
1939
1940		  val = *((unsigned long *) (buf + size - offset));
1941		  if (! found_nonnull)
1942		    {
1943		      if (val != 0)
1944			found_nonnull = 1;
1945		    }
1946		  else if (val == 0x0)
1947		    {
1948		      unsigned long bottom;
1949		      unsigned long top;
1950
1951		      bottom = seg->fileoff + seg->filesize - offset;
1952		      top = seg->fileoff + seg->filesize - 4;
1953		      *rbuf = bfd_malloc (top - bottom);
1954		      *rlen = top - bottom;
1955
1956		      memcpy (*rbuf, buf + size - *rlen, *rlen);
1957		      return 0;
1958		    }
1959		}
1960
1961	      if (size == (end - start))
1962		break;
1963
1964	      size *= 2;
1965	    }
1966	}
1967    }
1968
1969  return -1;
1970}
1971
1972char *
1973bfd_mach_o_core_file_failing_command (bfd *abfd)
1974{
1975  unsigned char *buf = NULL;
1976  unsigned int len = 0;
1977  int ret = -1;
1978
1979  ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
1980  if (ret < 0)
1981    return NULL;
1982
1983  return (char *) buf;
1984}
1985
1986int
1987bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
1988{
1989  return 0;
1990}
1991
1992#define TARGET_NAME 		mach_o_be_vec
1993#define TARGET_STRING     	"mach-o-be"
1994#define TARGET_BIG_ENDIAN 	1
1995#define TARGET_ARCHIVE 		0
1996
1997#include "mach-o-target.c"
1998
1999#undef TARGET_NAME
2000#undef TARGET_STRING
2001#undef TARGET_BIG_ENDIAN
2002#undef TARGET_ARCHIVE
2003
2004#define TARGET_NAME 		mach_o_le_vec
2005#define TARGET_STRING 		"mach-o-le"
2006#define TARGET_BIG_ENDIAN 	0
2007#define TARGET_ARCHIVE 		0
2008
2009#include "mach-o-target.c"
2010
2011#undef TARGET_NAME
2012#undef TARGET_STRING
2013#undef TARGET_BIG_ENDIAN
2014#undef TARGET_ARCHIVE
2015
2016#define TARGET_NAME 		mach_o_fat_vec
2017#define TARGET_STRING 		"mach-o-fat"
2018#define TARGET_BIG_ENDIAN 	1
2019#define TARGET_ARCHIVE 		1
2020
2021#include "mach-o-target.c"
2022
2023#undef TARGET_NAME
2024#undef TARGET_STRING
2025#undef TARGET_BIG_ENDIAN
2026#undef TARGET_ARCHIVE
2027