PR ld/11843
[binutils.git] / bfd / mach-o.c
bloba02030e5dcdeddd014e6e8ce08e95192aa30442d
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;
634 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
635 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
637 offset = 8;
638 for (i = 0; i < cmd->nflavours; i++)
640 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
641 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
643 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
644 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
646 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
647 || bfd_bwrite ((void *) buf, 8, abfd) != 8)
648 return -1;
650 offset += cmd->flavours[i].size + 8;
653 return 0;
656 long
657 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
658 asection *asect)
660 return (asect->reloc_count + 1) * sizeof (arelent *);
663 static int
664 bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
665 arelent *res, asymbol **syms)
667 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
668 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
669 bfd_mach_o_reloc_info reloc;
670 bfd_vma addr;
671 bfd_vma symnum;
672 asymbol **sym;
674 addr = bfd_get_32 (abfd, buf + 0);
675 symnum = bfd_get_32 (abfd, buf + 4);
677 if (addr & BFD_MACH_O_SR_SCATTERED)
679 unsigned int j;
681 /* Scattered relocation.
682 Extract section and offset from r_value. */
683 res->sym_ptr_ptr = NULL;
684 res->addend = 0;
685 for (j = 0; j < mdata->nsects; j++)
687 bfd_mach_o_section *sect = mdata->sections[j];
688 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
690 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
691 res->addend = symnum - sect->addr;
692 break;
695 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
696 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
697 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
698 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
699 reloc.r_scattered = 1;
701 else
703 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
704 res->addend = 0;
705 res->address = addr;
706 if (symnum & BFD_MACH_O_R_EXTERN)
708 sym = syms + num;
709 reloc.r_extern = 1;
711 else
713 BFD_ASSERT (num != 0);
714 BFD_ASSERT (num <= mdata->nsects);
715 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
716 /* For a symbol defined in section S, the addend (stored in the
717 binary) contains the address of the section. To comply with
718 bfd conventio, substract the section address.
719 Use the address from the header, so that the user can modify
720 the vma of the section. */
721 res->addend = -mdata->sections[num - 1]->addr;
722 reloc.r_extern = 0;
724 res->sym_ptr_ptr = sym;
725 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
726 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
727 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
728 reloc.r_scattered = 0;
731 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
732 return -1;
733 return 0;
736 static int
737 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
738 unsigned long count,
739 arelent *res, asymbol **syms)
741 unsigned long i;
742 char *native_relocs;
743 bfd_size_type native_size;
745 /* Allocate and read relocs. */
746 native_size = count * BFD_MACH_O_RELENT_SIZE;
747 native_relocs = bfd_malloc (native_size);
748 if (native_relocs == NULL)
749 return -1;
751 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
752 || bfd_bread (native_relocs, native_size, abfd) != native_size)
753 goto err;
755 for (i = 0; i < count; i++)
757 char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
759 if (bfd_mach_o_canonicalize_one_reloc (abfd, buf, &res[i], syms) < 0)
760 goto err;
762 free (native_relocs);
763 return i;
764 err:
765 free (native_relocs);
766 return -1;
769 long
770 bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
771 arelent **rels, asymbol **syms)
773 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
774 unsigned long i;
775 arelent *res;
777 if (asect->reloc_count == 0)
778 return 0;
780 /* No need to go further if we don't know how to read relocs. */
781 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
782 return 0;
784 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
785 if (res == NULL)
786 return -1;
788 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
789 asect->reloc_count, res, syms) < 0)
791 free (res);
792 return -1;
795 for (i = 0; i < asect->reloc_count; i++)
796 rels[i] = &res[i];
797 rels[i] = NULL;
798 asect->relocation = res;
800 return i;
803 long
804 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
806 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
808 if (mdata->dysymtab == NULL)
809 return 1;
810 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
811 * sizeof (arelent *);
814 long
815 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
816 struct bfd_symbol **syms)
818 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
819 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
820 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
821 unsigned long i;
822 arelent *res;
824 if (dysymtab == NULL)
825 return 0;
826 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
827 return 0;
829 /* No need to go further if we don't know how to read relocs. */
830 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
831 return 0;
833 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
834 if (res == NULL)
835 return -1;
837 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
838 dysymtab->nextrel, res, syms) < 0)
840 free (res);
841 return -1;
844 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
845 dysymtab->nlocrel,
846 res + dysymtab->nextrel, syms) < 0)
848 free (res);
849 return -1;
852 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
853 rels[i] = &res[i];
854 rels[i] = NULL;
855 return i;
858 static bfd_boolean
859 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
861 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
862 unsigned int i;
863 arelent **entries;
864 asection *sec;
865 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
867 sec = section->bfdsection;
868 if (sec->reloc_count == 0)
869 return TRUE;
871 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
872 return TRUE;
874 /* Allocate relocation room. */
875 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
876 section->nreloc = sec->reloc_count;
877 sec->rel_filepos = mdata->filelen;
878 section->reloff = sec->rel_filepos;
879 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
881 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
882 return FALSE;
884 /* Convert and write. */
885 entries = section->bfdsection->orelocation;
886 for (i = 0; i < section->nreloc; i++)
888 arelent *rel = entries[i];
889 char buf[8];
890 bfd_mach_o_reloc_info info, *pinfo = &info;
892 /* Convert relocation to an intermediate representation. */
893 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
894 return FALSE;
896 /* Lower the relocation info. */
897 if (pinfo->r_scattered)
899 unsigned long v;
901 v = BFD_MACH_O_SR_SCATTERED
902 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
903 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
904 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
905 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
906 bfd_put_32 (abfd, v, buf);
907 bfd_put_32 (abfd, pinfo->r_value, buf + 4);
909 else
911 unsigned long v;
913 bfd_put_32 (abfd, pinfo->r_address, buf);
914 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
915 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
916 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
917 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
918 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
919 bfd_put_32 (abfd, v, buf + 4);
922 if (bfd_bwrite ((void *) buf, BFD_MACH_O_RELENT_SIZE, abfd)
923 != BFD_MACH_O_RELENT_SIZE)
924 return FALSE;
926 return TRUE;
929 static int
930 bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
932 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
934 memcpy (buf, section->sectname, 16);
935 memcpy (buf + 16, section->segname, 16);
936 bfd_h_put_32 (abfd, section->addr, buf + 32);
937 bfd_h_put_32 (abfd, section->size, buf + 36);
938 bfd_h_put_32 (abfd, section->offset, buf + 40);
939 bfd_h_put_32 (abfd, section->align, buf + 44);
940 bfd_h_put_32 (abfd, section->reloff, buf + 48);
941 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
942 bfd_h_put_32 (abfd, section->flags, buf + 56);
943 bfd_h_put_32 (abfd, section->reserved1, buf + 60);
944 bfd_h_put_32 (abfd, section->reserved2, buf + 64);
946 if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
947 != BFD_MACH_O_SECTION_SIZE)
948 return -1;
950 return 0;
953 static int
954 bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
956 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
958 memcpy (buf, section->sectname, 16);
959 memcpy (buf + 16, section->segname, 16);
960 bfd_h_put_64 (abfd, section->addr, buf + 32);
961 bfd_h_put_64 (abfd, section->size, buf + 40);
962 bfd_h_put_32 (abfd, section->offset, buf + 48);
963 bfd_h_put_32 (abfd, section->align, buf + 52);
964 bfd_h_put_32 (abfd, section->reloff, buf + 56);
965 bfd_h_put_32 (abfd, section->nreloc, buf + 60);
966 bfd_h_put_32 (abfd, section->flags, buf + 64);
967 bfd_h_put_32 (abfd, section->reserved1, buf + 68);
968 bfd_h_put_32 (abfd, section->reserved2, buf + 72);
969 bfd_h_put_32 (abfd, section->reserved3, buf + 76);
971 if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
972 != BFD_MACH_O_SECTION_64_SIZE)
973 return -1;
975 return 0;
978 static int
979 bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
981 unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
982 bfd_mach_o_segment_command *seg = &command->command.segment;
983 unsigned long i;
985 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
987 for (i = 0; i < seg->nsects; i++)
988 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
989 return -1;
991 memcpy (buf, seg->segname, 16);
992 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
993 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
994 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
995 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
996 bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
997 bfd_h_put_32 (abfd, seg->initprot, buf + 36);
998 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
999 bfd_h_put_32 (abfd, seg->flags, buf + 44);
1001 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1002 || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd)
1003 != BFD_MACH_O_LC_SEGMENT_SIZE - 8))
1004 return -1;
1006 for (i = 0; i < seg->nsects; i++)
1007 if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
1008 return -1;
1010 return 0;
1013 static int
1014 bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1016 unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
1017 bfd_mach_o_segment_command *seg = &command->command.segment;
1018 unsigned long i;
1020 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1022 for (i = 0; i < seg->nsects; i++)
1023 if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
1024 return -1;
1026 memcpy (buf, seg->segname, 16);
1027 bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
1028 bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
1029 bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
1030 bfd_h_put_64 (abfd, seg->filesize, buf + 40);
1031 bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
1032 bfd_h_put_32 (abfd, seg->initprot, buf + 52);
1033 bfd_h_put_32 (abfd, seg->nsects, buf + 56);
1034 bfd_h_put_32 (abfd, seg->flags, buf + 60);
1036 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1037 || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
1038 != BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
1039 return -1;
1041 for (i = 0; i < seg->nsects; i++)
1042 if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
1043 return -1;
1045 return 0;
1048 static bfd_boolean
1049 bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1051 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1052 bfd_mach_o_symtab_command *sym = &command->command.symtab;
1053 unsigned char buf[16];
1054 unsigned long i;
1055 unsigned int wide = bfd_mach_o_wide_p (abfd);
1056 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1057 struct bfd_strtab_hash *strtab;
1058 asymbol **symbols = bfd_get_outsymbols (abfd);
1060 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1062 /* Write the symbols first. */
1063 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1064 sym->symoff = mdata->filelen;
1065 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1066 return FALSE;
1068 sym->nsyms = bfd_get_symcount (abfd);
1069 mdata->filelen += sym->nsyms * symlen;
1071 strtab = _bfd_stringtab_init ();
1072 if (strtab == NULL)
1073 return FALSE;
1075 for (i = 0; i < sym->nsyms; i++)
1077 bfd_size_type str_index;
1078 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1080 /* Compute name index. */
1081 /* An index of 0 always means the empty string. */
1082 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
1083 str_index = 0;
1084 else
1086 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1087 if (str_index == (bfd_size_type) -1)
1088 goto err;
1090 bfd_h_put_32 (abfd, str_index, buf);
1091 bfd_h_put_8 (abfd, s->n_type, buf + 4);
1092 bfd_h_put_8 (abfd, s->n_sect, buf + 5);
1093 bfd_h_put_16 (abfd, s->n_desc, buf + 6);
1094 if (wide)
1095 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1096 else
1097 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
1099 if (bfd_bwrite ((void *) buf, symlen, abfd) != symlen)
1100 goto err;
1102 sym->strsize = _bfd_stringtab_size (strtab);
1103 sym->stroff = mdata->filelen;
1104 mdata->filelen += sym->strsize;
1106 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1107 goto err;
1108 _bfd_stringtab_free (strtab);
1110 /* The command. */
1111 bfd_h_put_32 (abfd, sym->symoff, buf);
1112 bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
1113 bfd_h_put_32 (abfd, sym->stroff, buf + 8);
1114 bfd_h_put_32 (abfd, sym->strsize, buf + 12);
1116 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1117 || bfd_bwrite ((void *) buf, 16, abfd) != 16)
1118 return FALSE;
1120 return TRUE;
1122 err:
1123 _bfd_stringtab_free (strtab);
1124 return FALSE;
1127 /* Process the symbols and generate Mach-O specific fields.
1128 Number them. */
1130 static bfd_boolean
1131 bfd_mach_o_mangle_symbols (bfd *abfd)
1133 unsigned long i;
1134 asymbol **symbols = bfd_get_outsymbols (abfd);
1136 for (i = 0; i < bfd_get_symcount (abfd); i++)
1138 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1140 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1142 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1143 symbols should be N_UNDEF | N_EXT), we suppose the back-end
1144 values haven't been set. */
1145 if (s->symbol.section == bfd_abs_section_ptr)
1146 s->n_type = BFD_MACH_O_N_ABS;
1147 else if (s->symbol.section == bfd_und_section_ptr)
1149 s->n_type = BFD_MACH_O_N_UNDF;
1150 if (s->symbol.flags & BSF_WEAK)
1151 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1153 else if (s->symbol.section == bfd_com_section_ptr)
1154 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1155 else
1156 s->n_type = BFD_MACH_O_N_SECT;
1158 if (s->symbol.flags & BSF_GLOBAL)
1159 s->n_type |= BFD_MACH_O_N_EXT;
1162 /* Compute section index. */
1163 if (s->symbol.section != bfd_abs_section_ptr
1164 && s->symbol.section != bfd_und_section_ptr
1165 && s->symbol.section != bfd_com_section_ptr)
1166 s->n_sect = s->symbol.section->target_index;
1168 /* Number symbols. */
1169 s->symbol.udata.i = i;
1171 return TRUE;
1174 bfd_boolean
1175 bfd_mach_o_write_contents (bfd *abfd)
1177 unsigned int i;
1178 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1180 if (mdata->header.ncmds == 0)
1181 if (!bfd_mach_o_build_commands (abfd))
1182 return FALSE;
1184 /* Now write header information. */
1185 if (mdata->header.filetype == 0)
1187 if (abfd->flags & EXEC_P)
1188 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1189 else if (abfd->flags & DYNAMIC)
1190 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1191 else
1192 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1194 if (!bfd_mach_o_write_header (abfd, &mdata->header))
1195 return FALSE;
1197 /* Assign a number to each symbols. */
1198 if (!bfd_mach_o_mangle_symbols (abfd))
1199 return FALSE;
1201 for (i = 0; i < mdata->header.ncmds; i++)
1203 unsigned char buf[8];
1204 bfd_mach_o_load_command *cur = &mdata->commands[i];
1205 unsigned long typeflag;
1207 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
1209 bfd_h_put_32 (abfd, typeflag, buf);
1210 bfd_h_put_32 (abfd, cur->len, buf + 4);
1212 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1213 || bfd_bwrite ((void *) buf, 8, abfd) != 8)
1214 return FALSE;
1216 switch (cur->type)
1218 case BFD_MACH_O_LC_SEGMENT:
1219 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1220 return FALSE;
1221 break;
1222 case BFD_MACH_O_LC_SEGMENT_64:
1223 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
1224 return FALSE;
1225 break;
1226 case BFD_MACH_O_LC_SYMTAB:
1227 if (!bfd_mach_o_write_symtab (abfd, cur))
1228 return FALSE;
1229 break;
1230 case BFD_MACH_O_LC_SYMSEG:
1231 break;
1232 case BFD_MACH_O_LC_THREAD:
1233 case BFD_MACH_O_LC_UNIXTHREAD:
1234 if (bfd_mach_o_write_thread (abfd, cur) != 0)
1235 return FALSE;
1236 break;
1237 case BFD_MACH_O_LC_LOADFVMLIB:
1238 case BFD_MACH_O_LC_IDFVMLIB:
1239 case BFD_MACH_O_LC_IDENT:
1240 case BFD_MACH_O_LC_FVMFILE:
1241 case BFD_MACH_O_LC_PREPAGE:
1242 case BFD_MACH_O_LC_DYSYMTAB:
1243 case BFD_MACH_O_LC_LOAD_DYLIB:
1244 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1245 case BFD_MACH_O_LC_ID_DYLIB:
1246 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1247 case BFD_MACH_O_LC_LOAD_DYLINKER:
1248 case BFD_MACH_O_LC_ID_DYLINKER:
1249 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1250 case BFD_MACH_O_LC_ROUTINES:
1251 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1252 break;
1253 default:
1254 fprintf (stderr,
1255 "unable to write unknown load command 0x%lx\n",
1256 (unsigned long) cur->type);
1257 return FALSE;
1261 return TRUE;
1264 /* Build Mach-O load commands from the sections. */
1266 bfd_boolean
1267 bfd_mach_o_build_commands (bfd *abfd)
1269 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1270 unsigned int wide = mach_o_wide_p (&mdata->header);
1271 bfd_mach_o_segment_command *seg;
1272 bfd_mach_o_section *sections;
1273 asection *sec;
1274 bfd_mach_o_load_command *cmd;
1275 bfd_mach_o_load_command *symtab_cmd;
1276 int target_index;
1278 /* Return now if commands are already built. */
1279 if (mdata->header.ncmds)
1280 return FALSE;
1282 /* Very simple version: 1 command (segment) containing all sections. */
1283 mdata->header.ncmds = 2;
1284 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1285 * sizeof (bfd_mach_o_load_command));
1286 if (mdata->commands == NULL)
1287 return FALSE;
1288 cmd = &mdata->commands[0];
1289 seg = &cmd->command.segment;
1291 seg->nsects = bfd_count_sections (abfd);
1292 sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1293 if (sections == NULL)
1294 return FALSE;
1295 seg->sections = sections;
1297 /* Set segment command. */
1298 if (wide)
1300 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1301 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1302 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1303 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1305 else
1307 cmd->type = BFD_MACH_O_LC_SEGMENT;
1308 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1309 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1310 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1312 cmd->type_required = FALSE;
1313 mdata->header.sizeofcmds = cmd->len;
1314 mdata->filelen = cmd->offset + cmd->len;
1316 /* Set symtab command. */
1317 symtab_cmd = &mdata->commands[1];
1319 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1320 symtab_cmd->offset = cmd->offset + cmd->len;
1321 symtab_cmd->len = 6 * 4;
1322 symtab_cmd->type_required = FALSE;
1324 mdata->header.sizeofcmds += symtab_cmd->len;
1325 mdata->filelen += symtab_cmd->len;
1327 /* Fill segment command. */
1328 memset (seg->segname, 0, sizeof (seg->segname));
1329 seg->vmaddr = 0;
1330 seg->fileoff = mdata->filelen;
1331 seg->filesize = 0;
1332 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1333 | BFD_MACH_O_PROT_EXECUTE;
1334 seg->initprot = seg->maxprot;
1335 seg->flags = 0;
1337 /* Create Mach-O sections. */
1338 target_index = 0;
1339 for (sec = abfd->sections; sec; sec = sec->next)
1341 sections->bfdsection = sec;
1342 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
1343 sections->addr = bfd_get_section_vma (abfd, sec);
1344 sections->size = bfd_get_section_size (sec);
1345 sections->align = bfd_get_section_alignment (abfd, sec);
1347 if (sections->size != 0)
1349 mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
1350 sections->offset = mdata->filelen;
1352 else
1353 sections->offset = 0;
1354 sections->reloff = 0;
1355 sections->nreloc = 0;
1356 sections->reserved1 = 0;
1357 sections->reserved2 = 0;
1358 sections->reserved3 = 0;
1360 sec->filepos = sections->offset;
1361 sec->target_index = ++target_index;
1363 mdata->filelen += sections->size;
1364 sections++;
1366 seg->filesize = mdata->filelen - seg->fileoff;
1367 seg->vmsize = seg->filesize;
1369 return TRUE;
1372 /* Set the contents of a section. */
1374 bfd_boolean
1375 bfd_mach_o_set_section_contents (bfd *abfd,
1376 asection *section,
1377 const void * location,
1378 file_ptr offset,
1379 bfd_size_type count)
1381 file_ptr pos;
1383 /* This must be done first, because bfd_set_section_contents is
1384 going to set output_has_begun to TRUE. */
1385 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1386 return FALSE;
1388 if (count == 0)
1389 return TRUE;
1391 pos = section->filepos + offset;
1392 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1393 || bfd_bwrite (location, count, abfd) != count)
1394 return FALSE;
1396 return TRUE;
1400 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1401 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1403 return 0;
1406 /* Make an empty symbol. This is required only because
1407 bfd_make_section_anyway wants to create a symbol for the section. */
1409 asymbol *
1410 bfd_mach_o_make_empty_symbol (bfd *abfd)
1412 asymbol *new_symbol;
1414 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1415 if (new_symbol == NULL)
1416 return new_symbol;
1417 new_symbol->the_bfd = abfd;
1418 new_symbol->udata.i = 0;
1419 return new_symbol;
1422 static bfd_boolean
1423 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1425 unsigned char buf[32];
1426 unsigned int size;
1427 bfd_vma (*get32) (const void *) = NULL;
1429 /* Just read the magic number. */
1430 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1431 || bfd_bread ((void *) buf, 4, abfd) != 4)
1432 return FALSE;
1434 if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
1436 header->byteorder = BFD_ENDIAN_BIG;
1437 header->magic = BFD_MACH_O_MH_MAGIC;
1438 header->version = 1;
1439 get32 = bfd_getb32;
1441 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
1443 header->byteorder = BFD_ENDIAN_LITTLE;
1444 header->magic = BFD_MACH_O_MH_MAGIC;
1445 header->version = 1;
1446 get32 = bfd_getl32;
1448 else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1450 header->byteorder = BFD_ENDIAN_BIG;
1451 header->magic = BFD_MACH_O_MH_MAGIC_64;
1452 header->version = 2;
1453 get32 = bfd_getb32;
1455 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1457 header->byteorder = BFD_ENDIAN_LITTLE;
1458 header->magic = BFD_MACH_O_MH_MAGIC_64;
1459 header->version = 2;
1460 get32 = bfd_getl32;
1462 else
1464 header->byteorder = BFD_ENDIAN_UNKNOWN;
1465 return FALSE;
1468 /* Once the size of the header is known, read the full header. */
1469 size = mach_o_wide_p (header) ?
1470 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1472 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1473 || bfd_bread ((void *) buf, size, abfd) != size)
1474 return FALSE;
1476 header->cputype = (*get32) (buf + 4);
1477 header->cpusubtype = (*get32) (buf + 8);
1478 header->filetype = (*get32) (buf + 12);
1479 header->ncmds = (*get32) (buf + 16);
1480 header->sizeofcmds = (*get32) (buf + 20);
1481 header->flags = (*get32) (buf + 24);
1483 if (mach_o_wide_p (header))
1484 header->reserved = (*get32) (buf + 28);
1486 return TRUE;
1489 static asection *
1490 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
1491 unsigned long prot)
1493 asection *bfdsec;
1494 char *sname;
1495 flagword flags;
1497 bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
1498 if (sname == NULL)
1499 return NULL;
1501 if (flags == SEC_NO_FLAGS)
1503 /* Try to guess flags. */
1504 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1505 flags = SEC_DEBUGGING;
1506 else
1508 flags = SEC_ALLOC;
1509 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1510 != BFD_MACH_O_S_ZEROFILL)
1512 flags |= SEC_LOAD;
1513 if (prot & BFD_MACH_O_PROT_EXECUTE)
1514 flags |= SEC_CODE;
1515 if (prot & BFD_MACH_O_PROT_WRITE)
1516 flags |= SEC_DATA;
1517 else if (prot & BFD_MACH_O_PROT_READ)
1518 flags |= SEC_READONLY;
1522 else
1524 if ((flags & SEC_DEBUGGING) == 0)
1525 flags |= SEC_ALLOC;
1528 if (section->offset != 0)
1529 flags |= SEC_HAS_CONTENTS;
1530 if (section->nreloc != 0)
1531 flags |= SEC_RELOC;
1533 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1534 if (bfdsec == NULL)
1535 return NULL;
1537 bfdsec->vma = section->addr;
1538 bfdsec->lma = section->addr;
1539 bfdsec->size = section->size;
1540 bfdsec->filepos = section->offset;
1541 bfdsec->alignment_power = section->align;
1542 bfdsec->segment_mark = 0;
1543 bfdsec->reloc_count = section->nreloc;
1544 bfdsec->rel_filepos = section->reloff;
1546 return bfdsec;
1549 static int
1550 bfd_mach_o_read_section_32 (bfd *abfd,
1551 bfd_mach_o_section *section,
1552 unsigned int offset,
1553 unsigned long prot)
1555 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
1557 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1558 || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
1559 != BFD_MACH_O_SECTION_SIZE))
1560 return -1;
1562 memcpy (section->sectname, buf, 16);
1563 section->sectname[16] = '\0';
1564 memcpy (section->segname, buf + 16, 16);
1565 section->segname[16] = '\0';
1566 section->addr = bfd_h_get_32 (abfd, buf + 32);
1567 section->size = bfd_h_get_32 (abfd, buf + 36);
1568 section->offset = bfd_h_get_32 (abfd, buf + 40);
1569 section->align = bfd_h_get_32 (abfd, buf + 44);
1570 section->reloff = bfd_h_get_32 (abfd, buf + 48);
1571 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
1572 section->flags = bfd_h_get_32 (abfd, buf + 56);
1573 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
1574 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
1575 section->reserved3 = 0;
1576 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1578 if (section->bfdsection == NULL)
1579 return -1;
1581 return 0;
1584 static int
1585 bfd_mach_o_read_section_64 (bfd *abfd,
1586 bfd_mach_o_section *section,
1587 unsigned int offset,
1588 unsigned long prot)
1590 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
1592 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1593 || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
1594 != BFD_MACH_O_SECTION_64_SIZE))
1595 return -1;
1597 memcpy (section->sectname, buf, 16);
1598 section->sectname[16] = '\0';
1599 memcpy (section->segname, buf + 16, 16);
1600 section->segname[16] = '\0';
1601 section->addr = bfd_h_get_64 (abfd, buf + 32);
1602 section->size = bfd_h_get_64 (abfd, buf + 40);
1603 section->offset = bfd_h_get_32 (abfd, buf + 48);
1604 section->align = bfd_h_get_32 (abfd, buf + 52);
1605 section->reloff = bfd_h_get_32 (abfd, buf + 56);
1606 section->nreloc = bfd_h_get_32 (abfd, buf + 60);
1607 section->flags = bfd_h_get_32 (abfd, buf + 64);
1608 section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
1609 section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
1610 section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
1611 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1613 if (section->bfdsection == NULL)
1614 return -1;
1616 return 0;
1619 static int
1620 bfd_mach_o_read_section (bfd *abfd,
1621 bfd_mach_o_section *section,
1622 unsigned int offset,
1623 unsigned long prot,
1624 unsigned int wide)
1626 if (wide)
1627 return bfd_mach_o_read_section_64 (abfd, section, offset, prot);
1628 else
1629 return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
1632 static int
1633 bfd_mach_o_read_symtab_symbol (bfd *abfd,
1634 bfd_mach_o_symtab_command *sym,
1635 bfd_mach_o_asymbol *s,
1636 unsigned long i)
1638 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1639 unsigned int wide = mach_o_wide_p (&mdata->header);
1640 unsigned int symwidth =
1641 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1642 unsigned int symoff = sym->symoff + (i * symwidth);
1643 unsigned char buf[16];
1644 unsigned char type = -1;
1645 unsigned char section = -1;
1646 short desc = -1;
1647 symvalue value = -1;
1648 unsigned long stroff = -1;
1649 unsigned int symtype = -1;
1651 BFD_ASSERT (sym->strtab != NULL);
1653 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1654 || bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
1656 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu\n",
1657 symwidth, (unsigned long) symoff);
1658 return -1;
1661 stroff = bfd_h_get_32 (abfd, buf);
1662 type = bfd_h_get_8 (abfd, buf + 4);
1663 symtype = type & BFD_MACH_O_N_TYPE;
1664 section = bfd_h_get_8 (abfd, buf + 5);
1665 desc = bfd_h_get_16 (abfd, buf + 6);
1666 if (wide)
1667 value = bfd_h_get_64 (abfd, buf + 8);
1668 else
1669 value = bfd_h_get_32 (abfd, buf + 8);
1671 if (stroff >= sym->strsize)
1673 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
1674 (unsigned long) stroff, (unsigned long) sym->strsize);
1675 return -1;
1678 s->symbol.the_bfd = abfd;
1679 s->symbol.name = sym->strtab + stroff;
1680 s->symbol.value = value;
1681 s->symbol.flags = 0x0;
1682 s->symbol.udata.i = 0;
1683 s->n_type = type;
1684 s->n_sect = section;
1685 s->n_desc = desc;
1687 if (type & BFD_MACH_O_N_STAB)
1689 s->symbol.flags |= BSF_DEBUGGING;
1690 s->symbol.section = bfd_und_section_ptr;
1691 switch (type)
1693 case N_FUN:
1694 case N_STSYM:
1695 case N_LCSYM:
1696 case N_BNSYM:
1697 case N_SLINE:
1698 case N_ENSYM:
1699 case N_ECOMM:
1700 case N_ECOML:
1701 case N_GSYM:
1702 if ((section > 0) && (section <= mdata->nsects))
1704 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1705 s->symbol.value =
1706 s->symbol.value - mdata->sections[section - 1]->addr;
1708 break;
1711 else
1713 if (type & BFD_MACH_O_N_PEXT)
1714 s->symbol.flags |= BSF_GLOBAL;
1716 if (type & BFD_MACH_O_N_EXT)
1717 s->symbol.flags |= BSF_GLOBAL;
1719 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1720 s->symbol.flags |= BSF_LOCAL;
1722 switch (symtype)
1724 case BFD_MACH_O_N_UNDF:
1725 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1726 && s->symbol.value != 0)
1728 /* A common symbol. */
1729 s->symbol.section = bfd_com_section_ptr;
1730 s->symbol.flags = BSF_NO_FLAGS;
1732 else
1734 s->symbol.section = bfd_und_section_ptr;
1735 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1736 s->symbol.flags |= BSF_WEAK;
1738 break;
1739 case BFD_MACH_O_N_PBUD:
1740 s->symbol.section = bfd_und_section_ptr;
1741 break;
1742 case BFD_MACH_O_N_ABS:
1743 s->symbol.section = bfd_abs_section_ptr;
1744 break;
1745 case BFD_MACH_O_N_SECT:
1746 if ((section > 0) && (section <= mdata->nsects))
1748 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1749 s->symbol.value =
1750 s->symbol.value - mdata->sections[section - 1]->addr;
1752 else
1754 /* Mach-O uses 0 to mean "no section"; not an error. */
1755 if (section != 0)
1757 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1758 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
1759 s->symbol.name, section, mdata->nsects);
1761 s->symbol.section = bfd_und_section_ptr;
1763 break;
1764 case BFD_MACH_O_N_INDR:
1765 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1766 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
1767 s->symbol.name);
1768 s->symbol.section = bfd_und_section_ptr;
1769 break;
1770 default:
1771 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
1772 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
1773 s->symbol.name, symtype);
1774 s->symbol.section = bfd_und_section_ptr;
1775 break;
1779 return 0;
1782 static int
1783 bfd_mach_o_read_symtab_strtab (bfd *abfd)
1785 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1786 bfd_mach_o_symtab_command *sym = mdata->symtab;
1788 /* Fail if there is no symtab. */
1789 if (sym == NULL)
1790 return -1;
1792 /* Success if already loaded. */
1793 if (sym->strtab)
1794 return 0;
1796 if (abfd->flags & BFD_IN_MEMORY)
1798 struct bfd_in_memory *b;
1800 b = (struct bfd_in_memory *) abfd->iostream;
1802 if ((sym->stroff + sym->strsize) > b->size)
1804 bfd_set_error (bfd_error_file_truncated);
1805 return -1;
1807 sym->strtab = (char *) b->buffer + sym->stroff;
1809 else
1811 sym->strtab = bfd_alloc (abfd, sym->strsize);
1812 if (sym->strtab == NULL)
1813 return -1;
1815 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1816 || bfd_bread ((void *) sym->strtab, sym->strsize, abfd) != sym->strsize)
1818 bfd_set_error (bfd_error_file_truncated);
1819 return -1;
1823 return 0;
1826 static int
1827 bfd_mach_o_read_symtab_symbols (bfd *abfd)
1829 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1830 bfd_mach_o_symtab_command *sym = mdata->symtab;
1831 unsigned long i;
1832 int ret;
1834 if (sym->symbols)
1835 return 0;
1837 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1839 if (sym->symbols == NULL)
1841 fprintf (stderr, "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols\n");
1842 return -1;
1845 ret = bfd_mach_o_read_symtab_strtab (abfd);
1846 if (ret != 0)
1847 return ret;
1849 for (i = 0; i < sym->nsyms; i++)
1851 ret = bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1852 if (ret != 0)
1853 return ret;
1856 return 0;
1860 bfd_mach_o_read_dysymtab_symbol (bfd *abfd,
1861 bfd_mach_o_dysymtab_command *dysym,
1862 bfd_mach_o_symtab_command *sym,
1863 bfd_mach_o_asymbol *s,
1864 unsigned long i)
1866 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1867 unsigned long sym_index;
1868 unsigned char buf[4];
1870 BFD_ASSERT (i < dysym->nindirectsyms);
1872 if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
1873 || bfd_bread ((void *) buf, 4, abfd) != 4)
1875 fprintf (stderr, "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
1876 (unsigned long) 4, isymoff);
1877 return -1;
1879 sym_index = bfd_h_get_32 (abfd, buf);
1881 return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
1884 static const char *
1885 bfd_mach_o_i386_flavour_string (unsigned int flavour)
1887 switch ((int) flavour)
1889 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
1890 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
1891 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1892 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
1893 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
1894 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1895 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
1896 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
1897 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
1898 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
1899 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
1900 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
1901 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
1902 default: return "UNKNOWN";
1906 static const char *
1907 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1909 switch ((int) flavour)
1911 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1912 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1913 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1914 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1915 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
1916 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
1917 default: return "UNKNOWN";
1921 static int
1922 bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
1924 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1925 unsigned char buf[4];
1926 unsigned int nameoff;
1928 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1929 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1931 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1932 || bfd_bread ((void *) buf, 4, abfd) != 4)
1933 return -1;
1935 nameoff = bfd_h_get_32 (abfd, buf + 0);
1937 cmd->name_offset = command->offset + nameoff;
1938 cmd->name_len = command->len - nameoff;
1939 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1940 if (cmd->name_str == NULL)
1941 return -1;
1942 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1943 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1944 return -1;
1945 return 0;
1948 static int
1949 bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1951 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1952 unsigned char buf[16];
1953 unsigned int nameoff;
1955 switch (command->type)
1957 case BFD_MACH_O_LC_LOAD_DYLIB:
1958 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1959 case BFD_MACH_O_LC_ID_DYLIB:
1960 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1961 break;
1962 default:
1963 BFD_FAIL ();
1964 return -1;
1967 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1968 || bfd_bread ((void *) buf, 16, abfd) != 16)
1969 return -1;
1971 nameoff = bfd_h_get_32 (abfd, buf + 0);
1972 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1973 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1974 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1976 cmd->name_offset = command->offset + nameoff;
1977 cmd->name_len = command->len - nameoff;
1978 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
1979 if (cmd->name_str == NULL)
1980 return -1;
1981 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
1982 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
1983 return -1;
1984 return 0;
1987 static int
1988 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1989 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1991 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1993 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1994 return 0;
1997 static int
1998 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
2000 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2001 bfd_mach_o_thread_command *cmd = &command->command.thread;
2002 unsigned char buf[8];
2003 unsigned int offset;
2004 unsigned int nflavours;
2005 unsigned int i;
2007 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2008 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2010 /* Count the number of threads. */
2011 offset = 8;
2012 nflavours = 0;
2013 while (offset != command->len)
2015 if (offset >= command->len)
2016 return -1;
2018 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2019 || bfd_bread ((void *) buf, 8, abfd) != 8)
2020 return -1;
2022 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
2023 nflavours++;
2026 /* Allocate threads. */
2027 cmd->flavours = bfd_alloc
2028 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
2029 if (cmd->flavours == NULL)
2030 return -1;
2031 cmd->nflavours = nflavours;
2033 offset = 8;
2034 nflavours = 0;
2035 while (offset != command->len)
2037 if (offset >= command->len)
2038 return -1;
2040 if (nflavours >= cmd->nflavours)
2041 return -1;
2043 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2044 || bfd_bread ((void *) buf, 8, abfd) != 8)
2045 return -1;
2047 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
2048 cmd->flavours[nflavours].offset = command->offset + offset + 8;
2049 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
2050 offset += cmd->flavours[nflavours].size + 8;
2051 nflavours++;
2054 for (i = 0; i < nflavours; i++)
2056 asection *bfdsec;
2057 unsigned int snamelen;
2058 char *sname;
2059 const char *flavourstr;
2060 const char *prefix = "LC_THREAD";
2061 unsigned int j = 0;
2063 switch (mdata->header.cputype)
2065 case BFD_MACH_O_CPU_TYPE_POWERPC:
2066 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
2067 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2068 break;
2069 case BFD_MACH_O_CPU_TYPE_I386:
2070 case BFD_MACH_O_CPU_TYPE_X86_64:
2071 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2072 break;
2073 default:
2074 flavourstr = "UNKNOWN_ARCHITECTURE";
2075 break;
2078 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
2079 sname = bfd_alloc (abfd, snamelen);
2080 if (sname == NULL)
2081 return -1;
2083 for (;;)
2085 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2086 if (bfd_get_section_by_name (abfd, sname) == NULL)
2087 break;
2088 j++;
2091 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
2093 bfdsec->vma = 0;
2094 bfdsec->lma = 0;
2095 bfdsec->size = cmd->flavours[i].size;
2096 bfdsec->filepos = cmd->flavours[i].offset;
2097 bfdsec->alignment_power = 0x0;
2099 cmd->section = bfdsec;
2102 return 0;
2105 static int
2106 bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2108 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2109 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2110 unsigned char buf[72];
2112 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2114 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2115 || bfd_bread ((void *) buf, 72, abfd) != 72)
2116 return -1;
2118 cmd->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
2119 cmd->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
2120 cmd->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
2121 cmd->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
2122 cmd->iundefsym = bfd_h_get_32 (abfd, buf + 16);
2123 cmd->nundefsym = bfd_h_get_32 (abfd, buf + 20);
2124 cmd->tocoff = bfd_h_get_32 (abfd, buf + 24);
2125 cmd->ntoc = bfd_h_get_32 (abfd, buf + 28);
2126 cmd->modtaboff = bfd_h_get_32 (abfd, buf + 32);
2127 cmd->nmodtab = bfd_h_get_32 (abfd, buf + 36);
2128 cmd->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
2129 cmd->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
2130 cmd->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
2131 cmd->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
2132 cmd->extreloff = bfd_h_get_32 (abfd, buf + 56);
2133 cmd->nextrel = bfd_h_get_32 (abfd, buf + 60);
2134 cmd->locreloff = bfd_h_get_32 (abfd, buf + 64);
2135 cmd->nlocrel = bfd_h_get_32 (abfd, buf + 68);
2137 if (cmd->nmodtab != 0)
2139 unsigned int i;
2140 int wide = bfd_mach_o_wide_p (abfd);
2141 unsigned int module_len = wide ? 56 : 52;
2143 cmd->dylib_module =
2144 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2145 if (cmd->dylib_module == NULL)
2146 return -1;
2148 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2149 return -1;
2151 for (i = 0; i < cmd->nmodtab; i++)
2153 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2154 unsigned long v;
2156 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
2157 return -1;
2159 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2160 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2161 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2162 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2163 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2164 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2165 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2166 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2167 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2168 v = bfd_h_get_32 (abfd, buf +36);
2169 module->iinit = v & 0xffff;
2170 module->iterm = (v >> 16) & 0xffff;
2171 v = bfd_h_get_32 (abfd, buf + 40);
2172 module->ninit = v & 0xffff;
2173 module->nterm = (v >> 16) & 0xffff;
2174 if (wide)
2176 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2177 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2179 else
2181 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2182 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2187 if (cmd->ntoc != 0)
2189 unsigned int i;
2191 cmd->dylib_toc = bfd_alloc
2192 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2193 if (cmd->dylib_toc == NULL)
2194 return -1;
2196 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2197 return -1;
2199 for (i = 0; i < cmd->ntoc; i++)
2201 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2203 if (bfd_bread ((void *) buf, 8, abfd) != 8)
2204 return -1;
2206 toc->symbol_index = bfd_h_get_32 (abfd, buf + 0);
2207 toc->module_index = bfd_h_get_32 (abfd, buf + 4);
2211 if (cmd->nindirectsyms != 0)
2213 unsigned int i;
2215 cmd->indirect_syms = bfd_alloc
2216 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2217 if (cmd->indirect_syms == NULL)
2218 return -1;
2220 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2221 return -1;
2223 for (i = 0; i < cmd->nindirectsyms; i++)
2225 unsigned int *is = &cmd->indirect_syms[i];
2227 if (bfd_bread ((void *) buf, 4, abfd) != 4)
2228 return -1;
2230 *is = bfd_h_get_32 (abfd, buf + 0);
2234 if (cmd->nextrefsyms != 0)
2236 unsigned long v;
2237 unsigned int i;
2239 cmd->ext_refs = bfd_alloc
2240 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2241 if (cmd->ext_refs == NULL)
2242 return -1;
2244 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2245 return -1;
2247 for (i = 0; i < cmd->nextrefsyms; i++)
2249 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2251 if (bfd_bread ((void *) buf, 4, abfd) != 4)
2252 return -1;
2254 /* Fields isym and flags are written as bit-fields, thus we need
2255 a specific processing for endianness. */
2256 v = bfd_h_get_32 (abfd, buf + 0);
2257 if (bfd_big_endian (abfd))
2259 ref->isym = (v >> 8) & 0xffffff;
2260 ref->flags = v & 0xff;
2262 else
2264 ref->isym = v & 0xffffff;
2265 ref->flags = (v >> 24) & 0xff;
2270 if (mdata->dysymtab)
2271 return -1;
2272 mdata->dysymtab = cmd;
2274 return 0;
2277 static int
2278 bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
2280 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2281 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2282 unsigned char buf[16];
2284 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2286 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2287 || bfd_bread ((void *) buf, 16, abfd) != 16)
2288 return -1;
2290 symtab->symoff = bfd_h_get_32 (abfd, buf);
2291 symtab->nsyms = bfd_h_get_32 (abfd, buf + 4);
2292 symtab->stroff = bfd_h_get_32 (abfd, buf + 8);
2293 symtab->strsize = bfd_h_get_32 (abfd, buf + 12);
2294 symtab->symbols = NULL;
2295 symtab->strtab = NULL;
2297 if (symtab->nsyms != 0)
2298 abfd->flags |= HAS_SYMS;
2300 if (mdata->symtab)
2301 return -1;
2302 mdata->symtab = symtab;
2303 return 0;
2306 static int
2307 bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
2309 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
2311 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2313 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2314 || bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
2315 return -1;
2317 return 0;
2320 static int
2321 bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
2323 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
2324 char buf[8];
2326 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2327 || bfd_bread ((void *) buf, 8, abfd) != 8)
2328 return -1;
2330 cmd->dataoff = bfd_get_32 (abfd, buf + 0);
2331 cmd->datasize = bfd_get_32 (abfd, buf + 4);
2332 return 0;
2335 static int
2336 bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
2338 bfd_mach_o_str_command *cmd = &command->command.str;
2339 char buf[4];
2340 unsigned long off;
2342 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2343 || bfd_bread ((void *) buf, 4, abfd) != 4)
2344 return -1;
2346 off = bfd_get_32 (abfd, buf + 0);
2347 cmd->stroff = command->offset + off;
2348 cmd->str_len = command->len - off;
2349 cmd->str = bfd_alloc (abfd, cmd->str_len);
2350 if (cmd->str == NULL)
2351 return -1;
2352 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
2353 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
2354 return -1;
2355 return 0;
2358 static int
2359 bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
2361 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
2362 char buf[40];
2364 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2365 || bfd_bread ((void *) buf, sizeof (buf), abfd) != sizeof (buf))
2366 return -1;
2368 cmd->rebase_off = bfd_get_32 (abfd, buf + 0);
2369 cmd->rebase_size = bfd_get_32 (abfd, buf + 4);
2370 cmd->bind_off = bfd_get_32 (abfd, buf + 8);
2371 cmd->bind_size = bfd_get_32 (abfd, buf + 12);
2372 cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16);
2373 cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20);
2374 cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24);
2375 cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28);
2376 cmd->export_off = bfd_get_32 (abfd, buf + 32);
2377 cmd->export_size = bfd_get_32 (abfd, buf + 36);
2378 return 0;
2381 static int
2382 bfd_mach_o_read_segment (bfd *abfd,
2383 bfd_mach_o_load_command *command,
2384 unsigned int wide)
2386 unsigned char buf[64];
2387 bfd_mach_o_segment_command *seg = &command->command.segment;
2388 unsigned long i;
2390 if (wide)
2392 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2394 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2395 || bfd_bread ((void *) buf, 64, abfd) != 64)
2396 return -1;
2398 memcpy (seg->segname, buf, 16);
2399 seg->segname[16] = '\0';
2401 seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
2402 seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
2403 seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
2404 seg->filesize = bfd_h_get_64 (abfd, buf + 40);
2405 seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
2406 seg->initprot = bfd_h_get_32 (abfd, buf + 52);
2407 seg->nsects = bfd_h_get_32 (abfd, buf + 56);
2408 seg->flags = bfd_h_get_32 (abfd, buf + 60);
2410 else
2412 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2414 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2415 || bfd_bread ((void *) buf, 48, abfd) != 48)
2416 return -1;
2418 memcpy (seg->segname, buf, 16);
2419 seg->segname[16] = '\0';
2421 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
2422 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
2423 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
2424 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
2425 seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
2426 seg->initprot = bfd_h_get_32 (abfd, buf + 36);
2427 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
2428 seg->flags = bfd_h_get_32 (abfd, buf + 44);
2431 if (seg->nsects != 0)
2433 seg->sections = bfd_alloc (abfd, seg->nsects
2434 * sizeof (bfd_mach_o_section));
2435 if (seg->sections == NULL)
2436 return -1;
2438 for (i = 0; i < seg->nsects; i++)
2440 bfd_vma segoff;
2441 if (wide)
2442 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2443 + (i * BFD_MACH_O_SECTION_64_SIZE);
2444 else
2445 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2446 + (i * BFD_MACH_O_SECTION_SIZE);
2448 if (bfd_mach_o_read_section
2449 (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
2450 return -1;
2454 return 0;
2457 static int
2458 bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2460 return bfd_mach_o_read_segment (abfd, command, 0);
2463 static int
2464 bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2466 return bfd_mach_o_read_segment (abfd, command, 1);
2469 static int
2470 bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2472 unsigned char buf[8];
2474 /* Read command type and length. */
2475 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2476 || bfd_bread ((void *) buf, 8, abfd) != 8)
2477 return -1;
2479 command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
2480 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
2481 ? TRUE : FALSE);
2482 command->len = bfd_h_get_32 (abfd, buf + 4);
2484 switch (command->type)
2486 case BFD_MACH_O_LC_SEGMENT:
2487 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
2488 return -1;
2489 break;
2490 case BFD_MACH_O_LC_SEGMENT_64:
2491 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
2492 return -1;
2493 break;
2494 case BFD_MACH_O_LC_SYMTAB:
2495 if (bfd_mach_o_read_symtab (abfd, command) != 0)
2496 return -1;
2497 break;
2498 case BFD_MACH_O_LC_SYMSEG:
2499 break;
2500 case BFD_MACH_O_LC_THREAD:
2501 case BFD_MACH_O_LC_UNIXTHREAD:
2502 if (bfd_mach_o_read_thread (abfd, command) != 0)
2503 return -1;
2504 break;
2505 case BFD_MACH_O_LC_LOAD_DYLINKER:
2506 case BFD_MACH_O_LC_ID_DYLINKER:
2507 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
2508 return -1;
2509 break;
2510 case BFD_MACH_O_LC_LOAD_DYLIB:
2511 case BFD_MACH_O_LC_ID_DYLIB:
2512 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2513 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2514 if (bfd_mach_o_read_dylib (abfd, command) != 0)
2515 return -1;
2516 break;
2517 case BFD_MACH_O_LC_PREBOUND_DYLIB:
2518 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
2519 return -1;
2520 break;
2521 case BFD_MACH_O_LC_LOADFVMLIB:
2522 case BFD_MACH_O_LC_IDFVMLIB:
2523 case BFD_MACH_O_LC_IDENT:
2524 case BFD_MACH_O_LC_FVMFILE:
2525 case BFD_MACH_O_LC_PREPAGE:
2526 case BFD_MACH_O_LC_ROUTINES:
2527 break;
2528 case BFD_MACH_O_LC_SUB_FRAMEWORK:
2529 case BFD_MACH_O_LC_SUB_UMBRELLA:
2530 case BFD_MACH_O_LC_SUB_LIBRARY:
2531 case BFD_MACH_O_LC_SUB_CLIENT:
2532 case BFD_MACH_O_LC_RPATH:
2533 if (bfd_mach_o_read_str (abfd, command) != 0)
2534 return -1;
2535 break;
2536 case BFD_MACH_O_LC_DYSYMTAB:
2537 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
2538 return -1;
2539 break;
2540 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2541 case BFD_MACH_O_LC_PREBIND_CKSUM:
2542 break;
2543 case BFD_MACH_O_LC_UUID:
2544 if (bfd_mach_o_read_uuid (abfd, command) != 0)
2545 return -1;
2546 break;
2547 case BFD_MACH_O_LC_CODE_SIGNATURE:
2548 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2549 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
2550 return -1;
2551 break;
2552 case BFD_MACH_O_LC_DYLD_INFO:
2553 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
2554 return -1;
2555 break;
2556 default:
2557 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
2558 (unsigned long) command->type);
2559 break;
2562 return 0;
2565 static void
2566 bfd_mach_o_flatten_sections (bfd *abfd)
2568 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2569 long csect = 0;
2570 unsigned long i, j;
2572 /* Count total number of sections. */
2573 mdata->nsects = 0;
2575 for (i = 0; i < mdata->header.ncmds; i++)
2577 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2578 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2580 bfd_mach_o_segment_command *seg;
2582 seg = &mdata->commands[i].command.segment;
2583 mdata->nsects += seg->nsects;
2587 /* Allocate sections array. */
2588 mdata->sections = bfd_alloc (abfd,
2589 mdata->nsects * sizeof (bfd_mach_o_section *));
2591 /* Fill the array. */
2592 csect = 0;
2594 for (i = 0; i < mdata->header.ncmds; i++)
2596 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2597 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2599 bfd_mach_o_segment_command *seg;
2601 seg = &mdata->commands[i].command.segment;
2602 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2604 for (j = 0; j < seg->nsects; j++)
2605 mdata->sections[csect++] = &seg->sections[j];
2611 bfd_mach_o_scan_start_address (bfd *abfd)
2613 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2614 bfd_mach_o_thread_command *cmd = NULL;
2615 unsigned long i;
2617 for (i = 0; i < mdata->header.ncmds; i++)
2619 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2620 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2622 if (cmd == NULL)
2623 cmd = &mdata->commands[i].command.thread;
2624 else
2625 return 0;
2629 if (cmd == NULL)
2630 return 0;
2632 for (i = 0; i < cmd->nflavours; i++)
2634 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2635 && (cmd->flavours[i].flavour
2636 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2638 unsigned char buf[4];
2640 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2641 || bfd_bread (buf, 4, abfd) != 4)
2642 return -1;
2644 abfd->start_address = bfd_h_get_32 (abfd, buf);
2646 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2647 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2649 unsigned char buf[4];
2651 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2652 || bfd_bread (buf, 4, abfd) != 4)
2653 return -1;
2655 abfd->start_address = bfd_h_get_32 (abfd, buf);
2657 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2658 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
2660 unsigned char buf[8];
2662 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2663 || bfd_bread (buf, 8, abfd) != 8)
2664 return -1;
2666 abfd->start_address = bfd_h_get_64 (abfd, buf);
2668 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2669 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2671 unsigned char buf[8];
2673 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2674 || bfd_bread (buf, 8, abfd) != 8)
2675 return -1;
2677 abfd->start_address = bfd_h_get_64 (abfd, buf);
2681 return 0;
2684 bfd_boolean
2685 bfd_mach_o_set_arch_mach (bfd *abfd,
2686 enum bfd_architecture arch,
2687 unsigned long machine)
2689 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
2691 /* If this isn't the right architecture for this backend, and this
2692 isn't the generic backend, fail. */
2693 if (arch != bed->arch
2694 && arch != bfd_arch_unknown
2695 && bed->arch != bfd_arch_unknown)
2696 return FALSE;
2698 return bfd_default_set_arch_mach (abfd, arch, machine);
2702 bfd_mach_o_scan (bfd *abfd,
2703 bfd_mach_o_header *header,
2704 bfd_mach_o_data_struct *mdata)
2706 unsigned int i;
2707 enum bfd_architecture cputype;
2708 unsigned long cpusubtype;
2709 unsigned int hdrsize;
2711 hdrsize = mach_o_wide_p (header) ?
2712 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2714 mdata->header = *header;
2716 abfd->flags = abfd->flags & BFD_IN_MEMORY;
2717 switch (header->filetype)
2719 case BFD_MACH_O_MH_OBJECT:
2720 abfd->flags |= HAS_RELOC;
2721 break;
2722 case BFD_MACH_O_MH_EXECUTE:
2723 abfd->flags |= EXEC_P;
2724 break;
2725 case BFD_MACH_O_MH_DYLIB:
2726 case BFD_MACH_O_MH_BUNDLE:
2727 abfd->flags |= DYNAMIC;
2728 break;
2731 abfd->tdata.mach_o_data = mdata;
2733 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2734 &cputype, &cpusubtype);
2735 if (cputype == bfd_arch_unknown)
2737 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
2738 header->cputype, header->cpusubtype);
2739 return -1;
2742 bfd_set_arch_mach (abfd, cputype, cpusubtype);
2744 if (header->ncmds != 0)
2746 mdata->commands = bfd_alloc
2747 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2748 if (mdata->commands == NULL)
2749 return -1;
2751 for (i = 0; i < header->ncmds; i++)
2753 bfd_mach_o_load_command *cur = &mdata->commands[i];
2755 if (i == 0)
2756 cur->offset = hdrsize;
2757 else
2759 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2760 cur->offset = prev->offset + prev->len;
2763 if (bfd_mach_o_read_command (abfd, cur) < 0)
2764 return -1;
2768 if (bfd_mach_o_scan_start_address (abfd) < 0)
2769 return -1;
2771 bfd_mach_o_flatten_sections (abfd);
2772 return 0;
2775 bfd_boolean
2776 bfd_mach_o_mkobject_init (bfd *abfd)
2778 bfd_mach_o_data_struct *mdata = NULL;
2780 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2781 if (mdata == NULL)
2782 return FALSE;
2783 abfd->tdata.mach_o_data = mdata;
2785 mdata->header.magic = 0;
2786 mdata->header.cputype = 0;
2787 mdata->header.cpusubtype = 0;
2788 mdata->header.filetype = 0;
2789 mdata->header.ncmds = 0;
2790 mdata->header.sizeofcmds = 0;
2791 mdata->header.flags = 0;
2792 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2793 mdata->commands = NULL;
2794 mdata->nsects = 0;
2795 mdata->sections = NULL;
2797 return TRUE;
2800 static bfd_boolean
2801 bfd_mach_o_gen_mkobject (bfd *abfd)
2803 bfd_mach_o_data_struct *mdata;
2805 if (!bfd_mach_o_mkobject_init (abfd))
2806 return FALSE;
2808 mdata = bfd_mach_o_get_data (abfd);
2809 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
2810 mdata->header.cputype = 0;
2811 mdata->header.cpusubtype = 0;
2812 mdata->header.byteorder = abfd->xvec->byteorder;
2813 mdata->header.version = 1;
2815 return TRUE;
2818 const bfd_target *
2819 bfd_mach_o_header_p (bfd *abfd,
2820 bfd_mach_o_filetype filetype,
2821 bfd_mach_o_cpu_type cputype)
2823 struct bfd_preserve preserve;
2824 bfd_mach_o_header header;
2826 preserve.marker = NULL;
2827 if (!bfd_mach_o_read_header (abfd, &header))
2828 goto wrong;
2830 if (! (header.byteorder == BFD_ENDIAN_BIG
2831 || header.byteorder == BFD_ENDIAN_LITTLE))
2833 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
2834 (unsigned long) header.byteorder);
2835 goto wrong;
2838 if (! ((header.byteorder == BFD_ENDIAN_BIG
2839 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2840 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2841 || (header.byteorder == BFD_ENDIAN_LITTLE
2842 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2843 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2844 goto wrong;
2846 /* Check cputype and filetype.
2847 In case of wildcard, do not accept magics that are handled by existing
2848 targets. */
2849 if (cputype)
2851 if (header.cputype != cputype)
2852 goto wrong;
2854 else
2856 switch (header.cputype)
2858 case BFD_MACH_O_CPU_TYPE_I386:
2859 /* Handled by mach-o-i386 */
2860 goto wrong;
2861 default:
2862 break;
2865 if (filetype)
2867 if (header.filetype != filetype)
2868 goto wrong;
2870 else
2872 switch (header.filetype)
2874 case BFD_MACH_O_MH_CORE:
2875 /* Handled by core_p */
2876 goto wrong;
2877 default:
2878 break;
2882 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2883 if (preserve.marker == NULL
2884 || !bfd_preserve_save (abfd, &preserve))
2885 goto fail;
2887 if (bfd_mach_o_scan (abfd, &header,
2888 (bfd_mach_o_data_struct *) preserve.marker) != 0)
2889 goto wrong;
2891 bfd_preserve_finish (abfd, &preserve);
2892 return abfd->xvec;
2894 wrong:
2895 bfd_set_error (bfd_error_wrong_format);
2897 fail:
2898 if (preserve.marker != NULL)
2899 bfd_preserve_restore (abfd, &preserve);
2900 return NULL;
2903 static const bfd_target *
2904 bfd_mach_o_gen_object_p (bfd *abfd)
2906 return bfd_mach_o_header_p (abfd, 0, 0);
2909 static const bfd_target *
2910 bfd_mach_o_gen_core_p (bfd *abfd)
2912 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
2915 typedef struct mach_o_fat_archentry
2917 unsigned long cputype;
2918 unsigned long cpusubtype;
2919 unsigned long offset;
2920 unsigned long size;
2921 unsigned long align;
2922 } mach_o_fat_archentry;
2924 typedef struct mach_o_fat_data_struct
2926 unsigned long magic;
2927 unsigned long nfat_arch;
2928 mach_o_fat_archentry *archentries;
2929 } mach_o_fat_data_struct;
2931 const bfd_target *
2932 bfd_mach_o_archive_p (bfd *abfd)
2934 mach_o_fat_data_struct *adata = NULL;
2935 unsigned char buf[20];
2936 unsigned long i;
2938 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2939 || bfd_bread ((void *) buf, 8, abfd) != 8)
2940 goto error;
2942 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
2943 if (adata == NULL)
2944 goto error;
2946 adata->magic = bfd_getb32 (buf);
2947 adata->nfat_arch = bfd_getb32 (buf + 4);
2948 if (adata->magic != 0xcafebabe)
2949 goto error;
2950 /* Avoid matching Java bytecode files, which have the same magic number.
2951 In the Java bytecode file format this field contains the JVM version,
2952 which starts at 43.0. */
2953 if (adata->nfat_arch > 30)
2954 goto error;
2956 adata->archentries =
2957 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2958 if (adata->archentries == NULL)
2959 goto error;
2961 for (i = 0; i < adata->nfat_arch; i++)
2963 if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
2964 || bfd_bread ((void *) buf, 20, abfd) != 20)
2965 goto error;
2966 adata->archentries[i].cputype = bfd_getb32 (buf);
2967 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
2968 adata->archentries[i].offset = bfd_getb32 (buf + 8);
2969 adata->archentries[i].size = bfd_getb32 (buf + 12);
2970 adata->archentries[i].align = bfd_getb32 (buf + 16);
2973 abfd->tdata.mach_o_fat_data = adata;
2974 return abfd->xvec;
2976 error:
2977 if (adata != NULL)
2978 bfd_release (abfd, adata);
2979 bfd_set_error (bfd_error_wrong_format);
2980 return NULL;
2983 bfd *
2984 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
2986 mach_o_fat_data_struct *adata;
2987 mach_o_fat_archentry *entry = NULL;
2988 unsigned long i;
2989 bfd *nbfd;
2990 enum bfd_architecture arch_type;
2991 unsigned long arch_subtype;
2993 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
2994 BFD_ASSERT (adata != NULL);
2996 /* Find index of previous entry. */
2997 if (prev == NULL)
2998 i = 0; /* Start at first one. */
2999 else
3001 for (i = 0; i < adata->nfat_arch; i++)
3003 if (adata->archentries[i].offset == prev->origin)
3004 break;
3007 if (i == adata->nfat_arch)
3009 /* Not found. */
3010 bfd_set_error (bfd_error_bad_value);
3011 return NULL;
3013 i++; /* Get next entry. */
3016 if (i >= adata->nfat_arch)
3018 bfd_set_error (bfd_error_no_more_archived_files);
3019 return NULL;
3022 entry = &adata->archentries[i];
3023 nbfd = _bfd_new_bfd_contained_in (archive);
3024 if (nbfd == NULL)
3025 return NULL;
3027 nbfd->origin = entry->offset;
3029 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3030 &arch_type, &arch_subtype);
3031 /* Create the member filename.
3032 Use FILENAME:ARCH_NAME. */
3034 char *s = NULL;
3035 const char *arch_name;
3036 size_t arch_file_len = strlen (bfd_get_filename (archive));
3038 arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
3039 s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
3040 if (s == NULL)
3041 return NULL;
3042 memcpy (s, bfd_get_filename (archive), arch_file_len);
3043 s[arch_file_len] = ':';
3044 strcpy (s + arch_file_len + 1, arch_name);
3045 nbfd->filename = s;
3047 nbfd->iostream = NULL;
3048 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3050 return nbfd;
3053 /* If ABFD format is FORMAT and architecture is ARCH, return it.
3054 If ABFD is a fat image containing a member that corresponds to FORMAT
3055 and ARCH, returns it.
3056 In other case, returns NULL.
3057 This function allows transparent uses of fat images. */
3058 bfd *
3059 bfd_mach_o_fat_extract (bfd *abfd,
3060 bfd_format format,
3061 const bfd_arch_info_type *arch)
3063 bfd *res;
3064 mach_o_fat_data_struct *adata;
3065 unsigned int i;
3067 if (bfd_check_format (abfd, format))
3069 if (bfd_get_arch_info (abfd) == arch)
3070 return abfd;
3071 return NULL;
3073 if (!bfd_check_format (abfd, bfd_archive)
3074 || abfd->xvec != &mach_o_fat_vec)
3075 return NULL;
3077 /* This is a Mach-O fat image. */
3078 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3079 BFD_ASSERT (adata != NULL);
3081 for (i = 0; i < adata->nfat_arch; i++)
3083 struct mach_o_fat_archentry *e = &adata->archentries[i];
3084 enum bfd_architecture cpu_type;
3085 unsigned long cpu_subtype;
3087 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3088 &cpu_type, &cpu_subtype);
3089 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3090 continue;
3092 /* The architecture is found. */
3093 res = _bfd_new_bfd_contained_in (abfd);
3094 if (res == NULL)
3095 return NULL;
3097 res->origin = e->offset;
3099 res->filename = strdup (abfd->filename);
3100 res->iostream = NULL;
3102 if (bfd_check_format (res, format))
3104 BFD_ASSERT (bfd_get_arch_info (res) == arch);
3105 return res;
3107 bfd_close (res);
3108 return NULL;
3111 return NULL;
3115 bfd_mach_o_lookup_section (bfd *abfd,
3116 asection *section,
3117 bfd_mach_o_load_command **mcommand,
3118 bfd_mach_o_section **msection)
3120 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3121 unsigned int i, j, num;
3123 bfd_mach_o_load_command *ncmd = NULL;
3124 bfd_mach_o_section *nsect = NULL;
3126 BFD_ASSERT (mcommand != NULL);
3127 BFD_ASSERT (msection != NULL);
3129 num = 0;
3130 for (i = 0; i < md->header.ncmds; i++)
3132 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3133 struct bfd_mach_o_segment_command *seg = NULL;
3135 if (cmd->type != BFD_MACH_O_LC_SEGMENT
3136 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
3137 continue;
3138 seg = &cmd->command.segment;
3140 for (j = 0; j < seg->nsects; j++)
3142 struct bfd_mach_o_section *sect = &seg->sections[j];
3144 if (sect->bfdsection == section)
3146 if (num == 0)
3148 nsect = sect;
3149 ncmd = cmd;
3151 num++;
3156 *mcommand = ncmd;
3157 *msection = nsect;
3158 return num;
3162 bfd_mach_o_lookup_command (bfd *abfd,
3163 bfd_mach_o_load_command_type type,
3164 bfd_mach_o_load_command **mcommand)
3166 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3167 bfd_mach_o_load_command *ncmd = NULL;
3168 unsigned int i, num;
3170 BFD_ASSERT (md != NULL);
3171 BFD_ASSERT (mcommand != NULL);
3173 num = 0;
3174 for (i = 0; i < md->header.ncmds; i++)
3176 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3178 if (cmd->type != type)
3179 continue;
3181 if (num == 0)
3182 ncmd = cmd;
3183 num++;
3186 *mcommand = ncmd;
3187 return num;
3190 unsigned long
3191 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3193 switch (type)
3195 case BFD_MACH_O_CPU_TYPE_MC680x0:
3196 return 0x04000000;
3197 case BFD_MACH_O_CPU_TYPE_MC88000:
3198 return 0xffffe000;
3199 case BFD_MACH_O_CPU_TYPE_POWERPC:
3200 return 0xc0000000;
3201 case BFD_MACH_O_CPU_TYPE_I386:
3202 return 0xc0000000;
3203 case BFD_MACH_O_CPU_TYPE_SPARC:
3204 return 0xf0000000;
3205 case BFD_MACH_O_CPU_TYPE_I860:
3206 return 0;
3207 case BFD_MACH_O_CPU_TYPE_HPPA:
3208 return 0xc0000000 - 0x04000000;
3209 default:
3210 return 0;
3214 typedef struct bfd_mach_o_xlat_name
3216 const char *name;
3217 unsigned long val;
3219 bfd_mach_o_xlat_name;
3221 static void
3222 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
3223 unsigned long val,
3224 FILE *file)
3226 int first = 1;
3228 for (; table->name; table++)
3230 if (table->val & val)
3232 if (!first)
3233 fprintf (file, "+");
3234 fprintf (file, "%s", table->name);
3235 val &= ~table->val;
3236 first = 0;
3239 if (val)
3241 if (!first)
3242 fprintf (file, "+");
3243 fprintf (file, "0x%lx", val);
3244 return;
3246 if (first)
3247 fprintf (file, "-");
3250 static const char *
3251 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
3253 for (; table->name; table++)
3254 if (table->val == val)
3255 return table->name;
3256 return "*UNKNOWN*";
3259 static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
3261 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
3262 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
3263 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
3264 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
3265 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
3266 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
3267 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
3268 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
3269 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
3270 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
3271 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
3272 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
3273 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
3274 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
3275 { NULL, 0}
3278 static bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
3280 { "object", BFD_MACH_O_MH_OBJECT },
3281 { "execute", BFD_MACH_O_MH_EXECUTE },
3282 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
3283 { "core", BFD_MACH_O_MH_CORE },
3284 { "preload", BFD_MACH_O_MH_PRELOAD },
3285 { "dylib", BFD_MACH_O_MH_DYLIB },
3286 { "dylinker", BFD_MACH_O_MH_DYLINKER },
3287 { "bundle", BFD_MACH_O_MH_BUNDLE },
3288 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
3289 { "dym", BFD_MACH_O_MH_DSYM },
3290 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
3291 { NULL, 0}
3294 static bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
3296 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
3297 { "incrlink", BFD_MACH_O_MH_INCRLINK },
3298 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
3299 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
3300 { "prebound", BFD_MACH_O_MH_PREBOUND },
3301 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
3302 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
3303 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
3304 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
3305 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
3306 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
3307 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
3308 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
3309 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
3310 { "canonical", BFD_MACH_O_MH_CANONICAL },
3311 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
3312 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
3313 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
3314 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
3315 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
3316 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
3317 { "pie", BFD_MACH_O_MH_PIE },
3318 { NULL, 0}
3321 static bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
3323 { "regular", BFD_MACH_O_S_REGULAR},
3324 { "zerofill", BFD_MACH_O_S_ZEROFILL},
3325 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3326 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3327 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3328 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3329 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3330 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3331 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3332 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3333 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3334 { "coalesced", BFD_MACH_O_S_COALESCED},
3335 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3336 { "interposing", BFD_MACH_O_S_INTERPOSING},
3337 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3338 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
3339 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3340 { NULL, 0}
3343 static bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
3345 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3346 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3347 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3348 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3349 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3350 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3351 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3352 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3353 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3354 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
3355 { NULL, 0}
3358 static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
3360 { "segment", BFD_MACH_O_LC_SEGMENT},
3361 { "symtab", BFD_MACH_O_LC_SYMTAB},
3362 { "symseg", BFD_MACH_O_LC_SYMSEG},
3363 { "thread", BFD_MACH_O_LC_THREAD},
3364 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
3365 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
3366 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
3367 { "ident", BFD_MACH_O_LC_IDENT},
3368 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
3369 { "prepage", BFD_MACH_O_LC_PREPAGE},
3370 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
3371 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
3372 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
3373 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
3374 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
3375 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
3376 { "routines", BFD_MACH_O_LC_ROUTINES},
3377 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
3378 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
3379 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
3380 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
3381 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
3382 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
3383 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
3384 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
3385 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
3386 { "uuid", BFD_MACH_O_LC_UUID},
3387 { "rpath", BFD_MACH_O_LC_RPATH},
3388 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
3389 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
3390 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
3391 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
3392 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
3393 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
3394 { NULL, 0}
3397 static void
3398 bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
3400 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3401 bfd_mach_o_header *h = &mdata->header;
3403 fputs (_("Mach-O header:\n"), file);
3404 fprintf (file, _(" magic : %08lx\n"), h->magic);
3405 fprintf (file, _(" cputype : %08lx (%s)\n"), h->cputype,
3406 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
3407 fprintf (file, _(" cpusubtype: %08lx\n"), h->cpusubtype);
3408 fprintf (file, _(" filetype : %08lx (%s)\n"),
3409 h->filetype,
3410 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
3411 fprintf (file, _(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
3412 fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds);
3413 fprintf (file, _(" flags : %08lx ("), h->flags);
3414 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file);
3415 fputs (_(")\n"), file);
3416 fprintf (file, _(" reserved : %08x\n"), h->reserved);
3419 static void
3420 bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
3422 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3423 unsigned int i, j;
3424 unsigned int sec_nbr = 0;
3426 fputs (_("Segments and Sections:\n"), file);
3427 fputs (_(" #: Segment name Section name Address\n"), file);
3429 for (i = 0; i < mdata->header.ncmds; i++)
3431 bfd_mach_o_segment_command *seg;
3433 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
3434 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
3435 continue;
3437 seg = &mdata->commands[i].command.segment;
3439 fprintf (file, "[Segment %-16s ", seg->segname);
3440 fprintf_vma (file, seg->vmaddr);
3441 fprintf (file, "-");
3442 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
3443 fputc (' ', file);
3444 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
3445 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
3446 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
3447 fprintf (file, "]\n");
3448 for (j = 0; j < seg->nsects; j++)
3450 bfd_mach_o_section *sec = &seg->sections[j];
3451 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
3452 sec->segname, sec->sectname);
3453 fprintf_vma (file, sec->addr);
3454 fprintf (file, " ");
3455 fprintf_vma (file, sec->size);
3456 fprintf (file, " %08lx\n", sec->flags);
3461 static void
3462 bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED,
3463 bfd_mach_o_section *sec, FILE *file)
3465 fprintf (file, " Section: %-16s %-16s (bfdname: %s)\n",
3466 sec->sectname, sec->segname, sec->bfdsection->name);
3467 fprintf (file, " addr: ");
3468 fprintf_vma (file, sec->addr);
3469 fprintf (file, " size: ");
3470 fprintf_vma (file, sec->size);
3471 fprintf (file, " offset: ");
3472 fprintf_vma (file, sec->offset);
3473 fprintf (file, "\n");
3474 fprintf (file, " align: %ld", sec->align);
3475 fprintf (file, " nreloc: %lu reloff: ", sec->nreloc);
3476 fprintf_vma (file, sec->reloff);
3477 fprintf (file, "\n");
3478 fprintf (file, " flags: %08lx (type: %s", sec->flags,
3479 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
3480 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
3481 fprintf (file, " attr: ");
3482 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
3483 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
3484 file);
3485 fprintf (file, ")\n");
3486 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3488 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3489 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3490 case BFD_MACH_O_S_SYMBOL_STUBS:
3491 fprintf (file, " first indirect sym: %lu", sec->reserved1);
3492 fprintf (file, " (%u entries)",
3493 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
3494 break;
3495 default:
3496 fprintf (file, " reserved1: 0x%lx", sec->reserved1);
3497 break;
3499 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3501 case BFD_MACH_O_S_SYMBOL_STUBS:
3502 fprintf (file, " stub size: %lu", sec->reserved2);
3503 break;
3504 default:
3505 fprintf (file, " reserved2: 0x%lx", sec->reserved2);
3506 break;
3508 fprintf (file, " reserved3: 0x%lx\n", sec->reserved3);
3511 static void
3512 bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
3513 bfd_mach_o_load_command *cmd, FILE *file)
3515 bfd_mach_o_segment_command *seg = &cmd->command.segment;
3516 unsigned int i;
3518 fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
3519 fprintf (file, " vmaddr: ");
3520 fprintf_vma (file, seg->vmaddr);
3521 fprintf (file, " vmsize: ");
3522 fprintf_vma (file, seg->vmsize);
3523 fprintf (file, "\n");
3524 fprintf (file, " fileoff: ");
3525 fprintf_vma (file, seg->fileoff);
3526 fprintf (file, " filesize: ");
3527 fprintf_vma (file, (bfd_vma)seg->filesize);
3528 fprintf (file, " endoff: ");
3529 fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
3530 fprintf (file, "\n");
3531 fprintf (file, " nsects: %lu ", seg->nsects);
3532 fprintf (file, " flags: %lx\n", seg->flags);
3533 for (i = 0; i < seg->nsects; i++)
3534 bfd_mach_o_print_section (abfd, &seg->sections[i], file);
3537 static void
3538 bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
3539 bfd_mach_o_load_command *cmd, FILE *file)
3541 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
3542 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3543 unsigned int i;
3545 fprintf (file, " local symbols: idx: %10lu num: %-8lu",
3546 dysymtab->ilocalsym, dysymtab->nlocalsym);
3547 fprintf (file, " (nxtidx: %lu)\n",
3548 dysymtab->ilocalsym + dysymtab->nlocalsym);
3549 fprintf (file, " external symbols: idx: %10lu num: %-8lu",
3550 dysymtab->iextdefsym, dysymtab->nextdefsym);
3551 fprintf (file, " (nxtidx: %lu)\n",
3552 dysymtab->iextdefsym + dysymtab->nextdefsym);
3553 fprintf (file, " undefined symbols: idx: %10lu num: %-8lu",
3554 dysymtab->iundefsym, dysymtab->nundefsym);
3555 fprintf (file, " (nxtidx: %lu)\n",
3556 dysymtab->iundefsym + dysymtab->nundefsym);
3557 fprintf (file, " table of content: off: 0x%08lx num: %-8lu",
3558 dysymtab->tocoff, dysymtab->ntoc);
3559 fprintf (file, " (endoff: 0x%08lx)\n",
3560 dysymtab->tocoff
3561 + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
3562 fprintf (file, " module table: off: 0x%08lx num: %-8lu",
3563 dysymtab->modtaboff, dysymtab->nmodtab);
3564 fprintf (file, " (endoff: 0x%08lx)\n",
3565 dysymtab->modtaboff + dysymtab->nmodtab
3566 * (mach_o_wide_p (&mdata->header) ?
3567 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
3568 fprintf (file, " external reference table: off: 0x%08lx num: %-8lu",
3569 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
3570 fprintf (file, " (endoff: 0x%08lx)\n",
3571 dysymtab->extrefsymoff
3572 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
3573 fprintf (file, " indirect symbol table: off: 0x%08lx num: %-8lu",
3574 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
3575 fprintf (file, " (endoff: 0x%08lx)\n",
3576 dysymtab->indirectsymoff
3577 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
3578 fprintf (file, " external relocation table: off: 0x%08lx num: %-8lu",
3579 dysymtab->extreloff, dysymtab->nextrel);
3580 fprintf (file, " (endoff: 0x%08lx)\n",
3581 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
3582 fprintf (file, " local relocation table: off: 0x%08lx num: %-8lu",
3583 dysymtab->locreloff, dysymtab->nlocrel);
3584 fprintf (file, " (endoff: 0x%08lx)\n",
3585 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
3587 if (dysymtab->ntoc > 0
3588 || dysymtab->nindirectsyms > 0
3589 || dysymtab->nextrefsyms > 0)
3591 /* Try to read the symbols to display the toc or indirect symbols. */
3592 bfd_mach_o_read_symtab_symbols (abfd);
3594 else if (dysymtab->nmodtab > 0)
3596 /* Try to read the strtab to display modules name. */
3597 bfd_mach_o_read_symtab_strtab (abfd);
3600 for (i = 0; i < dysymtab->nmodtab; i++)
3602 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
3603 fprintf (file, " module %u:\n", i);
3604 fprintf (file, " name: %lu", module->module_name_idx);
3605 if (mdata->symtab && mdata->symtab->strtab)
3606 fprintf (file, ": %s",
3607 mdata->symtab->strtab + module->module_name_idx);
3608 fprintf (file, "\n");
3609 fprintf (file, " extdefsym: idx: %8lu num: %lu\n",
3610 module->iextdefsym, module->nextdefsym);
3611 fprintf (file, " refsym: idx: %8lu num: %lu\n",
3612 module->irefsym, module->nrefsym);
3613 fprintf (file, " localsym: idx: %8lu num: %lu\n",
3614 module->ilocalsym, module->nlocalsym);
3615 fprintf (file, " extrel: idx: %8lu num: %lu\n",
3616 module->iextrel, module->nextrel);
3617 fprintf (file, " init: idx: %8u num: %u\n",
3618 module->iinit, module->ninit);
3619 fprintf (file, " term: idx: %8u num: %u\n",
3620 module->iterm, module->nterm);
3621 fprintf (file, " objc_module_info: addr: ");
3622 fprintf_vma (file, module->objc_module_info_addr);
3623 fprintf (file, " size: %lu\n", module->objc_module_info_size);
3626 if (dysymtab->ntoc > 0)
3628 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3630 fprintf (file, " table of content: (symbol/module)\n");
3631 for (i = 0; i < dysymtab->ntoc; i++)
3633 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
3635 fprintf (file, " %4u: ", i);
3636 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
3638 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
3639 fprintf (file, "%s (%lu)", name ? name : "*invalid*",
3640 toc->symbol_index);
3642 else
3643 fprintf (file, "%lu", toc->symbol_index);
3645 fprintf (file, " / ");
3646 if (symtab && symtab->strtab
3647 && toc->module_index < dysymtab->nmodtab)
3649 bfd_mach_o_dylib_module *mod;
3650 mod = &dysymtab->dylib_module[toc->module_index];
3651 fprintf (file, "%s (%lu)",
3652 symtab->strtab + mod->module_name_idx,
3653 toc->module_index);
3655 else
3656 fprintf (file, "%lu", toc->module_index);
3658 fprintf (file, "\n");
3662 if (dysymtab->nindirectsyms != 0)
3664 fprintf (file, " indirect symbols:\n");
3666 for (i = 0; i < mdata->nsects; i++)
3668 bfd_mach_o_section *sec = mdata->sections[i];
3669 unsigned int j, first, last;
3670 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3671 bfd_vma addr;
3672 bfd_vma entry_size;
3674 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3676 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3677 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3678 case BFD_MACH_O_S_SYMBOL_STUBS:
3679 first = sec->reserved1;
3680 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
3681 addr = sec->addr;
3682 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
3683 fprintf (file, " for section %s.%s:\n",
3684 sec->segname, sec->sectname);
3685 for (j = first; j < last; j++)
3687 unsigned int isym = dysymtab->indirect_syms[j];
3689 fprintf (file, " ");
3690 fprintf_vma (file, addr);
3691 fprintf (file, " %5u: 0x%08x", j, isym);
3692 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
3693 fprintf (file, " LOCAL");
3694 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
3695 fprintf (file, " ABSOLUTE");
3696 if (symtab && symtab->symbols
3697 && isym < symtab->nsyms
3698 && symtab->symbols[isym].symbol.name)
3699 fprintf (file, " %s", symtab->symbols[isym].symbol.name);
3700 fprintf (file, "\n");
3701 addr += entry_size;
3703 break;
3704 default:
3705 break;
3709 if (dysymtab->nextrefsyms > 0)
3711 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3713 fprintf (file, " external reference table: (symbol flags)\n");
3714 for (i = 0; i < dysymtab->nextrefsyms; i++)
3716 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
3718 fprintf (file, " %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
3719 if (symtab && symtab->symbols
3720 && ref->isym < symtab->nsyms
3721 && symtab->symbols[ref->isym].symbol.name)
3722 fprintf (file, " %s", symtab->symbols[ref->isym].symbol.name);
3723 fprintf (file, "\n");
3729 static void
3730 bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED,
3731 bfd_mach_o_load_command *cmd, FILE *file)
3733 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
3735 fprintf (file, " rebase: off: 0x%08x size: %-8u\n",
3736 info->rebase_off, info->rebase_size);
3737 fprintf (file, " bind: off: 0x%08x size: %-8u\n",
3738 info->bind_off, info->bind_size);
3739 fprintf (file, " weak bind: off: 0x%08x size: %-8u\n",
3740 info->weak_bind_off, info->weak_bind_size);
3741 fprintf (file, " lazy bind: off: 0x%08x size: %-8u\n",
3742 info->lazy_bind_off, info->lazy_bind_size);
3743 fprintf (file, " export: off: 0x%08x size: %-8u\n",
3744 info->export_off, info->export_size);
3747 bfd_boolean
3748 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
3750 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3751 FILE *file = (FILE *) ptr;
3752 unsigned int i;
3754 bfd_mach_o_print_private_header (abfd, file);
3755 fputc ('\n', file);
3757 for (i = 0; i < mdata->header.ncmds; i++)
3759 bfd_mach_o_load_command *cmd = &mdata->commands[i];
3761 fprintf (file, "Load command %s:",
3762 bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
3763 switch (cmd->type)
3765 case BFD_MACH_O_LC_SEGMENT:
3766 case BFD_MACH_O_LC_SEGMENT_64:
3767 bfd_mach_o_print_segment (abfd, cmd, file);
3768 break;
3769 case BFD_MACH_O_LC_UUID:
3771 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
3772 unsigned int j;
3774 for (j = 0; j < sizeof (uuid->uuid); j ++)
3775 fprintf (file, " %02x", uuid->uuid[j]);
3776 fputc ('\n', file);
3778 break;
3779 case BFD_MACH_O_LC_LOAD_DYLIB:
3780 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
3781 case BFD_MACH_O_LC_REEXPORT_DYLIB:
3782 case BFD_MACH_O_LC_ID_DYLIB:
3784 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
3785 fprintf (file, " %s\n", dylib->name_str);
3786 fprintf (file, " time stamp: 0x%08lx\n",
3787 dylib->timestamp);
3788 fprintf (file, " current version: 0x%08lx\n",
3789 dylib->current_version);
3790 fprintf (file, " comptibility version: 0x%08lx\n",
3791 dylib->compatibility_version);
3792 break;
3794 case BFD_MACH_O_LC_LOAD_DYLINKER:
3795 case BFD_MACH_O_LC_ID_DYLINKER:
3796 fprintf (file, " %s\n", cmd->command.dylinker.name_str);
3797 break;
3798 case BFD_MACH_O_LC_SYMTAB:
3800 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
3801 fprintf (file,
3802 "\n"
3803 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
3804 symtab->symoff, symtab->nsyms,
3805 symtab->symoff + symtab->nsyms
3806 * (mach_o_wide_p (&mdata->header)
3807 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
3808 fprintf (file,
3809 " stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
3810 symtab->stroff, symtab->strsize,
3811 symtab->stroff + symtab->strsize);
3812 break;
3814 case BFD_MACH_O_LC_DYSYMTAB:
3815 fprintf (file, "\n");
3816 bfd_mach_o_print_dysymtab (abfd, cmd, file);
3817 break;
3818 case BFD_MACH_O_LC_CODE_SIGNATURE:
3819 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
3821 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
3822 fprintf
3823 (file, "\n"
3824 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
3825 linkedit->dataoff, linkedit->datasize,
3826 linkedit->dataoff + linkedit->datasize);
3827 break;
3829 case BFD_MACH_O_LC_SUB_FRAMEWORK:
3830 case BFD_MACH_O_LC_SUB_UMBRELLA:
3831 case BFD_MACH_O_LC_SUB_LIBRARY:
3832 case BFD_MACH_O_LC_SUB_CLIENT:
3833 case BFD_MACH_O_LC_RPATH:
3835 bfd_mach_o_str_command *str = &cmd->command.str;
3836 fprintf (file, " %s\n", str->str);
3837 break;
3839 case BFD_MACH_O_LC_THREAD:
3840 case BFD_MACH_O_LC_UNIXTHREAD:
3842 bfd_mach_o_thread_command *thread = &cmd->command.thread;
3843 unsigned int j;
3844 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
3846 fprintf (file, " nflavours: %lu\n", thread->nflavours);
3847 for (j = 0; j < thread->nflavours; j++)
3849 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
3851 fprintf (file, " %2u: flavour: 0x%08lx offset: 0x%08lx"
3852 " size: 0x%08lx\n",
3853 j, flavour->flavour, flavour->offset,
3854 flavour->size);
3855 if (bed->_bfd_mach_o_print_thread)
3857 char *buf = bfd_malloc (flavour->size);
3859 if (buf
3860 && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
3861 && (bfd_bread (buf, flavour->size, abfd)
3862 == flavour->size))
3863 (*bed->_bfd_mach_o_print_thread)(abfd, flavour,
3864 file, buf);
3865 free (buf);
3868 break;
3870 case BFD_MACH_O_LC_DYLD_INFO:
3871 fprintf (file, "\n");
3872 bfd_mach_o_print_dyld_info (abfd, cmd, file);
3873 break;
3874 default:
3875 fprintf (file, "\n");
3876 break;
3878 fputc ('\n', file);
3881 bfd_mach_o_print_section_map (abfd, file);
3883 return TRUE;
3887 bfd_mach_o_core_fetch_environment (bfd *abfd,
3888 unsigned char **rbuf,
3889 unsigned int *rlen)
3891 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3892 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
3893 unsigned int i = 0;
3895 for (i = 0; i < mdata->header.ncmds; i++)
3897 bfd_mach_o_load_command *cur = &mdata->commands[i];
3898 bfd_mach_o_segment_command *seg = NULL;
3900 if (cur->type != BFD_MACH_O_LC_SEGMENT)
3901 continue;
3903 seg = &cur->command.segment;
3905 if ((seg->vmaddr + seg->vmsize) == stackaddr)
3907 unsigned long start = seg->fileoff;
3908 unsigned long end = seg->fileoff + seg->filesize;
3909 unsigned char *buf = bfd_malloc (1024);
3910 unsigned long size = 1024;
3912 for (;;)
3914 bfd_size_type nread = 0;
3915 unsigned long offset;
3916 int found_nonnull = 0;
3918 if (size > (end - start))
3919 size = (end - start);
3921 buf = bfd_realloc_or_free (buf, size);
3922 if (buf == NULL)
3923 return -1;
3925 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
3927 free (buf);
3928 return -1;
3931 nread = bfd_bread (buf, size, abfd);
3933 if (nread != size)
3935 free (buf);
3936 return -1;
3939 for (offset = 4; offset <= size; offset += 4)
3941 unsigned long val;
3943 val = *((unsigned long *) (buf + size - offset));
3944 if (! found_nonnull)
3946 if (val != 0)
3947 found_nonnull = 1;
3949 else if (val == 0x0)
3951 unsigned long bottom;
3952 unsigned long top;
3954 bottom = seg->fileoff + seg->filesize - offset;
3955 top = seg->fileoff + seg->filesize - 4;
3956 *rbuf = bfd_malloc (top - bottom);
3957 *rlen = top - bottom;
3959 memcpy (*rbuf, buf + size - *rlen, *rlen);
3960 free (buf);
3961 return 0;
3965 if (size == (end - start))
3966 break;
3968 size *= 2;
3971 free (buf);
3975 return -1;
3978 char *
3979 bfd_mach_o_core_file_failing_command (bfd *abfd)
3981 unsigned char *buf = NULL;
3982 unsigned int len = 0;
3983 int ret = -1;
3985 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
3986 if (ret < 0)
3987 return NULL;
3989 return (char *) buf;
3993 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3995 return 0;
3998 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
3999 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4001 #define bfd_mach_o_swap_reloc_in NULL
4002 #define bfd_mach_o_swap_reloc_out NULL
4003 #define bfd_mach_o_print_thread NULL
4005 #define TARGET_NAME mach_o_be_vec
4006 #define TARGET_STRING "mach-o-be"
4007 #define TARGET_ARCHITECTURE bfd_arch_unknown
4008 #define TARGET_BIG_ENDIAN 1
4009 #define TARGET_ARCHIVE 0
4010 #include "mach-o-target.c"
4012 #undef TARGET_NAME
4013 #undef TARGET_STRING
4014 #undef TARGET_ARCHITECTURE
4015 #undef TARGET_BIG_ENDIAN
4016 #undef TARGET_ARCHIVE
4018 #define TARGET_NAME mach_o_le_vec
4019 #define TARGET_STRING "mach-o-le"
4020 #define TARGET_ARCHITECTURE bfd_arch_unknown
4021 #define TARGET_BIG_ENDIAN 0
4022 #define TARGET_ARCHIVE 0
4024 #include "mach-o-target.c"
4026 #undef TARGET_NAME
4027 #undef TARGET_STRING
4028 #undef TARGET_ARCHITECTURE
4029 #undef TARGET_BIG_ENDIAN
4030 #undef TARGET_ARCHIVE
4032 /* Not yet handled: creating an archive. */
4033 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4035 /* Not used. */
4036 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4037 #define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4038 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4039 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4040 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4041 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4042 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4043 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
4044 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
4045 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4047 #define TARGET_NAME mach_o_fat_vec
4048 #define TARGET_STRING "mach-o-fat"
4049 #define TARGET_ARCHITECTURE bfd_arch_unknown
4050 #define TARGET_BIG_ENDIAN 1
4051 #define TARGET_ARCHIVE 1
4053 #include "mach-o-target.c"
4055 #undef TARGET_NAME
4056 #undef TARGET_STRING
4057 #undef TARGET_ARCHITECTURE
4058 #undef TARGET_BIG_ENDIAN
4059 #undef TARGET_ARCHIVE