2009-06-18 Dave Korn <dave.korn.cygwin@gmail.com>
[binutils.git] / bfd / mach-o.c
blobd8e702ec73b787b44ffe3ec7bba06748a7913762
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "sysdep.h"
23 #include "mach-o.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "libiberty.h"
27 #include "aout/stab_gnu.h"
28 #include <ctype.h>
30 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p
31 #define bfd_mach_o_core_p bfd_mach_o_gen_core_p
32 #define bfd_mach_o_mkobject bfd_false
34 #define FILE_ALIGN(off, algn) \
35 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
37 unsigned int
38 bfd_mach_o_version (bfd *abfd)
40 bfd_mach_o_data_struct *mdata = NULL;
42 BFD_ASSERT (bfd_mach_o_valid (abfd));
43 mdata = abfd->tdata.mach_o_data;
45 return mdata->header.version;
48 bfd_boolean
49 bfd_mach_o_valid (bfd *abfd)
51 if (abfd == NULL || abfd->xvec == NULL)
52 return FALSE;
54 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
55 return FALSE;
57 if (abfd->tdata.mach_o_data == NULL)
58 return FALSE;
59 return TRUE;
62 static INLINE bfd_boolean
63 mach_o_wide_p (bfd_mach_o_header *header)
65 switch (header->version)
67 case 1:
68 return FALSE;
69 case 2:
70 return TRUE;
71 default:
72 BFD_FAIL ();
73 return FALSE;
77 static INLINE bfd_boolean
78 bfd_mach_o_wide_p (bfd *abfd)
80 return mach_o_wide_p (&abfd->tdata.mach_o_data->header);
83 /* Tables to translate well known Mach-O segment/section names to bfd
84 names. Use of canonical names (such as .text or .debug_frame) is required
85 by gdb. */
87 struct mach_o_section_name_xlat
89 const char *bfd_name;
90 const char *mach_o_name;
93 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
95 { ".debug_frame", "__debug_frame" },
96 { ".debug_info", "__debug_info" },
97 { ".debug_abbrev", "__debug_abbrev" },
98 { ".debug_aranges", "__debug_aranges" },
99 { ".debug_macinfo", "__debug_macinfo" },
100 { ".debug_line", "__debug_line" },
101 { ".debug_loc", "__debug_loc" },
102 { ".debug_pubnames", "__debug_pubnames" },
103 { ".debug_pubtypes", "__debug_pubtypes" },
104 { ".debug_str", "__debug_str" },
105 { ".debug_ranges", "__debug_ranges" },
106 { NULL, NULL}
109 static const struct mach_o_section_name_xlat text_section_names_xlat[] =
111 { ".text", "__text" },
112 { ".cstring", "__cstring" },
113 { ".eh_frame", "__eh_frame" },
114 { NULL, NULL}
117 static const struct mach_o_section_name_xlat data_section_names_xlat[] =
119 { ".data", "__data" },
120 { ".bss", "__bss" },
121 { NULL, NULL}
124 struct mach_o_segment_name_xlat
126 const char *segname;
127 const struct mach_o_section_name_xlat *sections;
130 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
132 { "__DWARF", dwarf_section_names_xlat },
133 { "__TEXT", text_section_names_xlat },
134 { "__DATA", data_section_names_xlat },
135 { NULL, NULL }
139 /* Mach-O to bfd names. */
141 static char *
142 bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section)
144 const struct mach_o_segment_name_xlat *seg;
145 char *res;
146 unsigned int len;
147 const char *pfx = "";
149 for (seg = segsec_names_xlat; seg->segname; seg++)
151 if (strcmp (seg->segname, section->segname) == 0)
153 const struct mach_o_section_name_xlat *sec;
155 for (sec = seg->sections; sec->mach_o_name; sec++)
157 if (strcmp (sec->mach_o_name, section->sectname) == 0)
159 len = strlen (sec->bfd_name);
160 res = bfd_alloc (abfd, len + 1);
162 if (res == NULL)
163 return NULL;
164 strcpy (res, sec->bfd_name);
165 return res;
171 len = strlen (section->segname) + 1
172 + strlen (section->sectname) + 1;
174 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
175 with an underscore. */
176 if (section->segname[0] != '_')
178 static const char seg_pfx[] = "LC_SEGMENT.";
180 pfx = seg_pfx;
181 len += sizeof (seg_pfx) - 1;
184 res = bfd_alloc (abfd, len);
185 if (res == NULL)
186 return NULL;
187 snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
188 return res;
191 /* Convert a bfd section name to a Mach-O segment + section name. */
193 static void
194 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
195 asection *sect,
196 bfd_mach_o_section *section)
198 const struct mach_o_segment_name_xlat *seg;
199 const char *name = bfd_get_section_name (abfd, sect);
200 const char *dot;
201 unsigned int len;
202 unsigned int seglen;
203 unsigned int seclen;
205 /* List of well known names. They all start with a dot. */
206 if (name[0] == '.')
207 for (seg = segsec_names_xlat; seg->segname; seg++)
209 const struct mach_o_section_name_xlat *sec;
211 for (sec = seg->sections; sec->mach_o_name; sec++)
213 if (strcmp (sec->bfd_name, name) == 0)
215 strcpy (section->segname, seg->segname);
216 strcpy (section->sectname, sec->mach_o_name);
217 return;
222 /* Strip LC_SEGMENT. prefix. */
223 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
224 name += 11;
226 /* Find a dot. */
227 dot = strchr (name, '.');
228 len = strlen (name);
230 /* Try to split name into segment and section names. */
231 if (dot && dot != name)
233 seglen = dot - name;
234 seclen = len - (dot + 1 - name);
236 if (seglen < 16 && seclen < 16)
238 memcpy (section->segname, name, seglen);
239 section->segname[seglen] = 0;
240 memcpy (section->sectname, dot + 1, seclen);
241 section->sectname[seclen] = 0;
242 return;
246 if (len > 16)
247 len = 16;
248 memcpy (section->segname, name, len);
249 section->segname[len] = 0;
250 memcpy (section->sectname, name, len);
251 section->sectname[len] = 0;
254 /* Copy any private info we understand from the input symbol
255 to the output symbol. */
257 bfd_boolean
258 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
259 asymbol *isymbol ATTRIBUTE_UNUSED,
260 bfd *obfd ATTRIBUTE_UNUSED,
261 asymbol *osymbol ATTRIBUTE_UNUSED)
263 return TRUE;
266 /* Copy any private info we understand from the input section
267 to the output section. */
269 bfd_boolean
270 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
271 asection *isection ATTRIBUTE_UNUSED,
272 bfd *obfd ATTRIBUTE_UNUSED,
273 asection *osection ATTRIBUTE_UNUSED)
275 return TRUE;
278 /* Copy any private info we understand from the input bfd
279 to the output bfd. */
281 bfd_boolean
282 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
284 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
285 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
286 return TRUE;
288 BFD_ASSERT (bfd_mach_o_valid (ibfd));
289 BFD_ASSERT (bfd_mach_o_valid (obfd));
291 /* FIXME: copy commands. */
293 return TRUE;
296 /* Count the total number of symbols. Traverse all sections. */
298 static long
299 bfd_mach_o_count_symbols (bfd *abfd)
301 bfd_mach_o_data_struct *mdata = NULL;
302 long nsyms = 0;
303 unsigned long i;
305 BFD_ASSERT (bfd_mach_o_valid (abfd));
306 mdata = abfd->tdata.mach_o_data;
308 for (i = 0; i < mdata->header.ncmds; i++)
309 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
311 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
312 nsyms += sym->nsyms;
315 return nsyms;
318 long
319 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
321 long nsyms = bfd_mach_o_count_symbols (abfd);
323 if (nsyms < 0)
324 return nsyms;
326 return ((nsyms + 1) * sizeof (asymbol *));
329 long
330 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
332 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
333 long nsyms = bfd_mach_o_count_symbols (abfd);
334 asymbol **csym = alocation;
335 unsigned long i, j;
337 if (nsyms < 0)
338 return nsyms;
340 for (i = 0; i < mdata->header.ncmds; i++)
342 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
344 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
346 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
348 fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
349 return 0;
352 BFD_ASSERT (sym->symbols != NULL);
354 for (j = 0; j < sym->nsyms; j++)
356 BFD_ASSERT (csym < (alocation + nsyms));
357 *csym++ = &sym->symbols[j].symbol;
362 *csym++ = NULL;
364 return nsyms;
367 void
368 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
369 asymbol *symbol,
370 symbol_info *ret)
372 bfd_symbol_info (symbol, ret);
375 void
376 bfd_mach_o_print_symbol (bfd *abfd,
377 PTR afile,
378 asymbol *symbol,
379 bfd_print_symbol_type how)
381 FILE *file = (FILE *) afile;
382 const char *name;
383 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
385 switch (how)
387 case bfd_print_symbol_name:
388 fprintf (file, "%s", symbol->name);
389 break;
390 default:
391 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
392 if (asym->n_type & BFD_MACH_O_N_STAB)
393 name = bfd_get_stab_name (asym->n_type);
394 else
395 switch (asym->n_type & BFD_MACH_O_N_TYPE)
397 case BFD_MACH_O_N_UNDF:
398 name = "UND";
399 break;
400 case BFD_MACH_O_N_ABS:
401 name = "ABS";
402 break;
403 case BFD_MACH_O_N_INDR:
404 name = "INDR";
405 break;
406 case BFD_MACH_O_N_PBUD:
407 name = "PBUD";
408 break;
409 case BFD_MACH_O_N_SECT:
410 name = "SECT";
411 break;
412 default:
413 name = "???";
414 break;
416 if (name == NULL)
417 name = "";
418 fprintf (file, " %02x %-6s %02x %04x",
419 asym->n_type, name, asym->n_sect, asym->n_desc);
420 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
421 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
422 fprintf (file, " %-5s", symbol->section->name);
423 fprintf (file, " %s", symbol->name);
427 static void
428 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
429 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
430 enum bfd_architecture *type,
431 unsigned long *subtype)
433 *subtype = bfd_arch_unknown;
435 switch (mtype)
437 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
438 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
439 case BFD_MACH_O_CPU_TYPE_I386:
440 *type = bfd_arch_i386;
441 *subtype = bfd_mach_i386_i386;
442 break;
443 case BFD_MACH_O_CPU_TYPE_X86_64:
444 *type = bfd_arch_i386;
445 *subtype = bfd_mach_x86_64;
446 break;
447 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
448 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
449 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
450 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
451 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
452 case BFD_MACH_O_CPU_TYPE_SPARC:
453 *type = bfd_arch_sparc;
454 *subtype = bfd_mach_sparc;
455 break;
456 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
457 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
458 case BFD_MACH_O_CPU_TYPE_POWERPC:
459 *type = bfd_arch_powerpc;
460 *subtype = bfd_mach_ppc;
461 break;
462 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
463 *type = bfd_arch_powerpc;
464 *subtype = bfd_mach_ppc64;
465 break;
466 default:
467 *type = bfd_arch_unknown;
468 break;
472 static bfd_boolean
473 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
475 unsigned char buf[32];
476 unsigned int size;
478 size = mach_o_wide_p (header) ?
479 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
481 bfd_h_put_32 (abfd, header->magic, buf + 0);
482 bfd_h_put_32 (abfd, header->cputype, buf + 4);
483 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
484 bfd_h_put_32 (abfd, header->filetype, buf + 12);
485 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
486 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
487 bfd_h_put_32 (abfd, header->flags, buf + 24);
489 if (mach_o_wide_p (header))
490 bfd_h_put_32 (abfd, header->reserved, buf + 28);
492 if (bfd_seek (abfd, 0, SEEK_SET) != 0
493 || bfd_bwrite ((PTR) buf, size, abfd) != size)
494 return FALSE;
496 return TRUE;
499 static int
500 bfd_mach_o_scan_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
502 bfd_mach_o_thread_command *cmd = &command->command.thread;
503 unsigned int i;
504 unsigned char buf[8];
505 unsigned int offset;
506 unsigned int nflavours;
508 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
509 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
511 offset = 8;
512 nflavours = 0;
513 for (i = 0; i < cmd->nflavours; i++)
515 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
516 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
518 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
519 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
521 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
522 || bfd_bwrite ((PTR) buf, 8, abfd) != 8)
523 return -1;
525 offset += cmd->flavours[i].size + 8;
528 return 0;
531 long
532 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
533 asection *asect)
535 return (asect->reloc_count + 1) * sizeof (arelent *);
538 long
539 bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
540 arelent **rels, asymbol **syms)
542 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
543 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
544 unsigned long i;
545 arelent *res;
546 char *native_relocs;
547 bfd_size_type native_size;
549 if (asect->reloc_count == 0)
550 return 0;
552 /* No need to go further if we don't know how to read relocs. */
553 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
554 return 0;
556 /* Allocate and read relocs. */
557 native_size = asect->reloc_count * BFD_MACH_O_RELENT_SIZE;
558 native_relocs = bfd_malloc (native_size);
559 if (native_relocs == NULL)
560 return -1;
562 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0
563 || bfd_bread (native_relocs, native_size, abfd) != native_size)
565 free (native_relocs);
566 return -1;
569 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
570 if (res == NULL)
572 free (native_relocs);
573 return -1;
576 for (i = 0; i < asect->reloc_count; i++)
578 char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
579 bfd_mach_o_reloc_info reloc;
580 bfd_vma addr;
581 bfd_vma symnum;
582 asymbol **sym;
584 addr = bfd_get_32 (abfd, buf + 0);
585 symnum = bfd_get_32 (abfd, buf + 4);
587 if (addr & BFD_MACH_O_SR_SCATTERED)
589 unsigned int j;
591 /* Scattered relocation.
592 Extract section and offset from r_value. */
593 res[i].sym_ptr_ptr = NULL;
594 res[i].addend = 0;
595 for (j = 0; j < mdata->nsects; j++)
597 bfd_mach_o_section *sect = mdata->sections[j];
598 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
600 res[i].sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
601 res[i].addend = symnum - sect->addr;
602 break;
605 res[i].address = BFD_MACH_O_GET_SR_ADDRESS (addr);
606 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
607 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
608 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
609 reloc.r_scattered = 1;
611 else
613 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
614 res[i].addend = 0;
615 res[i].address = addr;
616 if (symnum & BFD_MACH_O_R_EXTERN)
617 sym = syms + num;
618 else
620 BFD_ASSERT (num != 0);
621 BFD_ASSERT (num <= mdata->nsects);
622 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
624 res[i].sym_ptr_ptr = sym;
625 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
626 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
627 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
628 reloc.r_scattered = 0;
631 if (!(*bed->_bfd_mach_o_swap_reloc_in)(&res[i], &reloc))
633 free (res);
634 free (native_relocs);
635 return -1;
637 rels[i] = &res[i];
639 asect->relocation = res;
640 free (native_relocs);
641 return i;
644 static bfd_boolean
645 bfd_mach_o_scan_write_relocs (bfd *abfd, bfd_mach_o_section *section)
647 bfd_mach_o_data_struct *mdata = bfd_get_mach_o_data (abfd);
648 unsigned int i;
649 arelent **entries;
650 asection *sec;
651 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
653 sec = section->bfdsection;
654 if (sec->reloc_count == 0)
655 return TRUE;
657 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
658 return TRUE;
660 /* Allocate relocation room. */
661 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
662 section->nreloc = sec->reloc_count;
663 sec->rel_filepos = mdata->filelen;
664 section->reloff = sec->rel_filepos;
665 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
667 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
668 return FALSE;
670 /* Convert and write. */
671 entries = section->bfdsection->orelocation;
672 for (i = 0; i < section->nreloc; i++)
674 arelent *rel = entries[i];
675 char buf[8];
676 bfd_mach_o_reloc_info info, *pinfo = &info;
678 /* Convert relocation to an intermediate representation. */
679 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
680 return FALSE;
682 /* Lower the relocation info. */
683 if (pinfo->r_scattered)
685 unsigned long v;
687 v = BFD_MACH_O_SR_SCATTERED
688 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
689 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
690 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
691 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
692 bfd_put_32 (abfd, v, buf);
693 bfd_put_32 (abfd, pinfo->r_value, buf + 4);
695 else
697 unsigned long v;
699 bfd_put_32 (abfd, pinfo->r_address, buf);
700 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
701 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
702 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
703 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
704 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
705 bfd_put_32 (abfd, v, buf + 4);
708 if (bfd_bwrite ((PTR) buf, BFD_MACH_O_RELENT_SIZE, abfd)
709 != BFD_MACH_O_RELENT_SIZE)
710 return FALSE;
712 return TRUE;
715 static int
716 bfd_mach_o_scan_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
718 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
720 memcpy (buf, section->sectname, 16);
721 memcpy (buf + 16, section->segname, 16);
722 bfd_h_put_32 (abfd, section->addr, buf + 32);
723 bfd_h_put_32 (abfd, section->size, buf + 36);
724 bfd_h_put_32 (abfd, section->offset, buf + 40);
725 bfd_h_put_32 (abfd, section->align, buf + 44);
726 bfd_h_put_32 (abfd, section->reloff, buf + 48);
727 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
728 bfd_h_put_32 (abfd, section->flags, buf + 56);
729 bfd_h_put_32 (abfd, section->reserved1, buf + 60);
730 bfd_h_put_32 (abfd, section->reserved2, buf + 64);
732 if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
733 != BFD_MACH_O_SECTION_SIZE)
734 return -1;
736 return 0;
739 static int
740 bfd_mach_o_scan_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
742 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
744 memcpy (buf, section->sectname, 16);
745 memcpy (buf + 16, section->segname, 16);
746 bfd_h_put_64 (abfd, section->addr, buf + 32);
747 bfd_h_put_64 (abfd, section->size, buf + 40);
748 bfd_h_put_32 (abfd, section->offset, buf + 48);
749 bfd_h_put_32 (abfd, section->align, buf + 52);
750 bfd_h_put_32 (abfd, section->reloff, buf + 56);
751 bfd_h_put_32 (abfd, section->nreloc, buf + 60);
752 bfd_h_put_32 (abfd, section->flags, buf + 64);
753 bfd_h_put_32 (abfd, section->reserved1, buf + 68);
754 bfd_h_put_32 (abfd, section->reserved2, buf + 72);
755 bfd_h_put_32 (abfd, section->reserved3, buf + 76);
757 if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
758 != BFD_MACH_O_SECTION_64_SIZE)
759 return -1;
761 return 0;
764 static int
765 bfd_mach_o_scan_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
767 unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
768 bfd_mach_o_segment_command *seg = &command->command.segment;
769 unsigned long i;
771 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
773 for (i = 0; i < seg->nsects; i++)
774 if (!bfd_mach_o_scan_write_relocs (abfd, &seg->sections[i]))
775 return -1;
777 memcpy (buf, seg->segname, 16);
778 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
779 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
780 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
781 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
782 bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
783 bfd_h_put_32 (abfd, seg->initprot, buf + 36);
784 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
785 bfd_h_put_32 (abfd, seg->flags, buf + 44);
787 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
788 || (bfd_bwrite ((PTR) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd)
789 != BFD_MACH_O_LC_SEGMENT_SIZE - 8))
790 return -1;
792 for (i = 0; i < seg->nsects; i++)
793 if (bfd_mach_o_scan_write_section_32 (abfd, &seg->sections[i]))
794 return -1;
796 return 0;
799 static int
800 bfd_mach_o_scan_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
802 unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
803 bfd_mach_o_segment_command *seg = &command->command.segment;
804 unsigned long i;
806 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
808 for (i = 0; i < seg->nsects; i++)
809 if (!bfd_mach_o_scan_write_relocs (abfd, &seg->sections[i]))
810 return -1;
812 memcpy (buf, seg->segname, 16);
813 bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
814 bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
815 bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
816 bfd_h_put_64 (abfd, seg->filesize, buf + 40);
817 bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
818 bfd_h_put_32 (abfd, seg->initprot, buf + 52);
819 bfd_h_put_32 (abfd, seg->nsects, buf + 56);
820 bfd_h_put_32 (abfd, seg->flags, buf + 60);
822 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
823 || (bfd_bwrite ((PTR) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
824 != BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
825 return -1;
827 for (i = 0; i < seg->nsects; i++)
828 if (bfd_mach_o_scan_write_section_64 (abfd, &seg->sections[i]))
829 return -1;
831 return 0;
834 static bfd_boolean
835 bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
837 bfd_mach_o_data_struct *mdata = bfd_get_mach_o_data (abfd);
838 bfd_mach_o_symtab_command *sym = &command->command.symtab;
839 unsigned char buf[16];
840 unsigned long i;
841 unsigned int wide = bfd_mach_o_wide_p (abfd);
842 unsigned int symlen = wide ? 16 : 12;
843 struct bfd_strtab_hash *strtab;
844 asymbol **symbols = bfd_get_outsymbols (abfd);
846 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
848 /* Write the symbols first. */
849 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
850 sym->symoff = mdata->filelen;
851 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
852 return FALSE;
854 sym->nsyms = bfd_get_symcount (abfd);
855 mdata->filelen += sym->nsyms * symlen;
857 strtab = _bfd_stringtab_init ();
858 if (strtab == NULL)
859 return FALSE;
861 for (i = 0; i < sym->nsyms; i++)
863 unsigned char buf[16];
864 bfd_size_type index;
865 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
867 /* Compute name index. */
868 /* An index of 0 always means the empty string. */
869 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
870 index = 0;
871 else
873 index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
874 if (index == (bfd_size_type) -1)
875 goto err;
877 bfd_h_put_32 (abfd, index, buf);
878 bfd_h_put_8 (abfd, s->n_type, buf + 4);
879 bfd_h_put_8 (abfd, s->n_sect, buf + 5);
880 bfd_h_put_16 (abfd, s->n_desc, buf + 6);
881 if (wide)
882 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
883 else
884 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
886 if (bfd_bwrite ((PTR) buf, symlen, abfd) != symlen)
887 goto err;
889 sym->strsize = _bfd_stringtab_size (strtab);
890 sym->stroff = mdata->filelen;
891 mdata->filelen += sym->strsize;
893 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
894 goto err;
895 _bfd_stringtab_free (strtab);
897 /* The command. */
898 bfd_h_put_32 (abfd, sym->symoff, buf);
899 bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
900 bfd_h_put_32 (abfd, sym->stroff, buf + 8);
901 bfd_h_put_32 (abfd, sym->strsize, buf + 12);
903 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
904 || bfd_bwrite ((PTR) buf, 16, abfd) != 16)
905 return FALSE;
907 return TRUE;
909 err:
910 _bfd_stringtab_free (strtab);
911 return FALSE;
914 /* Process the symbols and generate Mach-O specific fields.
915 Number them. */
917 static bfd_boolean
918 bfd_mach_o_mangle_symbols (bfd *abfd)
920 unsigned long i;
921 asymbol **symbols = bfd_get_outsymbols (abfd);
923 for (i = 0; i < bfd_get_symcount (abfd); i++)
925 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
927 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
929 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
930 symbols should be N_UNDEF | N_EXT), we suppose the back-end
931 values haven't been set. */
932 if (s->symbol.section == bfd_abs_section_ptr)
933 s->n_type = BFD_MACH_O_N_ABS;
934 else if (s->symbol.section == bfd_und_section_ptr)
936 s->n_type = BFD_MACH_O_N_UNDF;
937 if (s->symbol.flags & BSF_WEAK)
938 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
940 else if (s->symbol.section == bfd_com_section_ptr)
941 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
942 else
943 s->n_type = BFD_MACH_O_N_SECT;
945 if (s->symbol.flags & BSF_GLOBAL)
946 s->n_type |= BFD_MACH_O_N_EXT;
949 /* Compute section index. */
950 if (s->symbol.section != bfd_abs_section_ptr
951 && s->symbol.section != bfd_und_section_ptr
952 && s->symbol.section != bfd_com_section_ptr)
953 s->n_sect = s->symbol.section->target_index;
955 /* Number symbols. */
956 s->symbol.udata.i = i;
958 return TRUE;
961 bfd_boolean
962 bfd_mach_o_write_contents (bfd *abfd)
964 unsigned int i;
965 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
967 if (mdata->header.ncmds == 0)
968 if (!bfd_mach_o_build_commands (abfd))
969 return FALSE;
971 /* Now write header information. */
972 if (mdata->header.filetype == 0)
974 if (abfd->flags & EXEC_P)
975 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
976 else if (abfd->flags & DYNAMIC)
977 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
978 else
979 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
981 if (!bfd_mach_o_write_header (abfd, &mdata->header))
982 return FALSE;
984 /* Assign a number to each symbols. */
985 if (!bfd_mach_o_mangle_symbols (abfd))
986 return FALSE;
988 for (i = 0; i < mdata->header.ncmds; i++)
990 unsigned char buf[8];
991 bfd_mach_o_load_command *cur = &mdata->commands[i];
992 unsigned long typeflag;
994 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
996 bfd_h_put_32 (abfd, typeflag, buf);
997 bfd_h_put_32 (abfd, cur->len, buf + 4);
999 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1000 || bfd_bwrite ((PTR) buf, 8, abfd) != 8)
1001 return FALSE;
1003 switch (cur->type)
1005 case BFD_MACH_O_LC_SEGMENT:
1006 if (bfd_mach_o_scan_write_segment_32 (abfd, cur) != 0)
1007 return FALSE;
1008 break;
1009 case BFD_MACH_O_LC_SEGMENT_64:
1010 if (bfd_mach_o_scan_write_segment_64 (abfd, cur) != 0)
1011 return FALSE;
1012 break;
1013 case BFD_MACH_O_LC_SYMTAB:
1014 if (!bfd_mach_o_scan_write_symtab (abfd, cur))
1015 return FALSE;
1016 break;
1017 case BFD_MACH_O_LC_SYMSEG:
1018 break;
1019 case BFD_MACH_O_LC_THREAD:
1020 case BFD_MACH_O_LC_UNIXTHREAD:
1021 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
1022 return FALSE;
1023 break;
1024 case BFD_MACH_O_LC_LOADFVMLIB:
1025 case BFD_MACH_O_LC_IDFVMLIB:
1026 case BFD_MACH_O_LC_IDENT:
1027 case BFD_MACH_O_LC_FVMFILE:
1028 case BFD_MACH_O_LC_PREPAGE:
1029 case BFD_MACH_O_LC_DYSYMTAB:
1030 case BFD_MACH_O_LC_LOAD_DYLIB:
1031 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1032 case BFD_MACH_O_LC_ID_DYLIB:
1033 case BFD_MACH_O_LC_LOAD_DYLINKER:
1034 case BFD_MACH_O_LC_ID_DYLINKER:
1035 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1036 case BFD_MACH_O_LC_ROUTINES:
1037 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1038 break;
1039 default:
1040 fprintf (stderr,
1041 "unable to write unknown load command 0x%lx\n",
1042 (unsigned long) cur->type);
1043 return FALSE;
1047 return TRUE;
1050 /* Build Mach-O load commands from the sections. */
1052 bfd_boolean
1053 bfd_mach_o_build_commands (bfd *abfd)
1055 bfd_mach_o_data_struct *mdata = bfd_get_mach_o_data (abfd);
1056 unsigned int wide = mach_o_wide_p (&mdata->header);
1057 bfd_mach_o_segment_command *seg;
1058 bfd_mach_o_section *sections;
1059 asection *sec;
1060 bfd_mach_o_load_command *cmd;
1061 bfd_mach_o_load_command *symtab_cmd;
1062 int target_index;
1064 /* Return now if commands are already built. */
1065 if (mdata->header.ncmds)
1066 return FALSE;
1068 /* Very simple version: 1 command (segment) containing all sections. */
1069 mdata->header.ncmds = 2;
1070 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1071 * sizeof (bfd_mach_o_load_command));
1072 if (mdata->commands == NULL)
1073 return FALSE;
1074 cmd = &mdata->commands[0];
1075 seg = &cmd->command.segment;
1077 seg->nsects = bfd_count_sections (abfd);
1078 sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1079 if (sections == NULL)
1080 return FALSE;
1081 seg->sections = sections;
1083 /* Set segment command. */
1084 if (wide)
1086 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1087 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1088 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1089 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1091 else
1093 cmd->type = BFD_MACH_O_LC_SEGMENT;
1094 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1095 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1096 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1098 cmd->type_required = FALSE;
1099 mdata->header.sizeofcmds = cmd->len;
1100 mdata->filelen = cmd->offset + cmd->len;
1102 /* Set symtab command. */
1103 symtab_cmd = &mdata->commands[1];
1105 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1106 symtab_cmd->offset = cmd->offset + cmd->len;
1107 symtab_cmd->len = 6 * 4;
1108 symtab_cmd->type_required = FALSE;
1110 mdata->header.sizeofcmds += symtab_cmd->len;
1111 mdata->filelen += symtab_cmd->len;
1113 /* Fill segment command. */
1114 memset (seg->segname, 0, sizeof (seg->segname));
1115 seg->vmaddr = 0;
1116 seg->fileoff = mdata->filelen;
1117 seg->filesize = 0;
1118 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1119 | BFD_MACH_O_PROT_EXECUTE;
1120 seg->initprot = seg->maxprot;
1121 seg->flags = 0;
1123 /* Create Mach-O sections. */
1124 target_index = 0;
1125 for (sec = abfd->sections; sec; sec = sec->next)
1127 sections->bfdsection = sec;
1128 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
1129 sections->addr = bfd_get_section_vma (abfd, sec);
1130 sections->size = bfd_get_section_size (sec);
1131 sections->align = bfd_get_section_alignment (abfd, sec);
1133 if (sections->size != 0)
1135 mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
1136 sections->offset = mdata->filelen;
1138 else
1139 sections->offset = 0;
1140 sections->reloff = 0;
1141 sections->nreloc = 0;
1142 sections->reserved1 = 0;
1143 sections->reserved2 = 0;
1144 sections->reserved3 = 0;
1146 sec->filepos = sections->offset;
1147 sec->target_index = ++target_index;
1149 mdata->filelen += sections->size;
1150 sections++;
1152 seg->filesize = mdata->filelen - seg->fileoff;
1153 seg->vmsize = seg->filesize;
1155 return TRUE;
1158 /* Set the contents of a section. */
1160 bfd_boolean
1161 bfd_mach_o_set_section_contents (bfd *abfd,
1162 asection *section,
1163 const void * location,
1164 file_ptr offset,
1165 bfd_size_type count)
1167 file_ptr pos;
1169 /* This must be done first, because bfd_set_section_contents is
1170 going to set output_has_begun to TRUE. */
1171 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1172 return FALSE;
1174 if (count == 0)
1175 return TRUE;
1177 pos = section->filepos + offset;
1178 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1179 || bfd_bwrite (location, count, abfd) != count)
1180 return FALSE;
1182 return TRUE;
1186 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1187 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1189 return 0;
1192 /* Make an empty symbol. This is required only because
1193 bfd_make_section_anyway wants to create a symbol for the section. */
1195 asymbol *
1196 bfd_mach_o_make_empty_symbol (bfd *abfd)
1198 asymbol *new;
1200 new = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1201 if (new == NULL)
1202 return new;
1203 new->the_bfd = abfd;
1204 new->udata.i = 0;
1205 return new;
1208 static bfd_boolean
1209 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1211 unsigned char buf[32];
1212 unsigned int size;
1213 bfd_vma (*get32) (const void *) = NULL;
1215 /* Just read the magic number. */
1216 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1217 || bfd_bread ((PTR) buf, 4, abfd) != 4)
1218 return FALSE;
1220 if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
1222 header->byteorder = BFD_ENDIAN_BIG;
1223 header->magic = BFD_MACH_O_MH_MAGIC;
1224 header->version = 1;
1225 get32 = bfd_getb32;
1227 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
1229 header->byteorder = BFD_ENDIAN_LITTLE;
1230 header->magic = BFD_MACH_O_MH_MAGIC;
1231 header->version = 1;
1232 get32 = bfd_getl32;
1234 else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1236 header->byteorder = BFD_ENDIAN_BIG;
1237 header->magic = BFD_MACH_O_MH_MAGIC_64;
1238 header->version = 2;
1239 get32 = bfd_getb32;
1241 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1243 header->byteorder = BFD_ENDIAN_LITTLE;
1244 header->magic = BFD_MACH_O_MH_MAGIC_64;
1245 header->version = 2;
1246 get32 = bfd_getl32;
1248 else
1250 header->byteorder = BFD_ENDIAN_UNKNOWN;
1251 return FALSE;
1254 /* Once the size of the header is known, read the full header. */
1255 size = mach_o_wide_p (header) ?
1256 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1258 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1259 || bfd_bread ((PTR) buf, size, abfd) != size)
1260 return FALSE;
1262 header->cputype = (*get32) (buf + 4);
1263 header->cpusubtype = (*get32) (buf + 8);
1264 header->filetype = (*get32) (buf + 12);
1265 header->ncmds = (*get32) (buf + 16);
1266 header->sizeofcmds = (*get32) (buf + 20);
1267 header->flags = (*get32) (buf + 24);
1269 if (mach_o_wide_p (header))
1270 header->reserved = (*get32) (buf + 28);
1272 return TRUE;
1275 static asection *
1276 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
1277 unsigned long prot)
1279 asection *bfdsec;
1280 char *sname;
1281 flagword flags;
1283 sname = bfd_mach_o_convert_section_name_to_bfd (abfd, section);
1284 if (sname == NULL)
1285 return NULL;
1287 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1288 flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
1289 else
1291 flags = SEC_ALLOC;
1292 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1293 != BFD_MACH_O_S_ZEROFILL)
1295 flags |= SEC_HAS_CONTENTS | SEC_LOAD;
1296 if (prot & BFD_MACH_O_PROT_EXECUTE)
1297 flags |= SEC_CODE;
1298 if (prot & BFD_MACH_O_PROT_WRITE)
1299 flags |= SEC_DATA;
1300 else if (prot & BFD_MACH_O_PROT_READ)
1301 flags |= SEC_READONLY;
1304 if (section->nreloc != 0)
1305 flags |= SEC_RELOC;
1307 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1308 if (bfdsec == NULL)
1309 return NULL;
1311 bfdsec->vma = section->addr;
1312 bfdsec->lma = section->addr;
1313 bfdsec->size = section->size;
1314 bfdsec->filepos = section->offset;
1315 bfdsec->alignment_power = section->align;
1316 bfdsec->segment_mark = 0;
1317 bfdsec->reloc_count = section->nreloc;
1318 bfdsec->rel_filepos = section->reloff;
1320 return bfdsec;
1323 static int
1324 bfd_mach_o_scan_read_section_32 (bfd *abfd,
1325 bfd_mach_o_section *section,
1326 unsigned int offset,
1327 unsigned long prot)
1329 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
1331 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1332 || (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
1333 != BFD_MACH_O_SECTION_SIZE))
1334 return -1;
1336 memcpy (section->sectname, buf, 16);
1337 section->sectname[16] = '\0';
1338 memcpy (section->segname, buf + 16, 16);
1339 section->segname[16] = '\0';
1340 section->addr = bfd_h_get_32 (abfd, buf + 32);
1341 section->size = bfd_h_get_32 (abfd, buf + 36);
1342 section->offset = bfd_h_get_32 (abfd, buf + 40);
1343 section->align = bfd_h_get_32 (abfd, buf + 44);
1344 section->reloff = bfd_h_get_32 (abfd, buf + 48);
1345 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
1346 section->flags = bfd_h_get_32 (abfd, buf + 56);
1347 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
1348 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
1349 section->reserved3 = 0;
1350 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1352 if (section->bfdsection == NULL)
1353 return -1;
1355 return 0;
1358 static int
1359 bfd_mach_o_scan_read_section_64 (bfd *abfd,
1360 bfd_mach_o_section *section,
1361 unsigned int offset,
1362 unsigned long prot)
1364 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
1366 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1367 || (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
1368 != BFD_MACH_O_SECTION_64_SIZE))
1369 return -1;
1371 memcpy (section->sectname, buf, 16);
1372 section->sectname[16] = '\0';
1373 memcpy (section->segname, buf + 16, 16);
1374 section->segname[16] = '\0';
1375 section->addr = bfd_h_get_64 (abfd, buf + 32);
1376 section->size = bfd_h_get_64 (abfd, buf + 40);
1377 section->offset = bfd_h_get_32 (abfd, buf + 48);
1378 section->align = bfd_h_get_32 (abfd, buf + 52);
1379 section->reloff = bfd_h_get_32 (abfd, buf + 56);
1380 section->nreloc = bfd_h_get_32 (abfd, buf + 60);
1381 section->flags = bfd_h_get_32 (abfd, buf + 64);
1382 section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
1383 section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
1384 section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
1385 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1387 if (section->bfdsection == NULL)
1388 return -1;
1390 return 0;
1393 static int
1394 bfd_mach_o_scan_read_section (bfd *abfd,
1395 bfd_mach_o_section *section,
1396 unsigned int offset,
1397 unsigned long prot,
1398 unsigned int wide)
1400 if (wide)
1401 return bfd_mach_o_scan_read_section_64 (abfd, section, offset, prot);
1402 else
1403 return bfd_mach_o_scan_read_section_32 (abfd, section, offset, prot);
1407 bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
1408 bfd_mach_o_symtab_command *sym,
1409 bfd_mach_o_asymbol *s,
1410 unsigned long i)
1412 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1413 unsigned int wide = mach_o_wide_p (&mdata->header);
1414 unsigned int symwidth = wide ? 16 : 12;
1415 unsigned int symoff = sym->symoff + (i * symwidth);
1416 unsigned char buf[16];
1417 unsigned char type = -1;
1418 unsigned char section = -1;
1419 short desc = -1;
1420 symvalue value = -1;
1421 unsigned long stroff = -1;
1422 unsigned int symtype = -1;
1424 BFD_ASSERT (sym->strtab != NULL);
1426 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1427 || bfd_bread ((PTR) buf, symwidth, abfd) != symwidth)
1429 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
1430 symwidth, (unsigned long) symoff);
1431 return -1;
1434 stroff = bfd_h_get_32 (abfd, buf);
1435 type = bfd_h_get_8 (abfd, buf + 4);
1436 symtype = type & BFD_MACH_O_N_TYPE;
1437 section = bfd_h_get_8 (abfd, buf + 5);
1438 desc = bfd_h_get_16 (abfd, buf + 6);
1439 if (wide)
1440 value = bfd_h_get_64 (abfd, buf + 8);
1441 else
1442 value = bfd_h_get_32 (abfd, buf + 8);
1444 if (stroff >= sym->strsize)
1446 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
1447 (unsigned long) stroff, (unsigned long) sym->strsize);
1448 return -1;
1451 s->symbol.the_bfd = abfd;
1452 s->symbol.name = sym->strtab + stroff;
1453 s->symbol.value = value;
1454 s->symbol.flags = 0x0;
1455 s->symbol.udata.i = 0;
1456 s->n_type = type;
1457 s->n_sect = section;
1458 s->n_desc = desc;
1460 if (type & BFD_MACH_O_N_STAB)
1462 s->symbol.flags |= BSF_DEBUGGING;
1463 s->symbol.section = bfd_und_section_ptr;
1464 switch (type)
1466 case N_FUN:
1467 case N_STSYM:
1468 case N_LCSYM:
1469 case N_BNSYM:
1470 case N_SLINE:
1471 case N_ENSYM:
1472 case N_ECOMM:
1473 case N_ECOML:
1474 case N_GSYM:
1475 if ((section > 0) && (section <= mdata->nsects))
1477 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1478 s->symbol.value =
1479 s->symbol.value - mdata->sections[section - 1]->addr;
1481 break;
1484 else
1486 if (type & BFD_MACH_O_N_PEXT)
1487 s->symbol.flags |= BSF_GLOBAL;
1489 if (type & BFD_MACH_O_N_EXT)
1490 s->symbol.flags |= BSF_GLOBAL;
1492 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1493 s->symbol.flags |= BSF_LOCAL;
1495 switch (symtype)
1497 case BFD_MACH_O_N_UNDF:
1498 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1499 && s->symbol.value != 0)
1501 /* A common symbol. */
1502 s->symbol.section = bfd_com_section_ptr;
1503 s->symbol.flags = BSF_NO_FLAGS;
1505 else
1507 s->symbol.section = bfd_und_section_ptr;
1508 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1509 s->symbol.flags |= BSF_WEAK;
1511 break;
1512 case BFD_MACH_O_N_PBUD:
1513 s->symbol.section = bfd_und_section_ptr;
1514 break;
1515 case BFD_MACH_O_N_ABS:
1516 s->symbol.section = bfd_abs_section_ptr;
1517 break;
1518 case BFD_MACH_O_N_SECT:
1519 if ((section > 0) && (section <= mdata->nsects))
1521 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1522 s->symbol.value =
1523 s->symbol.value - mdata->sections[section - 1]->addr;
1525 else
1527 /* Mach-O uses 0 to mean "no section"; not an error. */
1528 if (section != 0)
1530 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1531 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
1532 s->symbol.name, section, mdata->nsects);
1534 s->symbol.section = bfd_und_section_ptr;
1536 break;
1537 case BFD_MACH_O_N_INDR:
1538 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1539 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
1540 s->symbol.name);
1541 s->symbol.section = bfd_und_section_ptr;
1542 break;
1543 default:
1544 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1545 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
1546 s->symbol.name, symtype);
1547 s->symbol.section = bfd_und_section_ptr;
1548 break;
1552 return 0;
1556 bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
1557 bfd_mach_o_symtab_command *sym)
1559 BFD_ASSERT (sym->strtab == NULL);
1561 if (abfd->flags & BFD_IN_MEMORY)
1563 struct bfd_in_memory *b;
1565 b = (struct bfd_in_memory *) abfd->iostream;
1567 if ((sym->stroff + sym->strsize) > b->size)
1569 bfd_set_error (bfd_error_file_truncated);
1570 return -1;
1572 sym->strtab = (char *) b->buffer + sym->stroff;
1573 return 0;
1576 sym->strtab = bfd_alloc (abfd, sym->strsize);
1577 if (sym->strtab == NULL)
1578 return -1;
1580 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1581 || bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
1583 bfd_set_error (bfd_error_file_truncated);
1584 return -1;
1587 return 0;
1591 bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
1592 bfd_mach_o_symtab_command *sym)
1594 unsigned long i;
1595 int ret;
1597 BFD_ASSERT (sym->symbols == NULL);
1598 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1600 if (sym->symbols == NULL)
1602 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
1603 return -1;
1606 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
1607 if (ret != 0)
1608 return ret;
1610 for (i = 0; i < sym->nsyms; i++)
1612 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1613 if (ret != 0)
1614 return ret;
1617 return 0;
1621 bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
1622 bfd_mach_o_dysymtab_command *dysym,
1623 bfd_mach_o_symtab_command *sym,
1624 bfd_mach_o_asymbol *s,
1625 unsigned long i)
1627 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1628 unsigned long symindex;
1629 unsigned char buf[4];
1631 BFD_ASSERT (i < dysym->nindirectsyms);
1633 if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
1634 || bfd_bread ((PTR) buf, 4, abfd) != 4)
1636 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
1637 (unsigned long) 4, isymoff);
1638 return -1;
1640 symindex = bfd_h_get_32 (abfd, buf);
1642 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
1645 static const char *
1646 bfd_mach_o_i386_flavour_string (unsigned int flavour)
1648 switch ((int) flavour)
1650 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
1651 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
1652 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1653 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
1654 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
1655 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1656 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
1657 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
1658 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
1659 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
1660 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
1661 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
1662 case BFD_MACH_O_THREAD_STATE_NONE: return "THREAD_STATE_NONE";
1663 default: return "UNKNOWN";
1667 static const char *
1668 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1670 switch ((int) flavour)
1672 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1673 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1674 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1675 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1676 default: return "UNKNOWN";
1680 static int
1681 bfd_mach_o_scan_read_dylinker (bfd *abfd,
1682 bfd_mach_o_load_command *command)
1684 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1685 unsigned char buf[4];
1686 unsigned int nameoff;
1687 asection *bfdsec;
1688 char *sname;
1689 const char *prefix;
1691 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1692 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1694 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1695 || bfd_bread ((PTR) buf, 4, abfd) != 4)
1696 return -1;
1698 nameoff = bfd_h_get_32 (abfd, buf + 0);
1700 cmd->name_offset = command->offset + nameoff;
1701 cmd->name_len = command->len - nameoff;
1703 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
1704 prefix = "LC_LOAD_DYLINKER";
1705 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
1706 prefix = "LC_ID_DYLINKER";
1707 else
1708 abort ();
1710 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1711 if (sname == NULL)
1712 return -1;
1713 strcpy (sname, prefix);
1715 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1716 if (bfdsec == NULL)
1717 return -1;
1719 bfdsec->vma = 0;
1720 bfdsec->lma = 0;
1721 bfdsec->size = command->len - nameoff;
1722 bfdsec->filepos = command->offset + nameoff;
1723 bfdsec->alignment_power = 0;
1725 cmd->section = bfdsec;
1727 return 0;
1730 static int
1731 bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1733 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1734 unsigned char buf[16];
1735 unsigned int nameoff;
1736 asection *bfdsec;
1737 char *sname;
1738 const char *prefix;
1740 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1741 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1742 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1744 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1745 || bfd_bread ((PTR) buf, 16, abfd) != 16)
1746 return -1;
1748 nameoff = bfd_h_get_32 (abfd, buf + 0);
1749 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1750 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1751 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1753 cmd->name_offset = command->offset + nameoff;
1754 cmd->name_len = command->len - nameoff;
1756 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1757 prefix = "LC_LOAD_DYLIB";
1758 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1759 prefix = "LC_LOAD_WEAK_DYLIB";
1760 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1761 prefix = "LC_ID_DYLIB";
1762 else
1763 abort ();
1765 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1766 if (sname == NULL)
1767 return -1;
1768 strcpy (sname, prefix);
1770 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1771 if (bfdsec == NULL)
1772 return -1;
1774 bfdsec->vma = 0;
1775 bfdsec->lma = 0;
1776 bfdsec->size = command->len - 8;
1777 bfdsec->filepos = command->offset + 8;
1778 bfdsec->alignment_power = 0;
1780 cmd->section = bfdsec;
1782 return 0;
1785 static int
1786 bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1787 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1789 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1791 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1792 return 0;
1795 static int
1796 bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1798 bfd_mach_o_data_struct *mdata = NULL;
1799 bfd_mach_o_thread_command *cmd = &command->command.thread;
1800 unsigned char buf[8];
1801 unsigned int offset;
1802 unsigned int nflavours;
1803 unsigned int i;
1805 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1806 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1808 BFD_ASSERT (bfd_mach_o_valid (abfd));
1809 mdata = abfd->tdata.mach_o_data;
1811 offset = 8;
1812 nflavours = 0;
1813 while (offset != command->len)
1815 if (offset >= command->len)
1816 return -1;
1818 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
1819 || bfd_bread ((PTR) buf, 8, abfd) != 8)
1820 return -1;
1822 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1823 nflavours++;
1826 cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
1827 if (cmd->flavours == NULL)
1828 return -1;
1829 cmd->nflavours = nflavours;
1831 offset = 8;
1832 nflavours = 0;
1833 while (offset != command->len)
1835 if (offset >= command->len)
1836 return -1;
1838 if (nflavours >= cmd->nflavours)
1839 return -1;
1841 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
1842 || bfd_bread ((PTR) buf, 8, abfd) != 8)
1843 return -1;
1845 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1846 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1847 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1848 offset += cmd->flavours[nflavours].size + 8;
1849 nflavours++;
1852 for (i = 0; i < nflavours; i++)
1854 asection *bfdsec;
1855 unsigned int snamelen;
1856 char *sname;
1857 const char *flavourstr;
1858 const char *prefix = "LC_THREAD";
1859 unsigned int j = 0;
1861 switch (mdata->header.cputype)
1863 case BFD_MACH_O_CPU_TYPE_POWERPC:
1864 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
1865 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1866 break;
1867 case BFD_MACH_O_CPU_TYPE_I386:
1868 case BFD_MACH_O_CPU_TYPE_X86_64:
1869 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1870 break;
1871 default:
1872 flavourstr = "UNKNOWN_ARCHITECTURE";
1873 break;
1876 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1877 sname = bfd_alloc (abfd, snamelen);
1878 if (sname == NULL)
1879 return -1;
1881 for (;;)
1883 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1884 if (bfd_get_section_by_name (abfd, sname) == NULL)
1885 break;
1886 j++;
1889 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1891 bfdsec->vma = 0;
1892 bfdsec->lma = 0;
1893 bfdsec->size = cmd->flavours[i].size;
1894 bfdsec->filepos = cmd->flavours[i].offset;
1895 bfdsec->alignment_power = 0x0;
1897 cmd->section = bfdsec;
1900 return 0;
1903 static int
1904 bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1906 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1907 unsigned char buf[72];
1909 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1911 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1912 || bfd_bread ((PTR) buf, 72, abfd) != 72)
1913 return -1;
1915 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1916 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1917 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1918 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1919 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1920 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1921 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1922 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1923 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1924 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1925 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1926 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1927 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1928 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1929 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1930 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1931 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1932 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1934 return 0;
1937 static int
1938 bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1940 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1941 unsigned char buf[16];
1943 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1945 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1946 || bfd_bread ((PTR) buf, 16, abfd) != 16)
1947 return -1;
1949 seg->symoff = bfd_h_get_32 (abfd, buf);
1950 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1951 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1952 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1953 seg->symbols = NULL;
1954 seg->strtab = NULL;
1956 if (seg->nsyms != 0)
1957 abfd->flags |= HAS_SYMS;
1959 return 0;
1962 static int
1963 bfd_mach_o_scan_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
1965 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
1966 asection *bfdsec;
1967 char *sname;
1968 static const char prefix[] = "LC_UUID";
1970 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
1972 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1973 || bfd_bread ((PTR) cmd->uuid, 16, abfd) != 16)
1974 return -1;
1976 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1977 if (sname == NULL)
1978 return -1;
1979 strcpy (sname, prefix);
1981 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1982 if (bfdsec == NULL)
1983 return -1;
1985 bfdsec->vma = 0;
1986 bfdsec->lma = 0;
1987 bfdsec->size = command->len - 8;
1988 bfdsec->filepos = command->offset + 8;
1989 bfdsec->alignment_power = 0;
1991 cmd->section = bfdsec;
1993 return 0;
1996 static int
1997 bfd_mach_o_scan_read_segment (bfd *abfd,
1998 bfd_mach_o_load_command *command,
1999 unsigned int wide)
2001 unsigned char buf[64];
2002 bfd_mach_o_segment_command *seg = &command->command.segment;
2003 unsigned long i;
2005 if (wide)
2007 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2009 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2010 || bfd_bread ((PTR) buf, 64, abfd) != 64)
2011 return -1;
2013 memcpy (seg->segname, buf, 16);
2014 seg->segname[16] = '\0';
2016 seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
2017 seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
2018 seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
2019 seg->filesize = bfd_h_get_64 (abfd, buf + 40);
2020 seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
2021 seg->initprot = bfd_h_get_32 (abfd, buf + 52);
2022 seg->nsects = bfd_h_get_32 (abfd, buf + 56);
2023 seg->flags = bfd_h_get_32 (abfd, buf + 60);
2025 else
2027 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2029 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
2030 || bfd_bread ((PTR) buf, 48, abfd) != 48)
2031 return -1;
2033 memcpy (seg->segname, buf, 16);
2034 seg->segname[16] = '\0';
2036 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
2037 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
2038 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
2039 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
2040 seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
2041 seg->initprot = bfd_h_get_32 (abfd, buf + 36);
2042 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
2043 seg->flags = bfd_h_get_32 (abfd, buf + 44);
2046 if (seg->nsects != 0)
2048 seg->sections = bfd_alloc (abfd, seg->nsects
2049 * sizeof (bfd_mach_o_section));
2050 if (seg->sections == NULL)
2051 return -1;
2053 for (i = 0; i < seg->nsects; i++)
2055 bfd_vma segoff;
2056 if (wide)
2057 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2058 + (i * BFD_MACH_O_SECTION_64_SIZE);
2059 else
2060 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2061 + (i * BFD_MACH_O_SECTION_SIZE);
2063 if (bfd_mach_o_scan_read_section
2064 (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
2065 return -1;
2069 return 0;
2072 static int
2073 bfd_mach_o_scan_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2075 return bfd_mach_o_scan_read_segment (abfd, command, 0);
2078 static int
2079 bfd_mach_o_scan_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2081 return bfd_mach_o_scan_read_segment (abfd, command, 1);
2084 static int
2085 bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2087 unsigned char buf[8];
2089 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2090 || bfd_bread ((PTR) buf, 8, abfd) != 8)
2091 return -1;
2093 command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
2094 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
2095 ? TRUE : FALSE);
2096 command->len = bfd_h_get_32 (abfd, buf + 4);
2098 switch (command->type)
2100 case BFD_MACH_O_LC_SEGMENT:
2101 if (bfd_mach_o_scan_read_segment_32 (abfd, command) != 0)
2102 return -1;
2103 break;
2104 case BFD_MACH_O_LC_SEGMENT_64:
2105 if (bfd_mach_o_scan_read_segment_64 (abfd, command) != 0)
2106 return -1;
2107 break;
2108 case BFD_MACH_O_LC_SYMTAB:
2109 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
2110 return -1;
2111 break;
2112 case BFD_MACH_O_LC_SYMSEG:
2113 break;
2114 case BFD_MACH_O_LC_THREAD:
2115 case BFD_MACH_O_LC_UNIXTHREAD:
2116 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
2117 return -1;
2118 break;
2119 case BFD_MACH_O_LC_LOAD_DYLINKER:
2120 case BFD_MACH_O_LC_ID_DYLINKER:
2121 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
2122 return -1;
2123 break;
2124 case BFD_MACH_O_LC_LOAD_DYLIB:
2125 case BFD_MACH_O_LC_ID_DYLIB:
2126 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2127 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
2128 return -1;
2129 break;
2130 case BFD_MACH_O_LC_PREBOUND_DYLIB:
2131 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
2132 return -1;
2133 break;
2134 case BFD_MACH_O_LC_LOADFVMLIB:
2135 case BFD_MACH_O_LC_IDFVMLIB:
2136 case BFD_MACH_O_LC_IDENT:
2137 case BFD_MACH_O_LC_FVMFILE:
2138 case BFD_MACH_O_LC_PREPAGE:
2139 case BFD_MACH_O_LC_ROUTINES:
2140 case BFD_MACH_O_LC_SUB_FRAMEWORK:
2141 break;
2142 case BFD_MACH_O_LC_DYSYMTAB:
2143 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
2144 return -1;
2145 break;
2146 case BFD_MACH_O_LC_SUB_UMBRELLA:
2147 case BFD_MACH_O_LC_SUB_CLIENT:
2148 case BFD_MACH_O_LC_SUB_LIBRARY:
2149 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2150 case BFD_MACH_O_LC_PREBIND_CKSUM:
2151 break;
2152 case BFD_MACH_O_LC_UUID:
2153 if (bfd_mach_o_scan_read_uuid (abfd, command) != 0)
2154 return -1;
2155 break;
2156 case BFD_MACH_O_LC_CODE_SIGNATURE:
2157 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2158 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2159 break;
2160 default:
2161 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
2162 (unsigned long) command->type);
2163 break;
2166 return 0;
2169 static void
2170 bfd_mach_o_flatten_sections (bfd *abfd)
2172 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2173 long csect = 0;
2174 unsigned long i, j;
2176 /* Count total number of sections. */
2177 mdata->nsects = 0;
2179 for (i = 0; i < mdata->header.ncmds; i++)
2181 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2182 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2184 bfd_mach_o_segment_command *seg;
2186 seg = &mdata->commands[i].command.segment;
2187 mdata->nsects += seg->nsects;
2191 /* Allocate sections array. */
2192 mdata->sections = bfd_alloc (abfd,
2193 mdata->nsects * sizeof (bfd_mach_o_section *));
2195 /* Fill the array. */
2196 csect = 0;
2198 for (i = 0; i < mdata->header.ncmds; i++)
2200 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2201 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2203 bfd_mach_o_segment_command *seg;
2205 seg = &mdata->commands[i].command.segment;
2206 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2208 for (j = 0; j < seg->nsects; j++)
2209 mdata->sections[csect++] = &seg->sections[j];
2215 bfd_mach_o_scan_start_address (bfd *abfd)
2217 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2218 bfd_mach_o_thread_command *cmd = NULL;
2219 unsigned long i;
2221 for (i = 0; i < mdata->header.ncmds; i++)
2223 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2224 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2226 if (cmd == NULL)
2227 cmd = &mdata->commands[i].command.thread;
2228 else
2229 return 0;
2233 if (cmd == NULL)
2234 return 0;
2236 for (i = 0; i < cmd->nflavours; i++)
2238 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2239 && (cmd->flavours[i].flavour
2240 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2242 unsigned char buf[4];
2244 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2245 || bfd_bread (buf, 4, abfd) != 4)
2246 return -1;
2248 abfd->start_address = bfd_h_get_32 (abfd, buf);
2250 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2251 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2253 unsigned char buf[4];
2255 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2256 || bfd_bread (buf, 4, abfd) != 4)
2257 return -1;
2259 abfd->start_address = bfd_h_get_32 (abfd, buf);
2261 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2262 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE_64))
2264 unsigned char buf[8];
2266 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2267 || bfd_bread (buf, 8, abfd) != 8)
2268 return -1;
2270 abfd->start_address = bfd_h_get_64 (abfd, buf);
2272 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2273 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2275 unsigned char buf[8];
2277 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2278 || bfd_bread (buf, 8, abfd) != 8)
2279 return -1;
2281 abfd->start_address = bfd_h_get_64 (abfd, buf);
2285 return 0;
2289 bfd_mach_o_scan (bfd *abfd,
2290 bfd_mach_o_header *header,
2291 bfd_mach_o_data_struct *mdata)
2293 unsigned int i;
2294 enum bfd_architecture cputype;
2295 unsigned long cpusubtype;
2296 unsigned int hdrsize;
2298 hdrsize = mach_o_wide_p (header) ?
2299 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2301 mdata->header = *header;
2303 abfd->flags = abfd->flags & BFD_IN_MEMORY;
2304 switch (header->filetype)
2306 case BFD_MACH_O_MH_OBJECT:
2307 abfd->flags |= HAS_RELOC;
2308 break;
2309 case BFD_MACH_O_MH_EXECUTE:
2310 abfd->flags |= EXEC_P;
2311 break;
2312 case BFD_MACH_O_MH_DYLIB:
2313 case BFD_MACH_O_MH_BUNDLE:
2314 abfd->flags |= DYNAMIC;
2315 break;
2318 abfd->tdata.mach_o_data = mdata;
2320 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2321 &cputype, &cpusubtype);
2322 if (cputype == bfd_arch_unknown)
2324 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
2325 header->cputype, header->cpusubtype);
2326 return -1;
2329 bfd_set_arch_mach (abfd, cputype, cpusubtype);
2331 if (header->ncmds != 0)
2333 mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2334 if (mdata->commands == NULL)
2335 return -1;
2337 for (i = 0; i < header->ncmds; i++)
2339 bfd_mach_o_load_command *cur = &mdata->commands[i];
2341 if (i == 0)
2342 cur->offset = hdrsize;
2343 else
2345 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2346 cur->offset = prev->offset + prev->len;
2349 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
2350 return -1;
2354 if (bfd_mach_o_scan_start_address (abfd) < 0)
2355 return -1;
2357 bfd_mach_o_flatten_sections (abfd);
2358 return 0;
2361 bfd_boolean
2362 bfd_mach_o_mkobject_init (bfd *abfd)
2364 bfd_mach_o_data_struct *mdata = NULL;
2366 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2367 if (mdata == NULL)
2368 return FALSE;
2369 abfd->tdata.mach_o_data = mdata;
2371 mdata->header.magic = 0;
2372 mdata->header.cputype = 0;
2373 mdata->header.cpusubtype = 0;
2374 mdata->header.filetype = 0;
2375 mdata->header.ncmds = 0;
2376 mdata->header.sizeofcmds = 0;
2377 mdata->header.flags = 0;
2378 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2379 mdata->commands = NULL;
2380 mdata->nsects = 0;
2381 mdata->sections = NULL;
2383 return TRUE;
2386 const bfd_target *
2387 bfd_mach_o_header_p (bfd *abfd,
2388 bfd_mach_o_filetype filetype,
2389 bfd_mach_o_cpu_type cputype)
2391 struct bfd_preserve preserve;
2392 bfd_mach_o_header header;
2394 preserve.marker = NULL;
2395 if (!bfd_mach_o_read_header (abfd, &header))
2396 goto wrong;
2398 if (! (header.byteorder == BFD_ENDIAN_BIG
2399 || header.byteorder == BFD_ENDIAN_LITTLE))
2401 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
2402 (unsigned long) header.byteorder);
2403 goto wrong;
2406 if (! ((header.byteorder == BFD_ENDIAN_BIG
2407 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2408 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2409 || (header.byteorder == BFD_ENDIAN_LITTLE
2410 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2411 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2412 goto wrong;
2414 /* Check cputype and filetype.
2415 In case of wildcard, do not accept magics that are handled by existing
2416 targets. */
2417 if (cputype)
2419 if (header.cputype != cputype)
2420 goto wrong;
2422 else
2424 switch (header.cputype)
2426 case BFD_MACH_O_CPU_TYPE_I386:
2427 /* Handled by mach-o-i386 */
2428 goto wrong;
2429 default:
2430 break;
2433 if (filetype)
2435 if (header.filetype != filetype)
2436 goto wrong;
2438 else
2440 switch (header.filetype)
2442 case BFD_MACH_O_MH_CORE:
2443 /* Handled by core_p */
2444 goto wrong;
2445 default:
2446 break;
2450 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2451 if (preserve.marker == NULL
2452 || !bfd_preserve_save (abfd, &preserve))
2453 goto fail;
2455 if (bfd_mach_o_scan (abfd, &header,
2456 (bfd_mach_o_data_struct *) preserve.marker) != 0)
2457 goto wrong;
2459 bfd_preserve_finish (abfd, &preserve);
2460 return abfd->xvec;
2462 wrong:
2463 bfd_set_error (bfd_error_wrong_format);
2465 fail:
2466 if (preserve.marker != NULL)
2467 bfd_preserve_restore (abfd, &preserve);
2468 return NULL;
2471 static const bfd_target *
2472 bfd_mach_o_gen_object_p (bfd *abfd)
2474 return bfd_mach_o_header_p (abfd, 0, 0);
2477 static const bfd_target *
2478 bfd_mach_o_gen_core_p (bfd *abfd)
2480 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
2483 typedef struct mach_o_fat_archentry
2485 unsigned long cputype;
2486 unsigned long cpusubtype;
2487 unsigned long offset;
2488 unsigned long size;
2489 unsigned long align;
2490 } mach_o_fat_archentry;
2492 typedef struct mach_o_fat_data_struct
2494 unsigned long magic;
2495 unsigned long nfat_arch;
2496 mach_o_fat_archentry *archentries;
2497 } mach_o_fat_data_struct;
2499 const bfd_target *
2500 bfd_mach_o_archive_p (bfd *abfd)
2502 mach_o_fat_data_struct *adata = NULL;
2503 unsigned char buf[20];
2504 unsigned long i;
2506 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2507 || bfd_bread ((PTR) buf, 8, abfd) != 8)
2508 goto error;
2510 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
2511 if (adata == NULL)
2512 goto error;
2514 adata->magic = bfd_getb32 (buf);
2515 adata->nfat_arch = bfd_getb32 (buf + 4);
2516 if (adata->magic != 0xcafebabe)
2517 goto error;
2518 /* Avoid matching Java bytecode files, which have the same magic number.
2519 In the Java bytecode file format this field contains the JVM version,
2520 which starts at 43.0. */
2521 if (adata->nfat_arch > 30)
2522 goto error;
2524 adata->archentries =
2525 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2526 if (adata->archentries == NULL)
2527 goto error;
2529 for (i = 0; i < adata->nfat_arch; i++)
2531 if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
2532 || bfd_bread ((PTR) buf, 20, abfd) != 20)
2533 goto error;
2534 adata->archentries[i].cputype = bfd_getb32 (buf);
2535 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
2536 adata->archentries[i].offset = bfd_getb32 (buf + 8);
2537 adata->archentries[i].size = bfd_getb32 (buf + 12);
2538 adata->archentries[i].align = bfd_getb32 (buf + 16);
2541 abfd->tdata.mach_o_fat_data = adata;
2542 return abfd->xvec;
2544 error:
2545 if (adata != NULL)
2546 bfd_release (abfd, adata);
2547 bfd_set_error (bfd_error_wrong_format);
2548 return NULL;
2551 bfd *
2552 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
2554 mach_o_fat_data_struct *adata;
2555 mach_o_fat_archentry *entry = NULL;
2556 unsigned long i;
2557 bfd *nbfd;
2558 enum bfd_architecture arch_type;
2559 unsigned long arch_subtype;
2561 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
2562 BFD_ASSERT (adata != NULL);
2564 /* Find index of previous entry. */
2565 if (prev == NULL)
2566 i = 0; /* Start at first one. */
2567 else
2569 for (i = 0; i < adata->nfat_arch; i++)
2571 if (adata->archentries[i].offset == prev->origin)
2572 break;
2575 if (i == adata->nfat_arch)
2577 /* Not found. */
2578 bfd_set_error (bfd_error_bad_value);
2579 return NULL;
2581 i++; /* Get next entry. */
2584 if (i >= adata->nfat_arch)
2586 bfd_set_error (bfd_error_no_more_archived_files);
2587 return NULL;
2590 entry = &adata->archentries[i];
2591 nbfd = _bfd_new_bfd_contained_in (archive);
2592 if (nbfd == NULL)
2593 return NULL;
2595 nbfd->origin = entry->offset;
2597 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
2598 &arch_type, &arch_subtype);
2599 /* Create the member filename.
2600 Use FILENAME:ARCH_NAME. */
2602 char *s = NULL;
2603 const char *arch_name;
2604 size_t arch_file_len = strlen (bfd_get_filename (archive));
2606 arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
2607 s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
2608 if (s == NULL)
2609 return NULL;
2610 memcpy (s, bfd_get_filename (archive), arch_file_len);
2611 s[arch_file_len] = ':';
2612 strcpy (s + arch_file_len + 1, arch_name);
2613 nbfd->filename = s;
2615 nbfd->iostream = NULL;
2616 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
2618 return nbfd;
2621 /* If ABFD format is FORMAT and architecture is ARCH, return it.
2622 If ABFD is a fat image containing a member that corresponds to FORMAT
2623 and ARCH, returns it.
2624 In other case, returns NULL.
2625 This function allows transparent uses of fat images. */
2626 bfd *
2627 bfd_mach_o_fat_extract (bfd *abfd,
2628 bfd_format format,
2629 const bfd_arch_info_type *arch)
2631 bfd *res;
2632 mach_o_fat_data_struct *adata;
2633 unsigned int i;
2635 if (bfd_check_format (abfd, format))
2637 if (bfd_get_arch_info (abfd) == arch)
2638 return abfd;
2639 return NULL;
2641 if (!bfd_check_format (abfd, bfd_archive)
2642 || abfd->xvec != &mach_o_fat_vec)
2643 return NULL;
2645 /* This is a Mach-O fat image. */
2646 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
2647 BFD_ASSERT (adata != NULL);
2649 for (i = 0; i < adata->nfat_arch; i++)
2651 struct mach_o_fat_archentry *e = &adata->archentries[i];
2652 enum bfd_architecture cpu_type;
2653 unsigned long cpu_subtype;
2655 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
2656 &cpu_type, &cpu_subtype);
2657 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
2658 continue;
2660 /* The architecture is found. */
2661 res = _bfd_new_bfd_contained_in (abfd);
2662 if (res == NULL)
2663 return NULL;
2665 res->origin = e->offset;
2667 res->filename = strdup (abfd->filename);
2668 res->iostream = NULL;
2670 if (bfd_check_format (res, format))
2672 BFD_ASSERT (bfd_get_arch_info (res) == arch);
2673 return res;
2675 bfd_close (res);
2676 return NULL;
2679 return NULL;
2683 bfd_mach_o_lookup_section (bfd *abfd,
2684 asection *section,
2685 bfd_mach_o_load_command **mcommand,
2686 bfd_mach_o_section **msection)
2688 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
2689 unsigned int i, j, num;
2691 bfd_mach_o_load_command *ncmd = NULL;
2692 bfd_mach_o_section *nsect = NULL;
2694 BFD_ASSERT (mcommand != NULL);
2695 BFD_ASSERT (msection != NULL);
2697 num = 0;
2698 for (i = 0; i < md->header.ncmds; i++)
2700 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2701 struct bfd_mach_o_segment_command *seg = NULL;
2703 if (cmd->type != BFD_MACH_O_LC_SEGMENT
2704 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
2705 continue;
2706 seg = &cmd->command.segment;
2708 if (seg->segment == section)
2710 if (num == 0)
2711 ncmd = cmd;
2712 num++;
2715 for (j = 0; j < seg->nsects; j++)
2717 struct bfd_mach_o_section *sect = &seg->sections[j];
2719 if (sect->bfdsection == section)
2721 if (num == 0)
2722 nsect = sect;
2723 num++;
2728 *mcommand = ncmd;
2729 *msection = nsect;
2730 return num;
2734 bfd_mach_o_lookup_command (bfd *abfd,
2735 bfd_mach_o_load_command_type type,
2736 bfd_mach_o_load_command **mcommand)
2738 struct mach_o_data_struct *md = NULL;
2739 bfd_mach_o_load_command *ncmd = NULL;
2740 unsigned int i, num;
2742 md = abfd->tdata.mach_o_data;
2744 BFD_ASSERT (md != NULL);
2745 BFD_ASSERT (mcommand != NULL);
2747 num = 0;
2748 for (i = 0; i < md->header.ncmds; i++)
2750 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2752 if (cmd->type != type)
2753 continue;
2755 if (num == 0)
2756 ncmd = cmd;
2757 num++;
2760 *mcommand = ncmd;
2761 return num;
2764 unsigned long
2765 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
2767 switch (type)
2769 case BFD_MACH_O_CPU_TYPE_MC680x0:
2770 return 0x04000000;
2771 case BFD_MACH_O_CPU_TYPE_MC88000:
2772 return 0xffffe000;
2773 case BFD_MACH_O_CPU_TYPE_POWERPC:
2774 return 0xc0000000;
2775 case BFD_MACH_O_CPU_TYPE_I386:
2776 return 0xc0000000;
2777 case BFD_MACH_O_CPU_TYPE_SPARC:
2778 return 0xf0000000;
2779 case BFD_MACH_O_CPU_TYPE_I860:
2780 return 0;
2781 case BFD_MACH_O_CPU_TYPE_HPPA:
2782 return 0xc0000000 - 0x04000000;
2783 default:
2784 return 0;
2788 bfd_boolean
2789 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, PTR ptr)
2791 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2792 FILE *file = (FILE *) ptr;
2793 unsigned int i, j;
2794 unsigned int sec_nbr = 0;
2796 fprintf (file, _("Segments and Sections:\n"));
2797 fprintf (file, _(" #: Segment name Section name Address\n"));
2799 for (i = 0; i < mdata->header.ncmds; i++)
2801 bfd_mach_o_segment_command *seg;
2803 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
2804 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
2805 continue;
2807 seg = &mdata->commands[i].command.segment;
2809 fprintf (file, "[Segment %-16s ", seg->segname);
2810 fprintf_vma (file, seg->vmaddr);
2811 fprintf (file, "-");
2812 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
2813 fputc (' ', file);
2814 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
2815 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
2816 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
2817 fprintf (file, "]\n");
2818 for (j = 0; j < seg->nsects; j++)
2820 bfd_mach_o_section *sec = &seg->sections[j];
2821 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
2822 sec->segname, sec->sectname);
2823 fprintf_vma (file, sec->addr);
2824 fprintf (file, " ");
2825 fprintf_vma (file, sec->size);
2826 fprintf (file, " %08lx\n", sec->flags);
2830 for (i = 0; i < mdata->header.ncmds; i++)
2832 bfd_mach_o_load_command *cmd = &mdata->commands[i];
2834 switch (cmd->type)
2836 case BFD_MACH_O_LC_SEGMENT:
2837 case BFD_MACH_O_LC_SEGMENT_64:
2838 break;
2839 case BFD_MACH_O_LC_UUID:
2841 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
2842 unsigned int i;
2844 fprintf (file, "\n"
2845 "UUID:");
2846 for (i = 0; i < sizeof (uuid->uuid); i++)
2847 fprintf (file, " %02x", uuid->uuid[i]);
2848 fputc ('\n', file);
2850 break;
2851 case BFD_MACH_O_LC_LOAD_DYLIB:
2853 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
2854 bfd_byte *data = NULL;
2856 if (! bfd_malloc_and_get_section (abfd, dylib->section, &data))
2858 if (data != NULL)
2859 free (data);
2860 break;
2862 fprintf (file, "\n"
2863 "LOAD_DYLIB: %s\n",
2864 data + dylib->name_offset - cmd->offset - 8);
2865 fprintf (file, " time stamp: 0x%08lx\n",
2866 dylib->timestamp);
2867 fprintf (file, " current version: 0x%08lx\n",
2868 dylib->current_version);
2869 fprintf (file, " comptibility version: 0x%08lx\n",
2870 dylib->compatibility_version);
2871 free (data);
2872 break;
2874 case BFD_MACH_O_LC_LOAD_DYLINKER:
2876 bfd_mach_o_dylinker_command *linker = &cmd->command.dylinker;
2877 bfd_byte *data = NULL;
2879 if (! bfd_malloc_and_get_section (abfd, linker->section, &data))
2881 if (data != NULL)
2882 free (data);
2883 break;
2885 fprintf (file, "\n"
2886 "LOAD_DYLINKER: %s\n",
2887 data + linker->name_offset - cmd->offset - 8);
2888 free (data);
2889 break;
2891 case BFD_MACH_O_LC_SYMTAB:
2893 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
2894 fprintf (file, "\n"
2895 "LC_SYMTAB: nsyms: %u, strsize: %u\n",
2896 symtab->nsyms, symtab->strsize);
2897 break;
2899 case BFD_MACH_O_LC_DYSYMTAB:
2901 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
2902 fprintf (file, "\n"
2903 "LC_DYSYMTAB:\n"
2904 " local symbols: index: %lu number: %lu\n",
2905 dysymtab->ilocalsym, dysymtab->nlocalsym);
2906 fprintf (file,
2907 " external symbols: index: %lu number: %lu\n",
2908 dysymtab->iextdefsym, dysymtab->nextdefsym);
2909 fprintf (file,
2910 " undefined symbols: index: %lu number: %lu\n",
2911 dysymtab->iundefsym, dysymtab->nundefsym);
2912 fprintf (file,
2913 " ntoc: offset: %lu number: %lu\n",
2914 dysymtab->tocoff, dysymtab->ntoc);
2915 fprintf (file,
2916 " module table: offset: %lu number: %lu\n",
2917 dysymtab->modtaboff, dysymtab->nmodtab);
2918 break;
2920 default:
2921 fprintf (file, "LC_%d\n", cmd->type);
2922 break;
2926 return TRUE;
2930 bfd_mach_o_core_fetch_environment (bfd *abfd,
2931 unsigned char **rbuf,
2932 unsigned int *rlen)
2934 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2935 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2936 unsigned int i = 0;
2938 for (i = 0; i < mdata->header.ncmds; i++)
2940 bfd_mach_o_load_command *cur = &mdata->commands[i];
2941 bfd_mach_o_segment_command *seg = NULL;
2943 if (cur->type != BFD_MACH_O_LC_SEGMENT)
2944 continue;
2946 seg = &cur->command.segment;
2948 if ((seg->vmaddr + seg->vmsize) == stackaddr)
2950 unsigned long start = seg->fileoff;
2951 unsigned long end = seg->fileoff + seg->filesize;
2952 unsigned char *buf = bfd_malloc (1024);
2953 unsigned long size = 1024;
2955 for (;;)
2957 bfd_size_type nread = 0;
2958 unsigned long offset;
2959 int found_nonnull = 0;
2961 if (size > (end - start))
2962 size = (end - start);
2964 buf = bfd_realloc_or_free (buf, size);
2965 if (buf == NULL)
2966 return -1;
2968 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
2970 free (buf);
2971 return -1;
2974 nread = bfd_bread (buf, size, abfd);
2976 if (nread != size)
2978 free (buf);
2979 return -1;
2982 for (offset = 4; offset <= size; offset += 4)
2984 unsigned long val;
2986 val = *((unsigned long *) (buf + size - offset));
2987 if (! found_nonnull)
2989 if (val != 0)
2990 found_nonnull = 1;
2992 else if (val == 0x0)
2994 unsigned long bottom;
2995 unsigned long top;
2997 bottom = seg->fileoff + seg->filesize - offset;
2998 top = seg->fileoff + seg->filesize - 4;
2999 *rbuf = bfd_malloc (top - bottom);
3000 *rlen = top - bottom;
3002 memcpy (*rbuf, buf + size - *rlen, *rlen);
3003 free (buf);
3004 return 0;
3008 if (size == (end - start))
3009 break;
3011 size *= 2;
3014 free (buf);
3018 return -1;
3021 char *
3022 bfd_mach_o_core_file_failing_command (bfd *abfd)
3024 unsigned char *buf = NULL;
3025 unsigned int len = 0;
3026 int ret = -1;
3028 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
3029 if (ret < 0)
3030 return NULL;
3032 return (char *) buf;
3036 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3038 return 0;
3041 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
3042 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
3044 #define bfd_mach_o_swap_reloc_in NULL
3045 #define bfd_mach_o_swap_reloc_out NULL
3047 #define TARGET_NAME mach_o_be_vec
3048 #define TARGET_STRING "mach-o-be"
3049 #define TARGET_BIG_ENDIAN 1
3050 #define TARGET_ARCHIVE 0
3051 #include "mach-o-target.c"
3053 #undef TARGET_NAME
3054 #undef TARGET_STRING
3055 #undef TARGET_BIG_ENDIAN
3056 #undef TARGET_ARCHIVE
3058 #define TARGET_NAME mach_o_le_vec
3059 #define TARGET_STRING "mach-o-le"
3060 #define TARGET_BIG_ENDIAN 0
3061 #define TARGET_ARCHIVE 0
3063 #include "mach-o-target.c"
3065 #undef TARGET_NAME
3066 #undef TARGET_STRING
3067 #undef TARGET_BIG_ENDIAN
3068 #undef TARGET_ARCHIVE
3070 #define TARGET_NAME mach_o_fat_vec
3071 #define TARGET_STRING "mach-o-fat"
3072 #define TARGET_BIG_ENDIAN 1
3073 #define TARGET_ARCHIVE 1
3075 #include "mach-o-target.c"
3077 #undef TARGET_NAME
3078 #undef TARGET_STRING
3079 #undef TARGET_BIG_ENDIAN
3080 #undef TARGET_ARCHIVE