2009-06-05 Tristan Gingold <gingold@adacore.com>
[binutils.git] / bfd / mach-o.c
blob86f3dd145e62db80ac79a310db39faa3912b8b0b
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 static unsigned int
35 bfd_mach_o_version (bfd *abfd)
37 bfd_mach_o_data_struct *mdata = NULL;
39 BFD_ASSERT (bfd_mach_o_valid (abfd));
40 mdata = abfd->tdata.mach_o_data;
42 return mdata->header.version;
45 bfd_boolean
46 bfd_mach_o_valid (bfd *abfd)
48 if (abfd == NULL || abfd->xvec == NULL)
49 return FALSE;
51 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
52 return FALSE;
54 if (abfd->tdata.mach_o_data == NULL)
55 return FALSE;
56 return TRUE;
59 /* Tables to translate well known Mach-O segment/section names to bfd
60 names. Use of canonical names (such as .text or .debug_frame) is required
61 by gdb. */
63 struct mach_o_section_name_xlat
65 const char *bfd_name;
66 const char *mach_o_name;
69 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
71 { ".debug_frame", "__debug_frame" },
72 { ".debug_info", "__debug_info" },
73 { ".debug_abbrev", "__debug_abbrev" },
74 { ".debug_aranges", "__debug_aranges" },
75 { ".debug_macinfo", "__debug_macinfo" },
76 { ".debug_line", "__debug_line" },
77 { ".debug_loc", "__debug_loc" },
78 { ".debug_pubnames", "__debug_pubnames" },
79 { ".debug_pubtypes", "__debug_pubtypes" },
80 { ".debug_str", "__debug_str" },
81 { ".debug_ranges", "__debug_ranges" },
82 { NULL, NULL}
85 static const struct mach_o_section_name_xlat text_section_names_xlat[] =
87 { ".text", "__text" },
88 { ".cstring", "__cstring" },
89 { ".eh_frame", "__eh_frame" },
90 { NULL, NULL}
93 static const struct mach_o_section_name_xlat data_section_names_xlat[] =
95 { ".data", "__data" },
96 { ".bss", "__bss" },
97 { NULL, NULL}
100 struct mach_o_segment_name_xlat
102 const char *segname;
103 const struct mach_o_section_name_xlat *sections;
106 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
108 { "__DWARF", dwarf_section_names_xlat },
109 { "__TEXT", text_section_names_xlat },
110 { "__DATA", data_section_names_xlat },
111 { NULL, NULL }
115 /* Mach-O to bfd names. */
117 static char *
118 bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section)
120 const struct mach_o_segment_name_xlat *seg;
121 char *res;
122 unsigned int len;
124 for (seg = segsec_names_xlat; seg->segname; seg++)
126 if (strcmp (seg->segname, section->segname) == 0)
128 const struct mach_o_section_name_xlat *sec;
130 for (sec = seg->sections; sec->mach_o_name; sec++)
132 if (strcmp (sec->mach_o_name, section->sectname) == 0)
134 len = strlen (sec->bfd_name);
135 res = bfd_alloc (abfd, len + 1);
137 if (res == NULL)
138 return NULL;
139 strcpy (res, sec->bfd_name);
140 return res;
146 len = sizeof ("LC_SEGMENT") - 1 + 1
147 + strlen (section->segname) + 1
148 + strlen (section->sectname) + 1;
150 res = bfd_alloc (abfd, len);
151 if (res == NULL)
152 return NULL;
153 snprintf (res, len, "LC_SEGMENT.%s.%s", section->segname, section->sectname);
154 return res;
157 /* Convert a bfd sectio name to a Mach-O segment + section name. */
159 static void
160 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
161 asection *sect,
162 bfd_mach_o_section *section)
164 const struct mach_o_segment_name_xlat *seg;
165 const char *name = bfd_get_section_name (abfd, sect);
166 const char *dot;
167 unsigned int len;
168 unsigned int seglen;
169 unsigned int seclen;
171 /* List of well known names. */
172 for (seg = segsec_names_xlat; seg->segname; seg++)
174 const struct mach_o_section_name_xlat *sec;
176 for (sec = seg->sections; sec->mach_o_name; sec++)
178 if (strcmp (sec->bfd_name, name) == 0)
180 strcpy (section->segname, seg->segname);
181 strcpy (section->sectname, sec->mach_o_name);
182 return;
187 /* Strip LC_SEGMENT. prefix. */
188 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
189 name += 11;
191 /* Find a dot. */
192 dot = strchr (name, '.');
193 len = strlen (name);
195 /* Try to split name into segment and section names. */
196 if (dot && dot != name)
198 seglen = dot - name;
199 seclen = len - (dot + 1 - name);
201 if (seglen < 16 && seclen < 16)
203 memcpy (section->segname, name, seglen);
204 section->segname[seglen] = 0;
205 memcpy (section->sectname, dot + 1, seclen);
206 section->sectname[seclen] = 0;
207 return;
211 if (len > 16)
212 len = 16;
213 memcpy (section->segname, name, len);
214 section->segname[len] = 0;
215 memcpy (section->sectname, name, len);
216 section->sectname[len] = 0;
219 /* Copy any private info we understand from the input symbol
220 to the output symbol. */
222 bfd_boolean
223 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
224 asymbol *isymbol ATTRIBUTE_UNUSED,
225 bfd *obfd ATTRIBUTE_UNUSED,
226 asymbol *osymbol ATTRIBUTE_UNUSED)
228 return TRUE;
231 /* Copy any private info we understand from the input section
232 to the output section. */
234 bfd_boolean
235 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
236 asection *isection ATTRIBUTE_UNUSED,
237 bfd *obfd ATTRIBUTE_UNUSED,
238 asection *osection ATTRIBUTE_UNUSED)
240 return TRUE;
243 /* Copy any private info we understand from the input bfd
244 to the output bfd. */
246 bfd_boolean
247 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
249 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
250 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
251 return TRUE;
253 BFD_ASSERT (bfd_mach_o_valid (ibfd));
254 BFD_ASSERT (bfd_mach_o_valid (obfd));
256 /* FIXME: copy commands. */
258 return TRUE;
261 /* Count the total number of symbols. Traverse all sections. */
263 static long
264 bfd_mach_o_count_symbols (bfd *abfd)
266 bfd_mach_o_data_struct *mdata = NULL;
267 long nsyms = 0;
268 unsigned long i;
270 BFD_ASSERT (bfd_mach_o_valid (abfd));
271 mdata = abfd->tdata.mach_o_data;
273 for (i = 0; i < mdata->header.ncmds; i++)
274 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
276 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
277 nsyms += sym->nsyms;
280 return nsyms;
283 long
284 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
286 long nsyms = bfd_mach_o_count_symbols (abfd);
288 if (nsyms < 0)
289 return nsyms;
291 return ((nsyms + 1) * sizeof (asymbol *));
294 long
295 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
297 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
298 long nsyms = bfd_mach_o_count_symbols (abfd);
299 asymbol **csym = alocation;
300 unsigned long i, j;
302 if (nsyms < 0)
303 return nsyms;
305 for (i = 0; i < mdata->header.ncmds; i++)
307 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
309 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
311 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
313 fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
314 return 0;
317 BFD_ASSERT (sym->symbols != NULL);
319 for (j = 0; j < sym->nsyms; j++)
321 BFD_ASSERT (csym < (alocation + nsyms));
322 *csym++ = &sym->symbols[j];
327 *csym++ = NULL;
329 return nsyms;
332 void
333 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
334 asymbol *symbol,
335 symbol_info *ret)
337 bfd_symbol_info (symbol, ret);
340 void
341 bfd_mach_o_print_symbol (bfd *abfd,
342 PTR afile,
343 asymbol *symbol,
344 bfd_print_symbol_type how)
346 FILE *file = (FILE *) afile;
347 unsigned char ntype;
348 unsigned char nsect;
349 unsigned int ndesc;
350 const char *name;
352 switch (how)
354 case bfd_print_symbol_name:
355 fprintf (file, "%s", symbol->name);
356 break;
357 default:
358 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
359 ntype = BFD_MACH_O_SYM_NTYPE (symbol);
360 nsect = BFD_MACH_O_SYM_NSECT (symbol);
361 ndesc = BFD_MACH_O_SYM_NDESC (symbol);
362 if (ntype & BFD_MACH_O_N_STAB)
363 name = bfd_get_stab_name (ntype);
364 else
365 switch (ntype & BFD_MACH_O_N_TYPE)
367 case BFD_MACH_O_N_UNDF:
368 name = "UND";
369 break;
370 case BFD_MACH_O_N_ABS:
371 name = "ABS";
372 break;
373 case BFD_MACH_O_N_INDR:
374 name = "INDR";
375 break;
376 case BFD_MACH_O_N_PBUD:
377 name = "PBUD";
378 break;
379 case BFD_MACH_O_N_SECT:
380 name = "SECT";
381 break;
382 default:
383 name = "???";
384 break;
386 if (name == NULL)
387 name = "";
388 fprintf (file, " %02x %-6s %02x %04x", ntype, name, nsect, ndesc);
389 if ((ntype & BFD_MACH_O_N_STAB) == 0
390 && (ntype & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
391 fprintf (file, " %-5s", symbol->section->name);
392 fprintf (file, " %s", symbol->name);
396 static void
397 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
398 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
399 enum bfd_architecture *type,
400 unsigned long *subtype)
402 *subtype = bfd_arch_unknown;
404 switch (mtype)
406 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
407 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
408 case BFD_MACH_O_CPU_TYPE_I386:
409 *type = bfd_arch_i386;
410 *subtype = bfd_mach_i386_i386;
411 break;
412 case BFD_MACH_O_CPU_TYPE_X86_64:
413 *type = bfd_arch_i386;
414 *subtype = bfd_mach_x86_64;
415 break;
416 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
417 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
418 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
419 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
420 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
421 case BFD_MACH_O_CPU_TYPE_SPARC:
422 *type = bfd_arch_sparc;
423 *subtype = bfd_mach_sparc;
424 break;
425 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
426 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
427 case BFD_MACH_O_CPU_TYPE_POWERPC:
428 *type = bfd_arch_powerpc;
429 *subtype = bfd_mach_ppc;
430 break;
431 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
432 *type = bfd_arch_powerpc;
433 *subtype = bfd_mach_ppc64;
434 break;
435 default:
436 *type = bfd_arch_unknown;
437 break;
441 static bfd_boolean
442 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
444 unsigned char buf[32];
445 unsigned int size;
447 size = (header->version == 2) ?
448 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
450 bfd_h_put_32 (abfd, header->magic, buf + 0);
451 bfd_h_put_32 (abfd, header->cputype, buf + 4);
452 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
453 bfd_h_put_32 (abfd, header->filetype, buf + 12);
454 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
455 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
456 bfd_h_put_32 (abfd, header->flags, buf + 24);
458 if (header->version == 2)
459 bfd_h_put_32 (abfd, header->reserved, buf + 28);
461 bfd_seek (abfd, 0, SEEK_SET);
462 if (bfd_bwrite ((PTR) buf, size, abfd) != size)
463 return FALSE;
465 return TRUE;
468 static int
469 bfd_mach_o_scan_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
471 bfd_mach_o_thread_command *cmd = &command->command.thread;
472 unsigned int i;
473 unsigned char buf[8];
474 bfd_vma offset;
475 unsigned int nflavours;
477 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
478 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
480 offset = 8;
481 nflavours = 0;
482 for (i = 0; i < cmd->nflavours; i++)
484 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
485 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
487 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
488 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
490 bfd_seek (abfd, command->offset + offset, SEEK_SET);
491 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
492 return -1;
494 offset += cmd->flavours[i].size + 8;
497 return 0;
500 static int
501 bfd_mach_o_scan_write_section_32 (bfd *abfd,
502 bfd_mach_o_section *section,
503 bfd_vma offset)
505 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
507 memcpy (buf, section->sectname, 16);
508 memcpy (buf + 16, section->segname, 16);
509 bfd_h_put_32 (abfd, section->addr, buf + 32);
510 bfd_h_put_32 (abfd, section->size, buf + 36);
511 bfd_h_put_32 (abfd, section->offset, buf + 40);
512 bfd_h_put_32 (abfd, section->align, buf + 44);
513 bfd_h_put_32 (abfd, section->reloff, buf + 48);
514 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
515 bfd_h_put_32 (abfd, section->flags, buf + 56);
516 bfd_h_put_32 (abfd, section->reserved1, buf + 60);
517 bfd_h_put_32 (abfd, section->reserved2, buf + 64);
519 bfd_seek (abfd, offset, SEEK_SET);
520 if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
521 != BFD_MACH_O_SECTION_SIZE)
522 return -1;
524 return 0;
527 static int
528 bfd_mach_o_scan_write_section_64 (bfd *abfd,
529 bfd_mach_o_section *section,
530 bfd_vma offset)
532 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
534 memcpy (buf, section->sectname, 16);
535 memcpy (buf + 16, section->segname, 16);
536 bfd_h_put_64 (abfd, section->addr, buf + 32);
537 bfd_h_put_64 (abfd, section->size, buf + 40);
538 bfd_h_put_32 (abfd, section->offset, buf + 48);
539 bfd_h_put_32 (abfd, section->align, buf + 52);
540 bfd_h_put_32 (abfd, section->reloff, buf + 56);
541 bfd_h_put_32 (abfd, section->nreloc, buf + 60);
542 bfd_h_put_32 (abfd, section->flags, buf + 64);
543 bfd_h_put_32 (abfd, section->reserved1, buf + 68);
544 bfd_h_put_32 (abfd, section->reserved2, buf + 72);
545 bfd_h_put_32 (abfd, section->reserved3, buf + 76);
547 bfd_seek (abfd, offset, SEEK_SET);
548 if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
549 != BFD_MACH_O_SECTION_64_SIZE)
550 return -1;
552 return 0;
555 static int
556 bfd_mach_o_scan_write_section (bfd *abfd,
557 bfd_mach_o_section *section,
558 bfd_vma offset,
559 unsigned int wide)
561 if (wide)
562 return bfd_mach_o_scan_write_section_64 (abfd, section, offset);
563 else
564 return bfd_mach_o_scan_write_section_32 (abfd, section, offset);
567 static int
568 bfd_mach_o_scan_write_segment (bfd *abfd,
569 bfd_mach_o_load_command *command,
570 unsigned int wide)
572 unsigned char buf[64];
573 bfd_mach_o_segment_command *seg = &command->command.segment;
574 unsigned long i;
576 if (wide)
578 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
580 memcpy (buf, seg->segname, 16);
582 bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
583 bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
584 bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
585 bfd_h_put_64 (abfd, seg->filesize, buf + 40);
586 bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
587 bfd_h_put_32 (abfd, seg->initprot, buf + 52);
588 bfd_h_put_32 (abfd, seg->nsects, buf + 56);
589 bfd_h_put_32 (abfd, seg->flags, buf + 60);
591 bfd_seek (abfd, command->offset + 8, SEEK_SET);
592 if (bfd_bwrite ((PTR) buf, 64, abfd) != 64)
593 return -1;
595 else
597 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
599 memcpy (buf, seg->segname, 16);
601 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
602 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
603 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
604 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
605 bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
606 bfd_h_put_32 (abfd, seg->initprot, buf + 36);
607 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
608 bfd_h_put_32 (abfd, seg->flags, buf + 44);
610 bfd_seek (abfd, command->offset + 8, SEEK_SET);
611 if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
612 return -1;
615 for (i = 0; i < seg->nsects; i++)
617 bfd_vma segoff;
618 if (wide)
619 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
620 + (i * BFD_MACH_O_SECTION_64_SIZE);
621 else
622 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
623 + (i * BFD_MACH_O_SECTION_SIZE);
625 if (bfd_mach_o_scan_write_section
626 (abfd, &seg->sections[i], segoff, wide) != 0)
627 return -1;
630 return 0;
633 static int
634 bfd_mach_o_scan_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
636 return bfd_mach_o_scan_write_segment (abfd, command, 0);
639 static int
640 bfd_mach_o_scan_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
642 return bfd_mach_o_scan_write_segment (abfd, command, 1);
645 static int
646 bfd_mach_o_scan_write_symtab_symbols (bfd *abfd, bfd_mach_o_load_command *command)
648 bfd_mach_o_symtab_command *sym = &command->command.symtab;
649 asymbol *s = NULL;
650 unsigned long i;
652 for (i = 0; i < sym->nsyms; i++)
654 unsigned char buf[12];
655 bfd_vma symoff = sym->symoff + (i * 12);
656 unsigned char ntype = 0;
657 unsigned char nsect = 0;
658 short ndesc = 0;
660 s = &sym->symbols[i];
662 /* Instead just set from the stored values. */
663 ntype = BFD_MACH_O_SYM_NTYPE (s);
664 nsect = BFD_MACH_O_SYM_NSECT (s);
665 ndesc = BFD_MACH_O_SYM_NDESC (s);
667 bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
668 bfd_h_put_8 (abfd, ntype, buf + 4);
669 bfd_h_put_8 (abfd, nsect, buf + 5);
670 bfd_h_put_16 (abfd, ndesc, buf + 6);
671 bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
673 bfd_seek (abfd, symoff, SEEK_SET);
674 if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
676 fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
677 12, (unsigned long) symoff);
678 return -1;
682 return 0;
685 static int
686 bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
688 bfd_mach_o_symtab_command *seg = &command->command.symtab;
689 unsigned char buf[16];
691 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
693 bfd_h_put_32 (abfd, seg->symoff, buf);
694 bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
695 bfd_h_put_32 (abfd, seg->stroff, buf + 8);
696 bfd_h_put_32 (abfd, seg->strsize, buf + 12);
698 bfd_seek (abfd, command->offset + 8, SEEK_SET);
699 if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
700 return -1;
702 if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
703 return -1;
705 return 0;
708 bfd_boolean
709 bfd_mach_o_write_contents (bfd *abfd)
711 unsigned int i;
712 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
714 /* Now write header information. */
715 if (!bfd_mach_o_write_header (abfd, &mdata->header))
716 return FALSE;
718 for (i = 0; i < mdata->header.ncmds; i++)
720 unsigned char buf[8];
721 bfd_mach_o_load_command *cur = &mdata->commands[i];
722 unsigned long typeflag;
724 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
726 bfd_h_put_32 (abfd, typeflag, buf);
727 bfd_h_put_32 (abfd, cur->len, buf + 4);
729 bfd_seek (abfd, cur->offset, SEEK_SET);
730 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
731 return FALSE;
733 switch (cur->type)
735 case BFD_MACH_O_LC_SEGMENT:
736 if (bfd_mach_o_scan_write_segment_32 (abfd, cur) != 0)
737 return FALSE;
738 break;
739 case BFD_MACH_O_LC_SEGMENT_64:
740 if (bfd_mach_o_scan_write_segment_64 (abfd, cur) != 0)
741 return FALSE;
742 break;
743 case BFD_MACH_O_LC_SYMTAB:
744 if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
745 return FALSE;
746 break;
747 case BFD_MACH_O_LC_SYMSEG:
748 break;
749 case BFD_MACH_O_LC_THREAD:
750 case BFD_MACH_O_LC_UNIXTHREAD:
751 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
752 return FALSE;
753 break;
754 case BFD_MACH_O_LC_LOADFVMLIB:
755 case BFD_MACH_O_LC_IDFVMLIB:
756 case BFD_MACH_O_LC_IDENT:
757 case BFD_MACH_O_LC_FVMFILE:
758 case BFD_MACH_O_LC_PREPAGE:
759 case BFD_MACH_O_LC_DYSYMTAB:
760 case BFD_MACH_O_LC_LOAD_DYLIB:
761 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
762 case BFD_MACH_O_LC_ID_DYLIB:
763 case BFD_MACH_O_LC_LOAD_DYLINKER:
764 case BFD_MACH_O_LC_ID_DYLINKER:
765 case BFD_MACH_O_LC_PREBOUND_DYLIB:
766 case BFD_MACH_O_LC_ROUTINES:
767 case BFD_MACH_O_LC_SUB_FRAMEWORK:
768 break;
769 default:
770 fprintf (stderr,
771 "unable to write unknown load command 0x%lx\n",
772 (unsigned long) cur->type);
773 return FALSE;
777 return TRUE;
780 /* Build Mach-O load commands from the sections. */
782 bfd_boolean
783 bfd_mach_o_build_commands (bfd *abfd)
785 bfd_mach_o_data_struct *mdata = bfd_get_mach_o_data (abfd);
786 unsigned int wide = (mdata->header.version == 2);
787 bfd_mach_o_segment_command *seg;
788 bfd_mach_o_section *sections;
789 asection *sec;
790 file_ptr filepos;
792 /* Return now if commands are already built. */
793 if (mdata->header.ncmds)
794 return FALSE;
796 /* Very simple version: 1 command (segment) containing all sections. */
797 mdata->header.ncmds = 1;
798 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
799 * sizeof (bfd_mach_o_load_command));
800 if (mdata->commands == NULL)
801 return FALSE;
802 seg = &mdata->commands[0].command.segment;
803 seg->nsects = bfd_count_sections (abfd);
804 sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
805 if (sections == NULL)
806 return FALSE;
807 seg->sections = sections;
809 /* Set segment command. */
810 if (wide)
812 mdata->commands[0].type = BFD_MACH_O_LC_SEGMENT_64;
813 mdata->commands[0].offset = BFD_MACH_O_HEADER_64_SIZE;
814 mdata->commands[0].len = BFD_MACH_O_LC_SEGMENT_64_SIZE
815 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
817 else
819 mdata->commands[0].type = BFD_MACH_O_LC_SEGMENT;
820 mdata->commands[0].offset = BFD_MACH_O_HEADER_SIZE;
821 mdata->commands[0].len = BFD_MACH_O_LC_SEGMENT_SIZE
822 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
824 mdata->commands[0].type_required = FALSE;
825 mdata->header.sizeofcmds = mdata->commands[0].len;
827 filepos = mdata->commands[0].offset + mdata->commands[0].len;
829 memset (seg->segname, 0, sizeof (seg->segname));
830 seg->vmaddr = 0;
831 seg->fileoff = filepos;
832 seg->filesize = 0;
833 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
834 | BFD_MACH_O_PROT_EXECUTE;
835 seg->initprot = seg->maxprot;
836 seg->flags = 0;
838 /* Create Mach-O sections. */
839 for (sec = abfd->sections; sec; sec = sec->next)
841 sections->bfdsection = sec;
842 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
843 sections->addr = bfd_get_section_vma (abfd, sec);
844 sections->size = bfd_get_section_size (sec);
845 sections->align = bfd_get_section_alignment (abfd, sec);
847 filepos = (filepos + ((file_ptr) 1 << sections->align) - 1)
848 & ((file_ptr) -1 << sections->align);
849 sections->offset = filepos;
850 sections->reloff = 0;
851 sections->nreloc = 0;
852 sections->reserved1 = 0;
853 sections->reserved2 = 0;
854 sections->reserved3 = 0;
856 sec->filepos = filepos;
858 filepos += sections->size;
859 sections++;
861 seg->filesize = filepos - seg->fileoff;
862 seg->vmsize = seg->filesize;
864 return TRUE;
867 /* Set the contents of a section. */
869 bfd_boolean
870 bfd_mach_o_set_section_contents (bfd *abfd,
871 asection *section,
872 const void * location,
873 file_ptr offset,
874 bfd_size_type count)
876 file_ptr pos;
878 /* This must be done first, because bfd_set_section_contents is
879 going to set output_has_begun to TRUE. */
880 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
881 return FALSE;
883 if (count == 0)
884 return TRUE;
886 pos = section->filepos + offset;
887 if (bfd_seek (abfd, pos, SEEK_SET) != 0
888 || bfd_bwrite (location, count, abfd) != count)
889 return FALSE;
891 return TRUE;
895 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
896 struct bfd_link_info *info ATTRIBUTE_UNUSED)
898 return 0;
901 /* Make an empty symbol. This is required only because
902 bfd_make_section_anyway wants to create a symbol for the section. */
904 asymbol *
905 bfd_mach_o_make_empty_symbol (bfd *abfd)
907 asymbol *new;
909 new = bfd_zalloc (abfd, sizeof (* new));
910 if (new == NULL)
911 return new;
912 new->the_bfd = abfd;
913 return new;
916 static bfd_boolean
917 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
919 unsigned char buf[32];
920 unsigned int size;
921 bfd_vma (*get32) (const void *) = NULL;
923 /* Just read the magic number. */
924 bfd_seek (abfd, 0, SEEK_SET);
925 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
926 return FALSE;
928 if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
930 header->byteorder = BFD_ENDIAN_BIG;
931 header->magic = BFD_MACH_O_MH_MAGIC;
932 header->version = 1;
933 get32 = bfd_getb32;
935 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
937 header->byteorder = BFD_ENDIAN_LITTLE;
938 header->magic = BFD_MACH_O_MH_MAGIC;
939 header->version = 1;
940 get32 = bfd_getl32;
942 else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
944 header->byteorder = BFD_ENDIAN_BIG;
945 header->magic = BFD_MACH_O_MH_MAGIC_64;
946 header->version = 2;
947 get32 = bfd_getb32;
949 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
951 header->byteorder = BFD_ENDIAN_LITTLE;
952 header->magic = BFD_MACH_O_MH_MAGIC_64;
953 header->version = 2;
954 get32 = bfd_getl32;
956 else
958 header->byteorder = BFD_ENDIAN_UNKNOWN;
959 return FALSE;
962 /* Once the size of the header is known, read the full header. */
963 size = (header->version == 2) ?
964 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
966 bfd_seek (abfd, 0, SEEK_SET);
967 if (bfd_bread ((PTR) buf, size, abfd) != size)
968 return FALSE;
970 header->cputype = (*get32) (buf + 4);
971 header->cpusubtype = (*get32) (buf + 8);
972 header->filetype = (*get32) (buf + 12);
973 header->ncmds = (*get32) (buf + 16);
974 header->sizeofcmds = (*get32) (buf + 20);
975 header->flags = (*get32) (buf + 24);
977 if (header->version == 2)
978 header->reserved = (*get32) (buf + 28);
980 return TRUE;
983 static asection *
984 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
985 unsigned long prot)
987 asection *bfdsec;
988 char *sname;
989 flagword flags;
991 sname = bfd_mach_o_convert_section_name_to_bfd (abfd, section);
992 if (sname == NULL)
993 return NULL;
995 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
996 flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
997 else
999 flags = SEC_ALLOC;
1000 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1001 != BFD_MACH_O_S_ZEROFILL)
1003 flags |= SEC_HAS_CONTENTS | SEC_LOAD;
1004 if (prot & BFD_MACH_O_PROT_EXECUTE)
1005 flags |= SEC_CODE;
1006 if (prot & BFD_MACH_O_PROT_WRITE)
1007 flags |= SEC_DATA;
1008 else if (prot & BFD_MACH_O_PROT_READ)
1009 flags |= SEC_READONLY;
1012 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
1013 if (bfdsec == NULL)
1014 return NULL;
1016 bfdsec->vma = section->addr;
1017 bfdsec->lma = section->addr;
1018 bfdsec->size = section->size;
1019 bfdsec->filepos = section->offset;
1020 bfdsec->alignment_power = section->align;
1021 bfdsec->segment_mark = 0;
1023 return bfdsec;
1026 static int
1027 bfd_mach_o_scan_read_section_32 (bfd *abfd,
1028 bfd_mach_o_section *section,
1029 bfd_vma offset,
1030 unsigned long prot)
1032 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
1034 bfd_seek (abfd, offset, SEEK_SET);
1035 if (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
1036 != BFD_MACH_O_SECTION_SIZE)
1037 return -1;
1039 memcpy (section->sectname, buf, 16);
1040 section->sectname[16] = '\0';
1041 memcpy (section->segname, buf + 16, 16);
1042 section->segname[16] = '\0';
1043 section->addr = bfd_h_get_32 (abfd, buf + 32);
1044 section->size = bfd_h_get_32 (abfd, buf + 36);
1045 section->offset = bfd_h_get_32 (abfd, buf + 40);
1046 section->align = bfd_h_get_32 (abfd, buf + 44);
1047 section->reloff = bfd_h_get_32 (abfd, buf + 48);
1048 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
1049 section->flags = bfd_h_get_32 (abfd, buf + 56);
1050 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
1051 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
1052 section->reserved3 = 0;
1053 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1055 if (section->bfdsection == NULL)
1056 return -1;
1058 return 0;
1061 static int
1062 bfd_mach_o_scan_read_section_64 (bfd *abfd,
1063 bfd_mach_o_section *section,
1064 bfd_vma offset,
1065 unsigned long prot)
1067 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
1069 bfd_seek (abfd, offset, SEEK_SET);
1070 if (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
1071 != BFD_MACH_O_SECTION_64_SIZE)
1072 return -1;
1074 memcpy (section->sectname, buf, 16);
1075 section->sectname[16] = '\0';
1076 memcpy (section->segname, buf + 16, 16);
1077 section->segname[16] = '\0';
1078 section->addr = bfd_h_get_64 (abfd, buf + 32);
1079 section->size = bfd_h_get_64 (abfd, buf + 40);
1080 section->offset = bfd_h_get_32 (abfd, buf + 48);
1081 section->align = bfd_h_get_32 (abfd, buf + 52);
1082 section->reloff = bfd_h_get_32 (abfd, buf + 56);
1083 section->nreloc = bfd_h_get_32 (abfd, buf + 60);
1084 section->flags = bfd_h_get_32 (abfd, buf + 64);
1085 section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
1086 section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
1087 section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
1088 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1090 if (section->bfdsection == NULL)
1091 return -1;
1093 return 0;
1096 static int
1097 bfd_mach_o_scan_read_section (bfd *abfd,
1098 bfd_mach_o_section *section,
1099 bfd_vma offset,
1100 unsigned long prot,
1101 unsigned int wide)
1103 if (wide)
1104 return bfd_mach_o_scan_read_section_64 (abfd, section, offset, prot);
1105 else
1106 return bfd_mach_o_scan_read_section_32 (abfd, section, offset, prot);
1110 bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
1111 bfd_mach_o_symtab_command *sym,
1112 asymbol *s,
1113 unsigned long i)
1115 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1116 unsigned int wide = (mdata->header.version == 2);
1117 unsigned int symwidth = wide ? 16 : 12;
1118 bfd_vma symoff = sym->symoff + (i * symwidth);
1119 unsigned char buf[16];
1120 unsigned char type = -1;
1121 unsigned char section = -1;
1122 short desc = -1;
1123 symvalue value = -1;
1124 unsigned long stroff = -1;
1125 unsigned int symtype = -1;
1127 BFD_ASSERT (sym->strtab != NULL);
1129 bfd_seek (abfd, symoff, SEEK_SET);
1130 if (bfd_bread ((PTR) buf, symwidth, abfd) != symwidth)
1132 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
1133 symwidth, (unsigned long) symoff);
1134 return -1;
1137 stroff = bfd_h_get_32 (abfd, buf);
1138 type = bfd_h_get_8 (abfd, buf + 4);
1139 symtype = (type & 0x0e);
1140 section = bfd_h_get_8 (abfd, buf + 5);
1141 desc = bfd_h_get_16 (abfd, buf + 6);
1142 if (wide)
1143 value = bfd_h_get_64 (abfd, buf + 8);
1144 else
1145 value = bfd_h_get_32 (abfd, buf + 8);
1147 if (stroff >= sym->strsize)
1149 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
1150 (unsigned long) stroff, (unsigned long) sym->strsize);
1151 return -1;
1154 s->the_bfd = abfd;
1155 s->name = sym->strtab + stroff;
1156 s->value = value;
1157 s->udata.i = (type << 24) | (section << 16) | desc;
1158 s->flags = 0x0;
1160 if (type & BFD_MACH_O_N_STAB)
1162 s->flags |= BSF_DEBUGGING;
1163 s->section = bfd_und_section_ptr;
1164 switch (type)
1166 case N_FUN:
1167 case N_STSYM:
1168 case N_LCSYM:
1169 case N_BNSYM:
1170 case N_SLINE:
1171 case N_ENSYM:
1172 case N_ECOMM:
1173 case N_ECOML:
1174 case N_GSYM:
1175 if ((section > 0) && (section <= mdata->nsects))
1177 s->section = mdata->sections[section - 1]->bfdsection;
1178 s->value = s->value - mdata->sections[section - 1]->addr;
1180 break;
1183 else
1185 if (type & BFD_MACH_O_N_PEXT)
1186 s->flags |= BSF_GLOBAL;
1188 if (type & BFD_MACH_O_N_EXT)
1189 s->flags |= BSF_GLOBAL;
1191 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1192 s->flags |= BSF_LOCAL;
1194 switch (symtype)
1196 case BFD_MACH_O_N_UNDF:
1197 s->section = bfd_und_section_ptr;
1198 break;
1199 case BFD_MACH_O_N_PBUD:
1200 s->section = bfd_und_section_ptr;
1201 break;
1202 case BFD_MACH_O_N_ABS:
1203 s->section = bfd_abs_section_ptr;
1204 break;
1205 case BFD_MACH_O_N_SECT:
1206 if ((section > 0) && (section <= mdata->nsects))
1208 s->section = mdata->sections[section - 1]->bfdsection;
1209 s->value = s->value - mdata->sections[section - 1]->addr;
1211 else
1213 /* Mach-O uses 0 to mean "no section"; not an error. */
1214 if (section != 0)
1216 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1217 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
1218 s->name, section, mdata->nsects);
1220 s->section = bfd_und_section_ptr;
1222 break;
1223 case BFD_MACH_O_N_INDR:
1224 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1225 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
1226 s->name);
1227 s->section = bfd_und_section_ptr;
1228 break;
1229 default:
1230 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
1231 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
1232 s->name, symtype);
1233 s->section = bfd_und_section_ptr;
1234 break;
1238 return 0;
1242 bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
1243 bfd_mach_o_symtab_command *sym)
1245 BFD_ASSERT (sym->strtab == NULL);
1247 if (abfd->flags & BFD_IN_MEMORY)
1249 struct bfd_in_memory *b;
1251 b = (struct bfd_in_memory *) abfd->iostream;
1253 if ((sym->stroff + sym->strsize) > b->size)
1255 bfd_set_error (bfd_error_file_truncated);
1256 return -1;
1258 sym->strtab = (char *) b->buffer + sym->stroff;
1259 return 0;
1262 sym->strtab = bfd_alloc (abfd, sym->strsize);
1263 if (sym->strtab == NULL)
1264 return -1;
1266 bfd_seek (abfd, sym->stroff, SEEK_SET);
1267 if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
1269 fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
1270 sym->strsize, sym->stroff);
1271 return -1;
1274 return 0;
1278 bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
1279 bfd_mach_o_symtab_command *sym)
1281 unsigned long i;
1282 int ret;
1284 BFD_ASSERT (sym->symbols == NULL);
1285 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
1287 if (sym->symbols == NULL)
1289 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
1290 return -1;
1293 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
1294 if (ret != 0)
1295 return ret;
1297 for (i = 0; i < sym->nsyms; i++)
1299 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1300 if (ret != 0)
1301 return ret;
1304 return 0;
1308 bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
1309 bfd_mach_o_dysymtab_command *dysym,
1310 bfd_mach_o_symtab_command *sym,
1311 asymbol *s,
1312 unsigned long i)
1314 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1315 unsigned long symindex;
1316 unsigned char buf[4];
1318 BFD_ASSERT (i < dysym->nindirectsyms);
1320 bfd_seek (abfd, isymoff, SEEK_SET);
1321 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
1323 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
1324 (unsigned long) 4, isymoff);
1325 return -1;
1327 symindex = bfd_h_get_32 (abfd, buf);
1329 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
1332 static const char *
1333 bfd_mach_o_i386_flavour_string (unsigned int flavour)
1335 switch ((int) flavour)
1337 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
1338 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
1339 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1340 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
1341 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
1342 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1343 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
1344 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
1345 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
1346 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
1347 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
1348 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
1349 case BFD_MACH_O_THREAD_STATE_NONE: return "THREAD_STATE_NONE";
1350 default: return "UNKNOWN";
1354 static const char *
1355 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
1357 switch ((int) flavour)
1359 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1360 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1361 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1362 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1363 default: return "UNKNOWN";
1367 static int
1368 bfd_mach_o_scan_read_dylinker (bfd *abfd,
1369 bfd_mach_o_load_command *command)
1371 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1372 unsigned char buf[4];
1373 unsigned int nameoff;
1374 asection *bfdsec;
1375 char *sname;
1376 const char *prefix;
1378 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1379 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1381 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1382 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
1383 return -1;
1385 nameoff = bfd_h_get_32 (abfd, buf + 0);
1387 cmd->name_offset = command->offset + nameoff;
1388 cmd->name_len = command->len - nameoff;
1390 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
1391 prefix = "LC_LOAD_DYLINKER";
1392 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
1393 prefix = "LC_ID_DYLINKER";
1394 else
1395 abort ();
1397 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1398 if (sname == NULL)
1399 return -1;
1400 strcpy (sname, prefix);
1402 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1403 if (bfdsec == NULL)
1404 return -1;
1406 bfdsec->vma = 0;
1407 bfdsec->lma = 0;
1408 bfdsec->size = command->len - nameoff;
1409 bfdsec->filepos = command->offset + nameoff;
1410 bfdsec->alignment_power = 0;
1412 cmd->section = bfdsec;
1414 return 0;
1417 static int
1418 bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
1420 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1421 unsigned char buf[16];
1422 unsigned int nameoff;
1423 asection *bfdsec;
1424 char *sname;
1425 const char *prefix;
1427 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1428 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1429 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1431 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1432 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1433 return -1;
1435 nameoff = bfd_h_get_32 (abfd, buf + 0);
1436 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1437 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1438 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1440 cmd->name_offset = command->offset + nameoff;
1441 cmd->name_len = command->len - nameoff;
1443 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1444 prefix = "LC_LOAD_DYLIB";
1445 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1446 prefix = "LC_LOAD_WEAK_DYLIB";
1447 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1448 prefix = "LC_ID_DYLIB";
1449 else
1450 abort ();
1452 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1453 if (sname == NULL)
1454 return -1;
1455 strcpy (sname, prefix);
1457 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1458 if (bfdsec == NULL)
1459 return -1;
1461 bfdsec->vma = 0;
1462 bfdsec->lma = 0;
1463 bfdsec->size = command->len - 8;
1464 bfdsec->filepos = command->offset + 8;
1465 bfdsec->alignment_power = 0;
1467 cmd->section = bfdsec;
1469 return 0;
1472 static int
1473 bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1474 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1476 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1478 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1479 return 0;
1482 static int
1483 bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1485 bfd_mach_o_data_struct *mdata = NULL;
1486 bfd_mach_o_thread_command *cmd = &command->command.thread;
1487 unsigned char buf[8];
1488 bfd_vma offset;
1489 unsigned int nflavours;
1490 unsigned int i;
1492 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1493 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1495 BFD_ASSERT (bfd_mach_o_valid (abfd));
1496 mdata = abfd->tdata.mach_o_data;
1498 offset = 8;
1499 nflavours = 0;
1500 while (offset != command->len)
1502 if (offset >= command->len)
1503 return -1;
1505 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1507 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1508 return -1;
1510 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1511 nflavours++;
1514 cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
1515 if (cmd->flavours == NULL)
1516 return -1;
1517 cmd->nflavours = nflavours;
1519 offset = 8;
1520 nflavours = 0;
1521 while (offset != command->len)
1523 if (offset >= command->len)
1524 return -1;
1526 if (nflavours >= cmd->nflavours)
1527 return -1;
1529 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1531 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1532 return -1;
1534 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1535 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1536 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1537 offset += cmd->flavours[nflavours].size + 8;
1538 nflavours++;
1541 for (i = 0; i < nflavours; i++)
1543 asection *bfdsec;
1544 unsigned int snamelen;
1545 char *sname;
1546 const char *flavourstr;
1547 const char *prefix = "LC_THREAD";
1548 unsigned int j = 0;
1550 switch (mdata->header.cputype)
1552 case BFD_MACH_O_CPU_TYPE_POWERPC:
1553 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
1554 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1555 break;
1556 case BFD_MACH_O_CPU_TYPE_I386:
1557 case BFD_MACH_O_CPU_TYPE_X86_64:
1558 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1559 break;
1560 default:
1561 flavourstr = "UNKNOWN_ARCHITECTURE";
1562 break;
1565 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1566 sname = bfd_alloc (abfd, snamelen);
1567 if (sname == NULL)
1568 return -1;
1570 for (;;)
1572 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1573 if (bfd_get_section_by_name (abfd, sname) == NULL)
1574 break;
1575 j++;
1578 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1580 bfdsec->vma = 0;
1581 bfdsec->lma = 0;
1582 bfdsec->size = cmd->flavours[i].size;
1583 bfdsec->filepos = cmd->flavours[i].offset;
1584 bfdsec->alignment_power = 0x0;
1586 cmd->section = bfdsec;
1589 return 0;
1592 static int
1593 bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1595 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1596 unsigned char buf[72];
1598 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1600 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1601 if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1602 return -1;
1604 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1605 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1606 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1607 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1608 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1609 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1610 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1611 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1612 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1613 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1614 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1615 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1616 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1617 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1618 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1619 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1620 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1621 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1623 return 0;
1626 static int
1627 bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1629 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1630 unsigned char buf[16];
1631 asection *bfdsec;
1632 char *sname;
1633 const char *prefix = "LC_SYMTAB.stabs";
1634 int nlist_size = (bfd_mach_o_version (abfd) > 1) ? 16 : 12;
1636 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1638 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1639 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1640 return -1;
1642 seg->symoff = bfd_h_get_32 (abfd, buf);
1643 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1644 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1645 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1646 seg->symbols = NULL;
1647 seg->strtab = NULL;
1649 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1650 if (sname == NULL)
1651 return -1;
1652 strcpy (sname, prefix);
1654 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1655 if (bfdsec == NULL)
1656 return -1;
1658 bfdsec->vma = 0;
1659 bfdsec->lma = 0;
1660 bfdsec->size = seg->nsyms * nlist_size;
1661 bfdsec->filepos = seg->symoff;
1662 bfdsec->alignment_power = 0;
1664 seg->stabs_segment = bfdsec;
1666 if (seg->nsyms != 0)
1667 abfd->flags |= HAS_SYMS;
1669 prefix = "LC_SYMTAB.stabstr";
1670 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1671 if (sname == NULL)
1672 return -1;
1673 strcpy (sname, prefix);
1675 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1676 if (bfdsec == NULL)
1677 return -1;
1679 bfdsec->vma = 0;
1680 bfdsec->lma = 0;
1681 bfdsec->size = seg->strsize;
1682 bfdsec->filepos = seg->stroff;
1683 bfdsec->alignment_power = 0;
1685 seg->stabstr_segment = bfdsec;
1687 return 0;
1690 static int
1691 bfd_mach_o_scan_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
1693 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
1694 asection *bfdsec;
1695 char *sname;
1696 static const char prefix[] = "LC_UUID";
1698 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
1700 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1701 if (bfd_bread ((PTR) cmd->uuid, 16, abfd) != 16)
1702 return -1;
1704 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1705 if (sname == NULL)
1706 return -1;
1707 strcpy (sname, prefix);
1709 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1710 if (bfdsec == NULL)
1711 return -1;
1713 bfdsec->vma = 0;
1714 bfdsec->lma = 0;
1715 bfdsec->size = command->len - 8;
1716 bfdsec->filepos = command->offset + 8;
1717 bfdsec->alignment_power = 0;
1719 cmd->section = bfdsec;
1721 return 0;
1724 static int
1725 bfd_mach_o_scan_read_segment (bfd *abfd,
1726 bfd_mach_o_load_command *command,
1727 unsigned int wide)
1729 unsigned char buf[64];
1730 bfd_mach_o_segment_command *seg = &command->command.segment;
1731 unsigned long i;
1733 if (wide)
1735 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1737 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1738 if (bfd_bread ((PTR) buf, 64, abfd) != 64)
1739 return -1;
1741 memcpy (seg->segname, buf, 16);
1742 seg->segname[16] = '\0';
1744 seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
1745 seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
1746 seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
1747 seg->filesize = bfd_h_get_64 (abfd, buf + 40);
1748 seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
1749 seg->initprot = bfd_h_get_32 (abfd, buf + 52);
1750 seg->nsects = bfd_h_get_32 (abfd, buf + 56);
1751 seg->flags = bfd_h_get_32 (abfd, buf + 60);
1753 else
1755 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1757 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1758 if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1759 return -1;
1761 memcpy (seg->segname, buf, 16);
1762 seg->segname[16] = '\0';
1764 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1765 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1766 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1767 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
1768 seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
1769 seg->initprot = bfd_h_get_32 (abfd, buf + 36);
1770 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1771 seg->flags = bfd_h_get_32 (abfd, buf + 44);
1774 if (seg->nsects != 0)
1776 seg->sections = bfd_alloc (abfd, seg->nsects
1777 * sizeof (bfd_mach_o_section));
1778 if (seg->sections == NULL)
1779 return -1;
1781 for (i = 0; i < seg->nsects; i++)
1783 bfd_vma segoff;
1784 if (wide)
1785 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
1786 + (i * BFD_MACH_O_SECTION_64_SIZE);
1787 else
1788 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
1789 + (i * BFD_MACH_O_SECTION_SIZE);
1791 if (bfd_mach_o_scan_read_section
1792 (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
1793 return -1;
1797 return 0;
1800 static int
1801 bfd_mach_o_scan_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1803 return bfd_mach_o_scan_read_segment (abfd, command, 0);
1806 static int
1807 bfd_mach_o_scan_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1809 return bfd_mach_o_scan_read_segment (abfd, command, 1);
1812 static int
1813 bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
1815 unsigned char buf[8];
1817 bfd_seek (abfd, command->offset, SEEK_SET);
1818 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1819 return -1;
1821 command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
1822 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1823 ? TRUE : FALSE);
1824 command->len = bfd_h_get_32 (abfd, buf + 4);
1826 switch (command->type)
1828 case BFD_MACH_O_LC_SEGMENT:
1829 if (bfd_mach_o_scan_read_segment_32 (abfd, command) != 0)
1830 return -1;
1831 break;
1832 case BFD_MACH_O_LC_SEGMENT_64:
1833 if (bfd_mach_o_scan_read_segment_64 (abfd, command) != 0)
1834 return -1;
1835 break;
1836 case BFD_MACH_O_LC_SYMTAB:
1837 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1838 return -1;
1839 break;
1840 case BFD_MACH_O_LC_SYMSEG:
1841 break;
1842 case BFD_MACH_O_LC_THREAD:
1843 case BFD_MACH_O_LC_UNIXTHREAD:
1844 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1845 return -1;
1846 break;
1847 case BFD_MACH_O_LC_LOAD_DYLINKER:
1848 case BFD_MACH_O_LC_ID_DYLINKER:
1849 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1850 return -1;
1851 break;
1852 case BFD_MACH_O_LC_LOAD_DYLIB:
1853 case BFD_MACH_O_LC_ID_DYLIB:
1854 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1855 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1856 return -1;
1857 break;
1858 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1859 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1860 return -1;
1861 break;
1862 case BFD_MACH_O_LC_LOADFVMLIB:
1863 case BFD_MACH_O_LC_IDFVMLIB:
1864 case BFD_MACH_O_LC_IDENT:
1865 case BFD_MACH_O_LC_FVMFILE:
1866 case BFD_MACH_O_LC_PREPAGE:
1867 case BFD_MACH_O_LC_ROUTINES:
1868 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1869 break;
1870 case BFD_MACH_O_LC_DYSYMTAB:
1871 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1872 return -1;
1873 break;
1874 case BFD_MACH_O_LC_SUB_UMBRELLA:
1875 case BFD_MACH_O_LC_SUB_CLIENT:
1876 case BFD_MACH_O_LC_SUB_LIBRARY:
1877 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1878 case BFD_MACH_O_LC_PREBIND_CKSUM:
1879 break;
1880 case BFD_MACH_O_LC_UUID:
1881 if (bfd_mach_o_scan_read_uuid (abfd, command) != 0)
1882 return -1;
1883 break;
1884 case BFD_MACH_O_LC_CODE_SIGNATURE:
1885 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1886 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1887 break;
1888 default:
1889 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1890 (unsigned long) command->type);
1891 break;
1894 return 0;
1897 static void
1898 bfd_mach_o_flatten_sections (bfd *abfd)
1900 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1901 long csect = 0;
1902 unsigned long i, j;
1904 /* Count total number of sections. */
1905 mdata->nsects = 0;
1907 for (i = 0; i < mdata->header.ncmds; i++)
1909 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
1910 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
1912 bfd_mach_o_segment_command *seg;
1914 seg = &mdata->commands[i].command.segment;
1915 mdata->nsects += seg->nsects;
1919 /* Allocate sections array. */
1920 mdata->sections = bfd_alloc (abfd,
1921 mdata->nsects * sizeof (bfd_mach_o_section *));
1923 /* Fill the array. */
1924 csect = 0;
1926 for (i = 0; i < mdata->header.ncmds; i++)
1928 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
1929 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
1931 bfd_mach_o_segment_command *seg;
1933 seg = &mdata->commands[i].command.segment;
1934 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1936 for (j = 0; j < seg->nsects; j++)
1937 mdata->sections[csect++] = &seg->sections[j];
1943 bfd_mach_o_scan_start_address (bfd *abfd)
1945 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1946 bfd_mach_o_thread_command *cmd = NULL;
1947 unsigned long i;
1949 for (i = 0; i < mdata->header.ncmds; i++)
1951 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1952 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1954 if (cmd == NULL)
1955 cmd = &mdata->commands[i].command.thread;
1956 else
1957 return 0;
1961 if (cmd == NULL)
1962 return 0;
1964 for (i = 0; i < cmd->nflavours; i++)
1966 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1967 && (cmd->flavours[i].flavour
1968 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
1970 unsigned char buf[4];
1972 bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1974 if (bfd_bread (buf, 4, abfd) != 4)
1975 return -1;
1977 abfd->start_address = bfd_h_get_32 (abfd, buf);
1979 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1980 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1982 unsigned char buf[4];
1984 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1986 if (bfd_bread (buf, 4, abfd) != 4)
1987 return -1;
1989 abfd->start_address = bfd_h_get_32 (abfd, buf);
1991 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
1992 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE_64))
1994 unsigned char buf[8];
1996 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1998 if (bfd_bread (buf, 8, abfd) != 8)
1999 return -1;
2001 abfd->start_address = bfd_h_get_64 (abfd, buf);
2003 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2004 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2006 unsigned char buf[8];
2008 bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET);
2010 if (bfd_bread (buf, 8, abfd) != 8)
2011 return -1;
2013 abfd->start_address = bfd_h_get_64 (abfd, buf);
2017 return 0;
2021 bfd_mach_o_scan (bfd *abfd,
2022 bfd_mach_o_header *header,
2023 bfd_mach_o_data_struct *mdata)
2025 unsigned int i;
2026 enum bfd_architecture cputype;
2027 unsigned long cpusubtype;
2028 unsigned int hdrsize;
2030 hdrsize = (header->version == 2) ?
2031 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2033 mdata->header = *header;
2034 mdata->symbols = NULL;
2036 abfd->flags = abfd->flags & BFD_IN_MEMORY;
2037 switch (header->filetype)
2039 case BFD_MACH_O_MH_OBJECT:
2040 abfd->flags |= HAS_RELOC;
2041 break;
2042 case BFD_MACH_O_MH_EXECUTE:
2043 abfd->flags |= EXEC_P;
2044 break;
2045 case BFD_MACH_O_MH_DYLIB:
2046 case BFD_MACH_O_MH_BUNDLE:
2047 abfd->flags |= DYNAMIC;
2048 break;
2051 abfd->tdata.mach_o_data = mdata;
2053 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2054 &cputype, &cpusubtype);
2055 if (cputype == bfd_arch_unknown)
2057 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
2058 header->cputype, header->cpusubtype);
2059 return -1;
2062 bfd_set_arch_mach (abfd, cputype, cpusubtype);
2064 if (header->ncmds != 0)
2066 mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2067 if (mdata->commands == NULL)
2068 return -1;
2070 for (i = 0; i < header->ncmds; i++)
2072 bfd_mach_o_load_command *cur = &mdata->commands[i];
2074 if (i == 0)
2075 cur->offset = hdrsize;
2076 else
2078 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2079 cur->offset = prev->offset + prev->len;
2082 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
2083 return -1;
2087 if (bfd_mach_o_scan_start_address (abfd) < 0)
2088 return -1;
2090 bfd_mach_o_flatten_sections (abfd);
2091 return 0;
2094 bfd_boolean
2095 bfd_mach_o_mkobject_init (bfd *abfd)
2097 bfd_mach_o_data_struct *mdata = NULL;
2099 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2100 if (mdata == NULL)
2101 return FALSE;
2102 abfd->tdata.mach_o_data = mdata;
2104 mdata->header.magic = 0;
2105 mdata->header.cputype = 0;
2106 mdata->header.cpusubtype = 0;
2107 mdata->header.filetype = 0;
2108 mdata->header.ncmds = 0;
2109 mdata->header.sizeofcmds = 0;
2110 mdata->header.flags = 0;
2111 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2112 mdata->commands = NULL;
2113 mdata->nsymbols = 0;
2114 mdata->symbols = NULL;
2115 mdata->nsects = 0;
2116 mdata->sections = NULL;
2117 mdata->ibfd = NULL;
2119 return TRUE;
2122 const bfd_target *
2123 bfd_mach_o_header_p (bfd *abfd,
2124 bfd_mach_o_filetype filetype,
2125 bfd_mach_o_cpu_type cputype)
2127 struct bfd_preserve preserve;
2128 bfd_mach_o_header header;
2130 preserve.marker = NULL;
2131 if (!bfd_mach_o_read_header (abfd, &header))
2132 goto wrong;
2134 if (! (header.byteorder == BFD_ENDIAN_BIG
2135 || header.byteorder == BFD_ENDIAN_LITTLE))
2137 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
2138 (unsigned long) header.byteorder);
2139 goto wrong;
2142 if (! ((header.byteorder == BFD_ENDIAN_BIG
2143 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2144 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2145 || (header.byteorder == BFD_ENDIAN_LITTLE
2146 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2147 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2148 goto wrong;
2150 /* Check cputype and filetype.
2151 In case of wildcard, do not accept magics that are handled by existing
2152 targets. */
2153 if (cputype)
2155 if (header.cputype != cputype)
2156 goto wrong;
2158 else
2160 switch (header.cputype)
2162 case BFD_MACH_O_CPU_TYPE_I386:
2163 /* Handled by mach-o-i386 */
2164 goto wrong;
2165 default:
2166 break;
2169 if (filetype)
2171 if (header.filetype != filetype)
2172 goto wrong;
2174 else
2176 switch (header.filetype)
2178 case BFD_MACH_O_MH_CORE:
2179 /* Handled by core_p */
2180 goto wrong;
2181 default:
2182 break;
2186 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2187 if (preserve.marker == NULL
2188 || !bfd_preserve_save (abfd, &preserve))
2189 goto fail;
2191 if (bfd_mach_o_scan (abfd, &header,
2192 (bfd_mach_o_data_struct *) preserve.marker) != 0)
2193 goto wrong;
2195 bfd_preserve_finish (abfd, &preserve);
2196 return abfd->xvec;
2198 wrong:
2199 bfd_set_error (bfd_error_wrong_format);
2201 fail:
2202 if (preserve.marker != NULL)
2203 bfd_preserve_restore (abfd, &preserve);
2204 return NULL;
2207 static const bfd_target *
2208 bfd_mach_o_gen_object_p (bfd *abfd)
2210 return bfd_mach_o_header_p (abfd, 0, 0);
2213 static const bfd_target *
2214 bfd_mach_o_gen_core_p (bfd *abfd)
2216 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
2219 typedef struct mach_o_fat_archentry
2221 unsigned long cputype;
2222 unsigned long cpusubtype;
2223 unsigned long offset;
2224 unsigned long size;
2225 unsigned long align;
2226 } mach_o_fat_archentry;
2228 typedef struct mach_o_fat_data_struct
2230 unsigned long magic;
2231 unsigned long nfat_arch;
2232 mach_o_fat_archentry *archentries;
2233 } mach_o_fat_data_struct;
2235 const bfd_target *
2236 bfd_mach_o_archive_p (bfd *abfd)
2238 mach_o_fat_data_struct *adata = NULL;
2239 unsigned char buf[20];
2240 unsigned long i;
2242 bfd_seek (abfd, 0, SEEK_SET);
2243 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
2244 goto error;
2246 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
2247 if (adata == NULL)
2248 goto error;
2250 adata->magic = bfd_getb32 (buf);
2251 adata->nfat_arch = bfd_getb32 (buf + 4);
2252 if (adata->magic != 0xcafebabe)
2253 goto error;
2254 /* Avoid matching Java bytecode files, which have the same magic number.
2255 In the Java bytecode file format this field contains the JVM version,
2256 which starts at 43.0. */
2257 if (adata->nfat_arch > 30)
2258 goto error;
2260 adata->archentries =
2261 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2262 if (adata->archentries == NULL)
2263 goto error;
2265 for (i = 0; i < adata->nfat_arch; i++)
2267 bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
2269 if (bfd_bread ((PTR) buf, 20, abfd) != 20)
2270 goto error;
2271 adata->archentries[i].cputype = bfd_getb32 (buf);
2272 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
2273 adata->archentries[i].offset = bfd_getb32 (buf + 8);
2274 adata->archentries[i].size = bfd_getb32 (buf + 12);
2275 adata->archentries[i].align = bfd_getb32 (buf + 16);
2278 abfd->tdata.mach_o_fat_data = adata;
2279 return abfd->xvec;
2281 error:
2282 if (adata != NULL)
2283 bfd_release (abfd, adata);
2284 bfd_set_error (bfd_error_wrong_format);
2285 return NULL;
2288 bfd *
2289 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
2291 mach_o_fat_data_struct *adata;
2292 mach_o_fat_archentry *entry = NULL;
2293 unsigned long i;
2294 bfd *nbfd;
2295 enum bfd_architecture arch_type;
2296 unsigned long arch_subtype;
2298 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
2299 BFD_ASSERT (adata != NULL);
2301 /* Find index of previous entry. */
2302 if (prev == NULL)
2303 i = 0; /* Start at first one. */
2304 else
2306 for (i = 0; i < adata->nfat_arch; i++)
2308 if (adata->archentries[i].offset == prev->origin)
2309 break;
2312 if (i == adata->nfat_arch)
2314 /* Not found. */
2315 bfd_set_error (bfd_error_bad_value);
2316 return NULL;
2318 i++; /* Get next entry. */
2321 if (i >= adata->nfat_arch)
2323 bfd_set_error (bfd_error_no_more_archived_files);
2324 return NULL;
2327 entry = &adata->archentries[i];
2328 nbfd = _bfd_new_bfd_contained_in (archive);
2329 if (nbfd == NULL)
2330 return NULL;
2332 nbfd->origin = entry->offset;
2334 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
2335 &arch_type, &arch_subtype);
2336 /* Create the member filename.
2337 Use FILENAME:ARCH_NAME. */
2339 char *s = NULL;
2340 const char *arch_name;
2341 size_t arch_file_len = strlen (bfd_get_filename (archive));
2343 arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
2344 s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
2345 if (s == NULL)
2346 return NULL;
2347 memcpy (s, bfd_get_filename (archive), arch_file_len);
2348 s[arch_file_len] = ':';
2349 strcpy (s + arch_file_len + 1, arch_name);
2350 nbfd->filename = s;
2352 nbfd->iostream = NULL;
2353 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
2355 return nbfd;
2358 /* If ABFD format is FORMAT and architecture is ARCH, return it.
2359 If ABFD is a fat image containing a member that corresponds to FORMAT
2360 and ARCH, returns it.
2361 In other case, returns NULL.
2362 This function allows transparent uses of fat images. */
2363 bfd *
2364 bfd_mach_o_fat_extract (bfd *abfd,
2365 bfd_format format,
2366 const bfd_arch_info_type *arch)
2368 bfd *res;
2369 mach_o_fat_data_struct *adata;
2370 unsigned int i;
2372 if (bfd_check_format (abfd, format))
2374 if (bfd_get_arch_info (abfd) == arch)
2375 return abfd;
2376 return NULL;
2378 if (!bfd_check_format (abfd, bfd_archive)
2379 || abfd->xvec != &mach_o_fat_vec)
2380 return NULL;
2382 /* This is a Mach-O fat image. */
2383 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
2384 BFD_ASSERT (adata != NULL);
2386 for (i = 0; i < adata->nfat_arch; i++)
2388 struct mach_o_fat_archentry *e = &adata->archentries[i];
2389 enum bfd_architecture cpu_type;
2390 unsigned long cpu_subtype;
2392 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
2393 &cpu_type, &cpu_subtype);
2394 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
2395 continue;
2397 /* The architecture is found. */
2398 res = _bfd_new_bfd_contained_in (abfd);
2399 if (res == NULL)
2400 return NULL;
2402 res->origin = e->offset;
2404 res->filename = strdup (abfd->filename);
2405 res->iostream = NULL;
2407 if (bfd_check_format (res, format))
2409 BFD_ASSERT (bfd_get_arch_info (res) == arch);
2410 return res;
2412 bfd_close (res);
2413 return NULL;
2416 return NULL;
2420 bfd_mach_o_lookup_section (bfd *abfd,
2421 asection *section,
2422 bfd_mach_o_load_command **mcommand,
2423 bfd_mach_o_section **msection)
2425 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
2426 unsigned int i, j, num;
2428 bfd_mach_o_load_command *ncmd = NULL;
2429 bfd_mach_o_section *nsect = NULL;
2431 BFD_ASSERT (mcommand != NULL);
2432 BFD_ASSERT (msection != NULL);
2434 num = 0;
2435 for (i = 0; i < md->header.ncmds; i++)
2437 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2438 struct bfd_mach_o_segment_command *seg = NULL;
2440 if (cmd->type != BFD_MACH_O_LC_SEGMENT
2441 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
2442 continue;
2443 seg = &cmd->command.segment;
2445 if (seg->segment == section)
2447 if (num == 0)
2448 ncmd = cmd;
2449 num++;
2452 for (j = 0; j < seg->nsects; j++)
2454 struct bfd_mach_o_section *sect = &seg->sections[j];
2456 if (sect->bfdsection == section)
2458 if (num == 0)
2459 nsect = sect;
2460 num++;
2465 *mcommand = ncmd;
2466 *msection = nsect;
2467 return num;
2471 bfd_mach_o_lookup_command (bfd *abfd,
2472 bfd_mach_o_load_command_type type,
2473 bfd_mach_o_load_command **mcommand)
2475 struct mach_o_data_struct *md = NULL;
2476 bfd_mach_o_load_command *ncmd = NULL;
2477 unsigned int i, num;
2479 md = abfd->tdata.mach_o_data;
2481 BFD_ASSERT (md != NULL);
2482 BFD_ASSERT (mcommand != NULL);
2484 num = 0;
2485 for (i = 0; i < md->header.ncmds; i++)
2487 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2489 if (cmd->type != type)
2490 continue;
2492 if (num == 0)
2493 ncmd = cmd;
2494 num++;
2497 *mcommand = ncmd;
2498 return num;
2501 unsigned long
2502 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
2504 switch (type)
2506 case BFD_MACH_O_CPU_TYPE_MC680x0:
2507 return 0x04000000;
2508 case BFD_MACH_O_CPU_TYPE_MC88000:
2509 return 0xffffe000;
2510 case BFD_MACH_O_CPU_TYPE_POWERPC:
2511 return 0xc0000000;
2512 case BFD_MACH_O_CPU_TYPE_I386:
2513 return 0xc0000000;
2514 case BFD_MACH_O_CPU_TYPE_SPARC:
2515 return 0xf0000000;
2516 case BFD_MACH_O_CPU_TYPE_I860:
2517 return 0;
2518 case BFD_MACH_O_CPU_TYPE_HPPA:
2519 return 0xc0000000 - 0x04000000;
2520 default:
2521 return 0;
2525 bfd_boolean
2526 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, PTR ptr)
2528 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2529 FILE *file = (FILE *) ptr;
2530 unsigned int i, j;
2531 unsigned int sec_nbr = 0;
2533 fprintf (file, _("Segments and Sections:\n"));
2534 fprintf (file, _(" #: Segment name Section name Address\n"));
2536 for (i = 0; i < mdata->header.ncmds; i++)
2538 bfd_mach_o_segment_command *seg;
2540 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
2541 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
2542 continue;
2544 seg = &mdata->commands[i].command.segment;
2546 fprintf (file, "[Segment %-16s ", seg->segname);
2547 fprintf_vma (file, seg->vmaddr);
2548 fprintf (file, "-");
2549 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
2550 fputc (' ', file);
2551 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
2552 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
2553 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
2554 fprintf (file, "]\n");
2555 for (j = 0; j < seg->nsects; j++)
2557 bfd_mach_o_section *sec = &seg->sections[j];
2558 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
2559 sec->segname, sec->sectname);
2560 fprintf_vma (file, sec->addr);
2561 fprintf (file, " ");
2562 fprintf_vma (file, sec->size);
2563 fprintf (file, " %08lx\n", sec->flags);
2567 for (i = 0; i < mdata->header.ncmds; i++)
2569 bfd_mach_o_load_command *cmd = &mdata->commands[i];
2571 switch (cmd->type)
2573 case BFD_MACH_O_LC_SEGMENT:
2574 case BFD_MACH_O_LC_SEGMENT_64:
2575 break;
2576 case BFD_MACH_O_LC_UUID:
2578 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
2579 unsigned int i;
2581 fprintf (file, "\n"
2582 "UUID:");
2583 for (i = 0; i < sizeof (uuid->uuid); i++)
2584 fprintf (file, " %02x", uuid->uuid[i]);
2585 fputc ('\n', file);
2587 break;
2588 case BFD_MACH_O_LC_LOAD_DYLIB:
2590 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
2591 bfd_byte *data = NULL;
2593 if (! bfd_malloc_and_get_section (abfd, dylib->section, &data))
2595 if (data != NULL)
2596 free (data);
2597 break;
2599 fprintf (file, "\n"
2600 "LOAD_DYLIB: %s\n",
2601 data + dylib->name_offset - cmd->offset - 8);
2602 fprintf (file, " time stamp: 0x%08lx\n",
2603 dylib->timestamp);
2604 fprintf (file, " current version: 0x%08lx\n",
2605 dylib->current_version);
2606 fprintf (file, " comptibility version: 0x%08lx\n",
2607 dylib->compatibility_version);
2608 free (data);
2609 break;
2611 case BFD_MACH_O_LC_LOAD_DYLINKER:
2613 bfd_mach_o_dylinker_command *linker = &cmd->command.dylinker;
2614 bfd_byte *data = NULL;
2616 if (! bfd_malloc_and_get_section (abfd, linker->section, &data))
2618 if (data != NULL)
2619 free (data);
2620 break;
2622 fprintf (file, "\n"
2623 "LOAD_DYLINKER: %s\n",
2624 data + linker->name_offset - cmd->offset - 8);
2625 free (data);
2626 break;
2628 case BFD_MACH_O_LC_SYMTAB:
2630 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
2631 fprintf (file, "\n"
2632 "LC_SYMTAB: nsyms: %lu, strsize: %lu\n",
2633 symtab->nsyms, symtab->strsize);
2634 break;
2636 case BFD_MACH_O_LC_DYSYMTAB:
2638 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
2639 fprintf (file, "\n"
2640 "LC_DYSYMTAB:\n"
2641 " local symbols: index: %lu number: %lu\n",
2642 dysymtab->ilocalsym, dysymtab->nlocalsym);
2643 fprintf (file,
2644 " external symbols: index: %lu number: %lu\n",
2645 dysymtab->iextdefsym, dysymtab->nextdefsym);
2646 fprintf (file,
2647 " undefined symbols: index: %lu number: %lu\n",
2648 dysymtab->iundefsym, dysymtab->nundefsym);
2649 fprintf (file,
2650 " ntoc: offset: %lu number: %lu\n",
2651 dysymtab->tocoff, dysymtab->ntoc);
2652 fprintf (file,
2653 " module table: offset: %lu number: %lu\n",
2654 dysymtab->modtaboff, dysymtab->nmodtab);
2655 break;
2657 default:
2658 fprintf (file, "LC_%d\n", cmd->type);
2659 break;
2663 return TRUE;
2667 bfd_mach_o_core_fetch_environment (bfd *abfd,
2668 unsigned char **rbuf,
2669 unsigned int *rlen)
2671 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2672 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2673 unsigned int i = 0;
2675 for (i = 0; i < mdata->header.ncmds; i++)
2677 bfd_mach_o_load_command *cur = &mdata->commands[i];
2678 bfd_mach_o_segment_command *seg = NULL;
2680 if (cur->type != BFD_MACH_O_LC_SEGMENT)
2681 continue;
2683 seg = &cur->command.segment;
2685 if ((seg->vmaddr + seg->vmsize) == stackaddr)
2687 unsigned long start = seg->fileoff;
2688 unsigned long end = seg->fileoff + seg->filesize;
2689 unsigned char *buf = bfd_malloc (1024);
2690 unsigned long size = 1024;
2692 for (;;)
2694 bfd_size_type nread = 0;
2695 unsigned long offset;
2696 int found_nonnull = 0;
2698 if (size > (end - start))
2699 size = (end - start);
2701 buf = bfd_realloc_or_free (buf, size);
2702 if (buf == NULL)
2703 return -1;
2705 bfd_seek (abfd, end - size, SEEK_SET);
2706 nread = bfd_bread (buf, size, abfd);
2708 if (nread != size)
2710 free (buf);
2711 return -1;
2714 for (offset = 4; offset <= size; offset += 4)
2716 unsigned long val;
2718 val = *((unsigned long *) (buf + size - offset));
2719 if (! found_nonnull)
2721 if (val != 0)
2722 found_nonnull = 1;
2724 else if (val == 0x0)
2726 unsigned long bottom;
2727 unsigned long top;
2729 bottom = seg->fileoff + seg->filesize - offset;
2730 top = seg->fileoff + seg->filesize - 4;
2731 *rbuf = bfd_malloc (top - bottom);
2732 *rlen = top - bottom;
2734 memcpy (*rbuf, buf + size - *rlen, *rlen);
2735 free (buf);
2736 return 0;
2740 if (size == (end - start))
2741 break;
2743 size *= 2;
2746 free (buf);
2750 return -1;
2753 char *
2754 bfd_mach_o_core_file_failing_command (bfd *abfd)
2756 unsigned char *buf = NULL;
2757 unsigned int len = 0;
2758 int ret = -1;
2760 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
2761 if (ret < 0)
2762 return NULL;
2764 return (char *) buf;
2768 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
2770 return 0;
2773 #define TARGET_NAME mach_o_be_vec
2774 #define TARGET_STRING "mach-o-be"
2775 #define TARGET_BIG_ENDIAN 1
2776 #define TARGET_ARCHIVE 0
2778 #include "mach-o-target.c"
2780 #undef TARGET_NAME
2781 #undef TARGET_STRING
2782 #undef TARGET_BIG_ENDIAN
2783 #undef TARGET_ARCHIVE
2785 #define TARGET_NAME mach_o_le_vec
2786 #define TARGET_STRING "mach-o-le"
2787 #define TARGET_BIG_ENDIAN 0
2788 #define TARGET_ARCHIVE 0
2790 #include "mach-o-target.c"
2792 #undef TARGET_NAME
2793 #undef TARGET_STRING
2794 #undef TARGET_BIG_ENDIAN
2795 #undef TARGET_ARCHIVE
2797 #define TARGET_NAME mach_o_fat_vec
2798 #define TARGET_STRING "mach-o-fat"
2799 #define TARGET_BIG_ENDIAN 1
2800 #define TARGET_ARCHIVE 1
2802 #include "mach-o-target.c"
2804 #undef TARGET_NAME
2805 #undef TARGET_STRING
2806 #undef TARGET_BIG_ENDIAN
2807 #undef TARGET_ARCHIVE