[Patch] Mach-O: add write capability
Tristan Gingold
gingold@adacore.com
Tue Jun 2 14:41:00 GMT 2009
More information about the Binutils mailing list
Tue Jun 2 14:41:00 GMT 2009
- Previous message (by thread): MIPS -gc-sections broken?
- Next message (by thread): [Patch] Mach-O: add write capability
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi, the Mach-O bfd back-end was mostly a read-only back-end - which is still very useful but somewhat incomplete. This patch starts to add write capability. Far from being complete but I was at least able to objcopy from binary to Mach-O or from Mach-O object file to Mach-O object file. Also until now there was only 2 generic targets. I added an i386 targets, others (x86-64, ppc and ppc64) will come later. I have also replaced some hard-coded values with constants. I plan also to port gas to Mach-O as this will be useful to run the testsuite. I did some manual checks to test this new feature. Tristan. bfd/ 2009-06-02 Tristan Gingold <gingold@adacore.com> * mach-o.h: Update copyright year. (bfd_mach_o_mach_header_magic): New enum. (bfd_mach_o_cpu_subtype): Now an enum. (BFD_MACH_O_HEADER_SIZE, BFD_MACH_O_HEADER_64_SIZE): New macros. (BFD_MACH_O_SECTION_SIZE, BFD_MACH_O_SECTION_64_SIZE): Ditto. (BFD_MACH_O_LC_SEGMENT_SIZE, BFD_MACH_O_LC_SEGMENT_64_SIZE): Ditto. (bfd_mach_o_load_command): Field type_required is now a boolean. Reindent prototypes. (bfd_mach_o_object_p, bfd_mach_o_core_p): Remove. (bfd_mach_o_bfd_copy_private_symbol_data): Add a prototype. (bfd_mach_o_bfd_copy_private_section_data): Ditto. (bfd_mach_o_bfd_copy_private_bfd_data): Ditto. (bfd_mach_o_get_symtab_upper_bound): Ditto. (bfd_mach_o_canonicalize_symtab): Ditto. (bfd_mach_o_get_symbol_info): Ditto. (bfd_mach_o_print_symbol): Ditto. (bfd_mach_o_bfd_print_private_bfd_data): Ditto. (bfd_mach_o_make_empty_symbol): Ditto. (bfd_mach_o_write_contents): Ditto. * mach-o.c (bfd_mach_o_object_p, bfd_mach_o_core_p, bfd_mach_o_mkobject): Defines. (bfd_mach_o_valid): Returns FALSE/TRUE instead of 0/1. Do not check with target vector but with flavour. (struct mach_o_section_name_xlat): New declaration. (dwarf_section_names_xlat): Ditto. (text_section_names_xlat): Ditto. (data_section_names_xlat): Ditto. (struct mach_o_segment_name_xlat): Ditto. (segsec_names_xlat): Ditto. (bfd_mach_o_convert_section_name_to_bfd): New function. (bfd_mach_o_convert_section_name_to_mach_o): Ditto. (bfd_mach_o_bfd_copy_private_symbol_data): Make it public. (bfd_mach_o_bfd_copy_private_section_data): Ditto. (bfd_mach_o_bfd_copy_private_bfd_data): Ditto. Accept any input and output flavour. Do not share private data anymore. (bfd_mach_o_count_symbols): Add a comment. (bfd_mach_o_get_symtab_upper_bound): Make it public. (bfd_mach_o_canonicalize_symtab): Ditto. (bfd_mach_o_get_symbol_info): Ditto. (bfd_mach_o_print_symbol): Ditto. (bfd_mach_o_write_header): Now returns a boolean instead of an int. Use constants instead of hard-coded values. (bfd_mach_o_scan_write_section_32): Use constants instead of hard-coded values. (bfd_mach_o_scan_write_section_64): Ditto. (bfd_mach_o_scan_write_segment): Ditto. Do not copy sections anymore. (bfd_mach_o_write_contents): Make it public. Remove dead code. Rewrite typeflag assignment. (bfd_mach_o_build_commands): New function. (bfd_mach_o_set_section_contents): Ditto. (bfd_mach_o_make_empty_symbol): Make it public. (bfd_mach_o_read_header): Make it static. Convert to bfd_boolean. Use constants instead of hard-coded values. (bfd_mach_o_make_bfd_section): Call bfd_mach_o_convert_section_name_to_bfd to create name. (bfd_mach_o_scan_read_section_32): Use constants instead of hard-coded values. (bfd_mach_o_scan_read_section_64): Ditto. (bfd_mach_o_scan_read_segment): Do not create a bfd section for a segment anymore. Use constants instead of hard-coded values. (bfd_mach_o_scan_read_command): Fix style. (bfd_mach_o_scan): Use constants instead of hard-coded values. Get rid of BFD_IO_FUNCS. (bfd_mach_o_mkobject_init): Renamed from bfd_mach_o_mkobject. (bfd_mach_o_header_p): Created from bfd_mach_o_object_p. (bfd_mach_o_gen_object_p): New function, replaces bfd_mach_o_object_p. (bfd_mach_o_object_p): Removed. (bfd_mach_o_gen_core_p): New function, replaces ... (bfd_mach_o_core_p): ... deleted. (bfd_mach_o_bfd_print_private_bfd_data): Make it public. * mach-o-i386.c: New file. * config.bfd: Use mach_o_i386_vec as targ_defvec for ix86-darwin. * configure.in (TDEFINES): Add mach_o_i386_vec. * configure: Regenerates. * targets.c: Add mach_o_i386_vec. * mach-o.c: Update copyright years. (BFD_IO_FUNCS): Remove (was not used). (bfd_mach_o_mkarchive, bfd_mach_o_read_ar_hdr, bfd_mach_o_slurp_armap bfd_mach_o_slurp_extended_name_table, bfd_mach_o_construct_extended_name_table, bfd_mach_o_truncate_arname, bfd_mach_o_write_armap, bfd_mach_o_get_elt_at_index, bfd_mach_o_generic_stat_arch_elt, bfd_mach_o_update_armap_timestamp, bfd_mach_o_close_and_cleanup, bfd_mach_o_bfd_free_cached_info, bfd_mach_o_new_section_hook, bfd_mach_o_get_section_contents_in_window, bfd_mach_o_bfd_is_local_label_name, bfd_mach_o_bfd_is_target_special_symbol, bfd_mach_o_bfd_is_local_label_name, bfd_mach_o_get_lineno, bfd_mach_o_find_nearest_line, bfd_mach_o_find_inliner_info, bfd_mach_o_bfd_make_debug_symbol, bfd_mach_o_read_minisymbols, bfd_mach_o_minisymbol_to_symbol, bfd_mach_o_bfd_get_relocated_section_contents, bfd_mach_o_bfd_relax_section, bfd_mach_o_bfd_link_hash_table_create, bfd_mach_o_bfd_link_hash_table_free, bfd_mach_o_bfd_link_add_symbols, bfd_mach_o_bfd_link_just_syms, bfd_mach_o_bfd_final_link, bfd_mach_o_bfd_link_split_section, bfd_mach_o_set_arch_mach, bfd_mach_o_bfd_merge_private_bfd_data, bfd_mach_o_bfd_set_private_flags, bfd_mach_o_get_section_contents, bfd_mach_o_bfd_gc_sections, bfd_mach_o_bfd_merge_sections, bfd_mach_o_bfd_is_group_section, bfd_mach_o_bfd_discard_group, bfd_mach_o_section_already_linked, bfd_mach_o_bfd_define_common_symbol, bfd_mach_o_bfd_copy_private_header_data, bfd_mach_o_core_file_matches_executable_p): Move these defines ... * mach-o-target.c: ... here. Update copyright years. Index: config.bfd =================================================================== RCS file: /cvs/src/src/bfd/config.bfd,v retrieving revision 1.249 diff -c -p -r1.249 config.bfd *** config.bfd 26 May 2009 14:12:02 -0000 1.249 --- config.bfd 2 Jun 2009 14:26:10 -0000 *************** case "${targ}" in *** 541,548 **** targ_selvecs="i386coff_vec i386aout_vec" ;; i[3-7]86-*-darwin* | i[3-7]86-*-macos10* | i[3-7]86-*-rhapsody*) ! targ_defvec=mach_o_le_vec ! targ_selvecs="mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec" targ_archs="bfd_i386_arch bfd_powerpc_arch bfd_rs6000_arch" ;; i[3-7]86-sequent-bsd*) --- 541,548 ---- targ_selvecs="i386coff_vec i386aout_vec" ;; i[3-7]86-*-darwin* | i[3-7]86-*-macos10* | i[3-7]86-*-rhapsody*) ! targ_defvec=mach_o_i386_vec ! targ_selvecs="mach_o_i386_vec mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec" targ_archs="bfd_i386_arch bfd_powerpc_arch bfd_rs6000_arch" ;; i[3-7]86-sequent-bsd*) Index: configure =================================================================== RCS file: /cvs/src/src/bfd/configure,v retrieving revision 1.303 diff -c -p -r1.303 configure *** configure 27 May 2009 16:29:55 -0000 1.303 --- configure 2 Jun 2009 14:26:14 -0000 *************** do *** 21171,21176 **** --- 21171,21177 ---- mach_o_be_vec) tb="$tb mach-o.lo" ;; mach_o_le_vec) tb="$tb mach-o.lo" ;; mach_o_fat_vec) tb="$tb mach-o.lo" ;; + mach_o_i386_vec) tb="$tb mach-o-i386.lo" ;; mcore_pe_big_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;; mcore_pe_little_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;; mcore_pei_big_vec) tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;; Index: configure.in =================================================================== RCS file: /cvs/src/src/bfd/configure.in,v retrieving revision 1.262 diff -c -p -r1.262 configure.in *** configure.in 27 May 2009 16:29:55 -0000 1.262 --- configure.in 2 Jun 2009 14:26:14 -0000 *************** do *** 868,873 **** --- 868,874 ---- mach_o_be_vec) tb="$tb mach-o.lo" ;; mach_o_le_vec) tb="$tb mach-o.lo" ;; mach_o_fat_vec) tb="$tb mach-o.lo" ;; + mach_o_i386_vec) tb="$tb mach-o-i386.lo" ;; mcore_pe_big_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;; mcore_pe_little_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;; mcore_pei_big_vec) tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;; Index: mach-o-target.c =================================================================== RCS file: /cvs/src/src/bfd/mach-o-target.c,v retrieving revision 1.6 diff -c -p -r1.6 mach-o-target.c *** mach-o-target.c 6 Nov 2008 13:03:43 -0000 1.6 --- mach-o-target.c 2 Jun 2009 14:26:14 -0000 *************** *** 1,5 **** /* Mach-O support for BFD. ! Copyright 1999, 2000, 2001, 2002, 2007 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. --- 1,5 ---- /* Mach-O support for BFD. ! Copyright 1999, 2000, 2001, 2002, 2007, 2009 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. *************** *** 19,24 **** --- 19,76 ---- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + /* Define generic entry points here so that we don't need to duplicate the + defines in every target. But define once as this file may be included + several times. */ + #ifndef MACH_O_TARGET_COMMON_DEFINED + #define MACH_O_TARGET_COMMON_DEFINED + + #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive + #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr + #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap + #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table + #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table + #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname + #define bfd_mach_o_write_armap _bfd_noarchive_write_armap + #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index + #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt + #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp + #define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup + #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info + #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook + #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window + #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name + #define bfd_mach_o_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) + #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name + #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno + #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line + #define bfd_mach_o_find_inliner_info _bfd_nosymbols_find_inliner_info + #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol + #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols + #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol + #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents + #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section + #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create + #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free + #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols + #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms + #define bfd_mach_o_bfd_final_link _bfd_generic_final_link + #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section + #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach + #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data + #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags + #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents + #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections + #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections + #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section + #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group + #define bfd_mach_o_section_already_linked _bfd_generic_section_already_linked + #define bfd_mach_o_bfd_define_common_symbol bfd_generic_define_common_symbol + #define bfd_mach_o_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data + #define bfd_mach_o_core_file_matches_executable_p generic_core_file_matches_executable_p + + #endif /* MACH_O_TARGET_COMMON_DEFINED */ + #ifndef TARGET_NAME #error TARGET_NAME must be defined #endif /* TARGET_NAME */ Index: mach-o.c =================================================================== RCS file: /cvs/src/src/bfd/mach-o.c,v retrieving revision 1.33 diff -c -p -r1.33 mach-o.c *** mach-o.c 16 Apr 2009 23:06:58 -0000 1.33 --- mach-o.c 2 Jun 2009 14:26:15 -0000 *************** *** 1,5 **** /* Mach-O support for BFD. ! Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. --- 1,5 ---- /* Mach-O support for BFD. ! Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. *************** *** 27,80 **** #include "aout/stab_gnu.h" #include <ctype.h> ! #ifndef BFD_IO_FUNCS ! #define BFD_IO_FUNCS 0 ! #endif ! ! #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive ! #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr ! #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap ! #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table ! #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table ! #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname ! #define bfd_mach_o_write_armap _bfd_noarchive_write_armap ! #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index ! #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt ! #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp ! #define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup ! #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info ! #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook ! #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window ! #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name ! #define bfd_mach_o_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) ! #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name ! #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno ! #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line ! #define bfd_mach_o_find_inliner_info _bfd_nosymbols_find_inliner_info ! #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol ! #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols ! #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol ! #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents ! #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section ! #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create ! #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free ! #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols ! #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms ! #define bfd_mach_o_bfd_final_link _bfd_generic_final_link ! #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section ! #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach ! #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data ! #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags ! #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents ! #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents ! #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections ! #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections ! #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section ! #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group ! #define bfd_mach_o_section_already_linked _bfd_generic_section_already_linked ! #define bfd_mach_o_bfd_define_common_symbol bfd_generic_define_common_symbol ! #define bfd_mach_o_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data ! #define bfd_mach_o_core_file_matches_executable_p generic_core_file_matches_executable_p static unsigned int bfd_mach_o_version (bfd *abfd) --- 27,35 ---- #include "aout/stab_gnu.h" #include <ctype.h> ! #define bfd_mach_o_object_p bfd_mach_o_gen_object_p ! #define bfd_mach_o_core_p bfd_mach_o_gen_core_p ! #define bfd_mach_o_mkobject bfd_false static unsigned int bfd_mach_o_version (bfd *abfd) *************** bfd_boolean *** 91,112 **** bfd_mach_o_valid (bfd *abfd) { if (abfd == NULL || abfd->xvec == NULL) ! return 0; ! if (! ((abfd->xvec == &mach_o_be_vec) ! || (abfd->xvec == &mach_o_le_vec) ! || (abfd->xvec == &mach_o_fat_vec))) ! return 0; if (abfd->tdata.mach_o_data == NULL) ! return 0; ! return 1; } /* Copy any private info we understand from the input symbol to the output symbol. */ ! static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED, asymbol *isymbol ATTRIBUTE_UNUSED, bfd *obfd ATTRIBUTE_UNUSED, --- 46,225 ---- bfd_mach_o_valid (bfd *abfd) { if (abfd == NULL || abfd->xvec == NULL) ! return FALSE; ! if (abfd->xvec->flavour != bfd_target_mach_o_flavour) ! return FALSE; if (abfd->tdata.mach_o_data == NULL) ! return FALSE; ! return TRUE; ! } ! ! /* Tables to translate well known Mach-O segment/section names to bfd ! names. Use of canonical names (such as .text or .debug_frame) is required ! by gdb. */ ! ! struct mach_o_section_name_xlat ! { ! const char *bfd_name; ! const char *mach_o_name; ! }; ! ! static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] = ! { ! { ".debug_frame", "__debug_frame" }, ! { ".debug_info", "__debug_info" }, ! { ".debug_abbrev", "__debug_abbrev" }, ! { ".debug_aranges", "__debug_aranges" }, ! { ".debug_macinfo", "__debug_macinfo" }, ! { ".debug_line", "__debug_line" }, ! { ".debug_loc", "__debug_loc" }, ! { ".debug_pubnames", "__debug_pubnames" }, ! { ".debug_pubtypes", "__debug_pubtypes" }, ! { ".debug_str", "__debug_str" }, ! { ".debug_ranges", "__debug_ranges" }, ! { NULL, NULL} ! }; ! ! static const struct mach_o_section_name_xlat text_section_names_xlat[] = ! { ! { ".text", "__text" }, ! { ".cstring", "__cstring" }, ! { ".eh_frame", "__eh_frame" }, ! { NULL, NULL} ! }; ! ! static const struct mach_o_section_name_xlat data_section_names_xlat[] = ! { ! { ".data", "__data" }, ! { ".bss", "__bss" }, ! { NULL, NULL} ! }; ! ! struct mach_o_segment_name_xlat ! { ! const char *segname; ! const struct mach_o_section_name_xlat *sections; ! }; ! ! static const struct mach_o_segment_name_xlat segsec_names_xlat[] = ! { ! { "__DWARF", dwarf_section_names_xlat }, ! { "__TEXT", text_section_names_xlat }, ! { "__DATA", data_section_names_xlat }, ! { NULL, NULL } ! }; ! ! ! /* Mach-O to bfd names. */ ! ! static char * ! bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section) ! { ! const struct mach_o_segment_name_xlat *seg; ! char *res; ! unsigned int len; ! ! for (seg = segsec_names_xlat; seg->segname; seg++) ! { ! if (strcmp (seg->segname, section->segname) == 0) ! { ! const struct mach_o_section_name_xlat *sec; ! ! for (sec = seg->sections; sec->mach_o_name; sec++) ! { ! if (strcmp (sec->mach_o_name, section->sectname) == 0) ! { ! len = strlen (sec->bfd_name); ! res = bfd_alloc (abfd, len + 1); ! ! if (res == NULL) ! return NULL; ! strcpy (res, sec->bfd_name); ! return res; ! } ! } ! } ! } ! ! len = sizeof ("LC_SEGMENT") - 1 + 1 ! + strlen (section->segname) + 1 ! + strlen (section->sectname) + 1; ! ! res = bfd_alloc (abfd, len); ! if (res == NULL) ! return NULL; ! snprintf (res, len, "LC_SEGMENT.%s.%s", section->segname, section- >sectname); ! return res; ! } ! ! /* Convert a bfd sectio name to a Mach-O segment + section name. */ ! ! static void ! bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED, ! asection *sect, ! bfd_mach_o_section *section) ! { ! const struct mach_o_segment_name_xlat *seg; ! const char *name = bfd_get_section_name (abfd, sect); ! const char *dot; ! unsigned int len; ! unsigned int seglen; ! unsigned int seclen; ! ! /* List of well known names. */ ! for (seg = segsec_names_xlat; seg->segname; seg++) ! { ! const struct mach_o_section_name_xlat *sec; ! ! for (sec = seg->sections; sec->mach_o_name; sec++) ! { ! if (strcmp (sec->bfd_name, name) == 0) ! { ! strcpy (section->segname, seg->segname); ! strcpy (section->sectname, sec->mach_o_name); ! return; ! } ! } ! } ! ! /* Strip LC_SEGMENT. prefix. */ ! if (strncmp (name, "LC_SEGMENT.", 11) == 0) ! name += 11; ! ! /* Find a dot. */ ! dot = strchr (name, '.'); ! len = strlen (name); ! ! /* Try to split name into segment and section names. */ ! if (dot && dot != name) ! { ! seglen = dot - name; ! seclen = len - (dot + 1 - name); ! ! if (seglen < 16 && seclen < 16) ! { ! memcpy (section->segname, name, seglen); ! section->segname[seglen] = 0; ! memcpy (section->sectname, dot + 1, seclen); ! section->sectname[seclen] = 0; ! return; ! } ! } ! ! if (len > 16) ! len = 16; ! memcpy (section->segname, name, len); ! section->segname[len] = 0; ! memcpy (section->sectname, name, len); ! section->sectname[len] = 0; } /* Copy any private info we understand from the input symbol to the output symbol. */ ! bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED, asymbol *isymbol ATTRIBUTE_UNUSED, bfd *obfd ATTRIBUTE_UNUSED, *************** bfd_mach_o_bfd_copy_private_symbol_data *** 118,124 **** /* Copy any private info we understand from the input section to the output section. */ ! static bfd_boolean bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, asection *isection ATTRIBUTE_UNUSED, bfd *obfd ATTRIBUTE_UNUSED, --- 231,237 ---- /* Copy any private info we understand from the input section to the output section. */ ! bfd_boolean bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, asection *isection ATTRIBUTE_UNUSED, bfd *obfd ATTRIBUTE_UNUSED, *************** bfd_mach_o_bfd_copy_private_section_data *** 130,146 **** /* Copy any private info we understand from the input bfd to the output bfd. */ ! static bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { BFD_ASSERT (bfd_mach_o_valid (ibfd)); BFD_ASSERT (bfd_mach_o_valid (obfd)); ! obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data; ! obfd->tdata.mach_o_data->ibfd = ibfd; return TRUE; } static long bfd_mach_o_count_symbols (bfd *abfd) { --- 243,265 ---- /* Copy any private info we understand from the input bfd to the output bfd. */ ! bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { + if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour + || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour) + return TRUE; + BFD_ASSERT (bfd_mach_o_valid (ibfd)); BFD_ASSERT (bfd_mach_o_valid (obfd)); ! /* FIXME: copy commands. */ ! return TRUE; } + /* Count the total number of symbols. Traverse all sections. */ + static long bfd_mach_o_count_symbols (bfd *abfd) { *************** bfd_mach_o_count_symbols (bfd *abfd) *** 161,167 **** return nsyms; } ! static long bfd_mach_o_get_symtab_upper_bound (bfd *abfd) { long nsyms = bfd_mach_o_count_symbols (abfd); --- 280,286 ---- return nsyms; } ! long bfd_mach_o_get_symtab_upper_bound (bfd *abfd) { long nsyms = bfd_mach_o_count_symbols (abfd); *************** bfd_mach_o_get_symtab_upper_bound (bfd * *** 172,178 **** return ((nsyms + 1) * sizeof (asymbol *)); } ! static long bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation) { bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data; --- 291,297 ---- return ((nsyms + 1) * sizeof (asymbol *)); } ! long bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation) { bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data; *************** bfd_mach_o_canonicalize_symtab (bfd *abf *** 210,216 **** return nsyms; } ! static void bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, asymbol *symbol, symbol_info *ret) --- 329,335 ---- return nsyms; } ! void bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, asymbol *symbol, symbol_info *ret) *************** bfd_mach_o_get_symbol_info (bfd *abfd AT *** 218,224 **** bfd_symbol_info (symbol, ret); } ! static void bfd_mach_o_print_symbol (bfd *abfd, PTR afile, asymbol *symbol, --- 337,343 ---- bfd_symbol_info (symbol, ret); } ! void bfd_mach_o_print_symbol (bfd *abfd, PTR afile, asymbol *symbol, *************** bfd_mach_o_convert_architecture (bfd_mac *** 319,331 **** } } ! static int bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header) { unsigned char buf[32]; unsigned int size; ! size = (header->version == 2) ? 32 : 28; bfd_h_put_32 (abfd, header->magic, buf + 0); bfd_h_put_32 (abfd, header->cputype, buf + 4); --- 438,451 ---- } } ! static bfd_boolean bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header) { unsigned char buf[32]; unsigned int size; ! size = (header->version == 2) ? ! BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE; bfd_h_put_32 (abfd, header->magic, buf + 0); bfd_h_put_32 (abfd, header->cputype, buf + 4); *************** bfd_mach_o_write_header (bfd *abfd, bfd_ *** 340,348 **** bfd_seek (abfd, 0, SEEK_SET); if (bfd_bwrite ((PTR) buf, size, abfd) != size) ! return -1; ! return 0; } static int --- 460,468 ---- bfd_seek (abfd, 0, SEEK_SET); if (bfd_bwrite ((PTR) buf, size, abfd) != size) ! return FALSE; ! return TRUE; } static int *************** bfd_mach_o_scan_write_section_32 (bfd *a *** 382,388 **** bfd_mach_o_section *section, bfd_vma offset) { ! unsigned char buf[68]; memcpy (buf, section->sectname, 16); memcpy (buf + 16, section->segname, 16); --- 502,508 ---- bfd_mach_o_section *section, bfd_vma offset) { ! unsigned char buf[BFD_MACH_O_SECTION_SIZE]; memcpy (buf, section->sectname, 16); memcpy (buf + 16, section->segname, 16); *************** bfd_mach_o_scan_write_section_32 (bfd *a *** 397,403 **** bfd_h_put_32 (abfd, section->reserved2, buf + 64); bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bwrite ((PTR) buf, 68, abfd) != 68) return -1; return 0; --- 517,524 ---- bfd_h_put_32 (abfd, section->reserved2, buf + 64); bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd) ! != BFD_MACH_O_SECTION_SIZE) return -1; return 0; *************** bfd_mach_o_scan_write_section_64 (bfd *a *** 408,414 **** bfd_mach_o_section *section, bfd_vma offset) { ! unsigned char buf[80]; memcpy (buf, section->sectname, 16); memcpy (buf + 16, section->segname, 16); --- 529,535 ---- bfd_mach_o_section *section, bfd_vma offset) { ! unsigned char buf[BFD_MACH_O_SECTION_64_SIZE]; memcpy (buf, section->sectname, 16); memcpy (buf + 16, section->segname, 16); *************** bfd_mach_o_scan_write_section_64 (bfd *a *** 424,430 **** bfd_h_put_32 (abfd, section->reserved3, buf + 76); bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bwrite ((PTR) buf, 80, abfd) != 80) return -1; return 0; --- 545,552 ---- bfd_h_put_32 (abfd, section->reserved3, buf + 76); bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd) ! != BFD_MACH_O_SECTION_64_SIZE) return -1; return 0; *************** bfd_mach_o_scan_write_segment (bfd *abfd *** 490,527 **** return -1; } - { - char buf[1024]; - bfd_vma nbytes = seg->filesize; - bfd_vma curoff = seg->fileoff; - - while (nbytes > 0) - { - bfd_vma thiswrite = nbytes; - - if (thiswrite > 1024) - thiswrite = 1024; - - bfd_seek (abfd, curoff, SEEK_SET); - if (bfd_bread ((PTR) buf, thiswrite, abfd) != thiswrite) - return -1; - - bfd_seek (abfd, curoff, SEEK_SET); - if (bfd_bwrite ((PTR) buf, thiswrite, abfd) != thiswrite) - return -1; - - nbytes -= thiswrite; - curoff += thiswrite; - } - } - for (i = 0; i < seg->nsects; i++) { bfd_vma segoff; if (wide) ! segoff = command->offset + 64 + 8 + (i * 80); else ! segoff = command->offset + 48 + 8 + (i * 68); if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff, wide) != 0) --- 612,626 ---- return -1; } for (i = 0; i < seg->nsects; i++) { bfd_vma segoff; if (wide) ! segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE ! + (i * BFD_MACH_O_SECTION_64_SIZE); else ! segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE ! + (i * BFD_MACH_O_SECTION_SIZE); if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff, wide) != 0) *************** bfd_mach_o_scan_write_symtab (bfd *abfd, *** 606,627 **** return 0; } ! static bfd_boolean bfd_mach_o_write_contents (bfd *abfd) { unsigned int i; - asection *s; - bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data; - /* Write data sections first in case they overlap header data to be - written later. */ - - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - ; - /* Now write header information. */ ! if (bfd_mach_o_write_header (abfd, &mdata->header) != 0) return FALSE; for (i = 0; i < mdata->header.ncmds; i++) --- 705,718 ---- return 0; } ! bfd_boolean bfd_mach_o_write_contents (bfd *abfd) { unsigned int i; bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data; /* Now write header information. */ ! if (!bfd_mach_o_write_header (abfd, &mdata->header)) return FALSE; for (i = 0; i < mdata->header.ncmds; i++) *************** bfd_mach_o_write_contents (bfd *abfd) *** 630,636 **** bfd_mach_o_load_command *cur = &mdata->commands[i]; unsigned long typeflag; ! typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type; bfd_h_put_32 (abfd, typeflag, buf); bfd_h_put_32 (abfd, cur->len, buf + 4); --- 721,727 ---- bfd_mach_o_load_command *cur = &mdata->commands[i]; unsigned long typeflag; ! typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0); bfd_h_put_32 (abfd, typeflag, buf); bfd_h_put_32 (abfd, cur->len, buf + 4); *************** bfd_mach_o_write_contents (bfd *abfd) *** 686,692 **** return TRUE; } ! static int bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED) { --- 777,897 ---- return TRUE; } ! /* Build Mach-O load commands from the sections. */ ! ! bfd_boolean ! bfd_mach_o_build_commands (bfd *abfd) ! { ! bfd_mach_o_data_struct *mdata = bfd_get_mach_o_data (abfd); ! unsigned int wide = (mdata->header.version == 2); ! bfd_mach_o_segment_command *seg; ! bfd_mach_o_section *sections; ! asection *sec; ! file_ptr filepos; ! ! /* Return now if commands are already built. */ ! if (mdata->header.ncmds) ! return FALSE; ! ! /* Very simple version: 1 command (segment) containing all sections. */ ! mdata->header.ncmds = 1; ! mdata->commands = bfd_alloc (abfd, mdata->header.ncmds ! * sizeof (bfd_mach_o_load_command)); ! if (mdata->commands == NULL) ! return FALSE; ! seg = &mdata->commands[0].command.segment; ! seg->nsects = bfd_count_sections (abfd); ! sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)); ! if (sections == NULL) ! return FALSE; ! seg->sections = sections; ! ! /* Set segment command. */ ! if (wide) ! { ! mdata->commands[0].type = BFD_MACH_O_LC_SEGMENT_64; ! mdata->commands[0].offset = BFD_MACH_O_HEADER_64_SIZE; ! mdata->commands[0].len = BFD_MACH_O_LC_SEGMENT_64_SIZE ! + BFD_MACH_O_SECTION_64_SIZE * seg->nsects; ! } ! else ! { ! mdata->commands[0].type = BFD_MACH_O_LC_SEGMENT; ! mdata->commands[0].offset = BFD_MACH_O_HEADER_SIZE; ! mdata->commands[0].len = BFD_MACH_O_LC_SEGMENT_SIZE ! + BFD_MACH_O_SECTION_SIZE * seg->nsects; ! } ! mdata->commands[0].type_required = FALSE; ! mdata->header.sizeofcmds = mdata->commands[0].len; ! ! filepos = mdata->commands[0].offset + mdata->commands[0].len; ! ! memset (seg->segname, 0, sizeof (seg->segname)); ! seg->vmaddr = 0; ! seg->fileoff = filepos; ! seg->filesize = 0; ! seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE ! | BFD_MACH_O_PROT_EXECUTE; ! seg->initprot = seg->maxprot; ! seg->flags = 0; ! ! /* Create Mach-O sections. */ ! for (sec = abfd->sections; sec; sec = sec->next) ! { ! sections->bfdsection = sec; ! bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections); ! sections->addr = bfd_get_section_vma (abfd, sec); ! sections->size = bfd_get_section_size (sec); ! sections->align = bfd_get_section_alignment (abfd, sec); ! ! filepos = (filepos + ((file_ptr) 1 << sections->align) - 1) ! & ((file_ptr) -1 << sections->align); ! sections->offset = filepos; ! sections->reloff = 0; ! sections->nreloc = 0; ! sections->reserved1 = 0; ! sections->reserved2 = 0; ! sections->reserved3 = 0; ! ! sec->filepos = filepos; ! ! filepos += sections->size; ! sections++; ! } ! seg->filesize = filepos - seg->fileoff; ! seg->vmsize = seg->filesize; ! ! return TRUE; ! } ! ! /* Set the contents of a section. */ ! ! bfd_boolean ! bfd_mach_o_set_section_contents (bfd *abfd, ! asection *section, ! const void * location, ! file_ptr offset, ! bfd_size_type count) ! { ! file_ptr pos; ! ! /* This must be done first, because bfd_set_section_contents is ! going to set output_has_begun to TRUE. */ ! if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd)) ! return FALSE; ! ! if (count == 0) ! return TRUE; ! ! pos = section->filepos + offset; ! if (bfd_seek (abfd, pos, SEEK_SET) != 0 ! || bfd_bwrite (location, count, abfd) != count) ! return FALSE; ! ! return TRUE; ! } ! ! int bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED) { *************** bfd_mach_o_sizeof_headers (bfd *a ATTRIB *** 696,702 **** /* Make an empty symbol. This is required only because bfd_make_section_anyway wants to create a symbol for the section. */ ! static asymbol * bfd_mach_o_make_empty_symbol (bfd *abfd) { asymbol *new; --- 901,907 ---- /* Make an empty symbol. This is required only because bfd_make_section_anyway wants to create a symbol for the section. */ ! asymbol * bfd_mach_o_make_empty_symbol (bfd *abfd) { asymbol *new; *************** bfd_mach_o_make_empty_symbol (bfd *abfd) *** 708,766 **** return new; } ! static int bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header) { unsigned char buf[32]; unsigned int size; bfd_vma (*get32) (const void *) = NULL; - bfd_seek (abfd, 0, SEEK_SET); - /* Just read the magic number. */ if (bfd_bread ((PTR) buf, 4, abfd) != 4) ! return -1; ! if (bfd_getb32 (buf) == 0xfeedface) { header->byteorder = BFD_ENDIAN_BIG; ! header->magic = 0xfeedface; header->version = 1; get32 = bfd_getb32; } ! else if (bfd_getl32 (buf) == 0xfeedface) { header->byteorder = BFD_ENDIAN_LITTLE; ! header->magic = 0xfeedface; header->version = 1; get32 = bfd_getl32; } ! else if (bfd_getb32 (buf) == 0xfeedfacf) { header->byteorder = BFD_ENDIAN_BIG; ! header->magic = 0xfeedfacf; header->version = 2; get32 = bfd_getb32; } ! else if (bfd_getl32 (buf) == 0xfeedfacf) { header->byteorder = BFD_ENDIAN_LITTLE; ! header->magic = 0xfeedfacf; header->version = 2; get32 = bfd_getl32; } else { header->byteorder = BFD_ENDIAN_UNKNOWN; ! return -1; } /* Once the size of the header is known, read the full header. */ ! size = (header->version == 2) ? 32 : 28; bfd_seek (abfd, 0, SEEK_SET); if (bfd_bread ((PTR) buf, size, abfd) != size) ! return -1; header->cputype = (*get32) (buf + 4); header->cpusubtype = (*get32) (buf + 8); --- 913,971 ---- return new; } ! static bfd_boolean bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header) { unsigned char buf[32]; unsigned int size; bfd_vma (*get32) (const void *) = NULL; /* Just read the magic number. */ + bfd_seek (abfd, 0, SEEK_SET); if (bfd_bread ((PTR) buf, 4, abfd) != 4) ! return FALSE; ! if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC) { header->byteorder = BFD_ENDIAN_BIG; ! header->magic = BFD_MACH_O_MH_MAGIC; header->version = 1; get32 = bfd_getb32; } ! else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC) { header->byteorder = BFD_ENDIAN_LITTLE; ! header->magic = BFD_MACH_O_MH_MAGIC; header->version = 1; get32 = bfd_getl32; } ! else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64) { header->byteorder = BFD_ENDIAN_BIG; ! header->magic = BFD_MACH_O_MH_MAGIC_64; header->version = 2; get32 = bfd_getb32; } ! else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64) { header->byteorder = BFD_ENDIAN_LITTLE; ! header->magic = BFD_MACH_O_MH_MAGIC_64; header->version = 2; get32 = bfd_getl32; } else { header->byteorder = BFD_ENDIAN_UNKNOWN; ! return FALSE; } /* Once the size of the header is known, read the full header. */ ! size = (header->version == 2) ? ! BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE; bfd_seek (abfd, 0, SEEK_SET); if (bfd_bread ((PTR) buf, size, abfd) != size) ! return FALSE; header->cputype = (*get32) (buf + 4); header->cpusubtype = (*get32) (buf + 8); *************** bfd_mach_o_read_header (bfd *abfd, bfd_m *** 772,778 **** if (header->version == 2) header->reserved = (*get32) (buf + 28); ! return 0; } static asection * --- 977,983 ---- if (header->version == 2) header->reserved = (*get32) (buf + 28); ! return TRUE; } static asection * *************** bfd_mach_o_make_bfd_section (bfd *abfd, *** 781,821 **** { asection *bfdsec; char *sname; - const char *prefix = "LC_SEGMENT"; - unsigned int snamelen; flagword flags; ! snamelen = strlen (prefix) + 1 ! + strlen (section->segname) + 1 ! + strlen (section->sectname) + 1; ! ! sname = bfd_alloc (abfd, snamelen); if (sname == NULL) return NULL; - /* Use canonical dwarf section names for dwarf sections. */ - if (strcmp (section->segname, "__DWARF") == 0 - && strncmp (section->sectname, "__", 2) == 0) - sprintf (sname, ".%s", section->sectname + 2); - else if (strcmp (section->segname, "__TEXT") == 0) - { - if (strcmp (section->sectname, "__eh_frame") == 0) - strcpy (sname, ".eh_frame"); - else if (section->sectname[0]) - sprintf (sname, "%s.%s", section->segname, section->sectname); - else - strcpy (sname, section->segname); - } - else if (strcmp (section->segname, "__DATA") == 0) - { - if (section->sectname[0]) - sprintf (sname, "%s.%s", section->segname, section->sectname); - else - strcpy (sname, section->segname); - } - else - sprintf (sname, "%s.%s.%s", prefix, section->segname, section- >sectname); - if (section->flags & BFD_MACH_O_S_ATTR_DEBUG) flags = SEC_HAS_CONTENTS | SEC_DEBUGGING; else --- 986,997 ---- { asection *bfdsec; char *sname; flagword flags; ! sname = bfd_mach_o_convert_section_name_to_bfd (abfd, section); if (sname == NULL) return NULL; if (section->flags & BFD_MACH_O_S_ATTR_DEBUG) flags = SEC_HAS_CONTENTS | SEC_DEBUGGING; else *************** bfd_mach_o_scan_read_section_32 (bfd *ab *** 853,862 **** bfd_vma offset, unsigned long prot) { ! unsigned char buf[68]; bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bread ((PTR) buf, 68, abfd) != 68) return -1; memcpy (section->sectname, buf, 16); --- 1029,1039 ---- bfd_vma offset, unsigned long prot) { ! unsigned char buf[BFD_MACH_O_SECTION_SIZE]; bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd) ! != BFD_MACH_O_SECTION_SIZE) return -1; memcpy (section->sectname, buf, 16); *************** bfd_mach_o_scan_read_section_64 (bfd *ab *** 887,896 **** bfd_vma offset, unsigned long prot) { ! unsigned char buf[80]; bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bread ((PTR) buf, 80, abfd) != 80) return -1; memcpy (section->sectname, buf, 16); --- 1064,1074 ---- bfd_vma offset, unsigned long prot) { ! unsigned char buf[BFD_MACH_O_SECTION_64_SIZE]; bfd_seek (abfd, offset, SEEK_SET); ! if (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd) ! != BFD_MACH_O_SECTION_64_SIZE) return -1; memcpy (section->sectname, buf, 16); *************** bfd_mach_o_scan_read_segment (bfd *abfd, *** 1551,1560 **** unsigned char buf[64]; bfd_mach_o_segment_command *seg = &command->command.segment; unsigned long i; - asection *bfdsec; - char *sname; - const char *prefix = "LC_SEGMENT"; - unsigned int snamelen; if (wide) { --- 1729,1734 ---- *************** bfd_mach_o_scan_read_segment (bfd *abfd, *** 1597,1641 **** seg->flags = bfd_h_get_32 (abfd, buf + 44); } - snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1; - sname = bfd_alloc (abfd, snamelen); - if (sname == NULL) - return -1; - if (strcmp (seg->segname, "__TEXT") == 0 - || strcmp (seg->segname, "__DATA") == 0 - || strcmp (seg->segname, "__IMPORT") == 0 - || strcmp (seg->segname, "__LINKEDIT") == 0) - strcpy (sname, seg->segname); - else - sprintf (sname, "%s.%s", prefix, seg->segname); - - bfdsec = bfd_make_section_anyway (abfd, sname); - if (bfdsec == NULL) - return -1; - - bfdsec->vma = seg->vmaddr; - bfdsec->lma = seg->vmaddr; - bfdsec->size = seg->filesize; - bfdsec->filepos = seg->fileoff; - bfdsec->alignment_power = 0x0; - bfdsec->flags = SEC_HAS_CONTENTS; - bfdsec->segment_mark = 1; - - seg->segment = bfdsec; - if (seg->nsects != 0) { ! seg->sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)); if (seg->sections == NULL) return -1; for (i = 0; i < seg->nsects; i++) { bfd_vma segoff; ! if (wide) ! segoff = command->offset + 64 + 8 + (i * 80); ! else ! segoff = command->offset + 48 + 8 + (i * 68); if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0) --- 1771,1792 ---- seg->flags = bfd_h_get_32 (abfd, buf + 44); } if (seg->nsects != 0) { ! seg->sections = bfd_alloc (abfd, seg->nsects ! * sizeof (bfd_mach_o_section)); if (seg->sections == NULL) return -1; for (i = 0; i < seg->nsects; i++) { bfd_vma segoff; ! if (wide) ! segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE ! + (i * BFD_MACH_O_SECTION_64_SIZE); ! else ! segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE ! + (i * BFD_MACH_O_SECTION_SIZE); if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0) *************** bfd_mach_o_scan_read_command (bfd *abfd, *** 1667,1675 **** if (bfd_bread ((PTR) buf, 8, abfd) != 8) return -1; ! command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD); command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD ! ? 1 : 0); command->len = bfd_h_get_32 (abfd, buf + 4); switch (command->type) --- 1818,1826 ---- if (bfd_bread ((PTR) buf, 8, abfd) != 8) return -1; ! command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD; command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD ! ? TRUE : FALSE); command->len = bfd_h_get_32 (abfd, buf + 4); switch (command->type) *************** bfd_mach_o_scan (bfd *abfd, *** 1876,1887 **** unsigned long cpusubtype; unsigned int hdrsize; ! hdrsize = (header->version == 2) ? 32 : 28; mdata->header = *header; mdata->symbols = NULL; ! abfd->flags = abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS); switch (header->filetype) { case BFD_MACH_O_MH_OBJECT: --- 2027,2039 ---- unsigned long cpusubtype; unsigned int hdrsize; ! hdrsize = (header->version == 2) ? ! BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE; mdata->header = *header; mdata->symbols = NULL; ! abfd->flags = abfd->flags & BFD_IN_MEMORY; switch (header->filetype) { case BFD_MACH_O_MH_OBJECT: *************** bfd_mach_o_scan (bfd *abfd, *** 1940,1946 **** } bfd_boolean ! bfd_mach_o_mkobject (bfd *abfd) { bfd_mach_o_data_struct *mdata = NULL; --- 2092,2098 ---- } bfd_boolean ! bfd_mach_o_mkobject_init (bfd *abfd) { bfd_mach_o_data_struct *mdata = NULL; *************** bfd_mach_o_mkobject (bfd *abfd) *** 1968,1980 **** } const bfd_target * ! bfd_mach_o_object_p (bfd *abfd) { struct bfd_preserve preserve; bfd_mach_o_header header; preserve.marker = NULL; ! if (bfd_mach_o_read_header (abfd, &header) != 0) goto wrong; if (! (header.byteorder == BFD_ENDIAN_BIG --- 2120,2134 ---- } const bfd_target * ! bfd_mach_o_header_p (bfd *abfd, ! bfd_mach_o_filetype filetype, ! bfd_mach_o_cpu_type cputype) { struct bfd_preserve preserve; bfd_mach_o_header header; preserve.marker = NULL; ! if (!bfd_mach_o_read_header (abfd, &header)) goto wrong; if (! (header.byteorder == BFD_ENDIAN_BIG *************** bfd_mach_o_object_p (bfd *abfd) *** 1993,1998 **** --- 2147,2188 ---- && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE))) goto wrong; + /* Check cputype and filetype. + In case of wildcard, do not accept magics that are handled by existing + targets. */ + if (cputype) + { + if (header.cputype != cputype) + goto wrong; + } + else + { + switch (header.cputype) + { + case BFD_MACH_O_CPU_TYPE_I386: + /* Handled by mach-o-i386 */ + goto wrong; + default: + break; + } + } + if (filetype) + { + if (header.filetype != filetype) + goto wrong; + } + else + { + switch (header.filetype) + { + case BFD_MACH_O_MH_CORE: + /* Handled by core_p */ + goto wrong; + default: + break; + } + } + preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct)); if (preserve.marker == NULL || !bfd_preserve_save (abfd, &preserve)) *************** bfd_mach_o_object_p (bfd *abfd) *** 2014,2067 **** return NULL; } ! const bfd_target * ! bfd_mach_o_core_p (bfd *abfd) { ! struct bfd_preserve preserve; ! bfd_mach_o_header header; ! ! preserve.marker = NULL; ! if (bfd_mach_o_read_header (abfd, &header) != 0) ! goto wrong; ! ! if (! (header.byteorder == BFD_ENDIAN_BIG ! || header.byteorder == BFD_ENDIAN_LITTLE)) ! { ! fprintf (stderr, "unknown header byte-order value 0x%lx\n", ! (unsigned long) header.byteorder); ! abort (); ! } ! ! if (! ((header.byteorder == BFD_ENDIAN_BIG ! && abfd->xvec->byteorder == BFD_ENDIAN_BIG ! && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG) ! || (header.byteorder == BFD_ENDIAN_LITTLE ! && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE ! && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE))) ! goto wrong; ! ! if (header.filetype != BFD_MACH_O_MH_CORE) ! goto wrong; ! ! preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct)); ! if (preserve.marker == NULL ! || !bfd_preserve_save (abfd, &preserve)) ! goto fail; ! ! if (bfd_mach_o_scan (abfd, &header, ! (bfd_mach_o_data_struct *) preserve.marker) != 0) ! goto wrong; ! ! bfd_preserve_finish (abfd, &preserve); ! return abfd->xvec; ! ! wrong: ! bfd_set_error (bfd_error_wrong_format); ! fail: ! if (preserve.marker != NULL) ! bfd_preserve_restore (abfd, &preserve); ! return NULL; } typedef struct mach_o_fat_archentry --- 2204,2219 ---- return NULL; } ! static const bfd_target * ! bfd_mach_o_gen_object_p (bfd *abfd) { ! return bfd_mach_o_header_p (abfd, 0, 0); ! } ! static const bfd_target * ! bfd_mach_o_gen_core_p (bfd *abfd) ! { ! return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0); } typedef struct mach_o_fat_archentry *************** bfd_mach_o_stack_addr (enum bfd_mach_o_c *** 2370,2376 **** } } ! static bfd_boolean bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, PTR ptr) { bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data; --- 2522,2528 ---- } } ! bfd_boolean bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, PTR ptr) { bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data; Index: mach-o.h =================================================================== RCS file: /cvs/src/src/bfd/mach-o.h,v retrieving revision 1.12 diff -c -p -r1.12 mach-o.h *** mach-o.h 23 Dec 2008 11:32:45 -0000 1.12 --- mach-o.h 2 Jun 2009 14:26:15 -0000 *************** *** 1,5 **** /* Mach-O support for BFD. ! Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. --- 1,5 ---- /* Mach-O support for BFD. ! Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. *************** *** 40,45 **** --- 40,54 ---- #define BFD_MACH_O_SYM_NSECT(SYM) (((SYM)->udata.i >> 16) & 0xff) #define BFD_MACH_O_SYM_NDESC(SYM) ((SYM)->udata.i & 0xffff) + typedef enum bfd_mach_o_mach_header_magic + { + BFD_MACH_O_MH_MAGIC = 0xfeedface, + BFD_MACH_O_MH_CIGAM = 0xcefaedfe, + BFD_MACH_O_MH_MAGIC_64 = 0xfeedfacf, + BFD_MACH_O_MH_CIGAM_64 = 0xcffaedfe + } + bfd_mach_o_mach_header_magic; + typedef enum bfd_mach_o_ppc_thread_flavour { BFD_MACH_O_PPC_THREAD_STATE = 1, *************** typedef enum bfd_mach_o_cpu_type *** 134,139 **** --- 143,154 ---- } bfd_mach_o_cpu_type; + typedef enum bfd_mach_o_cpu_subtype + { + BFD_MACH_O_CPU_SUBTYPE_X86_ALL = 3 + } + bfd_mach_o_cpu_subtype; + typedef enum bfd_mach_o_filetype { BFD_MACH_O_MH_OBJECT = 1, *************** bfd_mach_o_section_type; *** 225,232 **** /* Section contains only true machine instructions. */ #define BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS 0x80000000 - typedef unsigned long bfd_mach_o_cpu_subtype; - typedef struct bfd_mach_o_header { unsigned long magic; --- 240,245 ---- *************** typedef struct bfd_mach_o_header *** 243,248 **** --- 256,264 ---- } bfd_mach_o_header; + #define BFD_MACH_O_HEADER_SIZE 28 + #define BFD_MACH_O_HEADER_64_SIZE 32 + typedef struct bfd_mach_o_section { asection *bfdsection; *************** typedef struct bfd_mach_o_section *** 260,265 **** --- 276,283 ---- unsigned long reserved3; } bfd_mach_o_section; + #define BFD_MACH_O_SECTION_SIZE 68 + #define BFD_MACH_O_SECTION_64_SIZE 80 typedef struct bfd_mach_o_segment_command { *************** typedef struct bfd_mach_o_segment_comman *** 276,281 **** --- 294,301 ---- asection *segment; } bfd_mach_o_segment_command; + #define BFD_MACH_O_LC_SEGMENT_SIZE 56 + #define BFD_MACH_O_LC_SEGMENT_64_SIZE 72 /* Protection flags. */ #define BFD_MACH_O_PROT_READ 0x01 *************** bfd_mach_o_uuid_command; *** 506,512 **** typedef struct bfd_mach_o_load_command { bfd_mach_o_load_command_type type; ! unsigned int type_required; bfd_vma offset; bfd_vma len; union --- 526,532 ---- typedef struct bfd_mach_o_load_command { bfd_mach_o_load_command_type type; ! bfd_boolean type_required; bfd_vma offset; bfd_vma len; union *************** mach_o_data_struct; *** 540,565 **** typedef struct mach_o_data_struct bfd_mach_o_data_struct; ! bfd_boolean bfd_mach_o_valid (bfd *); ! int bfd_mach_o_scan_read_symtab_symbol (bfd *, bfd_mach_o_symtab_command *, asymbol *, unsigned long); ! int bfd_mach_o_scan_read_symtab_strtab (bfd *, bfd_mach_o_symtab_command *); ! int bfd_mach_o_scan_read_symtab_symbols (bfd *, bfd_mach_o_symtab_command *); ! int bfd_mach_o_scan_read_dysymtab_symbol (bfd *, bfd_mach_o_dysymtab_command *, bfd_mach_o_symtab_command *, asymbol *, unsigned long); ! int bfd_mach_o_scan_start_address (bfd *); ! int bfd_mach_o_scan (bfd *, bfd_mach_o_header *, bfd_mach_o_data_struct *); ! bfd_boolean bfd_mach_o_mkobject (bfd *); ! const bfd_target * bfd_mach_o_object_p (bfd *); ! const bfd_target * bfd_mach_o_core_p (bfd *); ! const bfd_target * bfd_mach_o_archive_p (bfd *); ! bfd * bfd_mach_o_openr_next_archived_file (bfd *, bfd *); ! int bfd_mach_o_lookup_section (bfd *, asection *, bfd_mach_o_load_command **, bfd_mach_o_section **); ! int bfd_mach_o_lookup_command (bfd *, bfd_mach_o_load_command_type, bfd_mach_o_load_command **); ! unsigned long bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type); ! int bfd_mach_o_core_fetch_environment (bfd *, unsigned char **, unsigned int *); ! char * bfd_mach_o_core_file_failing_command (bfd *); ! int bfd_mach_o_core_file_failing_signal (bfd *); ! bfd_boolean bfd_mach_o_core_file_matches_executable_p (bfd *, bfd *); bfd *bfd_mach_o_fat_extract (bfd *, bfd_format , const bfd_arch_info_type *); extern const bfd_target mach_o_be_vec; extern const bfd_target mach_o_le_vec; --- 560,603 ---- typedef struct mach_o_data_struct bfd_mach_o_data_struct; ! bfd_boolean bfd_mach_o_valid (bfd *); ! int bfd_mach_o_scan_read_symtab_symbol (bfd *, bfd_mach_o_symtab_command *, asymbol *, unsigned long); ! int bfd_mach_o_scan_read_symtab_strtab (bfd *, bfd_mach_o_symtab_command *); ! int bfd_mach_o_scan_read_symtab_symbols (bfd *, bfd_mach_o_symtab_command *); ! int bfd_mach_o_scan_read_dysymtab_symbol (bfd *, bfd_mach_o_dysymtab_command *, bfd_mach_o_symtab_command *, asymbol *, unsigned long); ! int bfd_mach_o_scan_start_address (bfd *); ! int bfd_mach_o_scan (bfd *, bfd_mach_o_header *, bfd_mach_o_data_struct *); ! bfd_boolean bfd_mach_o_mkobject_init (bfd *); ! const bfd_target *bfd_mach_o_object_p (bfd *); ! const bfd_target *bfd_mach_o_core_p (bfd *); ! const bfd_target *bfd_mach_o_archive_p (bfd *); ! bfd *bfd_mach_o_openr_next_archived_file (bfd *, bfd *); ! int bfd_mach_o_lookup_section (bfd *, asection *, bfd_mach_o_load_command **, bfd_mach_o_section **); ! int bfd_mach_o_lookup_command (bfd *, bfd_mach_o_load_command_type, bfd_mach_o_load_command **); ! bfd_boolean bfd_mach_o_write_contents (bfd *); ! bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data (bfd *, asymbol *, ! bfd *, asymbol *); ! bfd_boolean bfd_mach_o_bfd_copy_private_section_data (bfd *, asection *, ! bfd *, asection *); ! bfd_boolean bfd_mach_o_bfd_copy_private_bfd_data (bfd *, bfd *); ! long bfd_mach_o_get_symtab_upper_bound (bfd *); ! long bfd_mach_o_canonicalize_symtab (bfd *, asymbol **); ! asymbol *bfd_mach_o_make_empty_symbol (bfd *); ! void bfd_mach_o_get_symbol_info (bfd *, asymbol *, symbol_info *); ! void bfd_mach_o_print_symbol (bfd *, PTR, asymbol *, bfd_print_symbol_type); ! bfd_boolean bfd_mach_o_bfd_print_private_bfd_data (bfd *, PTR); ! int bfd_mach_o_sizeof_headers (bfd *, struct bfd_link_info *); ! unsigned long bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type); ! int bfd_mach_o_core_fetch_environment (bfd *, unsigned char **, unsigned int *); ! char *bfd_mach_o_core_file_failing_command (bfd *); ! int bfd_mach_o_core_file_failing_signal (bfd *); ! bfd_boolean bfd_mach_o_core_file_matches_executable_p (bfd *, bfd *); bfd *bfd_mach_o_fat_extract (bfd *, bfd_format , const bfd_arch_info_type *); + const bfd_target *bfd_mach_o_header_p (bfd *, bfd_mach_o_filetype, + bfd_mach_o_cpu_type); + bfd_boolean bfd_mach_o_build_commands (bfd *abfd); + bfd_boolean bfd_mach_o_set_section_contents (bfd *, asection *, const void *, + file_ptr, bfd_size_type); extern const bfd_target mach_o_be_vec; extern const bfd_target mach_o_le_vec; Index: targets.c =================================================================== RCS file: /cvs/src/src/bfd/targets.c,v retrieving revision 1.173 diff -c -p -r1.173 targets.c *** targets.c 28 May 2009 11:30:49 -0000 1.173 --- targets.c 2 Jun 2009 14:26:15 -0000 *************** extern const bfd_target m88kopenbsd_vec; *** 747,752 **** --- 747,753 ---- extern const bfd_target mach_o_be_vec; extern const bfd_target mach_o_le_vec; extern const bfd_target mach_o_fat_vec; + extern const bfd_target mach_o_i386_vec; extern const bfd_target maxqcoff_vec; extern const bfd_target mcore_pe_big_vec; extern const bfd_target mcore_pe_little_vec; *************** static const bfd_target * const _bfd_tar *** 1115,1120 **** --- 1116,1122 ---- &mach_o_be_vec, &mach_o_le_vec, &mach_o_fat_vec, + &mach_o_i386_vec, &maxqcoff_vec, &mcore_pe_big_vec, &mcore_pe_little_vec, *** /dev/null Tue Jun 2 16:19:02 2009 --- mach-o-i386.c Tue Jun 2 10:26:16 2009 *************** *** 0 **** --- 1,69 ---- + /* Intel i386 Mach-O support for BFD. + Copyright 2009 + Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + + #include "sysdep.h" + #include "mach-o.h" + #include "bfd.h" + #include "libbfd.h" + #include "libiberty.h" + + #define bfd_mach_o_object_p bfd_mach_o_i386_object_p + #define bfd_mach_o_core_p bfd_mach_o_i386_core_p + #define bfd_mach_o_mkobject bfd_mach_o_i386_mkobject + + static const bfd_target * + bfd_mach_o_i386_object_p (bfd *abfd) + { + return bfd_mach_o_header_p (abfd, 0, BFD_MACH_O_CPU_TYPE_I386); + } + + static const bfd_target * + bfd_mach_o_i386_core_p (bfd *abfd) + { + return bfd_mach_o_header_p (abfd, + BFD_MACH_O_MH_CORE, BFD_MACH_O_CPU_TYPE_I386); + } + + static bfd_boolean + bfd_mach_o_i386_mkobject (bfd *abfd) + { + bfd_mach_o_data_struct *mdata; + + if (!bfd_mach_o_mkobject_init (abfd)) + return FALSE; + + mdata = abfd->tdata.mach_o_data; + mdata->header.magic = BFD_MACH_O_MH_MAGIC; + mdata->header.cputype = BFD_MACH_O_CPU_TYPE_I386; + mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_X86_ALL; + mdata->header.filetype = BFD_MACH_O_MH_OBJECT; + mdata->header.byteorder = BFD_ENDIAN_LITTLE; + mdata->header.version = 1; + + return TRUE; + } + + #define TARGET_NAME mach_o_i386_vec + #define TARGET_STRING "mach-o-i386" + #define TARGET_BIG_ENDIAN 0 + #define TARGET_ARCHIVE 0 + + #include "mach-o-target.c"
- Previous message (by thread): MIPS -gc-sections broken?
- Next message (by thread): [Patch] Mach-O: add write capability
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list