bfd/
[platform/upstream/binutils.git] / bfd / mach-o.c
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
107 bfd_boolean
108 bfd_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
126 static bfd_boolean
127 bfd_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
138 static bfd_boolean
139 bfd_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
150 static bfd_boolean
151 bfd_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
161 static long
162 bfd_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
181 static long
182 bfd_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
192 static long
193 bfd_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
230 static void
231 bfd_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
238 static void
239 bfd_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
257 static void
258 bfd_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
291 static int
292 bfd_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
311 static int
312 bfd_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
344 static int
345 bfd_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
370 static int
371 bfd_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
429 static int
430 bfd_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
470 static int
471 bfd_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
493 static bfd_boolean
494 bfd_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
569 static int
570 bfd_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
579 static asymbol *
580 bfd_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
591 static int
592 bfd_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
630 static asection *
631 bfd_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
664 static int
665 bfd_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
696 int
697 bfd_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
808 int
809 bfd_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
844 int
845 bfd_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
874 int
875 bfd_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
899 static const char *
900 bfd_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
920 static const char *
921 bfd_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
933 static int
934 bfd_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
983 static int
984 bfd_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
1038 static int
1039 bfd_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
1048 static int
1049 bfd_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
1156 static int
1157 bfd_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
1190 static int
1191 bfd_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
1250 static int
1251 bfd_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
1316 static int
1317 bfd_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
1389 static void
1390 bfd_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
1428 int
1429 bfd_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
1482 int
1483 bfd_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
1539 bfd_boolean
1540 bfd_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
1567 const bfd_target *
1568 bfd_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
1614 const bfd_target *
1615 bfd_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
1664 typedef 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
1674 typedef 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
1681 const bfd_target *
1682 bfd_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
1730 bfd *
1731 bfd_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
1788 int
1789 bfd_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
1838 int
1839 bfd_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
1869 unsigned long
1870 bfd_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
1893 int
1894 bfd_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
1972 char *
1973 bfd_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
1986 int
1987 bfd_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