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