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