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