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