Sync from gcc mainline.
[binutils.git] / bfd / mach-o.c
blob43e1d85d00d17855f4ea3f1923b3ec3add1cd00d
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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>
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_mach_o_gen_mkobject
34 #define FILE_ALIGN(off, algn) \
35 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
37 static int bfd_mach_o_read_symtab_symbols (bfd *);
39 unsigned int
40 bfd_mach_o_version (bfd *abfd)
42 bfd_mach_o_data_struct *mdata = NULL;
44 BFD_ASSERT (bfd_mach_o_valid (abfd));
45 mdata = bfd_mach_o_get_data (abfd);
47 return mdata->header.version;
50 bfd_boolean
51 bfd_mach_o_valid (bfd *abfd)
53 if (abfd == NULL || abfd->xvec == NULL)
54 return FALSE;
56 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
57 return FALSE;
59 if (bfd_mach_o_get_data (abfd) == NULL)
60 return FALSE;
61 return TRUE;
64 static INLINE bfd_boolean
65 mach_o_wide_p (bfd_mach_o_header *header)
67 switch (header->version)
69 case 1:
70 return FALSE;
71 case 2:
72 return TRUE;
73 default:
74 BFD_FAIL ();
75 return FALSE;
79 static INLINE bfd_boolean
80 bfd_mach_o_wide_p (bfd *abfd)
82 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
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. */
89 struct mach_o_section_name_xlat
91 const char *bfd_name;
92 const char *mach_o_name;
93 flagword flags;
96 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
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}
112 static const struct mach_o_section_name_xlat text_section_names_xlat[] =
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}
121 static const struct mach_o_section_name_xlat data_section_names_xlat[] =
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}
132 struct mach_o_segment_name_xlat
134 const char *segname;
135 const struct mach_o_section_name_xlat *sections;
138 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
140 { "__DWARF", dwarf_section_names_xlat },
141 { "__TEXT", text_section_names_xlat },
142 { "__DATA", data_section_names_xlat },
143 { NULL, NULL }
147 /* Mach-O to bfd names. */
149 static void
150 bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
151 char **name, flagword *flags)
153 const struct mach_o_segment_name_xlat *seg;
154 char *res;
155 unsigned int len;
156 const char *pfx = "";
158 *name = NULL;
159 *flags = SEC_NO_FLAGS;
161 for (seg = segsec_names_xlat; seg->segname; seg++)
163 if (strcmp (seg->segname, section->segname) == 0)
165 const struct mach_o_section_name_xlat *sec;
167 for (sec = seg->sections; sec->mach_o_name; sec++)
169 if (strcmp (sec->mach_o_name, section->sectname) == 0)
171 len = strlen (sec->bfd_name);
172 res = bfd_alloc (abfd, len + 1);
174 if (res == NULL)
175 return;
176 strcpy (res, sec->bfd_name);
177 *name = res;
178 *flags = sec->flags;
179 return;
185 len = strlen (section->segname) + 1
186 + strlen (section->sectname) + 1;
188 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
189 with an underscore. */
190 if (section->segname[0] != '_')
192 static const char seg_pfx[] = "LC_SEGMENT.";
194 pfx = seg_pfx;
195 len += sizeof (seg_pfx) - 1;
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;
205 /* Convert a bfd section name to a Mach-O segment + section name. */
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)
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;
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++)
223 const struct mach_o_section_name_xlat *sec;
225 for (sec = seg->sections; sec->mach_o_name; sec++)
227 if (strcmp (sec->bfd_name, name) == 0)
229 strcpy (section->segname, seg->segname);
230 strcpy (section->sectname, sec->mach_o_name);
231 return;
236 /* Strip LC_SEGMENT. prefix. */
237 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
238 name += 11;
240 /* Find a dot. */
241 dot = strchr (name, '.');
242 len = strlen (name);
244 /* Try to split name into segment and section names. */
245 if (dot && dot != name)
247 seglen = dot - name;
248 seclen = len - (dot + 1 - name);
250 if (seglen < 16 && seclen < 16)
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;
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;
268 /* Return the size of an entry for section SEC.
269 Must be called only for symbol pointer section and symbol stubs
270 sections. */
272 static unsigned int
273 bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
275 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
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;
288 /* Return the number of indirect symbols for a section.
289 Must be called only for symbol pointer section and symbol stubs
290 sections. */
292 static unsigned int
293 bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
295 unsigned int elsz;
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;
305 /* Copy any private info we understand from the input symbol
306 to the output symbol. */
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)
314 return TRUE;
317 /* Copy any private info we understand from the input section
318 to the output section. */
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)
326 return TRUE;
329 /* Copy any private info we understand from the input bfd
330 to the output bfd. */
332 bfd_boolean
333 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
335 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
336 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
337 return TRUE;
339 BFD_ASSERT (bfd_mach_o_valid (ibfd));
340 BFD_ASSERT (bfd_mach_o_valid (obfd));
342 /* FIXME: copy commands. */
344 return TRUE;
347 /* Count the total number of symbols. */
349 static long
350 bfd_mach_o_count_symbols (bfd *abfd)
352 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
354 if (mdata->symtab == NULL)
355 return 0;
356 return mdata->symtab->nsyms;
359 long
360 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
362 long nsyms = bfd_mach_o_count_symbols (abfd);
364 return ((nsyms + 1) * sizeof (asymbol *));
367 long
368 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
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;
375 if (nsyms < 0)
376 return nsyms;
378 if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
380 fprintf (stderr,
381 "bfd_mach_o_canonicalize_symtab: unable to load symbols\n");
382 return 0;
385 BFD_ASSERT (sym->symbols != NULL);
387 for (j = 0; j < sym->nsyms; j++)
388 alocation[j] = &sym->symbols[j].symbol;
390 alocation[j] = NULL;
392 return nsyms;
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)
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;
412 *ret = NULL;
414 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
415 return 0;
417 if (dysymtab->nindirectsyms == 0)
418 return 0;
420 count = dysymtab->nindirectsyms;
421 size = count * sizeof (asymbol) + 1;
423 for (j = 0; j < count; j++)
425 unsigned int isym = dysymtab->indirect_syms[j];
427 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
428 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
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;
438 n = 0;
439 for (i = 0; i < mdata->nsects; i++)
441 bfd_mach_o_section *sec = mdata->sections[i];
442 unsigned int first, last;
443 bfd_vma addr;
444 bfd_vma entry_size;
446 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
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++)
457 unsigned int isym = dysymtab->indirect_syms[j];
459 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
460 s->section = sec->bfdsection;
461 s->value = addr - sec->addr;
462 s->udata.p = NULL;
464 if (isym < symtab->nsyms
465 && symtab->symbols[isym].symbol.name)
467 const char *sym = symtab->symbols[isym].symbol.name;
468 size_t len;
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");
477 else
478 s->name = nul_name;
480 addr += entry_size;
481 s++;
482 n++;
484 break;
485 default:
486 break;
490 return n;
493 void
494 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
495 asymbol *symbol,
496 symbol_info *ret)
498 bfd_symbol_info (symbol, ret);
501 void
502 bfd_mach_o_print_symbol (bfd *abfd,
503 void * afile,
504 asymbol *symbol,
505 bfd_print_symbol_type how)
507 FILE *file = (FILE *) afile;
508 const char *name;
509 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
511 switch (how)
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)
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;
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);
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)
559 *subtype = bfd_arch_unknown;
561 switch (mtype)
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;
598 static bfd_boolean
599 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
601 unsigned char buf[32];
602 unsigned int size;
604 size = mach_o_wide_p (header) ?
605 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
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);
615 if (mach_o_wide_p (header))
616 bfd_h_put_32 (abfd, header->reserved, buf + 28);
618 if (bfd_seek (abfd, 0, SEEK_SET) != 0
619 || bfd_bwrite ((void *) buf, size, abfd) != size)
620 return FALSE;
622 return TRUE;
625 static int
626 bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
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;
634 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
635 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
637 offset = 8;
638 nflavours = 0;
639 for (i = 0; i < cmd->nflavours; i++)
641 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
642 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
644 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
645 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
647 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
648 || bfd_bwrite ((void *) buf, 8, abfd) != 8)
649 return -1;
651 offset += cmd->flavours[i].size + 8;
654 return 0;
657 long
658 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
659 asection *asect)
661 return (asect->reloc_count + 1) * sizeof (arelent *);
664 static int
665 bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
666 arelent *res, asymbol **syms)
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;
675 addr = bfd_get_32 (abfd, buf + 0);
676 symnum = bfd_get_32 (abfd, buf + 4);
678 if (addr & BFD_MACH_O_SR_SCATTERED)
680 unsigned int j;
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++)
688 bfd_mach_o_section *sect = mdata->sections[j];
689 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
691 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
692 res->addend = symnum - sect->addr;
693 break;
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;
702 else
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)
709 sym = syms + num;
710 reloc.r_extern = 1;
712 else
714 BFD_ASSERT (num != 0);
715 BFD_ASSERT (num <= mdata->nsects);
716 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
717 /* For a symbol defined in section S, the addend (stored in the
718 binary) contains the address of the section. To comply with
719 bfd conventio, substract the section address.
720 Use the address from the header, so that the user can modify
721 the vma of the section. */
722 res->addend = -mdata->sections[num - 1]->addr;
723 reloc.r_extern = 0;
725 res->sym_ptr_ptr = sym;
726 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
727 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
728 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
729 reloc.r_scattered = 0;
732 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
733 return -1;
734 return 0;
737 static int
738 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
739 unsigned long count,
740 arelent *res, asymbol **syms)
742 unsigned long i;
743 char *native_relocs;
744 bfd_size_type native_size;
746 /* Allocate and read relocs. */
747 native_size = count * BFD_MACH_O_RELENT_SIZE;
748 native_relocs = bfd_malloc (native_size);
749 if (native_relocs == NULL)
750 return -1;
752 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
753 || bfd_bread (native_relocs, native_size, abfd) != native_size)
754 goto err;
756 for (i = 0; i < count; i++)
758 char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
760 if (bfd_mach_o_canonicalize_one_reloc (abfd, buf, &res[i], syms) < 0)
761 goto err;
763 free (native_relocs);
764 return i;
765 err:
766 free (native_relocs);
767 return -1;
770 long
771 bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
772 arelent **rels, asymbol **syms)
774 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
775 unsigned long i;
776 arelent *res;
778 if (asect->reloc_count == 0)
779 return 0;
781 /* No need to go further if we don't know how to read relocs. */
782 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
783 return 0;
785 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
786 if (res == NULL)
787 return -1;
789 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
790 asect->reloc_count, res, syms) < 0)
792 free (res);
793 return -1;
796 for (i = 0; i < asect->reloc_count; i++)
797 rels[i] = &res[i];
798 rels[i] = NULL;
799 asect->relocation = res;
801 return i;
804 long
805 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
807 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
809 if (mdata->dysymtab == NULL)
810 return 1;
811 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
812 * sizeof (arelent *);
815 long
816 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
817 struct bfd_symbol **syms)
819 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
820 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
821 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
822 unsigned long i;
823 arelent *res;
825 if (dysymtab == NULL)
826 return 0;
827 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
828 return 0;
830 /* No need to go further if we don't know how to read relocs. */
831 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
832 return 0;
834 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
835 if (res == NULL)
836 return -1;
838 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
839 dysymtab->nextrel, res, syms) < 0)
841 free (res);
842 return -1;
845 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
846 dysymtab->nlocrel,
847 res + dysymtab->nextrel, syms) < 0)
849 free (res);
850 return -1;
853 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
854 rels[i] = &res[i];
855 rels[i] = NULL;
856 return i;
859 static bfd_boolean
860 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
862 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
863 unsigned int i;
864 arelent **entries;
865 asection *sec;
866 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
868 sec = section->bfdsection;
869 if (sec->reloc_count == 0)
870 return TRUE;
872 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
873 return TRUE;
875 /* Allocate relocation room. */
876 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
877 section->nreloc = sec->reloc_count;
878 sec->rel_filepos = mdata->filelen;
879 section->reloff = sec->rel_filepos;
880 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
882 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
883 return FALSE;
885 /* Convert and write. */
886 entries = section->bfdsection->orelocation;
887 for (i = 0; i < section->nreloc; i++)
889 arelent *rel = entries[i];
890 char buf[8];
891 bfd_mach_o_reloc_info info, *pinfo = &info;
893 /* Convert relocation to an intermediate representation. */
894 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
895 return FALSE;
897 /* Lower the relocation info. */
898 if (pinfo->r_scattered)
900 unsigned long v;
902 v = BFD_MACH_O_SR_SCATTERED
903 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
904 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
905 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
906 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
907 bfd_put_32 (abfd, v, buf);
908 bfd_put_32 (abfd, pinfo->r_value, buf + 4);
910 else
912 unsigned long v;
914 bfd_put_32 (abfd, pinfo->r_address, buf);
915 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
916 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
917 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
918 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
919 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
920 bfd_put_32 (abfd, v, buf + 4);
923 if (bfd_bwrite ((void *) buf, BFD_MACH_O_RELENT_SIZE, abfd)
924 != BFD_MACH_O_RELENT_SIZE)
925 return FALSE;
927 return TRUE;
930 static int
931 bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
933 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
935 memcpy (buf, section->sectname, 16);
936 memcpy (buf + 16, section->segname, 16);
937 bfd_h_put_32 (abfd, section->addr, buf + 32);
938 bfd_h_put_32 (abfd, section->size, buf + 36);
939 bfd_h_put_32 (abfd, section->offset, buf + 40);
940 bfd_h_put_32 (abfd, section->align, buf + 44);
941 bfd_h_put_32 (abfd, section->reloff, buf + 48);
942 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
943 bfd_h_put_32 (abfd, section->flags, buf + 56);
944 bfd_h_put_32 (abfd, section->reserved1, buf + 60);
945 bfd_h_put_32 (abfd, section->reserved2, buf + 64);
947 if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
948 != BFD_MACH_O_SECTION_SIZE)
949 return -1;
951 return 0;
954 static int
955 bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
957 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
959 memcpy (buf, section->sectname, 16);
960 memcpy (buf + 16, section->segname, 16);
961 bfd_h_put_64 (abfd, section->addr, buf + 32);
962 bfd_h_put_64 (abfd, section->size, buf + 40);
963 bfd_h_put_32 (abfd, section->offset, buf + 48);
964 bfd_h_put_32 (abfd, section->align, buf + 52);
965 bfd_h_put_32 (abfd, section->reloff, buf + 56);
966 bfd_h_put_32 (abfd, section->nreloc, buf + 60);
967 bfd_h_put_32 (abfd, section->flags, buf + 64);
968 bfd_h_put_32 (abfd, section->reserved1, buf + 68);
969 bfd_h_put_32 (abfd, section->reserved2, buf + 72);
970 bfd_h_put_32 (abfd, section->reserved3, buf + 76);
972 if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
973 != BFD_MACH_O_SECTION_64_SIZE)
974 return -1;
976 return 0;
979 static int
980 bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
982 unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
983 bfd_mach_o_segment_command *seg = &command->command.segment;
984 unsigned long i;
986 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
988 for (i = 0; i < seg->nsects; i++)
989 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
990 return -1;
992 memcpy (buf, seg->segname, 16);
993 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
994 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
995 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
996 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
997 bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
998 bfd_h_put_32 (abfd, seg->initprot, buf + 36);
999 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
1000 bfd_h_put_32 (abfd, seg->flags, buf + 44);
1002 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1003 || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd)
1004 != BFD_MACH_O_LC_SEGMENT_SIZE - 8))
1005 return -1;
1007 for (i = 0; i < seg->nsects; i++)
1008 if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
1009 return -1;
1011 return 0;
1014 static int
1015 bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1017 unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
1018 bfd_mach_o_segment_command *seg = &command->command.segment;
1019 unsigned long i;
1021 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1023 for (i = 0; i < seg->nsects; i++)
1024 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
1025 return -1;
1027 memcpy (buf, seg->segname, 16);
1028 bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
1029 bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
1030 bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
1031 bfd_h_put_64 (abfd, seg->filesize, buf + 40);
1032 bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
1033 bfd_h_put_32 (abfd, seg->initprot, buf + 52);
1034 bfd_h_put_32 (abfd, seg->nsects, buf + 56);
1035 bfd_h_put_32 (abfd, seg->flags, buf + 60);
1037 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1038 || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
1039 != BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
1040 return -1;
1042 for (i = 0; i < seg->nsects; i++)
1043 if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
1044 return -1;
1046 return 0;
1049 static bfd_boolean
1050 bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1052 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1053 bfd_mach_o_symtab_command *sym = &command->command.symtab;
1054 unsigned char buf[16];
1055 unsigned long i;
1056 unsigned int wide = bfd_mach_o_wide_p (abfd);
1057 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1058 struct bfd_strtab_hash *strtab;
1059 asymbol **symbols = bfd_get_outsymbols (abfd);
1061 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1063 /* Write the symbols first. */
1064 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1065 sym->symoff = mdata->filelen;
1066 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1067 return FALSE;
1069 sym->nsyms = bfd_get_symcount (abfd);
1070 mdata->filelen += sym->nsyms * symlen;
1072 strtab = _bfd_stringtab_init ();
1073 if (strtab == NULL)
1074 return FALSE;
1076 for (i = 0; i < sym->nsyms; i++)
1078 bfd_size_type str_index;
1079 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1081 /* Compute name index. */
1082 /* An index of 0 always means the empty string. */
1083 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
1084 str_index = 0;
1085 else
1087 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1088 if (str_index == (bfd_size_type) -1)
1089 goto err;
1091 bfd_h_put_32 (abfd, str_index, buf);
1092 bfd_h_put_8 (abfd, s->n_type, buf + 4);
1093 bfd_h_put_8 (abfd, s->n_sect, buf + 5);
1094 bfd_h_put_16 (abfd, s->n_desc, buf + 6);
1095 if (wide)
1096 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1097 else
1098 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1100 if (bfd_bwrite ((void *) buf, symlen, abfd) != symlen)
1101 goto err;
1103 sym->strsize = _bfd_stringtab_size (strtab);
1104 sym->stroff = mdata->filelen;
1105 mdata->filelen += sym->strsize;
1107 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1108 goto err;
1109 _bfd_stringtab_free (strtab);
1111 /* The command. */
1112 bfd_h_put_32 (abfd, sym->symoff, buf);
1113 bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
1114 bfd_h_put_32 (abfd, sym->stroff, buf + 8);
1115 bfd_h_put_32 (abfd, sym->strsize, buf + 12);
1117 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1118 || bfd_bwrite ((void *) buf, 16, abfd) != 16)
1119 return FALSE;
1121 return TRUE;
1123 err:
1124 _bfd_stringtab_free (strtab);
1125 return FALSE;
1128 /* Process the symbols and generate Mach-O specific fields.
1129 Number them. */
1131 static bfd_boolean
1132 bfd_mach_o_mangle_symbols (bfd *abfd)
1134 unsigned long i;
1135 asymbol **symbols = bfd_get_outsymbols (abfd);
1137 for (i = 0; i < bfd_get_symcount (abfd); i++)
1139 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1141 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1143 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1144 symbols should be N_UNDEF | N_EXT), we suppose the back-end
1145 values haven't been set. */
1146 if (s->symbol.section == bfd_abs_section_ptr)
1147 s->n_type = BFD_MACH_O_N_ABS;
1148 else if (s->symbol.section == bfd_und_section_ptr)
1150 s->n_type = BFD_MACH_O_N_UNDF;
1151 if (s->symbol.flags & BSF_WEAK)
1152 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1154 else if (s->symbol.section == bfd_com_section_ptr)
1155 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1156 else
1157 s->n_type = BFD_MACH_O_N_SECT;
1159 if (s->symbol.flags & BSF_GLOBAL)
1160 s->n_type |= BFD_MACH_O_N_EXT;
1163 /* Compute section index. */
1164 if (s->symbol.section != bfd_abs_section_ptr
1165 && s->symbol.section != bfd_und_section_ptr
1166 && s->symbol.section != bfd_com_section_ptr)
1167 s->n_sect = s->symbol.section->target_index;
1169 /* Number symbols. */
1170 s->symbol.udata.i = i;
1172 return TRUE;
1175 bfd_boolean
1176 bfd_mach_o_write_contents (bfd *abfd)
1178 unsigned int i;
1179 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1181 if (mdata->header.ncmds == 0)
1182 if (!bfd_mach_o_build_commands (abfd))
1183 return FALSE;
1185 /* Now write header information. */
1186 if (mdata->header.filetype == 0)
1188 if (abfd->flags & EXEC_P)
1189 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1190 else if (abfd->flags & DYNAMIC)
1191 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1192 else
1193 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1195 if (!bfd_mach_o_write_header (abfd, &mdata->header))
1196 return FALSE;
1198 /* Assign a number to each symbols. */
1199 if (!bfd_mach_o_mangle_symbols (abfd))
1200 return FALSE;
1202 for (i = 0; i < mdata->header.ncmds; i++)
1204 unsigned char buf[8];
1205 bfd_mach_o_load_command *cur = &mdata->commands[i];
1206 unsigned long typeflag;
1208 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
1210 bfd_h_put_32 (abfd, typeflag, buf);
1211 bfd_h_put_32 (abfd, cur->len, buf + 4);
1213 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1214 || bfd_bwrite ((void *) buf, 8, abfd) != 8)
1215 return FALSE;
1217 switch (cur->type)
1219 case BFD_MACH_O_LC_SEGMENT:
1220 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1221 return FALSE;
1222 break;
1223 case BFD_MACH_O_LC_SEGMENT_64:
1224 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
1225 return FALSE;
1226 break;
1227 case BFD_MACH_O_LC_SYMTAB:
1228 if (!bfd_mach_o_write_symtab (abfd, cur))
1229 return FALSE;
1230 break;
1231 case BFD_MACH_O_LC_SYMSEG:
1232 break;
1233 case BFD_MACH_O_LC_THREAD:
1234 case BFD_MACH_O_LC_UNIXTHREAD:
1235 if (bfd_mach_o_write_thread (abfd, cur) != 0)
1236 return FALSE;
1237 break;
1238 case BFD_MACH_O_LC_LOADFVMLIB:
1239 case BFD_MACH_O_LC_IDFVMLIB:
1240 case BFD_MACH_O_LC_IDENT:
1241 case BFD_MACH_O_LC_FVMFILE:
1242 case BFD_MACH_O_LC_PREPAGE:
1243 case BFD_MACH_O_LC_DYSYMTAB:
1244 case BFD_MACH_O_LC_LOAD_DYLIB:
1245 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1246 case BFD_MACH_O_LC_ID_DYLIB:
1247 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1248 case BFD_MACH_O_LC_LOAD_DYLINKER:
1249 case BFD_MACH_O_LC_ID_DYLINKER:
1250 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1251 case BFD_MACH_O_LC_ROUTINES:
1252 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1253 break;
1254 default:
1255 fprintf (stderr,
1256 "unable to write unknown load command 0x%lx\n",
1257 (unsigned long) cur->type);
1258 return FALSE;
1262 return TRUE;
1265 /* Build Mach-O load commands from the sections. */
1267 bfd_boolean
1268 bfd_mach_o_build_commands (bfd *abfd)
1270 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1271 unsigned int wide = mach_o_wide_p (&mdata->header);
1272 bfd_mach_o_segment_command *seg;
1273 bfd_mach_o_section *sections;
1274 asection *sec;
1275 bfd_mach_o_load_command *cmd;
1276 bfd_mach_o_load_command *symtab_cmd;
1277 int target_index;
1279 /* Return now if commands are already built. */
1280 if (mdata->header.ncmds)
1281 return FALSE;
1283 /* Very simple version: 1 command (segment) containing all sections. */
1284 mdata->header.ncmds = 2;
1285 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1286 * sizeof (bfd_mach_o_load_command));
1287 if (mdata->commands == NULL)
1288 return FALSE;
1289 cmd = &mdata->commands[0];
1290 seg = &cmd->command.segment;
1292 seg->nsects = bfd_count_sections (abfd);
1293 sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1294 if (sections == NULL)
1295 return FALSE;
1296 seg->sections = sections;
1298 /* Set segment command. */
1299 if (wide)
1301 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1302 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1303 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1304 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1306 else
1308 cmd->type = BFD_MACH_O_LC_SEGMENT;
1309 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1310 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1311 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1313 cmd->type_required = FALSE;
1314 mdata->header.sizeofcmds = cmd->len;
1315 mdata->filelen = cmd->offset + cmd->len;
1317 /* Set symtab command. */
1318 symtab_cmd = &mdata->commands[1];
1320 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1321 symtab_cmd->offset = cmd->offset + cmd->len;
1322 symtab_cmd->len = 6 * 4;
1323 symtab_cmd->type_required = FALSE;
1325 mdata->header.sizeofcmds += symtab_cmd->len;
1326 mdata->filelen += symtab_cmd->len;
1328 /* Fill segment command. */
1329 memset (seg->segname, 0, sizeof (seg->segname));
1330 seg->vmaddr = 0;
1331 seg->fileoff = mdata->filelen;
1332 seg->filesize = 0;
1333 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1334 | BFD_MACH_O_PROT_EXECUTE;
1335 seg->initprot = seg->maxprot;
1336 seg->flags = 0;
1338 /* Create Mach-O sections. */
1339 target_index = 0;
1340 for (sec = abfd->sections; sec; sec = sec->next)
1342 sections->bfdsection = sec;
1343 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
1344 sections->addr = bfd_get_section_vma (abfd, sec);
1345 sections->size = bfd_get_section_size (sec);
1346 sections->align = bfd_get_section_alignment (abfd, sec);
1348 if (sections->size != 0)
1350 mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
1351 sections->offset = mdata->filelen;
1353 else
1354 sections->offset = 0;
1355 sections->reloff = 0;
1356 sections->nreloc = 0;
1357 sections->reserved1 = 0;
1358 sections->reserved2 = 0;
1359 sections->reserved3 = 0;
1361 sec->filepos = sections->offset;
1362 sec->target_index = ++target_index;
1364 mdata->filelen += sections->size;
1365 sections++;
1367 seg->filesize = mdata->filelen - seg->fileoff;
1368 seg->vmsize = seg->filesize;
1370 return TRUE;
1373 /* Set the contents of a section. */
1375 bfd_boolean
1376 bfd_mach_o_set_section_contents (bfd *abfd,
1377 asection *section,
1378 const void * location,
1379 file_ptr offset,
1380 bfd_size_type count)
1382 file_ptr pos;
1384 /* This must be done first, because bfd_set_section_contents is
1385 going to set output_has_begun to TRUE. */
1386 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1387 return FALSE;
1389 if (count == 0)
1390 return TRUE;
1392 pos = section->filepos + offset;
1393 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1394 || bfd_bwrite (location, count, abfd) != count)
1395 return FALSE;
1397 return TRUE;
1401 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1402 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1404 return 0;
1407 /* Make an empty symbol. This is required only because
1408 bfd_make_section_anyway wants to create a symbol for the section. */
1410 asymbol *
1411 bfd_mach_o_make_empty_symbol (bfd *abfd)
1413 asymbol *new_symbol;
1415 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1416 if (new_symbol == NULL)
1417 return new_symbol;
1418 new_symbol->the_bfd = abfd;
1419 new_symbol->udata.i = 0;
1420 return new_symbol;
1423 static bfd_boolean
1424 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1426 unsigned char buf[32];
1427 unsigned int size;
1428 bfd_vma (*get32) (const void *) = NULL;
1430 /* Just read the magic number. */
1431 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1432 || bfd_bread ((void *) buf, 4, abfd) != 4)
1433 return FALSE;
1435 if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
1437 header->byteorder = BFD_ENDIAN_BIG;
1438 header->magic = BFD_MACH_O_MH_MAGIC;
1439 header->version = 1;
1440 get32 = bfd_getb32;
1442 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
1444 header->byteorder = BFD_ENDIAN_LITTLE;
1445 header->magic = BFD_MACH_O_MH_MAGIC;
1446 header->version = 1;
1447 get32 = bfd_getl32;
1449 else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1451 header->byteorder = BFD_ENDIAN_BIG;
1452 header->magic = BFD_MACH_O_MH_MAGIC_64;
1453 header->version = 2;
1454 get32 = bfd_getb32;
1456 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1458 header->byteorder = BFD_ENDIAN_LITTLE;
1459 header->magic = BFD_MACH_O_MH_MAGIC_64;
1460 header->version = 2;
1461 get32 = bfd_getl32;
1463 else
1465 header->byteorder = BFD_ENDIAN_UNKNOWN;
1466 return FALSE;
1469 /* Once the size of the header is known, read the full header. */
1470 size = mach_o_wide_p (header) ?
1471 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1473 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1474 || bfd_bread ((void *) buf, size, abfd) != size)
1475 return FALSE;
1477 header->cputype = (*get32) (buf + 4);
1478 header->cpusubtype = (*get32) (buf + 8);
1479 header->filetype = (*get32) (buf + 12);
1480 header->ncmds = (*get32) (buf + 16);
1481 header->sizeofcmds = (*get32) (buf + 20);
1482 header->flags = (*get32) (buf + 24);
1484 if (mach_o_wide_p (header))
1485 header->reserved = (*get32) (buf + 28);
1487 return TRUE;
1490 static asection *
1491 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
1492 unsigned long prot)
1494 asection *bfdsec;
1495 char *sname;
1496 flagword flags;
1498 bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
1499 if (sname == NULL)
1500 return NULL;
1502 if (flags == SEC_NO_FLAGS)
1504 /* Try to guess flags. */
1505 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1506 flags = SEC_DEBUGGING;
1507 else
1509 flags = SEC_ALLOC;
1510 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1511 != BFD_MACH_O_S_ZEROFILL)
1513 flags |= SEC_LOAD;
1514 if (prot & BFD_MACH_O_PROT_EXECUTE)
1515 flags |= SEC_CODE;
1516 if (prot & BFD_MACH_O_PROT_WRITE)
1517 flags |= SEC_DATA;
1518 else if (prot & BFD_MACH_O_PROT_READ)
1519 flags |= SEC_READONLY;
1523 else
1525 if ((flags & SEC_DEBUGGING) == 0)
1526 flags |= SEC_ALLOC;
1529 if (section->offset != 0)
1530 flags |= SEC_HAS_CONTENTS;
1531 if (section->nreloc != 0)
1532 flags |= SEC_RELOC;
1534 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1535 if (bfdsec == NULL)
1536 return NULL;
1538 bfdsec->vma = section->addr;
1539 bfdsec->lma = section->addr;
1540 bfdsec->size = section->size;
1541 bfdsec->filepos = section->offset;
1542 bfdsec->alignment_power = section->align;
1543 bfdsec->segment_mark = 0;
1544 bfdsec->reloc_count = section->nreloc;
1545 bfdsec->rel_filepos = section->reloff;
1547 return bfdsec;
1550 static int
1551 bfd_mach_o_read_section_32 (bfd *abfd,
1552 bfd_mach_o_section *section,
1553 unsigned int offset,
1554 unsigned long prot)
1556 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
1558 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1559 || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
1560 != BFD_MACH_O_SECTION_SIZE))
1561 return -1;
1563 memcpy (section->sectname, buf, 16);
1564 section->sectname[16] = '\0';
1565 memcpy (section->segname, buf + 16, 16);
1566 section->segname[16] = '\0';
1567 section->addr = bfd_h_get_32 (abfd, buf + 32);
1568 section->size = bfd_h_get_32 (abfd, buf + 36);
1569 section->offset = bfd_h_get_32 (abfd, buf + 40);
1570 section->align = bfd_h_get_32 (abfd, buf + 44);
1571 section->reloff = bfd_h_get_32 (abfd, buf + 48);
1572 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
1573 section->flags = bfd_h_get_32 (abfd, buf + 56);
1574 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
1575 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
1576 section->reserved3 = 0;
1577 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1579 if (section->bfdsection == NULL)
1580 return -1;
1582 return 0;
1585 static int
1586 bfd_mach_o_read_section_64 (bfd *abfd,
1587 bfd_mach_o_section *section,
1588 unsigned int offset,
1589 unsigned long prot)
1591 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
1593 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1594 || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
1595 != BFD_MACH_O_SECTION_64_SIZE))
1596 return -1;
1598 memcpy (section->sectname, buf, 16);
1599 section->sectname[16] = '\0';
1600 memcpy (section->segname, buf + 16, 16);
1601 section->segname[16] = '\0';
1602 section->addr = bfd_h_get_64 (abfd, buf + 32);
1603 section->size = bfd_h_get_64 (abfd, buf + 40);
1604 section->offset = bfd_h_get_32 (abfd, buf + 48);
1605 section->align = bfd_h_get_32 (abfd, buf + 52);
1606 section->reloff = bfd_h_get_32 (abfd, buf + 56);
1607 section->nreloc = bfd_h_get_32 (abfd, buf + 60);
1608 section->flags = bfd_h_get_32 (abfd, buf + 64);
1609 section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
1610 section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
1611 section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
1612 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1614 if (section->bfdsection == NULL)
1615 return -1;
1617 return 0;
1620 static int
1621 bfd_mach_o_read_section (bfd *abfd,
1622 bfd_mach_o_section *section,
1623 unsigned int offset,
1624 unsigned long prot,
1625 unsigned int wide)
1627 if (wide)
1628 return bfd_mach_o_read_section_64 (abfd, section, offset, prot);
1629 else
1630 return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
1633 static int
1634 bfd_mach_o_read_symtab_symbol (bfd *abfd,
1635 bfd_mach_o_symtab_command *sym,
1636 bfd_mach_o_asymbol *s,
1637 unsigned long i)
1639 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1640 unsigned int wide = mach_o_wide_p (&mdata->header);
1641 unsigned int symwidth =
1642 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1643 unsigned int symoff = sym->symoff + (i * symwidth);
1644 unsigned char buf[16];
1645 unsigned char type = -1;
1646 unsigned char section = -1;
1647 short desc = -1;
1648 symvalue value = -1;
1649 unsigned long stroff = -1;
1650 unsigned int symtype = -1;
1652 BFD_ASSERT (sym->strtab != NULL);
1654 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1655 || bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
1657 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu\n",
1658 symwidth, (unsigned long) symoff);
1659 return -1;
1662 stroff = bfd_h_get_32 (abfd, buf);
1663 type = bfd_h_get_8 (abfd, buf + 4);
1664 symtype = type & BFD_MACH_O_N_TYPE;
1665 section = bfd_h_get_8 (abfd, buf + 5);
1666 desc = bfd_h_get_16 (abfd, buf + 6);
1667 if (wide)
1668 value = bfd_h_get_64 (abfd, buf + 8);
1669 else
1670 value = bfd_h_get_32 (abfd, buf + 8);
1672 if (stroff >= sym->strsize)
1674 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
1675 (unsigned long) stroff, (unsigned long) sym->strsize);
1676 return -1;
1679 s->symbol.the_bfd = abfd;
1680 s->symbol.name = sym->strtab + stroff;
1681 s->symbol.value = value;
1682 s->symbol.flags = 0x0;
1683 s->symbol.udata.i = 0;
1684 s->n_type = type;
1685 s->n_sect = section;
1686 s->n_desc = desc;
1688 if (type & BFD_MACH_O_N_STAB)
1690 s->symbol.flags |= BSF_DEBUGGING;
1691 s->symbol.section = bfd_und_section_ptr;
1692 switch (type)
1694 case N_FUN:
1695 case N_STSYM:
1696 case N_LCSYM:
1697 case N_BNSYM:
1698 case N_SLINE:
1699 case N_ENSYM:
1700 case N_ECOMM:
1701 case N_ECOML:
1702 case N_GSYM:
1703 if ((section > 0) && (section <= mdata->nsects))
1705 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1706 s->symbol.value =
1707 s->symbol.value - mdata->sections[section - 1]->addr;
1709 break;
1712 else
1714 if (type & BFD_MACH_O_N_PEXT)
1715 s->symbol.flags |= BSF_GLOBAL;
1717 if (type & BFD_MACH_O_N_EXT)
1718 s->symbol.flags |= BSF_GLOBAL;
1720 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1721 s->symbol.flags |= BSF_LOCAL;
1723 switch (symtype)
1725 case BFD_MACH_O_N_UNDF:
1726 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1727 && s->symbol.value != 0)
1729 /* A common symbol. */
1730 s->symbol.section = bfd_com_section_ptr;
1731 s->symbol.flags = BSF_NO_FLAGS;
1733 else
1735 s->symbol.section = bfd_und_section_ptr;
1736 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1737 s->symbol.flags |= BSF_WEAK;
1739 break;
1740 case BFD_MACH_O_N_PBUD:
1741 s->symbol.section = bfd_und_section_ptr;
1742 break;
1743 case BFD_MACH_O_N_ABS:
1744 s->symbol.section = bfd_abs_section_ptr;
1745 break;
1746 case BFD_MACH_O_N_SECT:
1747 if ((section > 0) && (section <= mdata->nsects))
1749 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1750 s->symbol.value =
1751 s->symbol.value - mdata->sections[section - 1]->addr;
1753 else
1755 /* Mach-O uses 0 to mean "no section"; not an error. */
1756 if (section != 0)
1758 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1759 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
1760 s->symbol.name, section, mdata->nsects);
1762 s->symbol.section = bfd_und_section_ptr;
1764 break;
1765 case BFD_MACH_O_N_INDR:
1766 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1767 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
1768 s->symbol.name);
1769 s->symbol.section = bfd_und_section_ptr;
1770 break;
1771 default:
1772 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1773 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
1774 s->symbol.name, symtype);
1775 s->symbol.section = bfd_und_section_ptr;
1776 break;
1780 return 0;
1783 static int
1784 bfd_mach_o_read_symtab_strtab (bfd *abfd)
1786 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1787 bfd_mach_o_symtab_command *sym = mdata->symtab;
1789 /* Fail if there is no symtab. */
1790 if (sym == NULL)
1791 return -1;
1793 /* Success if already loaded. */
1794 if (sym->strtab)
1795 return 0;
1797 if (abfd->flags & BFD_IN_MEMORY)
1799 struct bfd_in_memory *b;
1801 b = (struct bfd_in_memory *) abfd->iostream;
1803 if ((sym->stroff + sym->strsize) > b->size)
1805 bfd_set_error (bfd_error_file_truncated);
1806 return -1;
1808 sym->strtab = (char *) b->buffer + sym->stroff;
1810 else
1812 sym->strtab = bfd_alloc (abfd, sym->strsize);
1813 if (sym->strtab == NULL)
1814 return -1;
1816 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1817 || bfd_bread ((void *) sym->strtab, sym->strsize, abfd) != sym->strsize)
1819 bfd_set_error (bfd_error_file_truncated);
1820 return -1;
1824 return 0;
1827 static int
1828 bfd_mach_o_read_symtab_symbols (bfd *abfd)
1830 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1831 bfd_mach_o_symtab_command *sym = mdata->symtab;
1832 unsigned long i;
1833 int ret;
1835 if (sym->symbols)
1836 return 0;
1838 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1840 if (sym->symbols == NULL)
1842 fprintf (stderr, "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols\n");
1843 return -1;
1846 ret = bfd_mach_o_read_symtab_strtab (abfd);
1847 if (ret != 0)
1848 return ret;
1850 for (i = 0; i < sym->nsyms; i++)
1852 ret = bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1853 if (ret != 0)
1854 return ret;
1857 return 0;
1861 bfd_mach_o_read_dysymtab_symbol (bfd *abfd,
1862 bfd_mach_o_dysymtab_command *dysym,
1863 bfd_mach_o_symtab_command *sym,
1864 bfd_mach_o_asymbol *s,
1865 unsigned long i)
1867 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1868 unsigned long sym_index;
1869 unsigned char buf[4];
1871 BFD_ASSERT (i < dysym->nindirectsyms);
1873 if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
1874 || bfd_bread ((void *) buf, 4, abfd) != 4)
1876 fprintf (stderr, "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
1877 (unsigned long) 4, isymoff);
1878 return -1;
1880 sym_index = bfd_h_get_32 (abfd, buf);
1882 return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
1885 static const char *
1886 bfd_mach_o_i386_flavour_string (unsigned int flavour)
1888 switch ((int) flavour)
1890 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
1891 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
1892 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1893 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
1894 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
1895 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1896 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
1897 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
1898 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
1899 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
1900 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
1901 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
1902 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
1903 default: return "UNKNOWN";
1907 static const char *
1908 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1910 switch ((int) flavour)
1912 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1913 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1914 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1915 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1916 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
1917 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
1918 default: return "UNKNOWN";
1922 static int
1923 bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
1925 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1926 unsigned char buf[4];
1927 unsigned int nameoff;
1929 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1930 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1932 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1933 || bfd_bread ((void *) buf, 4, abfd) != 4)
1934 return -1;
1936 nameoff = bfd_h_get_32 (abfd, buf + 0);
1938 cmd->name_offset = command->offset + nameoff;
1939 cmd->name_len = command->len - nameoff;
1940 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1941 if (cmd->name_str == NULL)
1942 return -1;
1943 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1944 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1945 return -1;
1946 return 0;
1949 static int
1950 bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1952 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1953 unsigned char buf[16];
1954 unsigned int nameoff;
1956 switch (command->type)
1958 case BFD_MACH_O_LC_LOAD_DYLIB:
1959 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1960 case BFD_MACH_O_LC_ID_DYLIB:
1961 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1962 break;
1963 default:
1964 BFD_FAIL ();
1965 return -1;
1968 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1969 || bfd_bread ((void *) buf, 16, abfd) != 16)
1970 return -1;
1972 nameoff = bfd_h_get_32 (abfd, buf + 0);
1973 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1974 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1975 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1977 cmd->name_offset = command->offset + nameoff;
1978 cmd->name_len = command->len - nameoff;
1979 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1980 if (cmd->name_str == NULL)
1981 return -1;
1982 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1983 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1984 return -1;
1985 return 0;
1988 static int
1989 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1990 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1992 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1994 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1995 return 0;
1998 static int
1999 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
2001 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2002 bfd_mach_o_thread_command *cmd = &command->command.thread;
2003 unsigned char buf[8];
2004 unsigned int offset;
2005 unsigned int nflavours;
2006 unsigned int i;
2008 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2009 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2011 /* Count the number of threads. */
2012 offset = 8;
2013 nflavours = 0;
2014 while (offset != command->len)
2016 if (offset >= command->len)
2017 return -1;
2019 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2020 || bfd_bread ((void *) buf, 8, abfd) != 8)
2021 return -1;
2023 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
2024 nflavours++;
2027 /* Allocate threads. */
2028 cmd->flavours = bfd_alloc
2029 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
2030 if (cmd->flavours == NULL)
2031 return -1;
2032 cmd->nflavours = nflavours;
2034 offset = 8;
2035 nflavours = 0;
2036 while (offset != command->len)
2038 if (offset >= command->len)
2039 return -1;
2041 if (nflavours >= cmd->nflavours)
2042 return -1;
2044 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2045 || bfd_bread ((void *) buf, 8, abfd) != 8)
2046 return -1;
2048 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
2049 cmd->flavours[nflavours].offset = command->offset + offset + 8;
2050 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
2051 offset += cmd->flavours[nflavours].size + 8;
2052 nflavours++;
2055 for (i = 0; i < nflavours; i++)
2057 asection *bfdsec;
2058 unsigned int snamelen;
2059 char *sname;
2060 const char *flavourstr;
2061 const char *prefix = "LC_THREAD";
2062 unsigned int j = 0;
2064 switch (mdata->header.cputype)
2066 case BFD_MACH_O_CPU_TYPE_POWERPC:
2067 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
2068 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2069 break;
2070 case BFD_MACH_O_CPU_TYPE_I386:
2071 case BFD_MACH_O_CPU_TYPE_X86_64:
2072 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2073 break;
2074 default:
2075 flavourstr = "UNKNOWN_ARCHITECTURE";
2076 break;
2079 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
2080 sname = bfd_alloc (abfd, snamelen);
2081 if (sname == NULL)
2082 return -1;
2084 for (;;)
2086 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2087 if (bfd_get_section_by_name (abfd, sname) == NULL)
2088 break;
2089 j++;
2092 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
2094 bfdsec->vma = 0;
2095 bfdsec->lma = 0;
2096 bfdsec->size = cmd->flavours[i].size;
2097 bfdsec->filepos = cmd->flavours[i].offset;
2098 bfdsec->alignment_power = 0x0;
2100 cmd->section = bfdsec;
2103 return 0;
2106 static int
2107 bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2109 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2110 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2111 unsigned char buf[72];
2113 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2115 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2116 || bfd_bread ((void *) buf, 72, abfd) != 72)
2117 return -1;
2119 cmd->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
2120 cmd->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
2121 cmd->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
2122 cmd->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
2123 cmd->iundefsym = bfd_h_get_32 (abfd, buf + 16);
2124 cmd->nundefsym = bfd_h_get_32 (abfd, buf + 20);
2125 cmd->tocoff = bfd_h_get_32 (abfd, buf + 24);
2126 cmd->ntoc = bfd_h_get_32 (abfd, buf + 28);
2127 cmd->modtaboff = bfd_h_get_32 (abfd, buf + 32);
2128 cmd->nmodtab = bfd_h_get_32 (abfd, buf + 36);
2129 cmd->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
2130 cmd->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
2131 cmd->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
2132 cmd->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
2133 cmd->extreloff = bfd_h_get_32 (abfd, buf + 56);
2134 cmd->nextrel = bfd_h_get_32 (abfd, buf + 60);
2135 cmd->locreloff = bfd_h_get_32 (abfd, buf + 64);
2136 cmd->nlocrel = bfd_h_get_32 (abfd, buf + 68);
2138 if (cmd->nmodtab != 0)
2140 unsigned int i;
2141 int wide = bfd_mach_o_wide_p (abfd);
2142 unsigned int module_len = wide ? 56 : 52;
2144 cmd->dylib_module =
2145 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2146 if (cmd->dylib_module == NULL)
2147 return -1;
2149 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2150 return -1;
2152 for (i = 0; i < cmd->nmodtab; i++)
2154 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2155 unsigned long v;
2157 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
2158 return -1;
2160 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2161 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2162 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2163 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2164 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2165 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2166 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2167 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2168 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2169 v = bfd_h_get_32 (abfd, buf +36);
2170 module->iinit = v & 0xffff;
2171 module->iterm = (v >> 16) & 0xffff;
2172 v = bfd_h_get_32 (abfd, buf + 40);
2173 module->ninit = v & 0xffff;
2174 module->nterm = (v >> 16) & 0xffff;
2175 if (wide)
2177 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2178 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2180 else
2182 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2183 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2188 if (cmd->ntoc != 0)
2190 unsigned int i;
2192 cmd->dylib_toc = bfd_alloc
2193 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2194 if (cmd->dylib_toc == NULL)
2195 return -1;
2197 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2198 return -1;
2200 for (i = 0; i < cmd->ntoc; i++)
2202 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2204 if (bfd_bread ((void *) buf, 8, abfd) != 8)
2205 return -1;
2207 toc->symbol_index = bfd_h_get_32 (abfd, buf + 0);
2208 toc->module_index = bfd_h_get_32 (abfd, buf + 4);
2212 if (cmd->nindirectsyms != 0)
2214 unsigned int i;
2216 cmd->indirect_syms = bfd_alloc
2217 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2218 if (cmd->indirect_syms == NULL)
2219 return -1;
2221 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2222 return -1;
2224 for (i = 0; i < cmd->nindirectsyms; i++)
2226 unsigned int *is = &cmd->indirect_syms[i];
2228 if (bfd_bread ((void *) buf, 4, abfd) != 4)
2229 return -1;
2231 *is = bfd_h_get_32 (abfd, buf + 0);
2235 if (cmd->nextrefsyms != 0)
2237 unsigned long v;
2238 unsigned int i;
2240 cmd->ext_refs = bfd_alloc
2241 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2242 if (cmd->ext_refs == NULL)
2243 return -1;
2245 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2246 return -1;
2248 for (i = 0; i < cmd->nextrefsyms; i++)
2250 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2252 if (bfd_bread ((void *) buf, 4, abfd) != 4)
2253 return -1;
2255 /* Fields isym and flags are written as bit-fields, thus we need
2256 a specific processing for endianness. */
2257 v = bfd_h_get_32 (abfd, buf + 0);
2258 if (bfd_big_endian (abfd))
2260 ref->isym = (v >> 8) & 0xffffff;
2261 ref->flags = v & 0xff;
2263 else
2265 ref->isym = v & 0xffffff;
2266 ref->flags = (v >> 24) & 0xff;
2271 if (mdata->dysymtab)
2272 return -1;
2273 mdata->dysymtab = cmd;
2275 return 0;
2278 static int
2279 bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
2281 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2282 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2283 unsigned char buf[16];
2285 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2287 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2288 || bfd_bread ((void *) buf, 16, abfd) != 16)
2289 return -1;
2291 symtab->symoff = bfd_h_get_32 (abfd, buf);
2292 symtab->nsyms = bfd_h_get_32 (abfd, buf + 4);
2293 symtab->stroff = bfd_h_get_32 (abfd, buf + 8);
2294 symtab->strsize = bfd_h_get_32 (abfd, buf + 12);
2295 symtab->symbols = NULL;
2296 symtab->strtab = NULL;
2298 if (symtab->nsyms != 0)
2299 abfd->flags |= HAS_SYMS;
2301 if (mdata->symtab)
2302 return -1;
2303 mdata->symtab = symtab;
2304 return 0;
2307 static int
2308 bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
2310 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
2312 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2314 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2315 || bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
2316 return -1;
2318 return 0;
2321 static int
2322 bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
2324 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
2325 char buf[8];
2327 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2328 || bfd_bread ((void *) buf, 8, abfd) != 8)
2329 return -1;
2331 cmd->dataoff = bfd_get_32 (abfd, buf + 0);
2332 cmd->datasize = bfd_get_32 (abfd, buf + 4);
2333 return 0;
2336 static int
2337 bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
2339 bfd_mach_o_str_command *cmd = &command->command.str;
2340 char buf[4];
2341 unsigned long off;
2343 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2344 || bfd_bread ((void *) buf, 4, abfd) != 4)
2345 return -1;
2347 off = bfd_get_32 (abfd, buf + 0);
2348 cmd->stroff = command->offset + off;
2349 cmd->str_len = command->len - off;
2350 cmd->str = bfd_alloc (abfd, cmd->str_len);
2351 if (cmd->str == NULL)
2352 return -1;
2353 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
2354 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
2355 return -1;
2356 return 0;
2359 static int
2360 bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
2362 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
2363 char buf[40];
2365 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2366 || bfd_bread ((void *) buf, sizeof (buf), abfd) != sizeof (buf))
2367 return -1;
2369 cmd->rebase_off = bfd_get_32 (abfd, buf + 0);
2370 cmd->rebase_size = bfd_get_32 (abfd, buf + 4);
2371 cmd->bind_off = bfd_get_32 (abfd, buf + 8);
2372 cmd->bind_size = bfd_get_32 (abfd, buf + 12);
2373 cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16);
2374 cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20);
2375 cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24);
2376 cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28);
2377 cmd->export_off = bfd_get_32 (abfd, buf + 32);
2378 cmd->export_size = bfd_get_32 (abfd, buf + 36);
2379 return 0;
2382 static int
2383 bfd_mach_o_read_segment (bfd *abfd,
2384 bfd_mach_o_load_command *command,
2385 unsigned int wide)
2387 unsigned char buf[64];
2388 bfd_mach_o_segment_command *seg = &command->command.segment;
2389 unsigned long i;
2391 if (wide)
2393 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2395 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2396 || bfd_bread ((void *) buf, 64, abfd) != 64)
2397 return -1;
2399 memcpy (seg->segname, buf, 16);
2400 seg->segname[16] = '\0';
2402 seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
2403 seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
2404 seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
2405 seg->filesize = bfd_h_get_64 (abfd, buf + 40);
2406 seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
2407 seg->initprot = bfd_h_get_32 (abfd, buf + 52);
2408 seg->nsects = bfd_h_get_32 (abfd, buf + 56);
2409 seg->flags = bfd_h_get_32 (abfd, buf + 60);
2411 else
2413 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2415 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2416 || bfd_bread ((void *) buf, 48, abfd) != 48)
2417 return -1;
2419 memcpy (seg->segname, buf, 16);
2420 seg->segname[16] = '\0';
2422 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
2423 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
2424 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
2425 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
2426 seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
2427 seg->initprot = bfd_h_get_32 (abfd, buf + 36);
2428 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
2429 seg->flags = bfd_h_get_32 (abfd, buf + 44);
2432 if (seg->nsects != 0)
2434 seg->sections = bfd_alloc (abfd, seg->nsects
2435 * sizeof (bfd_mach_o_section));
2436 if (seg->sections == NULL)
2437 return -1;
2439 for (i = 0; i < seg->nsects; i++)
2441 bfd_vma segoff;
2442 if (wide)
2443 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2444 + (i * BFD_MACH_O_SECTION_64_SIZE);
2445 else
2446 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2447 + (i * BFD_MACH_O_SECTION_SIZE);
2449 if (bfd_mach_o_read_section
2450 (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
2451 return -1;
2455 return 0;
2458 static int
2459 bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2461 return bfd_mach_o_read_segment (abfd, command, 0);
2464 static int
2465 bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2467 return bfd_mach_o_read_segment (abfd, command, 1);
2470 static int
2471 bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2473 unsigned char buf[8];
2475 /* Read command type and length. */
2476 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2477 || bfd_bread ((void *) buf, 8, abfd) != 8)
2478 return -1;
2480 command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
2481 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
2482 ? TRUE : FALSE);
2483 command->len = bfd_h_get_32 (abfd, buf + 4);
2485 switch (command->type)
2487 case BFD_MACH_O_LC_SEGMENT:
2488 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
2489 return -1;
2490 break;
2491 case BFD_MACH_O_LC_SEGMENT_64:
2492 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
2493 return -1;
2494 break;
2495 case BFD_MACH_O_LC_SYMTAB:
2496 if (bfd_mach_o_read_symtab (abfd, command) != 0)
2497 return -1;
2498 break;
2499 case BFD_MACH_O_LC_SYMSEG:
2500 break;
2501 case BFD_MACH_O_LC_THREAD:
2502 case BFD_MACH_O_LC_UNIXTHREAD:
2503 if (bfd_mach_o_read_thread (abfd, command) != 0)
2504 return -1;
2505 break;
2506 case BFD_MACH_O_LC_LOAD_DYLINKER:
2507 case BFD_MACH_O_LC_ID_DYLINKER:
2508 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
2509 return -1;
2510 break;
2511 case BFD_MACH_O_LC_LOAD_DYLIB:
2512 case BFD_MACH_O_LC_ID_DYLIB:
2513 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2514 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2515 if (bfd_mach_o_read_dylib (abfd, command) != 0)
2516 return -1;
2517 break;
2518 case BFD_MACH_O_LC_PREBOUND_DYLIB:
2519 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
2520 return -1;
2521 break;
2522 case BFD_MACH_O_LC_LOADFVMLIB:
2523 case BFD_MACH_O_LC_IDFVMLIB:
2524 case BFD_MACH_O_LC_IDENT:
2525 case BFD_MACH_O_LC_FVMFILE:
2526 case BFD_MACH_O_LC_PREPAGE:
2527 case BFD_MACH_O_LC_ROUTINES:
2528 break;
2529 case BFD_MACH_O_LC_SUB_FRAMEWORK:
2530 case BFD_MACH_O_LC_SUB_UMBRELLA:
2531 case BFD_MACH_O_LC_SUB_LIBRARY:
2532 case BFD_MACH_O_LC_SUB_CLIENT:
2533 case BFD_MACH_O_LC_RPATH:
2534 if (bfd_mach_o_read_str (abfd, command) != 0)
2535 return -1;
2536 break;
2537 case BFD_MACH_O_LC_DYSYMTAB:
2538 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
2539 return -1;
2540 break;
2541 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2542 case BFD_MACH_O_LC_PREBIND_CKSUM:
2543 break;
2544 case BFD_MACH_O_LC_UUID:
2545 if (bfd_mach_o_read_uuid (abfd, command) != 0)
2546 return -1;
2547 break;
2548 case BFD_MACH_O_LC_CODE_SIGNATURE:
2549 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2550 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
2551 return -1;
2552 break;
2553 case BFD_MACH_O_LC_DYLD_INFO:
2554 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
2555 return -1;
2556 break;
2557 default:
2558 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
2559 (unsigned long) command->type);
2560 break;
2563 return 0;
2566 static void
2567 bfd_mach_o_flatten_sections (bfd *abfd)
2569 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2570 long csect = 0;
2571 unsigned long i, j;
2573 /* Count total number of sections. */
2574 mdata->nsects = 0;
2576 for (i = 0; i < mdata->header.ncmds; i++)
2578 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2579 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2581 bfd_mach_o_segment_command *seg;
2583 seg = &mdata->commands[i].command.segment;
2584 mdata->nsects += seg->nsects;
2588 /* Allocate sections array. */
2589 mdata->sections = bfd_alloc (abfd,
2590 mdata->nsects * sizeof (bfd_mach_o_section *));
2592 /* Fill the array. */
2593 csect = 0;
2595 for (i = 0; i < mdata->header.ncmds; i++)
2597 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2598 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2600 bfd_mach_o_segment_command *seg;
2602 seg = &mdata->commands[i].command.segment;
2603 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2605 for (j = 0; j < seg->nsects; j++)
2606 mdata->sections[csect++] = &seg->sections[j];
2612 bfd_mach_o_scan_start_address (bfd *abfd)
2614 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2615 bfd_mach_o_thread_command *cmd = NULL;
2616 unsigned long i;
2618 for (i = 0; i < mdata->header.ncmds; i++)
2620 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2621 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2623 if (cmd == NULL)
2624 cmd = &mdata->commands[i].command.thread;
2625 else
2626 return 0;
2630 if (cmd == NULL)
2631 return 0;
2633 for (i = 0; i < cmd->nflavours; i++)
2635 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2636 && (cmd->flavours[i].flavour
2637 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2639 unsigned char buf[4];
2641 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2642 || bfd_bread (buf, 4, abfd) != 4)
2643 return -1;
2645 abfd->start_address = bfd_h_get_32 (abfd, buf);
2647 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2648 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2650 unsigned char buf[4];
2652 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2653 || bfd_bread (buf, 4, abfd) != 4)
2654 return -1;
2656 abfd->start_address = bfd_h_get_32 (abfd, buf);
2658 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2659 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
2661 unsigned char buf[8];
2663 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2664 || bfd_bread (buf, 8, abfd) != 8)
2665 return -1;
2667 abfd->start_address = bfd_h_get_64 (abfd, buf);
2669 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2670 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2672 unsigned char buf[8];
2674 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2675 || bfd_bread (buf, 8, abfd) != 8)
2676 return -1;
2678 abfd->start_address = bfd_h_get_64 (abfd, buf);
2682 return 0;
2685 bfd_boolean
2686 bfd_mach_o_set_arch_mach (bfd *abfd,
2687 enum bfd_architecture arch,
2688 unsigned long machine)
2690 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
2692 /* If this isn't the right architecture for this backend, and this
2693 isn't the generic backend, fail. */
2694 if (arch != bed->arch
2695 && arch != bfd_arch_unknown
2696 && bed->arch != bfd_arch_unknown)
2697 return FALSE;
2699 return bfd_default_set_arch_mach (abfd, arch, machine);
2703 bfd_mach_o_scan (bfd *abfd,
2704 bfd_mach_o_header *header,
2705 bfd_mach_o_data_struct *mdata)
2707 unsigned int i;
2708 enum bfd_architecture cputype;
2709 unsigned long cpusubtype;
2710 unsigned int hdrsize;
2712 hdrsize = mach_o_wide_p (header) ?
2713 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2715 mdata->header = *header;
2717 abfd->flags = abfd->flags & BFD_IN_MEMORY;
2718 switch (header->filetype)
2720 case BFD_MACH_O_MH_OBJECT:
2721 abfd->flags |= HAS_RELOC;
2722 break;
2723 case BFD_MACH_O_MH_EXECUTE:
2724 abfd->flags |= EXEC_P;
2725 break;
2726 case BFD_MACH_O_MH_DYLIB:
2727 case BFD_MACH_O_MH_BUNDLE:
2728 abfd->flags |= DYNAMIC;
2729 break;
2732 abfd->tdata.mach_o_data = mdata;
2734 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2735 &cputype, &cpusubtype);
2736 if (cputype == bfd_arch_unknown)
2738 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
2739 header->cputype, header->cpusubtype);
2740 return -1;
2743 bfd_set_arch_mach (abfd, cputype, cpusubtype);
2745 if (header->ncmds != 0)
2747 mdata->commands = bfd_alloc
2748 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2749 if (mdata->commands == NULL)
2750 return -1;
2752 for (i = 0; i < header->ncmds; i++)
2754 bfd_mach_o_load_command *cur = &mdata->commands[i];
2756 if (i == 0)
2757 cur->offset = hdrsize;
2758 else
2760 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2761 cur->offset = prev->offset + prev->len;
2764 if (bfd_mach_o_read_command (abfd, cur) < 0)
2765 return -1;
2769 if (bfd_mach_o_scan_start_address (abfd) < 0)
2770 return -1;
2772 bfd_mach_o_flatten_sections (abfd);
2773 return 0;
2776 bfd_boolean
2777 bfd_mach_o_mkobject_init (bfd *abfd)
2779 bfd_mach_o_data_struct *mdata = NULL;
2781 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2782 if (mdata == NULL)
2783 return FALSE;
2784 abfd->tdata.mach_o_data = mdata;
2786 mdata->header.magic = 0;
2787 mdata->header.cputype = 0;
2788 mdata->header.cpusubtype = 0;
2789 mdata->header.filetype = 0;
2790 mdata->header.ncmds = 0;
2791 mdata->header.sizeofcmds = 0;
2792 mdata->header.flags = 0;
2793 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2794 mdata->commands = NULL;
2795 mdata->nsects = 0;
2796 mdata->sections = NULL;
2798 return TRUE;
2801 static bfd_boolean
2802 bfd_mach_o_gen_mkobject (bfd *abfd)
2804 bfd_mach_o_data_struct *mdata;
2806 if (!bfd_mach_o_mkobject_init (abfd))
2807 return FALSE;
2809 mdata = bfd_mach_o_get_data (abfd);
2810 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
2811 mdata->header.cputype = 0;
2812 mdata->header.cpusubtype = 0;
2813 mdata->header.byteorder = abfd->xvec->byteorder;
2814 mdata->header.version = 1;
2816 return TRUE;
2819 const bfd_target *
2820 bfd_mach_o_header_p (bfd *abfd,
2821 bfd_mach_o_filetype filetype,
2822 bfd_mach_o_cpu_type cputype)
2824 struct bfd_preserve preserve;
2825 bfd_mach_o_header header;
2827 preserve.marker = NULL;
2828 if (!bfd_mach_o_read_header (abfd, &header))
2829 goto wrong;
2831 if (! (header.byteorder == BFD_ENDIAN_BIG
2832 || header.byteorder == BFD_ENDIAN_LITTLE))
2834 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
2835 (unsigned long) header.byteorder);
2836 goto wrong;
2839 if (! ((header.byteorder == BFD_ENDIAN_BIG
2840 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2841 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2842 || (header.byteorder == BFD_ENDIAN_LITTLE
2843 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2844 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2845 goto wrong;
2847 /* Check cputype and filetype.
2848 In case of wildcard, do not accept magics that are handled by existing
2849 targets. */
2850 if (cputype)
2852 if (header.cputype != cputype)
2853 goto wrong;
2855 else
2857 switch (header.cputype)
2859 case BFD_MACH_O_CPU_TYPE_I386:
2860 /* Handled by mach-o-i386 */
2861 goto wrong;
2862 default:
2863 break;
2866 if (filetype)
2868 if (header.filetype != filetype)
2869 goto wrong;
2871 else
2873 switch (header.filetype)
2875 case BFD_MACH_O_MH_CORE:
2876 /* Handled by core_p */
2877 goto wrong;
2878 default:
2879 break;
2883 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2884 if (preserve.marker == NULL
2885 || !bfd_preserve_save (abfd, &preserve))
2886 goto fail;
2888 if (bfd_mach_o_scan (abfd, &header,
2889 (bfd_mach_o_data_struct *) preserve.marker) != 0)
2890 goto wrong;
2892 bfd_preserve_finish (abfd, &preserve);
2893 return abfd->xvec;
2895 wrong:
2896 bfd_set_error (bfd_error_wrong_format);
2898 fail:
2899 if (preserve.marker != NULL)
2900 bfd_preserve_restore (abfd, &preserve);
2901 return NULL;
2904 static const bfd_target *
2905 bfd_mach_o_gen_object_p (bfd *abfd)
2907 return bfd_mach_o_header_p (abfd, 0, 0);
2910 static const bfd_target *
2911 bfd_mach_o_gen_core_p (bfd *abfd)
2913 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
2916 typedef struct mach_o_fat_archentry
2918 unsigned long cputype;
2919 unsigned long cpusubtype;
2920 unsigned long offset;
2921 unsigned long size;
2922 unsigned long align;
2923 } mach_o_fat_archentry;
2925 typedef struct mach_o_fat_data_struct
2927 unsigned long magic;
2928 unsigned long nfat_arch;
2929 mach_o_fat_archentry *archentries;
2930 } mach_o_fat_data_struct;
2932 const bfd_target *
2933 bfd_mach_o_archive_p (bfd *abfd)
2935 mach_o_fat_data_struct *adata = NULL;
2936 unsigned char buf[20];
2937 unsigned long i;
2939 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2940 || bfd_bread ((void *) buf, 8, abfd) != 8)
2941 goto error;
2943 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
2944 if (adata == NULL)
2945 goto error;
2947 adata->magic = bfd_getb32 (buf);
2948 adata->nfat_arch = bfd_getb32 (buf + 4);
2949 if (adata->magic != 0xcafebabe)
2950 goto error;
2951 /* Avoid matching Java bytecode files, which have the same magic number.
2952 In the Java bytecode file format this field contains the JVM version,
2953 which starts at 43.0. */
2954 if (adata->nfat_arch > 30)
2955 goto error;
2957 adata->archentries =
2958 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2959 if (adata->archentries == NULL)
2960 goto error;
2962 for (i = 0; i < adata->nfat_arch; i++)
2964 if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
2965 || bfd_bread ((void *) buf, 20, abfd) != 20)
2966 goto error;
2967 adata->archentries[i].cputype = bfd_getb32 (buf);
2968 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
2969 adata->archentries[i].offset = bfd_getb32 (buf + 8);
2970 adata->archentries[i].size = bfd_getb32 (buf + 12);
2971 adata->archentries[i].align = bfd_getb32 (buf + 16);
2974 abfd->tdata.mach_o_fat_data = adata;
2975 return abfd->xvec;
2977 error:
2978 if (adata != NULL)
2979 bfd_release (abfd, adata);
2980 bfd_set_error (bfd_error_wrong_format);
2981 return NULL;
2984 bfd *
2985 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
2987 mach_o_fat_data_struct *adata;
2988 mach_o_fat_archentry *entry = NULL;
2989 unsigned long i;
2990 bfd *nbfd;
2991 enum bfd_architecture arch_type;
2992 unsigned long arch_subtype;
2994 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
2995 BFD_ASSERT (adata != NULL);
2997 /* Find index of previous entry. */
2998 if (prev == NULL)
2999 i = 0; /* Start at first one. */
3000 else
3002 for (i = 0; i < adata->nfat_arch; i++)
3004 if (adata->archentries[i].offset == prev->origin)
3005 break;
3008 if (i == adata->nfat_arch)
3010 /* Not found. */
3011 bfd_set_error (bfd_error_bad_value);
3012 return NULL;
3014 i++; /* Get next entry. */
3017 if (i >= adata->nfat_arch)
3019 bfd_set_error (bfd_error_no_more_archived_files);
3020 return NULL;
3023 entry = &adata->archentries[i];
3024 nbfd = _bfd_new_bfd_contained_in (archive);
3025 if (nbfd == NULL)
3026 return NULL;
3028 nbfd->origin = entry->offset;
3030 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3031 &arch_type, &arch_subtype);
3032 /* Create the member filename.
3033 Use FILENAME:ARCH_NAME. */
3035 char *s = NULL;
3036 const char *arch_name;
3037 size_t arch_file_len = strlen (bfd_get_filename (archive));
3039 arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
3040 s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
3041 if (s == NULL)
3042 return NULL;
3043 memcpy (s, bfd_get_filename (archive), arch_file_len);
3044 s[arch_file_len] = ':';
3045 strcpy (s + arch_file_len + 1, arch_name);
3046 nbfd->filename = s;
3048 nbfd->iostream = NULL;
3049 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3051 return nbfd;
3054 /* If ABFD format is FORMAT and architecture is ARCH, return it.
3055 If ABFD is a fat image containing a member that corresponds to FORMAT
3056 and ARCH, returns it.
3057 In other case, returns NULL.
3058 This function allows transparent uses of fat images. */
3059 bfd *
3060 bfd_mach_o_fat_extract (bfd *abfd,
3061 bfd_format format,
3062 const bfd_arch_info_type *arch)
3064 bfd *res;
3065 mach_o_fat_data_struct *adata;
3066 unsigned int i;
3068 if (bfd_check_format (abfd, format))
3070 if (bfd_get_arch_info (abfd) == arch)
3071 return abfd;
3072 return NULL;
3074 if (!bfd_check_format (abfd, bfd_archive)
3075 || abfd->xvec != &mach_o_fat_vec)
3076 return NULL;
3078 /* This is a Mach-O fat image. */
3079 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3080 BFD_ASSERT (adata != NULL);
3082 for (i = 0; i < adata->nfat_arch; i++)
3084 struct mach_o_fat_archentry *e = &adata->archentries[i];
3085 enum bfd_architecture cpu_type;
3086 unsigned long cpu_subtype;
3088 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3089 &cpu_type, &cpu_subtype);
3090 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3091 continue;
3093 /* The architecture is found. */
3094 res = _bfd_new_bfd_contained_in (abfd);
3095 if (res == NULL)
3096 return NULL;
3098 res->origin = e->offset;
3100 res->filename = strdup (abfd->filename);
3101 res->iostream = NULL;
3103 if (bfd_check_format (res, format))
3105 BFD_ASSERT (bfd_get_arch_info (res) == arch);
3106 return res;
3108 bfd_close (res);
3109 return NULL;
3112 return NULL;
3116 bfd_mach_o_lookup_section (bfd *abfd,
3117 asection *section,
3118 bfd_mach_o_load_command **mcommand,
3119 bfd_mach_o_section **msection)
3121 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3122 unsigned int i, j, num;
3124 bfd_mach_o_load_command *ncmd = NULL;
3125 bfd_mach_o_section *nsect = NULL;
3127 BFD_ASSERT (mcommand != NULL);
3128 BFD_ASSERT (msection != NULL);
3130 num = 0;
3131 for (i = 0; i < md->header.ncmds; i++)
3133 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3134 struct bfd_mach_o_segment_command *seg = NULL;
3136 if (cmd->type != BFD_MACH_O_LC_SEGMENT
3137 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
3138 continue;
3139 seg = &cmd->command.segment;
3141 for (j = 0; j < seg->nsects; j++)
3143 struct bfd_mach_o_section *sect = &seg->sections[j];
3145 if (sect->bfdsection == section)
3147 if (num == 0)
3149 nsect = sect;
3150 ncmd = cmd;
3152 num++;
3157 *mcommand = ncmd;
3158 *msection = nsect;
3159 return num;
3163 bfd_mach_o_lookup_command (bfd *abfd,
3164 bfd_mach_o_load_command_type type,
3165 bfd_mach_o_load_command **mcommand)
3167 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3168 bfd_mach_o_load_command *ncmd = NULL;
3169 unsigned int i, num;
3171 BFD_ASSERT (md != NULL);
3172 BFD_ASSERT (mcommand != NULL);
3174 num = 0;
3175 for (i = 0; i < md->header.ncmds; i++)
3177 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3179 if (cmd->type != type)
3180 continue;
3182 if (num == 0)
3183 ncmd = cmd;
3184 num++;
3187 *mcommand = ncmd;
3188 return num;
3191 unsigned long
3192 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3194 switch (type)
3196 case BFD_MACH_O_CPU_TYPE_MC680x0:
3197 return 0x04000000;
3198 case BFD_MACH_O_CPU_TYPE_MC88000:
3199 return 0xffffe000;
3200 case BFD_MACH_O_CPU_TYPE_POWERPC:
3201 return 0xc0000000;
3202 case BFD_MACH_O_CPU_TYPE_I386:
3203 return 0xc0000000;
3204 case BFD_MACH_O_CPU_TYPE_SPARC:
3205 return 0xf0000000;
3206 case BFD_MACH_O_CPU_TYPE_I860:
3207 return 0;
3208 case BFD_MACH_O_CPU_TYPE_HPPA:
3209 return 0xc0000000 - 0x04000000;
3210 default:
3211 return 0;
3215 typedef struct bfd_mach_o_xlat_name
3217 const char *name;
3218 unsigned long val;
3220 bfd_mach_o_xlat_name;
3222 static void
3223 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
3224 unsigned long val,
3225 FILE *file)
3227 int first = 1;
3229 for (; table->name; table++)
3231 if (table->val & val)
3233 if (!first)
3234 fprintf (file, "+");
3235 fprintf (file, "%s", table->name);
3236 val &= ~table->val;
3237 first = 0;
3240 if (val)
3242 if (!first)
3243 fprintf (file, "+");
3244 fprintf (file, "0x%lx", val);
3245 return;
3247 if (first)
3248 fprintf (file, "-");
3251 static const char *
3252 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
3254 for (; table->name; table++)
3255 if (table->val == val)
3256 return table->name;
3257 return "*UNKNOWN*";
3260 static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
3262 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
3263 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
3264 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
3265 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
3266 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
3267 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
3268 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
3269 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
3270 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
3271 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
3272 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
3273 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
3274 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
3275 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
3276 { NULL, 0}
3279 static bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
3281 { "object", BFD_MACH_O_MH_OBJECT },
3282 { "execute", BFD_MACH_O_MH_EXECUTE },
3283 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
3284 { "core", BFD_MACH_O_MH_CORE },
3285 { "preload", BFD_MACH_O_MH_PRELOAD },
3286 { "dylib", BFD_MACH_O_MH_DYLIB },
3287 { "dylinker", BFD_MACH_O_MH_DYLINKER },
3288 { "bundle", BFD_MACH_O_MH_BUNDLE },
3289 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
3290 { "dym", BFD_MACH_O_MH_DSYM },
3291 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
3292 { NULL, 0}
3295 static bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
3297 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
3298 { "incrlink", BFD_MACH_O_MH_INCRLINK },
3299 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
3300 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
3301 { "prebound", BFD_MACH_O_MH_PREBOUND },
3302 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
3303 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
3304 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
3305 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
3306 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
3307 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
3308 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
3309 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
3310 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
3311 { "canonical", BFD_MACH_O_MH_CANONICAL },
3312 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
3313 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
3314 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
3315 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
3316 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
3317 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
3318 { "pie", BFD_MACH_O_MH_PIE },
3319 { NULL, 0}
3322 static bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
3324 { "regular", BFD_MACH_O_S_REGULAR},
3325 { "zerofill", BFD_MACH_O_S_ZEROFILL},
3326 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3327 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3328 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3329 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3330 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3331 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3332 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3333 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3334 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3335 { "coalesced", BFD_MACH_O_S_COALESCED},
3336 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3337 { "interposing", BFD_MACH_O_S_INTERPOSING},
3338 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3339 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
3340 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3341 { NULL, 0}
3344 static bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
3346 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3347 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3348 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3349 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3350 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3351 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3352 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3353 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3354 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3355 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
3356 { NULL, 0}
3359 static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
3361 { "segment", BFD_MACH_O_LC_SEGMENT},
3362 { "symtab", BFD_MACH_O_LC_SYMTAB},
3363 { "symseg", BFD_MACH_O_LC_SYMSEG},
3364 { "thread", BFD_MACH_O_LC_THREAD},
3365 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
3366 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
3367 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
3368 { "ident", BFD_MACH_O_LC_IDENT},
3369 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
3370 { "prepage", BFD_MACH_O_LC_PREPAGE},
3371 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
3372 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
3373 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
3374 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
3375 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
3376 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
3377 { "routines", BFD_MACH_O_LC_ROUTINES},
3378 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
3379 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
3380 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
3381 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
3382 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
3383 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
3384 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
3385 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
3386 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
3387 { "uuid", BFD_MACH_O_LC_UUID},
3388 { "rpath", BFD_MACH_O_LC_RPATH},
3389 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
3390 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
3391 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
3392 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
3393 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
3394 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
3395 { NULL, 0}
3398 static void
3399 bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
3401 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3402 bfd_mach_o_header *h = &mdata->header;
3404 fputs (_("Mach-O header:\n"), file);
3405 fprintf (file, _(" magic : %08lx\n"), h->magic);
3406 fprintf (file, _(" cputype : %08lx (%s)\n"), h->cputype,
3407 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
3408 fprintf (file, _(" cpusubtype: %08lx\n"), h->cpusubtype);
3409 fprintf (file, _(" filetype : %08lx (%s)\n"),
3410 h->filetype,
3411 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
3412 fprintf (file, _(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
3413 fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds);
3414 fprintf (file, _(" flags : %08lx ("), h->flags);
3415 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file);
3416 fputs (_(")\n"), file);
3417 fprintf (file, _(" reserved : %08x\n"), h->reserved);
3420 static void
3421 bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
3423 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3424 unsigned int i, j;
3425 unsigned int sec_nbr = 0;
3427 fputs (_("Segments and Sections:\n"), file);
3428 fputs (_(" #: Segment name Section name Address\n"), file);
3430 for (i = 0; i < mdata->header.ncmds; i++)
3432 bfd_mach_o_segment_command *seg;
3434 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
3435 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
3436 continue;
3438 seg = &mdata->commands[i].command.segment;
3440 fprintf (file, "[Segment %-16s ", seg->segname);
3441 fprintf_vma (file, seg->vmaddr);
3442 fprintf (file, "-");
3443 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
3444 fputc (' ', file);
3445 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
3446 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
3447 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
3448 fprintf (file, "]\n");
3449 for (j = 0; j < seg->nsects; j++)
3451 bfd_mach_o_section *sec = &seg->sections[j];
3452 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
3453 sec->segname, sec->sectname);
3454 fprintf_vma (file, sec->addr);
3455 fprintf (file, " ");
3456 fprintf_vma (file, sec->size);
3457 fprintf (file, " %08lx\n", sec->flags);
3462 static void
3463 bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED,
3464 bfd_mach_o_section *sec, FILE *file)
3466 fprintf (file, " Section: %-16s %-16s (bfdname: %s)\n",
3467 sec->sectname, sec->segname, sec->bfdsection->name);
3468 fprintf (file, " addr: ");
3469 fprintf_vma (file, sec->addr);
3470 fprintf (file, " size: ");
3471 fprintf_vma (file, sec->size);
3472 fprintf (file, " offset: ");
3473 fprintf_vma (file, sec->offset);
3474 fprintf (file, "\n");
3475 fprintf (file, " align: %ld", sec->align);
3476 fprintf (file, " nreloc: %lu reloff: ", sec->nreloc);
3477 fprintf_vma (file, sec->reloff);
3478 fprintf (file, "\n");
3479 fprintf (file, " flags: %08lx (type: %s", sec->flags,
3480 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
3481 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
3482 fprintf (file, " attr: ");
3483 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
3484 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
3485 file);
3486 fprintf (file, ")\n");
3487 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3489 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3490 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3491 case BFD_MACH_O_S_SYMBOL_STUBS:
3492 fprintf (file, " first indirect sym: %lu", sec->reserved1);
3493 fprintf (file, " (%u entries)",
3494 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
3495 break;
3496 default:
3497 fprintf (file, " reserved1: 0x%lx", sec->reserved1);
3498 break;
3500 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3502 case BFD_MACH_O_S_SYMBOL_STUBS:
3503 fprintf (file, " stub size: %lu", sec->reserved2);
3504 break;
3505 default:
3506 fprintf (file, " reserved2: 0x%lx", sec->reserved2);
3507 break;
3509 fprintf (file, " reserved3: 0x%lx\n", sec->reserved3);
3512 static void
3513 bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
3514 bfd_mach_o_load_command *cmd, FILE *file)
3516 bfd_mach_o_segment_command *seg = &cmd->command.segment;
3517 unsigned int i;
3519 fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
3520 fprintf (file, " vmaddr: ");
3521 fprintf_vma (file, seg->vmaddr);
3522 fprintf (file, " vmsize: ");
3523 fprintf_vma (file, seg->vmsize);
3524 fprintf (file, "\n");
3525 fprintf (file, " fileoff: ");
3526 fprintf_vma (file, seg->fileoff);
3527 fprintf (file, " filesize: ");
3528 fprintf_vma (file, (bfd_vma)seg->filesize);
3529 fprintf (file, " endoff: ");
3530 fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
3531 fprintf (file, "\n");
3532 fprintf (file, " nsects: %lu ", seg->nsects);
3533 fprintf (file, " flags: %lx\n", seg->flags);
3534 for (i = 0; i < seg->nsects; i++)
3535 bfd_mach_o_print_section (abfd, &seg->sections[i], file);
3538 static void
3539 bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
3540 bfd_mach_o_load_command *cmd, FILE *file)
3542 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
3543 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3544 unsigned int i;
3546 fprintf (file, " local symbols: idx: %10lu num: %-8lu",
3547 dysymtab->ilocalsym, dysymtab->nlocalsym);
3548 fprintf (file, " (nxtidx: %lu)\n",
3549 dysymtab->ilocalsym + dysymtab->nlocalsym);
3550 fprintf (file, " external symbols: idx: %10lu num: %-8lu",
3551 dysymtab->iextdefsym, dysymtab->nextdefsym);
3552 fprintf (file, " (nxtidx: %lu)\n",
3553 dysymtab->iextdefsym + dysymtab->nextdefsym);
3554 fprintf (file, " undefined symbols: idx: %10lu num: %-8lu",
3555 dysymtab->iundefsym, dysymtab->nundefsym);
3556 fprintf (file, " (nxtidx: %lu)\n",
3557 dysymtab->iundefsym + dysymtab->nundefsym);
3558 fprintf (file, " table of content: off: 0x%08lx num: %-8lu",
3559 dysymtab->tocoff, dysymtab->ntoc);
3560 fprintf (file, " (endoff: 0x%08lx)\n",
3561 dysymtab->tocoff
3562 + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
3563 fprintf (file, " module table: off: 0x%08lx num: %-8lu",
3564 dysymtab->modtaboff, dysymtab->nmodtab);
3565 fprintf (file, " (endoff: 0x%08lx)\n",
3566 dysymtab->modtaboff + dysymtab->nmodtab
3567 * (mach_o_wide_p (&mdata->header) ?
3568 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
3569 fprintf (file, " external reference table: off: 0x%08lx num: %-8lu",
3570 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
3571 fprintf (file, " (endoff: 0x%08lx)\n",
3572 dysymtab->extrefsymoff
3573 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
3574 fprintf (file, " indirect symbol table: off: 0x%08lx num: %-8lu",
3575 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
3576 fprintf (file, " (endoff: 0x%08lx)\n",
3577 dysymtab->indirectsymoff
3578 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
3579 fprintf (file, " external relocation table: off: 0x%08lx num: %-8lu",
3580 dysymtab->extreloff, dysymtab->nextrel);
3581 fprintf (file, " (endoff: 0x%08lx)\n",
3582 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
3583 fprintf (file, " local relocation table: off: 0x%08lx num: %-8lu",
3584 dysymtab->locreloff, dysymtab->nlocrel);
3585 fprintf (file, " (endoff: 0x%08lx)\n",
3586 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
3588 if (dysymtab->ntoc > 0
3589 || dysymtab->nindirectsyms > 0
3590 || dysymtab->nextrefsyms > 0)
3592 /* Try to read the symbols to display the toc or indirect symbols. */
3593 bfd_mach_o_read_symtab_symbols (abfd);
3595 else if (dysymtab->nmodtab > 0)
3597 /* Try to read the strtab to display modules name. */
3598 bfd_mach_o_read_symtab_strtab (abfd);
3601 for (i = 0; i < dysymtab->nmodtab; i++)
3603 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
3604 fprintf (file, " module %u:\n", i);
3605 fprintf (file, " name: %lu", module->module_name_idx);
3606 if (mdata->symtab && mdata->symtab->strtab)
3607 fprintf (file, ": %s",
3608 mdata->symtab->strtab + module->module_name_idx);
3609 fprintf (file, "\n");
3610 fprintf (file, " extdefsym: idx: %8lu num: %lu\n",
3611 module->iextdefsym, module->nextdefsym);
3612 fprintf (file, " refsym: idx: %8lu num: %lu\n",
3613 module->irefsym, module->nrefsym);
3614 fprintf (file, " localsym: idx: %8lu num: %lu\n",
3615 module->ilocalsym, module->nlocalsym);
3616 fprintf (file, " extrel: idx: %8lu num: %lu\n",
3617 module->iextrel, module->nextrel);
3618 fprintf (file, " init: idx: %8u num: %u\n",
3619 module->iinit, module->ninit);
3620 fprintf (file, " term: idx: %8u num: %u\n",
3621 module->iterm, module->nterm);
3622 fprintf (file, " objc_module_info: addr: ");
3623 fprintf_vma (file, module->objc_module_info_addr);
3624 fprintf (file, " size: %lu\n", module->objc_module_info_size);
3627 if (dysymtab->ntoc > 0)
3629 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3631 fprintf (file, " table of content: (symbol/module)\n");
3632 for (i = 0; i < dysymtab->ntoc; i++)
3634 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
3636 fprintf (file, " %4u: ", i);
3637 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
3639 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
3640 fprintf (file, "%s (%lu)", name ? name : "*invalid*",
3641 toc->symbol_index);
3643 else
3644 fprintf (file, "%lu", toc->symbol_index);
3646 fprintf (file, " / ");
3647 if (symtab && symtab->strtab
3648 && toc->module_index < dysymtab->nmodtab)
3650 bfd_mach_o_dylib_module *mod;
3651 mod = &dysymtab->dylib_module[toc->module_index];
3652 fprintf (file, "%s (%lu)",
3653 symtab->strtab + mod->module_name_idx,
3654 toc->module_index);
3656 else
3657 fprintf (file, "%lu", toc->module_index);
3659 fprintf (file, "\n");
3663 if (dysymtab->nindirectsyms != 0)
3665 fprintf (file, " indirect symbols:\n");
3667 for (i = 0; i < mdata->nsects; i++)
3669 bfd_mach_o_section *sec = mdata->sections[i];
3670 unsigned int j, first, last;
3671 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3672 bfd_vma addr;
3673 bfd_vma entry_size;
3675 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3677 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3678 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3679 case BFD_MACH_O_S_SYMBOL_STUBS:
3680 first = sec->reserved1;
3681 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
3682 addr = sec->addr;
3683 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
3684 fprintf (file, " for section %s.%s:\n",
3685 sec->segname, sec->sectname);
3686 for (j = first; j < last; j++)
3688 unsigned int isym = dysymtab->indirect_syms[j];
3690 fprintf (file, " ");
3691 fprintf_vma (file, addr);
3692 fprintf (file, " %5u: 0x%08x", j, isym);
3693 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
3694 fprintf (file, " LOCAL");
3695 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
3696 fprintf (file, " ABSOLUTE");
3697 if (symtab && symtab->symbols
3698 && isym < symtab->nsyms
3699 && symtab->symbols[isym].symbol.name)
3700 fprintf (file, " %s", symtab->symbols[isym].symbol.name);
3701 fprintf (file, "\n");
3702 addr += entry_size;
3704 break;
3705 default:
3706 break;
3710 if (dysymtab->nextrefsyms > 0)
3712 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3714 fprintf (file, " external reference table: (symbol flags)\n");
3715 for (i = 0; i < dysymtab->nextrefsyms; i++)
3717 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
3719 fprintf (file, " %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
3720 if (symtab && symtab->symbols
3721 && ref->isym < symtab->nsyms
3722 && symtab->symbols[ref->isym].symbol.name)
3723 fprintf (file, " %s", symtab->symbols[ref->isym].symbol.name);
3724 fprintf (file, "\n");
3730 static void
3731 bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED,
3732 bfd_mach_o_load_command *cmd, FILE *file)
3734 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
3736 fprintf (file, " rebase: off: 0x%08x size: %-8u\n",
3737 info->rebase_off, info->rebase_size);
3738 fprintf (file, " bind: off: 0x%08x size: %-8u\n",
3739 info->bind_off, info->bind_size);
3740 fprintf (file, " weak bind: off: 0x%08x size: %-8u\n",
3741 info->weak_bind_off, info->weak_bind_size);
3742 fprintf (file, " lazy bind: off: 0x%08x size: %-8u\n",
3743 info->lazy_bind_off, info->lazy_bind_size);
3744 fprintf (file, " export: off: 0x%08x size: %-8u\n",
3745 info->export_off, info->export_size);
3748 bfd_boolean
3749 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
3751 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3752 FILE *file = (FILE *) ptr;
3753 unsigned int i;
3755 bfd_mach_o_print_private_header (abfd, file);
3756 fputc ('\n', file);
3758 for (i = 0; i < mdata->header.ncmds; i++)
3760 bfd_mach_o_load_command *cmd = &mdata->commands[i];
3762 fprintf (file, "Load command %s:",
3763 bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
3764 switch (cmd->type)
3766 case BFD_MACH_O_LC_SEGMENT:
3767 case BFD_MACH_O_LC_SEGMENT_64:
3768 bfd_mach_o_print_segment (abfd, cmd, file);
3769 break;
3770 case BFD_MACH_O_LC_UUID:
3772 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
3773 unsigned int j;
3775 for (j = 0; j < sizeof (uuid->uuid); j ++)
3776 fprintf (file, " %02x", uuid->uuid[j]);
3777 fputc ('\n', file);
3779 break;
3780 case BFD_MACH_O_LC_LOAD_DYLIB:
3781 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
3782 case BFD_MACH_O_LC_REEXPORT_DYLIB:
3783 case BFD_MACH_O_LC_ID_DYLIB:
3785 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
3786 fprintf (file, " %s\n", dylib->name_str);
3787 fprintf (file, " time stamp: 0x%08lx\n",
3788 dylib->timestamp);
3789 fprintf (file, " current version: 0x%08lx\n",
3790 dylib->current_version);
3791 fprintf (file, " comptibility version: 0x%08lx\n",
3792 dylib->compatibility_version);
3793 break;
3795 case BFD_MACH_O_LC_LOAD_DYLINKER:
3796 case BFD_MACH_O_LC_ID_DYLINKER:
3797 fprintf (file, " %s\n", cmd->command.dylinker.name_str);
3798 break;
3799 case BFD_MACH_O_LC_SYMTAB:
3801 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
3802 fprintf (file,
3803 "\n"
3804 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
3805 symtab->symoff, symtab->nsyms,
3806 symtab->symoff + symtab->nsyms
3807 * (mach_o_wide_p (&mdata->header)
3808 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
3809 fprintf (file,
3810 " stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
3811 symtab->stroff, symtab->strsize,
3812 symtab->stroff + symtab->strsize);
3813 break;
3815 case BFD_MACH_O_LC_DYSYMTAB:
3816 fprintf (file, "\n");
3817 bfd_mach_o_print_dysymtab (abfd, cmd, file);
3818 break;
3819 case BFD_MACH_O_LC_CODE_SIGNATURE:
3820 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
3822 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
3823 fprintf
3824 (file, "\n"
3825 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
3826 linkedit->dataoff, linkedit->datasize,
3827 linkedit->dataoff + linkedit->datasize);
3828 break;
3830 case BFD_MACH_O_LC_SUB_FRAMEWORK:
3831 case BFD_MACH_O_LC_SUB_UMBRELLA:
3832 case BFD_MACH_O_LC_SUB_LIBRARY:
3833 case BFD_MACH_O_LC_SUB_CLIENT:
3834 case BFD_MACH_O_LC_RPATH:
3836 bfd_mach_o_str_command *str = &cmd->command.str;
3837 fprintf (file, " %s\n", str->str);
3838 break;
3840 case BFD_MACH_O_LC_THREAD:
3841 case BFD_MACH_O_LC_UNIXTHREAD:
3843 bfd_mach_o_thread_command *thread = &cmd->command.thread;
3844 unsigned int j;
3845 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3847 fprintf (file, " nflavours: %lu\n", thread->nflavours);
3848 for (j = 0; j < thread->nflavours; j++)
3850 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
3852 fprintf (file, " %2u: flavour: 0x%08lx offset: 0x%08lx"
3853 " size: 0x%08lx\n",
3854 j, flavour->flavour, flavour->offset,
3855 flavour->size);
3856 if (bed->_bfd_mach_o_print_thread)
3858 char *buf = bfd_malloc (flavour->size);
3860 if (buf
3861 && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
3862 && (bfd_bread (buf, flavour->size, abfd)
3863 == flavour->size))
3864 (*bed->_bfd_mach_o_print_thread)(abfd, flavour,
3865 file, buf);
3866 free (buf);
3869 break;
3871 case BFD_MACH_O_LC_DYLD_INFO:
3872 fprintf (file, "\n");
3873 bfd_mach_o_print_dyld_info (abfd, cmd, file);
3874 break;
3875 default:
3876 fprintf (file, "\n");
3877 break;
3879 fputc ('\n', file);
3882 bfd_mach_o_print_section_map (abfd, file);
3884 return TRUE;
3888 bfd_mach_o_core_fetch_environment (bfd *abfd,
3889 unsigned char **rbuf,
3890 unsigned int *rlen)
3892 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3893 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
3894 unsigned int i = 0;
3896 for (i = 0; i < mdata->header.ncmds; i++)
3898 bfd_mach_o_load_command *cur = &mdata->commands[i];
3899 bfd_mach_o_segment_command *seg = NULL;
3901 if (cur->type != BFD_MACH_O_LC_SEGMENT)
3902 continue;
3904 seg = &cur->command.segment;
3906 if ((seg->vmaddr + seg->vmsize) == stackaddr)
3908 unsigned long start = seg->fileoff;
3909 unsigned long end = seg->fileoff + seg->filesize;
3910 unsigned char *buf = bfd_malloc (1024);
3911 unsigned long size = 1024;
3913 for (;;)
3915 bfd_size_type nread = 0;
3916 unsigned long offset;
3917 int found_nonnull = 0;
3919 if (size > (end - start))
3920 size = (end - start);
3922 buf = bfd_realloc_or_free (buf, size);
3923 if (buf == NULL)
3924 return -1;
3926 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
3928 free (buf);
3929 return -1;
3932 nread = bfd_bread (buf, size, abfd);
3934 if (nread != size)
3936 free (buf);
3937 return -1;
3940 for (offset = 4; offset <= size; offset += 4)
3942 unsigned long val;
3944 val = *((unsigned long *) (buf + size - offset));
3945 if (! found_nonnull)
3947 if (val != 0)
3948 found_nonnull = 1;
3950 else if (val == 0x0)
3952 unsigned long bottom;
3953 unsigned long top;
3955 bottom = seg->fileoff + seg->filesize - offset;
3956 top = seg->fileoff + seg->filesize - 4;
3957 *rbuf = bfd_malloc (top - bottom);
3958 *rlen = top - bottom;
3960 memcpy (*rbuf, buf + size - *rlen, *rlen);
3961 free (buf);
3962 return 0;
3966 if (size == (end - start))
3967 break;
3969 size *= 2;
3972 free (buf);
3976 return -1;
3979 char *
3980 bfd_mach_o_core_file_failing_command (bfd *abfd)
3982 unsigned char *buf = NULL;
3983 unsigned int len = 0;
3984 int ret = -1;
3986 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
3987 if (ret < 0)
3988 return NULL;
3990 return (char *) buf;
3994 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3996 return 0;
3999 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
4000 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4002 #define bfd_mach_o_swap_reloc_in NULL
4003 #define bfd_mach_o_swap_reloc_out NULL
4004 #define bfd_mach_o_print_thread NULL
4006 #define TARGET_NAME mach_o_be_vec
4007 #define TARGET_STRING "mach-o-be"
4008 #define TARGET_ARCHITECTURE bfd_arch_unknown
4009 #define TARGET_BIG_ENDIAN 1
4010 #define TARGET_ARCHIVE 0
4011 #include "mach-o-target.c"
4013 #undef TARGET_NAME
4014 #undef TARGET_STRING
4015 #undef TARGET_ARCHITECTURE
4016 #undef TARGET_BIG_ENDIAN
4017 #undef TARGET_ARCHIVE
4019 #define TARGET_NAME mach_o_le_vec
4020 #define TARGET_STRING "mach-o-le"
4021 #define TARGET_ARCHITECTURE bfd_arch_unknown
4022 #define TARGET_BIG_ENDIAN 0
4023 #define TARGET_ARCHIVE 0
4025 #include "mach-o-target.c"
4027 #undef TARGET_NAME
4028 #undef TARGET_STRING
4029 #undef TARGET_ARCHITECTURE
4030 #undef TARGET_BIG_ENDIAN
4031 #undef TARGET_ARCHIVE
4033 /* Not yet handled: creating an archive. */
4034 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4036 /* Not used. */
4037 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4038 #define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4039 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4040 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4041 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4042 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4043 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4044 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
4045 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
4046 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4048 #define TARGET_NAME mach_o_fat_vec
4049 #define TARGET_STRING "mach-o-fat"
4050 #define TARGET_ARCHITECTURE bfd_arch_unknown
4051 #define TARGET_BIG_ENDIAN 1
4052 #define TARGET_ARCHIVE 1
4054 #include "mach-o-target.c"
4056 #undef TARGET_NAME
4057 #undef TARGET_STRING
4058 #undef TARGET_ARCHITECTURE
4059 #undef TARGET_BIG_ENDIAN
4060 #undef TARGET_ARCHIVE