]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/mach-o.c
* aout-target.h, aoutf1.h, bfdio.c, bfdwin.c: Update copyright date.
[thirdparty/binutils-gdb.git] / bfd / mach-o.c
CommitLineData
3af9a47b 1/* Mach-O support for BFD.
eac93a98 2 Copyright 1999, 2000, 2001, 2002, 2003
3af9a47b
NC
3 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
17 You should have received a copy of the GNU General Public License
a95a4550 18 along with this program; if not, write to the Free Software
3af9a47b
NC
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
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>
27
28#ifndef BFD_IO_FUNCS
29#define BFD_IO_FUNCS 0
30#endif
31
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
72
b34976b6
AM
73static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data
74 PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
75static bfd_boolean bfd_mach_o_bfd_copy_private_section_data
76 PARAMS ((bfd *, asection *, bfd *, asection *));
77static bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data
78 PARAMS ((bfd *, bfd *));
79static long bfd_mach_o_count_symbols
80 PARAMS ((bfd *));
81static long bfd_mach_o_get_symtab_upper_bound
82 PARAMS ((bfd *));
6cee3f79 83static long bfd_mach_o_canonicalize_symtab
b34976b6
AM
84 PARAMS ((bfd *, asymbol **));
85static void bfd_mach_o_get_symbol_info
86 PARAMS ((bfd *, asymbol *, symbol_info *));
87static void bfd_mach_o_print_symbol
88 PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
89static void bfd_mach_o_convert_architecture
90 PARAMS ((bfd_mach_o_cpu_type, bfd_mach_o_cpu_subtype,
91 enum bfd_architecture *, unsigned long *));
92static bfd_boolean bfd_mach_o_write_contents
93 PARAMS ((bfd *));
94static int bfd_mach_o_sizeof_headers
95 PARAMS ((bfd *, bfd_boolean));
96static asymbol * bfd_mach_o_make_empty_symbol
97 PARAMS ((bfd *));
98static int bfd_mach_o_write_header
99 PARAMS ((bfd *, bfd_mach_o_header *));
100static int bfd_mach_o_read_header
101 PARAMS ((bfd *, bfd_mach_o_header *));
102static asection * bfd_mach_o_make_bfd_section
103 PARAMS ((bfd *, bfd_mach_o_section *));
104static int bfd_mach_o_scan_read_section
105 PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
106static int bfd_mach_o_scan_write_section
107 PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
108static int bfd_mach_o_scan_write_symtab_symbols
109 PARAMS ((bfd *, bfd_mach_o_load_command *));
110static int bfd_mach_o_scan_write_thread
111 PARAMS ((bfd *, bfd_mach_o_load_command *));
112static int bfd_mach_o_scan_read_dylinker
113 PARAMS ((bfd *, bfd_mach_o_load_command *));
114static int bfd_mach_o_scan_read_dylib
115 PARAMS ((bfd *, bfd_mach_o_load_command *));
116static int bfd_mach_o_scan_read_prebound_dylib
117 PARAMS ((bfd *, bfd_mach_o_load_command *));
118static int bfd_mach_o_scan_read_thread
119 PARAMS ((bfd *, bfd_mach_o_load_command *));
120static int bfd_mach_o_scan_write_symtab
121 PARAMS ((bfd *, bfd_mach_o_load_command *));
122static int bfd_mach_o_scan_read_dysymtab
123 PARAMS ((bfd *, bfd_mach_o_load_command *));
124static int bfd_mach_o_scan_read_symtab
125 PARAMS ((bfd *, bfd_mach_o_load_command *));
126static int bfd_mach_o_scan_read_segment
127 PARAMS ((bfd *, bfd_mach_o_load_command *));
128static int bfd_mach_o_scan_write_segment
129 PARAMS ((bfd *, bfd_mach_o_load_command *));
130static int bfd_mach_o_scan_read_command
131 PARAMS ((bfd *, bfd_mach_o_load_command *));
132static void bfd_mach_o_flatten_sections
133 PARAMS ((bfd *));
134static const char * bfd_mach_o_i386_flavour_string
135 PARAMS ((unsigned int));
136static const char * bfd_mach_o_ppc_flavour_string
137 PARAMS ((unsigned int));
3af9a47b
NC
138
139/* The flags field of a section structure is separated into two parts a section
140 type and section attributes. The section types are mutually exclusive (it
141 can only have one type) but the section attributes are not (it may have more
142 than one attribute). */
143
144#define SECTION_TYPE 0x000000ff /* 256 section types. */
145#define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes. */
146
147/* Constants for the section attributes part of the flags field of a section
148 structure. */
149
150#define SECTION_ATTRIBUTES_USR 0xff000000 /* User-settable attributes. */
151#define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* Section contains only true machine instructions. */
152#define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* System setable attributes. */
153#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* Section contains some machine instructions. */
154#define S_ATTR_EXT_RELOC 0x00000200 /* Section has external relocation entries. */
155#define S_ATTR_LOC_RELOC 0x00000100 /* Section has local relocation entries. */
156
157#define N_STAB 0xe0
158#define N_TYPE 0x1e
159#define N_EXT 0x01
160#define N_UNDF 0x0
161#define N_ABS 0x2
162#define N_SECT 0xe
163#define N_INDR 0xa
164
b34976b6 165bfd_boolean
3af9a47b
NC
166bfd_mach_o_valid (abfd)
167 bfd *abfd;
168{
169 if (abfd == NULL || abfd->xvec == NULL)
170 return 0;
171
172 if (! ((abfd->xvec == &mach_o_be_vec)
173 || (abfd->xvec == &mach_o_le_vec)
174 || (abfd->xvec == &mach_o_fat_vec)))
175 return 0;
176
177 if (abfd->tdata.mach_o_data == NULL)
178 return 0;
179 return 1;
180}
181
182/* Copy any private info we understand from the input symbol
183 to the output symbol. */
184
b34976b6 185static bfd_boolean
3af9a47b
NC
186bfd_mach_o_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
187 bfd *ibfd ATTRIBUTE_UNUSED;
188 asymbol *isymbol ATTRIBUTE_UNUSED;
189 bfd *obfd ATTRIBUTE_UNUSED;
190 asymbol *osymbol ATTRIBUTE_UNUSED;
191{
b34976b6 192 return TRUE;
3af9a47b
NC
193}
194
195/* Copy any private info we understand from the input section
196 to the output section. */
197
b34976b6 198static bfd_boolean
3af9a47b
NC
199bfd_mach_o_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
200 bfd *ibfd ATTRIBUTE_UNUSED;
201 asection *isection ATTRIBUTE_UNUSED;
202 bfd *obfd ATTRIBUTE_UNUSED;
203 asection *osection ATTRIBUTE_UNUSED;
204{
b34976b6 205 return TRUE;
3af9a47b
NC
206}
207
208/* Copy any private info we understand from the input bfd
209 to the output bfd. */
210
b34976b6 211static bfd_boolean
3af9a47b
NC
212bfd_mach_o_bfd_copy_private_bfd_data (ibfd, obfd)
213 bfd *ibfd;
214 bfd *obfd;
215{
216 BFD_ASSERT (bfd_mach_o_valid (ibfd));
217 BFD_ASSERT (bfd_mach_o_valid (obfd));
218
219 obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
220 obfd->tdata.mach_o_data->ibfd = ibfd;
b34976b6 221 return TRUE;
3af9a47b
NC
222}
223
224static long
225bfd_mach_o_count_symbols (abfd)
226 bfd *abfd;
227{
228 bfd_mach_o_data_struct *mdata = NULL;
229 long nsyms = 0;
230 unsigned long i;
a95a4550 231
3af9a47b
NC
232 BFD_ASSERT (bfd_mach_o_valid (abfd));
233 mdata = abfd->tdata.mach_o_data;
234
235 for (i = 0; i < mdata->header.ncmds; i++)
236 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
237 {
238 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
239 nsyms += sym->nsyms;
240 }
241
242 return nsyms;
243}
244
245static long
246bfd_mach_o_get_symtab_upper_bound (abfd)
247 bfd *abfd;
248{
249 long nsyms = bfd_mach_o_count_symbols (abfd);
250
251 if (nsyms < 0)
252 return nsyms;
253
254 return ((nsyms + 1) * sizeof (asymbol *));
255}
256
257static long
6cee3f79 258bfd_mach_o_canonicalize_symtab (abfd, alocation)
3af9a47b
NC
259 bfd *abfd;
260 asymbol **alocation;
261{
262 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
263 long nsyms = bfd_mach_o_count_symbols (abfd);
264 asymbol **csym = alocation;
265 unsigned long i, j;
266
267 if (nsyms < 0)
268 return nsyms;
269
270 for (i = 0; i < mdata->header.ncmds; i++)
271 {
272 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
273 {
274 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
275
276 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
277 {
6cee3f79 278 fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
3af9a47b
NC
279 return 0;
280 }
281
282 BFD_ASSERT (sym->symbols != NULL);
283
284 for (j = 0; j < sym->nsyms; j++)
285 {
286 BFD_ASSERT (csym < (alocation + nsyms));
287 *csym++ = &sym->symbols[j];
288 }
289 }
290 }
291
292 *csym++ = NULL;
a95a4550 293
3af9a47b
NC
294 return nsyms;
295}
296
297static void
298bfd_mach_o_get_symbol_info (abfd, symbol, ret)
299 bfd *abfd ATTRIBUTE_UNUSED;
300 asymbol *symbol;
301 symbol_info *ret;
302{
303 bfd_symbol_info (symbol, ret);
304}
305
306static void
307bfd_mach_o_print_symbol (abfd, afile, symbol, how)
308 bfd *abfd;
309 PTR afile;
310 asymbol *symbol;
311 bfd_print_symbol_type how;
312{
313 FILE *file = (FILE *) afile;
314
315 switch (how)
316 {
317 case bfd_print_symbol_name:
318 fprintf (file, "%s", symbol->name);
319 break;
320 default:
321 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
322 fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
323 }
324}
325
326static void
327bfd_mach_o_convert_architecture (mtype, msubtype, type, subtype)
328 bfd_mach_o_cpu_type mtype;
329 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED;
330 enum bfd_architecture *type;
331 unsigned long *subtype;
332{
333 *subtype = bfd_arch_unknown;
334
335 switch (mtype)
336 {
337 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
338 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
339 case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
340 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
341 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
342 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
343 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
344 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
345 case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
346 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
347 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
348 case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
349 default: *type = bfd_arch_unknown; break;
350 }
351
352 switch (*type)
353 {
354 case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
355 case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
356 default:
357 *subtype = bfd_arch_unknown;
358 }
359}
a95a4550 360
b34976b6 361static bfd_boolean
3af9a47b
NC
362bfd_mach_o_write_contents (abfd)
363 bfd *abfd;
364{
365 unsigned int i;
366 asection *s;
367
368 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
369
370 /* Write data sections first in case they overlap header data to be
371 written later. */
372
373 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
374 ;
375
376#if 0
377 for (i = 0; i < mdata->header.ncmds; i++)
378 {
379 bfd_mach_o_load_command *cur = &mdata->commands[i];
380 if (cur->type != BFD_MACH_O_LC_SEGMENT)
381 break;
382
383 {
384 bfd_mach_o_segment_command *seg = &cur->command.segment;
385 char buf[1024];
386 bfd_vma nbytes = seg->filesize;
387 bfd_vma curoff = seg->fileoff;
388
389 while (nbytes > 0)
390 {
391 bfd_vma thisread = nbytes;
392
393 if (thisread > 1024)
394 thisread = 1024;
395
396 bfd_seek (abfd, curoff, SEEK_SET);
397 if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
b34976b6 398 return FALSE;
3af9a47b
NC
399
400 bfd_seek (abfd, curoff, SEEK_SET);
401 if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
b34976b6 402 return FALSE;
3af9a47b
NC
403
404 nbytes -= thisread;
405 curoff += thisread;
406 }
407 }
408 }
409#endif
410
411 /* Now write header information. */
412 if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
b34976b6 413 return FALSE;
3af9a47b
NC
414
415 for (i = 0; i < mdata->header.ncmds; i++)
416 {
417 unsigned char buf[8];
418 bfd_mach_o_load_command *cur = &mdata->commands[i];
419 unsigned long typeflag;
420
421 typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
422
423 bfd_h_put_32 (abfd, typeflag, buf);
424 bfd_h_put_32 (abfd, cur->len, buf + 4);
425
426 bfd_seek (abfd, cur->offset, SEEK_SET);
427 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
b34976b6 428 return FALSE;
3af9a47b
NC
429
430 switch (cur->type)
431 {
432 case BFD_MACH_O_LC_SEGMENT:
433 if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
b34976b6 434 return FALSE;
3af9a47b
NC
435 break;
436 case BFD_MACH_O_LC_SYMTAB:
437 if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
b34976b6 438 return FALSE;
3af9a47b
NC
439 break;
440 case BFD_MACH_O_LC_SYMSEG:
441 break;
442 case BFD_MACH_O_LC_THREAD:
443 case BFD_MACH_O_LC_UNIXTHREAD:
444 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
b34976b6 445 return FALSE;
3af9a47b
NC
446 break;
447 case BFD_MACH_O_LC_LOADFVMLIB:
448 case BFD_MACH_O_LC_IDFVMLIB:
449 case BFD_MACH_O_LC_IDENT:
450 case BFD_MACH_O_LC_FVMFILE:
451 case BFD_MACH_O_LC_PREPAGE:
452 case BFD_MACH_O_LC_DYSYMTAB:
453 case BFD_MACH_O_LC_LOAD_DYLIB:
454 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
455 case BFD_MACH_O_LC_ID_DYLIB:
456 case BFD_MACH_O_LC_LOAD_DYLINKER:
457 case BFD_MACH_O_LC_ID_DYLINKER:
458 case BFD_MACH_O_LC_PREBOUND_DYLIB:
459 case BFD_MACH_O_LC_ROUTINES:
460 case BFD_MACH_O_LC_SUB_FRAMEWORK:
461 break;
462 default:
463 fprintf (stderr,
464 "unable to write unknown load command 0x%lx\n",
465 (long) cur->type);
b34976b6 466 return FALSE;
3af9a47b
NC
467 }
468 }
469
b34976b6 470 return TRUE;
3af9a47b
NC
471}
472
473static int
474bfd_mach_o_sizeof_headers (a, b)
475 bfd *a ATTRIBUTE_UNUSED;
b34976b6 476 bfd_boolean b ATTRIBUTE_UNUSED;
3af9a47b
NC
477{
478 return 0;
479}
480
481/* Make an empty symbol. This is required only because
482 bfd_make_section_anyway wants to create a symbol for the section. */
483
484static asymbol *
485bfd_mach_o_make_empty_symbol (abfd)
486 bfd *abfd;
487{
488 asymbol *new;
489
490 new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
491 if (new == NULL)
492 return new;
493 new->the_bfd = abfd;
494 return new;
495}
496
497static int
498bfd_mach_o_write_header (abfd, header)
499 bfd *abfd;
500 bfd_mach_o_header *header;
501{
502 unsigned char buf[28];
503
504 bfd_h_put_32 (abfd, header->magic, buf + 0);
505 bfd_h_put_32 (abfd, header->cputype, buf + 4);
506 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
507 bfd_h_put_32 (abfd, header->filetype, buf + 12);
508 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
509 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
510 bfd_h_put_32 (abfd, header->flags, buf + 24);
a95a4550 511
3af9a47b
NC
512 bfd_seek (abfd, 0, SEEK_SET);
513 if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
514 return -1;
515
516 return 0;
517}
518
519static int
520bfd_mach_o_read_header (abfd, header)
521 bfd *abfd;
522 bfd_mach_o_header *header;
523{
524 unsigned char buf[28];
525 bfd_vma (*get32) PARAMS ((const bfd_byte *)) = NULL;
526
527 bfd_seek (abfd, 0, SEEK_SET);
528
529 if (bfd_bread ((PTR) buf, 28, abfd) != 28)
530 return -1;
531
532 if (bfd_getb32 (buf) == 0xfeedface)
533 {
534 header->byteorder = BFD_ENDIAN_BIG;
535 header->magic = 0xfeedface;
536 get32 = bfd_getb32;
537 }
538 else if (bfd_getl32 (buf) == 0xfeedface)
539 {
a95a4550 540 header->byteorder = BFD_ENDIAN_LITTLE;
3af9a47b
NC
541 header->magic = 0xfeedface;
542 get32 = bfd_getl32;
543 }
544 else
545 {
546 header->byteorder = BFD_ENDIAN_UNKNOWN;
547 return -1;
548 }
a95a4550 549
3af9a47b
NC
550 header->cputype = (*get32) (buf + 4);
551 header->cpusubtype = (*get32) (buf + 8);
552 header->filetype = (*get32) (buf + 12);
553 header->ncmds = (*get32) (buf + 16);
554 header->sizeofcmds = (*get32) (buf + 20);
555 header->flags = (*get32) (buf + 24);
556
557 return 0;
558}
559
560static asection *
561bfd_mach_o_make_bfd_section (abfd, section)
562 bfd *abfd;
563 bfd_mach_o_section *section;
564{
565 asection *bfdsec;
566 char *sname;
567 const char *prefix = "LC_SEGMENT";
568 unsigned int snamelen;
569
570 snamelen = strlen (prefix) + 1
571 + strlen (section->segname) + 1
572 + strlen (section->sectname) + 1;
573
574 sname = (char *) bfd_alloc (abfd, snamelen);
575 if (sname == NULL)
576 return NULL;
577 sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
578
579 bfdsec = bfd_make_section_anyway (abfd, sname);
580 if (bfdsec == NULL)
581 return NULL;
a95a4550 582
3af9a47b
NC
583 bfdsec->vma = section->addr;
584 bfdsec->lma = section->addr;
585 bfdsec->_raw_size = section->size;
586 bfdsec->filepos = section->offset;
587 bfdsec->alignment_power = section->align;
588
589 if (section->flags & BFD_MACH_O_S_ZEROFILL)
590 bfdsec->flags = SEC_ALLOC;
591 else
592 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
593
594 return bfdsec;
595}
596
597static int
598bfd_mach_o_scan_read_section (abfd, section, offset)
599 bfd *abfd;
600 bfd_mach_o_section *section;
601 bfd_vma offset;
602{
603 unsigned char buf[68];
604
605 bfd_seek (abfd, offset, SEEK_SET);
606 if (bfd_bread ((PTR) buf, 68, abfd) != 68)
607 return -1;
a95a4550 608
3af9a47b
NC
609 memcpy (section->sectname, buf, 16);
610 section->sectname[16] = '\0';
611 memcpy (section->segname, buf + 16, 16);
612 section->segname[16] = '\0';
613 section->addr = bfd_h_get_32 (abfd, buf + 32);
614 section->size = bfd_h_get_32 (abfd, buf + 36);
615 section->offset = bfd_h_get_32 (abfd, buf + 40);
616 section->align = bfd_h_get_32 (abfd, buf + 44);
617 section->reloff = bfd_h_get_32 (abfd, buf + 48);
618 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
619 section->flags = bfd_h_get_32 (abfd, buf + 56);
620 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
621 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
622 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
623
624 if (section->bfdsection == NULL)
625 return -1;
626
627 return 0;
628}
629
630static int
631bfd_mach_o_scan_write_section (abfd, section, offset)
632 bfd *abfd;
633 bfd_mach_o_section *section;
634 bfd_vma offset;
635{
636 unsigned char buf[68];
637
638 memcpy (buf, section->sectname, 16);
639 memcpy (buf + 16, section->segname, 16);
640 bfd_h_put_32 (abfd, section->addr, buf + 32);
641 bfd_h_put_32 (abfd, section->size, buf + 36);
642 bfd_h_put_32 (abfd, section->offset, buf + 40);
643 bfd_h_put_32 (abfd, section->align, buf + 44);
644 bfd_h_put_32 (abfd, section->reloff, buf + 48);
645 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
646 bfd_h_put_32 (abfd, section->flags, buf + 56);
647 /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
648 /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
649
650 bfd_seek (abfd, offset, SEEK_SET);
651 if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
652 return -1;
a95a4550 653
3af9a47b
NC
654 return 0;
655}
656
657static int
658bfd_mach_o_scan_write_symtab_symbols (abfd, command)
659 bfd *abfd;
660 bfd_mach_o_load_command *command;
661{
662 bfd_mach_o_symtab_command *sym = &command->command.symtab;
663 asymbol *s = NULL;
664 unsigned long i;
665
666 for (i = 0; i < sym->nsyms; i++)
667 {
668 unsigned char buf[12];
669 bfd_vma symoff = sym->symoff + (i * 12);
670 unsigned char ntype = 0;
671 unsigned char nsect = 0;
672 short ndesc = 0;
673
674 s = &sym->symbols[i];
675
676 /* Don't set this from the symbol information; use stored values. */
a95a4550 677#if 0
3af9a47b
NC
678 if (s->flags & BSF_GLOBAL)
679 ntype |= N_EXT;
680 if (s->flags & BSF_DEBUGGING)
681 ntype |= N_STAB;
682
683 if (s->section == bfd_und_section_ptr)
684 ntype |= N_UNDF;
685 else if (s->section == bfd_abs_section_ptr)
686 ntype |= N_ABS;
687 else
688 ntype |= N_SECT;
689#endif
a95a4550 690
3af9a47b
NC
691 /* Instead just set from the stored values. */
692 ntype = (s->udata.i >> 24) & 0xff;
693 nsect = (s->udata.i >> 16) & 0xff;
694 ndesc = s->udata.i & 0xffff;
695
696 bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
697 bfd_h_put_8 (abfd, ntype, buf + 4);
698 bfd_h_put_8 (abfd, nsect, buf + 5);
699 bfd_h_put_16 (abfd, ndesc, buf + 6);
700 bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
701
702 bfd_seek (abfd, symoff, SEEK_SET);
703 if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
704 {
a95a4550 705 fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
3af9a47b 706 12, (unsigned long) symoff);
a95a4550 707 return -1;
3af9a47b
NC
708 }
709 }
710
711 return 0;
712}
713
714int
715bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)
716 bfd *abfd;
717 bfd_mach_o_symtab_command *sym;
718 asymbol *s;
719 unsigned long i;
720{
721 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
722 bfd_vma symoff = sym->symoff + (i * 12);
723 unsigned char buf[12];
724 unsigned char type = -1;
725 unsigned char section = -1;
726 short desc = -1;
e84d6fca 727 unsigned long value = -1;
3af9a47b
NC
728 unsigned long stroff = -1;
729 unsigned int symtype = -1;
730
731 BFD_ASSERT (sym->strtab != NULL);
732
733 bfd_seek (abfd, symoff, SEEK_SET);
734 if (bfd_bread ((PTR) buf, 12, abfd) != 12)
735 {
736 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
737 12, (unsigned long) symoff);
738 return -1;
739 }
740
741 stroff = bfd_h_get_32 (abfd, buf);
742 type = bfd_h_get_8 (abfd, buf + 4);
743 symtype = (type & 0x0e);
744 section = bfd_h_get_8 (abfd, buf + 5) - 1;
745 desc = bfd_h_get_16 (abfd, buf + 6);
746 value = bfd_h_get_32 (abfd, buf + 8);
747
748 if (stroff >= sym->strsize)
749 {
750 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
751 (unsigned long) stroff, (unsigned long) sym->strsize);
a95a4550 752 return -1;
3af9a47b
NC
753 }
754
755 s->the_bfd = abfd;
756 s->name = sym->strtab + stroff;
757 s->value = value;
758 s->udata.i = (type << 24) | (section << 16) | desc;
759 s->flags = 0x0;
760
761 if (type & BFD_MACH_O_N_STAB)
762 {
763 s->flags |= BSF_DEBUGGING;
764 s->section = bfd_und_section_ptr;
765 }
766 else
767 {
768 if (type & BFD_MACH_O_N_PEXT)
769 {
770 type &= ~BFD_MACH_O_N_PEXT;
771 s->flags |= BSF_GLOBAL;
772 }
773
774 if (type & BFD_MACH_O_N_EXT)
775 {
776 type &= ~BFD_MACH_O_N_EXT;
777 s->flags |= BSF_GLOBAL;
778 }
779
780 switch (symtype)
781 {
782 case BFD_MACH_O_N_UNDF:
783 s->section = bfd_und_section_ptr;
784 break;
785 case BFD_MACH_O_N_PBUD:
786 s->section = bfd_und_section_ptr;
787 break;
788 case BFD_MACH_O_N_ABS:
789 s->section = bfd_abs_section_ptr;
790 break;
791 case BFD_MACH_O_N_SECT:
792 if ((section > 0) && (section <= mdata->nsects))
793 {
794 s->section = mdata->sections[section - 1]->bfdsection;
795 s->value = s->value - mdata->sections[section - 1]->addr;
796 }
797 else
798 {
799 /* Mach-O uses 0 to mean "no section"; not an error. */
800 if (section != 0)
801 {
802 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
a95a4550 803 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
3af9a47b
NC
804 s->name, section, mdata->nsects);
805 }
806 s->section = bfd_und_section_ptr;
807 }
808 break;
809 case BFD_MACH_O_N_INDR:
810 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
a95a4550 811 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
3af9a47b
NC
812 s->name);
813 s->section = bfd_und_section_ptr;
814 break;
815 default:
816 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
a95a4550 817 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
3af9a47b
NC
818 s->name, symtype);
819 s->section = bfd_und_section_ptr;
820 break;
821 }
822 }
823
824 return 0;
825}
826
827int
828bfd_mach_o_scan_read_symtab_strtab (abfd, sym)
829 bfd *abfd;
830 bfd_mach_o_symtab_command *sym;
831{
832 BFD_ASSERT (sym->strtab == NULL);
833
834 if (abfd->flags & BFD_IN_MEMORY)
835 {
836 struct bfd_in_memory *b;
837
838 b = (struct bfd_in_memory *) abfd->iostream;
839
840 if ((sym->stroff + sym->strsize) > b->size)
841 {
842 bfd_set_error (bfd_error_file_truncated);
843 return -1;
844 }
845 sym->strtab = b->buffer + sym->stroff;
846 return 0;
847 }
848
849 sym->strtab = bfd_alloc (abfd, sym->strsize);
850 if (sym->strtab == NULL)
851 return -1;
852
853 bfd_seek (abfd, sym->stroff, SEEK_SET);
854 if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
855 {
856 fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
857 sym->strsize, sym->stroff);
a95a4550 858 return -1;
3af9a47b
NC
859 }
860
861 return 0;
862}
863
a95a4550 864int
3af9a47b
NC
865bfd_mach_o_scan_read_symtab_symbols (abfd, sym)
866 bfd *abfd;
867 bfd_mach_o_symtab_command *sym;
868{
869 unsigned long i;
870 int ret;
871
872 BFD_ASSERT (sym->symbols == NULL);
873 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
874
875 if (sym->symbols == NULL)
876 {
877 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
a95a4550 878 return -1;
3af9a47b 879 }
a95a4550 880
3af9a47b
NC
881 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
882 if (ret != 0)
883 return ret;
884
885 for (i = 0; i < sym->nsyms; i++)
886 {
887 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
888 if (ret != 0)
889 return ret;
890 }
a95a4550 891
3af9a47b
NC
892 return 0;
893}
894
895int
896bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, s, i)
897 bfd *abfd;
898 bfd_mach_o_dysymtab_command *dysym;
899 bfd_mach_o_symtab_command *sym;
900 asymbol *s;
901 unsigned long i;
902{
903 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
904 unsigned long symindex;
905 unsigned char buf[4];
906
907 BFD_ASSERT (i < dysym->nindirectsyms);
a95a4550 908
3af9a47b
NC
909 bfd_seek (abfd, isymoff, SEEK_SET);
910 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
911 {
912 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
913 (unsigned long) 4, isymoff);
914 return -1;
915 }
916 symindex = bfd_h_get_32 (abfd, buf);
a95a4550 917
3af9a47b
NC
918 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
919}
920
921static const char *
922bfd_mach_o_i386_flavour_string (flavour)
923 unsigned int flavour;
924{
925 switch ((int) flavour)
926 {
927 case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
928 case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
929 case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
930 case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
931 case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
932 case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
933 case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
934 case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
935 case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
936 case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
937 case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
938 case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
939 default: return "UNKNOWN";
940 }
941}
942
943static const char *
944bfd_mach_o_ppc_flavour_string (flavour)
945 unsigned int flavour;
946{
947 switch ((int) flavour)
948 {
949 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
950 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
951 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
952 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
953 default: return "UNKNOWN";
954 }
955}
956
957static int
958bfd_mach_o_scan_write_thread (abfd, command)
959 bfd *abfd;
960 bfd_mach_o_load_command *command;
961{
962 bfd_mach_o_thread_command *cmd = &command->command.thread;
963 unsigned int i;
964 unsigned char buf[8];
965 bfd_vma offset;
966 unsigned int nflavours;
967
968 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
969 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
970
971 offset = 8;
972 nflavours = 0;
973 for (i = 0; i < cmd->nflavours; i++)
974 {
975 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
976 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
977
978 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
979 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
980
981 bfd_seek (abfd, command->offset + offset, SEEK_SET);
982 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
983 return -1;
984
985 offset += cmd->flavours[i].size + 8;
986 }
987
988 return 0;
989}
990
991static int
992bfd_mach_o_scan_read_dylinker (abfd, command)
993 bfd *abfd;
994 bfd_mach_o_load_command *command;
995{
996 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
997 unsigned char buf[4];
998 unsigned int nameoff;
999 asection *bfdsec;
1000 char *sname;
1001 const char *prefix;
1002
1003 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1004 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1005
1006 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1007 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
1008 return -1;
1009
1010 nameoff = bfd_h_get_32 (abfd, buf + 0);
1011
1012 cmd->name_offset = command->offset + nameoff;
1013 cmd->name_len = command->len - nameoff;
1014
1015 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
1016 prefix = "LC_LOAD_DYLINKER";
1017 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
1018 prefix = "LC_ID_DYLINKER";
1019 else
1020 abort ();
1021
1022 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1023 if (sname == NULL)
1024 return -1;
1025 strcpy (sname, prefix);
1026
1027 bfdsec = bfd_make_section_anyway (abfd, sname);
1028 if (bfdsec == NULL)
1029 return -1;
a95a4550 1030
3af9a47b
NC
1031 bfdsec->vma = 0;
1032 bfdsec->lma = 0;
1033 bfdsec->_raw_size = command->len - 8;
1034 bfdsec->filepos = command->offset + 8;
1035 bfdsec->alignment_power = 0;
1036 bfdsec->flags = SEC_HAS_CONTENTS;
1037
1038 cmd->section = bfdsec;
1039
1040 return 0;
1041}
1042
1043static int
1044bfd_mach_o_scan_read_dylib (abfd, command)
1045 bfd *abfd;
1046 bfd_mach_o_load_command *command;
1047{
1048 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1049 unsigned char buf[16];
1050 unsigned int nameoff;
1051 asection *bfdsec;
1052 char *sname;
1053 const char *prefix;
1054
1055 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1056 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1057 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1058
1059 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1060 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1061 return -1;
1062
1063 nameoff = bfd_h_get_32 (abfd, buf + 0);
1064 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1065 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1066 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1067
1068 cmd->name_offset = command->offset + nameoff;
1069 cmd->name_len = command->len - nameoff;
1070
1071 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1072 prefix = "LC_LOAD_DYLIB";
1073 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1074 prefix = "LC_LOAD_WEAK_DYLIB";
1075 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1076 prefix = "LC_ID_DYLIB";
1077 else
1078 abort ();
1079
1080 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1081 if (sname == NULL)
1082 return -1;
1083 strcpy (sname, prefix);
1084
1085 bfdsec = bfd_make_section_anyway (abfd, sname);
1086 if (bfdsec == NULL)
1087 return -1;
a95a4550 1088
3af9a47b
NC
1089 bfdsec->vma = 0;
1090 bfdsec->lma = 0;
1091 bfdsec->_raw_size = command->len - 8;
1092 bfdsec->filepos = command->offset + 8;
1093 bfdsec->alignment_power = 0;
1094 bfdsec->flags = SEC_HAS_CONTENTS;
1095
1096 cmd->section = bfdsec;
1097
1098 return 0;
1099}
1100
1101static int
1102bfd_mach_o_scan_read_prebound_dylib (abfd, command)
1103 bfd *abfd ATTRIBUTE_UNUSED;
1104 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED;
1105{
1106 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1107
1108 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1109 return 0;
1110}
1111
1112static int
1113bfd_mach_o_scan_read_thread (abfd, command)
1114 bfd *abfd;
1115 bfd_mach_o_load_command *command;
1116{
1117 bfd_mach_o_data_struct *mdata = NULL;
1118 bfd_mach_o_thread_command *cmd = &command->command.thread;
1119 unsigned char buf[8];
1120 bfd_vma offset;
1121 unsigned int nflavours;
1122 unsigned int i;
1123
1124 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1125 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1126
1127 BFD_ASSERT (bfd_mach_o_valid (abfd));
1128 mdata = abfd->tdata.mach_o_data;
a95a4550 1129
3af9a47b
NC
1130 offset = 8;
1131 nflavours = 0;
1132 while (offset != command->len)
1133 {
1134 if (offset >= command->len)
1135 return -1;
1136
1137 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1138
1139 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1140 return -1;
1141
1142 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1143 nflavours++;
1144 }
1145
1146 cmd->flavours =
1147 ((bfd_mach_o_thread_flavour *)
1148 bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour)));
1149 if (cmd->flavours == NULL)
1150 return -1;
1151 cmd->nflavours = nflavours;
1152
1153 offset = 8;
1154 nflavours = 0;
1155 while (offset != command->len)
1156 {
1157 if (offset >= command->len)
1158 return -1;
1159
1160 if (nflavours >= cmd->nflavours)
1161 return -1;
1162
1163 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1164
1165 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1166 return -1;
1167
1168 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1169 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1170 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1171 offset += cmd->flavours[nflavours].size + 8;
1172 nflavours++;
1173 }
1174
1175 for (i = 0; i < nflavours; i++)
1176 {
1177 asection *bfdsec;
1178 unsigned int snamelen;
1179 char *sname;
1180 const char *flavourstr;
1181 const char *prefix = "LC_THREAD";
a95a4550
AM
1182 unsigned int j = 0;
1183
3af9a47b
NC
1184 switch (mdata->header.cputype)
1185 {
1186 case BFD_MACH_O_CPU_TYPE_POWERPC:
1187 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1188 break;
1189 case BFD_MACH_O_CPU_TYPE_I386:
1190 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1191 break;
1192 default:
1193 flavourstr = "UNKNOWN_ARCHITECTURE";
1194 break;
1195 }
a95a4550 1196
3af9a47b
NC
1197 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1198 sname = (char *) bfd_alloc (abfd, snamelen);
1199 if (sname == NULL)
1200 return -1;
1201
1202 for (;;)
1203 {
a95a4550
AM
1204 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1205 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 1206 break;
a95a4550 1207 j++;
3af9a47b
NC
1208 }
1209
1210 bfdsec = bfd_make_section (abfd, sname);
a95a4550 1211
3af9a47b
NC
1212 bfdsec->vma = 0;
1213 bfdsec->lma = 0;
1214 bfdsec->_raw_size = cmd->flavours[i].size;
1215 bfdsec->filepos = cmd->flavours[i].offset;
1216 bfdsec->alignment_power = 0x0;
1217 bfdsec->flags = SEC_HAS_CONTENTS;
1218
1219 cmd->section = bfdsec;
1220 }
1221
1222 return 0;
1223}
1224
a95a4550 1225static int
3af9a47b
NC
1226bfd_mach_o_scan_write_symtab (abfd, command)
1227 bfd *abfd;
1228 bfd_mach_o_load_command *command;
1229{
1230 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1231 unsigned char buf[16];
1232
1233 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1234
1235 bfd_h_put_32 (abfd, seg->symoff, buf);
1236 bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
1237 bfd_h_put_32 (abfd, seg->stroff, buf + 8);
1238 bfd_h_put_32 (abfd, seg->strsize, buf + 12);
1239
1240 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1241 if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
1242 return -1;
a95a4550 1243
3af9a47b
NC
1244 if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
1245 return -1;
1246
1247 return 0;
1248}
1249
a95a4550 1250static int
3af9a47b
NC
1251bfd_mach_o_scan_read_dysymtab (abfd, command)
1252 bfd *abfd;
1253 bfd_mach_o_load_command *command;
1254{
1255 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1256 unsigned char buf[72];
1257
1258 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1259
1260 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1261 if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1262 return -1;
1263
1264 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1265 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1266 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1267 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1268 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1269 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1270 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1271 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1272 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1273 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1274 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1275 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1276 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1277 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1278 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1279 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1280 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1281 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1282
1283 return 0;
1284}
1285
a95a4550 1286static int
3af9a47b
NC
1287bfd_mach_o_scan_read_symtab (abfd, command)
1288 bfd *abfd;
1289 bfd_mach_o_load_command *command;
1290{
1291 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1292 unsigned char buf[16];
1293 asection *bfdsec;
1294 char *sname;
1295 const char *prefix = "LC_SYMTAB.stabs";
1296
1297 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1298
1299 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1300 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1301 return -1;
a95a4550 1302
3af9a47b
NC
1303 seg->symoff = bfd_h_get_32 (abfd, buf);
1304 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1305 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1306 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1307 seg->symbols = NULL;
1308 seg->strtab = NULL;
1309
1310 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1311 if (sname == NULL)
1312 return -1;
1313 strcpy (sname, prefix);
1314
1315 bfdsec = bfd_make_section_anyway (abfd, sname);
1316 if (bfdsec == NULL)
1317 return -1;
a95a4550 1318
3af9a47b
NC
1319 bfdsec->vma = 0;
1320 bfdsec->lma = 0;
1321 bfdsec->_raw_size = seg->nsyms * 12;
1322 bfdsec->filepos = seg->symoff;
1323 bfdsec->alignment_power = 0;
1324 bfdsec->flags = SEC_HAS_CONTENTS;
1325
1326 seg->stabs_segment = bfdsec;
1327
1328 prefix = "LC_SYMTAB.stabstr";
1329 sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
1330 if (sname == NULL)
1331 return -1;
1332 strcpy (sname, prefix);
1333
1334 bfdsec = bfd_make_section_anyway (abfd, sname);
1335 if (bfdsec == NULL)
1336 return -1;
a95a4550 1337
3af9a47b
NC
1338 bfdsec->vma = 0;
1339 bfdsec->lma = 0;
1340 bfdsec->_raw_size = seg->strsize;
1341 bfdsec->filepos = seg->stroff;
1342 bfdsec->alignment_power = 0;
1343 bfdsec->flags = SEC_HAS_CONTENTS;
1344
1345 seg->stabstr_segment = bfdsec;
1346
1347 return 0;
1348}
1349
1350static int
1351bfd_mach_o_scan_read_segment (abfd, command)
1352 bfd *abfd;
1353 bfd_mach_o_load_command *command;
1354{
1355 unsigned char buf[48];
1356 bfd_mach_o_segment_command *seg = &command->command.segment;
1357 unsigned long i;
1358 asection *bfdsec;
1359 char *sname;
1360 const char *prefix = "LC_SEGMENT";
1361 unsigned int snamelen;
a95a4550 1362
3af9a47b
NC
1363 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1364
1365 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1366 if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1367 return -1;
1368
1369 memcpy (seg->segname, buf, 16);
1370 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1371 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1372 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1373 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
1374 /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1375 /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1376 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1377 seg->flags = bfd_h_get_32 (abfd, buf + 44);
1378
1379 snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1380 sname = (char *) bfd_alloc (abfd, snamelen);
1381 if (sname == NULL)
1382 return -1;
1383 sprintf (sname, "%s.%s", prefix, seg->segname);
1384
1385 bfdsec = bfd_make_section_anyway (abfd, sname);
1386 if (bfdsec == NULL)
1387 return -1;
1388
1389 bfdsec->vma = seg->vmaddr;
1390 bfdsec->lma = seg->vmaddr;
1391 bfdsec->_raw_size = seg->filesize;
1392 bfdsec->filepos = seg->fileoff;
1393 bfdsec->alignment_power = 0x0;
1394 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1395
1396 seg->segment = bfdsec;
1397
1398 if (seg->nsects != 0)
1399 {
a95a4550 1400 seg->sections =
3af9a47b
NC
1401 ((bfd_mach_o_section *)
1402 bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)));
1403 if (seg->sections == NULL)
1404 return -1;
a95a4550 1405
3af9a47b
NC
1406 for (i = 0; i < seg->nsects; i++)
1407 {
1408 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1409
e84d6fca
AM
1410 if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1411 segoff) != 0)
3af9a47b 1412 return -1;
a95a4550 1413 }
3af9a47b
NC
1414 }
1415
1416 return 0;
1417}
1418
1419static int
1420bfd_mach_o_scan_write_segment (abfd, command)
1421 bfd *abfd;
1422 bfd_mach_o_load_command *command;
1423{
1424 unsigned char buf[48];
1425 bfd_mach_o_segment_command *seg = &command->command.segment;
1426 unsigned long i;
a95a4550 1427
3af9a47b
NC
1428 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1429
1430 memcpy (buf, seg->segname, 16);
1431 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
1432 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
1433 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
1434 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
1435 bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
1436 bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
1437 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
1438 bfd_h_put_32 (abfd, seg->flags, buf + 44);
1439
1440 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1441 if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
1442 return -1;
1443
1444 {
1445 char buf[1024];
1446 bfd_vma nbytes = seg->filesize;
1447 bfd_vma curoff = seg->fileoff;
a95a4550 1448
3af9a47b
NC
1449 while (nbytes > 0)
1450 {
1451 bfd_vma thisread = nbytes;
1452
1453 if (thisread > 1024)
1454 thisread = 1024;
1455
1456 bfd_seek (abfd, curoff, SEEK_SET);
1457 if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
1458 return -1;
1459
1460 bfd_seek (abfd, curoff, SEEK_SET);
1461 if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
1462 return -1;
1463
1464 nbytes -= thisread;
1465 curoff += thisread;
1466 }
1467 }
1468
1469 for (i = 0; i < seg->nsects; i++)
1470 {
1471 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1472
1473 if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
1474 return -1;
1475 }
1476
1477 return 0;
1478}
1479
1480static int
1481bfd_mach_o_scan_read_command (abfd, command)
1482 bfd *abfd;
1483 bfd_mach_o_load_command *command;
1484{
1485 unsigned char buf[8];
1486
1487 bfd_seek (abfd, command->offset, SEEK_SET);
1488 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1489 return -1;
1490
1491 command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
e84d6fca
AM
1492 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1493 ? 1 : 0);
3af9a47b
NC
1494 command->len = bfd_h_get_32 (abfd, buf + 4);
1495
1496 switch (command->type)
1497 {
1498 case BFD_MACH_O_LC_SEGMENT:
1499 if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1500 return -1;
1501 break;
1502 case BFD_MACH_O_LC_SYMTAB:
1503 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1504 return -1;
1505 break;
1506 case BFD_MACH_O_LC_SYMSEG:
1507 break;
1508 case BFD_MACH_O_LC_THREAD:
1509 case BFD_MACH_O_LC_UNIXTHREAD:
1510 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1511 return -1;
1512 break;
1513 case BFD_MACH_O_LC_LOAD_DYLINKER:
1514 case BFD_MACH_O_LC_ID_DYLINKER:
1515 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1516 return -1;
1517 break;
1518 case BFD_MACH_O_LC_LOAD_DYLIB:
1519 case BFD_MACH_O_LC_ID_DYLIB:
1520 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1521 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1522 return -1;
1523 break;
1524 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1525 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1526 return -1;
1527 break;
1528 case BFD_MACH_O_LC_LOADFVMLIB:
1529 case BFD_MACH_O_LC_IDFVMLIB:
1530 case BFD_MACH_O_LC_IDENT:
1531 case BFD_MACH_O_LC_FVMFILE:
1532 case BFD_MACH_O_LC_PREPAGE:
1533 case BFD_MACH_O_LC_ROUTINES:
1534 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1535 break;
1536 case BFD_MACH_O_LC_DYSYMTAB:
1537 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1538 return -1;
1539 break;
1540 case BFD_MACH_O_LC_SUB_UMBRELLA:
1541 case BFD_MACH_O_LC_SUB_CLIENT:
1542 case BFD_MACH_O_LC_SUB_LIBRARY:
1543 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1544 case BFD_MACH_O_LC_PREBIND_CKSUM:
1545 break;
1546 default:
1547 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1548 (unsigned long) command->type);
1549 break;
1550 }
1551
1552 return 0;
1553}
1554
1555static void
1556bfd_mach_o_flatten_sections (abfd)
1557 bfd *abfd;
1558{
1559 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1560 long csect = 0;
1561 unsigned long i, j;
a95a4550 1562
3af9a47b
NC
1563 mdata->nsects = 0;
1564
1565 for (i = 0; i < mdata->header.ncmds; i++)
1566 {
1567 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1568 {
e84d6fca
AM
1569 bfd_mach_o_segment_command *seg;
1570
1571 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
1572 mdata->nsects += seg->nsects;
1573 }
1574 }
1575
e84d6fca
AM
1576 mdata->sections = bfd_alloc (abfd,
1577 mdata->nsects * sizeof (bfd_mach_o_section *));
3af9a47b
NC
1578 csect = 0;
1579
1580 for (i = 0; i < mdata->header.ncmds; i++)
1581 {
1582 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1583 {
e84d6fca 1584 bfd_mach_o_segment_command *seg;
3af9a47b 1585
e84d6fca 1586 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
1587 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1588
1589 for (j = 0; j < seg->nsects; j++)
1590 mdata->sections[csect++] = &seg->sections[j];
1591 }
1592 }
1593}
1594
1595int
1596bfd_mach_o_scan_start_address (abfd)
1597 bfd *abfd;
1598{
1599 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1600 bfd_mach_o_thread_command *cmd = NULL;
1601 unsigned long i;
1602
1603 for (i = 0; i < mdata->header.ncmds; i++)
1604 {
1605 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1606 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1607 {
1608 if (cmd == NULL)
1609 cmd = &mdata->commands[i].command.thread;
1610 else
1611 return 0;
1612 }
1613 }
1614
1615 if (cmd == NULL)
1616 return 0;
1617
1618 for (i = 0; i < cmd->nflavours; i++)
1619 {
a95a4550 1620 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
e84d6fca
AM
1621 && (cmd->flavours[i].flavour
1622 == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
3af9a47b
NC
1623 {
1624 unsigned char buf[4];
1625
1626 bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1627
1628 if (bfd_bread (buf, 4, abfd) != 4)
1629 return -1;
1630
1631 abfd->start_address = bfd_h_get_32 (abfd, buf);
1632 }
a95a4550 1633 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
3af9a47b
NC
1634 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1635 {
1636 unsigned char buf[4];
1637
1638 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1639
1640 if (bfd_bread (buf, 4, abfd) != 4)
1641 return -1;
1642
1643 abfd->start_address = bfd_h_get_32 (abfd, buf);
1644 }
1645 }
1646
1647 return 0;
1648}
1649
1650int
e84d6fca 1651bfd_mach_o_scan (abfd, header, mdata)
3af9a47b
NC
1652 bfd *abfd;
1653 bfd_mach_o_header *header;
e84d6fca 1654 bfd_mach_o_data_struct *mdata;
3af9a47b
NC
1655{
1656 unsigned int i;
3af9a47b
NC
1657 enum bfd_architecture cputype;
1658 unsigned long cpusubtype;
1659
3af9a47b
NC
1660 mdata->header = *header;
1661 mdata->symbols = NULL;
1662
e84d6fca
AM
1663 abfd->flags = (abfd->xvec->object_flags
1664 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
3af9a47b
NC
1665 abfd->tdata.mach_o_data = mdata;
1666
e84d6fca
AM
1667 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1668 &cputype, &cpusubtype);
3af9a47b
NC
1669 if (cputype == bfd_arch_unknown)
1670 {
1671 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1672 header->cputype, header->cpusubtype);
1673 return -1;
1674 }
1675
1676 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 1677
3af9a47b
NC
1678 if (header->ncmds != 0)
1679 {
a95a4550 1680 mdata->commands =
3af9a47b
NC
1681 ((bfd_mach_o_load_command *)
1682 bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));
1683 if (mdata->commands == NULL)
1684 return -1;
a95a4550 1685
3af9a47b
NC
1686 for (i = 0; i < header->ncmds; i++)
1687 {
1688 bfd_mach_o_load_command *cur = &mdata->commands[i];
1689
1690 if (i == 0)
1691 cur->offset = 28;
1692 else
1693 {
1694 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1695 cur->offset = prev->offset + prev->len;
1696 }
1697
1698 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1699 return -1;
a95a4550 1700 }
3af9a47b
NC
1701 }
1702
1703 if (bfd_mach_o_scan_start_address (abfd) < 0)
1704 {
1705#if 0
1706 fprintf (stderr, "bfd_mach_o_scan: unable to scan start address: %s\n",
1707 bfd_errmsg (bfd_get_error ()));
1708 abfd->tdata.mach_o_data = NULL;
1709 return -1;
1710#endif
1711 }
1712
1713 bfd_mach_o_flatten_sections (abfd);
1714
1715 return 0;
1716}
1717
b34976b6 1718bfd_boolean
3af9a47b
NC
1719bfd_mach_o_mkobject (abfd)
1720 bfd *abfd;
1721{
1722 bfd_mach_o_data_struct *mdata = NULL;
1723
a95a4550 1724 mdata = ((bfd_mach_o_data_struct *)
3af9a47b
NC
1725 bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
1726 if (mdata == NULL)
b34976b6 1727 return FALSE;
3af9a47b
NC
1728 abfd->tdata.mach_o_data = mdata;
1729
1730 mdata->header.magic = 0;
1731 mdata->header.cputype = 0;
1732 mdata->header.cpusubtype = 0;
1733 mdata->header.filetype = 0;
1734 mdata->header.ncmds = 0;
1735 mdata->header.sizeofcmds = 0;
1736 mdata->header.flags = 0;
1737 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1738 mdata->commands = NULL;
1739 mdata->nsymbols = 0;
1740 mdata->symbols = NULL;
1741 mdata->nsects = 0;
1742 mdata->sections = NULL;
1743 mdata->ibfd = NULL;
1744
b34976b6 1745 return TRUE;
3af9a47b
NC
1746}
1747
1748const bfd_target *
1749bfd_mach_o_object_p (abfd)
1750 bfd *abfd;
1751{
e84d6fca 1752 struct bfd_preserve preserve;
3af9a47b
NC
1753 bfd_mach_o_header header;
1754
e84d6fca 1755 preserve.marker = NULL;
3af9a47b 1756 if (bfd_mach_o_read_header (abfd, &header) != 0)
e84d6fca 1757 goto wrong;
3af9a47b 1758
e84d6fca
AM
1759 if (! (header.byteorder == BFD_ENDIAN_BIG
1760 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 1761 {
e84d6fca
AM
1762 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1763 (long) header.byteorder);
1764 goto wrong;
3af9a47b
NC
1765 }
1766
e84d6fca
AM
1767 if (! ((header.byteorder == BFD_ENDIAN_BIG
1768 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1769 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1770 || (header.byteorder == BFD_ENDIAN_LITTLE
1771 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1772 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1773 goto wrong;
3af9a47b 1774
e84d6fca
AM
1775 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1776 if (preserve.marker == NULL
1777 || !bfd_preserve_save (abfd, &preserve))
1778 goto fail;
3af9a47b 1779
e84d6fca
AM
1780 if (bfd_mach_o_scan (abfd, &header,
1781 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1782 goto wrong;
a95a4550 1783
e84d6fca 1784 bfd_preserve_finish (abfd, &preserve);
3af9a47b 1785 return abfd->xvec;
e84d6fca
AM
1786
1787 wrong:
1788 bfd_set_error (bfd_error_wrong_format);
1789
1790 fail:
1791 if (preserve.marker != NULL)
1792 bfd_preserve_restore (abfd, &preserve);
1793 return NULL;
3af9a47b
NC
1794}
1795
1796const bfd_target *
1797bfd_mach_o_core_p (abfd)
1798 bfd *abfd;
1799{
e84d6fca 1800 struct bfd_preserve preserve;
3af9a47b
NC
1801 bfd_mach_o_header header;
1802
e84d6fca 1803 preserve.marker = NULL;
3af9a47b 1804 if (bfd_mach_o_read_header (abfd, &header) != 0)
e84d6fca 1805 goto wrong;
3af9a47b 1806
e84d6fca
AM
1807 if (! (header.byteorder == BFD_ENDIAN_BIG
1808 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 1809 {
e84d6fca
AM
1810 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1811 (long) header.byteorder);
3af9a47b
NC
1812 abort ();
1813 }
1814
e84d6fca
AM
1815 if (! ((header.byteorder == BFD_ENDIAN_BIG
1816 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1817 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1818 || (header.byteorder == BFD_ENDIAN_LITTLE
1819 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1820 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1821 goto wrong;
3af9a47b
NC
1822
1823 if (header.filetype != BFD_MACH_O_MH_CORE)
e84d6fca 1824 goto wrong;
3af9a47b 1825
e84d6fca
AM
1826 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1827 if (preserve.marker == NULL
1828 || !bfd_preserve_save (abfd, &preserve))
1829 goto fail;
a95a4550 1830
e84d6fca
AM
1831 if (bfd_mach_o_scan (abfd, &header,
1832 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1833 goto wrong;
1834
1835 bfd_preserve_finish (abfd, &preserve);
3af9a47b 1836 return abfd->xvec;
e84d6fca
AM
1837
1838 wrong:
1839 bfd_set_error (bfd_error_wrong_format);
1840
1841 fail:
1842 if (preserve.marker != NULL)
1843 bfd_preserve_restore (abfd, &preserve);
1844 return NULL;
3af9a47b
NC
1845}
1846
1847typedef struct mach_o_fat_archentry
1848{
1849 unsigned long cputype;
1850 unsigned long cpusubtype;
1851 unsigned long offset;
1852 unsigned long size;
1853 unsigned long align;
1854 bfd *abfd;
1855} mach_o_fat_archentry;
1856
1857typedef struct mach_o_fat_data_struct
1858{
1859 unsigned long magic;
1860 unsigned long nfat_arch;
1861 mach_o_fat_archentry *archentries;
1862} mach_o_fat_data_struct;
1863
1864const bfd_target *
1865bfd_mach_o_archive_p (abfd)
1866 bfd *abfd;
1867{
e84d6fca 1868 mach_o_fat_data_struct *adata = NULL;
3af9a47b
NC
1869 unsigned char buf[20];
1870 unsigned long i;
1871
1872 bfd_seek (abfd, 0, SEEK_SET);
1873 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
e84d6fca 1874 goto error;
3af9a47b 1875
a95a4550 1876 adata = (mach_o_fat_data_struct *)
3af9a47b
NC
1877 bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1878 if (adata == NULL)
e84d6fca 1879 goto error;
a95a4550 1880
3af9a47b
NC
1881 adata->magic = bfd_getb32 (buf);
1882 adata->nfat_arch = bfd_getb32 (buf + 4);
1883 if (adata->magic != 0xcafebabe)
e84d6fca 1884 goto error;
3af9a47b 1885
a95a4550 1886 adata->archentries = (mach_o_fat_archentry *)
3af9a47b
NC
1887 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1888 if (adata->archentries == NULL)
e84d6fca 1889 goto error;
3af9a47b
NC
1890
1891 for (i = 0; i < adata->nfat_arch; i++)
1892 {
1893 bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1894
1895 if (bfd_bread ((PTR) buf, 20, abfd) != 20)
e84d6fca 1896 goto error;
3af9a47b
NC
1897 adata->archentries[i].cputype = bfd_getb32 (buf);
1898 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1899 adata->archentries[i].offset = bfd_getb32 (buf + 8);
1900 adata->archentries[i].size = bfd_getb32 (buf + 12);
1901 adata->archentries[i].align = bfd_getb32 (buf + 16);
1902 adata->archentries[i].abfd = NULL;
1903 }
1904
1905 abfd->tdata.mach_o_fat_data = adata;
1906 return abfd->xvec;
e84d6fca
AM
1907
1908 error:
1909 if (adata != NULL)
1910 bfd_release (abfd, adata);
1911 bfd_set_error (bfd_error_wrong_format);
1912 return NULL;
3af9a47b
NC
1913}
1914
1915bfd *
1916bfd_mach_o_openr_next_archived_file (archive, prev)
1917 bfd *archive;
1918 bfd *prev;
1919{
e84d6fca 1920 mach_o_fat_data_struct *adata;
3af9a47b
NC
1921 mach_o_fat_archentry *entry = NULL;
1922 unsigned long i;
1923
e84d6fca 1924 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
1925 BFD_ASSERT (adata != NULL);
1926
1927 /* Find index of previous entry. */
1928 if (prev == NULL)
1929 i = 0; /* Start at first one. */
1930 else
1931 {
1932 for (i = 0; i < adata->nfat_arch; i++)
1933 {
1934 if (adata->archentries[i].abfd == prev)
1935 break;
1936 }
1937
1938 if (i == adata->nfat_arch)
1939 {
1940 /* Not found. */
1941 bfd_set_error (bfd_error_bad_value);
a95a4550 1942 return NULL;
3af9a47b
NC
1943 }
1944 i++; /* Get next entry. */
1945 }
a95a4550 1946
3af9a47b
NC
1947 if (i >= adata->nfat_arch)
1948 {
1949 bfd_set_error (bfd_error_no_more_archived_files);
1950 return NULL;
1951 }
1952
1953 entry = &adata->archentries[i];
1954 if (entry->abfd == NULL)
1955 {
1956 bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1957 char *s = NULL;
1958
1959 if (nbfd == NULL)
1960 return NULL;
1961
1962 nbfd->origin = entry->offset;
1963 s = bfd_malloc (strlen (archive->filename) + 1);
1964 if (s == NULL)
1965 return NULL;
1966 strcpy (s, archive->filename);
1967 nbfd->filename = s;
1968 nbfd->iostream = NULL;
1969 entry->abfd = nbfd;
1970 }
1971
1972 return entry->abfd;
1973}
1974
e84d6fca
AM
1975int
1976bfd_mach_o_lookup_section (abfd, section, mcommand, msection)
1977 bfd *abfd;
1978 asection *section;
1979 bfd_mach_o_load_command **mcommand;
1980 bfd_mach_o_section **msection;
3af9a47b
NC
1981{
1982 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1983 unsigned int i, j, num;
1984
1985 bfd_mach_o_load_command *ncmd = NULL;
1986 bfd_mach_o_section *nsect = NULL;
1987
1988 BFD_ASSERT (mcommand != NULL);
1989 BFD_ASSERT (msection != NULL);
1990
1991 num = 0;
1992 for (i = 0; i < md->header.ncmds; i++)
1993 {
1994 struct bfd_mach_o_load_command *cmd = &md->commands[i];
1995 struct bfd_mach_o_segment_command *seg = NULL;
1996
1997 if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1998 continue;
1999 seg = &cmd->command.segment;
a95a4550 2000
3af9a47b
NC
2001 if (seg->segment == section)
2002 {
2003 if (num == 0)
2004 ncmd = cmd;
2005 num++;
2006 }
2007
2008 for (j = 0; j < seg->nsects; j++)
2009 {
2010 struct bfd_mach_o_section *sect = &seg->sections[j];
2011
2012 if (sect->bfdsection == section)
2013 {
2014 if (num == 0)
2015 nsect = sect;
2016 num++;
2017 }
2018 }
2019 }
a95a4550 2020
3af9a47b
NC
2021 *mcommand = ncmd;
2022 *msection = nsect;
2023 return num;
2024}
2025
2026int
e84d6fca
AM
2027bfd_mach_o_lookup_command (abfd, type, mcommand)
2028 bfd *abfd;
2029 bfd_mach_o_load_command_type type;
2030 bfd_mach_o_load_command **mcommand;
3af9a47b
NC
2031{
2032 struct mach_o_data_struct *md = NULL;
2033 bfd_mach_o_load_command *ncmd = NULL;
2034 unsigned int i, num;
2035
2036 md = abfd->tdata.mach_o_data;
2037
2038 BFD_ASSERT (md != NULL);
2039 BFD_ASSERT (mcommand != NULL);
2040
2041 num = 0;
2042 for (i = 0; i < md->header.ncmds; i++)
2043 {
2044 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2045
2046 if (cmd->type != type)
2047 continue;
2048
2049 if (num == 0)
2050 ncmd = cmd;
2051 num++;
2052 }
2053
2054 *mcommand = ncmd;
2055 return num;
2056}
2057
2058unsigned long
2059bfd_mach_o_stack_addr (type)
2060 enum bfd_mach_o_cpu_type type;
2061{
2062 switch (type)
2063 {
2064 case BFD_MACH_O_CPU_TYPE_MC680x0:
2065 return 0x04000000;
2066 case BFD_MACH_O_CPU_TYPE_MC88000:
2067 return 0xffffe000;
2068 case BFD_MACH_O_CPU_TYPE_POWERPC:
2069 return 0xc0000000;
2070 case BFD_MACH_O_CPU_TYPE_I386:
2071 return 0xc0000000;
2072 case BFD_MACH_O_CPU_TYPE_SPARC:
2073 return 0xf0000000;
2074 case BFD_MACH_O_CPU_TYPE_I860:
2075 return 0;
2076 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 2077 return 0xc0000000 - 0x04000000;
3af9a47b
NC
2078 default:
2079 return 0;
2080 }
2081}
2082
2083int
2084bfd_mach_o_core_fetch_environment (abfd, rbuf, rlen)
2085 bfd *abfd;
2086 unsigned char **rbuf;
2087 unsigned int *rlen;
2088{
2089 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2090 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2091 unsigned int i = 0;
2092
2093 for (i = 0; i < mdata->header.ncmds; i++)
2094 {
2095 bfd_mach_o_load_command *cur = &mdata->commands[i];
2096 bfd_mach_o_segment_command *seg = NULL;
2097
2098 if (cur->type != BFD_MACH_O_LC_SEGMENT)
2099 continue;
2100
2101 seg = &cur->command.segment;
2102
2103 if ((seg->vmaddr + seg->vmsize) == stackaddr)
2104 {
2105 unsigned long start = seg->fileoff;
2106 unsigned long end = seg->fileoff + seg->filesize;
2107 unsigned char *buf = bfd_malloc (1024);
2108 unsigned long size = 1024;
2109
2110 for (;;)
2111 {
2112 bfd_size_type nread = 0;
2113 unsigned long offset;
2114 int found_nonnull = 0;
2115
2116 if (size > (end - start))
2117 size = (end - start);
2118
2119 buf = bfd_realloc (buf, size);
2120
2121 bfd_seek (abfd, end - size, SEEK_SET);
2122 nread = bfd_bread (buf, size, abfd);
a95a4550 2123
3af9a47b
NC
2124 if (nread != size)
2125 return -1;
a95a4550 2126
3af9a47b
NC
2127 for (offset = 4; offset <= size; offset += 4)
2128 {
e84d6fca 2129 unsigned long val;
3af9a47b 2130
e84d6fca 2131 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
2132 if (! found_nonnull)
2133 {
2134 if (val != 0)
2135 found_nonnull = 1;
2136 }
2137 else if (val == 0x0)
2138 {
e84d6fca
AM
2139 unsigned long bottom;
2140 unsigned long top;
3af9a47b 2141
e84d6fca
AM
2142 bottom = seg->fileoff + seg->filesize - offset;
2143 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
2144 *rbuf = bfd_malloc (top - bottom);
2145 *rlen = top - bottom;
2146
2147 memcpy (*rbuf, buf + size - *rlen, *rlen);
2148 return 0;
2149 }
2150 }
2151
2152 if (size == (end - start))
2153 break;
2154
2155 size *= 2;
2156 }
2157 }
2158 }
2159
2160 return -1;
2161}
2162
2163char *
2164bfd_mach_o_core_file_failing_command (abfd)
2165 bfd *abfd;
2166{
2167 unsigned char *buf = NULL;
2168 unsigned int len = 0;
2169 int ret = -1;
2170
2171 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
2172 if (ret < 0)
2173 return NULL;
2174
2175 return buf;
2176}
2177
2178int
2179bfd_mach_o_core_file_failing_signal (abfd)
2180 bfd *abfd ATTRIBUTE_UNUSED;
2181{
2182 return 0;
2183}
2184
b34976b6 2185bfd_boolean
3af9a47b
NC
2186bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)
2187 bfd *core_bfd ATTRIBUTE_UNUSED;
2188 bfd *exec_bfd ATTRIBUTE_UNUSED;
2189{
b34976b6 2190 return TRUE;
3af9a47b
NC
2191}
2192
2193#define TARGET_NAME mach_o_be_vec
2194#define TARGET_STRING "mach-o-be"
2195#define TARGET_BIG_ENDIAN 1
2196#define TARGET_ARCHIVE 0
2197
2198#include "mach-o-target.c"
2199
2200#undef TARGET_NAME
2201#undef TARGET_STRING
2202#undef TARGET_BIG_ENDIAN
2203#undef TARGET_ARCHIVE
2204
2205#define TARGET_NAME mach_o_le_vec
2206#define TARGET_STRING "mach-o-le"
2207#define TARGET_BIG_ENDIAN 0
2208#define TARGET_ARCHIVE 0
2209
2210#include "mach-o-target.c"
2211
2212#undef TARGET_NAME
2213#undef TARGET_STRING
2214#undef TARGET_BIG_ENDIAN
2215#undef TARGET_ARCHIVE
2216
2217#define TARGET_NAME mach_o_fat_vec
2218#define TARGET_STRING "mach-o-fat"
2219#define TARGET_BIG_ENDIAN 1
2220#define TARGET_ARCHIVE 1
2221
2222#include "mach-o-target.c"
2223
2224#undef TARGET_NAME
2225#undef TARGET_STRING
2226#undef TARGET_BIG_ENDIAN
2227#undef TARGET_ARCHIVE