bfd/
[binutils.git] / bfd / mach-o.c
blob5973df790657d304a2411756c630c5ee26674f28
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 2009, 2010, 2011
4 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #include "sysdep.h"
24 #include "mach-o.h"
25 #include "bfd.h"
26 #include "libbfd.h"
27 #include "libiberty.h"
28 #include "aout/stab_gnu.h"
29 #include "mach-o/reloc.h"
30 #include "mach-o/external.h"
31 #include <ctype.h>
33 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p
34 #define bfd_mach_o_core_p bfd_mach_o_gen_core_p
35 #define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
37 #define FILE_ALIGN(off, algn) \
38 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
40 static int bfd_mach_o_read_symtab_symbols (bfd *);
42 unsigned int
43 bfd_mach_o_version (bfd *abfd)
45 bfd_mach_o_data_struct *mdata = NULL;
47 BFD_ASSERT (bfd_mach_o_valid (abfd));
48 mdata = bfd_mach_o_get_data (abfd);
50 return mdata->header.version;
53 bfd_boolean
54 bfd_mach_o_valid (bfd *abfd)
56 if (abfd == NULL || abfd->xvec == NULL)
57 return FALSE;
59 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
60 return FALSE;
62 if (bfd_mach_o_get_data (abfd) == NULL)
63 return FALSE;
64 return TRUE;
67 static INLINE bfd_boolean
68 mach_o_wide_p (bfd_mach_o_header *header)
70 switch (header->version)
72 case 1:
73 return FALSE;
74 case 2:
75 return TRUE;
76 default:
77 BFD_FAIL ();
78 return FALSE;
82 static INLINE bfd_boolean
83 bfd_mach_o_wide_p (bfd *abfd)
85 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
88 /* Tables to translate well known Mach-O segment/section names to bfd
89 names. Use of canonical names (such as .text or .debug_frame) is required
90 by gdb. */
92 struct mach_o_section_name_xlat
94 const char *bfd_name;
95 const char *mach_o_name;
96 flagword flags;
99 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
101 { ".debug_frame", "__debug_frame", SEC_DEBUGGING },
102 { ".debug_info", "__debug_info", SEC_DEBUGGING },
103 { ".debug_abbrev", "__debug_abbrev", SEC_DEBUGGING },
104 { ".debug_aranges", "__debug_aranges", SEC_DEBUGGING },
105 { ".debug_macinfo", "__debug_macinfo", SEC_DEBUGGING },
106 { ".debug_line", "__debug_line", SEC_DEBUGGING },
107 { ".debug_loc", "__debug_loc", SEC_DEBUGGING },
108 { ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING },
109 { ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING },
110 { ".debug_str", "__debug_str", SEC_DEBUGGING },
111 { ".debug_ranges", "__debug_ranges", SEC_DEBUGGING },
112 { NULL, NULL, 0}
115 static const struct mach_o_section_name_xlat text_section_names_xlat[] =
117 { ".text", "__text", SEC_CODE | SEC_LOAD },
118 { ".const", "__const", SEC_READONLY | SEC_DATA | SEC_LOAD },
119 { ".cstring", "__cstring", SEC_READONLY | SEC_DATA | SEC_LOAD },
120 { ".eh_frame", "__eh_frame", SEC_READONLY | SEC_LOAD },
121 { NULL, NULL, 0}
124 static const struct mach_o_section_name_xlat data_section_names_xlat[] =
126 { ".data", "__data", SEC_DATA | SEC_LOAD },
127 { ".const_data", "__const", SEC_DATA | SEC_LOAD },
128 { ".dyld", "__dyld", SEC_DATA | SEC_LOAD },
129 { ".lazy_symbol_ptr", "__la_symbol_ptr", SEC_DATA | SEC_LOAD },
130 { ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD },
131 { ".bss", "__bss", SEC_NO_FLAGS },
132 { NULL, NULL, 0}
135 struct mach_o_segment_name_xlat
137 const char *segname;
138 const struct mach_o_section_name_xlat *sections;
141 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
143 { "__DWARF", dwarf_section_names_xlat },
144 { "__TEXT", text_section_names_xlat },
145 { "__DATA", data_section_names_xlat },
146 { NULL, NULL }
149 /* Mach-O to bfd names. */
151 void
152 bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
153 const char **name, flagword *flags)
155 const struct mach_o_segment_name_xlat *seg;
157 *name = NULL;
158 *flags = SEC_NO_FLAGS;
160 for (seg = segsec_names_xlat; seg->segname; seg++)
162 if (strcmp (seg->segname, segname) == 0)
164 const struct mach_o_section_name_xlat *sec;
166 for (sec = seg->sections; sec->mach_o_name; sec++)
168 if (strcmp (sec->mach_o_name, sectname) == 0)
170 *name = sec->bfd_name;
171 *flags = sec->flags;
172 return;
175 return;
180 static void
181 bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
182 const char **name, flagword *flags)
184 char *res;
185 unsigned int len;
186 const char *pfx = "";
188 /* First search for a canonical name. */
189 bfd_mach_o_normalize_section_name (section->segname, section->sectname,
190 name, flags);
192 /* Return now if found. */
193 if (*name)
194 return;
196 len = strlen (section->segname) + 1
197 + strlen (section->sectname) + 1;
199 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
200 with an underscore. */
201 if (section->segname[0] != '_')
203 static const char seg_pfx[] = "LC_SEGMENT.";
205 pfx = seg_pfx;
206 len += sizeof (seg_pfx) - 1;
209 res = bfd_alloc (abfd, len);
210 if (res == NULL)
211 return;
212 snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
213 *name = res;
214 *flags = SEC_NO_FLAGS;
217 /* Convert a bfd section name to a Mach-O segment + section name. */
219 static void
220 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
221 asection *sect,
222 bfd_mach_o_section *section)
224 const struct mach_o_segment_name_xlat *seg;
225 const char *name = bfd_get_section_name (abfd, sect);
226 const char *dot;
227 unsigned int len;
228 unsigned int seglen;
229 unsigned int seclen;
231 /* List of well known names. They all start with a dot. */
232 if (name[0] == '.')
233 for (seg = segsec_names_xlat; seg->segname; seg++)
235 const struct mach_o_section_name_xlat *sec;
237 for (sec = seg->sections; sec->mach_o_name; sec++)
239 if (strcmp (sec->bfd_name, name) == 0)
241 strcpy (section->segname, seg->segname);
242 strcpy (section->sectname, sec->mach_o_name);
243 return;
248 /* Strip LC_SEGMENT. prefix. */
249 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
250 name += 11;
252 /* Find a dot. */
253 dot = strchr (name, '.');
254 len = strlen (name);
256 /* Try to split name into segment and section names. */
257 if (dot && dot != name)
259 seglen = dot - name;
260 seclen = len - (dot + 1 - name);
262 if (seglen < 16 && seclen < 16)
264 memcpy (section->segname, name, seglen);
265 section->segname[seglen] = 0;
266 memcpy (section->sectname, dot + 1, seclen);
267 section->sectname[seclen] = 0;
268 return;
272 if (len > 16)
273 len = 16;
274 memcpy (section->segname, name, len);
275 section->segname[len] = 0;
276 memcpy (section->sectname, name, len);
277 section->sectname[len] = 0;
280 /* Return the size of an entry for section SEC.
281 Must be called only for symbol pointer section and symbol stubs
282 sections. */
284 static unsigned int
285 bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
287 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
289 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
290 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
291 return bfd_mach_o_wide_p (abfd) ? 8 : 4;
292 case BFD_MACH_O_S_SYMBOL_STUBS:
293 return sec->reserved2;
294 default:
295 BFD_FAIL ();
296 return 0;
300 /* Return the number of indirect symbols for a section.
301 Must be called only for symbol pointer section and symbol stubs
302 sections. */
304 static unsigned int
305 bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
307 unsigned int elsz;
309 elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
310 if (elsz == 0)
311 return 0;
312 else
313 return sec->size / elsz;
317 /* Copy any private info we understand from the input symbol
318 to the output symbol. */
320 bfd_boolean
321 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
322 asymbol *isymbol ATTRIBUTE_UNUSED,
323 bfd *obfd ATTRIBUTE_UNUSED,
324 asymbol *osymbol ATTRIBUTE_UNUSED)
326 return TRUE;
329 /* Copy any private info we understand from the input section
330 to the output section. */
332 bfd_boolean
333 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
334 asection *isection ATTRIBUTE_UNUSED,
335 bfd *obfd ATTRIBUTE_UNUSED,
336 asection *osection ATTRIBUTE_UNUSED)
338 return TRUE;
341 /* Copy any private info we understand from the input bfd
342 to the output bfd. */
344 bfd_boolean
345 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
347 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
348 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
349 return TRUE;
351 BFD_ASSERT (bfd_mach_o_valid (ibfd));
352 BFD_ASSERT (bfd_mach_o_valid (obfd));
354 /* FIXME: copy commands. */
356 return TRUE;
359 /* Count the total number of symbols. */
361 static long
362 bfd_mach_o_count_symbols (bfd *abfd)
364 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
366 if (mdata->symtab == NULL)
367 return 0;
368 return mdata->symtab->nsyms;
371 long
372 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
374 long nsyms = bfd_mach_o_count_symbols (abfd);
376 return ((nsyms + 1) * sizeof (asymbol *));
379 long
380 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
382 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
383 long nsyms = bfd_mach_o_count_symbols (abfd);
384 bfd_mach_o_symtab_command *sym = mdata->symtab;
385 unsigned long j;
387 if (nsyms < 0)
388 return nsyms;
390 if (nsyms == 0)
392 /* Do not try to read symbols if there are none. */
393 alocation[0] = NULL;
394 return 0;
397 if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
399 (*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
400 return 0;
403 BFD_ASSERT (sym->symbols != NULL);
405 for (j = 0; j < sym->nsyms; j++)
406 alocation[j] = &sym->symbols[j].symbol;
408 alocation[j] = NULL;
410 return nsyms;
413 long
414 bfd_mach_o_get_synthetic_symtab (bfd *abfd,
415 long symcount ATTRIBUTE_UNUSED,
416 asymbol **syms ATTRIBUTE_UNUSED,
417 long dynsymcount ATTRIBUTE_UNUSED,
418 asymbol **dynsyms ATTRIBUTE_UNUSED,
419 asymbol **ret)
421 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
422 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
423 bfd_mach_o_symtab_command *symtab = mdata->symtab;
424 asymbol *s;
425 unsigned long count, i, j, n;
426 size_t size;
427 char *names;
428 char *nul_name;
430 *ret = NULL;
432 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
433 return 0;
435 if (dysymtab->nindirectsyms == 0)
436 return 0;
438 count = dysymtab->nindirectsyms;
439 size = count * sizeof (asymbol) + 1;
441 for (j = 0; j < count; j++)
443 unsigned int isym = dysymtab->indirect_syms[j];
445 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
446 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
449 s = *ret = (asymbol *) bfd_malloc (size);
450 if (s == NULL)
451 return -1;
452 names = (char *) (s + count);
453 nul_name = names;
454 *names++ = 0;
456 n = 0;
457 for (i = 0; i < mdata->nsects; i++)
459 bfd_mach_o_section *sec = mdata->sections[i];
460 unsigned int first, last;
461 bfd_vma addr;
462 bfd_vma entry_size;
464 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
466 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
467 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
468 case BFD_MACH_O_S_SYMBOL_STUBS:
469 first = sec->reserved1;
470 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
471 addr = sec->addr;
472 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
473 for (j = first; j < last; j++)
475 unsigned int isym = dysymtab->indirect_syms[j];
477 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
478 s->section = sec->bfdsection;
479 s->value = addr - sec->addr;
480 s->udata.p = NULL;
482 if (isym < symtab->nsyms
483 && symtab->symbols[isym].symbol.name)
485 const char *sym = symtab->symbols[isym].symbol.name;
486 size_t len;
488 s->name = names;
489 len = strlen (sym);
490 memcpy (names, sym, len);
491 names += len;
492 memcpy (names, "$stub", sizeof ("$stub"));
493 names += sizeof ("$stub");
495 else
496 s->name = nul_name;
498 addr += entry_size;
499 s++;
500 n++;
502 break;
503 default:
504 break;
508 return n;
511 void
512 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
513 asymbol *symbol,
514 symbol_info *ret)
516 bfd_symbol_info (symbol, ret);
519 void
520 bfd_mach_o_print_symbol (bfd *abfd,
521 void * afile,
522 asymbol *symbol,
523 bfd_print_symbol_type how)
525 FILE *file = (FILE *) afile;
526 const char *name;
527 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
529 switch (how)
531 case bfd_print_symbol_name:
532 fprintf (file, "%s", symbol->name);
533 break;
534 default:
535 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
536 if (asym->n_type & BFD_MACH_O_N_STAB)
537 name = bfd_get_stab_name (asym->n_type);
538 else
539 switch (asym->n_type & BFD_MACH_O_N_TYPE)
541 case BFD_MACH_O_N_UNDF:
542 name = "UND";
543 break;
544 case BFD_MACH_O_N_ABS:
545 name = "ABS";
546 break;
547 case BFD_MACH_O_N_INDR:
548 name = "INDR";
549 break;
550 case BFD_MACH_O_N_PBUD:
551 name = "PBUD";
552 break;
553 case BFD_MACH_O_N_SECT:
554 name = "SECT";
555 break;
556 default:
557 name = "???";
558 break;
560 if (name == NULL)
561 name = "";
562 fprintf (file, " %02x %-6s %02x %04x",
563 asym->n_type, name, asym->n_sect, asym->n_desc);
564 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
565 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
566 fprintf (file, " %-5s", symbol->section->name);
567 fprintf (file, " %s", symbol->name);
571 static void
572 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
573 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
574 enum bfd_architecture *type,
575 unsigned long *subtype)
577 *subtype = bfd_arch_unknown;
579 switch (mtype)
581 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
582 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
583 case BFD_MACH_O_CPU_TYPE_I386:
584 *type = bfd_arch_i386;
585 *subtype = bfd_mach_i386_i386;
586 break;
587 case BFD_MACH_O_CPU_TYPE_X86_64:
588 *type = bfd_arch_i386;
589 *subtype = bfd_mach_x86_64;
590 break;
591 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
592 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
593 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
594 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
595 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
596 case BFD_MACH_O_CPU_TYPE_SPARC:
597 *type = bfd_arch_sparc;
598 *subtype = bfd_mach_sparc;
599 break;
600 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
601 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
602 case BFD_MACH_O_CPU_TYPE_POWERPC:
603 *type = bfd_arch_powerpc;
604 *subtype = bfd_mach_ppc;
605 break;
606 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
607 *type = bfd_arch_powerpc;
608 *subtype = bfd_mach_ppc64;
609 break;
610 default:
611 *type = bfd_arch_unknown;
612 break;
616 static bfd_boolean
617 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
619 struct mach_o_header_external raw;
620 unsigned int size;
622 size = mach_o_wide_p (header) ?
623 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
625 bfd_h_put_32 (abfd, header->magic, raw.magic);
626 bfd_h_put_32 (abfd, header->cputype, raw.cputype);
627 bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
628 bfd_h_put_32 (abfd, header->filetype, raw.filetype);
629 bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
630 bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
631 bfd_h_put_32 (abfd, header->flags, raw.flags);
633 if (mach_o_wide_p (header))
634 bfd_h_put_32 (abfd, header->reserved, raw.reserved);
636 if (bfd_seek (abfd, 0, SEEK_SET) != 0
637 || bfd_bwrite (&raw, size, abfd) != size)
638 return FALSE;
640 return TRUE;
643 static int
644 bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
646 bfd_mach_o_thread_command *cmd = &command->command.thread;
647 unsigned int i;
648 struct mach_o_thread_command_external raw;
649 unsigned int offset;
651 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
652 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
654 offset = 8;
655 for (i = 0; i < cmd->nflavours; i++)
657 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
658 BFD_ASSERT (cmd->flavours[i].offset ==
659 (command->offset + offset + BFD_MACH_O_LC_SIZE));
661 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
662 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
664 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
665 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
666 return -1;
668 offset += cmd->flavours[i].size + sizeof (raw);
671 return 0;
674 long
675 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
676 asection *asect)
678 return (asect->reloc_count + 1) * sizeof (arelent *);
681 static int
682 bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
683 struct mach_o_reloc_info_external *raw,
684 arelent *res, asymbol **syms)
686 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
687 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
688 bfd_mach_o_reloc_info reloc;
689 bfd_vma addr;
690 bfd_vma symnum;
691 asymbol **sym;
693 addr = bfd_get_32 (abfd, raw->r_address);
694 symnum = bfd_get_32 (abfd, raw->r_symbolnum);
696 if (addr & BFD_MACH_O_SR_SCATTERED)
698 unsigned int j;
700 /* Scattered relocation.
701 Extract section and offset from r_value. */
702 res->sym_ptr_ptr = NULL;
703 res->addend = 0;
704 for (j = 0; j < mdata->nsects; j++)
706 bfd_mach_o_section *sect = mdata->sections[j];
707 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
709 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
710 res->addend = symnum - sect->addr;
711 break;
714 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
715 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
716 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
717 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
718 reloc.r_scattered = 1;
720 else
722 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
723 res->addend = 0;
724 res->address = addr;
725 if (symnum & BFD_MACH_O_R_EXTERN)
727 sym = syms + num;
728 reloc.r_extern = 1;
730 else
732 BFD_ASSERT (num != 0);
733 BFD_ASSERT (num <= mdata->nsects);
734 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
735 /* For a symbol defined in section S, the addend (stored in the
736 binary) contains the address of the section. To comply with
737 bfd conventio, substract the section address.
738 Use the address from the header, so that the user can modify
739 the vma of the section. */
740 res->addend = -mdata->sections[num - 1]->addr;
741 reloc.r_extern = 0;
743 res->sym_ptr_ptr = sym;
744 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
745 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
746 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
747 reloc.r_scattered = 0;
750 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
751 return -1;
752 return 0;
755 static int
756 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
757 unsigned long count,
758 arelent *res, asymbol **syms)
760 unsigned long i;
761 struct mach_o_reloc_info_external *native_relocs;
762 bfd_size_type native_size;
764 /* Allocate and read relocs. */
765 native_size = count * BFD_MACH_O_RELENT_SIZE;
766 native_relocs =
767 (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
768 if (native_relocs == NULL)
769 return -1;
771 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
772 || bfd_bread (native_relocs, native_size, abfd) != native_size)
773 goto err;
775 for (i = 0; i < count; i++)
777 if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
778 &res[i], syms) < 0)
779 goto err;
781 free (native_relocs);
782 return i;
783 err:
784 free (native_relocs);
785 return -1;
788 long
789 bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
790 arelent **rels, asymbol **syms)
792 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
793 unsigned long i;
794 arelent *res;
796 if (asect->reloc_count == 0)
797 return 0;
799 /* No need to go further if we don't know how to read relocs. */
800 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
801 return 0;
803 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
804 if (res == NULL)
805 return -1;
807 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
808 asect->reloc_count, res, syms) < 0)
810 free (res);
811 return -1;
814 for (i = 0; i < asect->reloc_count; i++)
815 rels[i] = &res[i];
816 rels[i] = NULL;
817 asect->relocation = res;
819 return i;
822 long
823 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
825 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
827 if (mdata->dysymtab == NULL)
828 return 1;
829 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
830 * sizeof (arelent *);
833 long
834 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
835 struct bfd_symbol **syms)
837 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
838 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
839 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
840 unsigned long i;
841 arelent *res;
843 if (dysymtab == NULL)
844 return 0;
845 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
846 return 0;
848 /* No need to go further if we don't know how to read relocs. */
849 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
850 return 0;
852 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
853 if (res == NULL)
854 return -1;
856 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
857 dysymtab->nextrel, res, syms) < 0)
859 free (res);
860 return -1;
863 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
864 dysymtab->nlocrel,
865 res + dysymtab->nextrel, syms) < 0)
867 free (res);
868 return -1;
871 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
872 rels[i] = &res[i];
873 rels[i] = NULL;
874 return i;
877 static bfd_boolean
878 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
880 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
881 unsigned int i;
882 arelent **entries;
883 asection *sec;
884 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
886 sec = section->bfdsection;
887 if (sec->reloc_count == 0)
888 return TRUE;
890 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
891 return TRUE;
893 /* Allocate relocation room. */
894 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
895 section->nreloc = sec->reloc_count;
896 sec->rel_filepos = mdata->filelen;
897 section->reloff = sec->rel_filepos;
898 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
900 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
901 return FALSE;
903 /* Convert and write. */
904 entries = section->bfdsection->orelocation;
905 for (i = 0; i < section->nreloc; i++)
907 arelent *rel = entries[i];
908 struct mach_o_reloc_info_external raw;
909 bfd_mach_o_reloc_info info, *pinfo = &info;
911 /* Convert relocation to an intermediate representation. */
912 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
913 return FALSE;
915 /* Lower the relocation info. */
916 if (pinfo->r_scattered)
918 unsigned long v;
920 v = BFD_MACH_O_SR_SCATTERED
921 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
922 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
923 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
924 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
925 /* Note: scattered relocs have field in reverse order... */
926 bfd_put_32 (abfd, v, raw.r_address);
927 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
929 else
931 unsigned long v;
933 bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
934 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
935 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
936 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
937 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
938 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
939 bfd_put_32 (abfd, v, raw.r_symbolnum);
942 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
943 != BFD_MACH_O_RELENT_SIZE)
944 return FALSE;
946 return TRUE;
949 static int
950 bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
952 struct mach_o_section_32_external raw;
954 memcpy (raw.sectname, section->sectname, 16);
955 memcpy (raw.segname + 16, section->segname, 16);
956 bfd_h_put_32 (abfd, section->addr, raw.addr);
957 bfd_h_put_32 (abfd, section->size, raw.size);
958 bfd_h_put_32 (abfd, section->offset, raw.offset);
959 bfd_h_put_32 (abfd, section->align, raw.align);
960 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
961 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
962 bfd_h_put_32 (abfd, section->flags, raw.flags);
963 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
964 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
966 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
967 != BFD_MACH_O_SECTION_SIZE)
968 return -1;
970 return 0;
973 static int
974 bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
976 struct mach_o_section_64_external raw;
978 memcpy (raw.sectname, section->sectname, 16);
979 memcpy (raw.segname, section->segname, 16);
980 bfd_h_put_64 (abfd, section->addr, raw.addr);
981 bfd_h_put_64 (abfd, section->size, raw.size);
982 bfd_h_put_32 (abfd, section->offset, raw.offset);
983 bfd_h_put_32 (abfd, section->align, raw.align);
984 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
985 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
986 bfd_h_put_32 (abfd, section->flags, raw.flags);
987 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
988 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
989 bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
991 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
992 != BFD_MACH_O_SECTION_64_SIZE)
993 return -1;
995 return 0;
998 static int
999 bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1001 struct mach_o_segment_command_32_external raw;
1002 bfd_mach_o_segment_command *seg = &command->command.segment;
1003 unsigned long i;
1005 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1007 for (i = 0; i < seg->nsects; i++)
1008 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
1009 return -1;
1011 memcpy (raw.segname, seg->segname, 16);
1012 bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1013 bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1014 bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1015 bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1016 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1017 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1018 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1019 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1021 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1022 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1023 return -1;
1025 for (i = 0; i < seg->nsects; i++)
1026 if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
1027 return -1;
1029 return 0;
1032 static int
1033 bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1035 struct mach_o_segment_command_64_external raw;
1036 bfd_mach_o_segment_command *seg = &command->command.segment;
1037 unsigned long i;
1039 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1041 for (i = 0; i < seg->nsects; i++)
1042 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
1043 return -1;
1045 memcpy (raw.segname, seg->segname, 16);
1046 bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1047 bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1048 bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1049 bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1050 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1051 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1052 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1053 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1055 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1056 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1057 return -1;
1059 for (i = 0; i < seg->nsects; i++)
1060 if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
1061 return -1;
1063 return 0;
1066 static bfd_boolean
1067 bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1069 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1070 bfd_mach_o_symtab_command *sym = &command->command.symtab;
1071 unsigned long i;
1072 unsigned int wide = bfd_mach_o_wide_p (abfd);
1073 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1074 struct bfd_strtab_hash *strtab;
1075 asymbol **symbols = bfd_get_outsymbols (abfd);
1077 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1079 /* Write the symbols first. */
1080 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1081 sym->symoff = mdata->filelen;
1082 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1083 return FALSE;
1085 sym->nsyms = bfd_get_symcount (abfd);
1086 mdata->filelen += sym->nsyms * symlen;
1088 strtab = _bfd_stringtab_init ();
1089 if (strtab == NULL)
1090 return FALSE;
1092 for (i = 0; i < sym->nsyms; i++)
1094 bfd_size_type str_index;
1095 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1097 /* Compute name index. */
1098 /* An index of 0 always means the empty string. */
1099 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
1100 str_index = 0;
1101 else
1103 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1104 if (str_index == (bfd_size_type) -1)
1105 goto err;
1108 if (wide)
1110 struct mach_o_nlist_64_external raw;
1112 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1113 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1114 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1115 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1116 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1117 raw.n_value);
1119 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1120 goto err;
1122 else
1124 struct mach_o_nlist_external raw;
1126 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1127 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1128 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1129 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1130 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1131 raw.n_value);
1133 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1134 goto err;
1137 sym->strsize = _bfd_stringtab_size (strtab);
1138 sym->stroff = mdata->filelen;
1139 mdata->filelen += sym->strsize;
1141 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1142 goto err;
1143 _bfd_stringtab_free (strtab);
1145 /* The command. */
1147 struct mach_o_symtab_command_external raw;
1149 bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1150 bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1151 bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1152 bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1154 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1155 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1156 return FALSE;
1159 return TRUE;
1161 err:
1162 _bfd_stringtab_free (strtab);
1163 return FALSE;
1166 /* Process the symbols and generate Mach-O specific fields.
1167 Number them. */
1169 static bfd_boolean
1170 bfd_mach_o_mangle_symbols (bfd *abfd)
1172 unsigned long i;
1173 asymbol **symbols = bfd_get_outsymbols (abfd);
1175 for (i = 0; i < bfd_get_symcount (abfd); i++)
1177 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1179 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1181 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1182 symbols should be N_UNDEF | N_EXT), we suppose the back-end
1183 values haven't been set. */
1184 if (s->symbol.section == bfd_abs_section_ptr)
1185 s->n_type = BFD_MACH_O_N_ABS;
1186 else if (s->symbol.section == bfd_und_section_ptr)
1188 s->n_type = BFD_MACH_O_N_UNDF;
1189 if (s->symbol.flags & BSF_WEAK)
1190 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1192 else if (s->symbol.section == bfd_com_section_ptr)
1193 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1194 else
1195 s->n_type = BFD_MACH_O_N_SECT;
1197 if (s->symbol.flags & BSF_GLOBAL)
1198 s->n_type |= BFD_MACH_O_N_EXT;
1201 /* Compute section index. */
1202 if (s->symbol.section != bfd_abs_section_ptr
1203 && s->symbol.section != bfd_und_section_ptr
1204 && s->symbol.section != bfd_com_section_ptr)
1205 s->n_sect = s->symbol.section->target_index;
1207 /* Number symbols. */
1208 s->symbol.udata.i = i;
1210 return TRUE;
1213 bfd_boolean
1214 bfd_mach_o_write_contents (bfd *abfd)
1216 unsigned int i;
1217 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1219 if (mdata->header.ncmds == 0)
1220 if (!bfd_mach_o_build_commands (abfd))
1221 return FALSE;
1223 /* Now write header information. */
1224 if (mdata->header.filetype == 0)
1226 if (abfd->flags & EXEC_P)
1227 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1228 else if (abfd->flags & DYNAMIC)
1229 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1230 else
1231 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1233 if (!bfd_mach_o_write_header (abfd, &mdata->header))
1234 return FALSE;
1236 /* Assign a number to each symbols. */
1237 if (!bfd_mach_o_mangle_symbols (abfd))
1238 return FALSE;
1240 for (i = 0; i < mdata->header.ncmds; i++)
1242 struct mach_o_load_command_external raw;
1243 bfd_mach_o_load_command *cur = &mdata->commands[i];
1244 unsigned long typeflag;
1246 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
1248 bfd_h_put_32 (abfd, typeflag, raw.cmd);
1249 bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
1251 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1252 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
1253 return FALSE;
1255 switch (cur->type)
1257 case BFD_MACH_O_LC_SEGMENT:
1258 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1259 return FALSE;
1260 break;
1261 case BFD_MACH_O_LC_SEGMENT_64:
1262 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
1263 return FALSE;
1264 break;
1265 case BFD_MACH_O_LC_SYMTAB:
1266 if (!bfd_mach_o_write_symtab (abfd, cur))
1267 return FALSE;
1268 break;
1269 case BFD_MACH_O_LC_SYMSEG:
1270 break;
1271 case BFD_MACH_O_LC_THREAD:
1272 case BFD_MACH_O_LC_UNIXTHREAD:
1273 if (bfd_mach_o_write_thread (abfd, cur) != 0)
1274 return FALSE;
1275 break;
1276 case BFD_MACH_O_LC_LOADFVMLIB:
1277 case BFD_MACH_O_LC_IDFVMLIB:
1278 case BFD_MACH_O_LC_IDENT:
1279 case BFD_MACH_O_LC_FVMFILE:
1280 case BFD_MACH_O_LC_PREPAGE:
1281 case BFD_MACH_O_LC_DYSYMTAB:
1282 case BFD_MACH_O_LC_LOAD_DYLIB:
1283 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1284 case BFD_MACH_O_LC_ID_DYLIB:
1285 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1286 case BFD_MACH_O_LC_LOAD_DYLINKER:
1287 case BFD_MACH_O_LC_ID_DYLINKER:
1288 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1289 case BFD_MACH_O_LC_ROUTINES:
1290 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1291 break;
1292 default:
1293 (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1294 (unsigned long) cur->type);
1295 return FALSE;
1299 return TRUE;
1302 /* Build Mach-O load commands from the sections. */
1304 bfd_boolean
1305 bfd_mach_o_build_commands (bfd *abfd)
1307 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1308 unsigned int wide = mach_o_wide_p (&mdata->header);
1309 bfd_mach_o_segment_command *seg;
1310 bfd_mach_o_section *sections;
1311 asection *sec;
1312 bfd_mach_o_load_command *cmd;
1313 bfd_mach_o_load_command *symtab_cmd;
1314 int target_index;
1316 /* Return now if commands are already built. */
1317 if (mdata->header.ncmds)
1318 return FALSE;
1320 /* Very simple version: 1 command (segment) containing all sections. */
1321 mdata->header.ncmds = 2;
1322 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1323 * sizeof (bfd_mach_o_load_command));
1324 if (mdata->commands == NULL)
1325 return FALSE;
1326 cmd = &mdata->commands[0];
1327 seg = &cmd->command.segment;
1329 seg->nsects = bfd_count_sections (abfd);
1330 sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1331 if (sections == NULL)
1332 return FALSE;
1333 seg->sections = sections;
1335 /* Set segment command. */
1336 if (wide)
1338 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1339 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1340 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1341 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1343 else
1345 cmd->type = BFD_MACH_O_LC_SEGMENT;
1346 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1347 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1348 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1350 cmd->type_required = FALSE;
1351 mdata->header.sizeofcmds = cmd->len;
1352 mdata->filelen = cmd->offset + cmd->len;
1354 /* Set symtab command. */
1355 symtab_cmd = &mdata->commands[1];
1357 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1358 symtab_cmd->offset = cmd->offset + cmd->len;
1359 symtab_cmd->len = 6 * 4;
1360 symtab_cmd->type_required = FALSE;
1362 mdata->header.sizeofcmds += symtab_cmd->len;
1363 mdata->filelen += symtab_cmd->len;
1365 /* Fill segment command. */
1366 memset (seg->segname, 0, sizeof (seg->segname));
1367 seg->vmaddr = 0;
1368 seg->fileoff = mdata->filelen;
1369 seg->filesize = 0;
1370 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1371 | BFD_MACH_O_PROT_EXECUTE;
1372 seg->initprot = seg->maxprot;
1373 seg->flags = 0;
1375 /* Create Mach-O sections. */
1376 target_index = 0;
1377 for (sec = abfd->sections; sec; sec = sec->next)
1379 sections->bfdsection = sec;
1380 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
1381 sections->addr = bfd_get_section_vma (abfd, sec);
1382 sections->size = bfd_get_section_size (sec);
1383 sections->align = bfd_get_section_alignment (abfd, sec);
1385 if (sections->size != 0)
1387 mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
1388 sections->offset = mdata->filelen;
1390 else
1391 sections->offset = 0;
1392 sections->reloff = 0;
1393 sections->nreloc = 0;
1394 sections->reserved1 = 0;
1395 sections->reserved2 = 0;
1396 sections->reserved3 = 0;
1398 sec->filepos = sections->offset;
1399 sec->target_index = ++target_index;
1401 mdata->filelen += sections->size;
1402 sections++;
1404 seg->filesize = mdata->filelen - seg->fileoff;
1405 seg->vmsize = seg->filesize;
1407 return TRUE;
1410 /* Set the contents of a section. */
1412 bfd_boolean
1413 bfd_mach_o_set_section_contents (bfd *abfd,
1414 asection *section,
1415 const void * location,
1416 file_ptr offset,
1417 bfd_size_type count)
1419 file_ptr pos;
1421 /* This must be done first, because bfd_set_section_contents is
1422 going to set output_has_begun to TRUE. */
1423 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1424 return FALSE;
1426 if (count == 0)
1427 return TRUE;
1429 pos = section->filepos + offset;
1430 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1431 || bfd_bwrite (location, count, abfd) != count)
1432 return FALSE;
1434 return TRUE;
1438 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1439 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1441 return 0;
1444 /* Make an empty symbol. This is required only because
1445 bfd_make_section_anyway wants to create a symbol for the section. */
1447 asymbol *
1448 bfd_mach_o_make_empty_symbol (bfd *abfd)
1450 asymbol *new_symbol;
1452 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1453 if (new_symbol == NULL)
1454 return new_symbol;
1455 new_symbol->the_bfd = abfd;
1456 new_symbol->udata.i = 0;
1457 return new_symbol;
1460 static bfd_boolean
1461 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1463 struct mach_o_header_external raw;
1464 unsigned int size;
1465 bfd_vma (*get32) (const void *) = NULL;
1467 /* Just read the magic number. */
1468 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1469 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
1470 return FALSE;
1472 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
1474 header->byteorder = BFD_ENDIAN_BIG;
1475 header->magic = BFD_MACH_O_MH_MAGIC;
1476 header->version = 1;
1477 get32 = bfd_getb32;
1479 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
1481 header->byteorder = BFD_ENDIAN_LITTLE;
1482 header->magic = BFD_MACH_O_MH_MAGIC;
1483 header->version = 1;
1484 get32 = bfd_getl32;
1486 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1488 header->byteorder = BFD_ENDIAN_BIG;
1489 header->magic = BFD_MACH_O_MH_MAGIC_64;
1490 header->version = 2;
1491 get32 = bfd_getb32;
1493 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1495 header->byteorder = BFD_ENDIAN_LITTLE;
1496 header->magic = BFD_MACH_O_MH_MAGIC_64;
1497 header->version = 2;
1498 get32 = bfd_getl32;
1500 else
1502 header->byteorder = BFD_ENDIAN_UNKNOWN;
1503 return FALSE;
1506 /* Once the size of the header is known, read the full header. */
1507 size = mach_o_wide_p (header) ?
1508 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1510 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1511 || bfd_bread (&raw, size, abfd) != size)
1512 return FALSE;
1514 header->cputype = (*get32) (raw.cputype);
1515 header->cpusubtype = (*get32) (raw.cpusubtype);
1516 header->filetype = (*get32) (raw.filetype);
1517 header->ncmds = (*get32) (raw.ncmds);
1518 header->sizeofcmds = (*get32) (raw.sizeofcmds);
1519 header->flags = (*get32) (raw.flags);
1521 if (mach_o_wide_p (header))
1522 header->reserved = (*get32) (raw.reserved);
1524 return TRUE;
1527 static asection *
1528 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
1529 unsigned long prot)
1531 asection *bfdsec;
1532 const char *sname;
1533 flagword flags;
1535 bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
1536 if (sname == NULL)
1537 return NULL;
1539 if (flags == SEC_NO_FLAGS)
1541 /* Try to guess flags. */
1542 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1543 flags = SEC_DEBUGGING;
1544 else
1546 flags = SEC_ALLOC;
1547 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1548 != BFD_MACH_O_S_ZEROFILL)
1550 flags |= SEC_LOAD;
1551 if (prot & BFD_MACH_O_PROT_EXECUTE)
1552 flags |= SEC_CODE;
1553 if (prot & BFD_MACH_O_PROT_WRITE)
1554 flags |= SEC_DATA;
1555 else if (prot & BFD_MACH_O_PROT_READ)
1556 flags |= SEC_READONLY;
1560 else
1562 if ((flags & SEC_DEBUGGING) == 0)
1563 flags |= SEC_ALLOC;
1566 if (section->offset != 0)
1567 flags |= SEC_HAS_CONTENTS;
1568 if (section->nreloc != 0)
1569 flags |= SEC_RELOC;
1571 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1572 if (bfdsec == NULL)
1573 return NULL;
1575 bfdsec->vma = section->addr;
1576 bfdsec->lma = section->addr;
1577 bfdsec->size = section->size;
1578 bfdsec->filepos = section->offset;
1579 bfdsec->alignment_power = section->align;
1580 bfdsec->segment_mark = 0;
1581 bfdsec->reloc_count = section->nreloc;
1582 bfdsec->rel_filepos = section->reloff;
1584 return bfdsec;
1587 static int
1588 bfd_mach_o_read_section_32 (bfd *abfd,
1589 bfd_mach_o_section *section,
1590 unsigned int offset,
1591 unsigned long prot)
1593 struct mach_o_section_32_external raw;
1595 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1596 || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
1597 != BFD_MACH_O_SECTION_SIZE))
1598 return -1;
1600 memcpy (section->sectname, raw.sectname, 16);
1601 section->sectname[16] = '\0';
1602 memcpy (section->segname, raw.segname, 16);
1603 section->segname[16] = '\0';
1604 section->addr = bfd_h_get_32 (abfd, raw.addr);
1605 section->size = bfd_h_get_32 (abfd, raw.size);
1606 section->offset = bfd_h_get_32 (abfd, raw.offset);
1607 section->align = bfd_h_get_32 (abfd, raw.align);
1608 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1609 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1610 section->flags = bfd_h_get_32 (abfd, raw.flags);
1611 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1612 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1613 section->reserved3 = 0;
1614 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1616 if (section->bfdsection == NULL)
1617 return -1;
1619 return 0;
1622 static int
1623 bfd_mach_o_read_section_64 (bfd *abfd,
1624 bfd_mach_o_section *section,
1625 unsigned int offset,
1626 unsigned long prot)
1628 struct mach_o_section_64_external raw;
1630 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1631 || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
1632 != BFD_MACH_O_SECTION_64_SIZE))
1633 return -1;
1635 memcpy (section->sectname, raw.sectname, 16);
1636 section->sectname[16] = '\0';
1637 memcpy (section->segname, raw.segname, 16);
1638 section->segname[16] = '\0';
1639 section->addr = bfd_h_get_64 (abfd, raw.addr);
1640 section->size = bfd_h_get_64 (abfd, raw.size);
1641 section->offset = bfd_h_get_32 (abfd, raw.offset);
1642 section->align = bfd_h_get_32 (abfd, raw.align);
1643 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1644 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1645 section->flags = bfd_h_get_32 (abfd, raw.flags);
1646 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1647 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1648 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
1649 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1651 if (section->bfdsection == NULL)
1652 return -1;
1654 return 0;
1657 static int
1658 bfd_mach_o_read_section (bfd *abfd,
1659 bfd_mach_o_section *section,
1660 unsigned int offset,
1661 unsigned long prot,
1662 unsigned int wide)
1664 if (wide)
1665 return bfd_mach_o_read_section_64 (abfd, section, offset, prot);
1666 else
1667 return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
1670 static int
1671 bfd_mach_o_read_symtab_symbol (bfd *abfd,
1672 bfd_mach_o_symtab_command *sym,
1673 bfd_mach_o_asymbol *s,
1674 unsigned long i)
1676 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1677 unsigned int wide = mach_o_wide_p (&mdata->header);
1678 unsigned int symwidth =
1679 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1680 unsigned int symoff = sym->symoff + (i * symwidth);
1681 struct mach_o_nlist_64_external raw;
1682 unsigned char type = -1;
1683 unsigned char section = -1;
1684 short desc = -1;
1685 symvalue value = -1;
1686 unsigned long stroff = -1;
1687 unsigned int symtype = -1;
1689 BFD_ASSERT (sym->strtab != NULL);
1691 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1692 || bfd_bread (&raw, symwidth, abfd) != symwidth)
1694 (*_bfd_error_handler)
1695 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
1696 symwidth, (unsigned long) symoff);
1697 return -1;
1700 stroff = bfd_h_get_32 (abfd, raw.n_strx);
1701 type = bfd_h_get_8 (abfd, raw.n_type);
1702 symtype = type & BFD_MACH_O_N_TYPE;
1703 section = bfd_h_get_8 (abfd, raw.n_sect);
1704 desc = bfd_h_get_16 (abfd, raw.n_desc);
1705 if (wide)
1706 value = bfd_h_get_64 (abfd, raw.n_value);
1707 else
1708 value = bfd_h_get_32 (abfd, raw.n_value);
1710 if (stroff >= sym->strsize)
1712 (*_bfd_error_handler)
1713 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
1714 (unsigned long) stroff,
1715 (unsigned long) sym->strsize);
1716 return -1;
1719 s->symbol.the_bfd = abfd;
1720 s->symbol.name = sym->strtab + stroff;
1721 s->symbol.value = value;
1722 s->symbol.flags = 0x0;
1723 s->symbol.udata.i = 0;
1724 s->n_type = type;
1725 s->n_sect = section;
1726 s->n_desc = desc;
1728 if (type & BFD_MACH_O_N_STAB)
1730 s->symbol.flags |= BSF_DEBUGGING;
1731 s->symbol.section = bfd_und_section_ptr;
1732 switch (type)
1734 case N_FUN:
1735 case N_STSYM:
1736 case N_LCSYM:
1737 case N_BNSYM:
1738 case N_SLINE:
1739 case N_ENSYM:
1740 case N_ECOMM:
1741 case N_ECOML:
1742 case N_GSYM:
1743 if ((section > 0) && (section <= mdata->nsects))
1745 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1746 s->symbol.value =
1747 s->symbol.value - mdata->sections[section - 1]->addr;
1749 break;
1752 else
1754 if (type & BFD_MACH_O_N_PEXT)
1755 s->symbol.flags |= BSF_GLOBAL;
1757 if (type & BFD_MACH_O_N_EXT)
1758 s->symbol.flags |= BSF_GLOBAL;
1760 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1761 s->symbol.flags |= BSF_LOCAL;
1763 switch (symtype)
1765 case BFD_MACH_O_N_UNDF:
1766 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1767 && s->symbol.value != 0)
1769 /* A common symbol. */
1770 s->symbol.section = bfd_com_section_ptr;
1771 s->symbol.flags = BSF_NO_FLAGS;
1773 else
1775 s->symbol.section = bfd_und_section_ptr;
1776 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1777 s->symbol.flags |= BSF_WEAK;
1779 break;
1780 case BFD_MACH_O_N_PBUD:
1781 s->symbol.section = bfd_und_section_ptr;
1782 break;
1783 case BFD_MACH_O_N_ABS:
1784 s->symbol.section = bfd_abs_section_ptr;
1785 break;
1786 case BFD_MACH_O_N_SECT:
1787 if ((section > 0) && (section <= mdata->nsects))
1789 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1790 s->symbol.value =
1791 s->symbol.value - mdata->sections[section - 1]->addr;
1793 else
1795 /* Mach-O uses 0 to mean "no section"; not an error. */
1796 if (section != 0)
1798 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1799 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
1800 s->symbol.name, section, mdata->nsects);
1802 s->symbol.section = bfd_und_section_ptr;
1804 break;
1805 case BFD_MACH_O_N_INDR:
1806 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1807 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"),
1808 s->symbol.name);
1809 s->symbol.section = bfd_und_section_ptr;
1810 break;
1811 default:
1812 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1813 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
1814 s->symbol.name, symtype);
1815 s->symbol.section = bfd_und_section_ptr;
1816 break;
1820 return 0;
1823 static int
1824 bfd_mach_o_read_symtab_strtab (bfd *abfd)
1826 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1827 bfd_mach_o_symtab_command *sym = mdata->symtab;
1829 /* Fail if there is no symtab. */
1830 if (sym == NULL)
1831 return -1;
1833 /* Success if already loaded. */
1834 if (sym->strtab)
1835 return 0;
1837 if (abfd->flags & BFD_IN_MEMORY)
1839 struct bfd_in_memory *b;
1841 b = (struct bfd_in_memory *) abfd->iostream;
1843 if ((sym->stroff + sym->strsize) > b->size)
1845 bfd_set_error (bfd_error_file_truncated);
1846 return -1;
1848 sym->strtab = (char *) b->buffer + sym->stroff;
1850 else
1852 sym->strtab = bfd_alloc (abfd, sym->strsize);
1853 if (sym->strtab == NULL)
1854 return -1;
1856 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1857 || bfd_bread ((void *) sym->strtab, sym->strsize, abfd) != sym->strsize)
1859 bfd_set_error (bfd_error_file_truncated);
1860 return -1;
1864 return 0;
1867 static int
1868 bfd_mach_o_read_symtab_symbols (bfd *abfd)
1870 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1871 bfd_mach_o_symtab_command *sym = mdata->symtab;
1872 unsigned long i;
1873 int ret;
1875 if (sym == NULL || sym->symbols)
1877 /* Return now if there are no symbols or if already loaded. */
1878 return 0;
1881 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1883 if (sym->symbols == NULL)
1885 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
1886 return -1;
1889 ret = bfd_mach_o_read_symtab_strtab (abfd);
1890 if (ret != 0)
1891 return ret;
1893 for (i = 0; i < sym->nsyms; i++)
1895 ret = bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1896 if (ret != 0)
1897 return ret;
1900 return 0;
1904 bfd_mach_o_read_dysymtab_symbol (bfd *abfd,
1905 bfd_mach_o_dysymtab_command *dysym,
1906 bfd_mach_o_symtab_command *sym,
1907 bfd_mach_o_asymbol *s,
1908 unsigned long i)
1910 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1911 unsigned long sym_index;
1912 unsigned char raw[4];
1914 BFD_ASSERT (i < dysym->nindirectsyms);
1916 if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
1917 || bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
1919 (*_bfd_error_handler)
1920 (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
1921 (unsigned long) sizeof (raw), isymoff);
1922 return -1;
1924 sym_index = bfd_h_get_32 (abfd, raw);
1926 return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
1929 static const char *
1930 bfd_mach_o_i386_flavour_string (unsigned int flavour)
1932 switch ((int) flavour)
1934 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
1935 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
1936 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1937 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
1938 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
1939 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1940 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
1941 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
1942 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
1943 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
1944 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
1945 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
1946 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
1947 default: return "UNKNOWN";
1951 static const char *
1952 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1954 switch ((int) flavour)
1956 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1957 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1958 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1959 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1960 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
1961 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
1962 default: return "UNKNOWN";
1966 static int
1967 bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
1969 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1970 struct mach_o_str_command_external raw;
1971 unsigned int nameoff;
1973 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1974 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1976 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1977 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
1978 return -1;
1980 nameoff = bfd_h_get_32 (abfd, raw.str);
1982 cmd->name_offset = command->offset + nameoff;
1983 cmd->name_len = command->len - nameoff;
1984 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1985 if (cmd->name_str == NULL)
1986 return -1;
1987 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1988 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1989 return -1;
1990 return 0;
1993 static int
1994 bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1996 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1997 struct mach_o_dylib_command_external raw;
1998 unsigned int nameoff;
2000 switch (command->type)
2002 case BFD_MACH_O_LC_LOAD_DYLIB:
2003 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2004 case BFD_MACH_O_LC_ID_DYLIB:
2005 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2006 break;
2007 default:
2008 BFD_FAIL ();
2009 return -1;
2012 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2013 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2014 return -1;
2016 nameoff = bfd_h_get_32 (abfd, raw.name);
2017 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
2018 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
2019 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
2021 cmd->name_offset = command->offset + nameoff;
2022 cmd->name_len = command->len - nameoff;
2023 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2024 if (cmd->name_str == NULL)
2025 return -1;
2026 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2027 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
2028 return -1;
2029 return 0;
2032 static int
2033 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
2034 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
2036 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
2038 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
2039 return 0;
2042 static int
2043 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
2045 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2046 bfd_mach_o_thread_command *cmd = &command->command.thread;
2047 unsigned int offset;
2048 unsigned int nflavours;
2049 unsigned int i;
2051 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2052 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2054 /* Count the number of threads. */
2055 offset = 8;
2056 nflavours = 0;
2057 while (offset != command->len)
2059 struct mach_o_thread_command_external raw;
2061 if (offset >= command->len)
2062 return -1;
2064 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2065 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2066 return -1;
2068 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
2069 nflavours++;
2072 /* Allocate threads. */
2073 cmd->flavours = bfd_alloc
2074 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
2075 if (cmd->flavours == NULL)
2076 return -1;
2077 cmd->nflavours = nflavours;
2079 offset = 8;
2080 nflavours = 0;
2081 while (offset != command->len)
2083 struct mach_o_thread_command_external raw;
2085 if (offset >= command->len)
2086 return -1;
2088 if (nflavours >= cmd->nflavours)
2089 return -1;
2091 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2092 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2093 return -1;
2095 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
2096 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
2097 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
2098 offset += cmd->flavours[nflavours].size + sizeof (raw);
2099 nflavours++;
2102 for (i = 0; i < nflavours; i++)
2104 asection *bfdsec;
2105 unsigned int snamelen;
2106 char *sname;
2107 const char *flavourstr;
2108 const char *prefix = "LC_THREAD";
2109 unsigned int j = 0;
2111 switch (mdata->header.cputype)
2113 case BFD_MACH_O_CPU_TYPE_POWERPC:
2114 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
2115 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2116 break;
2117 case BFD_MACH_O_CPU_TYPE_I386:
2118 case BFD_MACH_O_CPU_TYPE_X86_64:
2119 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2120 break;
2121 default:
2122 flavourstr = "UNKNOWN_ARCHITECTURE";
2123 break;
2126 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
2127 sname = bfd_alloc (abfd, snamelen);
2128 if (sname == NULL)
2129 return -1;
2131 for (;;)
2133 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2134 if (bfd_get_section_by_name (abfd, sname) == NULL)
2135 break;
2136 j++;
2139 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
2141 bfdsec->vma = 0;
2142 bfdsec->lma = 0;
2143 bfdsec->size = cmd->flavours[i].size;
2144 bfdsec->filepos = cmd->flavours[i].offset;
2145 bfdsec->alignment_power = 0x0;
2147 cmd->section = bfdsec;
2150 return 0;
2153 static int
2154 bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2156 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2157 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2159 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2162 struct mach_o_dysymtab_command_external raw;
2164 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2165 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2166 return -1;
2168 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
2169 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
2170 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
2171 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
2172 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
2173 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
2174 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
2175 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
2176 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
2177 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
2178 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
2179 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
2180 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
2181 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
2182 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
2183 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
2184 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
2185 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
2188 if (cmd->nmodtab != 0)
2190 unsigned int i;
2191 int wide = bfd_mach_o_wide_p (abfd);
2192 unsigned int module_len = wide ? 56 : 52;
2194 cmd->dylib_module =
2195 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2196 if (cmd->dylib_module == NULL)
2197 return -1;
2199 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2200 return -1;
2202 for (i = 0; i < cmd->nmodtab; i++)
2204 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2205 unsigned long v;
2206 unsigned char buf[56];
2208 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
2209 return -1;
2211 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2212 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2213 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2214 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2215 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2216 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2217 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2218 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2219 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2220 v = bfd_h_get_32 (abfd, buf +36);
2221 module->iinit = v & 0xffff;
2222 module->iterm = (v >> 16) & 0xffff;
2223 v = bfd_h_get_32 (abfd, buf + 40);
2224 module->ninit = v & 0xffff;
2225 module->nterm = (v >> 16) & 0xffff;
2226 if (wide)
2228 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2229 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2231 else
2233 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2234 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2239 if (cmd->ntoc != 0)
2241 unsigned int i;
2243 cmd->dylib_toc = bfd_alloc
2244 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2245 if (cmd->dylib_toc == NULL)
2246 return -1;
2248 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2249 return -1;
2251 for (i = 0; i < cmd->ntoc; i++)
2253 struct mach_o_dylib_table_of_contents_external raw;
2254 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2256 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2257 return -1;
2259 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
2260 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
2264 if (cmd->nindirectsyms != 0)
2266 unsigned int i;
2268 cmd->indirect_syms = bfd_alloc
2269 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2270 if (cmd->indirect_syms == NULL)
2271 return -1;
2273 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2274 return -1;
2276 for (i = 0; i < cmd->nindirectsyms; i++)
2278 unsigned char raw[4];
2279 unsigned int *is = &cmd->indirect_syms[i];
2281 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
2282 return -1;
2284 *is = bfd_h_get_32 (abfd, raw);
2288 if (cmd->nextrefsyms != 0)
2290 unsigned long v;
2291 unsigned int i;
2293 cmd->ext_refs = bfd_alloc
2294 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2295 if (cmd->ext_refs == NULL)
2296 return -1;
2298 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2299 return -1;
2301 for (i = 0; i < cmd->nextrefsyms; i++)
2303 unsigned char raw[4];
2304 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2306 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
2307 return -1;
2309 /* Fields isym and flags are written as bit-fields, thus we need
2310 a specific processing for endianness. */
2311 v = bfd_h_get_32 (abfd, raw);
2312 if (bfd_big_endian (abfd))
2314 ref->isym = (v >> 8) & 0xffffff;
2315 ref->flags = v & 0xff;
2317 else
2319 ref->isym = v & 0xffffff;
2320 ref->flags = (v >> 24) & 0xff;
2325 if (mdata->dysymtab)
2326 return -1;
2327 mdata->dysymtab = cmd;
2329 return 0;
2332 static int
2333 bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
2335 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2336 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2337 struct mach_o_symtab_command_external raw;
2339 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2341 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2342 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2343 return -1;
2345 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
2346 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
2347 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
2348 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
2349 symtab->symbols = NULL;
2350 symtab->strtab = NULL;
2352 if (symtab->nsyms != 0)
2353 abfd->flags |= HAS_SYMS;
2355 if (mdata->symtab)
2356 return -1;
2357 mdata->symtab = symtab;
2358 return 0;
2361 static int
2362 bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
2364 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
2366 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2368 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2369 || bfd_bread (cmd->uuid, 16, abfd) != 16)
2370 return -1;
2372 return 0;
2375 static int
2376 bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
2378 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
2379 struct mach_o_linkedit_data_command_external raw;
2381 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2382 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2383 return -1;
2385 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
2386 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
2387 return 0;
2390 static int
2391 bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
2393 bfd_mach_o_str_command *cmd = &command->command.str;
2394 struct mach_o_str_command_external raw;
2395 unsigned long off;
2397 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2398 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2399 return -1;
2401 off = bfd_get_32 (abfd, raw.str);
2402 cmd->stroff = command->offset + off;
2403 cmd->str_len = command->len - off;
2404 cmd->str = bfd_alloc (abfd, cmd->str_len);
2405 if (cmd->str == NULL)
2406 return -1;
2407 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
2408 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
2409 return -1;
2410 return 0;
2413 static int
2414 bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
2416 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
2417 struct mach_o_dyld_info_command_external raw;
2419 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2420 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2421 return -1;
2423 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
2424 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
2425 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
2426 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
2427 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
2428 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
2429 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
2430 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
2431 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
2432 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
2433 return 0;
2436 static int
2437 bfd_mach_o_read_segment (bfd *abfd,
2438 bfd_mach_o_load_command *command,
2439 unsigned int wide)
2441 bfd_mach_o_segment_command *seg = &command->command.segment;
2442 unsigned long i;
2444 if (wide)
2446 struct mach_o_segment_command_64_external raw;
2448 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2450 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2451 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2452 return -1;
2454 memcpy (seg->segname, raw.segname, 16);
2455 seg->segname[16] = '\0';
2457 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
2458 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
2459 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
2460 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
2461 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2462 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2463 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2464 seg->flags = bfd_h_get_32 (abfd, raw.flags);
2466 else
2468 struct mach_o_segment_command_32_external raw;
2470 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2472 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2473 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2474 return -1;
2476 memcpy (seg->segname, raw.segname, 16);
2477 seg->segname[16] = '\0';
2479 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
2480 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
2481 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
2482 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
2483 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2484 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2485 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2486 seg->flags = bfd_h_get_32 (abfd, raw.flags);
2489 if (seg->nsects != 0)
2491 seg->sections = bfd_alloc (abfd, seg->nsects
2492 * sizeof (bfd_mach_o_section));
2493 if (seg->sections == NULL)
2494 return -1;
2496 for (i = 0; i < seg->nsects; i++)
2498 bfd_vma segoff;
2499 if (wide)
2500 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2501 + (i * BFD_MACH_O_SECTION_64_SIZE);
2502 else
2503 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2504 + (i * BFD_MACH_O_SECTION_SIZE);
2506 if (bfd_mach_o_read_section
2507 (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
2508 return -1;
2512 return 0;
2515 static int
2516 bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2518 return bfd_mach_o_read_segment (abfd, command, 0);
2521 static int
2522 bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2524 return bfd_mach_o_read_segment (abfd, command, 1);
2527 static int
2528 bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2530 struct mach_o_load_command_external raw;
2531 unsigned int cmd;
2533 /* Read command type and length. */
2534 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2535 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
2536 return -1;
2538 cmd = bfd_h_get_32 (abfd, raw.cmd);
2539 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
2540 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
2541 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
2543 switch (command->type)
2545 case BFD_MACH_O_LC_SEGMENT:
2546 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
2547 return -1;
2548 break;
2549 case BFD_MACH_O_LC_SEGMENT_64:
2550 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
2551 return -1;
2552 break;
2553 case BFD_MACH_O_LC_SYMTAB:
2554 if (bfd_mach_o_read_symtab (abfd, command) != 0)
2555 return -1;
2556 break;
2557 case BFD_MACH_O_LC_SYMSEG:
2558 break;
2559 case BFD_MACH_O_LC_THREAD:
2560 case BFD_MACH_O_LC_UNIXTHREAD:
2561 if (bfd_mach_o_read_thread (abfd, command) != 0)
2562 return -1;
2563 break;
2564 case BFD_MACH_O_LC_LOAD_DYLINKER:
2565 case BFD_MACH_O_LC_ID_DYLINKER:
2566 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
2567 return -1;
2568 break;
2569 case BFD_MACH_O_LC_LOAD_DYLIB:
2570 case BFD_MACH_O_LC_ID_DYLIB:
2571 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2572 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2573 if (bfd_mach_o_read_dylib (abfd, command) != 0)
2574 return -1;
2575 break;
2576 case BFD_MACH_O_LC_PREBOUND_DYLIB:
2577 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
2578 return -1;
2579 break;
2580 case BFD_MACH_O_LC_LOADFVMLIB:
2581 case BFD_MACH_O_LC_IDFVMLIB:
2582 case BFD_MACH_O_LC_IDENT:
2583 case BFD_MACH_O_LC_FVMFILE:
2584 case BFD_MACH_O_LC_PREPAGE:
2585 case BFD_MACH_O_LC_ROUTINES:
2586 case BFD_MACH_O_LC_ROUTINES_64:
2587 break;
2588 case BFD_MACH_O_LC_SUB_FRAMEWORK:
2589 case BFD_MACH_O_LC_SUB_UMBRELLA:
2590 case BFD_MACH_O_LC_SUB_LIBRARY:
2591 case BFD_MACH_O_LC_SUB_CLIENT:
2592 case BFD_MACH_O_LC_RPATH:
2593 if (bfd_mach_o_read_str (abfd, command) != 0)
2594 return -1;
2595 break;
2596 case BFD_MACH_O_LC_DYSYMTAB:
2597 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
2598 return -1;
2599 break;
2600 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2601 case BFD_MACH_O_LC_PREBIND_CKSUM:
2602 break;
2603 case BFD_MACH_O_LC_UUID:
2604 if (bfd_mach_o_read_uuid (abfd, command) != 0)
2605 return -1;
2606 break;
2607 case BFD_MACH_O_LC_CODE_SIGNATURE:
2608 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2609 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
2610 return -1;
2611 break;
2612 case BFD_MACH_O_LC_DYLD_INFO:
2613 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
2614 return -1;
2615 break;
2616 default:
2617 (*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
2618 (unsigned long) command->type);
2619 break;
2622 return 0;
2625 static void
2626 bfd_mach_o_flatten_sections (bfd *abfd)
2628 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2629 long csect = 0;
2630 unsigned long i, j;
2632 /* Count total number of sections. */
2633 mdata->nsects = 0;
2635 for (i = 0; i < mdata->header.ncmds; i++)
2637 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2638 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2640 bfd_mach_o_segment_command *seg;
2642 seg = &mdata->commands[i].command.segment;
2643 mdata->nsects += seg->nsects;
2647 /* Allocate sections array. */
2648 mdata->sections = bfd_alloc (abfd,
2649 mdata->nsects * sizeof (bfd_mach_o_section *));
2651 /* Fill the array. */
2652 csect = 0;
2654 for (i = 0; i < mdata->header.ncmds; i++)
2656 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2657 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2659 bfd_mach_o_segment_command *seg;
2661 seg = &mdata->commands[i].command.segment;
2662 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2664 for (j = 0; j < seg->nsects; j++)
2665 mdata->sections[csect++] = &seg->sections[j];
2671 bfd_mach_o_scan_start_address (bfd *abfd)
2673 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2674 bfd_mach_o_thread_command *cmd = NULL;
2675 unsigned long i;
2677 for (i = 0; i < mdata->header.ncmds; i++)
2679 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2680 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2682 if (cmd == NULL)
2683 cmd = &mdata->commands[i].command.thread;
2684 else
2685 return 0;
2689 if (cmd == NULL)
2690 return 0;
2692 for (i = 0; i < cmd->nflavours; i++)
2694 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2695 && (cmd->flavours[i].flavour
2696 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2698 unsigned char buf[4];
2700 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2701 || bfd_bread (buf, 4, abfd) != 4)
2702 return -1;
2704 abfd->start_address = bfd_h_get_32 (abfd, buf);
2706 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2707 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2709 unsigned char buf[4];
2711 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2712 || bfd_bread (buf, 4, abfd) != 4)
2713 return -1;
2715 abfd->start_address = bfd_h_get_32 (abfd, buf);
2717 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2718 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
2720 unsigned char buf[8];
2722 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2723 || bfd_bread (buf, 8, abfd) != 8)
2724 return -1;
2726 abfd->start_address = bfd_h_get_64 (abfd, buf);
2728 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2729 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2731 unsigned char buf[8];
2733 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2734 || bfd_bread (buf, 8, abfd) != 8)
2735 return -1;
2737 abfd->start_address = bfd_h_get_64 (abfd, buf);
2741 return 0;
2744 bfd_boolean
2745 bfd_mach_o_set_arch_mach (bfd *abfd,
2746 enum bfd_architecture arch,
2747 unsigned long machine)
2749 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
2751 /* If this isn't the right architecture for this backend, and this
2752 isn't the generic backend, fail. */
2753 if (arch != bed->arch
2754 && arch != bfd_arch_unknown
2755 && bed->arch != bfd_arch_unknown)
2756 return FALSE;
2758 return bfd_default_set_arch_mach (abfd, arch, machine);
2762 bfd_mach_o_scan (bfd *abfd,
2763 bfd_mach_o_header *header,
2764 bfd_mach_o_data_struct *mdata)
2766 unsigned int i;
2767 enum bfd_architecture cputype;
2768 unsigned long cpusubtype;
2769 unsigned int hdrsize;
2771 hdrsize = mach_o_wide_p (header) ?
2772 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2774 mdata->header = *header;
2776 abfd->flags = abfd->flags & BFD_IN_MEMORY;
2777 switch (header->filetype)
2779 case BFD_MACH_O_MH_OBJECT:
2780 abfd->flags |= HAS_RELOC;
2781 break;
2782 case BFD_MACH_O_MH_EXECUTE:
2783 abfd->flags |= EXEC_P;
2784 break;
2785 case BFD_MACH_O_MH_DYLIB:
2786 case BFD_MACH_O_MH_BUNDLE:
2787 abfd->flags |= DYNAMIC;
2788 break;
2791 abfd->tdata.mach_o_data = mdata;
2793 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2794 &cputype, &cpusubtype);
2795 if (cputype == bfd_arch_unknown)
2797 (*_bfd_error_handler) (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
2798 header->cputype, header->cpusubtype);
2799 return -1;
2802 bfd_set_arch_mach (abfd, cputype, cpusubtype);
2804 if (header->ncmds != 0)
2806 mdata->commands = bfd_alloc
2807 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2808 if (mdata->commands == NULL)
2809 return -1;
2811 for (i = 0; i < header->ncmds; i++)
2813 bfd_mach_o_load_command *cur = &mdata->commands[i];
2815 if (i == 0)
2816 cur->offset = hdrsize;
2817 else
2819 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2820 cur->offset = prev->offset + prev->len;
2823 if (bfd_mach_o_read_command (abfd, cur) < 0)
2824 return -1;
2828 if (bfd_mach_o_scan_start_address (abfd) < 0)
2829 return -1;
2831 bfd_mach_o_flatten_sections (abfd);
2832 return 0;
2835 bfd_boolean
2836 bfd_mach_o_mkobject_init (bfd *abfd)
2838 bfd_mach_o_data_struct *mdata = NULL;
2840 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2841 if (mdata == NULL)
2842 return FALSE;
2843 abfd->tdata.mach_o_data = mdata;
2845 mdata->header.magic = 0;
2846 mdata->header.cputype = 0;
2847 mdata->header.cpusubtype = 0;
2848 mdata->header.filetype = 0;
2849 mdata->header.ncmds = 0;
2850 mdata->header.sizeofcmds = 0;
2851 mdata->header.flags = 0;
2852 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2853 mdata->commands = NULL;
2854 mdata->nsects = 0;
2855 mdata->sections = NULL;
2857 return TRUE;
2860 static bfd_boolean
2861 bfd_mach_o_gen_mkobject (bfd *abfd)
2863 bfd_mach_o_data_struct *mdata;
2865 if (!bfd_mach_o_mkobject_init (abfd))
2866 return FALSE;
2868 mdata = bfd_mach_o_get_data (abfd);
2869 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
2870 mdata->header.cputype = 0;
2871 mdata->header.cpusubtype = 0;
2872 mdata->header.byteorder = abfd->xvec->byteorder;
2873 mdata->header.version = 1;
2875 return TRUE;
2878 const bfd_target *
2879 bfd_mach_o_header_p (bfd *abfd,
2880 bfd_mach_o_filetype filetype,
2881 bfd_mach_o_cpu_type cputype)
2883 struct bfd_preserve preserve;
2884 bfd_mach_o_header header;
2886 preserve.marker = NULL;
2887 if (!bfd_mach_o_read_header (abfd, &header))
2888 goto wrong;
2890 if (! (header.byteorder == BFD_ENDIAN_BIG
2891 || header.byteorder == BFD_ENDIAN_LITTLE))
2893 (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
2894 (unsigned long) header.byteorder);
2895 goto wrong;
2898 if (! ((header.byteorder == BFD_ENDIAN_BIG
2899 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2900 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2901 || (header.byteorder == BFD_ENDIAN_LITTLE
2902 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2903 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2904 goto wrong;
2906 /* Check cputype and filetype.
2907 In case of wildcard, do not accept magics that are handled by existing
2908 targets. */
2909 if (cputype)
2911 if (header.cputype != cputype)
2912 goto wrong;
2914 else
2916 switch (header.cputype)
2918 case BFD_MACH_O_CPU_TYPE_I386:
2919 /* Handled by mach-o-i386 */
2920 goto wrong;
2921 default:
2922 break;
2925 if (filetype)
2927 if (header.filetype != filetype)
2928 goto wrong;
2930 else
2932 switch (header.filetype)
2934 case BFD_MACH_O_MH_CORE:
2935 /* Handled by core_p */
2936 goto wrong;
2937 default:
2938 break;
2942 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2943 if (preserve.marker == NULL
2944 || !bfd_preserve_save (abfd, &preserve))
2945 goto fail;
2947 if (bfd_mach_o_scan (abfd, &header,
2948 (bfd_mach_o_data_struct *) preserve.marker) != 0)
2949 goto wrong;
2951 bfd_preserve_finish (abfd, &preserve);
2952 return abfd->xvec;
2954 wrong:
2955 bfd_set_error (bfd_error_wrong_format);
2957 fail:
2958 if (preserve.marker != NULL)
2959 bfd_preserve_restore (abfd, &preserve);
2960 return NULL;
2963 static const bfd_target *
2964 bfd_mach_o_gen_object_p (bfd *abfd)
2966 return bfd_mach_o_header_p (abfd, 0, 0);
2969 static const bfd_target *
2970 bfd_mach_o_gen_core_p (bfd *abfd)
2972 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
2975 typedef struct mach_o_fat_archentry
2977 unsigned long cputype;
2978 unsigned long cpusubtype;
2979 unsigned long offset;
2980 unsigned long size;
2981 unsigned long align;
2982 } mach_o_fat_archentry;
2984 typedef struct mach_o_fat_data_struct
2986 unsigned long magic;
2987 unsigned long nfat_arch;
2988 mach_o_fat_archentry *archentries;
2989 } mach_o_fat_data_struct;
2991 const bfd_target *
2992 bfd_mach_o_archive_p (bfd *abfd)
2994 mach_o_fat_data_struct *adata = NULL;
2995 struct mach_o_fat_header_external hdr;
2996 unsigned long i;
2998 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2999 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
3000 goto error;
3002 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3003 if (adata == NULL)
3004 goto error;
3006 adata->magic = bfd_getb32 (hdr.magic);
3007 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3008 if (adata->magic != 0xcafebabe)
3009 goto error;
3010 /* Avoid matching Java bytecode files, which have the same magic number.
3011 In the Java bytecode file format this field contains the JVM version,
3012 which starts at 43.0. */
3013 if (adata->nfat_arch > 30)
3014 goto error;
3016 adata->archentries =
3017 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
3018 if (adata->archentries == NULL)
3019 goto error;
3021 for (i = 0; i < adata->nfat_arch; i++)
3023 struct mach_o_fat_arch_external arch;
3024 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
3025 goto error;
3026 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
3027 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
3028 adata->archentries[i].offset = bfd_getb32 (arch.offset);
3029 adata->archentries[i].size = bfd_getb32 (arch.size);
3030 adata->archentries[i].align = bfd_getb32 (arch.align);
3033 abfd->tdata.mach_o_fat_data = adata;
3034 return abfd->xvec;
3036 error:
3037 if (adata != NULL)
3038 bfd_release (abfd, adata);
3039 bfd_set_error (bfd_error_wrong_format);
3040 return NULL;
3043 bfd *
3044 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3046 mach_o_fat_data_struct *adata;
3047 mach_o_fat_archentry *entry = NULL;
3048 unsigned long i;
3049 bfd *nbfd;
3050 enum bfd_architecture arch_type;
3051 unsigned long arch_subtype;
3053 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3054 BFD_ASSERT (adata != NULL);
3056 /* Find index of previous entry. */
3057 if (prev == NULL)
3058 i = 0; /* Start at first one. */
3059 else
3061 for (i = 0; i < adata->nfat_arch; i++)
3063 if (adata->archentries[i].offset == prev->origin)
3064 break;
3067 if (i == adata->nfat_arch)
3069 /* Not found. */
3070 bfd_set_error (bfd_error_bad_value);
3071 return NULL;
3073 i++; /* Get next entry. */
3076 if (i >= adata->nfat_arch)
3078 bfd_set_error (bfd_error_no_more_archived_files);
3079 return NULL;
3082 entry = &adata->archentries[i];
3083 nbfd = _bfd_new_bfd_contained_in (archive);
3084 if (nbfd == NULL)
3085 return NULL;
3087 nbfd->origin = entry->offset;
3089 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3090 &arch_type, &arch_subtype);
3091 /* Create the member filename.
3092 Use FILENAME:ARCH_NAME. */
3094 char *s = NULL;
3095 const char *arch_name;
3096 size_t arch_file_len = strlen (bfd_get_filename (archive));
3098 arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
3099 s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
3100 if (s == NULL)
3101 return NULL;
3102 memcpy (s, bfd_get_filename (archive), arch_file_len);
3103 s[arch_file_len] = ':';
3104 strcpy (s + arch_file_len + 1, arch_name);
3105 nbfd->filename = s;
3107 nbfd->iostream = NULL;
3108 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3110 return nbfd;
3113 /* If ABFD format is FORMAT and architecture is ARCH, return it.
3114 If ABFD is a fat image containing a member that corresponds to FORMAT
3115 and ARCH, returns it.
3116 In other case, returns NULL.
3117 This function allows transparent uses of fat images. */
3118 bfd *
3119 bfd_mach_o_fat_extract (bfd *abfd,
3120 bfd_format format,
3121 const bfd_arch_info_type *arch)
3123 bfd *res;
3124 mach_o_fat_data_struct *adata;
3125 unsigned int i;
3127 if (bfd_check_format (abfd, format))
3129 if (bfd_get_arch_info (abfd) == arch)
3130 return abfd;
3131 return NULL;
3133 if (!bfd_check_format (abfd, bfd_archive)
3134 || abfd->xvec != &mach_o_fat_vec)
3135 return NULL;
3137 /* This is a Mach-O fat image. */
3138 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3139 BFD_ASSERT (adata != NULL);
3141 for (i = 0; i < adata->nfat_arch; i++)
3143 struct mach_o_fat_archentry *e = &adata->archentries[i];
3144 enum bfd_architecture cpu_type;
3145 unsigned long cpu_subtype;
3147 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3148 &cpu_type, &cpu_subtype);
3149 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3150 continue;
3152 /* The architecture is found. */
3153 res = _bfd_new_bfd_contained_in (abfd);
3154 if (res == NULL)
3155 return NULL;
3157 res->origin = e->offset;
3159 res->filename = strdup (abfd->filename);
3160 res->iostream = NULL;
3162 if (bfd_check_format (res, format))
3164 BFD_ASSERT (bfd_get_arch_info (res) == arch);
3165 return res;
3167 bfd_close (res);
3168 return NULL;
3171 return NULL;
3175 bfd_mach_o_lookup_section (bfd *abfd,
3176 asection *section,
3177 bfd_mach_o_load_command **mcommand,
3178 bfd_mach_o_section **msection)
3180 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3181 unsigned int i, j, num;
3183 bfd_mach_o_load_command *ncmd = NULL;
3184 bfd_mach_o_section *nsect = NULL;
3186 BFD_ASSERT (mcommand != NULL);
3187 BFD_ASSERT (msection != NULL);
3189 num = 0;
3190 for (i = 0; i < md->header.ncmds; i++)
3192 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3193 struct bfd_mach_o_segment_command *seg = NULL;
3195 if (cmd->type != BFD_MACH_O_LC_SEGMENT
3196 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
3197 continue;
3198 seg = &cmd->command.segment;
3200 for (j = 0; j < seg->nsects; j++)
3202 struct bfd_mach_o_section *sect = &seg->sections[j];
3204 if (sect->bfdsection == section)
3206 if (num == 0)
3208 nsect = sect;
3209 ncmd = cmd;
3211 num++;
3216 *mcommand = ncmd;
3217 *msection = nsect;
3218 return num;
3222 bfd_mach_o_lookup_command (bfd *abfd,
3223 bfd_mach_o_load_command_type type,
3224 bfd_mach_o_load_command **mcommand)
3226 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3227 bfd_mach_o_load_command *ncmd = NULL;
3228 unsigned int i, num;
3230 BFD_ASSERT (md != NULL);
3231 BFD_ASSERT (mcommand != NULL);
3233 num = 0;
3234 for (i = 0; i < md->header.ncmds; i++)
3236 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3238 if (cmd->type != type)
3239 continue;
3241 if (num == 0)
3242 ncmd = cmd;
3243 num++;
3246 *mcommand = ncmd;
3247 return num;
3250 unsigned long
3251 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3253 switch (type)
3255 case BFD_MACH_O_CPU_TYPE_MC680x0:
3256 return 0x04000000;
3257 case BFD_MACH_O_CPU_TYPE_MC88000:
3258 return 0xffffe000;
3259 case BFD_MACH_O_CPU_TYPE_POWERPC:
3260 return 0xc0000000;
3261 case BFD_MACH_O_CPU_TYPE_I386:
3262 return 0xc0000000;
3263 case BFD_MACH_O_CPU_TYPE_SPARC:
3264 return 0xf0000000;
3265 case BFD_MACH_O_CPU_TYPE_I860:
3266 return 0;
3267 case BFD_MACH_O_CPU_TYPE_HPPA:
3268 return 0xc0000000 - 0x04000000;
3269 default:
3270 return 0;
3274 typedef struct bfd_mach_o_xlat_name
3276 const char *name;
3277 unsigned long val;
3279 bfd_mach_o_xlat_name;
3281 static void
3282 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
3283 unsigned long val,
3284 FILE *file)
3286 int first = 1;
3288 for (; table->name; table++)
3290 if (table->val & val)
3292 if (!first)
3293 fprintf (file, "+");
3294 fprintf (file, "%s", table->name);
3295 val &= ~table->val;
3296 first = 0;
3299 if (val)
3301 if (!first)
3302 fprintf (file, "+");
3303 fprintf (file, "0x%lx", val);
3304 return;
3306 if (first)
3307 fprintf (file, "-");
3310 static const char *
3311 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
3313 for (; table->name; table++)
3314 if (table->val == val)
3315 return table->name;
3316 return "*UNKNOWN*";
3319 static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
3321 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
3322 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
3323 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
3324 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
3325 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
3326 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
3327 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
3328 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
3329 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
3330 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
3331 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
3332 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
3333 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
3334 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
3335 { NULL, 0}
3338 static bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
3340 { "object", BFD_MACH_O_MH_OBJECT },
3341 { "execute", BFD_MACH_O_MH_EXECUTE },
3342 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
3343 { "core", BFD_MACH_O_MH_CORE },
3344 { "preload", BFD_MACH_O_MH_PRELOAD },
3345 { "dylib", BFD_MACH_O_MH_DYLIB },
3346 { "dylinker", BFD_MACH_O_MH_DYLINKER },
3347 { "bundle", BFD_MACH_O_MH_BUNDLE },
3348 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
3349 { "dym", BFD_MACH_O_MH_DSYM },
3350 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
3351 { NULL, 0}
3354 static bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
3356 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
3357 { "incrlink", BFD_MACH_O_MH_INCRLINK },
3358 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
3359 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
3360 { "prebound", BFD_MACH_O_MH_PREBOUND },
3361 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
3362 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
3363 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
3364 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
3365 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
3366 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
3367 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
3368 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
3369 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
3370 { "canonical", BFD_MACH_O_MH_CANONICAL },
3371 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
3372 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
3373 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
3374 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
3375 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
3376 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
3377 { "pie", BFD_MACH_O_MH_PIE },
3378 { NULL, 0}
3381 static bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
3383 { "regular", BFD_MACH_O_S_REGULAR},
3384 { "zerofill", BFD_MACH_O_S_ZEROFILL},
3385 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3386 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3387 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3388 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3389 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3390 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3391 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3392 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3393 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3394 { "coalesced", BFD_MACH_O_S_COALESCED},
3395 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3396 { "interposing", BFD_MACH_O_S_INTERPOSING},
3397 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3398 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
3399 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3400 { NULL, 0}
3403 static bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
3405 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3406 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3407 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3408 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3409 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3410 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3411 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3412 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3413 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3414 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
3415 { NULL, 0}
3418 static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
3420 { "segment", BFD_MACH_O_LC_SEGMENT},
3421 { "symtab", BFD_MACH_O_LC_SYMTAB},
3422 { "symseg", BFD_MACH_O_LC_SYMSEG},
3423 { "thread", BFD_MACH_O_LC_THREAD},
3424 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
3425 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
3426 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
3427 { "ident", BFD_MACH_O_LC_IDENT},
3428 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
3429 { "prepage", BFD_MACH_O_LC_PREPAGE},
3430 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
3431 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
3432 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
3433 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
3434 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
3435 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
3436 { "routines", BFD_MACH_O_LC_ROUTINES},
3437 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
3438 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
3439 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
3440 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
3441 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
3442 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
3443 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
3444 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
3445 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
3446 { "uuid", BFD_MACH_O_LC_UUID},
3447 { "rpath", BFD_MACH_O_LC_RPATH},
3448 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
3449 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
3450 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
3451 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
3452 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
3453 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
3454 { NULL, 0}
3457 /* Get the section type from NAME. Return -1 if NAME is unknown. */
3459 unsigned int
3460 bfd_mach_o_get_section_type_from_name (const char *name)
3462 bfd_mach_o_xlat_name *x;
3464 for (x = bfd_mach_o_section_type_name; x->name; x++)
3465 if (strcmp (x->name, name) == 0)
3466 return x->val;
3467 return (unsigned int)-1;
3470 /* Get the section attribute from NAME. Return -1 if NAME is unknown. */
3472 unsigned int
3473 bfd_mach_o_get_section_attribute_from_name (const char *name)
3475 bfd_mach_o_xlat_name *x;
3477 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
3478 if (strcmp (x->name, name) == 0)
3479 return x->val;
3480 return (unsigned int)-1;
3483 static void
3484 bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
3486 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3487 bfd_mach_o_header *h = &mdata->header;
3489 fputs (_("Mach-O header:\n"), file);
3490 fprintf (file, _(" magic : %08lx\n"), h->magic);
3491 fprintf (file, _(" cputype : %08lx (%s)\n"), h->cputype,
3492 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
3493 fprintf (file, _(" cpusubtype: %08lx\n"), h->cpusubtype);
3494 fprintf (file, _(" filetype : %08lx (%s)\n"),
3495 h->filetype,
3496 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
3497 fprintf (file, _(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
3498 fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds);
3499 fprintf (file, _(" flags : %08lx ("), h->flags);
3500 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file);
3501 fputs (_(")\n"), file);
3502 fprintf (file, _(" reserved : %08x\n"), h->reserved);
3505 static void
3506 bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
3508 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3509 unsigned int i, j;
3510 unsigned int sec_nbr = 0;
3512 fputs (_("Segments and Sections:\n"), file);
3513 fputs (_(" #: Segment name Section name Address\n"), file);
3515 for (i = 0; i < mdata->header.ncmds; i++)
3517 bfd_mach_o_segment_command *seg;
3519 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
3520 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
3521 continue;
3523 seg = &mdata->commands[i].command.segment;
3525 fprintf (file, "[Segment %-16s ", seg->segname);
3526 fprintf_vma (file, seg->vmaddr);
3527 fprintf (file, "-");
3528 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
3529 fputc (' ', file);
3530 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
3531 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
3532 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
3533 fprintf (file, "]\n");
3534 for (j = 0; j < seg->nsects; j++)
3536 bfd_mach_o_section *sec = &seg->sections[j];
3537 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
3538 sec->segname, sec->sectname);
3539 fprintf_vma (file, sec->addr);
3540 fprintf (file, " ");
3541 fprintf_vma (file, sec->size);
3542 fprintf (file, " %08lx\n", sec->flags);
3547 static void
3548 bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED,
3549 bfd_mach_o_section *sec, FILE *file)
3551 fprintf (file, " Section: %-16s %-16s (bfdname: %s)\n",
3552 sec->sectname, sec->segname, sec->bfdsection->name);
3553 fprintf (file, " addr: ");
3554 fprintf_vma (file, sec->addr);
3555 fprintf (file, " size: ");
3556 fprintf_vma (file, sec->size);
3557 fprintf (file, " offset: ");
3558 fprintf_vma (file, sec->offset);
3559 fprintf (file, "\n");
3560 fprintf (file, " align: %ld", sec->align);
3561 fprintf (file, " nreloc: %lu reloff: ", sec->nreloc);
3562 fprintf_vma (file, sec->reloff);
3563 fprintf (file, "\n");
3564 fprintf (file, " flags: %08lx (type: %s", sec->flags,
3565 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
3566 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
3567 fprintf (file, " attr: ");
3568 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
3569 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
3570 file);
3571 fprintf (file, ")\n");
3572 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3574 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3575 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3576 case BFD_MACH_O_S_SYMBOL_STUBS:
3577 fprintf (file, " first indirect sym: %lu", sec->reserved1);
3578 fprintf (file, " (%u entries)",
3579 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
3580 break;
3581 default:
3582 fprintf (file, " reserved1: 0x%lx", sec->reserved1);
3583 break;
3585 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3587 case BFD_MACH_O_S_SYMBOL_STUBS:
3588 fprintf (file, " stub size: %lu", sec->reserved2);
3589 break;
3590 default:
3591 fprintf (file, " reserved2: 0x%lx", sec->reserved2);
3592 break;
3594 fprintf (file, " reserved3: 0x%lx\n", sec->reserved3);
3597 static void
3598 bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
3599 bfd_mach_o_load_command *cmd, FILE *file)
3601 bfd_mach_o_segment_command *seg = &cmd->command.segment;
3602 unsigned int i;
3604 fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
3605 fprintf (file, " vmaddr: ");
3606 fprintf_vma (file, seg->vmaddr);
3607 fprintf (file, " vmsize: ");
3608 fprintf_vma (file, seg->vmsize);
3609 fprintf (file, "\n");
3610 fprintf (file, " fileoff: ");
3611 fprintf_vma (file, seg->fileoff);
3612 fprintf (file, " filesize: ");
3613 fprintf_vma (file, (bfd_vma)seg->filesize);
3614 fprintf (file, " endoff: ");
3615 fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
3616 fprintf (file, "\n");
3617 fprintf (file, " nsects: %lu ", seg->nsects);
3618 fprintf (file, " flags: %lx\n", seg->flags);
3619 for (i = 0; i < seg->nsects; i++)
3620 bfd_mach_o_print_section (abfd, &seg->sections[i], file);
3623 static void
3624 bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
3625 bfd_mach_o_load_command *cmd, FILE *file)
3627 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
3628 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3629 unsigned int i;
3631 fprintf (file, " local symbols: idx: %10lu num: %-8lu",
3632 dysymtab->ilocalsym, dysymtab->nlocalsym);
3633 fprintf (file, " (nxtidx: %lu)\n",
3634 dysymtab->ilocalsym + dysymtab->nlocalsym);
3635 fprintf (file, " external symbols: idx: %10lu num: %-8lu",
3636 dysymtab->iextdefsym, dysymtab->nextdefsym);
3637 fprintf (file, " (nxtidx: %lu)\n",
3638 dysymtab->iextdefsym + dysymtab->nextdefsym);
3639 fprintf (file, " undefined symbols: idx: %10lu num: %-8lu",
3640 dysymtab->iundefsym, dysymtab->nundefsym);
3641 fprintf (file, " (nxtidx: %lu)\n",
3642 dysymtab->iundefsym + dysymtab->nundefsym);
3643 fprintf (file, " table of content: off: 0x%08lx num: %-8lu",
3644 dysymtab->tocoff, dysymtab->ntoc);
3645 fprintf (file, " (endoff: 0x%08lx)\n",
3646 dysymtab->tocoff
3647 + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
3648 fprintf (file, " module table: off: 0x%08lx num: %-8lu",
3649 dysymtab->modtaboff, dysymtab->nmodtab);
3650 fprintf (file, " (endoff: 0x%08lx)\n",
3651 dysymtab->modtaboff + dysymtab->nmodtab
3652 * (mach_o_wide_p (&mdata->header) ?
3653 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
3654 fprintf (file, " external reference table: off: 0x%08lx num: %-8lu",
3655 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
3656 fprintf (file, " (endoff: 0x%08lx)\n",
3657 dysymtab->extrefsymoff
3658 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
3659 fprintf (file, " indirect symbol table: off: 0x%08lx num: %-8lu",
3660 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
3661 fprintf (file, " (endoff: 0x%08lx)\n",
3662 dysymtab->indirectsymoff
3663 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
3664 fprintf (file, " external relocation table: off: 0x%08lx num: %-8lu",
3665 dysymtab->extreloff, dysymtab->nextrel);
3666 fprintf (file, " (endoff: 0x%08lx)\n",
3667 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
3668 fprintf (file, " local relocation table: off: 0x%08lx num: %-8lu",
3669 dysymtab->locreloff, dysymtab->nlocrel);
3670 fprintf (file, " (endoff: 0x%08lx)\n",
3671 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
3673 if (dysymtab->ntoc > 0
3674 || dysymtab->nindirectsyms > 0
3675 || dysymtab->nextrefsyms > 0)
3677 /* Try to read the symbols to display the toc or indirect symbols. */
3678 bfd_mach_o_read_symtab_symbols (abfd);
3680 else if (dysymtab->nmodtab > 0)
3682 /* Try to read the strtab to display modules name. */
3683 bfd_mach_o_read_symtab_strtab (abfd);
3686 for (i = 0; i < dysymtab->nmodtab; i++)
3688 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
3689 fprintf (file, " module %u:\n", i);
3690 fprintf (file, " name: %lu", module->module_name_idx);
3691 if (mdata->symtab && mdata->symtab->strtab)
3692 fprintf (file, ": %s",
3693 mdata->symtab->strtab + module->module_name_idx);
3694 fprintf (file, "\n");
3695 fprintf (file, " extdefsym: idx: %8lu num: %lu\n",
3696 module->iextdefsym, module->nextdefsym);
3697 fprintf (file, " refsym: idx: %8lu num: %lu\n",
3698 module->irefsym, module->nrefsym);
3699 fprintf (file, " localsym: idx: %8lu num: %lu\n",
3700 module->ilocalsym, module->nlocalsym);
3701 fprintf (file, " extrel: idx: %8lu num: %lu\n",
3702 module->iextrel, module->nextrel);
3703 fprintf (file, " init: idx: %8u num: %u\n",
3704 module->iinit, module->ninit);
3705 fprintf (file, " term: idx: %8u num: %u\n",
3706 module->iterm, module->nterm);
3707 fprintf (file, " objc_module_info: addr: ");
3708 fprintf_vma (file, module->objc_module_info_addr);
3709 fprintf (file, " size: %lu\n", module->objc_module_info_size);
3712 if (dysymtab->ntoc > 0)
3714 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3716 fprintf (file, " table of content: (symbol/module)\n");
3717 for (i = 0; i < dysymtab->ntoc; i++)
3719 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
3721 fprintf (file, " %4u: ", i);
3722 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
3724 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
3725 fprintf (file, "%s (%lu)", name ? name : "*invalid*",
3726 toc->symbol_index);
3728 else
3729 fprintf (file, "%lu", toc->symbol_index);
3731 fprintf (file, " / ");
3732 if (symtab && symtab->strtab
3733 && toc->module_index < dysymtab->nmodtab)
3735 bfd_mach_o_dylib_module *mod;
3736 mod = &dysymtab->dylib_module[toc->module_index];
3737 fprintf (file, "%s (%lu)",
3738 symtab->strtab + mod->module_name_idx,
3739 toc->module_index);
3741 else
3742 fprintf (file, "%lu", toc->module_index);
3744 fprintf (file, "\n");
3748 if (dysymtab->nindirectsyms != 0)
3750 fprintf (file, " indirect symbols:\n");
3752 for (i = 0; i < mdata->nsects; i++)
3754 bfd_mach_o_section *sec = mdata->sections[i];
3755 unsigned int j, first, last;
3756 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3757 bfd_vma addr;
3758 bfd_vma entry_size;
3760 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3762 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3763 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3764 case BFD_MACH_O_S_SYMBOL_STUBS:
3765 first = sec->reserved1;
3766 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
3767 addr = sec->addr;
3768 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
3769 fprintf (file, " for section %s.%s:\n",
3770 sec->segname, sec->sectname);
3771 for (j = first; j < last; j++)
3773 unsigned int isym = dysymtab->indirect_syms[j];
3775 fprintf (file, " ");
3776 fprintf_vma (file, addr);
3777 fprintf (file, " %5u: 0x%08x", j, isym);
3778 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
3779 fprintf (file, " LOCAL");
3780 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
3781 fprintf (file, " ABSOLUTE");
3782 if (symtab && symtab->symbols
3783 && isym < symtab->nsyms
3784 && symtab->symbols[isym].symbol.name)
3785 fprintf (file, " %s", symtab->symbols[isym].symbol.name);
3786 fprintf (file, "\n");
3787 addr += entry_size;
3789 break;
3790 default:
3791 break;
3795 if (dysymtab->nextrefsyms > 0)
3797 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3799 fprintf (file, " external reference table: (symbol flags)\n");
3800 for (i = 0; i < dysymtab->nextrefsyms; i++)
3802 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
3804 fprintf (file, " %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
3805 if (symtab && symtab->symbols
3806 && ref->isym < symtab->nsyms
3807 && symtab->symbols[ref->isym].symbol.name)
3808 fprintf (file, " %s", symtab->symbols[ref->isym].symbol.name);
3809 fprintf (file, "\n");
3815 static void
3816 bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED,
3817 bfd_mach_o_load_command *cmd, FILE *file)
3819 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
3821 fprintf (file, " rebase: off: 0x%08x size: %-8u\n",
3822 info->rebase_off, info->rebase_size);
3823 fprintf (file, " bind: off: 0x%08x size: %-8u\n",
3824 info->bind_off, info->bind_size);
3825 fprintf (file, " weak bind: off: 0x%08x size: %-8u\n",
3826 info->weak_bind_off, info->weak_bind_size);
3827 fprintf (file, " lazy bind: off: 0x%08x size: %-8u\n",
3828 info->lazy_bind_off, info->lazy_bind_size);
3829 fprintf (file, " export: off: 0x%08x size: %-8u\n",
3830 info->export_off, info->export_size);
3833 bfd_boolean
3834 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
3836 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3837 FILE *file = (FILE *) ptr;
3838 unsigned int i;
3840 bfd_mach_o_print_private_header (abfd, file);
3841 fputc ('\n', file);
3843 for (i = 0; i < mdata->header.ncmds; i++)
3845 bfd_mach_o_load_command *cmd = &mdata->commands[i];
3847 fprintf (file, "Load command %s:",
3848 bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
3849 switch (cmd->type)
3851 case BFD_MACH_O_LC_SEGMENT:
3852 case BFD_MACH_O_LC_SEGMENT_64:
3853 bfd_mach_o_print_segment (abfd, cmd, file);
3854 break;
3855 case BFD_MACH_O_LC_UUID:
3857 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
3858 unsigned int j;
3860 for (j = 0; j < sizeof (uuid->uuid); j ++)
3861 fprintf (file, " %02x", uuid->uuid[j]);
3862 fputc ('\n', file);
3864 break;
3865 case BFD_MACH_O_LC_LOAD_DYLIB:
3866 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
3867 case BFD_MACH_O_LC_REEXPORT_DYLIB:
3868 case BFD_MACH_O_LC_ID_DYLIB:
3870 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
3871 fprintf (file, " %s\n", dylib->name_str);
3872 fprintf (file, " time stamp: 0x%08lx\n",
3873 dylib->timestamp);
3874 fprintf (file, " current version: 0x%08lx\n",
3875 dylib->current_version);
3876 fprintf (file, " comptibility version: 0x%08lx\n",
3877 dylib->compatibility_version);
3878 break;
3880 case BFD_MACH_O_LC_LOAD_DYLINKER:
3881 case BFD_MACH_O_LC_ID_DYLINKER:
3882 fprintf (file, " %s\n", cmd->command.dylinker.name_str);
3883 break;
3884 case BFD_MACH_O_LC_SYMTAB:
3886 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
3887 fprintf (file,
3888 "\n"
3889 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
3890 symtab->symoff, symtab->nsyms,
3891 symtab->symoff + symtab->nsyms
3892 * (mach_o_wide_p (&mdata->header)
3893 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
3894 fprintf (file,
3895 " stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
3896 symtab->stroff, symtab->strsize,
3897 symtab->stroff + symtab->strsize);
3898 break;
3900 case BFD_MACH_O_LC_DYSYMTAB:
3901 fprintf (file, "\n");
3902 bfd_mach_o_print_dysymtab (abfd, cmd, file);
3903 break;
3904 case BFD_MACH_O_LC_CODE_SIGNATURE:
3905 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
3907 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
3908 fprintf
3909 (file, "\n"
3910 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
3911 linkedit->dataoff, linkedit->datasize,
3912 linkedit->dataoff + linkedit->datasize);
3913 break;
3915 case BFD_MACH_O_LC_SUB_FRAMEWORK:
3916 case BFD_MACH_O_LC_SUB_UMBRELLA:
3917 case BFD_MACH_O_LC_SUB_LIBRARY:
3918 case BFD_MACH_O_LC_SUB_CLIENT:
3919 case BFD_MACH_O_LC_RPATH:
3921 bfd_mach_o_str_command *str = &cmd->command.str;
3922 fprintf (file, " %s\n", str->str);
3923 break;
3925 case BFD_MACH_O_LC_THREAD:
3926 case BFD_MACH_O_LC_UNIXTHREAD:
3928 bfd_mach_o_thread_command *thread = &cmd->command.thread;
3929 unsigned int j;
3930 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3932 fprintf (file, " nflavours: %lu\n", thread->nflavours);
3933 for (j = 0; j < thread->nflavours; j++)
3935 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
3937 fprintf (file, " %2u: flavour: 0x%08lx offset: 0x%08lx"
3938 " size: 0x%08lx\n",
3939 j, flavour->flavour, flavour->offset,
3940 flavour->size);
3941 if (bed->_bfd_mach_o_print_thread)
3943 char *buf = bfd_malloc (flavour->size);
3945 if (buf
3946 && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
3947 && (bfd_bread (buf, flavour->size, abfd)
3948 == flavour->size))
3949 (*bed->_bfd_mach_o_print_thread)(abfd, flavour,
3950 file, buf);
3951 free (buf);
3954 break;
3956 case BFD_MACH_O_LC_DYLD_INFO:
3957 fprintf (file, "\n");
3958 bfd_mach_o_print_dyld_info (abfd, cmd, file);
3959 break;
3960 default:
3961 fprintf (file, "\n");
3962 break;
3964 fputc ('\n', file);
3967 bfd_mach_o_print_section_map (abfd, file);
3969 return TRUE;
3973 bfd_mach_o_core_fetch_environment (bfd *abfd,
3974 unsigned char **rbuf,
3975 unsigned int *rlen)
3977 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3978 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
3979 unsigned int i = 0;
3981 for (i = 0; i < mdata->header.ncmds; i++)
3983 bfd_mach_o_load_command *cur = &mdata->commands[i];
3984 bfd_mach_o_segment_command *seg = NULL;
3986 if (cur->type != BFD_MACH_O_LC_SEGMENT)
3987 continue;
3989 seg = &cur->command.segment;
3991 if ((seg->vmaddr + seg->vmsize) == stackaddr)
3993 unsigned long start = seg->fileoff;
3994 unsigned long end = seg->fileoff + seg->filesize;
3995 unsigned char *buf = bfd_malloc (1024);
3996 unsigned long size = 1024;
3998 for (;;)
4000 bfd_size_type nread = 0;
4001 unsigned long offset;
4002 int found_nonnull = 0;
4004 if (size > (end - start))
4005 size = (end - start);
4007 buf = bfd_realloc_or_free (buf, size);
4008 if (buf == NULL)
4009 return -1;
4011 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
4013 free (buf);
4014 return -1;
4017 nread = bfd_bread (buf, size, abfd);
4019 if (nread != size)
4021 free (buf);
4022 return -1;
4025 for (offset = 4; offset <= size; offset += 4)
4027 unsigned long val;
4029 val = *((unsigned long *) (buf + size - offset));
4030 if (! found_nonnull)
4032 if (val != 0)
4033 found_nonnull = 1;
4035 else if (val == 0x0)
4037 unsigned long bottom;
4038 unsigned long top;
4040 bottom = seg->fileoff + seg->filesize - offset;
4041 top = seg->fileoff + seg->filesize - 4;
4042 *rbuf = bfd_malloc (top - bottom);
4043 *rlen = top - bottom;
4045 memcpy (*rbuf, buf + size - *rlen, *rlen);
4046 free (buf);
4047 return 0;
4051 if (size == (end - start))
4052 break;
4054 size *= 2;
4057 free (buf);
4061 return -1;
4064 char *
4065 bfd_mach_o_core_file_failing_command (bfd *abfd)
4067 unsigned char *buf = NULL;
4068 unsigned int len = 0;
4069 int ret = -1;
4071 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
4072 if (ret < 0)
4073 return NULL;
4075 return (char *) buf;
4079 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
4081 return 0;
4084 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
4085 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4087 #define bfd_mach_o_swap_reloc_in NULL
4088 #define bfd_mach_o_swap_reloc_out NULL
4089 #define bfd_mach_o_print_thread NULL
4091 #define TARGET_NAME mach_o_be_vec
4092 #define TARGET_STRING "mach-o-be"
4093 #define TARGET_ARCHITECTURE bfd_arch_unknown
4094 #define TARGET_BIG_ENDIAN 1
4095 #define TARGET_ARCHIVE 0
4096 #include "mach-o-target.c"
4098 #undef TARGET_NAME
4099 #undef TARGET_STRING
4100 #undef TARGET_ARCHITECTURE
4101 #undef TARGET_BIG_ENDIAN
4102 #undef TARGET_ARCHIVE
4104 #define TARGET_NAME mach_o_le_vec
4105 #define TARGET_STRING "mach-o-le"
4106 #define TARGET_ARCHITECTURE bfd_arch_unknown
4107 #define TARGET_BIG_ENDIAN 0
4108 #define TARGET_ARCHIVE 0
4110 #include "mach-o-target.c"
4112 #undef TARGET_NAME
4113 #undef TARGET_STRING
4114 #undef TARGET_ARCHITECTURE
4115 #undef TARGET_BIG_ENDIAN
4116 #undef TARGET_ARCHIVE
4118 /* Not yet handled: creating an archive. */
4119 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4121 /* Not used. */
4122 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4123 #define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4124 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4125 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4126 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4127 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4128 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4129 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
4130 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
4131 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4133 #define TARGET_NAME mach_o_fat_vec
4134 #define TARGET_STRING "mach-o-fat"
4135 #define TARGET_ARCHITECTURE bfd_arch_unknown
4136 #define TARGET_BIG_ENDIAN 1
4137 #define TARGET_ARCHIVE 1
4139 #include "mach-o-target.c"
4141 #undef TARGET_NAME
4142 #undef TARGET_STRING
4143 #undef TARGET_ARCHITECTURE
4144 #undef TARGET_BIG_ENDIAN
4145 #undef TARGET_ARCHIVE