OSDN Git Service

2011-12-12 Iain Sandoe <iains@gcc.gnu.org>
[pf3gnuchains/pf3gnuchains4x.git] / bfd / mach-o.c
1 /* Mach-O support for BFD.
2    Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3    2009, 2010, 2011
4    Free Software Foundation, Inc.
5
6    This file is part of BFD, the Binary File Descriptor library.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24 #include "mach-o.h"
25 #include "bfd.h"
26 #include "libbfd.h"
27 #include "libiberty.h"
28 #include "aout/stab_gnu.h"
29 #include "mach-o/reloc.h"
30 #include "mach-o/external.h"
31 #include <ctype.h>
32
33 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p
34 #define bfd_mach_o_core_p bfd_mach_o_gen_core_p
35 #define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
36
37 #define FILE_ALIGN(off, algn) \
38   (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
39
40 static int bfd_mach_o_read_symtab_symbols (bfd *);
41
42 unsigned int
43 bfd_mach_o_version (bfd *abfd)
44 {
45   bfd_mach_o_data_struct *mdata = NULL;
46
47   BFD_ASSERT (bfd_mach_o_valid (abfd));
48   mdata = bfd_mach_o_get_data (abfd);
49
50   return mdata->header.version;
51 }
52
53 bfd_boolean
54 bfd_mach_o_valid (bfd *abfd)
55 {
56   if (abfd == NULL || abfd->xvec == NULL)
57     return FALSE;
58
59   if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
60     return FALSE;
61
62   if (bfd_mach_o_get_data (abfd) == NULL)
63     return FALSE;
64   return TRUE;
65 }
66
67 static INLINE bfd_boolean
68 mach_o_wide_p (bfd_mach_o_header *header)
69 {
70   switch (header->version)
71     {
72     case 1:
73       return FALSE;
74     case 2:
75       return TRUE;
76     default:
77       BFD_FAIL ();
78       return FALSE;
79     }
80 }
81
82 static INLINE bfd_boolean
83 bfd_mach_o_wide_p (bfd *abfd)
84 {
85   return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
86 }
87       
88 /* Tables to translate well known Mach-O segment/section names to bfd
89    names.  Use of canonical names (such as .text or .debug_frame) is required
90    by gdb.  */
91
92 struct mach_o_section_name_xlat
93 {
94   const char *bfd_name;
95   const char *mach_o_name;
96   flagword flags;
97 };
98
99 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
100   {
101     { ".debug_frame",    "__debug_frame",    SEC_DEBUGGING },
102     { ".debug_info",     "__debug_info",     SEC_DEBUGGING },
103     { ".debug_abbrev",   "__debug_abbrev",   SEC_DEBUGGING },
104     { ".debug_aranges",  "__debug_aranges",  SEC_DEBUGGING },
105     { ".debug_macinfo",  "__debug_macinfo",  SEC_DEBUGGING },
106     { ".debug_line",     "__debug_line",     SEC_DEBUGGING },
107     { ".debug_loc",      "__debug_loc",      SEC_DEBUGGING },
108     { ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING },
109     { ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING },
110     { ".debug_str",      "__debug_str",      SEC_DEBUGGING },
111     { ".debug_ranges",   "__debug_ranges",   SEC_DEBUGGING },
112     { NULL, NULL, 0}
113   };
114
115 static const struct mach_o_section_name_xlat text_section_names_xlat[] =
116   {
117     { ".text",     "__text",      SEC_CODE | SEC_LOAD },
118     { ".const",    "__const",     SEC_READONLY | SEC_DATA | SEC_LOAD },
119     { ".cstring",  "__cstring",   SEC_READONLY | SEC_DATA | SEC_LOAD },
120     { ".eh_frame", "__eh_frame",  SEC_READONLY | SEC_LOAD },
121     { NULL, NULL, 0}
122   };
123
124 static const struct mach_o_section_name_xlat data_section_names_xlat[] =
125   {
126     { ".data",                "__data",          SEC_DATA | SEC_LOAD },
127     { ".const_data",          "__const",         SEC_DATA | SEC_LOAD },
128     { ".dyld",                "__dyld",          SEC_DATA | SEC_LOAD },
129     { ".lazy_symbol_ptr",     "__la_symbol_ptr", SEC_DATA | SEC_LOAD },
130     { ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD },
131     { ".bss",                 "__bss",           SEC_NO_FLAGS },
132     { NULL, NULL, 0}
133   };
134
135 struct mach_o_segment_name_xlat
136 {
137   /* Segment name.  */
138   const char *segname;
139
140   /* List of known sections for the segment.  */
141   const struct mach_o_section_name_xlat *sections;
142 };
143
144 /* List of known segment names.  */
145
146 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
147   {
148     { "__TEXT", text_section_names_xlat },
149     { "__DATA", data_section_names_xlat },
150     { "__DWARF", dwarf_section_names_xlat },
151     { NULL, NULL }
152   };
153
154 /* Mach-O to bfd names.  */
155
156 void
157 bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
158                                    const char **name, flagword *flags)
159 {
160   const struct mach_o_segment_name_xlat *seg;
161
162   *name = NULL;
163   *flags = SEC_NO_FLAGS;
164
165   for (seg = segsec_names_xlat; seg->segname; seg++)
166     {
167       if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
168         {
169           const struct mach_o_section_name_xlat *sec;
170
171           for (sec = seg->sections; sec->mach_o_name; sec++)
172             {
173               if (strncmp (sec->mach_o_name, sectname,
174                            BFD_MACH_O_SECTNAME_SIZE) == 0)
175                 {
176                   *name = sec->bfd_name;
177                   *flags = sec->flags;
178                   return;
179                 }
180             }
181           return;
182         }
183     }
184 }
185
186 /* Convert Mach-O section name to BFD.  Try to use standard names, otherwise
187    forge a new name.  SEGNAME and SECTNAME are 16 bytes strings.  */
188
189 static void
190 bfd_mach_o_convert_section_name_to_bfd
191   (bfd *abfd, const char *segname, const char *sectname,
192    const char **name, flagword *flags)
193 {
194   char *res;
195   unsigned int len;
196   const char *pfx = "";
197
198   /* First search for a canonical name.  */
199   bfd_mach_o_normalize_section_name (segname, sectname, name, flags);
200
201   /* Return now if found.  */
202   if (*name)
203     return;
204
205   len = 16 + 1 + 16 + 1;
206
207   /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
208      with an underscore.  */
209   if (segname[0] != '_')
210     {
211       static const char seg_pfx[] = "LC_SEGMENT.";
212
213       pfx = seg_pfx;
214       len += sizeof (seg_pfx) - 1;
215     }
216
217   res = bfd_alloc (abfd, len);
218   if (res == NULL)
219     return;
220   snprintf (res, len, "%s%.16s.%.16s", pfx, segname, sectname);
221   *name = res;
222   *flags = SEC_NO_FLAGS;
223 }
224
225 /* Convert a bfd section name to a Mach-O segment + section name.  */
226
227 static void
228 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
229                                            asection *sect,
230                                            bfd_mach_o_section *section)
231 {
232   const struct mach_o_segment_name_xlat *seg;
233   const char *name = bfd_get_section_name (abfd, sect);
234   const char *dot;
235   unsigned int len;
236   unsigned int seglen;
237   unsigned int seclen;
238
239   /* List of well known names.  They all start with a dot.  */
240   if (name[0] == '.')
241     for (seg = segsec_names_xlat; seg->segname; seg++)
242       {
243         const struct mach_o_section_name_xlat *sec;
244
245         for (sec = seg->sections; sec->mach_o_name; sec++)
246           {
247             if (strcmp (sec->bfd_name, name) == 0)
248               {
249                 strcpy (section->segname, seg->segname);
250                 strcpy (section->sectname, sec->mach_o_name);
251                 return;
252               }
253           }
254       }
255
256   /* Strip LC_SEGMENT. prefix.  */
257   if (strncmp (name, "LC_SEGMENT.", 11) == 0)
258     name += 11;
259
260   /* Find a dot.  */
261   dot = strchr (name, '.');
262   len = strlen (name);
263
264   /* Try to split name into segment and section names.  */
265   if (dot && dot != name)
266     {
267       seglen = dot - name;
268       seclen = len - (dot + 1 - name);
269
270       if (seglen < 16 && seclen < 16)
271         {
272           memcpy (section->segname, name, seglen);
273           section->segname[seglen] = 0;
274           memcpy (section->sectname, dot + 1, seclen);
275           section->sectname[seclen] = 0;
276           return;
277         }
278     }
279
280   if (len > 16)
281     len = 16;
282   memcpy (section->segname, name, len);
283   section->segname[len] = 0;
284   memcpy (section->sectname, name, len);
285   section->sectname[len] = 0;
286 }
287
288 /* Return the size of an entry for section SEC.
289    Must be called only for symbol pointer section and symbol stubs
290    sections.  */
291
292 static unsigned int
293 bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
294 {
295   switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
296     {
297     case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
298     case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
299       return bfd_mach_o_wide_p (abfd) ? 8 : 4;
300     case BFD_MACH_O_S_SYMBOL_STUBS:
301       return sec->reserved2;
302     default:
303       BFD_FAIL ();
304       return 0;
305     }
306 }
307
308 /* Return the number of indirect symbols for a section.
309    Must be called only for symbol pointer section and symbol stubs
310    sections.  */
311
312 static unsigned int
313 bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
314 {
315   unsigned int elsz;
316
317   elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
318   if (elsz == 0)
319     return 0;
320   else
321     return sec->size / elsz;
322 }
323
324
325 /* Copy any private info we understand from the input symbol
326    to the output symbol.  */
327
328 bfd_boolean
329 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
330                                          asymbol *isymbol ATTRIBUTE_UNUSED,
331                                          bfd *obfd ATTRIBUTE_UNUSED,
332                                          asymbol *osymbol ATTRIBUTE_UNUSED)
333 {
334   return TRUE;
335 }
336
337 /* Copy any private info we understand from the input section
338    to the output section.  */
339
340 bfd_boolean
341 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
342                                           asection *isection ATTRIBUTE_UNUSED,
343                                           bfd *obfd ATTRIBUTE_UNUSED,
344                                           asection *osection ATTRIBUTE_UNUSED)
345 {
346   return TRUE;
347 }
348
349 /* Copy any private info we understand from the input bfd
350    to the output bfd.  */
351
352 bfd_boolean
353 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
354 {
355   if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
356       || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
357     return TRUE;
358
359   BFD_ASSERT (bfd_mach_o_valid (ibfd));
360   BFD_ASSERT (bfd_mach_o_valid (obfd));
361
362   /* FIXME: copy commands.  */
363
364   return TRUE;
365 }
366
367 /* Count the total number of symbols.  */
368
369 static long
370 bfd_mach_o_count_symbols (bfd *abfd)
371 {
372   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
373
374   if (mdata->symtab == NULL)
375     return 0;
376   return mdata->symtab->nsyms;
377 }
378
379 long
380 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
381 {
382   long nsyms = bfd_mach_o_count_symbols (abfd);
383
384   return ((nsyms + 1) * sizeof (asymbol *));
385 }
386
387 long
388 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
389 {
390   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
391   long nsyms = bfd_mach_o_count_symbols (abfd);
392   bfd_mach_o_symtab_command *sym = mdata->symtab;
393   unsigned long j;
394
395   if (nsyms < 0)
396     return nsyms;
397
398   if (nsyms == 0)
399     {
400       /* Do not try to read symbols if there are none.  */
401       alocation[0] = NULL;
402       return 0;
403     }
404
405   if (!bfd_mach_o_read_symtab_symbols (abfd))
406     {
407       (*_bfd_error_handler)
408         (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
409       return 0;
410     }
411
412   BFD_ASSERT (sym->symbols != NULL);
413
414   for (j = 0; j < sym->nsyms; j++)
415     alocation[j] = &sym->symbols[j].symbol;
416
417   alocation[j] = NULL;
418
419   return nsyms;
420 }
421
422 long
423 bfd_mach_o_get_synthetic_symtab (bfd *abfd,
424                                  long symcount ATTRIBUTE_UNUSED,
425                                  asymbol **syms ATTRIBUTE_UNUSED,
426                                  long dynsymcount ATTRIBUTE_UNUSED,
427                                  asymbol **dynsyms ATTRIBUTE_UNUSED,
428                                  asymbol **ret)
429 {
430   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
431   bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
432   bfd_mach_o_symtab_command *symtab = mdata->symtab;
433   asymbol *s;
434   unsigned long count, i, j, n;
435   size_t size;
436   char *names;
437   char *nul_name;
438
439   *ret = NULL;
440
441   if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
442     return 0;
443
444   if (dysymtab->nindirectsyms == 0)
445     return 0;
446
447   count = dysymtab->nindirectsyms;
448   size = count * sizeof (asymbol) + 1;
449
450   for (j = 0; j < count; j++)
451     {
452       unsigned int isym = dysymtab->indirect_syms[j];
453               
454       if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
455         size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
456     }
457
458   s = *ret = (asymbol *) bfd_malloc (size);
459   if (s == NULL)
460     return -1;
461   names = (char *) (s + count);
462   nul_name = names;
463   *names++ = 0;
464   
465   n = 0;
466   for (i = 0; i < mdata->nsects; i++)
467     {
468       bfd_mach_o_section *sec = mdata->sections[i];
469       unsigned int first, last;
470       bfd_vma addr;
471       bfd_vma entry_size;
472       
473       switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
474         {
475         case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
476         case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
477         case BFD_MACH_O_S_SYMBOL_STUBS:
478           first = sec->reserved1;
479           last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
480           addr = sec->addr;
481           entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
482           for (j = first; j < last; j++)
483             {
484               unsigned int isym = dysymtab->indirect_syms[j];
485
486               s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
487               s->section = sec->bfdsection;
488               s->value = addr - sec->addr;
489               s->udata.p = NULL;
490               
491               if (isym < symtab->nsyms
492                   && symtab->symbols[isym].symbol.name)
493                 {
494                   const char *sym = symtab->symbols[isym].symbol.name;
495                   size_t len;
496
497                   s->name = names;
498                   len = strlen (sym);
499                   memcpy (names, sym, len);
500                   names += len;
501                   memcpy (names, "$stub", sizeof ("$stub"));
502                   names += sizeof ("$stub");
503                 }
504               else
505                 s->name = nul_name;
506
507               addr += entry_size;
508               s++;
509               n++;
510             }
511           break;
512         default:
513           break;
514         }
515     }
516
517   return n;
518 }
519
520 void
521 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
522                             asymbol *symbol,
523                             symbol_info *ret)
524 {
525   bfd_symbol_info (symbol, ret);
526 }
527
528 void
529 bfd_mach_o_print_symbol (bfd *abfd,
530                          void * afile,
531                          asymbol *symbol,
532                          bfd_print_symbol_type how)
533 {
534   FILE *file = (FILE *) afile;
535   const char *name;
536   bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
537
538   switch (how)
539     {
540     case bfd_print_symbol_name:
541       fprintf (file, "%s", symbol->name);
542       break;
543     default:
544       bfd_print_symbol_vandf (abfd, (void *) file, symbol);
545       if (asym->n_type & BFD_MACH_O_N_STAB)
546         name = bfd_get_stab_name (asym->n_type);
547       else
548         switch (asym->n_type & BFD_MACH_O_N_TYPE)
549           {
550           case BFD_MACH_O_N_UNDF:
551             if (symbol->value == 0)
552               name = "UND";
553             else
554               name = "COM";
555             break;
556           case BFD_MACH_O_N_ABS:
557             name = "ABS";
558             break;
559           case BFD_MACH_O_N_INDR:
560             name = "INDR";
561             break;
562           case BFD_MACH_O_N_PBUD:
563             name = "PBUD";
564             break;
565           case BFD_MACH_O_N_SECT:
566             name = "SECT";
567             break;
568           default:
569             name = "???";
570             break;
571           }
572       if (name == NULL)
573         name = "";
574       fprintf (file, " %02x %-6s %02x %04x",
575                asym->n_type, name, asym->n_sect, asym->n_desc);
576       if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
577           && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
578         fprintf (file, " [%s]", symbol->section->name);
579       fprintf (file, " %s", symbol->name);
580     }
581 }
582
583 static void
584 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
585                                  bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
586                                  enum bfd_architecture *type,
587                                  unsigned long *subtype)
588 {
589   *subtype = bfd_arch_unknown;
590
591   switch (mtype)
592     {
593     case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
594     case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
595     case BFD_MACH_O_CPU_TYPE_I386:
596       *type = bfd_arch_i386;
597       *subtype = bfd_mach_i386_i386;
598       break;
599     case BFD_MACH_O_CPU_TYPE_X86_64:
600       *type = bfd_arch_i386;
601       *subtype = bfd_mach_x86_64;
602       break;
603     case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
604     case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
605     case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
606     case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
607     case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
608     case BFD_MACH_O_CPU_TYPE_SPARC:
609       *type = bfd_arch_sparc;
610       *subtype = bfd_mach_sparc;
611       break;
612     case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
613     case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
614     case BFD_MACH_O_CPU_TYPE_POWERPC:
615       *type = bfd_arch_powerpc;
616       *subtype = bfd_mach_ppc;
617       break;
618     case BFD_MACH_O_CPU_TYPE_POWERPC_64:
619       *type = bfd_arch_powerpc;
620       *subtype = bfd_mach_ppc64;
621       break;
622     default:
623       *type = bfd_arch_unknown;
624       break;
625     }
626 }
627
628 static bfd_boolean
629 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
630 {
631   struct mach_o_header_external raw;
632   unsigned int size;
633
634   size = mach_o_wide_p (header) ?
635     BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
636
637   bfd_h_put_32 (abfd, header->magic, raw.magic);
638   bfd_h_put_32 (abfd, header->cputype, raw.cputype);
639   bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
640   bfd_h_put_32 (abfd, header->filetype, raw.filetype);
641   bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
642   bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
643   bfd_h_put_32 (abfd, header->flags, raw.flags);
644
645   if (mach_o_wide_p (header))
646     bfd_h_put_32 (abfd, header->reserved, raw.reserved);
647
648   if (bfd_seek (abfd, 0, SEEK_SET) != 0
649       || bfd_bwrite (&raw, size, abfd) != size)
650     return FALSE;
651
652   return TRUE;
653 }
654
655 static int
656 bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
657 {
658   bfd_mach_o_thread_command *cmd = &command->command.thread;
659   unsigned int i;
660   struct mach_o_thread_command_external raw;
661   unsigned int offset;
662
663   BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
664               || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
665
666   offset = 8;
667   for (i = 0; i < cmd->nflavours; i++)
668     {
669       BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
670       BFD_ASSERT (cmd->flavours[i].offset ==
671                   (command->offset + offset + BFD_MACH_O_LC_SIZE));
672
673       bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
674       bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
675
676       if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
677           || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
678         return -1;
679
680       offset += cmd->flavours[i].size + sizeof (raw);
681     }
682
683   return 0;
684 }
685
686 long
687 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
688                                   asection *asect)
689 {
690   return (asect->reloc_count + 1) * sizeof (arelent *);
691 }
692
693 static int
694 bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
695                                    struct mach_o_reloc_info_external *raw,
696                                    arelent *res, asymbol **syms)
697 {
698   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
699   bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
700   bfd_mach_o_reloc_info reloc;
701   bfd_vma addr;
702   bfd_vma symnum;
703   asymbol **sym;
704
705   addr = bfd_get_32 (abfd, raw->r_address);
706   symnum = bfd_get_32 (abfd, raw->r_symbolnum);
707   
708   if (addr & BFD_MACH_O_SR_SCATTERED)
709     {
710       unsigned int j;
711
712       /* Scattered relocation.
713          Extract section and offset from r_value.  */
714       res->sym_ptr_ptr = NULL;
715       res->addend = 0;
716       for (j = 0; j < mdata->nsects; j++)
717         {
718           bfd_mach_o_section *sect = mdata->sections[j];
719           if (symnum >= sect->addr && symnum < sect->addr + sect->size)
720             {
721               res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
722               res->addend = symnum - sect->addr;
723               break;
724             }
725         }
726       res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
727       reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
728       reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
729       reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
730       reloc.r_scattered = 1;
731     }
732   else
733     {
734       unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
735       res->addend = 0;
736       res->address = addr;
737       if (symnum & BFD_MACH_O_R_EXTERN)
738         {
739           sym = syms + num;
740           reloc.r_extern = 1;
741         }
742       else
743         {
744           BFD_ASSERT (num != 0);
745           BFD_ASSERT (num <= mdata->nsects);
746           sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
747           /* For a symbol defined in section S, the addend (stored in the
748              binary) contains the address of the section.  To comply with
749              bfd conventio, substract the section address.
750              Use the address from the header, so that the user can modify
751              the vma of the section.  */
752           res->addend = -mdata->sections[num - 1]->addr;
753           reloc.r_extern = 0;
754         }
755       res->sym_ptr_ptr = sym;
756       reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
757       reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
758       reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
759       reloc.r_scattered = 0;
760     }
761   
762   if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
763     return -1;
764   return 0;
765 }
766
767 static int
768 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
769                                 unsigned long count,
770                                 arelent *res, asymbol **syms)
771 {
772   unsigned long i;
773   struct mach_o_reloc_info_external *native_relocs;
774   bfd_size_type native_size;
775
776   /* Allocate and read relocs.  */
777   native_size = count * BFD_MACH_O_RELENT_SIZE;
778   native_relocs =
779     (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
780   if (native_relocs == NULL)
781     return -1;
782
783   if (bfd_seek (abfd, filepos, SEEK_SET) != 0
784       || bfd_bread (native_relocs, native_size, abfd) != native_size)
785     goto err;
786
787   for (i = 0; i < count; i++)
788     {
789       if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
790                                              &res[i], syms) < 0)
791         goto err;
792     }
793   free (native_relocs);
794   return i;
795  err:
796   free (native_relocs);
797   return -1;
798 }
799
800 long
801 bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
802                                arelent **rels, asymbol **syms)
803 {
804   bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
805   unsigned long i;
806   arelent *res;
807
808   if (asect->reloc_count == 0)
809     return 0;
810
811   /* No need to go further if we don't know how to read relocs.  */
812   if (bed->_bfd_mach_o_swap_reloc_in == NULL)
813     return 0;
814
815   res = bfd_malloc (asect->reloc_count * sizeof (arelent));
816   if (res == NULL)
817     return -1;
818
819   if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
820                                       asect->reloc_count, res, syms) < 0)
821     {
822       free (res);
823       return -1;
824     }
825
826   for (i = 0; i < asect->reloc_count; i++)
827     rels[i] = &res[i];
828   rels[i] = NULL;
829   asect->relocation = res;
830
831   return i;
832 }
833
834 long
835 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
836 {
837   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
838
839   if (mdata->dysymtab == NULL)
840     return 1;
841   return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
842     * sizeof (arelent *);
843 }
844
845 long
846 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
847                                        struct bfd_symbol **syms)
848 {
849   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
850   bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
851   bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
852   unsigned long i;
853   arelent *res;
854
855   if (dysymtab == NULL)
856     return 0;
857   if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
858     return 0;
859
860   /* No need to go further if we don't know how to read relocs.  */
861   if (bed->_bfd_mach_o_swap_reloc_in == NULL)
862     return 0;
863
864   res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
865   if (res == NULL)
866     return -1;
867
868   if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
869                                       dysymtab->nextrel, res, syms) < 0)
870     {
871       free (res);
872       return -1;
873     }
874
875   if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
876                                       dysymtab->nlocrel,
877                                       res + dysymtab->nextrel, syms) < 0)
878     {
879       free (res);
880       return -1;
881     }
882
883   for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
884     rels[i] = &res[i];
885   rels[i] = NULL;
886   return i;
887 }
888
889 static bfd_boolean
890 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
891 {
892   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
893   unsigned int i;
894   arelent **entries;
895   asection *sec;
896   bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
897
898   sec = section->bfdsection;
899   if (sec->reloc_count == 0)
900     return TRUE;
901
902   if (bed->_bfd_mach_o_swap_reloc_out == NULL)
903     return TRUE;
904
905   /* Allocate relocation room.  */
906   mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
907   section->nreloc = sec->reloc_count;
908   sec->rel_filepos = mdata->filelen;
909   section->reloff = sec->rel_filepos;
910   mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
911
912   if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
913     return FALSE;
914
915   /* Convert and write.  */
916   entries = section->bfdsection->orelocation;
917   for (i = 0; i < section->nreloc; i++)
918     {
919       arelent *rel = entries[i];
920       struct mach_o_reloc_info_external raw;
921       bfd_mach_o_reloc_info info, *pinfo = &info;
922
923       /* Convert relocation to an intermediate representation.  */
924       if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
925         return FALSE;
926
927       /* Lower the relocation info.  */
928       if (pinfo->r_scattered)
929         {
930           unsigned long v;
931
932           v = BFD_MACH_O_SR_SCATTERED
933             | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
934             | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
935             | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
936             | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
937           /* Note: scattered relocs have field in reverse order...  */
938           bfd_put_32 (abfd, v, raw.r_address);
939           bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
940         }
941       else
942         {
943           unsigned long v;
944
945           bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
946           v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
947             | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
948             | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
949             | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
950             | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
951           bfd_put_32 (abfd, v, raw.r_symbolnum);
952         }
953
954       if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
955           != BFD_MACH_O_RELENT_SIZE)
956         return FALSE;
957     }
958   return TRUE;
959 }
960
961 static int
962 bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
963 {
964   struct mach_o_section_32_external raw;
965
966   memcpy (raw.sectname, section->sectname, 16);
967   memcpy (raw.segname, section->segname, 16);
968   bfd_h_put_32 (abfd, section->addr, raw.addr);
969   bfd_h_put_32 (abfd, section->size, raw.size);
970   bfd_h_put_32 (abfd, section->offset, raw.offset);
971   bfd_h_put_32 (abfd, section->align, raw.align);
972   bfd_h_put_32 (abfd, section->reloff, raw.reloff);
973   bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
974   bfd_h_put_32 (abfd, section->flags, raw.flags);
975   bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
976   bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
977
978   if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
979       != BFD_MACH_O_SECTION_SIZE)
980     return -1;
981
982   return 0;
983 }
984
985 static int
986 bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
987 {
988   struct mach_o_section_64_external raw;
989
990   memcpy (raw.sectname, section->sectname, 16);
991   memcpy (raw.segname, section->segname, 16);
992   bfd_h_put_64 (abfd, section->addr, raw.addr);
993   bfd_h_put_64 (abfd, section->size, raw.size);
994   bfd_h_put_32 (abfd, section->offset, raw.offset);
995   bfd_h_put_32 (abfd, section->align, raw.align);
996   bfd_h_put_32 (abfd, section->reloff, raw.reloff);
997   bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
998   bfd_h_put_32 (abfd, section->flags, raw.flags);
999   bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
1000   bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1001   bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
1002
1003   if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
1004       != BFD_MACH_O_SECTION_64_SIZE)
1005     return -1;
1006
1007   return 0;
1008 }
1009
1010 static int
1011 bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1012 {
1013   struct mach_o_segment_command_32_external raw;
1014   bfd_mach_o_segment_command *seg = &command->command.segment;
1015   bfd_mach_o_section *sec;
1016
1017   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1018
1019   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1020     if (!bfd_mach_o_write_relocs (abfd, sec))
1021       return -1;
1022
1023   memcpy (raw.segname, seg->segname, 16);
1024   bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1025   bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1026   bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1027   bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1028   bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1029   bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1030   bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1031   bfd_h_put_32 (abfd, seg->flags, raw.flags);
1032   
1033   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1034       || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1035     return -1;
1036
1037   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1038     if (bfd_mach_o_write_section_32 (abfd, sec))
1039       return -1;
1040
1041   return 0;
1042 }
1043
1044 static int
1045 bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1046 {
1047   struct mach_o_segment_command_64_external raw;
1048   bfd_mach_o_segment_command *seg = &command->command.segment;
1049   bfd_mach_o_section *sec;
1050
1051   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1052
1053   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1054     if (!bfd_mach_o_write_relocs (abfd, sec))
1055       return -1;
1056
1057   memcpy (raw.segname, seg->segname, 16);
1058   bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1059   bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1060   bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1061   bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1062   bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1063   bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1064   bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1065   bfd_h_put_32 (abfd, seg->flags, raw.flags);
1066
1067   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1068       || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1069     return -1;
1070
1071   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1072     if (bfd_mach_o_write_section_64 (abfd, sec))
1073       return -1;
1074
1075   return 0;
1076 }
1077
1078 static bfd_boolean
1079 bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1080 {
1081   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1082   bfd_mach_o_symtab_command *sym = &command->command.symtab;
1083   unsigned long i;
1084   unsigned int wide = bfd_mach_o_wide_p (abfd);
1085   unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1086   struct bfd_strtab_hash *strtab;
1087   asymbol **symbols = bfd_get_outsymbols (abfd);
1088
1089   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1090
1091   /* Write the symbols first.  */
1092   mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1093   sym->symoff = mdata->filelen;
1094   if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1095     return FALSE;
1096
1097   sym->nsyms = bfd_get_symcount (abfd);
1098   mdata->filelen += sym->nsyms * symlen;
1099
1100   strtab = _bfd_stringtab_init ();
1101   if (strtab == NULL)
1102     return FALSE;
1103
1104   for (i = 0; i < sym->nsyms; i++)
1105     {
1106       bfd_size_type str_index;
1107       bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1108
1109       /* Compute name index.  */
1110       /* An index of 0 always means the empty string.  */
1111       if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
1112         str_index = 0;
1113       else
1114         {
1115           str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1116           if (str_index == (bfd_size_type) -1)
1117             goto err;
1118         }
1119
1120       if (wide)
1121         {
1122           struct mach_o_nlist_64_external raw;
1123
1124           bfd_h_put_32 (abfd, str_index, raw.n_strx);
1125           bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1126           bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1127           bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1128           bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1129                         raw.n_value);
1130
1131           if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1132             goto err;
1133         }
1134       else
1135         {
1136           struct mach_o_nlist_external raw;
1137
1138           bfd_h_put_32 (abfd, str_index, raw.n_strx);
1139           bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1140           bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1141           bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1142           bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1143                         raw.n_value);
1144
1145           if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1146             goto err;
1147         }
1148     }
1149   sym->strsize = _bfd_stringtab_size (strtab);
1150   sym->stroff = mdata->filelen;
1151   mdata->filelen += sym->strsize;
1152
1153   if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1154     goto err;
1155   _bfd_stringtab_free (strtab);
1156
1157   /* The command.  */
1158   {
1159     struct mach_o_symtab_command_external raw;
1160
1161     bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1162     bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1163     bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1164     bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1165
1166     if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1167         || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1168       return FALSE;
1169   }
1170
1171   return TRUE;
1172
1173  err:
1174   _bfd_stringtab_free (strtab);
1175   return FALSE;
1176 }
1177
1178 /* Process the symbols and generate Mach-O specific fields.
1179    Number them.  */
1180
1181 static bfd_boolean
1182 bfd_mach_o_mangle_symbols (bfd *abfd)
1183 {
1184   unsigned long i;
1185   asymbol **symbols = bfd_get_outsymbols (abfd);
1186
1187   for (i = 0; i < bfd_get_symcount (abfd); i++)
1188     {
1189       bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1190
1191       if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1192         {
1193           /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1194              symbols should be N_UNDEF | N_EXT), we suppose the back-end
1195              values haven't been set.  */
1196           if (s->symbol.section == bfd_abs_section_ptr)
1197             s->n_type = BFD_MACH_O_N_ABS;
1198           else if (s->symbol.section == bfd_und_section_ptr)
1199             {
1200               s->n_type = BFD_MACH_O_N_UNDF;
1201               if (s->symbol.flags & BSF_WEAK)
1202                 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1203             }
1204           else if (s->symbol.section == bfd_com_section_ptr)
1205             s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1206           else
1207             s->n_type = BFD_MACH_O_N_SECT;
1208           
1209           if (s->symbol.flags & BSF_GLOBAL)
1210             s->n_type |= BFD_MACH_O_N_EXT;
1211         }
1212
1213       /* Compute section index.  */
1214       if (s->symbol.section != bfd_abs_section_ptr
1215           && s->symbol.section != bfd_und_section_ptr
1216           && s->symbol.section != bfd_com_section_ptr)
1217         s->n_sect = s->symbol.section->target_index;
1218
1219       /* Number symbols.  */
1220       s->symbol.udata.i = i;
1221     }
1222   return TRUE;
1223 }
1224
1225 bfd_boolean
1226 bfd_mach_o_write_contents (bfd *abfd)
1227 {
1228   unsigned int i;
1229   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1230
1231   if (mdata->header.ncmds == 0)
1232     if (!bfd_mach_o_build_commands (abfd))
1233       return FALSE;
1234
1235   /* Now write header information.  */
1236   if (mdata->header.filetype == 0)
1237     {
1238       if (abfd->flags & EXEC_P)
1239         mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1240       else if (abfd->flags & DYNAMIC)
1241         mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1242       else
1243         mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1244     }
1245   if (!bfd_mach_o_write_header (abfd, &mdata->header))
1246     return FALSE;
1247
1248   /* Assign a number to each symbols.  */
1249   if (!bfd_mach_o_mangle_symbols (abfd))
1250     return FALSE;
1251
1252   for (i = 0; i < mdata->header.ncmds; i++)
1253     {
1254       struct mach_o_load_command_external raw;
1255       bfd_mach_o_load_command *cur = &mdata->commands[i];
1256       unsigned long typeflag;
1257
1258       typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
1259
1260       bfd_h_put_32 (abfd, typeflag, raw.cmd);
1261       bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
1262
1263       if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1264           || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
1265         return FALSE;
1266
1267       switch (cur->type)
1268         {
1269         case BFD_MACH_O_LC_SEGMENT:
1270           if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1271             return FALSE;
1272           break;
1273         case BFD_MACH_O_LC_SEGMENT_64:
1274           if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
1275             return FALSE;
1276           break;
1277         case BFD_MACH_O_LC_SYMTAB:
1278           if (!bfd_mach_o_write_symtab (abfd, cur))
1279             return FALSE;
1280           break;
1281         case BFD_MACH_O_LC_SYMSEG:
1282           break;
1283         case BFD_MACH_O_LC_THREAD:
1284         case BFD_MACH_O_LC_UNIXTHREAD:
1285           if (bfd_mach_o_write_thread (abfd, cur) != 0)
1286             return FALSE;
1287           break;
1288         case BFD_MACH_O_LC_LOADFVMLIB:
1289         case BFD_MACH_O_LC_IDFVMLIB:
1290         case BFD_MACH_O_LC_IDENT:
1291         case BFD_MACH_O_LC_FVMFILE:
1292         case BFD_MACH_O_LC_PREPAGE:
1293         case BFD_MACH_O_LC_DYSYMTAB:
1294         case BFD_MACH_O_LC_LOAD_DYLIB:
1295         case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1296         case BFD_MACH_O_LC_ID_DYLIB:
1297         case BFD_MACH_O_LC_REEXPORT_DYLIB:
1298         case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1299         case BFD_MACH_O_LC_LOAD_DYLINKER:
1300         case BFD_MACH_O_LC_ID_DYLINKER:
1301         case BFD_MACH_O_LC_PREBOUND_DYLIB:
1302         case BFD_MACH_O_LC_ROUTINES:
1303         case BFD_MACH_O_LC_SUB_FRAMEWORK:
1304           break;
1305         default:
1306           (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1307                                  (unsigned long) cur->type);
1308           return FALSE;
1309         }
1310     }
1311
1312   return TRUE;
1313 }
1314
1315 static void
1316 bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
1317                                       asection *sec)
1318 {
1319   bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
1320   if (seg->sect_head == NULL)
1321     seg->sect_head = s;
1322   else
1323     seg->sect_tail->next = s;
1324   seg->sect_tail = s;
1325 }
1326
1327 /* Create section Mach-O flags from BFD flags.  */
1328
1329 static void
1330 bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
1331 {
1332   flagword bfd_flags;
1333   bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
1334
1335   /* Create default flags.  */
1336   bfd_flags = bfd_get_section_flags (abfd, sec);
1337   if ((bfd_flags & SEC_CODE) == SEC_CODE)
1338     s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1339       | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1340       | BFD_MACH_O_S_REGULAR;
1341   else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1342     s->flags = BFD_MACH_O_S_ZEROFILL;
1343   else if (bfd_flags & SEC_DEBUGGING)
1344     s->flags = BFD_MACH_O_S_REGULAR |  BFD_MACH_O_S_ATTR_DEBUG;
1345   else
1346     s->flags = BFD_MACH_O_S_REGULAR;
1347 }
1348
1349 /* Build Mach-O load commands from the sections.  */
1350
1351 bfd_boolean
1352 bfd_mach_o_build_commands (bfd *abfd)
1353 {
1354   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1355   unsigned int wide = mach_o_wide_p (&mdata->header);
1356   bfd_mach_o_segment_command *seg;
1357   asection *sec;
1358   bfd_mach_o_load_command *cmd;
1359   bfd_mach_o_load_command *symtab_cmd;
1360   int target_index;
1361
1362   /* Return now if commands are already built.  */
1363   if (mdata->header.ncmds)
1364     return FALSE;
1365
1366   /* Very simple version: a command (segment) to contain all the sections and
1367      a command for the symbol table.  */
1368   mdata->header.ncmds = 2;
1369   mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1370                                * sizeof (bfd_mach_o_load_command));
1371   if (mdata->commands == NULL)
1372     return FALSE;
1373   cmd = &mdata->commands[0];
1374   seg = &cmd->command.segment;
1375
1376   seg->nsects = bfd_count_sections (abfd);
1377
1378   /* Set segment command.  */
1379   if (wide)
1380     {
1381       cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1382       cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1383       cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1384         + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1385     }
1386   else
1387     {
1388       cmd->type = BFD_MACH_O_LC_SEGMENT;
1389       cmd->offset = BFD_MACH_O_HEADER_SIZE;
1390       cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1391         + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1392     }
1393   cmd->type_required = FALSE;
1394   mdata->header.sizeofcmds = cmd->len;
1395   mdata->filelen = cmd->offset + cmd->len;
1396
1397   /* Set symtab command.  */
1398   symtab_cmd = &mdata->commands[1];
1399   
1400   symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1401   symtab_cmd->offset = cmd->offset + cmd->len;
1402   symtab_cmd->len = 6 * 4;
1403   symtab_cmd->type_required = FALSE;
1404   
1405   mdata->header.sizeofcmds += symtab_cmd->len;
1406   mdata->filelen += symtab_cmd->len;
1407
1408   /* Fill segment command.  */
1409   memset (seg->segname, 0, sizeof (seg->segname));
1410   seg->vmaddr = 0;
1411   seg->fileoff = mdata->filelen;
1412   seg->filesize = 0;
1413   seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1414     | BFD_MACH_O_PROT_EXECUTE;
1415   seg->initprot = seg->maxprot;
1416   seg->flags = 0;
1417   seg->sect_head = NULL;
1418   seg->sect_tail = NULL;
1419
1420   /* Create Mach-O sections.  */
1421   target_index = 0;
1422   for (sec = abfd->sections; sec; sec = sec->next)
1423     {
1424       bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
1425
1426       bfd_mach_o_append_section_to_segment (seg, sec);
1427
1428       if (msect->flags == 0)
1429         {
1430           /* We suppose it hasn't been set.  Convert from BFD flags.  */
1431           bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
1432         }
1433       msect->addr = bfd_get_section_vma (abfd, sec);
1434       msect->size = bfd_get_section_size (sec);
1435       msect->align = bfd_get_section_alignment (abfd, sec);
1436
1437       if (msect->size != 0)
1438         {
1439           mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
1440           msect->offset = mdata->filelen;
1441         }
1442       else
1443         msect->offset = 0;
1444
1445       sec->filepos = msect->offset;
1446       sec->target_index = ++target_index;
1447
1448       mdata->filelen += msect->size;
1449     }
1450   seg->filesize = mdata->filelen - seg->fileoff;
1451   seg->vmsize = seg->filesize;
1452
1453   return TRUE;
1454 }
1455
1456 /* Set the contents of a section.  */
1457
1458 bfd_boolean
1459 bfd_mach_o_set_section_contents (bfd *abfd,
1460                                  asection *section,
1461                                  const void * location,
1462                                  file_ptr offset,
1463                                  bfd_size_type count)
1464 {
1465   file_ptr pos;
1466
1467   /* This must be done first, because bfd_set_section_contents is
1468      going to set output_has_begun to TRUE.  */
1469   if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1470     return FALSE;
1471
1472   if (count == 0)
1473     return TRUE;
1474
1475   pos = section->filepos + offset;
1476   if (bfd_seek (abfd, pos, SEEK_SET) != 0
1477       || bfd_bwrite (location, count, abfd) != count)
1478     return FALSE;
1479
1480   return TRUE;
1481 }
1482
1483 int
1484 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1485                            struct bfd_link_info *info ATTRIBUTE_UNUSED)
1486 {
1487   return 0;
1488 }
1489
1490 /* Make an empty symbol.  This is required only because
1491    bfd_make_section_anyway wants to create a symbol for the section.  */
1492
1493 asymbol *
1494 bfd_mach_o_make_empty_symbol (bfd *abfd)
1495 {
1496   asymbol *new_symbol;
1497
1498   new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1499   if (new_symbol == NULL)
1500     return new_symbol;
1501   new_symbol->the_bfd = abfd;
1502   new_symbol->udata.i = 0;
1503   return new_symbol;
1504 }
1505
1506 static bfd_boolean
1507 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1508 {
1509   struct mach_o_header_external raw;
1510   unsigned int size;
1511   bfd_vma (*get32) (const void *) = NULL;
1512
1513   /* Just read the magic number.  */
1514   if (bfd_seek (abfd, 0, SEEK_SET) != 0
1515       || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
1516     return FALSE;
1517
1518   if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
1519     {
1520       header->byteorder = BFD_ENDIAN_BIG;
1521       header->magic = BFD_MACH_O_MH_MAGIC;
1522       header->version = 1;
1523       get32 = bfd_getb32;
1524     }
1525   else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
1526     {
1527       header->byteorder = BFD_ENDIAN_LITTLE;
1528       header->magic = BFD_MACH_O_MH_MAGIC;
1529       header->version = 1;
1530       get32 = bfd_getl32;
1531     }
1532   else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1533     {
1534       header->byteorder = BFD_ENDIAN_BIG;
1535       header->magic = BFD_MACH_O_MH_MAGIC_64;
1536       header->version = 2;
1537       get32 = bfd_getb32;
1538     }
1539   else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1540     {
1541       header->byteorder = BFD_ENDIAN_LITTLE;
1542       header->magic = BFD_MACH_O_MH_MAGIC_64;
1543       header->version = 2;
1544       get32 = bfd_getl32;
1545     }
1546   else
1547     {
1548       header->byteorder = BFD_ENDIAN_UNKNOWN;
1549       return FALSE;
1550     }
1551
1552   /* Once the size of the header is known, read the full header.  */
1553   size = mach_o_wide_p (header) ?
1554     BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1555
1556   if (bfd_seek (abfd, 0, SEEK_SET) != 0
1557       || bfd_bread (&raw, size, abfd) != size)
1558     return FALSE;
1559
1560   header->cputype = (*get32) (raw.cputype);
1561   header->cpusubtype = (*get32) (raw.cpusubtype);
1562   header->filetype = (*get32) (raw.filetype);
1563   header->ncmds = (*get32) (raw.ncmds);
1564   header->sizeofcmds = (*get32) (raw.sizeofcmds);
1565   header->flags = (*get32) (raw.flags);
1566
1567   if (mach_o_wide_p (header))
1568     header->reserved = (*get32) (raw.reserved);
1569
1570   return TRUE;
1571 }
1572
1573 bfd_boolean
1574 bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
1575 {
1576   bfd_mach_o_section *s;
1577
1578   s = bfd_mach_o_get_mach_o_section (sec);
1579   if (s == NULL)
1580     {
1581       flagword bfd_flags;
1582
1583       s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
1584       if (s == NULL)
1585         return FALSE;
1586       sec->used_by_bfd = s;
1587       s->bfdsection = sec;
1588
1589       /* Create default name.  */
1590       bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
1591
1592       /* Create default flags.  */
1593       bfd_flags = bfd_get_section_flags (abfd, sec);
1594       if ((bfd_flags & SEC_CODE) == SEC_CODE)
1595         s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1596           | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1597           | BFD_MACH_O_S_REGULAR;
1598       else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1599         s->flags = BFD_MACH_O_S_ZEROFILL;
1600       else if (bfd_flags & SEC_DEBUGGING)
1601         s->flags = BFD_MACH_O_S_REGULAR |  BFD_MACH_O_S_ATTR_DEBUG;
1602       else
1603         s->flags = BFD_MACH_O_S_REGULAR;
1604     }
1605
1606   return _bfd_generic_new_section_hook (abfd, sec);
1607 }
1608
1609 static void
1610 bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
1611                                      unsigned long prot)
1612 {
1613   flagword flags;
1614   bfd_mach_o_section *section;
1615
1616   flags = bfd_get_section_flags (abfd, sec);
1617   section = bfd_mach_o_get_mach_o_section (sec);
1618
1619   if (flags == SEC_NO_FLAGS)
1620     {
1621       /* Try to guess flags.  */
1622       if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1623         flags = SEC_DEBUGGING;
1624       else
1625         {
1626           flags = SEC_ALLOC;
1627           if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1628               != BFD_MACH_O_S_ZEROFILL)
1629             {
1630               flags |= SEC_LOAD;
1631               if (prot & BFD_MACH_O_PROT_EXECUTE)
1632                 flags |= SEC_CODE;
1633               if (prot & BFD_MACH_O_PROT_WRITE)
1634                 flags |= SEC_DATA;
1635               else if (prot & BFD_MACH_O_PROT_READ)
1636                 flags |= SEC_READONLY;
1637             }
1638         }
1639     }
1640   else
1641     {
1642       if ((flags & SEC_DEBUGGING) == 0)
1643         flags |= SEC_ALLOC;
1644     }
1645
1646   if (section->offset != 0)
1647     flags |= SEC_HAS_CONTENTS;
1648   if (section->nreloc != 0)
1649     flags |= SEC_RELOC;
1650
1651   bfd_set_section_flags (abfd, sec, flags);
1652
1653   sec->vma = section->addr;
1654   sec->lma = section->addr;
1655   sec->size = section->size;
1656   sec->filepos = section->offset;
1657   sec->alignment_power = section->align;
1658   sec->segment_mark = 0;
1659   sec->reloc_count = section->nreloc;
1660   sec->rel_filepos = section->reloff;
1661 }
1662
1663 static asection *
1664 bfd_mach_o_make_bfd_section (bfd *abfd,
1665                              const unsigned char *segname,
1666                              const unsigned char *sectname)
1667 {
1668   const char *sname;
1669   flagword flags;
1670
1671   bfd_mach_o_convert_section_name_to_bfd
1672     (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
1673   if (sname == NULL)
1674     return NULL;
1675
1676   return bfd_make_section_anyway_with_flags (abfd, sname, flags);
1677 }
1678
1679 static asection *
1680 bfd_mach_o_read_section_32 (bfd *abfd,
1681                             unsigned int offset,
1682                             unsigned long prot)
1683 {
1684   struct mach_o_section_32_external raw;
1685   asection *sec;
1686   bfd_mach_o_section *section;
1687
1688   if (bfd_seek (abfd, offset, SEEK_SET) != 0
1689       || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
1690           != BFD_MACH_O_SECTION_SIZE))
1691     return NULL;
1692
1693   sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
1694   if (sec == NULL)
1695     return NULL;
1696
1697   section = bfd_mach_o_get_mach_o_section (sec);
1698   memcpy (section->segname, raw.segname, sizeof (raw.segname));
1699   section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1700   memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
1701   section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
1702   section->addr = bfd_h_get_32 (abfd, raw.addr);
1703   section->size = bfd_h_get_32 (abfd, raw.size);
1704   section->offset = bfd_h_get_32 (abfd, raw.offset);
1705   section->align = bfd_h_get_32 (abfd, raw.align);
1706   section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1707   section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1708   section->flags = bfd_h_get_32 (abfd, raw.flags);
1709   section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1710   section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1711   section->reserved3 = 0;
1712
1713   bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1714
1715   return sec;
1716 }
1717
1718 static asection *
1719 bfd_mach_o_read_section_64 (bfd *abfd,
1720                             unsigned int offset,
1721                             unsigned long prot)
1722 {
1723   struct mach_o_section_64_external raw;
1724   asection *sec;
1725   bfd_mach_o_section *section;
1726
1727   if (bfd_seek (abfd, offset, SEEK_SET) != 0
1728       || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
1729           != BFD_MACH_O_SECTION_64_SIZE))
1730     return NULL;
1731
1732   sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
1733   if (sec == NULL)
1734     return NULL;
1735
1736   section = bfd_mach_o_get_mach_o_section (sec);
1737   memcpy (section->segname, raw.segname, sizeof (raw.segname));
1738   section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1739   memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
1740   section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
1741   section->addr = bfd_h_get_64 (abfd, raw.addr);
1742   section->size = bfd_h_get_64 (abfd, raw.size);
1743   section->offset = bfd_h_get_32 (abfd, raw.offset);
1744   section->align = bfd_h_get_32 (abfd, raw.align);
1745   section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1746   section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1747   section->flags = bfd_h_get_32 (abfd, raw.flags);
1748   section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1749   section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1750   section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
1751
1752   bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1753
1754   return sec;
1755 }
1756
1757 static asection *
1758 bfd_mach_o_read_section (bfd *abfd,
1759                          unsigned int offset,
1760                          unsigned long prot,
1761                          unsigned int wide)
1762 {
1763   if (wide)
1764     return bfd_mach_o_read_section_64 (abfd, offset, prot);
1765   else
1766     return bfd_mach_o_read_section_32 (abfd, offset, prot);
1767 }
1768
1769 static bfd_boolean
1770 bfd_mach_o_read_symtab_symbol (bfd *abfd,
1771                                bfd_mach_o_symtab_command *sym,
1772                                bfd_mach_o_asymbol *s,
1773                                unsigned long i)
1774 {
1775   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1776   unsigned int wide = mach_o_wide_p (&mdata->header);
1777   unsigned int symwidth =
1778     wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1779   unsigned int symoff = sym->symoff + (i * symwidth);
1780   struct mach_o_nlist_64_external raw;
1781   unsigned char type = -1;
1782   unsigned char section = -1;
1783   short desc = -1;
1784   symvalue value = -1;
1785   unsigned long stroff = -1;
1786   unsigned int symtype = -1;
1787
1788   BFD_ASSERT (sym->strtab != NULL);
1789
1790   if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1791       || bfd_bread (&raw, symwidth, abfd) != symwidth)
1792     {
1793       (*_bfd_error_handler)
1794         (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
1795          symwidth, (unsigned long) symoff);
1796       return FALSE;
1797     }
1798
1799   stroff = bfd_h_get_32 (abfd, raw.n_strx);
1800   type = bfd_h_get_8 (abfd, raw.n_type);
1801   symtype = type & BFD_MACH_O_N_TYPE;
1802   section = bfd_h_get_8 (abfd, raw.n_sect);
1803   desc = bfd_h_get_16 (abfd, raw.n_desc);
1804   if (wide)
1805     value = bfd_h_get_64 (abfd, raw.n_value);
1806   else
1807     value = bfd_h_get_32 (abfd, raw.n_value);
1808
1809   if (stroff >= sym->strsize)
1810     {
1811       (*_bfd_error_handler)
1812         (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
1813          (unsigned long) stroff,
1814          (unsigned long) sym->strsize);
1815       return FALSE;
1816     }
1817
1818   s->symbol.the_bfd = abfd;
1819   s->symbol.name = sym->strtab + stroff;
1820   s->symbol.value = value;
1821   s->symbol.flags = 0x0;
1822   s->symbol.udata.i = 0;
1823   s->n_type = type;
1824   s->n_sect = section;
1825   s->n_desc = desc;
1826
1827   if (type & BFD_MACH_O_N_STAB)
1828     {
1829       s->symbol.flags |= BSF_DEBUGGING;
1830       s->symbol.section = bfd_und_section_ptr;
1831       switch (type)
1832         {
1833         case N_FUN:
1834         case N_STSYM:
1835         case N_LCSYM:
1836         case N_BNSYM:
1837         case N_SLINE:
1838         case N_ENSYM:
1839         case N_ECOMM:
1840         case N_ECOML:
1841         case N_GSYM:
1842           if ((section > 0) && (section <= mdata->nsects))
1843             {
1844               s->symbol.section = mdata->sections[section - 1]->bfdsection;
1845               s->symbol.value =
1846                 s->symbol.value - mdata->sections[section - 1]->addr;
1847             }
1848           break;
1849         }
1850     }
1851   else
1852     {
1853       if (type & BFD_MACH_O_N_PEXT)
1854         s->symbol.flags |= BSF_GLOBAL;
1855
1856       if (type & BFD_MACH_O_N_EXT)
1857         s->symbol.flags |= BSF_GLOBAL;
1858
1859       if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1860         s->symbol.flags |= BSF_LOCAL;
1861
1862       switch (symtype)
1863         {
1864         case BFD_MACH_O_N_UNDF:
1865           if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1866               && s->symbol.value != 0)
1867             {
1868               /* A common symbol.  */
1869               s->symbol.section = bfd_com_section_ptr;
1870               s->symbol.flags = BSF_NO_FLAGS;
1871             }
1872           else
1873             {
1874               s->symbol.section = bfd_und_section_ptr;
1875               if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1876                 s->symbol.flags |= BSF_WEAK;
1877             }
1878           break;
1879         case BFD_MACH_O_N_PBUD:
1880           s->symbol.section = bfd_und_section_ptr;
1881           break;
1882         case BFD_MACH_O_N_ABS:
1883           s->symbol.section = bfd_abs_section_ptr;
1884           break;
1885         case BFD_MACH_O_N_SECT:
1886           if ((section > 0) && (section <= mdata->nsects))
1887             {
1888               s->symbol.section = mdata->sections[section - 1]->bfdsection;
1889               s->symbol.value =
1890                 s->symbol.value - mdata->sections[section - 1]->addr;
1891             }
1892           else
1893             {
1894               /* Mach-O uses 0 to mean "no section"; not an error.  */
1895               if (section != 0)
1896                 {
1897                   (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1898                                            "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
1899                                          s->symbol.name, section, mdata->nsects);
1900                 }
1901               s->symbol.section = bfd_und_section_ptr;
1902             }
1903           break;
1904         case BFD_MACH_O_N_INDR:
1905           /* FIXME: we don't follow the BFD convention as this indirect symbol
1906              won't be followed by the referenced one.  This looks harmless
1907              unless we start using the linker.  */
1908           s->symbol.flags |= BSF_INDIRECT;
1909           s->symbol.section = bfd_ind_section_ptr;
1910           s->symbol.value = 0;
1911           break;
1912         default:
1913           (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1914                                    "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
1915                                  s->symbol.name, symtype);
1916           s->symbol.section = bfd_und_section_ptr;
1917           break;
1918         }
1919     }
1920
1921   return TRUE;
1922 }
1923
1924 static bfd_boolean
1925 bfd_mach_o_read_symtab_strtab (bfd *abfd)
1926 {
1927   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1928   bfd_mach_o_symtab_command *sym = mdata->symtab;
1929
1930   /* Fail if there is no symtab.  */
1931   if (sym == NULL)
1932     return FALSE;
1933
1934   /* Success if already loaded.  */
1935   if (sym->strtab)
1936     return TRUE;
1937
1938   if (abfd->flags & BFD_IN_MEMORY)
1939     {
1940       struct bfd_in_memory *b;
1941
1942       b = (struct bfd_in_memory *) abfd->iostream;
1943
1944       if ((sym->stroff + sym->strsize) > b->size)
1945         {
1946           bfd_set_error (bfd_error_file_truncated);
1947           return FALSE;
1948         }
1949       sym->strtab = (char *) b->buffer + sym->stroff;
1950     }
1951   else
1952     {
1953       sym->strtab = bfd_alloc (abfd, sym->strsize);
1954       if (sym->strtab == NULL)
1955         return FALSE;
1956
1957       if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1958           || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
1959         {
1960           bfd_set_error (bfd_error_file_truncated);
1961           return FALSE;
1962         }
1963     }
1964
1965   return TRUE;
1966 }
1967
1968 static bfd_boolean
1969 bfd_mach_o_read_symtab_symbols (bfd *abfd)
1970 {
1971   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1972   bfd_mach_o_symtab_command *sym = mdata->symtab;
1973   unsigned long i;
1974
1975   if (sym == NULL || sym->symbols)
1976     {
1977       /* Return now if there are no symbols or if already loaded.  */
1978       return TRUE;
1979     }
1980
1981   sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1982
1983   if (sym->symbols == NULL)
1984     {
1985       (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
1986       return FALSE;
1987     }
1988
1989   if (!bfd_mach_o_read_symtab_strtab (abfd))
1990     return FALSE;
1991
1992   for (i = 0; i < sym->nsyms; i++)
1993     {
1994       if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
1995         return FALSE;
1996     }
1997
1998   return TRUE;
1999 }
2000
2001 static const char *
2002 bfd_mach_o_i386_flavour_string (unsigned int flavour)
2003 {
2004   switch ((int) flavour)
2005     {
2006     case BFD_MACH_O_x86_THREAD_STATE32:    return "x86_THREAD_STATE32";
2007     case BFD_MACH_O_x86_FLOAT_STATE32:     return "x86_FLOAT_STATE32";
2008     case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
2009     case BFD_MACH_O_x86_THREAD_STATE64:    return "x86_THREAD_STATE64";
2010     case BFD_MACH_O_x86_FLOAT_STATE64:     return "x86_FLOAT_STATE64";
2011     case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
2012     case BFD_MACH_O_x86_THREAD_STATE:      return "x86_THREAD_STATE";
2013     case BFD_MACH_O_x86_FLOAT_STATE:       return "x86_FLOAT_STATE";
2014     case BFD_MACH_O_x86_EXCEPTION_STATE:   return "x86_EXCEPTION_STATE";
2015     case BFD_MACH_O_x86_DEBUG_STATE32:     return "x86_DEBUG_STATE32";
2016     case BFD_MACH_O_x86_DEBUG_STATE64:     return "x86_DEBUG_STATE64";
2017     case BFD_MACH_O_x86_DEBUG_STATE:       return "x86_DEBUG_STATE";
2018     case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
2019     default: return "UNKNOWN";
2020     }
2021 }
2022
2023 static const char *
2024 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
2025 {
2026   switch ((int) flavour)
2027     {
2028     case BFD_MACH_O_PPC_THREAD_STATE:      return "PPC_THREAD_STATE";
2029     case BFD_MACH_O_PPC_FLOAT_STATE:       return "PPC_FLOAT_STATE";
2030     case BFD_MACH_O_PPC_EXCEPTION_STATE:   return "PPC_EXCEPTION_STATE";
2031     case BFD_MACH_O_PPC_VECTOR_STATE:      return "PPC_VECTOR_STATE";
2032     case BFD_MACH_O_PPC_THREAD_STATE64:    return "PPC_THREAD_STATE64";
2033     case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
2034     default: return "UNKNOWN";
2035     }
2036 }
2037
2038 static int
2039 bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
2040 {
2041   bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
2042   struct mach_o_str_command_external raw;
2043   unsigned int nameoff;
2044
2045   BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
2046               || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
2047
2048   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2049       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2050     return -1;
2051
2052   nameoff = bfd_h_get_32 (abfd, raw.str);
2053
2054   cmd->name_offset = command->offset + nameoff;
2055   cmd->name_len = command->len - nameoff;
2056   cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2057   if (cmd->name_str == NULL)
2058     return -1;
2059   if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2060       || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
2061     return -1;
2062   return 0;
2063 }
2064
2065 static int
2066 bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
2067 {
2068   bfd_mach_o_dylib_command *cmd = &command->command.dylib;
2069   struct mach_o_dylib_command_external raw;
2070   unsigned int nameoff;
2071
2072   switch (command->type)
2073     {
2074     case BFD_MACH_O_LC_LOAD_DYLIB:
2075     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2076     case BFD_MACH_O_LC_ID_DYLIB:
2077     case BFD_MACH_O_LC_REEXPORT_DYLIB:
2078     case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
2079       break;
2080     default:
2081       BFD_FAIL ();
2082       return -1;
2083     }
2084
2085   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2086       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2087     return -1;
2088
2089   nameoff = bfd_h_get_32 (abfd, raw.name);
2090   cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
2091   cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
2092   cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
2093
2094   cmd->name_offset = command->offset + nameoff;
2095   cmd->name_len = command->len - nameoff;
2096   cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2097   if (cmd->name_str == NULL)
2098     return -1;
2099   if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2100       || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
2101     return -1;
2102   return 0;
2103 }
2104
2105 static int
2106 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
2107                                 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
2108 {
2109   /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
2110
2111   BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
2112   return 0;
2113 }
2114
2115 static int
2116 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
2117 {
2118   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2119   bfd_mach_o_thread_command *cmd = &command->command.thread;
2120   unsigned int offset;
2121   unsigned int nflavours;
2122   unsigned int i;
2123
2124   BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2125               || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2126
2127   /* Count the number of threads.  */
2128   offset = 8;
2129   nflavours = 0;
2130   while (offset != command->len)
2131     {
2132       struct mach_o_thread_command_external raw;
2133
2134       if (offset >= command->len)
2135         return -1;
2136
2137       if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2138           || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2139         return -1;
2140
2141       offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
2142       nflavours++;
2143     }
2144
2145   /* Allocate threads.  */
2146   cmd->flavours = bfd_alloc
2147     (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
2148   if (cmd->flavours == NULL)
2149     return -1;
2150   cmd->nflavours = nflavours;
2151
2152   offset = 8;
2153   nflavours = 0;
2154   while (offset != command->len)
2155     {
2156       struct mach_o_thread_command_external raw;
2157
2158       if (offset >= command->len)
2159         return -1;
2160
2161       if (nflavours >= cmd->nflavours)
2162         return -1;
2163
2164       if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2165           || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2166         return -1;
2167
2168       cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
2169       cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
2170       cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
2171       offset += cmd->flavours[nflavours].size + sizeof (raw);
2172       nflavours++;
2173     }
2174
2175   for (i = 0; i < nflavours; i++)
2176     {
2177       asection *bfdsec;
2178       unsigned int snamelen;
2179       char *sname;
2180       const char *flavourstr;
2181       const char *prefix = "LC_THREAD";
2182       unsigned int j = 0;
2183
2184       switch (mdata->header.cputype)
2185         {
2186         case BFD_MACH_O_CPU_TYPE_POWERPC:
2187         case BFD_MACH_O_CPU_TYPE_POWERPC_64:
2188           flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2189           break;
2190         case BFD_MACH_O_CPU_TYPE_I386:
2191         case BFD_MACH_O_CPU_TYPE_X86_64:
2192           flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2193           break;
2194         default:
2195           flavourstr = "UNKNOWN_ARCHITECTURE";
2196           break;
2197         }
2198
2199       snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
2200       sname = bfd_alloc (abfd, snamelen);
2201       if (sname == NULL)
2202         return -1;
2203
2204       for (;;)
2205         {
2206           sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2207           if (bfd_get_section_by_name (abfd, sname) == NULL)
2208             break;
2209           j++;
2210         }
2211
2212       bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
2213
2214       bfdsec->vma = 0;
2215       bfdsec->lma = 0;
2216       bfdsec->size = cmd->flavours[i].size;
2217       bfdsec->filepos = cmd->flavours[i].offset;
2218       bfdsec->alignment_power = 0x0;
2219
2220       cmd->section = bfdsec;
2221     }
2222
2223   return 0;
2224 }
2225
2226 static int
2227 bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2228 {
2229   bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2230   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2231
2232   BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2233
2234   {
2235     struct mach_o_dysymtab_command_external raw;
2236
2237     if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2238         || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2239       return -1;
2240
2241     cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
2242     cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
2243     cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
2244     cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
2245     cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
2246     cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
2247     cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
2248     cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
2249     cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
2250     cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
2251     cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
2252     cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
2253     cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
2254     cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
2255     cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
2256     cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
2257     cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
2258     cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
2259   }
2260
2261   if (cmd->nmodtab != 0)
2262     {
2263       unsigned int i;
2264       int wide = bfd_mach_o_wide_p (abfd);
2265       unsigned int module_len = wide ? 56 : 52;
2266
2267       cmd->dylib_module =
2268         bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2269       if (cmd->dylib_module == NULL)
2270         return -1;
2271
2272       if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2273         return -1;
2274
2275       for (i = 0; i < cmd->nmodtab; i++)
2276         {
2277           bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2278           unsigned long v;
2279           unsigned char buf[56];
2280
2281           if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
2282             return -1;
2283
2284           module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2285           module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2286           module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2287           module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2288           module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2289           module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2290           module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2291           module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2292           module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2293           v = bfd_h_get_32 (abfd, buf +36);
2294           module->iinit = v & 0xffff;
2295           module->iterm = (v >> 16) & 0xffff;
2296           v = bfd_h_get_32 (abfd, buf + 40);
2297           module->ninit = v & 0xffff;
2298           module->nterm = (v >> 16) & 0xffff;
2299           if (wide)
2300             {
2301               module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2302               module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2303             }
2304           else
2305             {
2306               module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2307               module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2308             }
2309         }
2310     }
2311
2312   if (cmd->ntoc != 0)
2313     {
2314       unsigned int i;
2315
2316       cmd->dylib_toc = bfd_alloc
2317         (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2318       if (cmd->dylib_toc == NULL)
2319         return -1;
2320
2321       if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2322         return -1;
2323
2324       for (i = 0; i < cmd->ntoc; i++)
2325         {
2326           struct mach_o_dylib_table_of_contents_external raw;
2327           bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2328
2329           if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2330             return -1;
2331
2332           toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
2333           toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
2334         }
2335     }
2336
2337   if (cmd->nindirectsyms != 0)
2338     {
2339       unsigned int i;
2340
2341       cmd->indirect_syms = bfd_alloc
2342         (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2343       if (cmd->indirect_syms == NULL)
2344         return -1;
2345
2346       if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2347         return -1;
2348
2349       for (i = 0; i < cmd->nindirectsyms; i++)
2350         {
2351           unsigned char raw[4];
2352           unsigned int *is = &cmd->indirect_syms[i];
2353
2354           if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
2355             return -1;
2356
2357           *is = bfd_h_get_32 (abfd, raw);
2358         }
2359     }
2360
2361   if (cmd->nextrefsyms != 0)
2362     {
2363       unsigned long v;
2364       unsigned int i;
2365
2366       cmd->ext_refs = bfd_alloc
2367         (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2368       if (cmd->ext_refs == NULL)
2369         return -1;
2370
2371       if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2372         return -1;
2373
2374       for (i = 0; i < cmd->nextrefsyms; i++)
2375         {
2376           unsigned char raw[4];
2377           bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2378
2379           if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
2380             return -1;
2381
2382           /* Fields isym and flags are written as bit-fields, thus we need
2383              a specific processing for endianness.  */
2384           v = bfd_h_get_32 (abfd, raw);
2385           if (bfd_big_endian (abfd))
2386             {
2387               ref->isym = (v >> 8) & 0xffffff;
2388               ref->flags = v & 0xff;
2389             }
2390           else
2391             {
2392               ref->isym = v & 0xffffff;
2393               ref->flags = (v >> 24) & 0xff;
2394             }
2395         }
2396     }
2397
2398   if (mdata->dysymtab)
2399     return -1;
2400   mdata->dysymtab = cmd;
2401
2402   return 0;
2403 }
2404
2405 static int
2406 bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
2407 {
2408   bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2409   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2410   struct mach_o_symtab_command_external raw;
2411
2412   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2413
2414   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2415       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2416     return -1;
2417
2418   symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
2419   symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
2420   symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
2421   symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
2422   symtab->symbols = NULL;
2423   symtab->strtab = NULL;
2424
2425   if (symtab->nsyms != 0)
2426     abfd->flags |= HAS_SYMS;
2427
2428   if (mdata->symtab)
2429     return -1;
2430   mdata->symtab = symtab;
2431   return 0;
2432 }
2433
2434 static int
2435 bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
2436 {
2437   bfd_mach_o_uuid_command *cmd = &command->command.uuid;
2438
2439   BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2440
2441   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2442       || bfd_bread (cmd->uuid, 16, abfd) != 16)
2443     return -1;
2444
2445   return 0;
2446 }
2447
2448 static int
2449 bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
2450 {
2451   bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
2452   struct mach_o_linkedit_data_command_external raw;
2453
2454   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2455       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2456     return -1;
2457
2458   cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
2459   cmd->datasize = bfd_get_32 (abfd, raw.datasize);
2460   return 0;
2461 }
2462
2463 static int
2464 bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
2465 {
2466   bfd_mach_o_str_command *cmd = &command->command.str;
2467   struct mach_o_str_command_external raw;
2468   unsigned long off;
2469
2470   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2471       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2472     return -1;
2473
2474   off = bfd_get_32 (abfd, raw.str);
2475   cmd->stroff = command->offset + off;
2476   cmd->str_len = command->len - off;
2477   cmd->str = bfd_alloc (abfd, cmd->str_len);
2478   if (cmd->str == NULL)
2479     return -1;
2480   if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
2481       || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
2482     return -1;
2483   return 0;
2484 }
2485
2486 static int
2487 bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
2488 {
2489   bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
2490   struct mach_o_dyld_info_command_external raw;
2491
2492   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2493       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2494     return -1;
2495
2496   cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
2497   cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
2498   cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
2499   cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
2500   cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
2501   cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
2502   cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
2503   cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
2504   cmd->export_off = bfd_get_32 (abfd, raw.export_off);
2505   cmd->export_size = bfd_get_32 (abfd, raw.export_size);
2506   return 0;
2507 }
2508
2509 static bfd_boolean
2510 bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
2511 {
2512   bfd_mach_o_version_min_command *cmd = &command->command.version_min;
2513   struct mach_o_version_min_command_external raw;
2514   unsigned int ver;
2515
2516   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2517       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2518     return FALSE;
2519
2520   ver = bfd_get_32 (abfd, raw.version);
2521   cmd->rel = ver >> 16;
2522   cmd->maj = ver >> 8;
2523   cmd->min = ver;
2524   cmd->reserved = bfd_get_32 (abfd, raw.reserved);
2525   return TRUE;
2526 }
2527
2528 static int
2529 bfd_mach_o_read_segment (bfd *abfd,
2530                          bfd_mach_o_load_command *command,
2531                          unsigned int wide)
2532 {
2533   bfd_mach_o_segment_command *seg = &command->command.segment;
2534   unsigned long i;
2535
2536   if (wide)
2537     {
2538       struct mach_o_segment_command_64_external raw;
2539
2540       BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2541
2542       if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2543           || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2544         return -1;
2545
2546       memcpy (seg->segname, raw.segname, 16);
2547       seg->segname[16] = '\0';
2548
2549       seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
2550       seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
2551       seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
2552       seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
2553       seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2554       seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2555       seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2556       seg->flags = bfd_h_get_32 (abfd, raw.flags);
2557     }
2558   else
2559     {
2560       struct mach_o_segment_command_32_external raw;
2561
2562       BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2563
2564       if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2565           || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2566         return -1;
2567
2568       memcpy (seg->segname, raw.segname, 16);
2569       seg->segname[16] = '\0';
2570
2571       seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
2572       seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
2573       seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
2574       seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
2575       seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2576       seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2577       seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2578       seg->flags = bfd_h_get_32 (abfd, raw.flags);
2579     }
2580   seg->sect_head = NULL;
2581   seg->sect_tail = NULL;
2582
2583   for (i = 0; i < seg->nsects; i++)
2584     {
2585       bfd_vma segoff;
2586       asection *sec;
2587
2588       if (wide)
2589         segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2590           + (i * BFD_MACH_O_SECTION_64_SIZE);
2591       else
2592         segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2593           + (i * BFD_MACH_O_SECTION_SIZE);
2594
2595       sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
2596       if (sec == NULL)
2597         return -1;
2598
2599       bfd_mach_o_append_section_to_segment (seg, sec);
2600     }
2601
2602   return 0;
2603 }
2604
2605 static int
2606 bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2607 {
2608   return bfd_mach_o_read_segment (abfd, command, 0);
2609 }
2610
2611 static int
2612 bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2613 {
2614   return bfd_mach_o_read_segment (abfd, command, 1);
2615 }
2616
2617 static int
2618 bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2619 {
2620   struct mach_o_load_command_external raw;
2621   unsigned int cmd;
2622
2623   /* Read command type and length.  */
2624   if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2625       || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
2626     return -1;
2627
2628   cmd = bfd_h_get_32 (abfd, raw.cmd);
2629   command->type =  cmd & ~BFD_MACH_O_LC_REQ_DYLD;
2630   command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
2631   command->len = bfd_h_get_32 (abfd, raw.cmdsize);
2632
2633   switch (command->type)
2634     {
2635     case BFD_MACH_O_LC_SEGMENT:
2636       if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
2637         return -1;
2638       break;
2639     case BFD_MACH_O_LC_SEGMENT_64:
2640       if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
2641         return -1;
2642       break;
2643     case BFD_MACH_O_LC_SYMTAB:
2644       if (bfd_mach_o_read_symtab (abfd, command) != 0)
2645         return -1;
2646       break;
2647     case BFD_MACH_O_LC_SYMSEG:
2648       break;
2649     case BFD_MACH_O_LC_THREAD:
2650     case BFD_MACH_O_LC_UNIXTHREAD:
2651       if (bfd_mach_o_read_thread (abfd, command) != 0)
2652         return -1;
2653       break;
2654     case BFD_MACH_O_LC_LOAD_DYLINKER:
2655     case BFD_MACH_O_LC_ID_DYLINKER:
2656       if (bfd_mach_o_read_dylinker (abfd, command) != 0)
2657         return -1;
2658       break;
2659     case BFD_MACH_O_LC_LOAD_DYLIB:
2660     case BFD_MACH_O_LC_ID_DYLIB:
2661     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2662     case BFD_MACH_O_LC_REEXPORT_DYLIB:
2663     case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
2664       if (bfd_mach_o_read_dylib (abfd, command) != 0)
2665         return -1;
2666       break;
2667     case BFD_MACH_O_LC_PREBOUND_DYLIB:
2668       if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
2669         return -1;
2670       break;
2671     case BFD_MACH_O_LC_LOADFVMLIB:
2672     case BFD_MACH_O_LC_IDFVMLIB:
2673     case BFD_MACH_O_LC_IDENT:
2674     case BFD_MACH_O_LC_FVMFILE:
2675     case BFD_MACH_O_LC_PREPAGE:
2676     case BFD_MACH_O_LC_ROUTINES:
2677     case BFD_MACH_O_LC_ROUTINES_64:
2678       break;
2679     case BFD_MACH_O_LC_SUB_FRAMEWORK:
2680     case BFD_MACH_O_LC_SUB_UMBRELLA:
2681     case BFD_MACH_O_LC_SUB_LIBRARY:
2682     case BFD_MACH_O_LC_SUB_CLIENT:
2683     case BFD_MACH_O_LC_RPATH:
2684       if (bfd_mach_o_read_str (abfd, command) != 0)
2685         return -1;
2686       break;
2687     case BFD_MACH_O_LC_DYSYMTAB:
2688       if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
2689         return -1;
2690       break;
2691     case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2692     case BFD_MACH_O_LC_PREBIND_CKSUM:
2693       break;
2694     case BFD_MACH_O_LC_UUID:
2695       if (bfd_mach_o_read_uuid (abfd, command) != 0)
2696         return -1;
2697       break;
2698     case BFD_MACH_O_LC_CODE_SIGNATURE:
2699     case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2700     case BFD_MACH_O_LC_FUNCTION_STARTS:
2701       if (bfd_mach_o_read_linkedit (abfd, command) != 0)
2702         return -1;
2703       break;
2704     case BFD_MACH_O_LC_DYLD_INFO:
2705       if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
2706         return -1;
2707       break;
2708     case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
2709     case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
2710       if (!bfd_mach_o_read_version_min (abfd, command))
2711         return -1;
2712       break;
2713     default:
2714       (*_bfd_error_handler)(_("%B: unable to read unknown load command 0x%lx"),
2715          abfd, (unsigned long) command->type);
2716       break;
2717     }
2718
2719   return 0;
2720 }
2721
2722 static void
2723 bfd_mach_o_flatten_sections (bfd *abfd)
2724 {
2725   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2726   long csect = 0;
2727   unsigned long i;
2728
2729   /* Count total number of sections.  */
2730   mdata->nsects = 0;
2731
2732   for (i = 0; i < mdata->header.ncmds; i++)
2733     {
2734       if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2735           || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2736         {
2737           bfd_mach_o_segment_command *seg;
2738
2739           seg = &mdata->commands[i].command.segment;
2740           mdata->nsects += seg->nsects;
2741         }
2742     }
2743
2744   /* Allocate sections array.  */
2745   mdata->sections = bfd_alloc (abfd,
2746                                mdata->nsects * sizeof (bfd_mach_o_section *));
2747
2748   /* Fill the array.  */
2749   csect = 0;
2750
2751   for (i = 0; i < mdata->header.ncmds; i++)
2752     {
2753       if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2754           || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2755         {
2756           bfd_mach_o_segment_command *seg;
2757           bfd_mach_o_section *sec;
2758
2759           seg = &mdata->commands[i].command.segment;
2760           BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2761
2762           for (sec = seg->sect_head; sec != NULL; sec = sec->next)
2763             mdata->sections[csect++] = sec;
2764         }
2765     }
2766 }
2767
2768 static bfd_boolean
2769 bfd_mach_o_scan_start_address (bfd *abfd)
2770 {
2771   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2772   bfd_mach_o_thread_command *cmd = NULL;
2773   unsigned long i;
2774
2775   for (i = 0; i < mdata->header.ncmds; i++)
2776     if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2777         (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2778       {
2779         cmd = &mdata->commands[i].command.thread;
2780         break;
2781       }
2782
2783   if (cmd == NULL)
2784     return FALSE;
2785
2786   /* FIXME: create a subtarget hook ?  */
2787   for (i = 0; i < cmd->nflavours; i++)
2788     {
2789       if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2790           && (cmd->flavours[i].flavour
2791               == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2792         {
2793           unsigned char buf[4];
2794
2795           if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2796               || bfd_bread (buf, 4, abfd) != 4)
2797             return FALSE;
2798
2799           abfd->start_address = bfd_h_get_32 (abfd, buf);
2800         }
2801       else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2802                && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2803         {
2804           unsigned char buf[4];
2805
2806           if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2807               || bfd_bread (buf, 4, abfd) != 4)
2808             return FALSE;
2809
2810           abfd->start_address = bfd_h_get_32 (abfd, buf);
2811         }
2812       else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2813                && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
2814         {
2815           unsigned char buf[8];
2816
2817           if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2818               || bfd_bread (buf, 8, abfd) != 8)
2819             return FALSE;
2820
2821           abfd->start_address = bfd_h_get_64 (abfd, buf);
2822         }
2823       else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2824                && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2825         {
2826           unsigned char buf[8];
2827
2828           if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2829               || bfd_bread (buf, 8, abfd) != 8)
2830             return FALSE;
2831
2832           abfd->start_address = bfd_h_get_64 (abfd, buf);
2833         }
2834     }
2835
2836   return TRUE;
2837 }
2838
2839 bfd_boolean
2840 bfd_mach_o_set_arch_mach (bfd *abfd,
2841                           enum bfd_architecture arch,
2842                           unsigned long machine)
2843 {
2844   bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
2845
2846   /* If this isn't the right architecture for this backend, and this
2847      isn't the generic backend, fail.  */
2848   if (arch != bed->arch
2849       && arch != bfd_arch_unknown
2850       && bed->arch != bfd_arch_unknown)
2851     return FALSE;
2852
2853   return bfd_default_set_arch_mach (abfd, arch, machine);
2854 }
2855
2856 static bfd_boolean
2857 bfd_mach_o_scan (bfd *abfd,
2858                  bfd_mach_o_header *header,
2859                  bfd_mach_o_data_struct *mdata)
2860 {
2861   unsigned int i;
2862   enum bfd_architecture cputype;
2863   unsigned long cpusubtype;
2864   unsigned int hdrsize;
2865
2866   hdrsize = mach_o_wide_p (header) ?
2867     BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2868
2869   mdata->header = *header;
2870
2871   abfd->flags = abfd->flags & BFD_IN_MEMORY;
2872   switch (header->filetype)
2873     {
2874     case BFD_MACH_O_MH_OBJECT:
2875       abfd->flags |= HAS_RELOC;
2876       break;
2877     case BFD_MACH_O_MH_EXECUTE:
2878       abfd->flags |= EXEC_P;
2879       break;
2880     case BFD_MACH_O_MH_DYLIB:
2881     case BFD_MACH_O_MH_BUNDLE:
2882       abfd->flags |= DYNAMIC;
2883       break;
2884     }
2885
2886   abfd->tdata.mach_o_data = mdata;
2887
2888   bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2889                                    &cputype, &cpusubtype);
2890   if (cputype == bfd_arch_unknown)
2891     {
2892       (*_bfd_error_handler)
2893         (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
2894          header->cputype, header->cpusubtype);
2895       return FALSE;
2896     }
2897
2898   bfd_set_arch_mach (abfd, cputype, cpusubtype);
2899
2900   if (header->ncmds != 0)
2901     {
2902       mdata->commands = bfd_alloc
2903         (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2904       if (mdata->commands == NULL)
2905         return FALSE;
2906
2907       for (i = 0; i < header->ncmds; i++)
2908         {
2909           bfd_mach_o_load_command *cur = &mdata->commands[i];
2910
2911           if (i == 0)
2912             cur->offset = hdrsize;
2913           else
2914             {
2915               bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2916               cur->offset = prev->offset + prev->len;
2917             }
2918
2919           if (bfd_mach_o_read_command (abfd, cur) < 0)
2920             return FALSE;
2921         }
2922     }
2923
2924   if (bfd_mach_o_scan_start_address (abfd) < 0)
2925     return FALSE;
2926
2927   bfd_mach_o_flatten_sections (abfd);
2928   return TRUE;
2929 }
2930
2931 bfd_boolean
2932 bfd_mach_o_mkobject_init (bfd *abfd)
2933 {
2934   bfd_mach_o_data_struct *mdata = NULL;
2935
2936   mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2937   if (mdata == NULL)
2938     return FALSE;
2939   abfd->tdata.mach_o_data = mdata;
2940
2941   mdata->header.magic = 0;
2942   mdata->header.cputype = 0;
2943   mdata->header.cpusubtype = 0;
2944   mdata->header.filetype = 0;
2945   mdata->header.ncmds = 0;
2946   mdata->header.sizeofcmds = 0;
2947   mdata->header.flags = 0;
2948   mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2949   mdata->commands = NULL;
2950   mdata->nsects = 0;
2951   mdata->sections = NULL;
2952
2953   return TRUE;
2954 }
2955
2956 static bfd_boolean
2957 bfd_mach_o_gen_mkobject (bfd *abfd)
2958 {
2959   bfd_mach_o_data_struct *mdata;
2960
2961   if (!bfd_mach_o_mkobject_init (abfd))
2962     return FALSE;
2963
2964   mdata = bfd_mach_o_get_data (abfd);
2965   mdata->header.magic = BFD_MACH_O_MH_MAGIC;
2966   mdata->header.cputype = 0;
2967   mdata->header.cpusubtype = 0;
2968   mdata->header.byteorder = abfd->xvec->byteorder;
2969   mdata->header.version = 1;
2970
2971   return TRUE;
2972 }
2973
2974 const bfd_target *
2975 bfd_mach_o_header_p (bfd *abfd,
2976                      bfd_mach_o_filetype filetype,
2977                      bfd_mach_o_cpu_type cputype)
2978 {
2979   struct bfd_preserve preserve;
2980   bfd_mach_o_header header;
2981
2982   preserve.marker = NULL;
2983   if (!bfd_mach_o_read_header (abfd, &header))
2984     goto wrong;
2985
2986   if (! (header.byteorder == BFD_ENDIAN_BIG
2987          || header.byteorder == BFD_ENDIAN_LITTLE))
2988     {
2989       (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
2990                              (unsigned long) header.byteorder);
2991       goto wrong;
2992     }
2993
2994   if (! ((header.byteorder == BFD_ENDIAN_BIG
2995           && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2996           && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2997          || (header.byteorder == BFD_ENDIAN_LITTLE
2998              && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2999              && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
3000     goto wrong;
3001
3002   /* Check cputype and filetype.
3003      In case of wildcard, do not accept magics that are handled by existing
3004      targets.  */
3005   if (cputype)
3006     {
3007       if (header.cputype != cputype)
3008         goto wrong;
3009     }
3010   else
3011     {
3012       switch (header.cputype)
3013         {
3014         case BFD_MACH_O_CPU_TYPE_I386:
3015           /* Handled by mach-o-i386 */
3016           goto wrong;
3017         default:
3018           break;
3019         }
3020     }
3021   if (filetype)
3022     {
3023       if (header.filetype != filetype)
3024         goto wrong;
3025     }
3026   else
3027     {
3028       switch (header.filetype)
3029         {
3030         case BFD_MACH_O_MH_CORE:
3031           /* Handled by core_p */
3032           goto wrong;
3033         default:
3034           break;
3035         }
3036     }
3037
3038   preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
3039   if (preserve.marker == NULL
3040       || !bfd_preserve_save (abfd, &preserve))
3041     goto fail;
3042
3043   if (!bfd_mach_o_scan (abfd, &header,
3044                         (bfd_mach_o_data_struct *) preserve.marker))
3045     goto wrong;
3046
3047   bfd_preserve_finish (abfd, &preserve);
3048   return abfd->xvec;
3049
3050  wrong:
3051   bfd_set_error (bfd_error_wrong_format);
3052
3053  fail:
3054   if (preserve.marker != NULL)
3055     bfd_preserve_restore (abfd, &preserve);
3056   return NULL;
3057 }
3058
3059 static const bfd_target *
3060 bfd_mach_o_gen_object_p (bfd *abfd)
3061 {
3062   return bfd_mach_o_header_p (abfd, 0, 0);
3063 }
3064
3065 static const bfd_target *
3066 bfd_mach_o_gen_core_p (bfd *abfd)
3067 {
3068   return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3069 }
3070
3071 typedef struct mach_o_fat_archentry
3072 {
3073   unsigned long cputype;
3074   unsigned long cpusubtype;
3075   unsigned long offset;
3076   unsigned long size;
3077   unsigned long align;
3078 } mach_o_fat_archentry;
3079
3080 typedef struct mach_o_fat_data_struct
3081 {
3082   unsigned long magic;
3083   unsigned long nfat_arch;
3084   mach_o_fat_archentry *archentries;
3085 } mach_o_fat_data_struct;
3086
3087 const bfd_target *
3088 bfd_mach_o_archive_p (bfd *abfd)
3089 {
3090   mach_o_fat_data_struct *adata = NULL;
3091   struct mach_o_fat_header_external hdr;
3092   unsigned long i;
3093
3094   if (bfd_seek (abfd, 0, SEEK_SET) != 0
3095       || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
3096     goto error;
3097
3098   adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3099   if (adata == NULL)
3100     goto error;
3101
3102   adata->magic = bfd_getb32 (hdr.magic);
3103   adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3104   if (adata->magic != 0xcafebabe)
3105     goto error;
3106   /* Avoid matching Java bytecode files, which have the same magic number.
3107      In the Java bytecode file format this field contains the JVM version,
3108      which starts at 43.0.  */
3109   if (adata->nfat_arch > 30)
3110     goto error;
3111
3112   adata->archentries =
3113     bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
3114   if (adata->archentries == NULL)
3115     goto error;
3116
3117   for (i = 0; i < adata->nfat_arch; i++)
3118     {
3119       struct mach_o_fat_arch_external arch;
3120       if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
3121         goto error;
3122       adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
3123       adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
3124       adata->archentries[i].offset = bfd_getb32 (arch.offset);
3125       adata->archentries[i].size = bfd_getb32 (arch.size);
3126       adata->archentries[i].align = bfd_getb32 (arch.align);
3127     }
3128
3129   abfd->tdata.mach_o_fat_data = adata;
3130   return abfd->xvec;
3131
3132  error:
3133   if (adata != NULL)
3134     bfd_release (abfd, adata);
3135   bfd_set_error (bfd_error_wrong_format);
3136   return NULL;
3137 }
3138
3139 bfd *
3140 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3141 {
3142   mach_o_fat_data_struct *adata;
3143   mach_o_fat_archentry *entry = NULL;
3144   unsigned long i;
3145   bfd *nbfd;
3146   enum bfd_architecture arch_type;
3147   unsigned long arch_subtype;
3148
3149   adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3150   BFD_ASSERT (adata != NULL);
3151
3152   /* Find index of previous entry.  */
3153   if (prev == NULL)
3154     i = 0;      /* Start at first one.  */
3155   else
3156     {
3157       for (i = 0; i < adata->nfat_arch; i++)
3158         {
3159           if (adata->archentries[i].offset == prev->origin)
3160             break;
3161         }
3162
3163       if (i == adata->nfat_arch)
3164         {
3165           /* Not found.  */
3166           bfd_set_error (bfd_error_bad_value);
3167           return NULL;
3168         }
3169     i++;        /* Get next entry.  */
3170   }
3171
3172   if (i >= adata->nfat_arch)
3173     {
3174       bfd_set_error (bfd_error_no_more_archived_files);
3175       return NULL;
3176     }
3177
3178   entry = &adata->archentries[i];
3179   nbfd = _bfd_new_bfd_contained_in (archive);
3180   if (nbfd == NULL)
3181     return NULL;
3182
3183   nbfd->origin = entry->offset;
3184
3185   bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3186                                    &arch_type, &arch_subtype);
3187
3188   /* Create the member filename. Use ARCH_NAME.  */
3189   nbfd->filename = bfd_printable_arch_mach (arch_type, arch_subtype);
3190   nbfd->iostream = NULL;
3191   bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3192
3193   return nbfd;
3194 }
3195
3196 /* If ABFD format is FORMAT and architecture is ARCH, return it.
3197    If ABFD is a fat image containing a member that corresponds to FORMAT
3198    and ARCH, returns it.
3199    In other case, returns NULL.
3200    This function allows transparent uses of fat images.  */
3201 bfd *
3202 bfd_mach_o_fat_extract (bfd *abfd,
3203                         bfd_format format,
3204                         const bfd_arch_info_type *arch)
3205 {
3206   bfd *res;
3207   mach_o_fat_data_struct *adata;
3208   unsigned int i;
3209
3210   if (bfd_check_format (abfd, format))
3211     {
3212       if (bfd_get_arch_info (abfd) == arch)
3213         return abfd;
3214       return NULL;
3215     }
3216   if (!bfd_check_format (abfd, bfd_archive)
3217       || abfd->xvec != &mach_o_fat_vec)
3218     return NULL;
3219
3220   /* This is a Mach-O fat image.  */
3221   adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3222   BFD_ASSERT (adata != NULL);
3223
3224   for (i = 0; i < adata->nfat_arch; i++)
3225     {
3226       struct mach_o_fat_archentry *e = &adata->archentries[i];
3227       enum bfd_architecture cpu_type;
3228       unsigned long cpu_subtype;
3229
3230       bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3231                                        &cpu_type, &cpu_subtype);
3232       if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3233         continue;
3234
3235       /* The architecture is found.  */
3236       res = _bfd_new_bfd_contained_in (abfd);
3237       if (res == NULL)
3238         return NULL;
3239
3240       res->origin = e->offset;
3241
3242       res->filename = bfd_printable_arch_mach (cpu_type, cpu_subtype);
3243       res->iostream = NULL;
3244
3245       if (bfd_check_format (res, format))
3246         {
3247           BFD_ASSERT (bfd_get_arch_info (res) == arch);
3248           return res;
3249         }
3250       bfd_close (res);
3251       return NULL;
3252     }
3253
3254   return NULL;
3255 }
3256
3257 int
3258 bfd_mach_o_lookup_command (bfd *abfd,
3259                            bfd_mach_o_load_command_type type,
3260                            bfd_mach_o_load_command **mcommand)
3261 {
3262   struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3263   bfd_mach_o_load_command *ncmd = NULL;
3264   unsigned int i, num;
3265
3266   BFD_ASSERT (md != NULL);
3267   BFD_ASSERT (mcommand != NULL);
3268
3269   num = 0;
3270   for (i = 0; i < md->header.ncmds; i++)
3271     {
3272       struct bfd_mach_o_load_command *cmd = &md->commands[i];
3273
3274       if (cmd->type != type)
3275         continue;
3276
3277       if (num == 0)
3278         ncmd = cmd;
3279       num++;
3280     }
3281
3282   *mcommand = ncmd;
3283   return num;
3284 }
3285
3286 unsigned long
3287 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3288 {
3289   switch (type)
3290     {
3291     case BFD_MACH_O_CPU_TYPE_MC680x0:
3292       return 0x04000000;
3293     case BFD_MACH_O_CPU_TYPE_MC88000:
3294       return 0xffffe000;
3295     case BFD_MACH_O_CPU_TYPE_POWERPC:
3296       return 0xc0000000;
3297     case BFD_MACH_O_CPU_TYPE_I386:
3298       return 0xc0000000;
3299     case BFD_MACH_O_CPU_TYPE_SPARC:
3300       return 0xf0000000;
3301     case BFD_MACH_O_CPU_TYPE_I860:
3302       return 0;
3303     case BFD_MACH_O_CPU_TYPE_HPPA:
3304       return 0xc0000000 - 0x04000000;
3305     default:
3306       return 0;
3307     }
3308 }
3309
3310 typedef struct bfd_mach_o_xlat_name
3311 {
3312   const char *name;
3313   unsigned long val;
3314 }
3315 bfd_mach_o_xlat_name;
3316
3317 static void
3318 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
3319                         unsigned long val,
3320                         FILE *file)
3321 {
3322   int first = 1;
3323
3324   for (; table->name; table++)
3325     {
3326       if (table->val & val)
3327         {
3328           if (!first)
3329             fprintf (file, "+");
3330           fprintf (file, "%s", table->name);
3331           val &= ~table->val;
3332           first = 0;
3333         }
3334     }
3335   if (val)
3336     {
3337       if (!first)
3338         fprintf (file, "+");
3339       fprintf (file, "0x%lx", val);
3340       return;
3341     }
3342   if (first)
3343     fprintf (file, "-");
3344 }
3345
3346 static const char *
3347 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
3348                              unsigned long val)
3349 {
3350   for (; table->name; table++)
3351     if (table->val == val)
3352       return table->name;
3353   return NULL;
3354 }
3355
3356 static const char *
3357 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
3358 {
3359   const char *res = bfd_mach_o_get_name_or_null (table, val);
3360
3361   if (res == NULL)
3362     return "*UNKNOWN*";
3363   else
3364     return res;
3365 }
3366
3367 static const bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
3368 {
3369   { "vax", BFD_MACH_O_CPU_TYPE_VAX },
3370   { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
3371   { "i386", BFD_MACH_O_CPU_TYPE_I386 },
3372   { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
3373   { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
3374   { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
3375   { "arm", BFD_MACH_O_CPU_TYPE_ARM },
3376   { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
3377   { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
3378   { "i860", BFD_MACH_O_CPU_TYPE_I860 },
3379   { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
3380   { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
3381   { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
3382   { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
3383   { NULL, 0}
3384 };
3385
3386 static const bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
3387 {
3388   { "object", BFD_MACH_O_MH_OBJECT },
3389   { "execute", BFD_MACH_O_MH_EXECUTE },
3390   { "fvmlib", BFD_MACH_O_MH_FVMLIB },
3391   { "core", BFD_MACH_O_MH_CORE },
3392   { "preload", BFD_MACH_O_MH_PRELOAD },
3393   { "dylib", BFD_MACH_O_MH_DYLIB },
3394   { "dylinker", BFD_MACH_O_MH_DYLINKER },
3395   { "bundle", BFD_MACH_O_MH_BUNDLE },
3396   { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
3397   { "dym", BFD_MACH_O_MH_DSYM },
3398   { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
3399   { NULL, 0}
3400 };
3401
3402 static const bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
3403 {
3404   { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
3405   { "incrlink", BFD_MACH_O_MH_INCRLINK },
3406   { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
3407   { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
3408   { "prebound", BFD_MACH_O_MH_PREBOUND },
3409   { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
3410   { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
3411   { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
3412   { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
3413   { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
3414   { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
3415   { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
3416   { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
3417   { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
3418   { "canonical", BFD_MACH_O_MH_CANONICAL },
3419   { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
3420   { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
3421   { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
3422   { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
3423   { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
3424   { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
3425   { "pie", BFD_MACH_O_MH_PIE },
3426   { NULL, 0}
3427 };
3428
3429 static const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
3430 {
3431   { "regular", BFD_MACH_O_S_REGULAR},
3432   { "zerofill", BFD_MACH_O_S_ZEROFILL},
3433   { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3434   { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3435   { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3436   { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3437   { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3438   { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3439   { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3440   { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3441   { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3442   { "coalesced", BFD_MACH_O_S_COALESCED},
3443   { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3444   { "interposing", BFD_MACH_O_S_INTERPOSING},
3445   { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3446   { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
3447   { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3448   { NULL, 0}
3449 };
3450
3451 static const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
3452 {
3453   { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3454   { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3455   { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3456   { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3457   { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3458   { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3459   { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3460   { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3461   { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3462   { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
3463   { NULL, 0}
3464 };
3465
3466 static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
3467 {
3468   { "segment", BFD_MACH_O_LC_SEGMENT},
3469   { "symtab", BFD_MACH_O_LC_SYMTAB},
3470   { "symseg", BFD_MACH_O_LC_SYMSEG},
3471   { "thread", BFD_MACH_O_LC_THREAD},
3472   { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
3473   { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
3474   { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
3475   { "ident", BFD_MACH_O_LC_IDENT},
3476   { "fvmfile", BFD_MACH_O_LC_FVMFILE},
3477   { "prepage", BFD_MACH_O_LC_PREPAGE},
3478   { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
3479   { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
3480   { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
3481   { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
3482   { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
3483   { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
3484   { "routines", BFD_MACH_O_LC_ROUTINES},
3485   { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
3486   { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
3487   { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
3488   { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
3489   { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
3490   { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
3491   { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
3492   { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
3493   { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
3494   { "uuid", BFD_MACH_O_LC_UUID},
3495   { "rpath", BFD_MACH_O_LC_RPATH},
3496   { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
3497   { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
3498   { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
3499   { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
3500   { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
3501   { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
3502   { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
3503   { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
3504   { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
3505   { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
3506   { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
3507   { NULL, 0}
3508 };
3509
3510 /* Get the section type from NAME.  Return -1 if NAME is unknown.  */
3511
3512 unsigned int
3513 bfd_mach_o_get_section_type_from_name (const char *name)
3514 {
3515   const bfd_mach_o_xlat_name *x;
3516
3517   for (x = bfd_mach_o_section_type_name; x->name; x++)
3518     if (strcmp (x->name, name) == 0)
3519       return x->val;
3520   return (unsigned int)-1;
3521 }
3522
3523 /* Get the section attribute from NAME.  Return -1 if NAME is unknown.  */
3524
3525 unsigned int
3526 bfd_mach_o_get_section_attribute_from_name (const char *name)
3527 {
3528   const bfd_mach_o_xlat_name *x;
3529
3530   for (x = bfd_mach_o_section_attribute_name; x->name; x++)
3531     if (strcmp (x->name, name) == 0)
3532       return x->val;
3533   return (unsigned int)-1;
3534 }
3535
3536 static void
3537 bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
3538 {
3539   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3540   bfd_mach_o_header *h = &mdata->header;
3541
3542   fputs (_("Mach-O header:\n"), file);
3543   fprintf (file, _(" magic     : %08lx\n"), h->magic);
3544   fprintf (file, _(" cputype   : %08lx (%s)\n"), h->cputype,
3545            bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
3546   fprintf (file, _(" cpusubtype: %08lx\n"), h->cpusubtype);
3547   fprintf (file, _(" filetype  : %08lx (%s)\n"),
3548            h->filetype,
3549            bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
3550   fprintf (file, _(" ncmds     : %08lx (%lu)\n"), h->ncmds, h->ncmds);
3551   fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds);
3552   fprintf (file, _(" flags     : %08lx ("), h->flags);
3553   bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file);
3554   fputs (_(")\n"), file);
3555   fprintf (file, _(" reserved  : %08x\n"), h->reserved);
3556 }
3557
3558 static void
3559 bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
3560 {
3561   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3562   unsigned int i;
3563   unsigned int sec_nbr = 0;
3564
3565   fputs (_("Segments and Sections:\n"), file);
3566   fputs (_(" #: Segment name     Section name     Address\n"), file);
3567
3568   for (i = 0; i < mdata->header.ncmds; i++)
3569     {
3570       bfd_mach_o_segment_command *seg;
3571       bfd_mach_o_section *sec;
3572
3573       if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
3574           && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
3575         continue;
3576
3577       seg = &mdata->commands[i].command.segment;
3578
3579       fprintf (file, "[Segment %-16s ", seg->segname);
3580       fprintf_vma (file, seg->vmaddr);
3581       fprintf (file, "-");
3582       fprintf_vma  (file, seg->vmaddr + seg->vmsize - 1);
3583       fputc (' ', file);
3584       fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
3585       fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
3586       fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
3587       fprintf (file, "]\n");
3588
3589       for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3590         {
3591           fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
3592                    sec->segname, sec->sectname);
3593           fprintf_vma (file, sec->addr);
3594           fprintf (file, " ");
3595           fprintf_vma  (file, sec->size);
3596           fprintf (file, " %08lx\n", sec->flags);
3597         }
3598     }
3599 }
3600
3601 static void
3602 bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED,
3603                           bfd_mach_o_section *sec, FILE *file)
3604 {
3605   fprintf (file, " Section: %-16s %-16s (bfdname: %s)\n",
3606            sec->sectname, sec->segname, sec->bfdsection->name);
3607   fprintf (file, "  addr: ");
3608   fprintf_vma (file, sec->addr);
3609   fprintf (file, " size: ");
3610   fprintf_vma  (file, sec->size);
3611   fprintf (file, " offset: ");
3612   fprintf_vma (file, sec->offset);
3613   fprintf (file, "\n");
3614   fprintf (file, "  align: %ld", sec->align);
3615   fprintf (file, "  nreloc: %lu  reloff: ", sec->nreloc);
3616   fprintf_vma (file, sec->reloff);
3617   fprintf (file, "\n");
3618   fprintf (file, "  flags: %08lx (type: %s", sec->flags,
3619            bfd_mach_o_get_name (bfd_mach_o_section_type_name,
3620                                 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
3621   fprintf (file, " attr: ");
3622   bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
3623                           sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
3624                           file);
3625   fprintf (file, ")\n");
3626   switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3627     {
3628     case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3629     case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3630     case BFD_MACH_O_S_SYMBOL_STUBS:
3631       fprintf (file, "  first indirect sym: %lu", sec->reserved1);
3632       fprintf (file, " (%u entries)",
3633                bfd_mach_o_section_get_nbr_indirect (abfd, sec));
3634       break;
3635     default:
3636       fprintf (file, "  reserved1: 0x%lx", sec->reserved1);
3637       break;
3638     }
3639   switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3640     {
3641     case BFD_MACH_O_S_SYMBOL_STUBS:
3642       fprintf (file, "  stub size: %lu", sec->reserved2);
3643       break;
3644     default:
3645       fprintf (file, "  reserved2: 0x%lx", sec->reserved2);
3646       break;
3647     }
3648   fprintf (file, "  reserved3: 0x%lx\n", sec->reserved3);
3649 }
3650
3651 static void
3652 bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
3653                           bfd_mach_o_load_command *cmd, FILE *file)
3654 {
3655   bfd_mach_o_segment_command *seg = &cmd->command.segment;
3656   bfd_mach_o_section *sec;
3657
3658   fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
3659   fprintf (file, "    vmaddr: ");
3660   fprintf_vma (file, seg->vmaddr);
3661   fprintf (file, "   vmsize: ");
3662   fprintf_vma  (file, seg->vmsize);
3663   fprintf (file, "\n");
3664   fprintf (file, "   fileoff: ");
3665   fprintf_vma (file, seg->fileoff);
3666   fprintf (file, " filesize: ");
3667   fprintf_vma (file, (bfd_vma)seg->filesize);
3668   fprintf (file, " endoff: ");
3669   fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
3670   fprintf (file, "\n");
3671   fprintf (file, "   nsects: %lu  ", seg->nsects);
3672   fprintf (file, " flags: %lx\n", seg->flags);
3673   for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3674     bfd_mach_o_print_section (abfd, sec, file);
3675 }
3676
3677 static void
3678 bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
3679                            bfd_mach_o_load_command *cmd, FILE *file)
3680 {
3681   bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
3682   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3683   unsigned int i;
3684
3685   fprintf (file, "              local symbols: idx: %10lu  num: %-8lu",
3686            dysymtab->ilocalsym, dysymtab->nlocalsym);
3687   fprintf (file, " (nxtidx: %lu)\n",
3688            dysymtab->ilocalsym + dysymtab->nlocalsym);
3689   fprintf (file, "           external symbols: idx: %10lu  num: %-8lu",
3690            dysymtab->iextdefsym, dysymtab->nextdefsym);
3691   fprintf (file, " (nxtidx: %lu)\n",
3692            dysymtab->iextdefsym + dysymtab->nextdefsym);
3693   fprintf (file, "          undefined symbols: idx: %10lu  num: %-8lu",
3694            dysymtab->iundefsym, dysymtab->nundefsym);
3695   fprintf (file, " (nxtidx: %lu)\n",
3696            dysymtab->iundefsym + dysymtab->nundefsym);
3697   fprintf (file, "           table of content: off: 0x%08lx  num: %-8lu",
3698            dysymtab->tocoff, dysymtab->ntoc);
3699   fprintf (file, " (endoff: 0x%08lx)\n",
3700            dysymtab->tocoff 
3701            + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE); 
3702   fprintf (file, "               module table: off: 0x%08lx  num: %-8lu",
3703            dysymtab->modtaboff, dysymtab->nmodtab);
3704   fprintf (file, " (endoff: 0x%08lx)\n",
3705            dysymtab->modtaboff + dysymtab->nmodtab 
3706            * (mach_o_wide_p (&mdata->header) ? 
3707               BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
3708   fprintf (file, "   external reference table: off: 0x%08lx  num: %-8lu",
3709            dysymtab->extrefsymoff, dysymtab->nextrefsyms);
3710   fprintf (file, " (endoff: 0x%08lx)\n",
3711            dysymtab->extrefsymoff 
3712            + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
3713   fprintf (file, "      indirect symbol table: off: 0x%08lx  num: %-8lu",
3714            dysymtab->indirectsymoff, dysymtab->nindirectsyms);
3715   fprintf (file, " (endoff: 0x%08lx)\n",
3716            dysymtab->indirectsymoff 
3717            + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
3718   fprintf (file, "  external relocation table: off: 0x%08lx  num: %-8lu",
3719            dysymtab->extreloff, dysymtab->nextrel);
3720   fprintf (file, " (endoff: 0x%08lx)\n",
3721            dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
3722   fprintf (file, "     local relocation table: off: 0x%08lx  num: %-8lu",
3723            dysymtab->locreloff, dysymtab->nlocrel);
3724   fprintf (file, " (endoff: 0x%08lx)\n",
3725            dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
3726   
3727   if (dysymtab->ntoc > 0
3728       || dysymtab->nindirectsyms > 0
3729       || dysymtab->nextrefsyms > 0)
3730     {
3731       /* Try to read the symbols to display the toc or indirect symbols.  */
3732       bfd_mach_o_read_symtab_symbols (abfd);
3733     }
3734   else if (dysymtab->nmodtab > 0)
3735     {
3736       /* Try to read the strtab to display modules name.  */
3737       bfd_mach_o_read_symtab_strtab (abfd);
3738     }
3739   
3740   for (i = 0; i < dysymtab->nmodtab; i++)
3741     {
3742       bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
3743       fprintf (file, "  module %u:\n", i);
3744       fprintf (file, "   name: %lu", module->module_name_idx);
3745       if (mdata->symtab && mdata->symtab->strtab)
3746         fprintf (file, ": %s",
3747                  mdata->symtab->strtab + module->module_name_idx);
3748       fprintf (file, "\n");
3749       fprintf (file, "   extdefsym: idx: %8lu  num: %lu\n",
3750                module->iextdefsym, module->nextdefsym);
3751       fprintf (file, "      refsym: idx: %8lu  num: %lu\n",
3752                module->irefsym, module->nrefsym);
3753       fprintf (file, "    localsym: idx: %8lu  num: %lu\n",
3754                module->ilocalsym, module->nlocalsym);
3755       fprintf (file, "      extrel: idx: %8lu  num: %lu\n",
3756                module->iextrel, module->nextrel);
3757       fprintf (file, "        init: idx: %8u  num: %u\n",
3758                module->iinit, module->ninit);
3759       fprintf (file, "        term: idx: %8u  num: %u\n",
3760                module->iterm, module->nterm);
3761       fprintf (file, "   objc_module_info: addr: ");
3762       fprintf_vma (file, module->objc_module_info_addr);
3763       fprintf (file, "  size: %lu\n", module->objc_module_info_size);
3764     }
3765
3766   if (dysymtab->ntoc > 0)
3767     {
3768       bfd_mach_o_symtab_command *symtab = mdata->symtab;
3769       
3770       fprintf (file, "  table of content: (symbol/module)\n");
3771       for (i = 0; i < dysymtab->ntoc; i++)
3772         {
3773           bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
3774           
3775           fprintf (file, "   %4u: ", i);
3776           if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
3777             {
3778               const char *name = symtab->symbols[toc->symbol_index].symbol.name;
3779               fprintf (file, "%s (%lu)", name ? name : "*invalid*",
3780                        toc->symbol_index);
3781             }
3782           else
3783             fprintf (file, "%lu", toc->symbol_index);
3784           
3785           fprintf (file, " / ");
3786           if (symtab && symtab->strtab
3787               && toc->module_index < dysymtab->nmodtab)
3788             {
3789               bfd_mach_o_dylib_module *mod;
3790               mod = &dysymtab->dylib_module[toc->module_index];
3791               fprintf (file, "%s (%lu)",
3792                        symtab->strtab + mod->module_name_idx,
3793                        toc->module_index);
3794             }
3795           else
3796             fprintf (file, "%lu", toc->module_index);
3797           
3798           fprintf (file, "\n");
3799         }
3800     }
3801
3802   if (dysymtab->nindirectsyms != 0)
3803     {
3804       fprintf (file, "  indirect symbols:\n");
3805
3806       for (i = 0; i < mdata->nsects; i++)
3807         {
3808           bfd_mach_o_section *sec = mdata->sections[i];
3809           unsigned int j, first, last;
3810           bfd_mach_o_symtab_command *symtab = mdata->symtab;
3811           bfd_vma addr;
3812           bfd_vma entry_size;
3813       
3814           switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3815             {
3816             case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3817             case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3818             case BFD_MACH_O_S_SYMBOL_STUBS:
3819               first = sec->reserved1;
3820               last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
3821               addr = sec->addr;
3822               entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
3823               fprintf (file, "  for section %s.%s:\n",
3824                        sec->segname, sec->sectname);
3825               for (j = first; j < last; j++)
3826                 {
3827                   unsigned int isym = dysymtab->indirect_syms[j];
3828                   
3829                   fprintf (file, "   ");
3830                   fprintf_vma (file, addr);
3831                   fprintf (file, " %5u: 0x%08x", j, isym);
3832                   if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
3833                     fprintf (file, " LOCAL");
3834                   if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
3835                     fprintf (file, " ABSOLUTE");
3836                   if (symtab && symtab->symbols
3837                       && isym < symtab->nsyms
3838                       && symtab->symbols[isym].symbol.name)
3839                     fprintf (file, " %s", symtab->symbols[isym].symbol.name);
3840                   fprintf (file, "\n");
3841                   addr += entry_size;
3842                 }
3843               break;
3844             default:
3845               break;
3846             }
3847         }
3848     }
3849   if (dysymtab->nextrefsyms > 0)
3850     {
3851       bfd_mach_o_symtab_command *symtab = mdata->symtab;
3852       
3853       fprintf (file, "  external reference table: (symbol flags)\n");
3854       for (i = 0; i < dysymtab->nextrefsyms; i++)
3855         {
3856           bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
3857           
3858           fprintf (file, "   %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
3859           if (symtab && symtab->symbols
3860               && ref->isym < symtab->nsyms
3861               && symtab->symbols[ref->isym].symbol.name)
3862             fprintf (file, " %s", symtab->symbols[ref->isym].symbol.name);
3863           fprintf (file, "\n");
3864         }
3865     }
3866
3867 }
3868
3869 static void
3870 bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED,
3871                             bfd_mach_o_load_command *cmd, FILE *file)
3872 {
3873   bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
3874
3875   fprintf (file, "       rebase: off: 0x%08x  size: %-8u\n",
3876            info->rebase_off, info->rebase_size);
3877   fprintf (file, "         bind: off: 0x%08x  size: %-8u\n",
3878            info->bind_off, info->bind_size);
3879   fprintf (file, "    weak bind: off: 0x%08x  size: %-8u\n",
3880            info->weak_bind_off, info->weak_bind_size);
3881   fprintf (file, "    lazy bind: off: 0x%08x  size: %-8u\n",
3882            info->lazy_bind_off, info->lazy_bind_size);
3883   fprintf (file, "       export: off: 0x%08x  size: %-8u\n",
3884            info->export_off, info->export_size);
3885 }
3886
3887 bfd_boolean
3888 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
3889 {
3890   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3891   FILE *file = (FILE *) ptr;
3892   unsigned int i;
3893
3894   bfd_mach_o_print_private_header (abfd, file);
3895   fputc ('\n', file);
3896
3897   for (i = 0; i < mdata->header.ncmds; i++)
3898     {
3899       bfd_mach_o_load_command *cmd = &mdata->commands[i];
3900       const char *cmd_name;
3901       
3902       cmd_name = bfd_mach_o_get_name_or_null
3903         (bfd_mach_o_load_command_name, cmd->type);
3904       fprintf (file, "Load command ");
3905       if (cmd_name == NULL)
3906         fprintf (file, "0x%02x:", cmd->type);
3907       else
3908         fprintf (file, "%s:", cmd_name);
3909
3910       switch (cmd->type)
3911         {
3912         case BFD_MACH_O_LC_SEGMENT:
3913         case BFD_MACH_O_LC_SEGMENT_64:
3914           bfd_mach_o_print_segment (abfd, cmd, file);
3915           break;
3916         case BFD_MACH_O_LC_UUID:
3917           {
3918             bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
3919             unsigned int j;
3920
3921             for (j = 0; j < sizeof (uuid->uuid); j ++)
3922               fprintf (file, " %02x", uuid->uuid[j]);
3923             fputc ('\n', file);
3924           }
3925           break;
3926         case BFD_MACH_O_LC_LOAD_DYLIB:
3927         case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
3928         case BFD_MACH_O_LC_REEXPORT_DYLIB:
3929         case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
3930         case BFD_MACH_O_LC_ID_DYLIB:
3931           {
3932             bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
3933             fprintf (file, " %s\n", dylib->name_str);
3934             fprintf (file, "            time stamp: 0x%08lx\n",
3935                      dylib->timestamp);
3936             fprintf (file, "       current version: 0x%08lx\n",
3937                      dylib->current_version);
3938             fprintf (file, "  comptibility version: 0x%08lx\n",
3939                      dylib->compatibility_version);
3940             break;
3941           }
3942         case BFD_MACH_O_LC_LOAD_DYLINKER:
3943         case BFD_MACH_O_LC_ID_DYLINKER:
3944           fprintf (file, " %s\n", cmd->command.dylinker.name_str);
3945           break;
3946         case BFD_MACH_O_LC_SYMTAB:
3947           {
3948             bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
3949             fprintf (file,
3950                      "\n"
3951                      "   symoff: 0x%08x    nsyms: %8u  (endoff: 0x%08x)\n",
3952                      symtab->symoff, symtab->nsyms,
3953                      symtab->symoff + symtab->nsyms 
3954                      * (mach_o_wide_p (&mdata->header) 
3955                         ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
3956             fprintf (file,
3957                      "   stroff: 0x%08x  strsize: %8u  (endoff: 0x%08x)\n",
3958                      symtab->stroff, symtab->strsize,
3959                      symtab->stroff + symtab->strsize);
3960             break;
3961           }
3962         case BFD_MACH_O_LC_DYSYMTAB:
3963           fprintf (file, "\n");
3964           bfd_mach_o_print_dysymtab (abfd, cmd, file);
3965           break;
3966         case BFD_MACH_O_LC_CODE_SIGNATURE:
3967         case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
3968         case BFD_MACH_O_LC_FUNCTION_STARTS:
3969           {
3970             bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
3971             fprintf
3972               (file, "\n"
3973                "  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
3974                linkedit->dataoff, linkedit->datasize,
3975                linkedit->dataoff + linkedit->datasize);
3976             break;
3977           }
3978         case BFD_MACH_O_LC_SUB_FRAMEWORK:
3979         case BFD_MACH_O_LC_SUB_UMBRELLA:
3980         case BFD_MACH_O_LC_SUB_LIBRARY:
3981         case BFD_MACH_O_LC_SUB_CLIENT:
3982         case BFD_MACH_O_LC_RPATH:
3983           {
3984             bfd_mach_o_str_command *str = &cmd->command.str;
3985             fprintf (file, " %s\n", str->str);
3986             break;
3987           }
3988         case BFD_MACH_O_LC_THREAD:
3989         case BFD_MACH_O_LC_UNIXTHREAD:
3990           {
3991             bfd_mach_o_thread_command *thread = &cmd->command.thread;
3992             unsigned int j;
3993             bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3994
3995             fprintf (file, " nflavours: %lu\n", thread->nflavours);
3996             for (j = 0; j < thread->nflavours; j++)
3997               {
3998                 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
3999
4000                 fprintf (file, "  %2u: flavour: 0x%08lx  offset: 0x%08lx"
4001                          "  size: 0x%08lx\n",
4002                          j, flavour->flavour, flavour->offset,
4003                          flavour->size);
4004                 if (bed->_bfd_mach_o_print_thread)
4005                   {
4006                     char *buf = bfd_malloc (flavour->size);
4007
4008                     if (buf
4009                         && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
4010                         && (bfd_bread (buf, flavour->size, abfd) 
4011                             == flavour->size))
4012                       (*bed->_bfd_mach_o_print_thread)(abfd, flavour,
4013                                                        file, buf);
4014                     free (buf);
4015                   }
4016               }
4017             break;
4018           }
4019         case BFD_MACH_O_LC_DYLD_INFO:
4020           fprintf (file, "\n");
4021           bfd_mach_o_print_dyld_info (abfd, cmd, file);
4022           break;
4023         case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
4024         case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
4025           {
4026             bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
4027
4028             fprintf (file, " %u.%u.%u\n", ver->rel, ver->maj, ver->min);
4029           }
4030           break;
4031         default:
4032           fprintf (file, "\n");
4033           fprintf (file, "  offset: 0x%08lx\n", (unsigned long)cmd->offset);
4034           fprintf (file, "    size: 0x%08lx\n", (unsigned long)cmd->len);
4035           break;
4036         }
4037       fputc ('\n', file);
4038     }
4039
4040   bfd_mach_o_print_section_map (abfd, file);
4041
4042   return TRUE;
4043 }
4044
4045 int
4046 bfd_mach_o_core_fetch_environment (bfd *abfd,
4047                                    unsigned char **rbuf,
4048                                    unsigned int *rlen)
4049 {
4050   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4051   unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
4052   unsigned int i = 0;
4053
4054   for (i = 0; i < mdata->header.ncmds; i++)
4055     {
4056       bfd_mach_o_load_command *cur = &mdata->commands[i];
4057       bfd_mach_o_segment_command *seg = NULL;
4058
4059       if (cur->type != BFD_MACH_O_LC_SEGMENT)
4060         continue;
4061
4062       seg = &cur->command.segment;
4063
4064       if ((seg->vmaddr + seg->vmsize) == stackaddr)
4065         {
4066           unsigned long start = seg->fileoff;
4067           unsigned long end = seg->fileoff + seg->filesize;
4068           unsigned char *buf = bfd_malloc (1024);
4069           unsigned long size = 1024;
4070
4071           for (;;)
4072             {
4073               bfd_size_type nread = 0;
4074               unsigned long offset;
4075               int found_nonnull = 0;
4076
4077               if (size > (end - start))
4078                 size = (end - start);
4079
4080               buf = bfd_realloc_or_free (buf, size);
4081               if (buf == NULL)
4082                 return -1;
4083
4084               if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
4085                 {
4086                   free (buf);
4087                   return -1;
4088                 }
4089
4090               nread = bfd_bread (buf, size, abfd);
4091
4092               if (nread != size)
4093                 {
4094                   free (buf);
4095                   return -1;
4096                 }
4097
4098               for (offset = 4; offset <= size; offset += 4)
4099                 {
4100                   unsigned long val;
4101
4102                   val = *((unsigned long *) (buf + size - offset));
4103                   if (! found_nonnull)
4104                     {
4105                       if (val != 0)
4106                         found_nonnull = 1;
4107                     }
4108                   else if (val == 0x0)
4109                     {
4110                       unsigned long bottom;
4111                       unsigned long top;
4112
4113                       bottom = seg->fileoff + seg->filesize - offset;
4114                       top = seg->fileoff + seg->filesize - 4;
4115                       *rbuf = bfd_malloc (top - bottom);
4116                       *rlen = top - bottom;
4117
4118                       memcpy (*rbuf, buf + size - *rlen, *rlen);
4119                       free (buf);
4120                       return 0;
4121                     }
4122                 }
4123
4124               if (size == (end - start))
4125                 break;
4126
4127               size *= 2;
4128             }
4129
4130           free (buf);
4131         }
4132     }
4133
4134   return -1;
4135 }
4136
4137 char *
4138 bfd_mach_o_core_file_failing_command (bfd *abfd)
4139 {
4140   unsigned char *buf = NULL;
4141   unsigned int len = 0;
4142   int ret = -1;
4143
4144   ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
4145   if (ret < 0)
4146     return NULL;
4147
4148   return (char *) buf;
4149 }
4150
4151 int
4152 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
4153 {
4154   return 0;
4155 }
4156
4157 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 
4158 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4159
4160 #define bfd_mach_o_swap_reloc_in NULL
4161 #define bfd_mach_o_swap_reloc_out NULL
4162 #define bfd_mach_o_print_thread NULL
4163
4164 #define TARGET_NAME             mach_o_be_vec
4165 #define TARGET_STRING           "mach-o-be"
4166 #define TARGET_ARCHITECTURE     bfd_arch_unknown
4167 #define TARGET_BIG_ENDIAN       1
4168 #define TARGET_ARCHIVE          0
4169 #include "mach-o-target.c"
4170
4171 #undef TARGET_NAME
4172 #undef TARGET_STRING
4173 #undef TARGET_ARCHITECTURE
4174 #undef TARGET_BIG_ENDIAN
4175 #undef TARGET_ARCHIVE
4176
4177 #define TARGET_NAME             mach_o_le_vec
4178 #define TARGET_STRING           "mach-o-le"
4179 #define TARGET_ARCHITECTURE     bfd_arch_unknown
4180 #define TARGET_BIG_ENDIAN       0
4181 #define TARGET_ARCHIVE          0
4182
4183 #include "mach-o-target.c"
4184
4185 #undef TARGET_NAME
4186 #undef TARGET_STRING
4187 #undef TARGET_ARCHITECTURE
4188 #undef TARGET_BIG_ENDIAN
4189 #undef TARGET_ARCHIVE
4190
4191 /* Not yet handled: creating an archive.  */
4192 #define bfd_mach_o_mkarchive                      _bfd_noarchive_mkarchive
4193
4194 /* Not used.  */
4195 #define bfd_mach_o_read_ar_hdr                    _bfd_noarchive_read_ar_hdr
4196 #define bfd_mach_o_write_ar_hdr                   _bfd_noarchive_write_ar_hdr
4197 #define bfd_mach_o_slurp_armap                    _bfd_noarchive_slurp_armap
4198 #define bfd_mach_o_slurp_extended_name_table      _bfd_noarchive_slurp_extended_name_table
4199 #define bfd_mach_o_construct_extended_name_table  _bfd_noarchive_construct_extended_name_table
4200 #define bfd_mach_o_truncate_arname                _bfd_noarchive_truncate_arname
4201 #define bfd_mach_o_write_armap                    _bfd_noarchive_write_armap
4202 #define bfd_mach_o_get_elt_at_index               _bfd_noarchive_get_elt_at_index
4203 #define bfd_mach_o_generic_stat_arch_elt          _bfd_noarchive_generic_stat_arch_elt
4204 #define bfd_mach_o_update_armap_timestamp         _bfd_noarchive_update_armap_timestamp
4205
4206 #define TARGET_NAME             mach_o_fat_vec
4207 #define TARGET_STRING           "mach-o-fat"
4208 #define TARGET_ARCHITECTURE     bfd_arch_unknown
4209 #define TARGET_BIG_ENDIAN       1
4210 #define TARGET_ARCHIVE          1
4211
4212 #include "mach-o-target.c"
4213
4214 #undef TARGET_NAME
4215 #undef TARGET_STRING
4216 #undef TARGET_ARCHITECTURE
4217 #undef TARGET_BIG_ENDIAN
4218 #undef TARGET_ARCHIVE