OSDN Git Service

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