OSDN Git Service

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