2010-05-25 Tristan Gingold <gingold@adacore.com>
[binutils.git] / bfd / mach-o.c
blobd913d3c45ef6b792db6fda4e62abcff0a22f485f
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 2009, 2010
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 <ctype.h>
31 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p
32 #define bfd_mach_o_core_p bfd_mach_o_gen_core_p
33 #define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
35 #define FILE_ALIGN(off, algn) \
36 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
38 static int bfd_mach_o_read_symtab_symbols (bfd *);
40 unsigned int
41 bfd_mach_o_version (bfd *abfd)
43 bfd_mach_o_data_struct *mdata = NULL;
45 BFD_ASSERT (bfd_mach_o_valid (abfd));
46 mdata = bfd_mach_o_get_data (abfd);
48 return mdata->header.version;
51 bfd_boolean
52 bfd_mach_o_valid (bfd *abfd)
54 if (abfd == NULL || abfd->xvec == NULL)
55 return FALSE;
57 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
58 return FALSE;
60 if (bfd_mach_o_get_data (abfd) == NULL)
61 return FALSE;
62 return TRUE;
65 static INLINE bfd_boolean
66 mach_o_wide_p (bfd_mach_o_header *header)
68 switch (header->version)
70 case 1:
71 return FALSE;
72 case 2:
73 return TRUE;
74 default:
75 BFD_FAIL ();
76 return FALSE;
80 static INLINE bfd_boolean
81 bfd_mach_o_wide_p (bfd *abfd)
83 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
86 /* Tables to translate well known Mach-O segment/section names to bfd
87 names. Use of canonical names (such as .text or .debug_frame) is required
88 by gdb. */
90 struct mach_o_section_name_xlat
92 const char *bfd_name;
93 const char *mach_o_name;
94 flagword flags;
97 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
99 { ".debug_frame", "__debug_frame", SEC_DEBUGGING },
100 { ".debug_info", "__debug_info", SEC_DEBUGGING },
101 { ".debug_abbrev", "__debug_abbrev", SEC_DEBUGGING },
102 { ".debug_aranges", "__debug_aranges", SEC_DEBUGGING },
103 { ".debug_macinfo", "__debug_macinfo", SEC_DEBUGGING },
104 { ".debug_line", "__debug_line", SEC_DEBUGGING },
105 { ".debug_loc", "__debug_loc", SEC_DEBUGGING },
106 { ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING },
107 { ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING },
108 { ".debug_str", "__debug_str", SEC_DEBUGGING },
109 { ".debug_ranges", "__debug_ranges", SEC_DEBUGGING },
110 { NULL, NULL, 0}
113 static const struct mach_o_section_name_xlat text_section_names_xlat[] =
115 { ".text", "__text", SEC_CODE | SEC_LOAD },
116 { ".const", "__const", SEC_READONLY | SEC_DATA | SEC_LOAD },
117 { ".cstring", "__cstring", SEC_READONLY | SEC_DATA | SEC_LOAD },
118 { ".eh_frame", "__eh_frame", SEC_READONLY | SEC_LOAD },
119 { NULL, NULL, 0}
122 static const struct mach_o_section_name_xlat data_section_names_xlat[] =
124 { ".data", "__data", SEC_DATA | SEC_LOAD },
125 { ".const_data", "__const", SEC_DATA | SEC_LOAD },
126 { ".dyld", "__dyld", SEC_DATA | SEC_LOAD },
127 { ".lazy_symbol_ptr", "__la_symbol_ptr", SEC_DATA | SEC_LOAD },
128 { ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD },
129 { ".bss", "__bss", SEC_NO_FLAGS },
130 { NULL, NULL, 0}
133 struct mach_o_segment_name_xlat
135 const char *segname;
136 const struct mach_o_section_name_xlat *sections;
139 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
141 { "__DWARF", dwarf_section_names_xlat },
142 { "__TEXT", text_section_names_xlat },
143 { "__DATA", data_section_names_xlat },
144 { NULL, NULL }
148 /* Mach-O to bfd names. */
150 static void
151 bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
152 char **name, flagword *flags)
154 const struct mach_o_segment_name_xlat *seg;
155 char *res;
156 unsigned int len;
157 const char *pfx = "";
159 *name = NULL;
160 *flags = SEC_NO_FLAGS;
162 for (seg = segsec_names_xlat; seg->segname; seg++)
164 if (strcmp (seg->segname, section->segname) == 0)
166 const struct mach_o_section_name_xlat *sec;
168 for (sec = seg->sections; sec->mach_o_name; sec++)
170 if (strcmp (sec->mach_o_name, section->sectname) == 0)
172 len = strlen (sec->bfd_name);
173 res = bfd_alloc (abfd, len + 1);
175 if (res == NULL)
176 return;
177 strcpy (res, sec->bfd_name);
178 *name = res;
179 *flags = sec->flags;
180 return;
186 len = strlen (section->segname) + 1
187 + strlen (section->sectname) + 1;
189 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
190 with an underscore. */
191 if (section->segname[0] != '_')
193 static const char seg_pfx[] = "LC_SEGMENT.";
195 pfx = seg_pfx;
196 len += sizeof (seg_pfx) - 1;
199 res = bfd_alloc (abfd, len);
200 if (res == NULL)
201 return;
202 snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
203 *name = res;
206 /* Convert a bfd section name to a Mach-O segment + section name. */
208 static void
209 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
210 asection *sect,
211 bfd_mach_o_section *section)
213 const struct mach_o_segment_name_xlat *seg;
214 const char *name = bfd_get_section_name (abfd, sect);
215 const char *dot;
216 unsigned int len;
217 unsigned int seglen;
218 unsigned int seclen;
220 /* List of well known names. They all start with a dot. */
221 if (name[0] == '.')
222 for (seg = segsec_names_xlat; seg->segname; seg++)
224 const struct mach_o_section_name_xlat *sec;
226 for (sec = seg->sections; sec->mach_o_name; sec++)
228 if (strcmp (sec->bfd_name, name) == 0)
230 strcpy (section->segname, seg->segname);
231 strcpy (section->sectname, sec->mach_o_name);
232 return;
237 /* Strip LC_SEGMENT. prefix. */
238 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
239 name += 11;
241 /* Find a dot. */
242 dot = strchr (name, '.');
243 len = strlen (name);
245 /* Try to split name into segment and section names. */
246 if (dot && dot != name)
248 seglen = dot - name;
249 seclen = len - (dot + 1 - name);
251 if (seglen < 16 && seclen < 16)
253 memcpy (section->segname, name, seglen);
254 section->segname[seglen] = 0;
255 memcpy (section->sectname, dot + 1, seclen);
256 section->sectname[seclen] = 0;
257 return;
261 if (len > 16)
262 len = 16;
263 memcpy (section->segname, name, len);
264 section->segname[len] = 0;
265 memcpy (section->sectname, name, len);
266 section->sectname[len] = 0;
269 /* Return the size of an entry for section SEC.
270 Must be called only for symbol pointer section and symbol stubs
271 sections. */
273 static unsigned int
274 bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
276 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
278 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
279 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
280 return bfd_mach_o_wide_p (abfd) ? 8 : 4;
281 case BFD_MACH_O_S_SYMBOL_STUBS:
282 return sec->reserved2;
283 default:
284 BFD_FAIL ();
285 return 0;
289 /* Return the number of indirect symbols for a section.
290 Must be called only for symbol pointer section and symbol stubs
291 sections. */
293 static unsigned int
294 bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
296 unsigned int elsz;
298 elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
299 if (elsz == 0)
300 return 0;
301 else
302 return sec->size / elsz;
306 /* Copy any private info we understand from the input symbol
307 to the output symbol. */
309 bfd_boolean
310 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
311 asymbol *isymbol ATTRIBUTE_UNUSED,
312 bfd *obfd ATTRIBUTE_UNUSED,
313 asymbol *osymbol ATTRIBUTE_UNUSED)
315 return TRUE;
318 /* Copy any private info we understand from the input section
319 to the output section. */
321 bfd_boolean
322 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
323 asection *isection ATTRIBUTE_UNUSED,
324 bfd *obfd ATTRIBUTE_UNUSED,
325 asection *osection ATTRIBUTE_UNUSED)
327 return TRUE;
330 /* Copy any private info we understand from the input bfd
331 to the output bfd. */
333 bfd_boolean
334 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
336 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
337 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
338 return TRUE;
340 BFD_ASSERT (bfd_mach_o_valid (ibfd));
341 BFD_ASSERT (bfd_mach_o_valid (obfd));
343 /* FIXME: copy commands. */
345 return TRUE;
348 /* Count the total number of symbols. */
350 static long
351 bfd_mach_o_count_symbols (bfd *abfd)
353 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
355 if (mdata->symtab == NULL)
356 return 0;
357 return mdata->symtab->nsyms;
360 long
361 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
363 long nsyms = bfd_mach_o_count_symbols (abfd);
365 return ((nsyms + 1) * sizeof (asymbol *));
368 long
369 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
371 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
372 long nsyms = bfd_mach_o_count_symbols (abfd);
373 bfd_mach_o_symtab_command *sym = mdata->symtab;
374 unsigned long j;
376 if (nsyms < 0)
377 return nsyms;
379 if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
381 fprintf (stderr,
382 "bfd_mach_o_canonicalize_symtab: unable to load symbols\n");
383 return 0;
386 BFD_ASSERT (sym->symbols != NULL);
388 for (j = 0; j < sym->nsyms; j++)
389 alocation[j] = &sym->symbols[j].symbol;
391 alocation[j] = NULL;
393 return nsyms;
396 long
397 bfd_mach_o_get_synthetic_symtab (bfd *abfd,
398 long symcount ATTRIBUTE_UNUSED,
399 asymbol **syms ATTRIBUTE_UNUSED,
400 long dynsymcount ATTRIBUTE_UNUSED,
401 asymbol **dynsyms ATTRIBUTE_UNUSED,
402 asymbol **ret)
404 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
405 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
406 bfd_mach_o_symtab_command *symtab = mdata->symtab;
407 asymbol *s;
408 unsigned long count, i, j, n;
409 size_t size;
410 char *names;
411 char *nul_name;
413 *ret = NULL;
415 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
416 return 0;
418 if (dysymtab->nindirectsyms == 0)
419 return 0;
421 count = dysymtab->nindirectsyms;
422 size = count * sizeof (asymbol) + 1;
424 for (j = 0; j < count; j++)
426 unsigned int isym = dysymtab->indirect_syms[j];
428 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
429 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
432 s = *ret = (asymbol *) bfd_malloc (size);
433 if (s == NULL)
434 return -1;
435 names = (char *) (s + count);
436 nul_name = names;
437 *names++ = 0;
439 n = 0;
440 for (i = 0; i < mdata->nsects; i++)
442 bfd_mach_o_section *sec = mdata->sections[i];
443 unsigned int first, last;
444 bfd_vma addr;
445 bfd_vma entry_size;
447 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
449 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
450 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
451 case BFD_MACH_O_S_SYMBOL_STUBS:
452 first = sec->reserved1;
453 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
454 addr = sec->addr;
455 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
456 for (j = first; j < last; j++)
458 unsigned int isym = dysymtab->indirect_syms[j];
460 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
461 s->section = sec->bfdsection;
462 s->value = addr - sec->addr;
463 s->udata.p = NULL;
465 if (isym < symtab->nsyms
466 && symtab->symbols[isym].symbol.name)
468 const char *sym = symtab->symbols[isym].symbol.name;
469 size_t len;
471 s->name = names;
472 len = strlen (sym);
473 memcpy (names, sym, len);
474 names += len;
475 memcpy (names, "$stub", sizeof ("$stub"));
476 names += sizeof ("$stub");
478 else
479 s->name = nul_name;
481 addr += entry_size;
482 s++;
483 n++;
485 break;
486 default:
487 break;
491 return n;
494 void
495 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
496 asymbol *symbol,
497 symbol_info *ret)
499 bfd_symbol_info (symbol, ret);
502 void
503 bfd_mach_o_print_symbol (bfd *abfd,
504 void * afile,
505 asymbol *symbol,
506 bfd_print_symbol_type how)
508 FILE *file = (FILE *) afile;
509 const char *name;
510 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
512 switch (how)
514 case bfd_print_symbol_name:
515 fprintf (file, "%s", symbol->name);
516 break;
517 default:
518 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
519 if (asym->n_type & BFD_MACH_O_N_STAB)
520 name = bfd_get_stab_name (asym->n_type);
521 else
522 switch (asym->n_type & BFD_MACH_O_N_TYPE)
524 case BFD_MACH_O_N_UNDF:
525 name = "UND";
526 break;
527 case BFD_MACH_O_N_ABS:
528 name = "ABS";
529 break;
530 case BFD_MACH_O_N_INDR:
531 name = "INDR";
532 break;
533 case BFD_MACH_O_N_PBUD:
534 name = "PBUD";
535 break;
536 case BFD_MACH_O_N_SECT:
537 name = "SECT";
538 break;
539 default:
540 name = "???";
541 break;
543 if (name == NULL)
544 name = "";
545 fprintf (file, " %02x %-6s %02x %04x",
546 asym->n_type, name, asym->n_sect, asym->n_desc);
547 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
548 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
549 fprintf (file, " %-5s", symbol->section->name);
550 fprintf (file, " %s", symbol->name);
554 static void
555 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
556 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
557 enum bfd_architecture *type,
558 unsigned long *subtype)
560 *subtype = bfd_arch_unknown;
562 switch (mtype)
564 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
565 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
566 case BFD_MACH_O_CPU_TYPE_I386:
567 *type = bfd_arch_i386;
568 *subtype = bfd_mach_i386_i386;
569 break;
570 case BFD_MACH_O_CPU_TYPE_X86_64:
571 *type = bfd_arch_i386;
572 *subtype = bfd_mach_x86_64;
573 break;
574 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
575 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
576 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
577 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
578 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
579 case BFD_MACH_O_CPU_TYPE_SPARC:
580 *type = bfd_arch_sparc;
581 *subtype = bfd_mach_sparc;
582 break;
583 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
584 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
585 case BFD_MACH_O_CPU_TYPE_POWERPC:
586 *type = bfd_arch_powerpc;
587 *subtype = bfd_mach_ppc;
588 break;
589 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
590 *type = bfd_arch_powerpc;
591 *subtype = bfd_mach_ppc64;
592 break;
593 default:
594 *type = bfd_arch_unknown;
595 break;
599 static bfd_boolean
600 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
602 unsigned char buf[32];
603 unsigned int size;
605 size = mach_o_wide_p (header) ?
606 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
608 bfd_h_put_32 (abfd, header->magic, buf + 0);
609 bfd_h_put_32 (abfd, header->cputype, buf + 4);
610 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
611 bfd_h_put_32 (abfd, header->filetype, buf + 12);
612 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
613 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
614 bfd_h_put_32 (abfd, header->flags, buf + 24);
616 if (mach_o_wide_p (header))
617 bfd_h_put_32 (abfd, header->reserved, buf + 28);
619 if (bfd_seek (abfd, 0, SEEK_SET) != 0
620 || bfd_bwrite ((void *) buf, size, abfd) != size)
621 return FALSE;
623 return TRUE;
626 static int
627 bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
629 bfd_mach_o_thread_command *cmd = &command->command.thread;
630 unsigned int i;
631 unsigned char buf[8];
632 unsigned int offset;
633 unsigned int nflavours;
635 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
636 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
638 offset = 8;
639 nflavours = 0;
640 for (i = 0; i < cmd->nflavours; i++)
642 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
643 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
645 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
646 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
648 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
649 || bfd_bwrite ((void *) buf, 8, abfd) != 8)
650 return -1;
652 offset += cmd->flavours[i].size + 8;
655 return 0;
658 long
659 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
660 asection *asect)
662 return (asect->reloc_count + 1) * sizeof (arelent *);
665 static int
666 bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
667 arelent *res, asymbol **syms)
669 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
670 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
671 bfd_mach_o_reloc_info reloc;
672 bfd_vma addr;
673 bfd_vma symnum;
674 asymbol **sym;
676 addr = bfd_get_32 (abfd, buf + 0);
677 symnum = bfd_get_32 (abfd, buf + 4);
679 if (addr & BFD_MACH_O_SR_SCATTERED)
681 unsigned int j;
683 /* Scattered relocation.
684 Extract section and offset from r_value. */
685 res->sym_ptr_ptr = NULL;
686 res->addend = 0;
687 for (j = 0; j < mdata->nsects; j++)
689 bfd_mach_o_section *sect = mdata->sections[j];
690 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
692 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
693 res->addend = symnum - sect->addr;
694 break;
697 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
698 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
699 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
700 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
701 reloc.r_scattered = 1;
703 else
705 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
706 res->addend = 0;
707 res->address = addr;
708 if (symnum & BFD_MACH_O_R_EXTERN)
710 sym = syms + num;
711 reloc.r_extern = 1;
713 else
715 BFD_ASSERT (num != 0);
716 BFD_ASSERT (num <= mdata->nsects);
717 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
718 /* For a symbol defined in section S, the addend (stored in the
719 binary) contains the address of the section. To comply with
720 bfd conventio, substract the section address.
721 Use the address from the header, so that the user can modify
722 the vma of the section. */
723 res->addend = -mdata->sections[num - 1]->addr;
724 reloc.r_extern = 0;
726 res->sym_ptr_ptr = sym;
727 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
728 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
729 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
730 reloc.r_scattered = 0;
733 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
734 return -1;
735 return 0;
738 static int
739 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
740 unsigned long count,
741 arelent *res, asymbol **syms)
743 unsigned long i;
744 char *native_relocs;
745 bfd_size_type native_size;
747 /* Allocate and read relocs. */
748 native_size = count * BFD_MACH_O_RELENT_SIZE;
749 native_relocs = bfd_malloc (native_size);
750 if (native_relocs == NULL)
751 return -1;
753 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
754 || bfd_bread (native_relocs, native_size, abfd) != native_size)
755 goto err;
757 for (i = 0; i < count; i++)
759 char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
761 if (bfd_mach_o_canonicalize_one_reloc (abfd, buf, &res[i], syms) < 0)
762 goto err;
764 free (native_relocs);
765 return i;
766 err:
767 free (native_relocs);
768 return -1;
771 long
772 bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
773 arelent **rels, asymbol **syms)
775 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
776 unsigned long i;
777 arelent *res;
779 if (asect->reloc_count == 0)
780 return 0;
782 /* No need to go further if we don't know how to read relocs. */
783 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
784 return 0;
786 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
787 if (res == NULL)
788 return -1;
790 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
791 asect->reloc_count, res, syms) < 0)
793 free (res);
794 return -1;
797 for (i = 0; i < asect->reloc_count; i++)
798 rels[i] = &res[i];
799 rels[i] = NULL;
800 asect->relocation = res;
802 return i;
805 long
806 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
808 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
810 if (mdata->dysymtab == NULL)
811 return 1;
812 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
813 * sizeof (arelent *);
816 long
817 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
818 struct bfd_symbol **syms)
820 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
821 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
822 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
823 unsigned long i;
824 arelent *res;
826 if (dysymtab == NULL)
827 return 0;
828 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
829 return 0;
831 /* No need to go further if we don't know how to read relocs. */
832 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
833 return 0;
835 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
836 if (res == NULL)
837 return -1;
839 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
840 dysymtab->nextrel, res, syms) < 0)
842 free (res);
843 return -1;
846 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
847 dysymtab->nlocrel,
848 res + dysymtab->nextrel, syms) < 0)
850 free (res);
851 return -1;
854 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
855 rels[i] = &res[i];
856 rels[i] = NULL;
857 return i;
860 static bfd_boolean
861 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
863 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
864 unsigned int i;
865 arelent **entries;
866 asection *sec;
867 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
869 sec = section->bfdsection;
870 if (sec->reloc_count == 0)
871 return TRUE;
873 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
874 return TRUE;
876 /* Allocate relocation room. */
877 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
878 section->nreloc = sec->reloc_count;
879 sec->rel_filepos = mdata->filelen;
880 section->reloff = sec->rel_filepos;
881 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
883 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
884 return FALSE;
886 /* Convert and write. */
887 entries = section->bfdsection->orelocation;
888 for (i = 0; i < section->nreloc; i++)
890 arelent *rel = entries[i];
891 char buf[8];
892 bfd_mach_o_reloc_info info, *pinfo = &info;
894 /* Convert relocation to an intermediate representation. */
895 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
896 return FALSE;
898 /* Lower the relocation info. */
899 if (pinfo->r_scattered)
901 unsigned long v;
903 v = BFD_MACH_O_SR_SCATTERED
904 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
905 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
906 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
907 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
908 bfd_put_32 (abfd, v, buf);
909 bfd_put_32 (abfd, pinfo->r_value, buf + 4);
911 else
913 unsigned long v;
915 bfd_put_32 (abfd, pinfo->r_address, buf);
916 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
917 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
918 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
919 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
920 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
921 bfd_put_32 (abfd, v, buf + 4);
924 if (bfd_bwrite ((void *) buf, BFD_MACH_O_RELENT_SIZE, abfd)
925 != BFD_MACH_O_RELENT_SIZE)
926 return FALSE;
928 return TRUE;
931 static int
932 bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
934 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
936 memcpy (buf, section->sectname, 16);
937 memcpy (buf + 16, section->segname, 16);
938 bfd_h_put_32 (abfd, section->addr, buf + 32);
939 bfd_h_put_32 (abfd, section->size, buf + 36);
940 bfd_h_put_32 (abfd, section->offset, buf + 40);
941 bfd_h_put_32 (abfd, section->align, buf + 44);
942 bfd_h_put_32 (abfd, section->reloff, buf + 48);
943 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
944 bfd_h_put_32 (abfd, section->flags, buf + 56);
945 bfd_h_put_32 (abfd, section->reserved1, buf + 60);
946 bfd_h_put_32 (abfd, section->reserved2, buf + 64);
948 if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
949 != BFD_MACH_O_SECTION_SIZE)
950 return -1;
952 return 0;
955 static int
956 bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
958 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
960 memcpy (buf, section->sectname, 16);
961 memcpy (buf + 16, section->segname, 16);
962 bfd_h_put_64 (abfd, section->addr, buf + 32);
963 bfd_h_put_64 (abfd, section->size, buf + 40);
964 bfd_h_put_32 (abfd, section->offset, buf + 48);
965 bfd_h_put_32 (abfd, section->align, buf + 52);
966 bfd_h_put_32 (abfd, section->reloff, buf + 56);
967 bfd_h_put_32 (abfd, section->nreloc, buf + 60);
968 bfd_h_put_32 (abfd, section->flags, buf + 64);
969 bfd_h_put_32 (abfd, section->reserved1, buf + 68);
970 bfd_h_put_32 (abfd, section->reserved2, buf + 72);
971 bfd_h_put_32 (abfd, section->reserved3, buf + 76);
973 if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
974 != BFD_MACH_O_SECTION_64_SIZE)
975 return -1;
977 return 0;
980 static int
981 bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
983 unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
984 bfd_mach_o_segment_command *seg = &command->command.segment;
985 unsigned long i;
987 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
989 for (i = 0; i < seg->nsects; i++)
990 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
991 return -1;
993 memcpy (buf, seg->segname, 16);
994 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
995 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
996 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
997 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
998 bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
999 bfd_h_put_32 (abfd, seg->initprot, buf + 36);
1000 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
1001 bfd_h_put_32 (abfd, seg->flags, buf + 44);
1003 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1004 || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd)
1005 != BFD_MACH_O_LC_SEGMENT_SIZE - 8))
1006 return -1;
1008 for (i = 0; i < seg->nsects; i++)
1009 if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
1010 return -1;
1012 return 0;
1015 static int
1016 bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1018 unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
1019 bfd_mach_o_segment_command *seg = &command->command.segment;
1020 unsigned long i;
1022 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1024 for (i = 0; i < seg->nsects; i++)
1025 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
1026 return -1;
1028 memcpy (buf, seg->segname, 16);
1029 bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
1030 bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
1031 bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
1032 bfd_h_put_64 (abfd, seg->filesize, buf + 40);
1033 bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
1034 bfd_h_put_32 (abfd, seg->initprot, buf + 52);
1035 bfd_h_put_32 (abfd, seg->nsects, buf + 56);
1036 bfd_h_put_32 (abfd, seg->flags, buf + 60);
1038 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1039 || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
1040 != BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
1041 return -1;
1043 for (i = 0; i < seg->nsects; i++)
1044 if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
1045 return -1;
1047 return 0;
1050 static bfd_boolean
1051 bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1053 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1054 bfd_mach_o_symtab_command *sym = &command->command.symtab;
1055 unsigned char buf[16];
1056 unsigned long i;
1057 unsigned int wide = bfd_mach_o_wide_p (abfd);
1058 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1059 struct bfd_strtab_hash *strtab;
1060 asymbol **symbols = bfd_get_outsymbols (abfd);
1062 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1064 /* Write the symbols first. */
1065 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1066 sym->symoff = mdata->filelen;
1067 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1068 return FALSE;
1070 sym->nsyms = bfd_get_symcount (abfd);
1071 mdata->filelen += sym->nsyms * symlen;
1073 strtab = _bfd_stringtab_init ();
1074 if (strtab == NULL)
1075 return FALSE;
1077 for (i = 0; i < sym->nsyms; i++)
1079 bfd_size_type str_index;
1080 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1082 /* Compute name index. */
1083 /* An index of 0 always means the empty string. */
1084 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
1085 str_index = 0;
1086 else
1088 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1089 if (str_index == (bfd_size_type) -1)
1090 goto err;
1092 bfd_h_put_32 (abfd, str_index, buf);
1093 bfd_h_put_8 (abfd, s->n_type, buf + 4);
1094 bfd_h_put_8 (abfd, s->n_sect, buf + 5);
1095 bfd_h_put_16 (abfd, s->n_desc, buf + 6);
1096 if (wide)
1097 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1098 else
1099 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1101 if (bfd_bwrite ((void *) buf, symlen, abfd) != symlen)
1102 goto err;
1104 sym->strsize = _bfd_stringtab_size (strtab);
1105 sym->stroff = mdata->filelen;
1106 mdata->filelen += sym->strsize;
1108 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1109 goto err;
1110 _bfd_stringtab_free (strtab);
1112 /* The command. */
1113 bfd_h_put_32 (abfd, sym->symoff, buf);
1114 bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
1115 bfd_h_put_32 (abfd, sym->stroff, buf + 8);
1116 bfd_h_put_32 (abfd, sym->strsize, buf + 12);
1118 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1119 || bfd_bwrite ((void *) buf, 16, abfd) != 16)
1120 return FALSE;
1122 return TRUE;
1124 err:
1125 _bfd_stringtab_free (strtab);
1126 return FALSE;
1129 /* Process the symbols and generate Mach-O specific fields.
1130 Number them. */
1132 static bfd_boolean
1133 bfd_mach_o_mangle_symbols (bfd *abfd)
1135 unsigned long i;
1136 asymbol **symbols = bfd_get_outsymbols (abfd);
1138 for (i = 0; i < bfd_get_symcount (abfd); i++)
1140 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1142 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1144 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1145 symbols should be N_UNDEF | N_EXT), we suppose the back-end
1146 values haven't been set. */
1147 if (s->symbol.section == bfd_abs_section_ptr)
1148 s->n_type = BFD_MACH_O_N_ABS;
1149 else if (s->symbol.section == bfd_und_section_ptr)
1151 s->n_type = BFD_MACH_O_N_UNDF;
1152 if (s->symbol.flags & BSF_WEAK)
1153 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1155 else if (s->symbol.section == bfd_com_section_ptr)
1156 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1157 else
1158 s->n_type = BFD_MACH_O_N_SECT;
1160 if (s->symbol.flags & BSF_GLOBAL)
1161 s->n_type |= BFD_MACH_O_N_EXT;
1164 /* Compute section index. */
1165 if (s->symbol.section != bfd_abs_section_ptr
1166 && s->symbol.section != bfd_und_section_ptr
1167 && s->symbol.section != bfd_com_section_ptr)
1168 s->n_sect = s->symbol.section->target_index;
1170 /* Number symbols. */
1171 s->symbol.udata.i = i;
1173 return TRUE;
1176 bfd_boolean
1177 bfd_mach_o_write_contents (bfd *abfd)
1179 unsigned int i;
1180 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1182 if (mdata->header.ncmds == 0)
1183 if (!bfd_mach_o_build_commands (abfd))
1184 return FALSE;
1186 /* Now write header information. */
1187 if (mdata->header.filetype == 0)
1189 if (abfd->flags & EXEC_P)
1190 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1191 else if (abfd->flags & DYNAMIC)
1192 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1193 else
1194 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1196 if (!bfd_mach_o_write_header (abfd, &mdata->header))
1197 return FALSE;
1199 /* Assign a number to each symbols. */
1200 if (!bfd_mach_o_mangle_symbols (abfd))
1201 return FALSE;
1203 for (i = 0; i < mdata->header.ncmds; i++)
1205 unsigned char buf[8];
1206 bfd_mach_o_load_command *cur = &mdata->commands[i];
1207 unsigned long typeflag;
1209 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
1211 bfd_h_put_32 (abfd, typeflag, buf);
1212 bfd_h_put_32 (abfd, cur->len, buf + 4);
1214 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1215 || bfd_bwrite ((void *) buf, 8, abfd) != 8)
1216 return FALSE;
1218 switch (cur->type)
1220 case BFD_MACH_O_LC_SEGMENT:
1221 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1222 return FALSE;
1223 break;
1224 case BFD_MACH_O_LC_SEGMENT_64:
1225 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
1226 return FALSE;
1227 break;
1228 case BFD_MACH_O_LC_SYMTAB:
1229 if (!bfd_mach_o_write_symtab (abfd, cur))
1230 return FALSE;
1231 break;
1232 case BFD_MACH_O_LC_SYMSEG:
1233 break;
1234 case BFD_MACH_O_LC_THREAD:
1235 case BFD_MACH_O_LC_UNIXTHREAD:
1236 if (bfd_mach_o_write_thread (abfd, cur) != 0)
1237 return FALSE;
1238 break;
1239 case BFD_MACH_O_LC_LOADFVMLIB:
1240 case BFD_MACH_O_LC_IDFVMLIB:
1241 case BFD_MACH_O_LC_IDENT:
1242 case BFD_MACH_O_LC_FVMFILE:
1243 case BFD_MACH_O_LC_PREPAGE:
1244 case BFD_MACH_O_LC_DYSYMTAB:
1245 case BFD_MACH_O_LC_LOAD_DYLIB:
1246 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1247 case BFD_MACH_O_LC_ID_DYLIB:
1248 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1249 case BFD_MACH_O_LC_LOAD_DYLINKER:
1250 case BFD_MACH_O_LC_ID_DYLINKER:
1251 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1252 case BFD_MACH_O_LC_ROUTINES:
1253 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1254 break;
1255 default:
1256 fprintf (stderr,
1257 "unable to write unknown load command 0x%lx\n",
1258 (unsigned long) cur->type);
1259 return FALSE;
1263 return TRUE;
1266 /* Build Mach-O load commands from the sections. */
1268 bfd_boolean
1269 bfd_mach_o_build_commands (bfd *abfd)
1271 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1272 unsigned int wide = mach_o_wide_p (&mdata->header);
1273 bfd_mach_o_segment_command *seg;
1274 bfd_mach_o_section *sections;
1275 asection *sec;
1276 bfd_mach_o_load_command *cmd;
1277 bfd_mach_o_load_command *symtab_cmd;
1278 int target_index;
1280 /* Return now if commands are already built. */
1281 if (mdata->header.ncmds)
1282 return FALSE;
1284 /* Very simple version: 1 command (segment) containing all sections. */
1285 mdata->header.ncmds = 2;
1286 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1287 * sizeof (bfd_mach_o_load_command));
1288 if (mdata->commands == NULL)
1289 return FALSE;
1290 cmd = &mdata->commands[0];
1291 seg = &cmd->command.segment;
1293 seg->nsects = bfd_count_sections (abfd);
1294 sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1295 if (sections == NULL)
1296 return FALSE;
1297 seg->sections = sections;
1299 /* Set segment command. */
1300 if (wide)
1302 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1303 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1304 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1305 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1307 else
1309 cmd->type = BFD_MACH_O_LC_SEGMENT;
1310 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1311 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1312 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1314 cmd->type_required = FALSE;
1315 mdata->header.sizeofcmds = cmd->len;
1316 mdata->filelen = cmd->offset + cmd->len;
1318 /* Set symtab command. */
1319 symtab_cmd = &mdata->commands[1];
1321 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1322 symtab_cmd->offset = cmd->offset + cmd->len;
1323 symtab_cmd->len = 6 * 4;
1324 symtab_cmd->type_required = FALSE;
1326 mdata->header.sizeofcmds += symtab_cmd->len;
1327 mdata->filelen += symtab_cmd->len;
1329 /* Fill segment command. */
1330 memset (seg->segname, 0, sizeof (seg->segname));
1331 seg->vmaddr = 0;
1332 seg->fileoff = mdata->filelen;
1333 seg->filesize = 0;
1334 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1335 | BFD_MACH_O_PROT_EXECUTE;
1336 seg->initprot = seg->maxprot;
1337 seg->flags = 0;
1339 /* Create Mach-O sections. */
1340 target_index = 0;
1341 for (sec = abfd->sections; sec; sec = sec->next)
1343 sections->bfdsection = sec;
1344 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
1345 sections->addr = bfd_get_section_vma (abfd, sec);
1346 sections->size = bfd_get_section_size (sec);
1347 sections->align = bfd_get_section_alignment (abfd, sec);
1349 if (sections->size != 0)
1351 mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
1352 sections->offset = mdata->filelen;
1354 else
1355 sections->offset = 0;
1356 sections->reloff = 0;
1357 sections->nreloc = 0;
1358 sections->reserved1 = 0;
1359 sections->reserved2 = 0;
1360 sections->reserved3 = 0;
1362 sec->filepos = sections->offset;
1363 sec->target_index = ++target_index;
1365 mdata->filelen += sections->size;
1366 sections++;
1368 seg->filesize = mdata->filelen - seg->fileoff;
1369 seg->vmsize = seg->filesize;
1371 return TRUE;
1374 /* Set the contents of a section. */
1376 bfd_boolean
1377 bfd_mach_o_set_section_contents (bfd *abfd,
1378 asection *section,
1379 const void * location,
1380 file_ptr offset,
1381 bfd_size_type count)
1383 file_ptr pos;
1385 /* This must be done first, because bfd_set_section_contents is
1386 going to set output_has_begun to TRUE. */
1387 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1388 return FALSE;
1390 if (count == 0)
1391 return TRUE;
1393 pos = section->filepos + offset;
1394 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1395 || bfd_bwrite (location, count, abfd) != count)
1396 return FALSE;
1398 return TRUE;
1402 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1403 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1405 return 0;
1408 /* Make an empty symbol. This is required only because
1409 bfd_make_section_anyway wants to create a symbol for the section. */
1411 asymbol *
1412 bfd_mach_o_make_empty_symbol (bfd *abfd)
1414 asymbol *new_symbol;
1416 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1417 if (new_symbol == NULL)
1418 return new_symbol;
1419 new_symbol->the_bfd = abfd;
1420 new_symbol->udata.i = 0;
1421 return new_symbol;
1424 static bfd_boolean
1425 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1427 unsigned char buf[32];
1428 unsigned int size;
1429 bfd_vma (*get32) (const void *) = NULL;
1431 /* Just read the magic number. */
1432 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1433 || bfd_bread ((void *) buf, 4, abfd) != 4)
1434 return FALSE;
1436 if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
1438 header->byteorder = BFD_ENDIAN_BIG;
1439 header->magic = BFD_MACH_O_MH_MAGIC;
1440 header->version = 1;
1441 get32 = bfd_getb32;
1443 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
1445 header->byteorder = BFD_ENDIAN_LITTLE;
1446 header->magic = BFD_MACH_O_MH_MAGIC;
1447 header->version = 1;
1448 get32 = bfd_getl32;
1450 else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1452 header->byteorder = BFD_ENDIAN_BIG;
1453 header->magic = BFD_MACH_O_MH_MAGIC_64;
1454 header->version = 2;
1455 get32 = bfd_getb32;
1457 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1459 header->byteorder = BFD_ENDIAN_LITTLE;
1460 header->magic = BFD_MACH_O_MH_MAGIC_64;
1461 header->version = 2;
1462 get32 = bfd_getl32;
1464 else
1466 header->byteorder = BFD_ENDIAN_UNKNOWN;
1467 return FALSE;
1470 /* Once the size of the header is known, read the full header. */
1471 size = mach_o_wide_p (header) ?
1472 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1474 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1475 || bfd_bread ((void *) buf, size, abfd) != size)
1476 return FALSE;
1478 header->cputype = (*get32) (buf + 4);
1479 header->cpusubtype = (*get32) (buf + 8);
1480 header->filetype = (*get32) (buf + 12);
1481 header->ncmds = (*get32) (buf + 16);
1482 header->sizeofcmds = (*get32) (buf + 20);
1483 header->flags = (*get32) (buf + 24);
1485 if (mach_o_wide_p (header))
1486 header->reserved = (*get32) (buf + 28);
1488 return TRUE;
1491 static asection *
1492 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
1493 unsigned long prot)
1495 asection *bfdsec;
1496 char *sname;
1497 flagword flags;
1499 bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
1500 if (sname == NULL)
1501 return NULL;
1503 if (flags == SEC_NO_FLAGS)
1505 /* Try to guess flags. */
1506 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1507 flags = SEC_DEBUGGING;
1508 else
1510 flags = SEC_ALLOC;
1511 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1512 != BFD_MACH_O_S_ZEROFILL)
1514 flags |= SEC_LOAD;
1515 if (prot & BFD_MACH_O_PROT_EXECUTE)
1516 flags |= SEC_CODE;
1517 if (prot & BFD_MACH_O_PROT_WRITE)
1518 flags |= SEC_DATA;
1519 else if (prot & BFD_MACH_O_PROT_READ)
1520 flags |= SEC_READONLY;
1524 else
1526 if ((flags & SEC_DEBUGGING) == 0)
1527 flags |= SEC_ALLOC;
1530 if (section->offset != 0)
1531 flags |= SEC_HAS_CONTENTS;
1532 if (section->nreloc != 0)
1533 flags |= SEC_RELOC;
1535 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1536 if (bfdsec == NULL)
1537 return NULL;
1539 bfdsec->vma = section->addr;
1540 bfdsec->lma = section->addr;
1541 bfdsec->size = section->size;
1542 bfdsec->filepos = section->offset;
1543 bfdsec->alignment_power = section->align;
1544 bfdsec->segment_mark = 0;
1545 bfdsec->reloc_count = section->nreloc;
1546 bfdsec->rel_filepos = section->reloff;
1548 return bfdsec;
1551 static int
1552 bfd_mach_o_read_section_32 (bfd *abfd,
1553 bfd_mach_o_section *section,
1554 unsigned int offset,
1555 unsigned long prot)
1557 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
1559 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1560 || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
1561 != BFD_MACH_O_SECTION_SIZE))
1562 return -1;
1564 memcpy (section->sectname, buf, 16);
1565 section->sectname[16] = '\0';
1566 memcpy (section->segname, buf + 16, 16);
1567 section->segname[16] = '\0';
1568 section->addr = bfd_h_get_32 (abfd, buf + 32);
1569 section->size = bfd_h_get_32 (abfd, buf + 36);
1570 section->offset = bfd_h_get_32 (abfd, buf + 40);
1571 section->align = bfd_h_get_32 (abfd, buf + 44);
1572 section->reloff = bfd_h_get_32 (abfd, buf + 48);
1573 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
1574 section->flags = bfd_h_get_32 (abfd, buf + 56);
1575 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
1576 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
1577 section->reserved3 = 0;
1578 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1580 if (section->bfdsection == NULL)
1581 return -1;
1583 return 0;
1586 static int
1587 bfd_mach_o_read_section_64 (bfd *abfd,
1588 bfd_mach_o_section *section,
1589 unsigned int offset,
1590 unsigned long prot)
1592 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
1594 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1595 || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
1596 != BFD_MACH_O_SECTION_64_SIZE))
1597 return -1;
1599 memcpy (section->sectname, buf, 16);
1600 section->sectname[16] = '\0';
1601 memcpy (section->segname, buf + 16, 16);
1602 section->segname[16] = '\0';
1603 section->addr = bfd_h_get_64 (abfd, buf + 32);
1604 section->size = bfd_h_get_64 (abfd, buf + 40);
1605 section->offset = bfd_h_get_32 (abfd, buf + 48);
1606 section->align = bfd_h_get_32 (abfd, buf + 52);
1607 section->reloff = bfd_h_get_32 (abfd, buf + 56);
1608 section->nreloc = bfd_h_get_32 (abfd, buf + 60);
1609 section->flags = bfd_h_get_32 (abfd, buf + 64);
1610 section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
1611 section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
1612 section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
1613 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1615 if (section->bfdsection == NULL)
1616 return -1;
1618 return 0;
1621 static int
1622 bfd_mach_o_read_section (bfd *abfd,
1623 bfd_mach_o_section *section,
1624 unsigned int offset,
1625 unsigned long prot,
1626 unsigned int wide)
1628 if (wide)
1629 return bfd_mach_o_read_section_64 (abfd, section, offset, prot);
1630 else
1631 return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
1634 static int
1635 bfd_mach_o_read_symtab_symbol (bfd *abfd,
1636 bfd_mach_o_symtab_command *sym,
1637 bfd_mach_o_asymbol *s,
1638 unsigned long i)
1640 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1641 unsigned int wide = mach_o_wide_p (&mdata->header);
1642 unsigned int symwidth =
1643 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1644 unsigned int symoff = sym->symoff + (i * symwidth);
1645 unsigned char buf[16];
1646 unsigned char type = -1;
1647 unsigned char section = -1;
1648 short desc = -1;
1649 symvalue value = -1;
1650 unsigned long stroff = -1;
1651 unsigned int symtype = -1;
1653 BFD_ASSERT (sym->strtab != NULL);
1655 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1656 || bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
1658 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu\n",
1659 symwidth, (unsigned long) symoff);
1660 return -1;
1663 stroff = bfd_h_get_32 (abfd, buf);
1664 type = bfd_h_get_8 (abfd, buf + 4);
1665 symtype = type & BFD_MACH_O_N_TYPE;
1666 section = bfd_h_get_8 (abfd, buf + 5);
1667 desc = bfd_h_get_16 (abfd, buf + 6);
1668 if (wide)
1669 value = bfd_h_get_64 (abfd, buf + 8);
1670 else
1671 value = bfd_h_get_32 (abfd, buf + 8);
1673 if (stroff >= sym->strsize)
1675 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
1676 (unsigned long) stroff, (unsigned long) sym->strsize);
1677 return -1;
1680 s->symbol.the_bfd = abfd;
1681 s->symbol.name = sym->strtab + stroff;
1682 s->symbol.value = value;
1683 s->symbol.flags = 0x0;
1684 s->symbol.udata.i = 0;
1685 s->n_type = type;
1686 s->n_sect = section;
1687 s->n_desc = desc;
1689 if (type & BFD_MACH_O_N_STAB)
1691 s->symbol.flags |= BSF_DEBUGGING;
1692 s->symbol.section = bfd_und_section_ptr;
1693 switch (type)
1695 case N_FUN:
1696 case N_STSYM:
1697 case N_LCSYM:
1698 case N_BNSYM:
1699 case N_SLINE:
1700 case N_ENSYM:
1701 case N_ECOMM:
1702 case N_ECOML:
1703 case N_GSYM:
1704 if ((section > 0) && (section <= mdata->nsects))
1706 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1707 s->symbol.value =
1708 s->symbol.value - mdata->sections[section - 1]->addr;
1710 break;
1713 else
1715 if (type & BFD_MACH_O_N_PEXT)
1716 s->symbol.flags |= BSF_GLOBAL;
1718 if (type & BFD_MACH_O_N_EXT)
1719 s->symbol.flags |= BSF_GLOBAL;
1721 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1722 s->symbol.flags |= BSF_LOCAL;
1724 switch (symtype)
1726 case BFD_MACH_O_N_UNDF:
1727 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1728 && s->symbol.value != 0)
1730 /* A common symbol. */
1731 s->symbol.section = bfd_com_section_ptr;
1732 s->symbol.flags = BSF_NO_FLAGS;
1734 else
1736 s->symbol.section = bfd_und_section_ptr;
1737 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1738 s->symbol.flags |= BSF_WEAK;
1740 break;
1741 case BFD_MACH_O_N_PBUD:
1742 s->symbol.section = bfd_und_section_ptr;
1743 break;
1744 case BFD_MACH_O_N_ABS:
1745 s->symbol.section = bfd_abs_section_ptr;
1746 break;
1747 case BFD_MACH_O_N_SECT:
1748 if ((section > 0) && (section <= mdata->nsects))
1750 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1751 s->symbol.value =
1752 s->symbol.value - mdata->sections[section - 1]->addr;
1754 else
1756 /* Mach-O uses 0 to mean "no section"; not an error. */
1757 if (section != 0)
1759 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1760 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
1761 s->symbol.name, section, mdata->nsects);
1763 s->symbol.section = bfd_und_section_ptr;
1765 break;
1766 case BFD_MACH_O_N_INDR:
1767 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1768 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
1769 s->symbol.name);
1770 s->symbol.section = bfd_und_section_ptr;
1771 break;
1772 default:
1773 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1774 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
1775 s->symbol.name, symtype);
1776 s->symbol.section = bfd_und_section_ptr;
1777 break;
1781 return 0;
1784 static int
1785 bfd_mach_o_read_symtab_strtab (bfd *abfd)
1787 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1788 bfd_mach_o_symtab_command *sym = mdata->symtab;
1790 /* Fail if there is no symtab. */
1791 if (sym == NULL)
1792 return -1;
1794 /* Success if already loaded. */
1795 if (sym->strtab)
1796 return 0;
1798 if (abfd->flags & BFD_IN_MEMORY)
1800 struct bfd_in_memory *b;
1802 b = (struct bfd_in_memory *) abfd->iostream;
1804 if ((sym->stroff + sym->strsize) > b->size)
1806 bfd_set_error (bfd_error_file_truncated);
1807 return -1;
1809 sym->strtab = (char *) b->buffer + sym->stroff;
1811 else
1813 sym->strtab = bfd_alloc (abfd, sym->strsize);
1814 if (sym->strtab == NULL)
1815 return -1;
1817 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1818 || bfd_bread ((void *) sym->strtab, sym->strsize, abfd) != sym->strsize)
1820 bfd_set_error (bfd_error_file_truncated);
1821 return -1;
1825 return 0;
1828 static int
1829 bfd_mach_o_read_symtab_symbols (bfd *abfd)
1831 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1832 bfd_mach_o_symtab_command *sym = mdata->symtab;
1833 unsigned long i;
1834 int ret;
1836 if (sym->symbols)
1837 return 0;
1839 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1841 if (sym->symbols == NULL)
1843 fprintf (stderr, "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols\n");
1844 return -1;
1847 ret = bfd_mach_o_read_symtab_strtab (abfd);
1848 if (ret != 0)
1849 return ret;
1851 for (i = 0; i < sym->nsyms; i++)
1853 ret = bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1854 if (ret != 0)
1855 return ret;
1858 return 0;
1862 bfd_mach_o_read_dysymtab_symbol (bfd *abfd,
1863 bfd_mach_o_dysymtab_command *dysym,
1864 bfd_mach_o_symtab_command *sym,
1865 bfd_mach_o_asymbol *s,
1866 unsigned long i)
1868 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1869 unsigned long sym_index;
1870 unsigned char buf[4];
1872 BFD_ASSERT (i < dysym->nindirectsyms);
1874 if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
1875 || bfd_bread ((void *) buf, 4, abfd) != 4)
1877 fprintf (stderr, "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
1878 (unsigned long) 4, isymoff);
1879 return -1;
1881 sym_index = bfd_h_get_32 (abfd, buf);
1883 return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
1886 static const char *
1887 bfd_mach_o_i386_flavour_string (unsigned int flavour)
1889 switch ((int) flavour)
1891 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
1892 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
1893 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1894 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
1895 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
1896 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1897 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
1898 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
1899 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
1900 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
1901 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
1902 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
1903 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
1904 default: return "UNKNOWN";
1908 static const char *
1909 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1911 switch ((int) flavour)
1913 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1914 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1915 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1916 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1917 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
1918 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
1919 default: return "UNKNOWN";
1923 static int
1924 bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
1926 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1927 unsigned char buf[4];
1928 unsigned int nameoff;
1930 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1931 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1933 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1934 || bfd_bread ((void *) buf, 4, abfd) != 4)
1935 return -1;
1937 nameoff = bfd_h_get_32 (abfd, buf + 0);
1939 cmd->name_offset = command->offset + nameoff;
1940 cmd->name_len = command->len - nameoff;
1941 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1942 if (cmd->name_str == NULL)
1943 return -1;
1944 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1945 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1946 return -1;
1947 return 0;
1950 static int
1951 bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1953 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1954 unsigned char buf[16];
1955 unsigned int nameoff;
1957 switch (command->type)
1959 case BFD_MACH_O_LC_LOAD_DYLIB:
1960 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1961 case BFD_MACH_O_LC_ID_DYLIB:
1962 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1963 break;
1964 default:
1965 BFD_FAIL ();
1966 return -1;
1969 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1970 || bfd_bread ((void *) buf, 16, abfd) != 16)
1971 return -1;
1973 nameoff = bfd_h_get_32 (abfd, buf + 0);
1974 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1975 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1976 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1978 cmd->name_offset = command->offset + nameoff;
1979 cmd->name_len = command->len - nameoff;
1980 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1981 if (cmd->name_str == NULL)
1982 return -1;
1983 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1984 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1985 return -1;
1986 return 0;
1989 static int
1990 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1991 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1993 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1995 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1996 return 0;
1999 static int
2000 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
2002 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2003 bfd_mach_o_thread_command *cmd = &command->command.thread;
2004 unsigned char buf[8];
2005 unsigned int offset;
2006 unsigned int nflavours;
2007 unsigned int i;
2009 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2010 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2012 /* Count the number of threads. */
2013 offset = 8;
2014 nflavours = 0;
2015 while (offset != command->len)
2017 if (offset >= command->len)
2018 return -1;
2020 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2021 || bfd_bread ((void *) buf, 8, abfd) != 8)
2022 return -1;
2024 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
2025 nflavours++;
2028 /* Allocate threads. */
2029 cmd->flavours = bfd_alloc
2030 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
2031 if (cmd->flavours == NULL)
2032 return -1;
2033 cmd->nflavours = nflavours;
2035 offset = 8;
2036 nflavours = 0;
2037 while (offset != command->len)
2039 if (offset >= command->len)
2040 return -1;
2042 if (nflavours >= cmd->nflavours)
2043 return -1;
2045 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2046 || bfd_bread ((void *) buf, 8, abfd) != 8)
2047 return -1;
2049 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
2050 cmd->flavours[nflavours].offset = command->offset + offset + 8;
2051 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
2052 offset += cmd->flavours[nflavours].size + 8;
2053 nflavours++;
2056 for (i = 0; i < nflavours; i++)
2058 asection *bfdsec;
2059 unsigned int snamelen;
2060 char *sname;
2061 const char *flavourstr;
2062 const char *prefix = "LC_THREAD";
2063 unsigned int j = 0;
2065 switch (mdata->header.cputype)
2067 case BFD_MACH_O_CPU_TYPE_POWERPC:
2068 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
2069 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2070 break;
2071 case BFD_MACH_O_CPU_TYPE_I386:
2072 case BFD_MACH_O_CPU_TYPE_X86_64:
2073 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2074 break;
2075 default:
2076 flavourstr = "UNKNOWN_ARCHITECTURE";
2077 break;
2080 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
2081 sname = bfd_alloc (abfd, snamelen);
2082 if (sname == NULL)
2083 return -1;
2085 for (;;)
2087 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2088 if (bfd_get_section_by_name (abfd, sname) == NULL)
2089 break;
2090 j++;
2093 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
2095 bfdsec->vma = 0;
2096 bfdsec->lma = 0;
2097 bfdsec->size = cmd->flavours[i].size;
2098 bfdsec->filepos = cmd->flavours[i].offset;
2099 bfdsec->alignment_power = 0x0;
2101 cmd->section = bfdsec;
2104 return 0;
2107 static int
2108 bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2110 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2111 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2112 unsigned char buf[72];
2114 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2116 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2117 || bfd_bread ((void *) buf, 72, abfd) != 72)
2118 return -1;
2120 cmd->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
2121 cmd->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
2122 cmd->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
2123 cmd->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
2124 cmd->iundefsym = bfd_h_get_32 (abfd, buf + 16);
2125 cmd->nundefsym = bfd_h_get_32 (abfd, buf + 20);
2126 cmd->tocoff = bfd_h_get_32 (abfd, buf + 24);
2127 cmd->ntoc = bfd_h_get_32 (abfd, buf + 28);
2128 cmd->modtaboff = bfd_h_get_32 (abfd, buf + 32);
2129 cmd->nmodtab = bfd_h_get_32 (abfd, buf + 36);
2130 cmd->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
2131 cmd->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
2132 cmd->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
2133 cmd->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
2134 cmd->extreloff = bfd_h_get_32 (abfd, buf + 56);
2135 cmd->nextrel = bfd_h_get_32 (abfd, buf + 60);
2136 cmd->locreloff = bfd_h_get_32 (abfd, buf + 64);
2137 cmd->nlocrel = bfd_h_get_32 (abfd, buf + 68);
2139 if (cmd->nmodtab != 0)
2141 unsigned int i;
2142 int wide = bfd_mach_o_wide_p (abfd);
2143 unsigned int module_len = wide ? 56 : 52;
2145 cmd->dylib_module =
2146 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2147 if (cmd->dylib_module == NULL)
2148 return -1;
2150 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2151 return -1;
2153 for (i = 0; i < cmd->nmodtab; i++)
2155 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2156 unsigned long v;
2158 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
2159 return -1;
2161 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2162 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2163 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2164 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2165 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2166 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2167 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2168 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2169 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2170 v = bfd_h_get_32 (abfd, buf +36);
2171 module->iinit = v & 0xffff;
2172 module->iterm = (v >> 16) & 0xffff;
2173 v = bfd_h_get_32 (abfd, buf + 40);
2174 module->ninit = v & 0xffff;
2175 module->nterm = (v >> 16) & 0xffff;
2176 if (wide)
2178 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2179 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2181 else
2183 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2184 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2189 if (cmd->ntoc != 0)
2191 unsigned int i;
2193 cmd->dylib_toc = bfd_alloc
2194 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2195 if (cmd->dylib_toc == NULL)
2196 return -1;
2198 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2199 return -1;
2201 for (i = 0; i < cmd->ntoc; i++)
2203 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2205 if (bfd_bread ((void *) buf, 8, abfd) != 8)
2206 return -1;
2208 toc->symbol_index = bfd_h_get_32 (abfd, buf + 0);
2209 toc->module_index = bfd_h_get_32 (abfd, buf + 4);
2213 if (cmd->nindirectsyms != 0)
2215 unsigned int i;
2217 cmd->indirect_syms = bfd_alloc
2218 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2219 if (cmd->indirect_syms == NULL)
2220 return -1;
2222 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2223 return -1;
2225 for (i = 0; i < cmd->nindirectsyms; i++)
2227 unsigned int *is = &cmd->indirect_syms[i];
2229 if (bfd_bread ((void *) buf, 4, abfd) != 4)
2230 return -1;
2232 *is = bfd_h_get_32 (abfd, buf + 0);
2236 if (cmd->nextrefsyms != 0)
2238 unsigned long v;
2239 unsigned int i;
2241 cmd->ext_refs = bfd_alloc
2242 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2243 if (cmd->ext_refs == NULL)
2244 return -1;
2246 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2247 return -1;
2249 for (i = 0; i < cmd->nextrefsyms; i++)
2251 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2253 if (bfd_bread ((void *) buf, 4, abfd) != 4)
2254 return -1;
2256 /* Fields isym and flags are written as bit-fields, thus we need
2257 a specific processing for endianness. */
2258 v = bfd_h_get_32 (abfd, buf + 0);
2259 if (bfd_big_endian (abfd))
2261 ref->isym = (v >> 8) & 0xffffff;
2262 ref->flags = v & 0xff;
2264 else
2266 ref->isym = v & 0xffffff;
2267 ref->flags = (v >> 24) & 0xff;
2272 if (mdata->dysymtab)
2273 return -1;
2274 mdata->dysymtab = cmd;
2276 return 0;
2279 static int
2280 bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
2282 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2283 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2284 unsigned char buf[16];
2286 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2288 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2289 || bfd_bread ((void *) buf, 16, abfd) != 16)
2290 return -1;
2292 symtab->symoff = bfd_h_get_32 (abfd, buf);
2293 symtab->nsyms = bfd_h_get_32 (abfd, buf + 4);
2294 symtab->stroff = bfd_h_get_32 (abfd, buf + 8);
2295 symtab->strsize = bfd_h_get_32 (abfd, buf + 12);
2296 symtab->symbols = NULL;
2297 symtab->strtab = NULL;
2299 if (symtab->nsyms != 0)
2300 abfd->flags |= HAS_SYMS;
2302 if (mdata->symtab)
2303 return -1;
2304 mdata->symtab = symtab;
2305 return 0;
2308 static int
2309 bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
2311 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
2313 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2315 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2316 || bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
2317 return -1;
2319 return 0;
2322 static int
2323 bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
2325 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
2326 char buf[8];
2328 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2329 || bfd_bread ((void *) buf, 8, abfd) != 8)
2330 return -1;
2332 cmd->dataoff = bfd_get_32 (abfd, buf + 0);
2333 cmd->datasize = bfd_get_32 (abfd, buf + 4);
2334 return 0;
2337 static int
2338 bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
2340 bfd_mach_o_str_command *cmd = &command->command.str;
2341 char buf[4];
2342 unsigned long off;
2344 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2345 || bfd_bread ((void *) buf, 4, abfd) != 4)
2346 return -1;
2348 off = bfd_get_32 (abfd, buf + 0);
2349 cmd->stroff = command->offset + off;
2350 cmd->str_len = command->len - off;
2351 cmd->str = bfd_alloc (abfd, cmd->str_len);
2352 if (cmd->str == NULL)
2353 return -1;
2354 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
2355 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
2356 return -1;
2357 return 0;
2360 static int
2361 bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
2363 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
2364 char buf[40];
2366 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2367 || bfd_bread ((void *) buf, sizeof (buf), abfd) != sizeof (buf))
2368 return -1;
2370 cmd->rebase_off = bfd_get_32 (abfd, buf + 0);
2371 cmd->rebase_size = bfd_get_32 (abfd, buf + 4);
2372 cmd->bind_off = bfd_get_32 (abfd, buf + 8);
2373 cmd->bind_size = bfd_get_32 (abfd, buf + 12);
2374 cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16);
2375 cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20);
2376 cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24);
2377 cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28);
2378 cmd->export_off = bfd_get_32 (abfd, buf + 32);
2379 cmd->export_size = bfd_get_32 (abfd, buf + 36);
2380 return 0;
2383 static int
2384 bfd_mach_o_read_segment (bfd *abfd,
2385 bfd_mach_o_load_command *command,
2386 unsigned int wide)
2388 unsigned char buf[64];
2389 bfd_mach_o_segment_command *seg = &command->command.segment;
2390 unsigned long i;
2392 if (wide)
2394 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2396 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2397 || bfd_bread ((void *) buf, 64, abfd) != 64)
2398 return -1;
2400 memcpy (seg->segname, buf, 16);
2401 seg->segname[16] = '\0';
2403 seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
2404 seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
2405 seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
2406 seg->filesize = bfd_h_get_64 (abfd, buf + 40);
2407 seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
2408 seg->initprot = bfd_h_get_32 (abfd, buf + 52);
2409 seg->nsects = bfd_h_get_32 (abfd, buf + 56);
2410 seg->flags = bfd_h_get_32 (abfd, buf + 60);
2412 else
2414 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2416 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2417 || bfd_bread ((void *) buf, 48, abfd) != 48)
2418 return -1;
2420 memcpy (seg->segname, buf, 16);
2421 seg->segname[16] = '\0';
2423 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
2424 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
2425 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
2426 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
2427 seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
2428 seg->initprot = bfd_h_get_32 (abfd, buf + 36);
2429 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
2430 seg->flags = bfd_h_get_32 (abfd, buf + 44);
2433 if (seg->nsects != 0)
2435 seg->sections = bfd_alloc (abfd, seg->nsects
2436 * sizeof (bfd_mach_o_section));
2437 if (seg->sections == NULL)
2438 return -1;
2440 for (i = 0; i < seg->nsects; i++)
2442 bfd_vma segoff;
2443 if (wide)
2444 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2445 + (i * BFD_MACH_O_SECTION_64_SIZE);
2446 else
2447 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2448 + (i * BFD_MACH_O_SECTION_SIZE);
2450 if (bfd_mach_o_read_section
2451 (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
2452 return -1;
2456 return 0;
2459 static int
2460 bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2462 return bfd_mach_o_read_segment (abfd, command, 0);
2465 static int
2466 bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2468 return bfd_mach_o_read_segment (abfd, command, 1);
2471 static int
2472 bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2474 unsigned char buf[8];
2476 /* Read command type and length. */
2477 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2478 || bfd_bread ((void *) buf, 8, abfd) != 8)
2479 return -1;
2481 command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
2482 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
2483 ? TRUE : FALSE);
2484 command->len = bfd_h_get_32 (abfd, buf + 4);
2486 switch (command->type)
2488 case BFD_MACH_O_LC_SEGMENT:
2489 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
2490 return -1;
2491 break;
2492 case BFD_MACH_O_LC_SEGMENT_64:
2493 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
2494 return -1;
2495 break;
2496 case BFD_MACH_O_LC_SYMTAB:
2497 if (bfd_mach_o_read_symtab (abfd, command) != 0)
2498 return -1;
2499 break;
2500 case BFD_MACH_O_LC_SYMSEG:
2501 break;
2502 case BFD_MACH_O_LC_THREAD:
2503 case BFD_MACH_O_LC_UNIXTHREAD:
2504 if (bfd_mach_o_read_thread (abfd, command) != 0)
2505 return -1;
2506 break;
2507 case BFD_MACH_O_LC_LOAD_DYLINKER:
2508 case BFD_MACH_O_LC_ID_DYLINKER:
2509 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
2510 return -1;
2511 break;
2512 case BFD_MACH_O_LC_LOAD_DYLIB:
2513 case BFD_MACH_O_LC_ID_DYLIB:
2514 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2515 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2516 if (bfd_mach_o_read_dylib (abfd, command) != 0)
2517 return -1;
2518 break;
2519 case BFD_MACH_O_LC_PREBOUND_DYLIB:
2520 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
2521 return -1;
2522 break;
2523 case BFD_MACH_O_LC_LOADFVMLIB:
2524 case BFD_MACH_O_LC_IDFVMLIB:
2525 case BFD_MACH_O_LC_IDENT:
2526 case BFD_MACH_O_LC_FVMFILE:
2527 case BFD_MACH_O_LC_PREPAGE:
2528 case BFD_MACH_O_LC_ROUTINES:
2529 break;
2530 case BFD_MACH_O_LC_SUB_FRAMEWORK:
2531 case BFD_MACH_O_LC_SUB_UMBRELLA:
2532 case BFD_MACH_O_LC_SUB_LIBRARY:
2533 case BFD_MACH_O_LC_SUB_CLIENT:
2534 case BFD_MACH_O_LC_RPATH:
2535 if (bfd_mach_o_read_str (abfd, command) != 0)
2536 return -1;
2537 break;
2538 case BFD_MACH_O_LC_DYSYMTAB:
2539 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
2540 return -1;
2541 break;
2542 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2543 case BFD_MACH_O_LC_PREBIND_CKSUM:
2544 break;
2545 case BFD_MACH_O_LC_UUID:
2546 if (bfd_mach_o_read_uuid (abfd, command) != 0)
2547 return -1;
2548 break;
2549 case BFD_MACH_O_LC_CODE_SIGNATURE:
2550 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2551 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
2552 return -1;
2553 break;
2554 case BFD_MACH_O_LC_DYLD_INFO:
2555 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
2556 return -1;
2557 break;
2558 default:
2559 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
2560 (unsigned long) command->type);
2561 break;
2564 return 0;
2567 static void
2568 bfd_mach_o_flatten_sections (bfd *abfd)
2570 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2571 long csect = 0;
2572 unsigned long i, j;
2574 /* Count total number of sections. */
2575 mdata->nsects = 0;
2577 for (i = 0; i < mdata->header.ncmds; i++)
2579 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2580 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2582 bfd_mach_o_segment_command *seg;
2584 seg = &mdata->commands[i].command.segment;
2585 mdata->nsects += seg->nsects;
2589 /* Allocate sections array. */
2590 mdata->sections = bfd_alloc (abfd,
2591 mdata->nsects * sizeof (bfd_mach_o_section *));
2593 /* Fill the array. */
2594 csect = 0;
2596 for (i = 0; i < mdata->header.ncmds; i++)
2598 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2599 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2601 bfd_mach_o_segment_command *seg;
2603 seg = &mdata->commands[i].command.segment;
2604 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2606 for (j = 0; j < seg->nsects; j++)
2607 mdata->sections[csect++] = &seg->sections[j];
2613 bfd_mach_o_scan_start_address (bfd *abfd)
2615 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2616 bfd_mach_o_thread_command *cmd = NULL;
2617 unsigned long i;
2619 for (i = 0; i < mdata->header.ncmds; i++)
2621 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2622 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2624 if (cmd == NULL)
2625 cmd = &mdata->commands[i].command.thread;
2626 else
2627 return 0;
2631 if (cmd == NULL)
2632 return 0;
2634 for (i = 0; i < cmd->nflavours; i++)
2636 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2637 && (cmd->flavours[i].flavour
2638 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2640 unsigned char buf[4];
2642 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2643 || bfd_bread (buf, 4, abfd) != 4)
2644 return -1;
2646 abfd->start_address = bfd_h_get_32 (abfd, buf);
2648 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2649 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2651 unsigned char buf[4];
2653 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2654 || bfd_bread (buf, 4, abfd) != 4)
2655 return -1;
2657 abfd->start_address = bfd_h_get_32 (abfd, buf);
2659 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2660 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
2662 unsigned char buf[8];
2664 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2665 || bfd_bread (buf, 8, abfd) != 8)
2666 return -1;
2668 abfd->start_address = bfd_h_get_64 (abfd, buf);
2670 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2671 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2673 unsigned char buf[8];
2675 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2676 || bfd_bread (buf, 8, abfd) != 8)
2677 return -1;
2679 abfd->start_address = bfd_h_get_64 (abfd, buf);
2683 return 0;
2686 bfd_boolean
2687 bfd_mach_o_set_arch_mach (bfd *abfd,
2688 enum bfd_architecture arch,
2689 unsigned long machine)
2691 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
2693 /* If this isn't the right architecture for this backend, and this
2694 isn't the generic backend, fail. */
2695 if (arch != bed->arch
2696 && arch != bfd_arch_unknown
2697 && bed->arch != bfd_arch_unknown)
2698 return FALSE;
2700 return bfd_default_set_arch_mach (abfd, arch, machine);
2704 bfd_mach_o_scan (bfd *abfd,
2705 bfd_mach_o_header *header,
2706 bfd_mach_o_data_struct *mdata)
2708 unsigned int i;
2709 enum bfd_architecture cputype;
2710 unsigned long cpusubtype;
2711 unsigned int hdrsize;
2713 hdrsize = mach_o_wide_p (header) ?
2714 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2716 mdata->header = *header;
2718 abfd->flags = abfd->flags & BFD_IN_MEMORY;
2719 switch (header->filetype)
2721 case BFD_MACH_O_MH_OBJECT:
2722 abfd->flags |= HAS_RELOC;
2723 break;
2724 case BFD_MACH_O_MH_EXECUTE:
2725 abfd->flags |= EXEC_P;
2726 break;
2727 case BFD_MACH_O_MH_DYLIB:
2728 case BFD_MACH_O_MH_BUNDLE:
2729 abfd->flags |= DYNAMIC;
2730 break;
2733 abfd->tdata.mach_o_data = mdata;
2735 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2736 &cputype, &cpusubtype);
2737 if (cputype == bfd_arch_unknown)
2739 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
2740 header->cputype, header->cpusubtype);
2741 return -1;
2744 bfd_set_arch_mach (abfd, cputype, cpusubtype);
2746 if (header->ncmds != 0)
2748 mdata->commands = bfd_alloc
2749 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2750 if (mdata->commands == NULL)
2751 return -1;
2753 for (i = 0; i < header->ncmds; i++)
2755 bfd_mach_o_load_command *cur = &mdata->commands[i];
2757 if (i == 0)
2758 cur->offset = hdrsize;
2759 else
2761 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2762 cur->offset = prev->offset + prev->len;
2765 if (bfd_mach_o_read_command (abfd, cur) < 0)
2766 return -1;
2770 if (bfd_mach_o_scan_start_address (abfd) < 0)
2771 return -1;
2773 bfd_mach_o_flatten_sections (abfd);
2774 return 0;
2777 bfd_boolean
2778 bfd_mach_o_mkobject_init (bfd *abfd)
2780 bfd_mach_o_data_struct *mdata = NULL;
2782 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2783 if (mdata == NULL)
2784 return FALSE;
2785 abfd->tdata.mach_o_data = mdata;
2787 mdata->header.magic = 0;
2788 mdata->header.cputype = 0;
2789 mdata->header.cpusubtype = 0;
2790 mdata->header.filetype = 0;
2791 mdata->header.ncmds = 0;
2792 mdata->header.sizeofcmds = 0;
2793 mdata->header.flags = 0;
2794 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2795 mdata->commands = NULL;
2796 mdata->nsects = 0;
2797 mdata->sections = NULL;
2799 return TRUE;
2802 static bfd_boolean
2803 bfd_mach_o_gen_mkobject (bfd *abfd)
2805 bfd_mach_o_data_struct *mdata;
2807 if (!bfd_mach_o_mkobject_init (abfd))
2808 return FALSE;
2810 mdata = bfd_mach_o_get_data (abfd);
2811 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
2812 mdata->header.cputype = 0;
2813 mdata->header.cpusubtype = 0;
2814 mdata->header.byteorder = abfd->xvec->byteorder;
2815 mdata->header.version = 1;
2817 return TRUE;
2820 const bfd_target *
2821 bfd_mach_o_header_p (bfd *abfd,
2822 bfd_mach_o_filetype filetype,
2823 bfd_mach_o_cpu_type cputype)
2825 struct bfd_preserve preserve;
2826 bfd_mach_o_header header;
2828 preserve.marker = NULL;
2829 if (!bfd_mach_o_read_header (abfd, &header))
2830 goto wrong;
2832 if (! (header.byteorder == BFD_ENDIAN_BIG
2833 || header.byteorder == BFD_ENDIAN_LITTLE))
2835 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
2836 (unsigned long) header.byteorder);
2837 goto wrong;
2840 if (! ((header.byteorder == BFD_ENDIAN_BIG
2841 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2842 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2843 || (header.byteorder == BFD_ENDIAN_LITTLE
2844 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2845 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2846 goto wrong;
2848 /* Check cputype and filetype.
2849 In case of wildcard, do not accept magics that are handled by existing
2850 targets. */
2851 if (cputype)
2853 if (header.cputype != cputype)
2854 goto wrong;
2856 else
2858 switch (header.cputype)
2860 case BFD_MACH_O_CPU_TYPE_I386:
2861 /* Handled by mach-o-i386 */
2862 goto wrong;
2863 default:
2864 break;
2867 if (filetype)
2869 if (header.filetype != filetype)
2870 goto wrong;
2872 else
2874 switch (header.filetype)
2876 case BFD_MACH_O_MH_CORE:
2877 /* Handled by core_p */
2878 goto wrong;
2879 default:
2880 break;
2884 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2885 if (preserve.marker == NULL
2886 || !bfd_preserve_save (abfd, &preserve))
2887 goto fail;
2889 if (bfd_mach_o_scan (abfd, &header,
2890 (bfd_mach_o_data_struct *) preserve.marker) != 0)
2891 goto wrong;
2893 bfd_preserve_finish (abfd, &preserve);
2894 return abfd->xvec;
2896 wrong:
2897 bfd_set_error (bfd_error_wrong_format);
2899 fail:
2900 if (preserve.marker != NULL)
2901 bfd_preserve_restore (abfd, &preserve);
2902 return NULL;
2905 static const bfd_target *
2906 bfd_mach_o_gen_object_p (bfd *abfd)
2908 return bfd_mach_o_header_p (abfd, 0, 0);
2911 static const bfd_target *
2912 bfd_mach_o_gen_core_p (bfd *abfd)
2914 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
2917 typedef struct mach_o_fat_archentry
2919 unsigned long cputype;
2920 unsigned long cpusubtype;
2921 unsigned long offset;
2922 unsigned long size;
2923 unsigned long align;
2924 } mach_o_fat_archentry;
2926 typedef struct mach_o_fat_data_struct
2928 unsigned long magic;
2929 unsigned long nfat_arch;
2930 mach_o_fat_archentry *archentries;
2931 } mach_o_fat_data_struct;
2933 const bfd_target *
2934 bfd_mach_o_archive_p (bfd *abfd)
2936 mach_o_fat_data_struct *adata = NULL;
2937 unsigned char buf[20];
2938 unsigned long i;
2940 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2941 || bfd_bread ((void *) buf, 8, abfd) != 8)
2942 goto error;
2944 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
2945 if (adata == NULL)
2946 goto error;
2948 adata->magic = bfd_getb32 (buf);
2949 adata->nfat_arch = bfd_getb32 (buf + 4);
2950 if (adata->magic != 0xcafebabe)
2951 goto error;
2952 /* Avoid matching Java bytecode files, which have the same magic number.
2953 In the Java bytecode file format this field contains the JVM version,
2954 which starts at 43.0. */
2955 if (adata->nfat_arch > 30)
2956 goto error;
2958 adata->archentries =
2959 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2960 if (adata->archentries == NULL)
2961 goto error;
2963 for (i = 0; i < adata->nfat_arch; i++)
2965 if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
2966 || bfd_bread ((void *) buf, 20, abfd) != 20)
2967 goto error;
2968 adata->archentries[i].cputype = bfd_getb32 (buf);
2969 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
2970 adata->archentries[i].offset = bfd_getb32 (buf + 8);
2971 adata->archentries[i].size = bfd_getb32 (buf + 12);
2972 adata->archentries[i].align = bfd_getb32 (buf + 16);
2975 abfd->tdata.mach_o_fat_data = adata;
2976 return abfd->xvec;
2978 error:
2979 if (adata != NULL)
2980 bfd_release (abfd, adata);
2981 bfd_set_error (bfd_error_wrong_format);
2982 return NULL;
2985 bfd *
2986 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
2988 mach_o_fat_data_struct *adata;
2989 mach_o_fat_archentry *entry = NULL;
2990 unsigned long i;
2991 bfd *nbfd;
2992 enum bfd_architecture arch_type;
2993 unsigned long arch_subtype;
2995 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
2996 BFD_ASSERT (adata != NULL);
2998 /* Find index of previous entry. */
2999 if (prev == NULL)
3000 i = 0; /* Start at first one. */
3001 else
3003 for (i = 0; i < adata->nfat_arch; i++)
3005 if (adata->archentries[i].offset == prev->origin)
3006 break;
3009 if (i == adata->nfat_arch)
3011 /* Not found. */
3012 bfd_set_error (bfd_error_bad_value);
3013 return NULL;
3015 i++; /* Get next entry. */
3018 if (i >= adata->nfat_arch)
3020 bfd_set_error (bfd_error_no_more_archived_files);
3021 return NULL;
3024 entry = &adata->archentries[i];
3025 nbfd = _bfd_new_bfd_contained_in (archive);
3026 if (nbfd == NULL)
3027 return NULL;
3029 nbfd->origin = entry->offset;
3031 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3032 &arch_type, &arch_subtype);
3033 /* Create the member filename.
3034 Use FILENAME:ARCH_NAME. */
3036 char *s = NULL;
3037 const char *arch_name;
3038 size_t arch_file_len = strlen (bfd_get_filename (archive));
3040 arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
3041 s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
3042 if (s == NULL)
3043 return NULL;
3044 memcpy (s, bfd_get_filename (archive), arch_file_len);
3045 s[arch_file_len] = ':';
3046 strcpy (s + arch_file_len + 1, arch_name);
3047 nbfd->filename = s;
3049 nbfd->iostream = NULL;
3050 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3052 return nbfd;
3055 /* If ABFD format is FORMAT and architecture is ARCH, return it.
3056 If ABFD is a fat image containing a member that corresponds to FORMAT
3057 and ARCH, returns it.
3058 In other case, returns NULL.
3059 This function allows transparent uses of fat images. */
3060 bfd *
3061 bfd_mach_o_fat_extract (bfd *abfd,
3062 bfd_format format,
3063 const bfd_arch_info_type *arch)
3065 bfd *res;
3066 mach_o_fat_data_struct *adata;
3067 unsigned int i;
3069 if (bfd_check_format (abfd, format))
3071 if (bfd_get_arch_info (abfd) == arch)
3072 return abfd;
3073 return NULL;
3075 if (!bfd_check_format (abfd, bfd_archive)
3076 || abfd->xvec != &mach_o_fat_vec)
3077 return NULL;
3079 /* This is a Mach-O fat image. */
3080 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3081 BFD_ASSERT (adata != NULL);
3083 for (i = 0; i < adata->nfat_arch; i++)
3085 struct mach_o_fat_archentry *e = &adata->archentries[i];
3086 enum bfd_architecture cpu_type;
3087 unsigned long cpu_subtype;
3089 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3090 &cpu_type, &cpu_subtype);
3091 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3092 continue;
3094 /* The architecture is found. */
3095 res = _bfd_new_bfd_contained_in (abfd);
3096 if (res == NULL)
3097 return NULL;
3099 res->origin = e->offset;
3101 res->filename = strdup (abfd->filename);
3102 res->iostream = NULL;
3104 if (bfd_check_format (res, format))
3106 BFD_ASSERT (bfd_get_arch_info (res) == arch);
3107 return res;
3109 bfd_close (res);
3110 return NULL;
3113 return NULL;
3117 bfd_mach_o_lookup_section (bfd *abfd,
3118 asection *section,
3119 bfd_mach_o_load_command **mcommand,
3120 bfd_mach_o_section **msection)
3122 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3123 unsigned int i, j, num;
3125 bfd_mach_o_load_command *ncmd = NULL;
3126 bfd_mach_o_section *nsect = NULL;
3128 BFD_ASSERT (mcommand != NULL);
3129 BFD_ASSERT (msection != NULL);
3131 num = 0;
3132 for (i = 0; i < md->header.ncmds; i++)
3134 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3135 struct bfd_mach_o_segment_command *seg = NULL;
3137 if (cmd->type != BFD_MACH_O_LC_SEGMENT
3138 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
3139 continue;
3140 seg = &cmd->command.segment;
3142 for (j = 0; j < seg->nsects; j++)
3144 struct bfd_mach_o_section *sect = &seg->sections[j];
3146 if (sect->bfdsection == section)
3148 if (num == 0)
3150 nsect = sect;
3151 ncmd = cmd;
3153 num++;
3158 *mcommand = ncmd;
3159 *msection = nsect;
3160 return num;
3164 bfd_mach_o_lookup_command (bfd *abfd,
3165 bfd_mach_o_load_command_type type,
3166 bfd_mach_o_load_command **mcommand)
3168 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3169 bfd_mach_o_load_command *ncmd = NULL;
3170 unsigned int i, num;
3172 BFD_ASSERT (md != NULL);
3173 BFD_ASSERT (mcommand != NULL);
3175 num = 0;
3176 for (i = 0; i < md->header.ncmds; i++)
3178 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3180 if (cmd->type != type)
3181 continue;
3183 if (num == 0)
3184 ncmd = cmd;
3185 num++;
3188 *mcommand = ncmd;
3189 return num;
3192 unsigned long
3193 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3195 switch (type)
3197 case BFD_MACH_O_CPU_TYPE_MC680x0:
3198 return 0x04000000;
3199 case BFD_MACH_O_CPU_TYPE_MC88000:
3200 return 0xffffe000;
3201 case BFD_MACH_O_CPU_TYPE_POWERPC:
3202 return 0xc0000000;
3203 case BFD_MACH_O_CPU_TYPE_I386:
3204 return 0xc0000000;
3205 case BFD_MACH_O_CPU_TYPE_SPARC:
3206 return 0xf0000000;
3207 case BFD_MACH_O_CPU_TYPE_I860:
3208 return 0;
3209 case BFD_MACH_O_CPU_TYPE_HPPA:
3210 return 0xc0000000 - 0x04000000;
3211 default:
3212 return 0;
3216 typedef struct bfd_mach_o_xlat_name
3218 const char *name;
3219 unsigned long val;
3221 bfd_mach_o_xlat_name;
3223 static void
3224 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
3225 unsigned long val,
3226 FILE *file)
3228 int first = 1;
3230 for (; table->name; table++)
3232 if (table->val & val)
3234 if (!first)
3235 fprintf (file, "+");
3236 fprintf (file, "%s", table->name);
3237 val &= ~table->val;
3238 first = 0;
3241 if (val)
3243 if (!first)
3244 fprintf (file, "+");
3245 fprintf (file, "0x%lx", val);
3246 return;
3248 if (first)
3249 fprintf (file, "-");
3252 static const char *
3253 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
3255 for (; table->name; table++)
3256 if (table->val == val)
3257 return table->name;
3258 return "*UNKNOWN*";
3261 static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
3263 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
3264 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
3265 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
3266 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
3267 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
3268 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
3269 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
3270 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
3271 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
3272 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
3273 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
3274 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
3275 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
3276 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
3277 { NULL, 0}
3280 static bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
3282 { "object", BFD_MACH_O_MH_OBJECT },
3283 { "execute", BFD_MACH_O_MH_EXECUTE },
3284 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
3285 { "core", BFD_MACH_O_MH_CORE },
3286 { "preload", BFD_MACH_O_MH_PRELOAD },
3287 { "dylib", BFD_MACH_O_MH_DYLIB },
3288 { "dylinker", BFD_MACH_O_MH_DYLINKER },
3289 { "bundle", BFD_MACH_O_MH_BUNDLE },
3290 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
3291 { "dym", BFD_MACH_O_MH_DSYM },
3292 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
3293 { NULL, 0}
3296 static bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
3298 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
3299 { "incrlink", BFD_MACH_O_MH_INCRLINK },
3300 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
3301 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
3302 { "prebound", BFD_MACH_O_MH_PREBOUND },
3303 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
3304 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
3305 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
3306 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
3307 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
3308 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
3309 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
3310 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
3311 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
3312 { "canonical", BFD_MACH_O_MH_CANONICAL },
3313 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
3314 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
3315 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
3316 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
3317 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
3318 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
3319 { "pie", BFD_MACH_O_MH_PIE },
3320 { NULL, 0}
3323 static bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
3325 { "regular", BFD_MACH_O_S_REGULAR},
3326 { "zerofill", BFD_MACH_O_S_ZEROFILL},
3327 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3328 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3329 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3330 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3331 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3332 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3333 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3334 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3335 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3336 { "coalesced", BFD_MACH_O_S_COALESCED},
3337 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3338 { "interposing", BFD_MACH_O_S_INTERPOSING},
3339 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3340 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
3341 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3342 { NULL, 0}
3345 static bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
3347 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3348 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3349 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3350 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3351 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3352 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3353 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3354 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3355 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3356 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
3357 { NULL, 0}
3360 static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
3362 { "segment", BFD_MACH_O_LC_SEGMENT},
3363 { "symtab", BFD_MACH_O_LC_SYMTAB},
3364 { "symseg", BFD_MACH_O_LC_SYMSEG},
3365 { "thread", BFD_MACH_O_LC_THREAD},
3366 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
3367 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
3368 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
3369 { "ident", BFD_MACH_O_LC_IDENT},
3370 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
3371 { "prepage", BFD_MACH_O_LC_PREPAGE},
3372 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
3373 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
3374 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
3375 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
3376 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
3377 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
3378 { "routines", BFD_MACH_O_LC_ROUTINES},
3379 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
3380 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
3381 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
3382 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
3383 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
3384 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
3385 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
3386 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
3387 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
3388 { "uuid", BFD_MACH_O_LC_UUID},
3389 { "rpath", BFD_MACH_O_LC_RPATH},
3390 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
3391 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
3392 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
3393 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
3394 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
3395 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
3396 { NULL, 0}
3399 static void
3400 bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
3402 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3403 bfd_mach_o_header *h = &mdata->header;
3405 fputs (_("Mach-O header:\n"), file);
3406 fprintf (file, _(" magic : %08lx\n"), h->magic);
3407 fprintf (file, _(" cputype : %08lx (%s)\n"), h->cputype,
3408 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
3409 fprintf (file, _(" cpusubtype: %08lx\n"), h->cpusubtype);
3410 fprintf (file, _(" filetype : %08lx (%s)\n"),
3411 h->filetype,
3412 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
3413 fprintf (file, _(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
3414 fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds);
3415 fprintf (file, _(" flags : %08lx ("), h->flags);
3416 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file);
3417 fputs (_(")\n"), file);
3418 fprintf (file, _(" reserved : %08x\n"), h->reserved);
3421 static void
3422 bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
3424 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3425 unsigned int i, j;
3426 unsigned int sec_nbr = 0;
3428 fputs (_("Segments and Sections:\n"), file);
3429 fputs (_(" #: Segment name Section name Address\n"), file);
3431 for (i = 0; i < mdata->header.ncmds; i++)
3433 bfd_mach_o_segment_command *seg;
3435 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
3436 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
3437 continue;
3439 seg = &mdata->commands[i].command.segment;
3441 fprintf (file, "[Segment %-16s ", seg->segname);
3442 fprintf_vma (file, seg->vmaddr);
3443 fprintf (file, "-");
3444 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
3445 fputc (' ', file);
3446 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
3447 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
3448 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
3449 fprintf (file, "]\n");
3450 for (j = 0; j < seg->nsects; j++)
3452 bfd_mach_o_section *sec = &seg->sections[j];
3453 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
3454 sec->segname, sec->sectname);
3455 fprintf_vma (file, sec->addr);
3456 fprintf (file, " ");
3457 fprintf_vma (file, sec->size);
3458 fprintf (file, " %08lx\n", sec->flags);
3463 static void
3464 bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED,
3465 bfd_mach_o_section *sec, FILE *file)
3467 fprintf (file, " Section: %-16s %-16s (bfdname: %s)\n",
3468 sec->sectname, sec->segname, sec->bfdsection->name);
3469 fprintf (file, " addr: ");
3470 fprintf_vma (file, sec->addr);
3471 fprintf (file, " size: ");
3472 fprintf_vma (file, sec->size);
3473 fprintf (file, " offset: ");
3474 fprintf_vma (file, sec->offset);
3475 fprintf (file, "\n");
3476 fprintf (file, " align: %ld", sec->align);
3477 fprintf (file, " nreloc: %lu reloff: ", sec->nreloc);
3478 fprintf_vma (file, sec->reloff);
3479 fprintf (file, "\n");
3480 fprintf (file, " flags: %08lx (type: %s", sec->flags,
3481 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
3482 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
3483 fprintf (file, " attr: ");
3484 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
3485 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
3486 file);
3487 fprintf (file, ")\n");
3488 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3490 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3491 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3492 case BFD_MACH_O_S_SYMBOL_STUBS:
3493 fprintf (file, " first indirect sym: %lu", sec->reserved1);
3494 fprintf (file, " (%u entries)",
3495 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
3496 break;
3497 default:
3498 fprintf (file, " reserved1: 0x%lx", sec->reserved1);
3499 break;
3501 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3503 case BFD_MACH_O_S_SYMBOL_STUBS:
3504 fprintf (file, " stub size: %lu", sec->reserved2);
3505 break;
3506 default:
3507 fprintf (file, " reserved2: 0x%lx", sec->reserved2);
3508 break;
3510 fprintf (file, " reserved3: 0x%lx\n", sec->reserved3);
3513 static void
3514 bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
3515 bfd_mach_o_load_command *cmd, FILE *file)
3517 bfd_mach_o_segment_command *seg = &cmd->command.segment;
3518 unsigned int i;
3520 fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
3521 fprintf (file, " vmaddr: ");
3522 fprintf_vma (file, seg->vmaddr);
3523 fprintf (file, " vmsize: ");
3524 fprintf_vma (file, seg->vmsize);
3525 fprintf (file, "\n");
3526 fprintf (file, " fileoff: ");
3527 fprintf_vma (file, seg->fileoff);
3528 fprintf (file, " filesize: ");
3529 fprintf_vma (file, (bfd_vma)seg->filesize);
3530 fprintf (file, " endoff: ");
3531 fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
3532 fprintf (file, "\n");
3533 fprintf (file, " nsects: %lu ", seg->nsects);
3534 fprintf (file, " flags: %lx\n", seg->flags);
3535 for (i = 0; i < seg->nsects; i++)
3536 bfd_mach_o_print_section (abfd, &seg->sections[i], file);
3539 static void
3540 bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
3541 bfd_mach_o_load_command *cmd, FILE *file)
3543 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
3544 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3545 unsigned int i;
3547 fprintf (file, " local symbols: idx: %10lu num: %-8lu",
3548 dysymtab->ilocalsym, dysymtab->nlocalsym);
3549 fprintf (file, " (nxtidx: %lu)\n",
3550 dysymtab->ilocalsym + dysymtab->nlocalsym);
3551 fprintf (file, " external symbols: idx: %10lu num: %-8lu",
3552 dysymtab->iextdefsym, dysymtab->nextdefsym);
3553 fprintf (file, " (nxtidx: %lu)\n",
3554 dysymtab->iextdefsym + dysymtab->nextdefsym);
3555 fprintf (file, " undefined symbols: idx: %10lu num: %-8lu",
3556 dysymtab->iundefsym, dysymtab->nundefsym);
3557 fprintf (file, " (nxtidx: %lu)\n",
3558 dysymtab->iundefsym + dysymtab->nundefsym);
3559 fprintf (file, " table of content: off: 0x%08lx num: %-8lu",
3560 dysymtab->tocoff, dysymtab->ntoc);
3561 fprintf (file, " (endoff: 0x%08lx)\n",
3562 dysymtab->tocoff
3563 + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
3564 fprintf (file, " module table: off: 0x%08lx num: %-8lu",
3565 dysymtab->modtaboff, dysymtab->nmodtab);
3566 fprintf (file, " (endoff: 0x%08lx)\n",
3567 dysymtab->modtaboff + dysymtab->nmodtab
3568 * (mach_o_wide_p (&mdata->header) ?
3569 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
3570 fprintf (file, " external reference table: off: 0x%08lx num: %-8lu",
3571 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
3572 fprintf (file, " (endoff: 0x%08lx)\n",
3573 dysymtab->extrefsymoff
3574 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
3575 fprintf (file, " indirect symbol table: off: 0x%08lx num: %-8lu",
3576 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
3577 fprintf (file, " (endoff: 0x%08lx)\n",
3578 dysymtab->indirectsymoff
3579 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
3580 fprintf (file, " external relocation table: off: 0x%08lx num: %-8lu",
3581 dysymtab->extreloff, dysymtab->nextrel);
3582 fprintf (file, " (endoff: 0x%08lx)\n",
3583 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
3584 fprintf (file, " local relocation table: off: 0x%08lx num: %-8lu",
3585 dysymtab->locreloff, dysymtab->nlocrel);
3586 fprintf (file, " (endoff: 0x%08lx)\n",
3587 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
3589 if (dysymtab->ntoc > 0
3590 || dysymtab->nindirectsyms > 0
3591 || dysymtab->nextrefsyms > 0)
3593 /* Try to read the symbols to display the toc or indirect symbols. */
3594 bfd_mach_o_read_symtab_symbols (abfd);
3596 else if (dysymtab->nmodtab > 0)
3598 /* Try to read the strtab to display modules name. */
3599 bfd_mach_o_read_symtab_strtab (abfd);
3602 for (i = 0; i < dysymtab->nmodtab; i++)
3604 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
3605 fprintf (file, " module %u:\n", i);
3606 fprintf (file, " name: %lu", module->module_name_idx);
3607 if (mdata->symtab && mdata->symtab->strtab)
3608 fprintf (file, ": %s",
3609 mdata->symtab->strtab + module->module_name_idx);
3610 fprintf (file, "\n");
3611 fprintf (file, " extdefsym: idx: %8lu num: %lu\n",
3612 module->iextdefsym, module->nextdefsym);
3613 fprintf (file, " refsym: idx: %8lu num: %lu\n",
3614 module->irefsym, module->nrefsym);
3615 fprintf (file, " localsym: idx: %8lu num: %lu\n",
3616 module->ilocalsym, module->nlocalsym);
3617 fprintf (file, " extrel: idx: %8lu num: %lu\n",
3618 module->iextrel, module->nextrel);
3619 fprintf (file, " init: idx: %8u num: %u\n",
3620 module->iinit, module->ninit);
3621 fprintf (file, " term: idx: %8u num: %u\n",
3622 module->iterm, module->nterm);
3623 fprintf (file, " objc_module_info: addr: ");
3624 fprintf_vma (file, module->objc_module_info_addr);
3625 fprintf (file, " size: %lu\n", module->objc_module_info_size);
3628 if (dysymtab->ntoc > 0)
3630 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3632 fprintf (file, " table of content: (symbol/module)\n");
3633 for (i = 0; i < dysymtab->ntoc; i++)
3635 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
3637 fprintf (file, " %4u: ", i);
3638 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
3640 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
3641 fprintf (file, "%s (%lu)", name ? name : "*invalid*",
3642 toc->symbol_index);
3644 else
3645 fprintf (file, "%lu", toc->symbol_index);
3647 fprintf (file, " / ");
3648 if (symtab && symtab->strtab
3649 && toc->module_index < dysymtab->nmodtab)
3651 bfd_mach_o_dylib_module *mod;
3652 mod = &dysymtab->dylib_module[toc->module_index];
3653 fprintf (file, "%s (%lu)",
3654 symtab->strtab + mod->module_name_idx,
3655 toc->module_index);
3657 else
3658 fprintf (file, "%lu", toc->module_index);
3660 fprintf (file, "\n");
3664 if (dysymtab->nindirectsyms != 0)
3666 fprintf (file, " indirect symbols:\n");
3668 for (i = 0; i < mdata->nsects; i++)
3670 bfd_mach_o_section *sec = mdata->sections[i];
3671 unsigned int j, first, last;
3672 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3673 bfd_vma addr;
3674 bfd_vma entry_size;
3676 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3678 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3679 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3680 case BFD_MACH_O_S_SYMBOL_STUBS:
3681 first = sec->reserved1;
3682 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
3683 addr = sec->addr;
3684 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
3685 fprintf (file, " for section %s.%s:\n",
3686 sec->segname, sec->sectname);
3687 for (j = first; j < last; j++)
3689 unsigned int isym = dysymtab->indirect_syms[j];
3691 fprintf (file, " ");
3692 fprintf_vma (file, addr);
3693 fprintf (file, " %5u: 0x%08x", j, isym);
3694 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
3695 fprintf (file, " LOCAL");
3696 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
3697 fprintf (file, " ABSOLUTE");
3698 if (symtab && symtab->symbols
3699 && isym < symtab->nsyms
3700 && symtab->symbols[isym].symbol.name)
3701 fprintf (file, " %s", symtab->symbols[isym].symbol.name);
3702 fprintf (file, "\n");
3703 addr += entry_size;
3705 break;
3706 default:
3707 break;
3711 if (dysymtab->nextrefsyms > 0)
3713 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3715 fprintf (file, " external reference table: (symbol flags)\n");
3716 for (i = 0; i < dysymtab->nextrefsyms; i++)
3718 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
3720 fprintf (file, " %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
3721 if (symtab && symtab->symbols
3722 && ref->isym < symtab->nsyms
3723 && symtab->symbols[ref->isym].symbol.name)
3724 fprintf (file, " %s", symtab->symbols[ref->isym].symbol.name);
3725 fprintf (file, "\n");
3731 static void
3732 bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED,
3733 bfd_mach_o_load_command *cmd, FILE *file)
3735 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
3737 fprintf (file, " rebase: off: 0x%08x size: %-8u\n",
3738 info->rebase_off, info->rebase_size);
3739 fprintf (file, " bind: off: 0x%08x size: %-8u\n",
3740 info->bind_off, info->bind_size);
3741 fprintf (file, " weak bind: off: 0x%08x size: %-8u\n",
3742 info->weak_bind_off, info->weak_bind_size);
3743 fprintf (file, " lazy bind: off: 0x%08x size: %-8u\n",
3744 info->lazy_bind_off, info->lazy_bind_size);
3745 fprintf (file, " export: off: 0x%08x size: %-8u\n",
3746 info->export_off, info->export_size);
3749 bfd_boolean
3750 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
3752 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3753 FILE *file = (FILE *) ptr;
3754 unsigned int i;
3756 bfd_mach_o_print_private_header (abfd, file);
3757 fputc ('\n', file);
3759 for (i = 0; i < mdata->header.ncmds; i++)
3761 bfd_mach_o_load_command *cmd = &mdata->commands[i];
3763 fprintf (file, "Load command %s:",
3764 bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
3765 switch (cmd->type)
3767 case BFD_MACH_O_LC_SEGMENT:
3768 case BFD_MACH_O_LC_SEGMENT_64:
3769 bfd_mach_o_print_segment (abfd, cmd, file);
3770 break;
3771 case BFD_MACH_O_LC_UUID:
3773 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
3774 unsigned int j;
3776 for (j = 0; j < sizeof (uuid->uuid); j ++)
3777 fprintf (file, " %02x", uuid->uuid[j]);
3778 fputc ('\n', file);
3780 break;
3781 case BFD_MACH_O_LC_LOAD_DYLIB:
3782 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
3783 case BFD_MACH_O_LC_REEXPORT_DYLIB:
3784 case BFD_MACH_O_LC_ID_DYLIB:
3786 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
3787 fprintf (file, " %s\n", dylib->name_str);
3788 fprintf (file, " time stamp: 0x%08lx\n",
3789 dylib->timestamp);
3790 fprintf (file, " current version: 0x%08lx\n",
3791 dylib->current_version);
3792 fprintf (file, " comptibility version: 0x%08lx\n",
3793 dylib->compatibility_version);
3794 break;
3796 case BFD_MACH_O_LC_LOAD_DYLINKER:
3797 case BFD_MACH_O_LC_ID_DYLINKER:
3798 fprintf (file, " %s\n", cmd->command.dylinker.name_str);
3799 break;
3800 case BFD_MACH_O_LC_SYMTAB:
3802 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
3803 fprintf (file,
3804 "\n"
3805 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
3806 symtab->symoff, symtab->nsyms,
3807 symtab->symoff + symtab->nsyms
3808 * (mach_o_wide_p (&mdata->header)
3809 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
3810 fprintf (file,
3811 " stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
3812 symtab->stroff, symtab->strsize,
3813 symtab->stroff + symtab->strsize);
3814 break;
3816 case BFD_MACH_O_LC_DYSYMTAB:
3817 fprintf (file, "\n");
3818 bfd_mach_o_print_dysymtab (abfd, cmd, file);
3819 break;
3820 case BFD_MACH_O_LC_CODE_SIGNATURE:
3821 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
3823 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
3824 fprintf
3825 (file, "\n"
3826 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
3827 linkedit->dataoff, linkedit->datasize,
3828 linkedit->dataoff + linkedit->datasize);
3829 break;
3831 case BFD_MACH_O_LC_SUB_FRAMEWORK:
3832 case BFD_MACH_O_LC_SUB_UMBRELLA:
3833 case BFD_MACH_O_LC_SUB_LIBRARY:
3834 case BFD_MACH_O_LC_SUB_CLIENT:
3835 case BFD_MACH_O_LC_RPATH:
3837 bfd_mach_o_str_command *str = &cmd->command.str;
3838 fprintf (file, " %s\n", str->str);
3839 break;
3841 case BFD_MACH_O_LC_THREAD:
3842 case BFD_MACH_O_LC_UNIXTHREAD:
3844 bfd_mach_o_thread_command *thread = &cmd->command.thread;
3845 unsigned int j;
3846 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3848 fprintf (file, " nflavours: %lu\n", thread->nflavours);
3849 for (j = 0; j < thread->nflavours; j++)
3851 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
3853 fprintf (file, " %2u: flavour: 0x%08lx offset: 0x%08lx"
3854 " size: 0x%08lx\n",
3855 j, flavour->flavour, flavour->offset,
3856 flavour->size);
3857 if (bed->_bfd_mach_o_print_thread)
3859 char *buf = bfd_malloc (flavour->size);
3861 if (buf
3862 && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
3863 && (bfd_bread (buf, flavour->size, abfd)
3864 == flavour->size))
3865 (*bed->_bfd_mach_o_print_thread)(abfd, flavour,
3866 file, buf);
3867 free (buf);
3870 break;
3872 case BFD_MACH_O_LC_DYLD_INFO:
3873 fprintf (file, "\n");
3874 bfd_mach_o_print_dyld_info (abfd, cmd, file);
3875 break;
3876 default:
3877 fprintf (file, "\n");
3878 break;
3880 fputc ('\n', file);
3883 bfd_mach_o_print_section_map (abfd, file);
3885 return TRUE;
3889 bfd_mach_o_core_fetch_environment (bfd *abfd,
3890 unsigned char **rbuf,
3891 unsigned int *rlen)
3893 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3894 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
3895 unsigned int i = 0;
3897 for (i = 0; i < mdata->header.ncmds; i++)
3899 bfd_mach_o_load_command *cur = &mdata->commands[i];
3900 bfd_mach_o_segment_command *seg = NULL;
3902 if (cur->type != BFD_MACH_O_LC_SEGMENT)
3903 continue;
3905 seg = &cur->command.segment;
3907 if ((seg->vmaddr + seg->vmsize) == stackaddr)
3909 unsigned long start = seg->fileoff;
3910 unsigned long end = seg->fileoff + seg->filesize;
3911 unsigned char *buf = bfd_malloc (1024);
3912 unsigned long size = 1024;
3914 for (;;)
3916 bfd_size_type nread = 0;
3917 unsigned long offset;
3918 int found_nonnull = 0;
3920 if (size > (end - start))
3921 size = (end - start);
3923 buf = bfd_realloc_or_free (buf, size);
3924 if (buf == NULL)
3925 return -1;
3927 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
3929 free (buf);
3930 return -1;
3933 nread = bfd_bread (buf, size, abfd);
3935 if (nread != size)
3937 free (buf);
3938 return -1;
3941 for (offset = 4; offset <= size; offset += 4)
3943 unsigned long val;
3945 val = *((unsigned long *) (buf + size - offset));
3946 if (! found_nonnull)
3948 if (val != 0)
3949 found_nonnull = 1;
3951 else if (val == 0x0)
3953 unsigned long bottom;
3954 unsigned long top;
3956 bottom = seg->fileoff + seg->filesize - offset;
3957 top = seg->fileoff + seg->filesize - 4;
3958 *rbuf = bfd_malloc (top - bottom);
3959 *rlen = top - bottom;
3961 memcpy (*rbuf, buf + size - *rlen, *rlen);
3962 free (buf);
3963 return 0;
3967 if (size == (end - start))
3968 break;
3970 size *= 2;
3973 free (buf);
3977 return -1;
3980 char *
3981 bfd_mach_o_core_file_failing_command (bfd *abfd)
3983 unsigned char *buf = NULL;
3984 unsigned int len = 0;
3985 int ret = -1;
3987 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
3988 if (ret < 0)
3989 return NULL;
3991 return (char *) buf;
3995 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3997 return 0;
4000 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
4001 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4003 #define bfd_mach_o_swap_reloc_in NULL
4004 #define bfd_mach_o_swap_reloc_out NULL
4005 #define bfd_mach_o_print_thread NULL
4007 #define TARGET_NAME mach_o_be_vec
4008 #define TARGET_STRING "mach-o-be"
4009 #define TARGET_ARCHITECTURE bfd_arch_unknown
4010 #define TARGET_BIG_ENDIAN 1
4011 #define TARGET_ARCHIVE 0
4012 #include "mach-o-target.c"
4014 #undef TARGET_NAME
4015 #undef TARGET_STRING
4016 #undef TARGET_ARCHITECTURE
4017 #undef TARGET_BIG_ENDIAN
4018 #undef TARGET_ARCHIVE
4020 #define TARGET_NAME mach_o_le_vec
4021 #define TARGET_STRING "mach-o-le"
4022 #define TARGET_ARCHITECTURE bfd_arch_unknown
4023 #define TARGET_BIG_ENDIAN 0
4024 #define TARGET_ARCHIVE 0
4026 #include "mach-o-target.c"
4028 #undef TARGET_NAME
4029 #undef TARGET_STRING
4030 #undef TARGET_ARCHITECTURE
4031 #undef TARGET_BIG_ENDIAN
4032 #undef TARGET_ARCHIVE
4034 /* Not yet handled: creating an archive. */
4035 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4037 /* Not used. */
4038 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4039 #define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4040 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4041 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4042 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4043 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4044 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4045 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
4046 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
4047 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4049 #define TARGET_NAME mach_o_fat_vec
4050 #define TARGET_STRING "mach-o-fat"
4051 #define TARGET_ARCHITECTURE bfd_arch_unknown
4052 #define TARGET_BIG_ENDIAN 1
4053 #define TARGET_ARCHIVE 1
4055 #include "mach-o-target.c"
4057 #undef TARGET_NAME
4058 #undef TARGET_STRING
4059 #undef TARGET_ARCHITECTURE
4060 #undef TARGET_BIG_ENDIAN
4061 #undef TARGET_ARCHIVE