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