1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
25 #include "libiberty.h"
29 #define BFD_IO_FUNCS 0
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_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
48 #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
49 #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
50 #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
51 #define bfd_mach_o_find_inliner_info _bfd_nosymbols_find_inliner_info
52 #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
53 #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
54 #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
55 #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
56 #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
57 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
58 #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
59 #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
60 #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
61 #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
62 #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
63 #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
64 #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
65 #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
66 #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach
67 #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
68 #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
69 #define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
70 #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
71 #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
72 #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
73 #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
74 #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section
75 #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
76 #define bfd_mach_o_section_already_linked _bfd_generic_section_already_linked
77 #define bfd_mach_o_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
78 #define bfd_mach_o_core_file_matches_executable_p generic_core_file_matches_executable_p
81 /* The flags field of a section structure is separated into two parts a section
82 type and section attributes. The section types are mutually exclusive (it
83 can only have one type) but the section attributes are not (it may have more
84 than one attribute). */
86 #define SECTION_TYPE 0x000000ff /* 256 section types. */
87 #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes. */
89 /* Constants for the section attributes part of the flags field of a section
92 #define SECTION_ATTRIBUTES_USR 0xff000000 /* User-settable attributes. */
93 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* Section contains only true machine instructions. */
94 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* System setable attributes. */
95 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* Section contains some machine instructions. */
96 #define S_ATTR_EXT_RELOC 0x00000200 /* Section has external relocation entries. */
97 #define S_ATTR_LOC_RELOC 0x00000100 /* Section has local relocation entries. */
108 bfd_mach_o_valid (bfd
*abfd
)
110 if (abfd
== NULL
|| abfd
->xvec
== NULL
)
113 if (! ((abfd
->xvec
== &mach_o_be_vec
)
114 || (abfd
->xvec
== &mach_o_le_vec
)
115 || (abfd
->xvec
== &mach_o_fat_vec
)))
118 if (abfd
->tdata
.mach_o_data
== NULL
)
123 /* Copy any private info we understand from the input symbol
124 to the output symbol. */
127 bfd_mach_o_bfd_copy_private_symbol_data (bfd
*ibfd ATTRIBUTE_UNUSED
,
128 asymbol
*isymbol ATTRIBUTE_UNUSED
,
129 bfd
*obfd ATTRIBUTE_UNUSED
,
130 asymbol
*osymbol ATTRIBUTE_UNUSED
)
135 /* Copy any private info we understand from the input section
136 to the output section. */
139 bfd_mach_o_bfd_copy_private_section_data (bfd
*ibfd ATTRIBUTE_UNUSED
,
140 asection
*isection ATTRIBUTE_UNUSED
,
141 bfd
*obfd ATTRIBUTE_UNUSED
,
142 asection
*osection ATTRIBUTE_UNUSED
)
147 /* Copy any private info we understand from the input bfd
148 to the output bfd. */
151 bfd_mach_o_bfd_copy_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
153 BFD_ASSERT (bfd_mach_o_valid (ibfd
));
154 BFD_ASSERT (bfd_mach_o_valid (obfd
));
156 obfd
->tdata
.mach_o_data
= ibfd
->tdata
.mach_o_data
;
157 obfd
->tdata
.mach_o_data
->ibfd
= ibfd
;
162 bfd_mach_o_count_symbols (bfd
*abfd
)
164 bfd_mach_o_data_struct
*mdata
= NULL
;
168 BFD_ASSERT (bfd_mach_o_valid (abfd
));
169 mdata
= abfd
->tdata
.mach_o_data
;
171 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
172 if (mdata
->commands
[i
].type
== BFD_MACH_O_LC_SYMTAB
)
174 bfd_mach_o_symtab_command
*sym
= &mdata
->commands
[i
].command
.symtab
;
182 bfd_mach_o_get_symtab_upper_bound (bfd
*abfd
)
184 long nsyms
= bfd_mach_o_count_symbols (abfd
);
189 return ((nsyms
+ 1) * sizeof (asymbol
*));
193 bfd_mach_o_canonicalize_symtab (bfd
*abfd
, asymbol
**alocation
)
195 bfd_mach_o_data_struct
*mdata
= abfd
->tdata
.mach_o_data
;
196 long nsyms
= bfd_mach_o_count_symbols (abfd
);
197 asymbol
**csym
= alocation
;
203 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
205 if (mdata
->commands
[i
].type
== BFD_MACH_O_LC_SYMTAB
)
207 bfd_mach_o_symtab_command
*sym
= &mdata
->commands
[i
].command
.symtab
;
209 if (bfd_mach_o_scan_read_symtab_symbols (abfd
, &mdata
->commands
[i
].command
.symtab
) != 0)
211 fprintf (stderr
, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i
);
215 BFD_ASSERT (sym
->symbols
!= NULL
);
217 for (j
= 0; j
< sym
->nsyms
; j
++)
219 BFD_ASSERT (csym
< (alocation
+ nsyms
));
220 *csym
++ = &sym
->symbols
[j
];
231 bfd_mach_o_get_symbol_info (bfd
*abfd ATTRIBUTE_UNUSED
,
235 bfd_symbol_info (symbol
, ret
);
239 bfd_mach_o_print_symbol (bfd
*abfd
,
242 bfd_print_symbol_type how
)
244 FILE *file
= (FILE *) afile
;
248 case bfd_print_symbol_name
:
249 fprintf (file
, "%s", symbol
->name
);
252 bfd_print_symbol_vandf (abfd
, (PTR
) file
, symbol
);
253 fprintf (file
, " %-5s %s", symbol
->section
->name
, symbol
->name
);
258 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype
,
259 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED
,
260 enum bfd_architecture
*type
,
261 unsigned long *subtype
)
263 *subtype
= bfd_arch_unknown
;
267 case BFD_MACH_O_CPU_TYPE_VAX
: *type
= bfd_arch_vax
; break;
268 case BFD_MACH_O_CPU_TYPE_MC680x0
: *type
= bfd_arch_m68k
; break;
269 case BFD_MACH_O_CPU_TYPE_I386
: *type
= bfd_arch_i386
; break;
270 case BFD_MACH_O_CPU_TYPE_MIPS
: *type
= bfd_arch_mips
; break;
271 case BFD_MACH_O_CPU_TYPE_MC98000
: *type
= bfd_arch_m98k
; break;
272 case BFD_MACH_O_CPU_TYPE_HPPA
: *type
= bfd_arch_hppa
; break;
273 case BFD_MACH_O_CPU_TYPE_ARM
: *type
= bfd_arch_arm
; break;
274 case BFD_MACH_O_CPU_TYPE_MC88000
: *type
= bfd_arch_m88k
; break;
275 case BFD_MACH_O_CPU_TYPE_SPARC
: *type
= bfd_arch_sparc
; break;
276 case BFD_MACH_O_CPU_TYPE_I860
: *type
= bfd_arch_i860
; break;
277 case BFD_MACH_O_CPU_TYPE_ALPHA
: *type
= bfd_arch_alpha
; break;
278 case BFD_MACH_O_CPU_TYPE_POWERPC
: *type
= bfd_arch_powerpc
; break;
279 default: *type
= bfd_arch_unknown
; break;
284 case bfd_arch_i386
: *subtype
= bfd_mach_i386_i386
; break;
285 case bfd_arch_sparc
: *subtype
= bfd_mach_sparc
; break;
287 *subtype
= bfd_arch_unknown
;
292 bfd_mach_o_write_header (bfd
*abfd
, bfd_mach_o_header
*header
)
294 unsigned char buf
[28];
296 bfd_h_put_32 (abfd
, header
->magic
, buf
+ 0);
297 bfd_h_put_32 (abfd
, header
->cputype
, buf
+ 4);
298 bfd_h_put_32 (abfd
, header
->cpusubtype
, buf
+ 8);
299 bfd_h_put_32 (abfd
, header
->filetype
, buf
+ 12);
300 bfd_h_put_32 (abfd
, header
->ncmds
, buf
+ 16);
301 bfd_h_put_32 (abfd
, header
->sizeofcmds
, buf
+ 20);
302 bfd_h_put_32 (abfd
, header
->flags
, buf
+ 24);
304 bfd_seek (abfd
, 0, SEEK_SET
);
305 if (bfd_bwrite ((PTR
) buf
, 28, abfd
) != 28)
312 bfd_mach_o_scan_write_thread (bfd
*abfd
,
313 bfd_mach_o_load_command
*command
)
315 bfd_mach_o_thread_command
*cmd
= &command
->command
.thread
;
317 unsigned char buf
[8];
319 unsigned int nflavours
;
321 BFD_ASSERT ((command
->type
== BFD_MACH_O_LC_THREAD
)
322 || (command
->type
== BFD_MACH_O_LC_UNIXTHREAD
));
326 for (i
= 0; i
< cmd
->nflavours
; i
++)
328 BFD_ASSERT ((cmd
->flavours
[i
].size
% 4) == 0);
329 BFD_ASSERT (cmd
->flavours
[i
].offset
== (command
->offset
+ offset
+ 8));
331 bfd_h_put_32 (abfd
, cmd
->flavours
[i
].flavour
, buf
);
332 bfd_h_put_32 (abfd
, (cmd
->flavours
[i
].size
/ 4), buf
+ 4);
334 bfd_seek (abfd
, command
->offset
+ offset
, SEEK_SET
);
335 if (bfd_bwrite ((PTR
) buf
, 8, abfd
) != 8)
338 offset
+= cmd
->flavours
[i
].size
+ 8;
345 bfd_mach_o_scan_write_section (bfd
*abfd
,
346 bfd_mach_o_section
*section
,
349 unsigned char buf
[68];
351 memcpy (buf
, section
->sectname
, 16);
352 memcpy (buf
+ 16, section
->segname
, 16);
353 bfd_h_put_32 (abfd
, section
->addr
, buf
+ 32);
354 bfd_h_put_32 (abfd
, section
->size
, buf
+ 36);
355 bfd_h_put_32 (abfd
, section
->offset
, buf
+ 40);
356 bfd_h_put_32 (abfd
, section
->align
, buf
+ 44);
357 bfd_h_put_32 (abfd
, section
->reloff
, buf
+ 48);
358 bfd_h_put_32 (abfd
, section
->nreloc
, buf
+ 52);
359 bfd_h_put_32 (abfd
, section
->flags
, buf
+ 56);
360 /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
361 /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
363 bfd_seek (abfd
, offset
, SEEK_SET
);
364 if (bfd_bwrite ((PTR
) buf
, 68, abfd
) != 68)
371 bfd_mach_o_scan_write_segment (bfd
*abfd
, bfd_mach_o_load_command
*command
)
373 unsigned char buf
[48];
374 bfd_mach_o_segment_command
*seg
= &command
->command
.segment
;
377 BFD_ASSERT (command
->type
== BFD_MACH_O_LC_SEGMENT
);
379 memcpy (buf
, seg
->segname
, 16);
380 bfd_h_put_32 (abfd
, seg
->vmaddr
, buf
+ 16);
381 bfd_h_put_32 (abfd
, seg
->vmsize
, buf
+ 20);
382 bfd_h_put_32 (abfd
, seg
->fileoff
, buf
+ 24);
383 bfd_h_put_32 (abfd
, seg
->filesize
, buf
+ 28);
384 bfd_h_put_32 (abfd
, 0 /* seg->maxprot */, buf
+ 32);
385 bfd_h_put_32 (abfd
, 0 /* seg->initprot */, buf
+ 36);
386 bfd_h_put_32 (abfd
, seg
->nsects
, buf
+ 40);
387 bfd_h_put_32 (abfd
, seg
->flags
, buf
+ 44);
389 bfd_seek (abfd
, command
->offset
+ 8, SEEK_SET
);
390 if (bfd_bwrite ((PTR
) buf
, 48, abfd
) != 48)
395 bfd_vma nbytes
= seg
->filesize
;
396 bfd_vma curoff
= seg
->fileoff
;
400 bfd_vma thisread
= nbytes
;
405 bfd_seek (abfd
, curoff
, SEEK_SET
);
406 if (bfd_bread ((PTR
) buf
, thisread
, abfd
) != thisread
)
409 bfd_seek (abfd
, curoff
, SEEK_SET
);
410 if (bfd_bwrite ((PTR
) buf
, thisread
, abfd
) != thisread
)
418 for (i
= 0; i
< seg
->nsects
; i
++)
420 bfd_vma segoff
= command
->offset
+ 48 + 8 + (i
* 68);
422 if (bfd_mach_o_scan_write_section (abfd
, &seg
->sections
[i
], segoff
) != 0)
430 bfd_mach_o_scan_write_symtab_symbols (bfd
*abfd
,
431 bfd_mach_o_load_command
*command
)
433 bfd_mach_o_symtab_command
*sym
= &command
->command
.symtab
;
437 for (i
= 0; i
< sym
->nsyms
; i
++)
439 unsigned char buf
[12];
440 bfd_vma symoff
= sym
->symoff
+ (i
* 12);
441 unsigned char ntype
= 0;
442 unsigned char nsect
= 0;
445 s
= &sym
->symbols
[i
];
447 /* Instead just set from the stored values. */
448 ntype
= (s
->udata
.i
>> 24) & 0xff;
449 nsect
= (s
->udata
.i
>> 16) & 0xff;
450 ndesc
= s
->udata
.i
& 0xffff;
452 bfd_h_put_32 (abfd
, s
->name
- sym
->strtab
, buf
);
453 bfd_h_put_8 (abfd
, ntype
, buf
+ 4);
454 bfd_h_put_8 (abfd
, nsect
, buf
+ 5);
455 bfd_h_put_16 (abfd
, ndesc
, buf
+ 6);
456 bfd_h_put_32 (abfd
, s
->section
->vma
+ s
->value
, buf
+ 8);
458 bfd_seek (abfd
, symoff
, SEEK_SET
);
459 if (bfd_bwrite ((PTR
) buf
, 12, abfd
) != 12)
461 fprintf (stderr
, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
462 12, (unsigned long) symoff
);
471 bfd_mach_o_scan_write_symtab (bfd
*abfd
, bfd_mach_o_load_command
*command
)
473 bfd_mach_o_symtab_command
*seg
= &command
->command
.symtab
;
474 unsigned char buf
[16];
476 BFD_ASSERT (command
->type
== BFD_MACH_O_LC_SYMTAB
);
478 bfd_h_put_32 (abfd
, seg
->symoff
, buf
);
479 bfd_h_put_32 (abfd
, seg
->nsyms
, buf
+ 4);
480 bfd_h_put_32 (abfd
, seg
->stroff
, buf
+ 8);
481 bfd_h_put_32 (abfd
, seg
->strsize
, buf
+ 12);
483 bfd_seek (abfd
, command
->offset
+ 8, SEEK_SET
);
484 if (bfd_bwrite ((PTR
) buf
, 16, abfd
) != 16)
487 if (bfd_mach_o_scan_write_symtab_symbols (abfd
, command
) != 0)
494 bfd_mach_o_write_contents (bfd
*abfd
)
499 bfd_mach_o_data_struct
*mdata
= abfd
->tdata
.mach_o_data
;
501 /* Write data sections first in case they overlap header data to be
504 for (s
= abfd
->sections
; s
!= (asection
*) NULL
; s
= s
->next
)
507 /* Now write header information. */
508 if (bfd_mach_o_write_header (abfd
, &mdata
->header
) != 0)
511 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
513 unsigned char buf
[8];
514 bfd_mach_o_load_command
*cur
= &mdata
->commands
[i
];
515 unsigned long typeflag
;
517 typeflag
= cur
->type_required
? cur
->type
& BFD_MACH_O_LC_REQ_DYLD
: cur
->type
;
519 bfd_h_put_32 (abfd
, typeflag
, buf
);
520 bfd_h_put_32 (abfd
, cur
->len
, buf
+ 4);
522 bfd_seek (abfd
, cur
->offset
, SEEK_SET
);
523 if (bfd_bwrite ((PTR
) buf
, 8, abfd
) != 8)
528 case BFD_MACH_O_LC_SEGMENT
:
529 if (bfd_mach_o_scan_write_segment (abfd
, cur
) != 0)
532 case BFD_MACH_O_LC_SYMTAB
:
533 if (bfd_mach_o_scan_write_symtab (abfd
, cur
) != 0)
536 case BFD_MACH_O_LC_SYMSEG
:
538 case BFD_MACH_O_LC_THREAD
:
539 case BFD_MACH_O_LC_UNIXTHREAD
:
540 if (bfd_mach_o_scan_write_thread (abfd
, cur
) != 0)
543 case BFD_MACH_O_LC_LOADFVMLIB
:
544 case BFD_MACH_O_LC_IDFVMLIB
:
545 case BFD_MACH_O_LC_IDENT
:
546 case BFD_MACH_O_LC_FVMFILE
:
547 case BFD_MACH_O_LC_PREPAGE
:
548 case BFD_MACH_O_LC_DYSYMTAB
:
549 case BFD_MACH_O_LC_LOAD_DYLIB
:
550 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB
:
551 case BFD_MACH_O_LC_ID_DYLIB
:
552 case BFD_MACH_O_LC_LOAD_DYLINKER
:
553 case BFD_MACH_O_LC_ID_DYLINKER
:
554 case BFD_MACH_O_LC_PREBOUND_DYLIB
:
555 case BFD_MACH_O_LC_ROUTINES
:
556 case BFD_MACH_O_LC_SUB_FRAMEWORK
:
560 "unable to write unknown load command 0x%lx\n",
570 bfd_mach_o_sizeof_headers (bfd
*a ATTRIBUTE_UNUSED
,
571 bfd_boolean b ATTRIBUTE_UNUSED
)
576 /* Make an empty symbol. This is required only because
577 bfd_make_section_anyway wants to create a symbol for the section. */
580 bfd_mach_o_make_empty_symbol (bfd
*abfd
)
584 new = bfd_zalloc (abfd
, sizeof (* new));
592 bfd_mach_o_read_header (bfd
*abfd
, bfd_mach_o_header
*header
)
594 unsigned char buf
[28];
595 bfd_vma (*get32
) (const void *) = NULL
;
597 bfd_seek (abfd
, 0, SEEK_SET
);
599 if (bfd_bread ((PTR
) buf
, 28, abfd
) != 28)
602 if (bfd_getb32 (buf
) == 0xfeedface)
604 header
->byteorder
= BFD_ENDIAN_BIG
;
605 header
->magic
= 0xfeedface;
608 else if (bfd_getl32 (buf
) == 0xfeedface)
610 header
->byteorder
= BFD_ENDIAN_LITTLE
;
611 header
->magic
= 0xfeedface;
616 header
->byteorder
= BFD_ENDIAN_UNKNOWN
;
620 header
->cputype
= (*get32
) (buf
+ 4);
621 header
->cpusubtype
= (*get32
) (buf
+ 8);
622 header
->filetype
= (*get32
) (buf
+ 12);
623 header
->ncmds
= (*get32
) (buf
+ 16);
624 header
->sizeofcmds
= (*get32
) (buf
+ 20);
625 header
->flags
= (*get32
) (buf
+ 24);
631 bfd_mach_o_make_bfd_section (bfd
*abfd
, bfd_mach_o_section
*section
)
635 const char *prefix
= "LC_SEGMENT";
636 unsigned int snamelen
;
638 snamelen
= strlen (prefix
) + 1
639 + strlen (section
->segname
) + 1
640 + strlen (section
->sectname
) + 1;
642 sname
= bfd_alloc (abfd
, snamelen
);
645 sprintf (sname
, "%s.%s.%s", prefix
, section
->segname
, section
->sectname
);
647 bfdsec
= bfd_make_section_anyway (abfd
, sname
);
651 bfdsec
->vma
= section
->addr
;
652 bfdsec
->lma
= section
->addr
;
653 bfdsec
->size
= section
->size
;
654 bfdsec
->filepos
= section
->offset
;
655 bfdsec
->alignment_power
= section
->align
;
657 if (section
->flags
& BFD_MACH_O_S_ZEROFILL
)
658 bfdsec
->flags
= SEC_ALLOC
;
660 bfdsec
->flags
= SEC_HAS_CONTENTS
| SEC_LOAD
| SEC_ALLOC
| SEC_CODE
;
666 bfd_mach_o_scan_read_section (bfd
*abfd
,
667 bfd_mach_o_section
*section
,
670 unsigned char buf
[68];
672 bfd_seek (abfd
, offset
, SEEK_SET
);
673 if (bfd_bread ((PTR
) buf
, 68, abfd
) != 68)
676 memcpy (section
->sectname
, buf
, 16);
677 section
->sectname
[16] = '\0';
678 memcpy (section
->segname
, buf
+ 16, 16);
679 section
->segname
[16] = '\0';
680 section
->addr
= bfd_h_get_32 (abfd
, buf
+ 32);
681 section
->size
= bfd_h_get_32 (abfd
, buf
+ 36);
682 section
->offset
= bfd_h_get_32 (abfd
, buf
+ 40);
683 section
->align
= bfd_h_get_32 (abfd
, buf
+ 44);
684 section
->reloff
= bfd_h_get_32 (abfd
, buf
+ 48);
685 section
->nreloc
= bfd_h_get_32 (abfd
, buf
+ 52);
686 section
->flags
= bfd_h_get_32 (abfd
, buf
+ 56);
687 section
->reserved1
= bfd_h_get_32 (abfd
, buf
+ 60);
688 section
->reserved2
= bfd_h_get_32 (abfd
, buf
+ 64);
689 section
->bfdsection
= bfd_mach_o_make_bfd_section (abfd
, section
);
691 if (section
->bfdsection
== NULL
)
698 bfd_mach_o_scan_read_symtab_symbol (bfd
*abfd
,
699 bfd_mach_o_symtab_command
*sym
,
703 bfd_mach_o_data_struct
*mdata
= abfd
->tdata
.mach_o_data
;
704 bfd_vma symoff
= sym
->symoff
+ (i
* 12);
705 unsigned char buf
[12];
706 unsigned char type
= -1;
707 unsigned char section
= -1;
709 unsigned long value
= -1;
710 unsigned long stroff
= -1;
711 unsigned int symtype
= -1;
713 BFD_ASSERT (sym
->strtab
!= NULL
);
715 bfd_seek (abfd
, symoff
, SEEK_SET
);
716 if (bfd_bread ((PTR
) buf
, 12, abfd
) != 12)
718 fprintf (stderr
, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
719 12, (unsigned long) symoff
);
723 stroff
= bfd_h_get_32 (abfd
, buf
);
724 type
= bfd_h_get_8 (abfd
, buf
+ 4);
725 symtype
= (type
& 0x0e);
726 section
= bfd_h_get_8 (abfd
, buf
+ 5) - 1;
727 desc
= bfd_h_get_16 (abfd
, buf
+ 6);
728 value
= bfd_h_get_32 (abfd
, buf
+ 8);
730 if (stroff
>= sym
->strsize
)
732 fprintf (stderr
, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
733 (unsigned long) stroff
, (unsigned long) sym
->strsize
);
738 s
->name
= sym
->strtab
+ stroff
;
740 s
->udata
.i
= (type
<< 24) | (section
<< 16) | desc
;
743 if (type
& BFD_MACH_O_N_STAB
)
745 s
->flags
|= BSF_DEBUGGING
;
746 s
->section
= bfd_und_section_ptr
;
750 if (type
& BFD_MACH_O_N_PEXT
)
752 type
&= ~BFD_MACH_O_N_PEXT
;
753 s
->flags
|= BSF_GLOBAL
;
756 if (type
& BFD_MACH_O_N_EXT
)
758 type
&= ~BFD_MACH_O_N_EXT
;
759 s
->flags
|= BSF_GLOBAL
;
764 case BFD_MACH_O_N_UNDF
:
765 s
->section
= bfd_und_section_ptr
;
767 case BFD_MACH_O_N_PBUD
:
768 s
->section
= bfd_und_section_ptr
;
770 case BFD_MACH_O_N_ABS
:
771 s
->section
= bfd_abs_section_ptr
;
773 case BFD_MACH_O_N_SECT
:
774 if ((section
> 0) && (section
<= mdata
->nsects
))
776 s
->section
= mdata
->sections
[section
- 1]->bfdsection
;
777 s
->value
= s
->value
- mdata
->sections
[section
- 1]->addr
;
781 /* Mach-O uses 0 to mean "no section"; not an error. */
784 fprintf (stderr
, "bfd_mach_o_scan_read_symtab_symbol: "
785 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
786 s
->name
, section
, mdata
->nsects
);
788 s
->section
= bfd_und_section_ptr
;
791 case BFD_MACH_O_N_INDR
:
792 fprintf (stderr
, "bfd_mach_o_scan_read_symtab_symbol: "
793 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
795 s
->section
= bfd_und_section_ptr
;
798 fprintf (stderr
, "bfd_mach_o_scan_read_symtab_symbol: "
799 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
801 s
->section
= bfd_und_section_ptr
;
810 bfd_mach_o_scan_read_symtab_strtab (bfd
*abfd
,
811 bfd_mach_o_symtab_command
*sym
)
813 BFD_ASSERT (sym
->strtab
== NULL
);
815 if (abfd
->flags
& BFD_IN_MEMORY
)
817 struct bfd_in_memory
*b
;
819 b
= (struct bfd_in_memory
*) abfd
->iostream
;
821 if ((sym
->stroff
+ sym
->strsize
) > b
->size
)
823 bfd_set_error (bfd_error_file_truncated
);
826 sym
->strtab
= (char *) b
->buffer
+ sym
->stroff
;
830 sym
->strtab
= bfd_alloc (abfd
, sym
->strsize
);
831 if (sym
->strtab
== NULL
)
834 bfd_seek (abfd
, sym
->stroff
, SEEK_SET
);
835 if (bfd_bread ((PTR
) sym
->strtab
, sym
->strsize
, abfd
) != sym
->strsize
)
837 fprintf (stderr
, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
838 sym
->strsize
, sym
->stroff
);
846 bfd_mach_o_scan_read_symtab_symbols (bfd
*abfd
,
847 bfd_mach_o_symtab_command
*sym
)
852 BFD_ASSERT (sym
->symbols
== NULL
);
853 sym
->symbols
= bfd_alloc (abfd
, sym
->nsyms
* sizeof (asymbol
));
855 if (sym
->symbols
== NULL
)
857 fprintf (stderr
, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
861 ret
= bfd_mach_o_scan_read_symtab_strtab (abfd
, sym
);
865 for (i
= 0; i
< sym
->nsyms
; i
++)
867 ret
= bfd_mach_o_scan_read_symtab_symbol (abfd
, sym
, &sym
->symbols
[i
], i
);
876 bfd_mach_o_scan_read_dysymtab_symbol (bfd
*abfd
,
877 bfd_mach_o_dysymtab_command
*dysym
,
878 bfd_mach_o_symtab_command
*sym
,
882 unsigned long isymoff
= dysym
->indirectsymoff
+ (i
* 4);
883 unsigned long symindex
;
884 unsigned char buf
[4];
886 BFD_ASSERT (i
< dysym
->nindirectsyms
);
888 bfd_seek (abfd
, isymoff
, SEEK_SET
);
889 if (bfd_bread ((PTR
) buf
, 4, abfd
) != 4)
891 fprintf (stderr
, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
892 (unsigned long) 4, isymoff
);
895 symindex
= bfd_h_get_32 (abfd
, buf
);
897 return bfd_mach_o_scan_read_symtab_symbol (abfd
, sym
, s
, symindex
);
901 bfd_mach_o_i386_flavour_string (unsigned int flavour
)
903 switch ((int) flavour
)
905 case BFD_MACH_O_i386_NEW_THREAD_STATE
: return "i386_NEW_THREAD_STATE";
906 case BFD_MACH_O_i386_FLOAT_STATE
: return "i386_FLOAT_STATE";
907 case BFD_MACH_O_i386_ISA_PORT_MAP_STATE
: return "i386_ISA_PORT_MAP_STATE";
908 case BFD_MACH_O_i386_V86_ASSIST_STATE
: return "i386_V86_ASSIST_STATE";
909 case BFD_MACH_O_i386_REGS_SEGS_STATE
: return "i386_REGS_SEGS_STATE";
910 case BFD_MACH_O_i386_THREAD_SYSCALL_STATE
: return "i386_THREAD_SYSCALL_STATE";
911 case BFD_MACH_O_i386_THREAD_STATE_NONE
: return "i386_THREAD_STATE_NONE";
912 case BFD_MACH_O_i386_SAVED_STATE
: return "i386_SAVED_STATE";
913 case BFD_MACH_O_i386_THREAD_STATE
: return "i386_THREAD_STATE";
914 case BFD_MACH_O_i386_THREAD_FPSTATE
: return "i386_THREAD_FPSTATE";
915 case BFD_MACH_O_i386_THREAD_EXCEPTSTATE
: return "i386_THREAD_EXCEPTSTATE";
916 case BFD_MACH_O_i386_THREAD_CTHREADSTATE
: return "i386_THREAD_CTHREADSTATE";
917 default: return "UNKNOWN";
922 bfd_mach_o_ppc_flavour_string (unsigned int flavour
)
924 switch ((int) flavour
)
926 case BFD_MACH_O_PPC_THREAD_STATE
: return "PPC_THREAD_STATE";
927 case BFD_MACH_O_PPC_FLOAT_STATE
: return "PPC_FLOAT_STATE";
928 case BFD_MACH_O_PPC_EXCEPTION_STATE
: return "PPC_EXCEPTION_STATE";
929 case BFD_MACH_O_PPC_VECTOR_STATE
: return "PPC_VECTOR_STATE";
930 default: return "UNKNOWN";
935 bfd_mach_o_scan_read_dylinker (bfd
*abfd
,
936 bfd_mach_o_load_command
*command
)
938 bfd_mach_o_dylinker_command
*cmd
= &command
->command
.dylinker
;
939 unsigned char buf
[4];
940 unsigned int nameoff
;
945 BFD_ASSERT ((command
->type
== BFD_MACH_O_LC_ID_DYLINKER
)
946 || (command
->type
== BFD_MACH_O_LC_LOAD_DYLINKER
));
948 bfd_seek (abfd
, command
->offset
+ 8, SEEK_SET
);
949 if (bfd_bread ((PTR
) buf
, 4, abfd
) != 4)
952 nameoff
= bfd_h_get_32 (abfd
, buf
+ 0);
954 cmd
->name_offset
= command
->offset
+ nameoff
;
955 cmd
->name_len
= command
->len
- nameoff
;
957 if (command
->type
== BFD_MACH_O_LC_LOAD_DYLINKER
)
958 prefix
= "LC_LOAD_DYLINKER";
959 else if (command
->type
== BFD_MACH_O_LC_ID_DYLINKER
)
960 prefix
= "LC_ID_DYLINKER";
964 sname
= bfd_alloc (abfd
, strlen (prefix
) + 1);
967 strcpy (sname
, prefix
);
969 bfdsec
= bfd_make_section_anyway (abfd
, sname
);
975 bfdsec
->size
= command
->len
- 8;
976 bfdsec
->filepos
= command
->offset
+ 8;
977 bfdsec
->alignment_power
= 0;
978 bfdsec
->flags
= SEC_HAS_CONTENTS
;
980 cmd
->section
= bfdsec
;
986 bfd_mach_o_scan_read_dylib (bfd
*abfd
, bfd_mach_o_load_command
*command
)
988 bfd_mach_o_dylib_command
*cmd
= &command
->command
.dylib
;
989 unsigned char buf
[16];
990 unsigned int nameoff
;
995 BFD_ASSERT ((command
->type
== BFD_MACH_O_LC_ID_DYLIB
)
996 || (command
->type
== BFD_MACH_O_LC_LOAD_DYLIB
)
997 || (command
->type
== BFD_MACH_O_LC_LOAD_WEAK_DYLIB
));
999 bfd_seek (abfd
, command
->offset
+ 8, SEEK_SET
);
1000 if (bfd_bread ((PTR
) buf
, 16, abfd
) != 16)
1003 nameoff
= bfd_h_get_32 (abfd
, buf
+ 0);
1004 cmd
->timestamp
= bfd_h_get_32 (abfd
, buf
+ 4);
1005 cmd
->current_version
= bfd_h_get_32 (abfd
, buf
+ 8);
1006 cmd
->compatibility_version
= bfd_h_get_32 (abfd
, buf
+ 12);
1008 cmd
->name_offset
= command
->offset
+ nameoff
;
1009 cmd
->name_len
= command
->len
- nameoff
;
1011 if (command
->type
== BFD_MACH_O_LC_LOAD_DYLIB
)
1012 prefix
= "LC_LOAD_DYLIB";
1013 else if (command
->type
== BFD_MACH_O_LC_LOAD_WEAK_DYLIB
)
1014 prefix
= "LC_LOAD_WEAK_DYLIB";
1015 else if (command
->type
== BFD_MACH_O_LC_ID_DYLIB
)
1016 prefix
= "LC_ID_DYLIB";
1020 sname
= bfd_alloc (abfd
, strlen (prefix
) + 1);
1023 strcpy (sname
, prefix
);
1025 bfdsec
= bfd_make_section_anyway (abfd
, sname
);
1031 bfdsec
->size
= command
->len
- 8;
1032 bfdsec
->filepos
= command
->offset
+ 8;
1033 bfdsec
->alignment_power
= 0;
1034 bfdsec
->flags
= SEC_HAS_CONTENTS
;
1036 cmd
->section
= bfdsec
;
1042 bfd_mach_o_scan_read_prebound_dylib (bfd
*abfd ATTRIBUTE_UNUSED
,
1043 bfd_mach_o_load_command
*command ATTRIBUTE_UNUSED
)
1045 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1047 BFD_ASSERT (command
->type
== BFD_MACH_O_LC_PREBOUND_DYLIB
);
1052 bfd_mach_o_scan_read_thread (bfd
*abfd
, bfd_mach_o_load_command
*command
)
1054 bfd_mach_o_data_struct
*mdata
= NULL
;
1055 bfd_mach_o_thread_command
*cmd
= &command
->command
.thread
;
1056 unsigned char buf
[8];
1058 unsigned int nflavours
;
1061 BFD_ASSERT ((command
->type
== BFD_MACH_O_LC_THREAD
)
1062 || (command
->type
== BFD_MACH_O_LC_UNIXTHREAD
));
1064 BFD_ASSERT (bfd_mach_o_valid (abfd
));
1065 mdata
= abfd
->tdata
.mach_o_data
;
1069 while (offset
!= command
->len
)
1071 if (offset
>= command
->len
)
1074 bfd_seek (abfd
, command
->offset
+ offset
, SEEK_SET
);
1076 if (bfd_bread ((PTR
) buf
, 8, abfd
) != 8)
1079 offset
+= 8 + bfd_h_get_32 (abfd
, buf
+ 4) * 4;
1083 cmd
->flavours
= bfd_alloc (abfd
, nflavours
* sizeof (bfd_mach_o_thread_flavour
));
1084 if (cmd
->flavours
== NULL
)
1086 cmd
->nflavours
= nflavours
;
1090 while (offset
!= command
->len
)
1092 if (offset
>= command
->len
)
1095 if (nflavours
>= cmd
->nflavours
)
1098 bfd_seek (abfd
, command
->offset
+ offset
, SEEK_SET
);
1100 if (bfd_bread ((PTR
) buf
, 8, abfd
) != 8)
1103 cmd
->flavours
[nflavours
].flavour
= bfd_h_get_32 (abfd
, buf
);
1104 cmd
->flavours
[nflavours
].offset
= command
->offset
+ offset
+ 8;
1105 cmd
->flavours
[nflavours
].size
= bfd_h_get_32 (abfd
, buf
+ 4) * 4;
1106 offset
+= cmd
->flavours
[nflavours
].size
+ 8;
1110 for (i
= 0; i
< nflavours
; i
++)
1113 unsigned int snamelen
;
1115 const char *flavourstr
;
1116 const char *prefix
= "LC_THREAD";
1119 switch (mdata
->header
.cputype
)
1121 case BFD_MACH_O_CPU_TYPE_POWERPC
:
1122 flavourstr
= bfd_mach_o_ppc_flavour_string (cmd
->flavours
[i
].flavour
);
1124 case BFD_MACH_O_CPU_TYPE_I386
:
1125 flavourstr
= bfd_mach_o_i386_flavour_string (cmd
->flavours
[i
].flavour
);
1128 flavourstr
= "UNKNOWN_ARCHITECTURE";
1132 snamelen
= strlen (prefix
) + 1 + 20 + 1 + strlen (flavourstr
) + 1;
1133 sname
= bfd_alloc (abfd
, snamelen
);
1139 sprintf (sname
, "%s.%s.%u", prefix
, flavourstr
, j
);
1140 if (bfd_get_section_by_name (abfd
, sname
) == NULL
)
1145 bfdsec
= bfd_make_section (abfd
, sname
);
1149 bfdsec
->size
= cmd
->flavours
[i
].size
;
1150 bfdsec
->filepos
= cmd
->flavours
[i
].offset
;
1151 bfdsec
->alignment_power
= 0x0;
1152 bfdsec
->flags
= SEC_HAS_CONTENTS
;
1154 cmd
->section
= bfdsec
;
1161 bfd_mach_o_scan_read_dysymtab (bfd
*abfd
, bfd_mach_o_load_command
*command
)
1163 bfd_mach_o_dysymtab_command
*seg
= &command
->command
.dysymtab
;
1164 unsigned char buf
[72];
1166 BFD_ASSERT (command
->type
== BFD_MACH_O_LC_DYSYMTAB
);
1168 bfd_seek (abfd
, command
->offset
+ 8, SEEK_SET
);
1169 if (bfd_bread ((PTR
) buf
, 72, abfd
) != 72)
1172 seg
->ilocalsym
= bfd_h_get_32 (abfd
, buf
+ 0);
1173 seg
->nlocalsym
= bfd_h_get_32 (abfd
, buf
+ 4);
1174 seg
->iextdefsym
= bfd_h_get_32 (abfd
, buf
+ 8);
1175 seg
->nextdefsym
= bfd_h_get_32 (abfd
, buf
+ 12);
1176 seg
->iundefsym
= bfd_h_get_32 (abfd
, buf
+ 16);
1177 seg
->nundefsym
= bfd_h_get_32 (abfd
, buf
+ 20);
1178 seg
->tocoff
= bfd_h_get_32 (abfd
, buf
+ 24);
1179 seg
->ntoc
= bfd_h_get_32 (abfd
, buf
+ 28);
1180 seg
->modtaboff
= bfd_h_get_32 (abfd
, buf
+ 32);
1181 seg
->nmodtab
= bfd_h_get_32 (abfd
, buf
+ 36);
1182 seg
->extrefsymoff
= bfd_h_get_32 (abfd
, buf
+ 40);
1183 seg
->nextrefsyms
= bfd_h_get_32 (abfd
, buf
+ 44);
1184 seg
->indirectsymoff
= bfd_h_get_32 (abfd
, buf
+ 48);
1185 seg
->nindirectsyms
= bfd_h_get_32 (abfd
, buf
+ 52);
1186 seg
->extreloff
= bfd_h_get_32 (abfd
, buf
+ 56);
1187 seg
->nextrel
= bfd_h_get_32 (abfd
, buf
+ 60);
1188 seg
->locreloff
= bfd_h_get_32 (abfd
, buf
+ 64);
1189 seg
->nlocrel
= bfd_h_get_32 (abfd
, buf
+ 68);
1195 bfd_mach_o_scan_read_symtab (bfd
*abfd
, bfd_mach_o_load_command
*command
)
1197 bfd_mach_o_symtab_command
*seg
= &command
->command
.symtab
;
1198 unsigned char buf
[16];
1201 const char *prefix
= "LC_SYMTAB.stabs";
1203 BFD_ASSERT (command
->type
== BFD_MACH_O_LC_SYMTAB
);
1205 bfd_seek (abfd
, command
->offset
+ 8, SEEK_SET
);
1206 if (bfd_bread ((PTR
) buf
, 16, abfd
) != 16)
1209 seg
->symoff
= bfd_h_get_32 (abfd
, buf
);
1210 seg
->nsyms
= bfd_h_get_32 (abfd
, buf
+ 4);
1211 seg
->stroff
= bfd_h_get_32 (abfd
, buf
+ 8);
1212 seg
->strsize
= bfd_h_get_32 (abfd
, buf
+ 12);
1213 seg
->symbols
= NULL
;
1216 sname
= bfd_alloc (abfd
, strlen (prefix
) + 1);
1219 strcpy (sname
, prefix
);
1221 bfdsec
= bfd_make_section_anyway (abfd
, sname
);
1227 bfdsec
->size
= seg
->nsyms
* 12;
1228 bfdsec
->filepos
= seg
->symoff
;
1229 bfdsec
->alignment_power
= 0;
1230 bfdsec
->flags
= SEC_HAS_CONTENTS
;
1232 seg
->stabs_segment
= bfdsec
;
1234 prefix
= "LC_SYMTAB.stabstr";
1235 sname
= bfd_alloc (abfd
, strlen (prefix
) + 1);
1238 strcpy (sname
, prefix
);
1240 bfdsec
= bfd_make_section_anyway (abfd
, sname
);
1246 bfdsec
->size
= seg
->strsize
;
1247 bfdsec
->filepos
= seg
->stroff
;
1248 bfdsec
->alignment_power
= 0;
1249 bfdsec
->flags
= SEC_HAS_CONTENTS
;
1251 seg
->stabstr_segment
= bfdsec
;
1257 bfd_mach_o_scan_read_segment (bfd
*abfd
, bfd_mach_o_load_command
*command
)
1259 unsigned char buf
[48];
1260 bfd_mach_o_segment_command
*seg
= &command
->command
.segment
;
1264 const char *prefix
= "LC_SEGMENT";
1265 unsigned int snamelen
;
1267 BFD_ASSERT (command
->type
== BFD_MACH_O_LC_SEGMENT
);
1269 bfd_seek (abfd
, command
->offset
+ 8, SEEK_SET
);
1270 if (bfd_bread ((PTR
) buf
, 48, abfd
) != 48)
1273 memcpy (seg
->segname
, buf
, 16);
1274 seg
->vmaddr
= bfd_h_get_32 (abfd
, buf
+ 16);
1275 seg
->vmsize
= bfd_h_get_32 (abfd
, buf
+ 20);
1276 seg
->fileoff
= bfd_h_get_32 (abfd
, buf
+ 24);
1277 seg
->filesize
= bfd_h_get_32 (abfd
, buf
+ 28);
1278 /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1279 /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1280 seg
->nsects
= bfd_h_get_32 (abfd
, buf
+ 40);
1281 seg
->flags
= bfd_h_get_32 (abfd
, buf
+ 44);
1283 snamelen
= strlen (prefix
) + 1 + strlen (seg
->segname
) + 1;
1284 sname
= bfd_alloc (abfd
, snamelen
);
1287 sprintf (sname
, "%s.%s", prefix
, seg
->segname
);
1289 bfdsec
= bfd_make_section_anyway (abfd
, sname
);
1293 bfdsec
->vma
= seg
->vmaddr
;
1294 bfdsec
->lma
= seg
->vmaddr
;
1295 bfdsec
->size
= seg
->filesize
;
1296 bfdsec
->filepos
= seg
->fileoff
;
1297 bfdsec
->alignment_power
= 0x0;
1298 bfdsec
->flags
= SEC_HAS_CONTENTS
| SEC_LOAD
| SEC_ALLOC
| SEC_CODE
;
1300 seg
->segment
= bfdsec
;
1302 if (seg
->nsects
!= 0)
1304 seg
->sections
= bfd_alloc (abfd
, seg
->nsects
* sizeof (bfd_mach_o_section
));
1305 if (seg
->sections
== NULL
)
1308 for (i
= 0; i
< seg
->nsects
; i
++)
1310 bfd_vma segoff
= command
->offset
+ 48 + 8 + (i
* 68);
1312 if (bfd_mach_o_scan_read_section (abfd
, &seg
->sections
[i
],
1322 bfd_mach_o_scan_read_command (bfd
*abfd
, bfd_mach_o_load_command
*command
)
1324 unsigned char buf
[8];
1326 bfd_seek (abfd
, command
->offset
, SEEK_SET
);
1327 if (bfd_bread ((PTR
) buf
, 8, abfd
) != 8)
1330 command
->type
= (bfd_h_get_32 (abfd
, buf
) & ~BFD_MACH_O_LC_REQ_DYLD
);
1331 command
->type_required
= (bfd_h_get_32 (abfd
, buf
) & BFD_MACH_O_LC_REQ_DYLD
1333 command
->len
= bfd_h_get_32 (abfd
, buf
+ 4);
1335 switch (command
->type
)
1337 case BFD_MACH_O_LC_SEGMENT
:
1338 if (bfd_mach_o_scan_read_segment (abfd
, command
) != 0)
1341 case BFD_MACH_O_LC_SYMTAB
:
1342 if (bfd_mach_o_scan_read_symtab (abfd
, command
) != 0)
1345 case BFD_MACH_O_LC_SYMSEG
:
1347 case BFD_MACH_O_LC_THREAD
:
1348 case BFD_MACH_O_LC_UNIXTHREAD
:
1349 if (bfd_mach_o_scan_read_thread (abfd
, command
) != 0)
1352 case BFD_MACH_O_LC_LOAD_DYLINKER
:
1353 case BFD_MACH_O_LC_ID_DYLINKER
:
1354 if (bfd_mach_o_scan_read_dylinker (abfd
, command
) != 0)
1357 case BFD_MACH_O_LC_LOAD_DYLIB
:
1358 case BFD_MACH_O_LC_ID_DYLIB
:
1359 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB
:
1360 if (bfd_mach_o_scan_read_dylib (abfd
, command
) != 0)
1363 case BFD_MACH_O_LC_PREBOUND_DYLIB
:
1364 if (bfd_mach_o_scan_read_prebound_dylib (abfd
, command
) != 0)
1367 case BFD_MACH_O_LC_LOADFVMLIB
:
1368 case BFD_MACH_O_LC_IDFVMLIB
:
1369 case BFD_MACH_O_LC_IDENT
:
1370 case BFD_MACH_O_LC_FVMFILE
:
1371 case BFD_MACH_O_LC_PREPAGE
:
1372 case BFD_MACH_O_LC_ROUTINES
:
1373 case BFD_MACH_O_LC_SUB_FRAMEWORK
:
1375 case BFD_MACH_O_LC_DYSYMTAB
:
1376 if (bfd_mach_o_scan_read_dysymtab (abfd
, command
) != 0)
1379 case BFD_MACH_O_LC_SUB_UMBRELLA
:
1380 case BFD_MACH_O_LC_SUB_CLIENT
:
1381 case BFD_MACH_O_LC_SUB_LIBRARY
:
1382 case BFD_MACH_O_LC_TWOLEVEL_HINTS
:
1383 case BFD_MACH_O_LC_PREBIND_CKSUM
:
1386 fprintf (stderr
, "unable to read unknown load command 0x%lx\n",
1387 (unsigned long) command
->type
);
1395 bfd_mach_o_flatten_sections (bfd
*abfd
)
1397 bfd_mach_o_data_struct
*mdata
= abfd
->tdata
.mach_o_data
;
1403 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1405 if (mdata
->commands
[i
].type
== BFD_MACH_O_LC_SEGMENT
)
1407 bfd_mach_o_segment_command
*seg
;
1409 seg
= &mdata
->commands
[i
].command
.segment
;
1410 mdata
->nsects
+= seg
->nsects
;
1414 mdata
->sections
= bfd_alloc (abfd
,
1415 mdata
->nsects
* sizeof (bfd_mach_o_section
*));
1418 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1420 if (mdata
->commands
[i
].type
== BFD_MACH_O_LC_SEGMENT
)
1422 bfd_mach_o_segment_command
*seg
;
1424 seg
= &mdata
->commands
[i
].command
.segment
;
1425 BFD_ASSERT (csect
+ seg
->nsects
<= mdata
->nsects
);
1427 for (j
= 0; j
< seg
->nsects
; j
++)
1428 mdata
->sections
[csect
++] = &seg
->sections
[j
];
1434 bfd_mach_o_scan_start_address (bfd
*abfd
)
1436 bfd_mach_o_data_struct
*mdata
= abfd
->tdata
.mach_o_data
;
1437 bfd_mach_o_thread_command
*cmd
= NULL
;
1440 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1442 if ((mdata
->commands
[i
].type
== BFD_MACH_O_LC_THREAD
) ||
1443 (mdata
->commands
[i
].type
== BFD_MACH_O_LC_UNIXTHREAD
))
1446 cmd
= &mdata
->commands
[i
].command
.thread
;
1455 for (i
= 0; i
< cmd
->nflavours
; i
++)
1457 if ((mdata
->header
.cputype
== BFD_MACH_O_CPU_TYPE_I386
)
1458 && (cmd
->flavours
[i
].flavour
1459 == (unsigned long) BFD_MACH_O_i386_THREAD_STATE
))
1461 unsigned char buf
[4];
1463 bfd_seek (abfd
, cmd
->flavours
[i
].offset
+ 40, SEEK_SET
);
1465 if (bfd_bread (buf
, 4, abfd
) != 4)
1468 abfd
->start_address
= bfd_h_get_32 (abfd
, buf
);
1470 else if ((mdata
->header
.cputype
== BFD_MACH_O_CPU_TYPE_POWERPC
)
1471 && (cmd
->flavours
[i
].flavour
== BFD_MACH_O_PPC_THREAD_STATE
))
1473 unsigned char buf
[4];
1475 bfd_seek (abfd
, cmd
->flavours
[i
].offset
+ 0, SEEK_SET
);
1477 if (bfd_bread (buf
, 4, abfd
) != 4)
1480 abfd
->start_address
= bfd_h_get_32 (abfd
, buf
);
1488 bfd_mach_o_scan (bfd
*abfd
,
1489 bfd_mach_o_header
*header
,
1490 bfd_mach_o_data_struct
*mdata
)
1493 enum bfd_architecture cputype
;
1494 unsigned long cpusubtype
;
1496 mdata
->header
= *header
;
1497 mdata
->symbols
= NULL
;
1499 abfd
->flags
= (abfd
->xvec
->object_flags
1500 | (abfd
->flags
& (BFD_IN_MEMORY
| BFD_IO_FUNCS
)));
1501 abfd
->tdata
.mach_o_data
= mdata
;
1503 bfd_mach_o_convert_architecture (header
->cputype
, header
->cpusubtype
,
1504 &cputype
, &cpusubtype
);
1505 if (cputype
== bfd_arch_unknown
)
1507 fprintf (stderr
, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1508 header
->cputype
, header
->cpusubtype
);
1512 bfd_set_arch_mach (abfd
, cputype
, cpusubtype
);
1514 if (header
->ncmds
!= 0)
1516 mdata
->commands
= bfd_alloc (abfd
, header
->ncmds
* sizeof (bfd_mach_o_load_command
));
1517 if (mdata
->commands
== NULL
)
1520 for (i
= 0; i
< header
->ncmds
; i
++)
1522 bfd_mach_o_load_command
*cur
= &mdata
->commands
[i
];
1528 bfd_mach_o_load_command
*prev
= &mdata
->commands
[i
- 1];
1529 cur
->offset
= prev
->offset
+ prev
->len
;
1532 if (bfd_mach_o_scan_read_command (abfd
, cur
) < 0)
1537 if (bfd_mach_o_scan_start_address (abfd
) < 0)
1540 bfd_mach_o_flatten_sections (abfd
);
1545 bfd_mach_o_mkobject (bfd
*abfd
)
1547 bfd_mach_o_data_struct
*mdata
= NULL
;
1549 mdata
= bfd_alloc (abfd
, sizeof (bfd_mach_o_data_struct
));
1552 abfd
->tdata
.mach_o_data
= mdata
;
1554 mdata
->header
.magic
= 0;
1555 mdata
->header
.cputype
= 0;
1556 mdata
->header
.cpusubtype
= 0;
1557 mdata
->header
.filetype
= 0;
1558 mdata
->header
.ncmds
= 0;
1559 mdata
->header
.sizeofcmds
= 0;
1560 mdata
->header
.flags
= 0;
1561 mdata
->header
.byteorder
= BFD_ENDIAN_UNKNOWN
;
1562 mdata
->commands
= NULL
;
1563 mdata
->nsymbols
= 0;
1564 mdata
->symbols
= NULL
;
1566 mdata
->sections
= NULL
;
1573 bfd_mach_o_object_p (bfd
*abfd
)
1575 struct bfd_preserve preserve
;
1576 bfd_mach_o_header header
;
1578 preserve
.marker
= NULL
;
1579 if (bfd_mach_o_read_header (abfd
, &header
) != 0)
1582 if (! (header
.byteorder
== BFD_ENDIAN_BIG
1583 || header
.byteorder
== BFD_ENDIAN_LITTLE
))
1585 fprintf (stderr
, "unknown header byte-order value 0x%lx\n",
1586 (long) header
.byteorder
);
1590 if (! ((header
.byteorder
== BFD_ENDIAN_BIG
1591 && abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
1592 && abfd
->xvec
->header_byteorder
== BFD_ENDIAN_BIG
)
1593 || (header
.byteorder
== BFD_ENDIAN_LITTLE
1594 && abfd
->xvec
->byteorder
== BFD_ENDIAN_LITTLE
1595 && abfd
->xvec
->header_byteorder
== BFD_ENDIAN_LITTLE
)))
1598 preserve
.marker
= bfd_zalloc (abfd
, sizeof (bfd_mach_o_data_struct
));
1599 if (preserve
.marker
== NULL
1600 || !bfd_preserve_save (abfd
, &preserve
))
1603 if (bfd_mach_o_scan (abfd
, &header
,
1604 (bfd_mach_o_data_struct
*) preserve
.marker
) != 0)
1607 bfd_preserve_finish (abfd
, &preserve
);
1611 bfd_set_error (bfd_error_wrong_format
);
1614 if (preserve
.marker
!= NULL
)
1615 bfd_preserve_restore (abfd
, &preserve
);
1620 bfd_mach_o_core_p (bfd
*abfd
)
1622 struct bfd_preserve preserve
;
1623 bfd_mach_o_header header
;
1625 preserve
.marker
= NULL
;
1626 if (bfd_mach_o_read_header (abfd
, &header
) != 0)
1629 if (! (header
.byteorder
== BFD_ENDIAN_BIG
1630 || header
.byteorder
== BFD_ENDIAN_LITTLE
))
1632 fprintf (stderr
, "unknown header byte-order value 0x%lx\n",
1633 (long) header
.byteorder
);
1637 if (! ((header
.byteorder
== BFD_ENDIAN_BIG
1638 && abfd
->xvec
->byteorder
== BFD_ENDIAN_BIG
1639 && abfd
->xvec
->header_byteorder
== BFD_ENDIAN_BIG
)
1640 || (header
.byteorder
== BFD_ENDIAN_LITTLE
1641 && abfd
->xvec
->byteorder
== BFD_ENDIAN_LITTLE
1642 && abfd
->xvec
->header_byteorder
== BFD_ENDIAN_LITTLE
)))
1645 if (header
.filetype
!= BFD_MACH_O_MH_CORE
)
1648 preserve
.marker
= bfd_zalloc (abfd
, sizeof (bfd_mach_o_data_struct
));
1649 if (preserve
.marker
== NULL
1650 || !bfd_preserve_save (abfd
, &preserve
))
1653 if (bfd_mach_o_scan (abfd
, &header
,
1654 (bfd_mach_o_data_struct
*) preserve
.marker
) != 0)
1657 bfd_preserve_finish (abfd
, &preserve
);
1661 bfd_set_error (bfd_error_wrong_format
);
1664 if (preserve
.marker
!= NULL
)
1665 bfd_preserve_restore (abfd
, &preserve
);
1669 typedef struct mach_o_fat_archentry
1671 unsigned long cputype
;
1672 unsigned long cpusubtype
;
1673 unsigned long offset
;
1675 unsigned long align
;
1677 } mach_o_fat_archentry
;
1679 typedef struct mach_o_fat_data_struct
1681 unsigned long magic
;
1682 unsigned long nfat_arch
;
1683 mach_o_fat_archentry
*archentries
;
1684 } mach_o_fat_data_struct
;
1687 bfd_mach_o_archive_p (bfd
*abfd
)
1689 mach_o_fat_data_struct
*adata
= NULL
;
1690 unsigned char buf
[20];
1693 bfd_seek (abfd
, 0, SEEK_SET
);
1694 if (bfd_bread ((PTR
) buf
, 8, abfd
) != 8)
1697 adata
= bfd_alloc (abfd
, sizeof (mach_o_fat_data_struct
));
1701 adata
->magic
= bfd_getb32 (buf
);
1702 adata
->nfat_arch
= bfd_getb32 (buf
+ 4);
1703 if (adata
->magic
!= 0xcafebabe)
1706 adata
->archentries
=
1707 bfd_alloc (abfd
, adata
->nfat_arch
* sizeof (mach_o_fat_archentry
));
1708 if (adata
->archentries
== NULL
)
1711 for (i
= 0; i
< adata
->nfat_arch
; i
++)
1713 bfd_seek (abfd
, 8 + 20 * i
, SEEK_SET
);
1715 if (bfd_bread ((PTR
) buf
, 20, abfd
) != 20)
1717 adata
->archentries
[i
].cputype
= bfd_getb32 (buf
);
1718 adata
->archentries
[i
].cpusubtype
= bfd_getb32 (buf
+ 4);
1719 adata
->archentries
[i
].offset
= bfd_getb32 (buf
+ 8);
1720 adata
->archentries
[i
].size
= bfd_getb32 (buf
+ 12);
1721 adata
->archentries
[i
].align
= bfd_getb32 (buf
+ 16);
1722 adata
->archentries
[i
].abfd
= NULL
;
1725 abfd
->tdata
.mach_o_fat_data
= adata
;
1730 bfd_release (abfd
, adata
);
1731 bfd_set_error (bfd_error_wrong_format
);
1736 bfd_mach_o_openr_next_archived_file (bfd
*archive
, bfd
*prev
)
1738 mach_o_fat_data_struct
*adata
;
1739 mach_o_fat_archentry
*entry
= NULL
;
1742 adata
= (mach_o_fat_data_struct
*) archive
->tdata
.mach_o_fat_data
;
1743 BFD_ASSERT (adata
!= NULL
);
1745 /* Find index of previous entry. */
1747 i
= 0; /* Start at first one. */
1750 for (i
= 0; i
< adata
->nfat_arch
; i
++)
1752 if (adata
->archentries
[i
].abfd
== prev
)
1756 if (i
== adata
->nfat_arch
)
1759 bfd_set_error (bfd_error_bad_value
);
1762 i
++; /* Get next entry. */
1765 if (i
>= adata
->nfat_arch
)
1767 bfd_set_error (bfd_error_no_more_archived_files
);
1771 entry
= &adata
->archentries
[i
];
1772 if (entry
->abfd
== NULL
)
1774 bfd
*nbfd
= _bfd_new_bfd_contained_in (archive
);
1780 nbfd
->origin
= entry
->offset
;
1781 s
= bfd_malloc (strlen (archive
->filename
) + 1);
1784 strcpy (s
, archive
->filename
);
1786 nbfd
->iostream
= NULL
;
1794 bfd_mach_o_lookup_section (bfd
*abfd
,
1796 bfd_mach_o_load_command
**mcommand
,
1797 bfd_mach_o_section
**msection
)
1799 struct mach_o_data_struct
*md
= abfd
->tdata
.mach_o_data
;
1800 unsigned int i
, j
, num
;
1802 bfd_mach_o_load_command
*ncmd
= NULL
;
1803 bfd_mach_o_section
*nsect
= NULL
;
1805 BFD_ASSERT (mcommand
!= NULL
);
1806 BFD_ASSERT (msection
!= NULL
);
1809 for (i
= 0; i
< md
->header
.ncmds
; i
++)
1811 struct bfd_mach_o_load_command
*cmd
= &md
->commands
[i
];
1812 struct bfd_mach_o_segment_command
*seg
= NULL
;
1814 if (cmd
->type
!= BFD_MACH_O_LC_SEGMENT
)
1816 seg
= &cmd
->command
.segment
;
1818 if (seg
->segment
== section
)
1825 for (j
= 0; j
< seg
->nsects
; j
++)
1827 struct bfd_mach_o_section
*sect
= &seg
->sections
[j
];
1829 if (sect
->bfdsection
== section
)
1844 bfd_mach_o_lookup_command (bfd
*abfd
,
1845 bfd_mach_o_load_command_type type
,
1846 bfd_mach_o_load_command
**mcommand
)
1848 struct mach_o_data_struct
*md
= NULL
;
1849 bfd_mach_o_load_command
*ncmd
= NULL
;
1850 unsigned int i
, num
;
1852 md
= abfd
->tdata
.mach_o_data
;
1854 BFD_ASSERT (md
!= NULL
);
1855 BFD_ASSERT (mcommand
!= NULL
);
1858 for (i
= 0; i
< md
->header
.ncmds
; i
++)
1860 struct bfd_mach_o_load_command
*cmd
= &md
->commands
[i
];
1862 if (cmd
->type
!= type
)
1875 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type
)
1879 case BFD_MACH_O_CPU_TYPE_MC680x0
:
1881 case BFD_MACH_O_CPU_TYPE_MC88000
:
1883 case BFD_MACH_O_CPU_TYPE_POWERPC
:
1885 case BFD_MACH_O_CPU_TYPE_I386
:
1887 case BFD_MACH_O_CPU_TYPE_SPARC
:
1889 case BFD_MACH_O_CPU_TYPE_I860
:
1891 case BFD_MACH_O_CPU_TYPE_HPPA
:
1892 return 0xc0000000 - 0x04000000;
1899 bfd_mach_o_core_fetch_environment (bfd
*abfd
,
1900 unsigned char **rbuf
,
1903 bfd_mach_o_data_struct
*mdata
= abfd
->tdata
.mach_o_data
;
1904 unsigned long stackaddr
= bfd_mach_o_stack_addr (mdata
->header
.cputype
);
1907 for (i
= 0; i
< mdata
->header
.ncmds
; i
++)
1909 bfd_mach_o_load_command
*cur
= &mdata
->commands
[i
];
1910 bfd_mach_o_segment_command
*seg
= NULL
;
1912 if (cur
->type
!= BFD_MACH_O_LC_SEGMENT
)
1915 seg
= &cur
->command
.segment
;
1917 if ((seg
->vmaddr
+ seg
->vmsize
) == stackaddr
)
1919 unsigned long start
= seg
->fileoff
;
1920 unsigned long end
= seg
->fileoff
+ seg
->filesize
;
1921 unsigned char *buf
= bfd_malloc (1024);
1922 unsigned long size
= 1024;
1926 bfd_size_type nread
= 0;
1927 unsigned long offset
;
1928 int found_nonnull
= 0;
1930 if (size
> (end
- start
))
1931 size
= (end
- start
);
1933 buf
= bfd_realloc (buf
, size
);
1935 bfd_seek (abfd
, end
- size
, SEEK_SET
);
1936 nread
= bfd_bread (buf
, size
, abfd
);
1941 for (offset
= 4; offset
<= size
; offset
+= 4)
1945 val
= *((unsigned long *) (buf
+ size
- offset
));
1946 if (! found_nonnull
)
1951 else if (val
== 0x0)
1953 unsigned long bottom
;
1956 bottom
= seg
->fileoff
+ seg
->filesize
- offset
;
1957 top
= seg
->fileoff
+ seg
->filesize
- 4;
1958 *rbuf
= bfd_malloc (top
- bottom
);
1959 *rlen
= top
- bottom
;
1961 memcpy (*rbuf
, buf
+ size
- *rlen
, *rlen
);
1966 if (size
== (end
- start
))
1978 bfd_mach_o_core_file_failing_command (bfd
*abfd
)
1980 unsigned char *buf
= NULL
;
1981 unsigned int len
= 0;
1984 ret
= bfd_mach_o_core_fetch_environment (abfd
, &buf
, &len
);
1988 return (char *) buf
;
1992 bfd_mach_o_core_file_failing_signal (bfd
*abfd ATTRIBUTE_UNUSED
)
1997 #define TARGET_NAME mach_o_be_vec
1998 #define TARGET_STRING "mach-o-be"
1999 #define TARGET_BIG_ENDIAN 1
2000 #define TARGET_ARCHIVE 0
2002 #include "mach-o-target.c"
2005 #undef TARGET_STRING
2006 #undef TARGET_BIG_ENDIAN
2007 #undef TARGET_ARCHIVE
2009 #define TARGET_NAME mach_o_le_vec
2010 #define TARGET_STRING "mach-o-le"
2011 #define TARGET_BIG_ENDIAN 0
2012 #define TARGET_ARCHIVE 0
2014 #include "mach-o-target.c"
2017 #undef TARGET_STRING
2018 #undef TARGET_BIG_ENDIAN
2019 #undef TARGET_ARCHIVE
2021 #define TARGET_NAME mach_o_fat_vec
2022 #define TARGET_STRING "mach-o-fat"
2023 #define TARGET_BIG_ENDIAN 1
2024 #define TARGET_ARCHIVE 1
2026 #include "mach-o-target.c"
2029 #undef TARGET_STRING
2030 #undef TARGET_BIG_ENDIAN
2031 #undef TARGET_ARCHIVE