* config/tc-mcore.c (mcore_pool_count): New function.
[binutils.git] / bfd / mach-o.c
blob1daaf985ff76f154ddfdbad0354c7b97fed1b044
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "mach-o.h"
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "libiberty.h"
26 #include <ctype.h>
28 #ifndef BFD_IO_FUNCS
29 #define BFD_IO_FUNCS 0
30 #endif
32 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
33 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
34 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
35 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
36 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
37 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
38 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
39 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
40 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
41 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
42 #define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup
43 #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
44 #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
45 #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
46 #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
47 #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
48 #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
49 #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
50 #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
51 #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
52 #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
53 #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
54 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
55 #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
56 #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
57 #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
58 #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
59 #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
60 #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
61 #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
62 #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
63 #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach
64 #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
65 #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
66 #define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
67 #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
68 #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
69 #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
70 #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
71 #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
73 static boolean bfd_mach_o_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
74 static boolean bfd_mach_o_bfd_copy_private_section_data PARAMS ((bfd *, asection *, bfd *, asection *));
75 static boolean bfd_mach_o_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
76 static long bfd_mach_o_count_symbols PARAMS ((bfd *));
77 static long bfd_mach_o_get_symtab_upper_bound PARAMS ((bfd *));
78 static long bfd_mach_o_get_symtab PARAMS ((bfd *, asymbol **));
79 static void bfd_mach_o_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
80 static void bfd_mach_o_print_symbol PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
81 static void bfd_mach_o_convert_architecture PARAMS ((bfd_mach_o_cpu_type, bfd_mach_o_cpu_subtype, enum bfd_architecture *, unsigned long *));
82 static boolean bfd_mach_o_write_contents PARAMS ((bfd *));
83 static int bfd_mach_o_sizeof_headers PARAMS ((bfd *, boolean));
84 static asymbol * bfd_mach_o_make_empty_symbol PARAMS ((bfd *));
85 static int bfd_mach_o_write_header PARAMS ((bfd *, bfd_mach_o_header *));
86 static int bfd_mach_o_read_header PARAMS ((bfd *, bfd_mach_o_header *));
87 static asection * bfd_mach_o_make_bfd_section PARAMS ((bfd *, bfd_mach_o_section *));
88 static int bfd_mach_o_scan_read_section PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
89 static int bfd_mach_o_scan_write_section PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
90 static int bfd_mach_o_scan_write_symtab_symbols PARAMS ((bfd *, bfd_mach_o_load_command *));
91 static int bfd_mach_o_scan_write_thread PARAMS ((bfd *, bfd_mach_o_load_command *));
92 static int bfd_mach_o_scan_read_dylinker PARAMS ((bfd *, bfd_mach_o_load_command *));
93 static int bfd_mach_o_scan_read_dylib PARAMS ((bfd *, bfd_mach_o_load_command *));
94 static int bfd_mach_o_scan_read_prebound_dylib PARAMS ((bfd *, bfd_mach_o_load_command *));
95 static int bfd_mach_o_scan_read_thread PARAMS ((bfd *, bfd_mach_o_load_command *));
96 static int bfd_mach_o_scan_write_symtab PARAMS ((bfd *, bfd_mach_o_load_command *));
97 static int bfd_mach_o_scan_read_dysymtab PARAMS ((bfd *, bfd_mach_o_load_command *));
98 static int bfd_mach_o_scan_read_symtab PARAMS ((bfd *, bfd_mach_o_load_command *));
99 static int bfd_mach_o_scan_read_segment PARAMS ((bfd *, bfd_mach_o_load_command *));
100 static int bfd_mach_o_scan_write_segment PARAMS ((bfd *, bfd_mach_o_load_command *));
101 static int bfd_mach_o_scan_read_command PARAMS ((bfd *, bfd_mach_o_load_command *));
102 static void bfd_mach_o_flatten_sections PARAMS ((bfd *));
103 static const char * bfd_mach_o_i386_flavour_string PARAMS ((unsigned int));
104 static const char * bfd_mach_o_ppc_flavour_string PARAMS ((unsigned int));
106 /* The flags field of a section structure is separated into two parts a section
107 type and section attributes. The section types are mutually exclusive (it
108 can only have one type) but the section attributes are not (it may have more
109 than one attribute). */
111 #define SECTION_TYPE 0x000000ff /* 256 section types. */
112 #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes. */
114 /* Constants for the section attributes part of the flags field of a section
115 structure. */
117 #define SECTION_ATTRIBUTES_USR 0xff000000 /* User-settable attributes. */
118 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* Section contains only true machine instructions. */
119 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* System setable attributes. */
120 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* Section contains some machine instructions. */
121 #define S_ATTR_EXT_RELOC 0x00000200 /* Section has external relocation entries. */
122 #define S_ATTR_LOC_RELOC 0x00000100 /* Section has local relocation entries. */
124 #define N_STAB 0xe0
125 #define N_TYPE 0x1e
126 #define N_EXT 0x01
127 #define N_UNDF 0x0
128 #define N_ABS 0x2
129 #define N_SECT 0xe
130 #define N_INDR 0xa
132 boolean
133 bfd_mach_o_valid (abfd)
134 bfd *abfd;
136 if (abfd == NULL || abfd->xvec == NULL)
137 return 0;
139 if (! ((abfd->xvec == &mach_o_be_vec)
140 || (abfd->xvec == &mach_o_le_vec)
141 || (abfd->xvec == &mach_o_fat_vec)))
142 return 0;
144 if (abfd->tdata.mach_o_data == NULL)
145 return 0;
146 return 1;
149 /* Copy any private info we understand from the input symbol
150 to the output symbol. */
152 static boolean
153 bfd_mach_o_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
154 bfd *ibfd ATTRIBUTE_UNUSED;
155 asymbol *isymbol ATTRIBUTE_UNUSED;
156 bfd *obfd ATTRIBUTE_UNUSED;
157 asymbol *osymbol ATTRIBUTE_UNUSED;
159 return true;
162 /* Copy any private info we understand from the input section
163 to the output section. */
165 static boolean
166 bfd_mach_o_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
167 bfd *ibfd ATTRIBUTE_UNUSED;
168 asection *isection ATTRIBUTE_UNUSED;
169 bfd *obfd ATTRIBUTE_UNUSED;
170 asection *osection ATTRIBUTE_UNUSED;
172 return true;
175 /* Copy any private info we understand from the input bfd
176 to the output bfd. */
178 static boolean
179 bfd_mach_o_bfd_copy_private_bfd_data (ibfd, obfd)
180 bfd *ibfd;
181 bfd *obfd;
183 BFD_ASSERT (bfd_mach_o_valid (ibfd));
184 BFD_ASSERT (bfd_mach_o_valid (obfd));
186 obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
187 obfd->tdata.mach_o_data->ibfd = ibfd;
188 return true;
191 static long
192 bfd_mach_o_count_symbols (abfd)
193 bfd *abfd;
195 bfd_mach_o_data_struct *mdata = NULL;
196 long nsyms = 0;
197 unsigned long i;
199 BFD_ASSERT (bfd_mach_o_valid (abfd));
200 mdata = abfd->tdata.mach_o_data;
202 for (i = 0; i < mdata->header.ncmds; i++)
203 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
205 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
206 nsyms += sym->nsyms;
209 return nsyms;
212 static long
213 bfd_mach_o_get_symtab_upper_bound (abfd)
214 bfd *abfd;
216 long nsyms = bfd_mach_o_count_symbols (abfd);
218 if (nsyms < 0)
219 return nsyms;
221 return ((nsyms + 1) * sizeof (asymbol *));
224 static long
225 bfd_mach_o_get_symtab (abfd, alocation)
226 bfd *abfd;
227 asymbol **alocation;
229 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
230 long nsyms = bfd_mach_o_count_symbols (abfd);
231 asymbol **csym = alocation;
232 unsigned long i, j;
234 if (nsyms < 0)
235 return nsyms;
237 for (i = 0; i < mdata->header.ncmds; i++)
239 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
241 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
243 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
245 fprintf (stderr, "bfd_mach_o_get_symtab: unable to load symbols for section %lu\n", i);
246 return 0;
249 BFD_ASSERT (sym->symbols != NULL);
251 for (j = 0; j < sym->nsyms; j++)
253 BFD_ASSERT (csym < (alocation + nsyms));
254 *csym++ = &sym->symbols[j];
259 *csym++ = NULL;
261 return nsyms;
264 static void
265 bfd_mach_o_get_symbol_info (abfd, symbol, ret)
266 bfd *abfd ATTRIBUTE_UNUSED;
267 asymbol *symbol;
268 symbol_info *ret;
270 bfd_symbol_info (symbol, ret);
273 static void
274 bfd_mach_o_print_symbol (abfd, afile, symbol, how)
275 bfd *abfd;
276 PTR afile;
277 asymbol *symbol;
278 bfd_print_symbol_type how;
280 FILE *file = (FILE *) afile;
282 switch (how)
284 case bfd_print_symbol_name:
285 fprintf (file, "%s", symbol->name);
286 break;
287 default:
288 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
289 fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
293 static void
294 bfd_mach_o_convert_architecture (mtype, msubtype, type, subtype)
295 bfd_mach_o_cpu_type mtype;
296 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED;
297 enum bfd_architecture *type;
298 unsigned long *subtype;
300 *subtype = bfd_arch_unknown;
302 switch (mtype)
304 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
305 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
306 case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
307 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
308 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
309 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
310 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
311 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
312 case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
313 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
314 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
315 case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
316 default: *type = bfd_arch_unknown; break;
319 switch (*type)
321 case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
322 case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
323 default:
324 *subtype = bfd_arch_unknown;
328 static boolean
329 bfd_mach_o_write_contents (abfd)
330 bfd *abfd;
332 unsigned int i;
333 asection *s;
335 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
337 /* Write data sections first in case they overlap header data to be
338 written later. */
340 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
343 #if 0
344 for (i = 0; i < mdata->header.ncmds; i++)
346 bfd_mach_o_load_command *cur = &mdata->commands[i];
347 if (cur->type != BFD_MACH_O_LC_SEGMENT)
348 break;
351 bfd_mach_o_segment_command *seg = &cur->command.segment;
352 char buf[1024];
353 bfd_vma nbytes = seg->filesize;
354 bfd_vma curoff = seg->fileoff;
356 while (nbytes > 0)
358 bfd_vma thisread = nbytes;
360 if (thisread > 1024)
361 thisread = 1024;
363 bfd_seek (abfd, curoff, SEEK_SET);
364 if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
365 return false;
367 bfd_seek (abfd, curoff, SEEK_SET);
368 if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
369 return false;
371 nbytes -= thisread;
372 curoff += thisread;
376 #endif
378 /* Now write header information. */
379 if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
380 return false;
382 for (i = 0; i < mdata->header.ncmds; i++)
384 unsigned char buf[8];
385 bfd_mach_o_load_command *cur = &mdata->commands[i];
386 unsigned long typeflag;
388 typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
390 bfd_h_put_32 (abfd, typeflag, buf);
391 bfd_h_put_32 (abfd, cur->len, buf + 4);
393 bfd_seek (abfd, cur->offset, SEEK_SET);
394 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
395 return false;
397 switch (cur->type)
399 case BFD_MACH_O_LC_SEGMENT:
400 if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
401 return false;
402 break;
403 case BFD_MACH_O_LC_SYMTAB:
404 if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
405 return false;
406 break;
407 case BFD_MACH_O_LC_SYMSEG:
408 break;
409 case BFD_MACH_O_LC_THREAD:
410 case BFD_MACH_O_LC_UNIXTHREAD:
411 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
412 return false;
413 break;
414 case BFD_MACH_O_LC_LOADFVMLIB:
415 case BFD_MACH_O_LC_IDFVMLIB:
416 case BFD_MACH_O_LC_IDENT:
417 case BFD_MACH_O_LC_FVMFILE:
418 case BFD_MACH_O_LC_PREPAGE:
419 case BFD_MACH_O_LC_DYSYMTAB:
420 case BFD_MACH_O_LC_LOAD_DYLIB:
421 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
422 case BFD_MACH_O_LC_ID_DYLIB:
423 case BFD_MACH_O_LC_LOAD_DYLINKER:
424 case BFD_MACH_O_LC_ID_DYLINKER:
425 case BFD_MACH_O_LC_PREBOUND_DYLIB:
426 case BFD_MACH_O_LC_ROUTINES:
427 case BFD_MACH_O_LC_SUB_FRAMEWORK:
428 break;
429 default:
430 fprintf (stderr,
431 "unable to write unknown load command 0x%lx\n",
432 (long) cur->type);
433 return false;
437 return true;
440 static int
441 bfd_mach_o_sizeof_headers (a, b)
442 bfd *a ATTRIBUTE_UNUSED;
443 boolean b ATTRIBUTE_UNUSED;
445 return 0;
448 /* Make an empty symbol. This is required only because
449 bfd_make_section_anyway wants to create a symbol for the section. */
451 static asymbol *
452 bfd_mach_o_make_empty_symbol (abfd)
453 bfd *abfd;
455 asymbol *new;
457 new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
458 if (new == NULL)
459 return new;
460 new->the_bfd = abfd;
461 return new;
464 static int
465 bfd_mach_o_write_header (abfd, header)
466 bfd *abfd;
467 bfd_mach_o_header *header;
469 unsigned char buf[28];
471 bfd_h_put_32 (abfd, header->magic, buf + 0);
472 bfd_h_put_32 (abfd, header->cputype, buf + 4);
473 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
474 bfd_h_put_32 (abfd, header->filetype, buf + 12);
475 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
476 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
477 bfd_h_put_32 (abfd, header->flags, buf + 24);
479 bfd_seek (abfd, 0, SEEK_SET);
480 if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
481 return -1;
483 return 0;
486 static int
487 bfd_mach_o_read_header (abfd, header)
488 bfd *abfd;
489 bfd_mach_o_header *header;
491 unsigned char buf[28];
492 bfd_vma (*get32) PARAMS ((const bfd_byte *)) = NULL;
494 bfd_seek (abfd, 0, SEEK_SET);
496 if (bfd_bread ((PTR) buf, 28, abfd) != 28)
497 return -1;
499 if (bfd_getb32 (buf) == 0xfeedface)
501 header->byteorder = BFD_ENDIAN_BIG;
502 header->magic = 0xfeedface;
503 get32 = bfd_getb32;
505 else if (bfd_getl32 (buf) == 0xfeedface)
507 header->byteorder = BFD_ENDIAN_LITTLE;
508 header->magic = 0xfeedface;
509 get32 = bfd_getl32;
511 else
513 header->byteorder = BFD_ENDIAN_UNKNOWN;
514 return -1;
517 header->cputype = (*get32) (buf + 4);
518 header->cpusubtype = (*get32) (buf + 8);
519 header->filetype = (*get32) (buf + 12);
520 header->ncmds = (*get32) (buf + 16);
521 header->sizeofcmds = (*get32) (buf + 20);
522 header->flags = (*get32) (buf + 24);
524 return 0;
527 static asection *
528 bfd_mach_o_make_bfd_section (abfd, section)
529 bfd *abfd;
530 bfd_mach_o_section *section;
532 asection *bfdsec;
533 char *sname;
534 const char *prefix = "LC_SEGMENT";
535 unsigned int snamelen;
537 snamelen = strlen (prefix) + 1
538 + strlen (section->segname) + 1
539 + strlen (section->sectname) + 1;
541 sname = (char *) bfd_alloc (abfd, snamelen);
542 if (sname == NULL)
543 return NULL;
544 sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
546 bfdsec = bfd_make_section_anyway (abfd, sname);
547 if (bfdsec == NULL)
548 return NULL;
550 bfdsec->vma = section->addr;
551 bfdsec->lma = section->addr;
552 bfdsec->_raw_size = section->size;
553 bfdsec->filepos = section->offset;
554 bfdsec->alignment_power = section->align;
556 if (section->flags & BFD_MACH_O_S_ZEROFILL)
557 bfdsec->flags = SEC_ALLOC;
558 else
559 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
561 return bfdsec;
564 static int
565 bfd_mach_o_scan_read_section (abfd, section, offset)
566 bfd *abfd;
567 bfd_mach_o_section *section;
568 bfd_vma offset;
570 unsigned char buf[68];
572 bfd_seek (abfd, offset, SEEK_SET);
573 if (bfd_bread ((PTR) buf, 68, abfd) != 68)
574 return -1;
576 memcpy (section->sectname, buf, 16);
577 section->sectname[16] = '\0';
578 memcpy (section->segname, buf + 16, 16);
579 section->segname[16] = '\0';
580 section->addr = bfd_h_get_32 (abfd, buf + 32);
581 section->size = bfd_h_get_32 (abfd, buf + 36);
582 section->offset = bfd_h_get_32 (abfd, buf + 40);
583 section->align = bfd_h_get_32 (abfd, buf + 44);
584 section->reloff = bfd_h_get_32 (abfd, buf + 48);
585 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
586 section->flags = bfd_h_get_32 (abfd, buf + 56);
587 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
588 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
589 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
591 if (section->bfdsection == NULL)
592 return -1;
594 return 0;
597 static int
598 bfd_mach_o_scan_write_section (abfd, section, offset)
599 bfd *abfd;
600 bfd_mach_o_section *section;
601 bfd_vma offset;
603 unsigned char buf[68];
605 memcpy (buf, section->sectname, 16);
606 memcpy (buf + 16, section->segname, 16);
607 bfd_h_put_32 (abfd, section->addr, buf + 32);
608 bfd_h_put_32 (abfd, section->size, buf + 36);
609 bfd_h_put_32 (abfd, section->offset, buf + 40);
610 bfd_h_put_32 (abfd, section->align, buf + 44);
611 bfd_h_put_32 (abfd, section->reloff, buf + 48);
612 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
613 bfd_h_put_32 (abfd, section->flags, buf + 56);
614 /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
615 /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
617 bfd_seek (abfd, offset, SEEK_SET);
618 if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
619 return -1;
621 return 0;
624 static int
625 bfd_mach_o_scan_write_symtab_symbols (abfd, command)
626 bfd *abfd;
627 bfd_mach_o_load_command *command;
629 bfd_mach_o_symtab_command *sym = &command->command.symtab;
630 asymbol *s = NULL;
631 unsigned long i;
633 for (i = 0; i < sym->nsyms; i++)
635 unsigned char buf[12];
636 bfd_vma symoff = sym->symoff + (i * 12);
637 unsigned char ntype = 0;
638 unsigned char nsect = 0;
639 short ndesc = 0;
641 s = &sym->symbols[i];
643 /* Don't set this from the symbol information; use stored values. */
644 #if 0
645 if (s->flags & BSF_GLOBAL)
646 ntype |= N_EXT;
647 if (s->flags & BSF_DEBUGGING)
648 ntype |= N_STAB;
650 if (s->section == bfd_und_section_ptr)
651 ntype |= N_UNDF;
652 else if (s->section == bfd_abs_section_ptr)
653 ntype |= N_ABS;
654 else
655 ntype |= N_SECT;
656 #endif
658 /* Instead just set from the stored values. */
659 ntype = (s->udata.i >> 24) & 0xff;
660 nsect = (s->udata.i >> 16) & 0xff;
661 ndesc = s->udata.i & 0xffff;
663 bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
664 bfd_h_put_8 (abfd, ntype, buf + 4);
665 bfd_h_put_8 (abfd, nsect, buf + 5);
666 bfd_h_put_16 (abfd, ndesc, buf + 6);
667 bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
669 bfd_seek (abfd, symoff, SEEK_SET);
670 if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
672 fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
673 12, (unsigned long) symoff);
674 return -1;
678 return 0;
682 bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)
683 bfd *abfd;
684 bfd_mach_o_symtab_command *sym;
685 asymbol *s;
686 unsigned long i;
688 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
689 bfd_vma symoff = sym->symoff + (i * 12);
690 unsigned char buf[12];
691 unsigned char type = -1;
692 unsigned char section = -1;
693 short desc = -1;
694 unsigned long value = -1;
695 unsigned long stroff = -1;
696 unsigned int symtype = -1;
698 BFD_ASSERT (sym->strtab != NULL);
700 bfd_seek (abfd, symoff, SEEK_SET);
701 if (bfd_bread ((PTR) buf, 12, abfd) != 12)
703 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
704 12, (unsigned long) symoff);
705 return -1;
708 stroff = bfd_h_get_32 (abfd, buf);
709 type = bfd_h_get_8 (abfd, buf + 4);
710 symtype = (type & 0x0e);
711 section = bfd_h_get_8 (abfd, buf + 5) - 1;
712 desc = bfd_h_get_16 (abfd, buf + 6);
713 value = bfd_h_get_32 (abfd, buf + 8);
715 if (stroff >= sym->strsize)
717 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
718 (unsigned long) stroff, (unsigned long) sym->strsize);
719 return -1;
722 s->the_bfd = abfd;
723 s->name = sym->strtab + stroff;
724 s->value = value;
725 s->udata.i = (type << 24) | (section << 16) | desc;
726 s->flags = 0x0;
728 if (type & BFD_MACH_O_N_STAB)
730 s->flags |= BSF_DEBUGGING;
731 s->section = bfd_und_section_ptr;
733 else
735 if (type & BFD_MACH_O_N_PEXT)
737 type &= ~BFD_MACH_O_N_PEXT;
738 s->flags |= BSF_GLOBAL;
741 if (type & BFD_MACH_O_N_EXT)
743 type &= ~BFD_MACH_O_N_EXT;
744 s->flags |= BSF_GLOBAL;
747 switch (symtype)
749 case BFD_MACH_O_N_UNDF:
750 s->section = bfd_und_section_ptr;
751 break;
752 case BFD_MACH_O_N_PBUD:
753 s->section = bfd_und_section_ptr;
754 break;
755 case BFD_MACH_O_N_ABS:
756 s->section = bfd_abs_section_ptr;
757 break;
758 case BFD_MACH_O_N_SECT:
759 if ((section > 0) && (section <= mdata->nsects))
761 s->section = mdata->sections[section - 1]->bfdsection;
762 s->value = s->value - mdata->sections[section - 1]->addr;
764 else
766 /* Mach-O uses 0 to mean "no section"; not an error. */
767 if (section != 0)
769 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
770 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
771 s->name, section, mdata->nsects);
773 s->section = bfd_und_section_ptr;
775 break;
776 case BFD_MACH_O_N_INDR:
777 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
778 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
779 s->name);
780 s->section = bfd_und_section_ptr;
781 break;
782 default:
783 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
784 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
785 s->name, symtype);
786 s->section = bfd_und_section_ptr;
787 break;
791 return 0;
795 bfd_mach_o_scan_read_symtab_strtab (abfd, sym)
796 bfd *abfd;
797 bfd_mach_o_symtab_command *sym;
799 BFD_ASSERT (sym->strtab == NULL);
801 if (abfd->flags & BFD_IN_MEMORY)
803 struct bfd_in_memory *b;
805 b = (struct bfd_in_memory *) abfd->iostream;
807 if ((sym->stroff + sym->strsize) > b->size)
809 bfd_set_error (bfd_error_file_truncated);
810 return -1;
812 sym->strtab = b->buffer + sym->stroff;
813 return 0;
816 sym->strtab = bfd_alloc (abfd, sym->strsize);
817 if (sym->strtab == NULL)
818 return -1;
820 bfd_seek (abfd, sym->stroff, SEEK_SET);
821 if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
823 fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
824 sym->strsize, sym->stroff);
825 return -1;
828 return 0;
832 bfd_mach_o_scan_read_symtab_symbols (abfd, sym)
833 bfd *abfd;
834 bfd_mach_o_symtab_command *sym;
836 unsigned long i;
837 int ret;
839 BFD_ASSERT (sym->symbols == NULL);
840 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
842 if (sym->symbols == NULL)
844 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
845 return -1;
848 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
849 if (ret != 0)
850 return ret;
852 for (i = 0; i < sym->nsyms; i++)
854 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
855 if (ret != 0)
856 return ret;
859 return 0;
863 bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, s, i)
864 bfd *abfd;
865 bfd_mach_o_dysymtab_command *dysym;
866 bfd_mach_o_symtab_command *sym;
867 asymbol *s;
868 unsigned long i;
870 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
871 unsigned long symindex;
872 unsigned char buf[4];
874 BFD_ASSERT (i < dysym->nindirectsyms);
876 bfd_seek (abfd, isymoff, SEEK_SET);
877 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
879 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
880 (unsigned long) 4, isymoff);
881 return -1;
883 symindex = bfd_h_get_32 (abfd, buf);
885 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
888 static const char *
889 bfd_mach_o_i386_flavour_string (flavour)
890 unsigned int flavour;
892 switch ((int) flavour)
894 case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
895 case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
896 case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
897 case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
898 case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
899 case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
900 case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
901 case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
902 case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
903 case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
904 case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
905 case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
906 default: return "UNKNOWN";
910 static const char *
911 bfd_mach_o_ppc_flavour_string (flavour)
912 unsigned int flavour;
914 switch ((int) flavour)
916 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
917 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
918 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
919 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
920 default: return "UNKNOWN";
924 static int
925 bfd_mach_o_scan_write_thread (abfd, command)
926 bfd *abfd;
927 bfd_mach_o_load_command *command;
929 bfd_mach_o_thread_command *cmd = &command->command.thread;
930 unsigned int i;
931 unsigned char buf[8];
932 bfd_vma offset;
933 unsigned int nflavours;
935 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
936 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
938 offset = 8;
939 nflavours = 0;
940 for (i = 0; i < cmd->nflavours; i++)
942 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
943 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
945 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
946 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
948 bfd_seek (abfd, command->offset + offset, SEEK_SET);
949 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
950 return -1;
952 offset += cmd->flavours[i].size + 8;
955 return 0;
958 static int
959 bfd_mach_o_scan_read_dylinker (abfd, command)
960 bfd *abfd;
961 bfd_mach_o_load_command *command;
963 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
964 unsigned char buf[4];
965 unsigned int nameoff;
966 asection *bfdsec;
967 char *sname;
968 const char *prefix;
970 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
971 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
973 bfd_seek (abfd, command->offset + 8, SEEK_SET);
974 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
975 return -1;
977 nameoff = bfd_h_get_32 (abfd, buf + 0);
979 cmd->name_offset = command->offset + nameoff;
980 cmd->name_len = command->len - nameoff;
982 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
983 prefix = "LC_LOAD_DYLINKER";
984 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
985 prefix = "LC_ID_DYLINKER";
986 else
987 abort ();
989 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
990 if (sname == NULL)
991 return -1;
992 strcpy (sname, prefix);
994 bfdsec = bfd_make_section_anyway (abfd, sname);
995 if (bfdsec == NULL)
996 return -1;
998 bfdsec->vma = 0;
999 bfdsec->lma = 0;
1000 bfdsec->_raw_size = command->len - 8;
1001 bfdsec->filepos = command->offset + 8;
1002 bfdsec->alignment_power = 0;
1003 bfdsec->flags = SEC_HAS_CONTENTS;
1005 cmd->section = bfdsec;
1007 return 0;
1010 static int
1011 bfd_mach_o_scan_read_dylib (abfd, command)
1012 bfd *abfd;
1013 bfd_mach_o_load_command *command;
1015 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1016 unsigned char buf[16];
1017 unsigned int nameoff;
1018 asection *bfdsec;
1019 char *sname;
1020 const char *prefix;
1022 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1023 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1024 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1026 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1027 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1028 return -1;
1030 nameoff = bfd_h_get_32 (abfd, buf + 0);
1031 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1032 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1033 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1035 cmd->name_offset = command->offset + nameoff;
1036 cmd->name_len = command->len - nameoff;
1038 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1039 prefix = "LC_LOAD_DYLIB";
1040 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1041 prefix = "LC_LOAD_WEAK_DYLIB";
1042 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1043 prefix = "LC_ID_DYLIB";
1044 else
1045 abort ();
1047 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1048 if (sname == NULL)
1049 return -1;
1050 strcpy (sname, prefix);
1052 bfdsec = bfd_make_section_anyway (abfd, sname);
1053 if (bfdsec == NULL)
1054 return -1;
1056 bfdsec->vma = 0;
1057 bfdsec->lma = 0;
1058 bfdsec->_raw_size = command->len - 8;
1059 bfdsec->filepos = command->offset + 8;
1060 bfdsec->alignment_power = 0;
1061 bfdsec->flags = SEC_HAS_CONTENTS;
1063 cmd->section = bfdsec;
1065 return 0;
1068 static int
1069 bfd_mach_o_scan_read_prebound_dylib (abfd, command)
1070 bfd *abfd ATTRIBUTE_UNUSED;
1071 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED;
1073 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1075 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1076 return 0;
1079 static int
1080 bfd_mach_o_scan_read_thread (abfd, command)
1081 bfd *abfd;
1082 bfd_mach_o_load_command *command;
1084 bfd_mach_o_data_struct *mdata = NULL;
1085 bfd_mach_o_thread_command *cmd = &command->command.thread;
1086 unsigned char buf[8];
1087 bfd_vma offset;
1088 unsigned int nflavours;
1089 unsigned int i;
1091 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1092 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1094 BFD_ASSERT (bfd_mach_o_valid (abfd));
1095 mdata = abfd->tdata.mach_o_data;
1097 offset = 8;
1098 nflavours = 0;
1099 while (offset != command->len)
1101 if (offset >= command->len)
1102 return -1;
1104 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1106 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1107 return -1;
1109 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1110 nflavours++;
1113 cmd->flavours =
1114 ((bfd_mach_o_thread_flavour *)
1115 bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour)));
1116 if (cmd->flavours == NULL)
1117 return -1;
1118 cmd->nflavours = nflavours;
1120 offset = 8;
1121 nflavours = 0;
1122 while (offset != command->len)
1124 if (offset >= command->len)
1125 return -1;
1127 if (nflavours >= cmd->nflavours)
1128 return -1;
1130 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1132 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1133 return -1;
1135 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1136 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1137 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1138 offset += cmd->flavours[nflavours].size + 8;
1139 nflavours++;
1142 for (i = 0; i < nflavours; i++)
1144 asection *bfdsec;
1145 unsigned int snamelen;
1146 char *sname;
1147 const char *flavourstr;
1148 const char *prefix = "LC_THREAD";
1149 unsigned int j = 0;
1151 switch (mdata->header.cputype)
1153 case BFD_MACH_O_CPU_TYPE_POWERPC:
1154 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1155 break;
1156 case BFD_MACH_O_CPU_TYPE_I386:
1157 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1158 break;
1159 default:
1160 flavourstr = "UNKNOWN_ARCHITECTURE";
1161 break;
1164 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1165 sname = (char *) bfd_alloc (abfd, snamelen);
1166 if (sname == NULL)
1167 return -1;
1169 for (;;)
1171 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1172 if (bfd_get_section_by_name (abfd, sname) == NULL)
1173 break;
1174 j++;
1177 bfdsec = bfd_make_section (abfd, sname);
1179 bfdsec->vma = 0;
1180 bfdsec->lma = 0;
1181 bfdsec->_raw_size = cmd->flavours[i].size;
1182 bfdsec->filepos = cmd->flavours[i].offset;
1183 bfdsec->alignment_power = 0x0;
1184 bfdsec->flags = SEC_HAS_CONTENTS;
1186 cmd->section = bfdsec;
1189 return 0;
1192 static int
1193 bfd_mach_o_scan_write_symtab (abfd, command)
1194 bfd *abfd;
1195 bfd_mach_o_load_command *command;
1197 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1198 unsigned char buf[16];
1200 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1202 bfd_h_put_32 (abfd, seg->symoff, buf);
1203 bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
1204 bfd_h_put_32 (abfd, seg->stroff, buf + 8);
1205 bfd_h_put_32 (abfd, seg->strsize, buf + 12);
1207 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1208 if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
1209 return -1;
1211 if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
1212 return -1;
1214 return 0;
1217 static int
1218 bfd_mach_o_scan_read_dysymtab (abfd, command)
1219 bfd *abfd;
1220 bfd_mach_o_load_command *command;
1222 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1223 unsigned char buf[72];
1225 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1227 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1228 if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1229 return -1;
1231 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1232 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1233 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1234 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1235 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1236 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1237 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1238 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1239 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1240 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1241 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1242 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1243 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1244 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1245 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1246 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1247 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1248 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1250 return 0;
1253 static int
1254 bfd_mach_o_scan_read_symtab (abfd, command)
1255 bfd *abfd;
1256 bfd_mach_o_load_command *command;
1258 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1259 unsigned char buf[16];
1260 asection *bfdsec;
1261 char *sname;
1262 const char *prefix = "LC_SYMTAB.stabs";
1264 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1266 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1267 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1268 return -1;
1270 seg->symoff = bfd_h_get_32 (abfd, buf);
1271 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1272 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1273 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1274 seg->symbols = NULL;
1275 seg->strtab = NULL;
1277 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1278 if (sname == NULL)
1279 return -1;
1280 strcpy (sname, prefix);
1282 bfdsec = bfd_make_section_anyway (abfd, sname);
1283 if (bfdsec == NULL)
1284 return -1;
1286 bfdsec->vma = 0;
1287 bfdsec->lma = 0;
1288 bfdsec->_raw_size = seg->nsyms * 12;
1289 bfdsec->filepos = seg->symoff;
1290 bfdsec->alignment_power = 0;
1291 bfdsec->flags = SEC_HAS_CONTENTS;
1293 seg->stabs_segment = bfdsec;
1295 prefix = "LC_SYMTAB.stabstr";
1296 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1297 if (sname == NULL)
1298 return -1;
1299 strcpy (sname, prefix);
1301 bfdsec = bfd_make_section_anyway (abfd, sname);
1302 if (bfdsec == NULL)
1303 return -1;
1305 bfdsec->vma = 0;
1306 bfdsec->lma = 0;
1307 bfdsec->_raw_size = seg->strsize;
1308 bfdsec->filepos = seg->stroff;
1309 bfdsec->alignment_power = 0;
1310 bfdsec->flags = SEC_HAS_CONTENTS;
1312 seg->stabstr_segment = bfdsec;
1314 return 0;
1317 static int
1318 bfd_mach_o_scan_read_segment (abfd, command)
1319 bfd *abfd;
1320 bfd_mach_o_load_command *command;
1322 unsigned char buf[48];
1323 bfd_mach_o_segment_command *seg = &command->command.segment;
1324 unsigned long i;
1325 asection *bfdsec;
1326 char *sname;
1327 const char *prefix = "LC_SEGMENT";
1328 unsigned int snamelen;
1330 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1332 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1333 if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1334 return -1;
1336 memcpy (seg->segname, buf, 16);
1337 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1338 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1339 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1340 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
1341 /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1342 /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1343 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1344 seg->flags = bfd_h_get_32 (abfd, buf + 44);
1346 snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1347 sname = (char *) bfd_alloc (abfd, snamelen);
1348 if (sname == NULL)
1349 return -1;
1350 sprintf (sname, "%s.%s", prefix, seg->segname);
1352 bfdsec = bfd_make_section_anyway (abfd, sname);
1353 if (bfdsec == NULL)
1354 return -1;
1356 bfdsec->vma = seg->vmaddr;
1357 bfdsec->lma = seg->vmaddr;
1358 bfdsec->_raw_size = seg->filesize;
1359 bfdsec->filepos = seg->fileoff;
1360 bfdsec->alignment_power = 0x0;
1361 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1363 seg->segment = bfdsec;
1365 if (seg->nsects != 0)
1367 seg->sections =
1368 ((bfd_mach_o_section *)
1369 bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)));
1370 if (seg->sections == NULL)
1371 return -1;
1373 for (i = 0; i < seg->nsects; i++)
1375 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1377 if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1378 segoff) != 0)
1379 return -1;
1383 return 0;
1386 static int
1387 bfd_mach_o_scan_write_segment (abfd, command)
1388 bfd *abfd;
1389 bfd_mach_o_load_command *command;
1391 unsigned char buf[48];
1392 bfd_mach_o_segment_command *seg = &command->command.segment;
1393 unsigned long i;
1395 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1397 memcpy (buf, seg->segname, 16);
1398 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
1399 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
1400 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
1401 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
1402 bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
1403 bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
1404 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
1405 bfd_h_put_32 (abfd, seg->flags, buf + 44);
1407 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1408 if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
1409 return -1;
1412 char buf[1024];
1413 bfd_vma nbytes = seg->filesize;
1414 bfd_vma curoff = seg->fileoff;
1416 while (nbytes > 0)
1418 bfd_vma thisread = nbytes;
1420 if (thisread > 1024)
1421 thisread = 1024;
1423 bfd_seek (abfd, curoff, SEEK_SET);
1424 if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
1425 return -1;
1427 bfd_seek (abfd, curoff, SEEK_SET);
1428 if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
1429 return -1;
1431 nbytes -= thisread;
1432 curoff += thisread;
1436 for (i = 0; i < seg->nsects; i++)
1438 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1440 if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
1441 return -1;
1444 return 0;
1447 static int
1448 bfd_mach_o_scan_read_command (abfd, command)
1449 bfd *abfd;
1450 bfd_mach_o_load_command *command;
1452 unsigned char buf[8];
1454 bfd_seek (abfd, command->offset, SEEK_SET);
1455 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1456 return -1;
1458 command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1459 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1460 ? 1 : 0);
1461 command->len = bfd_h_get_32 (abfd, buf + 4);
1463 switch (command->type)
1465 case BFD_MACH_O_LC_SEGMENT:
1466 if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1467 return -1;
1468 break;
1469 case BFD_MACH_O_LC_SYMTAB:
1470 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1471 return -1;
1472 break;
1473 case BFD_MACH_O_LC_SYMSEG:
1474 break;
1475 case BFD_MACH_O_LC_THREAD:
1476 case BFD_MACH_O_LC_UNIXTHREAD:
1477 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1478 return -1;
1479 break;
1480 case BFD_MACH_O_LC_LOAD_DYLINKER:
1481 case BFD_MACH_O_LC_ID_DYLINKER:
1482 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1483 return -1;
1484 break;
1485 case BFD_MACH_O_LC_LOAD_DYLIB:
1486 case BFD_MACH_O_LC_ID_DYLIB:
1487 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1488 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1489 return -1;
1490 break;
1491 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1492 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1493 return -1;
1494 break;
1495 case BFD_MACH_O_LC_LOADFVMLIB:
1496 case BFD_MACH_O_LC_IDFVMLIB:
1497 case BFD_MACH_O_LC_IDENT:
1498 case BFD_MACH_O_LC_FVMFILE:
1499 case BFD_MACH_O_LC_PREPAGE:
1500 case BFD_MACH_O_LC_ROUTINES:
1501 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1502 break;
1503 case BFD_MACH_O_LC_DYSYMTAB:
1504 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1505 return -1;
1506 break;
1507 case BFD_MACH_O_LC_SUB_UMBRELLA:
1508 case BFD_MACH_O_LC_SUB_CLIENT:
1509 case BFD_MACH_O_LC_SUB_LIBRARY:
1510 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1511 case BFD_MACH_O_LC_PREBIND_CKSUM:
1512 break;
1513 default:
1514 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1515 (unsigned long) command->type);
1516 break;
1519 return 0;
1522 static void
1523 bfd_mach_o_flatten_sections (abfd)
1524 bfd *abfd;
1526 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1527 long csect = 0;
1528 unsigned long i, j;
1530 mdata->nsects = 0;
1532 for (i = 0; i < mdata->header.ncmds; i++)
1534 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1536 bfd_mach_o_segment_command *seg;
1538 seg = &mdata->commands[i].command.segment;
1539 mdata->nsects += seg->nsects;
1543 mdata->sections = bfd_alloc (abfd,
1544 mdata->nsects * sizeof (bfd_mach_o_section *));
1545 csect = 0;
1547 for (i = 0; i < mdata->header.ncmds; i++)
1549 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1551 bfd_mach_o_segment_command *seg;
1553 seg = &mdata->commands[i].command.segment;
1554 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1556 for (j = 0; j < seg->nsects; j++)
1557 mdata->sections[csect++] = &seg->sections[j];
1563 bfd_mach_o_scan_start_address (abfd)
1564 bfd *abfd;
1566 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1567 bfd_mach_o_thread_command *cmd = NULL;
1568 unsigned long i;
1570 for (i = 0; i < mdata->header.ncmds; i++)
1572 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1573 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1575 if (cmd == NULL)
1576 cmd = &mdata->commands[i].command.thread;
1577 else
1578 return 0;
1582 if (cmd == NULL)
1583 return 0;
1585 for (i = 0; i < cmd->nflavours; i++)
1587 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1588 && (cmd->flavours[i].flavour
1589 == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1591 unsigned char buf[4];
1593 bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1595 if (bfd_bread (buf, 4, abfd) != 4)
1596 return -1;
1598 abfd->start_address = bfd_h_get_32 (abfd, buf);
1600 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1601 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1603 unsigned char buf[4];
1605 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1607 if (bfd_bread (buf, 4, abfd) != 4)
1608 return -1;
1610 abfd->start_address = bfd_h_get_32 (abfd, buf);
1614 return 0;
1618 bfd_mach_o_scan (abfd, header, mdata)
1619 bfd *abfd;
1620 bfd_mach_o_header *header;
1621 bfd_mach_o_data_struct *mdata;
1623 unsigned int i;
1624 enum bfd_architecture cputype;
1625 unsigned long cpusubtype;
1627 mdata->header = *header;
1628 mdata->symbols = NULL;
1630 abfd->flags = (abfd->xvec->object_flags
1631 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1632 abfd->tdata.mach_o_data = mdata;
1634 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1635 &cputype, &cpusubtype);
1636 if (cputype == bfd_arch_unknown)
1638 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1639 header->cputype, header->cpusubtype);
1640 return -1;
1643 bfd_set_arch_mach (abfd, cputype, cpusubtype);
1645 if (header->ncmds != 0)
1647 mdata->commands =
1648 ((bfd_mach_o_load_command *)
1649 bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));
1650 if (mdata->commands == NULL)
1651 return -1;
1653 for (i = 0; i < header->ncmds; i++)
1655 bfd_mach_o_load_command *cur = &mdata->commands[i];
1657 if (i == 0)
1658 cur->offset = 28;
1659 else
1661 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1662 cur->offset = prev->offset + prev->len;
1665 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1666 return -1;
1670 if (bfd_mach_o_scan_start_address (abfd) < 0)
1672 #if 0
1673 fprintf (stderr, "bfd_mach_o_scan: unable to scan start address: %s\n",
1674 bfd_errmsg (bfd_get_error ()));
1675 abfd->tdata.mach_o_data = NULL;
1676 return -1;
1677 #endif
1680 bfd_mach_o_flatten_sections (abfd);
1682 return 0;
1685 boolean
1686 bfd_mach_o_mkobject (abfd)
1687 bfd *abfd;
1689 bfd_mach_o_data_struct *mdata = NULL;
1691 mdata = ((bfd_mach_o_data_struct *)
1692 bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
1693 if (mdata == NULL)
1694 return false;
1695 abfd->tdata.mach_o_data = mdata;
1697 mdata->header.magic = 0;
1698 mdata->header.cputype = 0;
1699 mdata->header.cpusubtype = 0;
1700 mdata->header.filetype = 0;
1701 mdata->header.ncmds = 0;
1702 mdata->header.sizeofcmds = 0;
1703 mdata->header.flags = 0;
1704 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1705 mdata->commands = NULL;
1706 mdata->nsymbols = 0;
1707 mdata->symbols = NULL;
1708 mdata->nsects = 0;
1709 mdata->sections = NULL;
1710 mdata->ibfd = NULL;
1712 return true;
1715 const bfd_target *
1716 bfd_mach_o_object_p (abfd)
1717 bfd *abfd;
1719 struct bfd_preserve preserve;
1720 bfd_mach_o_header header;
1722 preserve.marker = NULL;
1723 if (bfd_mach_o_read_header (abfd, &header) != 0)
1724 goto wrong;
1726 if (! (header.byteorder == BFD_ENDIAN_BIG
1727 || header.byteorder == BFD_ENDIAN_LITTLE))
1729 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1730 (long) header.byteorder);
1731 goto wrong;
1734 if (! ((header.byteorder == BFD_ENDIAN_BIG
1735 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1736 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1737 || (header.byteorder == BFD_ENDIAN_LITTLE
1738 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1739 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1740 goto wrong;
1742 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1743 if (preserve.marker == NULL
1744 || !bfd_preserve_save (abfd, &preserve))
1745 goto fail;
1747 if (bfd_mach_o_scan (abfd, &header,
1748 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1749 goto wrong;
1751 bfd_preserve_finish (abfd, &preserve);
1752 return abfd->xvec;
1754 wrong:
1755 bfd_set_error (bfd_error_wrong_format);
1757 fail:
1758 if (preserve.marker != NULL)
1759 bfd_preserve_restore (abfd, &preserve);
1760 return NULL;
1763 const bfd_target *
1764 bfd_mach_o_core_p (abfd)
1765 bfd *abfd;
1767 struct bfd_preserve preserve;
1768 bfd_mach_o_header header;
1770 preserve.marker = NULL;
1771 if (bfd_mach_o_read_header (abfd, &header) != 0)
1772 goto wrong;
1774 if (! (header.byteorder == BFD_ENDIAN_BIG
1775 || header.byteorder == BFD_ENDIAN_LITTLE))
1777 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1778 (long) header.byteorder);
1779 abort ();
1782 if (! ((header.byteorder == BFD_ENDIAN_BIG
1783 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1784 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1785 || (header.byteorder == BFD_ENDIAN_LITTLE
1786 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1787 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1788 goto wrong;
1790 if (header.filetype != BFD_MACH_O_MH_CORE)
1791 goto wrong;
1793 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1794 if (preserve.marker == NULL
1795 || !bfd_preserve_save (abfd, &preserve))
1796 goto fail;
1798 if (bfd_mach_o_scan (abfd, &header,
1799 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1800 goto wrong;
1802 bfd_preserve_finish (abfd, &preserve);
1803 return abfd->xvec;
1805 wrong:
1806 bfd_set_error (bfd_error_wrong_format);
1808 fail:
1809 if (preserve.marker != NULL)
1810 bfd_preserve_restore (abfd, &preserve);
1811 return NULL;
1814 typedef struct mach_o_fat_archentry
1816 unsigned long cputype;
1817 unsigned long cpusubtype;
1818 unsigned long offset;
1819 unsigned long size;
1820 unsigned long align;
1821 bfd *abfd;
1822 } mach_o_fat_archentry;
1824 typedef struct mach_o_fat_data_struct
1826 unsigned long magic;
1827 unsigned long nfat_arch;
1828 mach_o_fat_archentry *archentries;
1829 } mach_o_fat_data_struct;
1831 const bfd_target *
1832 bfd_mach_o_archive_p (abfd)
1833 bfd *abfd;
1835 mach_o_fat_data_struct *adata = NULL;
1836 unsigned char buf[20];
1837 unsigned long i;
1839 bfd_seek (abfd, 0, SEEK_SET);
1840 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1841 goto error;
1843 adata = (mach_o_fat_data_struct *)
1844 bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1845 if (adata == NULL)
1846 goto error;
1848 adata->magic = bfd_getb32 (buf);
1849 adata->nfat_arch = bfd_getb32 (buf + 4);
1850 if (adata->magic != 0xcafebabe)
1851 goto error;
1853 adata->archentries = (mach_o_fat_archentry *)
1854 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1855 if (adata->archentries == NULL)
1856 goto error;
1858 for (i = 0; i < adata->nfat_arch; i++)
1860 bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1862 if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1863 goto error;
1864 adata->archentries[i].cputype = bfd_getb32 (buf);
1865 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1866 adata->archentries[i].offset = bfd_getb32 (buf + 8);
1867 adata->archentries[i].size = bfd_getb32 (buf + 12);
1868 adata->archentries[i].align = bfd_getb32 (buf + 16);
1869 adata->archentries[i].abfd = NULL;
1872 abfd->tdata.mach_o_fat_data = adata;
1873 return abfd->xvec;
1875 error:
1876 if (adata != NULL)
1877 bfd_release (abfd, adata);
1878 bfd_set_error (bfd_error_wrong_format);
1879 return NULL;
1882 bfd *
1883 bfd_mach_o_openr_next_archived_file (archive, prev)
1884 bfd *archive;
1885 bfd *prev;
1887 mach_o_fat_data_struct *adata;
1888 mach_o_fat_archentry *entry = NULL;
1889 unsigned long i;
1891 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
1892 BFD_ASSERT (adata != NULL);
1894 /* Find index of previous entry. */
1895 if (prev == NULL)
1896 i = 0; /* Start at first one. */
1897 else
1899 for (i = 0; i < adata->nfat_arch; i++)
1901 if (adata->archentries[i].abfd == prev)
1902 break;
1905 if (i == adata->nfat_arch)
1907 /* Not found. */
1908 bfd_set_error (bfd_error_bad_value);
1909 return NULL;
1911 i++; /* Get next entry. */
1914 if (i >= adata->nfat_arch)
1916 bfd_set_error (bfd_error_no_more_archived_files);
1917 return NULL;
1920 entry = &adata->archentries[i];
1921 if (entry->abfd == NULL)
1923 bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1924 char *s = NULL;
1926 if (nbfd == NULL)
1927 return NULL;
1929 nbfd->origin = entry->offset;
1930 s = bfd_malloc (strlen (archive->filename) + 1);
1931 if (s == NULL)
1932 return NULL;
1933 strcpy (s, archive->filename);
1934 nbfd->filename = s;
1935 nbfd->iostream = NULL;
1936 entry->abfd = nbfd;
1939 return entry->abfd;
1943 bfd_mach_o_lookup_section (abfd, section, mcommand, msection)
1944 bfd *abfd;
1945 asection *section;
1946 bfd_mach_o_load_command **mcommand;
1947 bfd_mach_o_section **msection;
1949 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1950 unsigned int i, j, num;
1952 bfd_mach_o_load_command *ncmd = NULL;
1953 bfd_mach_o_section *nsect = NULL;
1955 BFD_ASSERT (mcommand != NULL);
1956 BFD_ASSERT (msection != NULL);
1958 num = 0;
1959 for (i = 0; i < md->header.ncmds; i++)
1961 struct bfd_mach_o_load_command *cmd = &md->commands[i];
1962 struct bfd_mach_o_segment_command *seg = NULL;
1964 if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1965 continue;
1966 seg = &cmd->command.segment;
1968 if (seg->segment == section)
1970 if (num == 0)
1971 ncmd = cmd;
1972 num++;
1975 for (j = 0; j < seg->nsects; j++)
1977 struct bfd_mach_o_section *sect = &seg->sections[j];
1979 if (sect->bfdsection == section)
1981 if (num == 0)
1982 nsect = sect;
1983 num++;
1988 *mcommand = ncmd;
1989 *msection = nsect;
1990 return num;
1994 bfd_mach_o_lookup_command (abfd, type, mcommand)
1995 bfd *abfd;
1996 bfd_mach_o_load_command_type type;
1997 bfd_mach_o_load_command **mcommand;
1999 struct mach_o_data_struct *md = NULL;
2000 bfd_mach_o_load_command *ncmd = NULL;
2001 unsigned int i, num;
2003 md = abfd->tdata.mach_o_data;
2005 BFD_ASSERT (md != NULL);
2006 BFD_ASSERT (mcommand != NULL);
2008 num = 0;
2009 for (i = 0; i < md->header.ncmds; i++)
2011 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2013 if (cmd->type != type)
2014 continue;
2016 if (num == 0)
2017 ncmd = cmd;
2018 num++;
2021 *mcommand = ncmd;
2022 return num;
2025 unsigned long
2026 bfd_mach_o_stack_addr (type)
2027 enum bfd_mach_o_cpu_type type;
2029 switch (type)
2031 case BFD_MACH_O_CPU_TYPE_MC680x0:
2032 return 0x04000000;
2033 case BFD_MACH_O_CPU_TYPE_MC88000:
2034 return 0xffffe000;
2035 case BFD_MACH_O_CPU_TYPE_POWERPC:
2036 return 0xc0000000;
2037 case BFD_MACH_O_CPU_TYPE_I386:
2038 return 0xc0000000;
2039 case BFD_MACH_O_CPU_TYPE_SPARC:
2040 return 0xf0000000;
2041 case BFD_MACH_O_CPU_TYPE_I860:
2042 return 0;
2043 case BFD_MACH_O_CPU_TYPE_HPPA:
2044 return 0xc0000000 - 0x04000000;
2045 default:
2046 return 0;
2051 bfd_mach_o_core_fetch_environment (abfd, rbuf, rlen)
2052 bfd *abfd;
2053 unsigned char **rbuf;
2054 unsigned int *rlen;
2056 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2057 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2058 unsigned int i = 0;
2060 for (i = 0; i < mdata->header.ncmds; i++)
2062 bfd_mach_o_load_command *cur = &mdata->commands[i];
2063 bfd_mach_o_segment_command *seg = NULL;
2065 if (cur->type != BFD_MACH_O_LC_SEGMENT)
2066 continue;
2068 seg = &cur->command.segment;
2070 if ((seg->vmaddr + seg->vmsize) == stackaddr)
2072 unsigned long start = seg->fileoff;
2073 unsigned long end = seg->fileoff + seg->filesize;
2074 unsigned char *buf = bfd_malloc (1024);
2075 unsigned long size = 1024;
2077 for (;;)
2079 bfd_size_type nread = 0;
2080 unsigned long offset;
2081 int found_nonnull = 0;
2083 if (size > (end - start))
2084 size = (end - start);
2086 buf = bfd_realloc (buf, size);
2088 bfd_seek (abfd, end - size, SEEK_SET);
2089 nread = bfd_bread (buf, size, abfd);
2091 if (nread != size)
2092 return -1;
2094 for (offset = 4; offset <= size; offset += 4)
2096 unsigned long val;
2098 val = *((unsigned long *) (buf + size - offset));
2099 if (! found_nonnull)
2101 if (val != 0)
2102 found_nonnull = 1;
2104 else if (val == 0x0)
2106 unsigned long bottom;
2107 unsigned long top;
2109 bottom = seg->fileoff + seg->filesize - offset;
2110 top = seg->fileoff + seg->filesize - 4;
2111 *rbuf = bfd_malloc (top - bottom);
2112 *rlen = top - bottom;
2114 memcpy (*rbuf, buf + size - *rlen, *rlen);
2115 return 0;
2119 if (size == (end - start))
2120 break;
2122 size *= 2;
2127 return -1;
2130 char *
2131 bfd_mach_o_core_file_failing_command (abfd)
2132 bfd *abfd;
2134 unsigned char *buf = NULL;
2135 unsigned int len = 0;
2136 int ret = -1;
2138 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
2139 if (ret < 0)
2140 return NULL;
2142 return buf;
2146 bfd_mach_o_core_file_failing_signal (abfd)
2147 bfd *abfd ATTRIBUTE_UNUSED;
2149 return 0;
2152 boolean
2153 bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)
2154 bfd *core_bfd ATTRIBUTE_UNUSED;
2155 bfd *exec_bfd ATTRIBUTE_UNUSED;
2157 return true;
2160 #define TARGET_NAME mach_o_be_vec
2161 #define TARGET_STRING "mach-o-be"
2162 #define TARGET_BIG_ENDIAN 1
2163 #define TARGET_ARCHIVE 0
2165 #include "mach-o-target.c"
2167 #undef TARGET_NAME
2168 #undef TARGET_STRING
2169 #undef TARGET_BIG_ENDIAN
2170 #undef TARGET_ARCHIVE
2172 #define TARGET_NAME mach_o_le_vec
2173 #define TARGET_STRING "mach-o-le"
2174 #define TARGET_BIG_ENDIAN 0
2175 #define TARGET_ARCHIVE 0
2177 #include "mach-o-target.c"
2179 #undef TARGET_NAME
2180 #undef TARGET_STRING
2181 #undef TARGET_BIG_ENDIAN
2182 #undef TARGET_ARCHIVE
2184 #define TARGET_NAME mach_o_fat_vec
2185 #define TARGET_STRING "mach-o-fat"
2186 #define TARGET_BIG_ENDIAN 1
2187 #define TARGET_ARCHIVE 1
2189 #include "mach-o-target.c"
2191 #undef TARGET_NAME
2192 #undef TARGET_STRING
2193 #undef TARGET_BIG_ENDIAN
2194 #undef TARGET_ARCHIVE