2009-06-05 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: Regenerated.
	* 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.
This commit is contained in:
Tristan Gingold 2009-06-05 09:19:44 +00:00
parent 07070927ce
commit 154a1ee56c
9 changed files with 710 additions and 281 deletions

View File

@ -1,3 +1,117 @@
2009-06-05 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: Regenerated.
* 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.
2009-06-04 Alan Modra <amodra@bigpond.net.au>
* dep-in.sed: Don't use \n in replacement part of s command.
@ -564,7 +678,7 @@
2009-04-21 H.J. Lu <hongjiu.lu@intel.com>
* coff-ia64.c (COFF_PAGE_SIZE): Changed to 8K.
* coffcode.h (coff_compute_section_file_positions): Clear
D_PAGED if PE section alignment is smaller than COFF_PAGE_SIZE.
@ -817,7 +931,7 @@
2009-04-02 Sterling Augustine <sterling@jaw.hq.tensilica.com>
* elf32-xtensa.c (relax_property_section): Always set r_offset
* elf32-xtensa.c (relax_property_section): Always set r_offset
to zero.
2009-04-02 Christophe Lyon <christophe.lyon@st.com>
@ -833,7 +947,7 @@
* elf32-vax.c (elf_vax_check_relocs): Do not put relocations against
hidden symbols into the GOT or PLT.GOT.
(elf_vax_relocate_section): Do not emit a PCREL reloc
(elf_vax_relocate_section): Do not emit a PCREL reloc
into a shared object if it is against a hidden symbol.
2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>

View File

@ -541,8 +541,8 @@ case "${targ}" in
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_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*)

1
bfd/configure vendored
View File

@ -21171,6 +21171,7 @@ do
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" ;;

View File

@ -868,6 +868,7 @@ do
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" ;;

69
bfd/mach-o-i386.c Normal file
View File

@ -0,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"

View File

@ -1,5 +1,5 @@
/* Mach-O support for BFD.
Copyright 1999, 2000, 2001, 2002, 2007
Copyright 1999, 2000, 2001, 2002, 2007, 2009
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -19,6 +19,58 @@
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 */

View File

@ -1,5 +1,5 @@
/* Mach-O support for BFD.
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
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,54 +27,9 @@
#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
#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)
@ -91,22 +46,180 @@ bfd_boolean
bfd_mach_o_valid (bfd *abfd)
{
if (abfd == NULL || abfd->xvec == NULL)
return 0;
return FALSE;
if (! ((abfd->xvec == &mach_o_be_vec)
|| (abfd->xvec == &mach_o_le_vec)
|| (abfd->xvec == &mach_o_fat_vec)))
return 0;
if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
return FALSE;
if (abfd->tdata.mach_o_data == NULL)
return 0;
return 1;
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. */
static bfd_boolean
bfd_boolean
bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
asymbol *isymbol ATTRIBUTE_UNUSED,
bfd *obfd ATTRIBUTE_UNUSED,
@ -118,7 +231,7 @@ bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
/* Copy any private info we understand from the input section
to the output section. */
static bfd_boolean
bfd_boolean
bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
asection *isection ATTRIBUTE_UNUSED,
bfd *obfd ATTRIBUTE_UNUSED,
@ -130,17 +243,23 @@ bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
/* Copy any private info we understand from the input bfd
to the output bfd. */
static bfd_boolean
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));
obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
obfd->tdata.mach_o_data->ibfd = ibfd;
/* FIXME: copy commands. */
return TRUE;
}
/* Count the total number of symbols. Traverse all sections. */
static long
bfd_mach_o_count_symbols (bfd *abfd)
{
@ -161,7 +280,7 @@ bfd_mach_o_count_symbols (bfd *abfd)
return nsyms;
}
static long
long
bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
{
long nsyms = bfd_mach_o_count_symbols (abfd);
@ -172,7 +291,7 @@ bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
return ((nsyms + 1) * sizeof (asymbol *));
}
static long
long
bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
{
bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
@ -210,7 +329,7 @@ bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
return nsyms;
}
static void
void
bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
asymbol *symbol,
symbol_info *ret)
@ -218,7 +337,7 @@ bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
bfd_symbol_info (symbol, ret);
}
static void
void
bfd_mach_o_print_symbol (bfd *abfd,
PTR afile,
asymbol *symbol,
@ -319,13 +438,14 @@ bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
}
}
static int
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) ? 32 : 28;
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);
@ -340,9 +460,9 @@ bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
bfd_seek (abfd, 0, SEEK_SET);
if (bfd_bwrite ((PTR) buf, size, abfd) != size)
return -1;
return FALSE;
return 0;
return TRUE;
}
static int
@ -382,7 +502,7 @@ bfd_mach_o_scan_write_section_32 (bfd *abfd,
bfd_mach_o_section *section,
bfd_vma offset)
{
unsigned char buf[68];
unsigned char buf[BFD_MACH_O_SECTION_SIZE];
memcpy (buf, section->sectname, 16);
memcpy (buf + 16, section->segname, 16);
@ -397,7 +517,8 @@ bfd_mach_o_scan_write_section_32 (bfd *abfd,
bfd_h_put_32 (abfd, section->reserved2, buf + 64);
bfd_seek (abfd, offset, SEEK_SET);
if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
!= BFD_MACH_O_SECTION_SIZE)
return -1;
return 0;
@ -408,7 +529,7 @@ bfd_mach_o_scan_write_section_64 (bfd *abfd,
bfd_mach_o_section *section,
bfd_vma offset)
{
unsigned char buf[80];
unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
memcpy (buf, section->sectname, 16);
memcpy (buf + 16, section->segname, 16);
@ -424,7 +545,8 @@ bfd_mach_o_scan_write_section_64 (bfd *abfd,
bfd_h_put_32 (abfd, section->reserved3, buf + 76);
bfd_seek (abfd, offset, SEEK_SET);
if (bfd_bwrite ((PTR) buf, 80, abfd) != 80)
if (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
!= BFD_MACH_O_SECTION_64_SIZE)
return -1;
return 0;
@ -490,38 +612,15 @@ bfd_mach_o_scan_write_segment (bfd *abfd,
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);
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
+ (i * BFD_MACH_O_SECTION_64_SIZE);
else
segoff = command->offset + 48 + 8 + (i * 68);
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)
@ -606,22 +705,14 @@ bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
return 0;
}
static bfd_boolean
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)
if (!bfd_mach_o_write_header (abfd, &mdata->header))
return FALSE;
for (i = 0; i < mdata->header.ncmds; i++)
@ -630,7 +721,7 @@ bfd_mach_o_write_contents (bfd *abfd)
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;
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);
@ -686,7 +777,121 @@ bfd_mach_o_write_contents (bfd *abfd)
return TRUE;
}
static int
/* 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)
{
@ -696,7 +901,7 @@ bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
/* Make an empty symbol. This is required only because
bfd_make_section_anyway wants to create a symbol for the section. */
static asymbol *
asymbol *
bfd_mach_o_make_empty_symbol (bfd *abfd)
{
asymbol *new;
@ -708,59 +913,59 @@ bfd_mach_o_make_empty_symbol (bfd *abfd)
return new;
}
static int
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;
bfd_seek (abfd, 0, SEEK_SET);
/* Just read the magic number. */
bfd_seek (abfd, 0, SEEK_SET);
if (bfd_bread ((PTR) buf, 4, abfd) != 4)
return -1;
return FALSE;
if (bfd_getb32 (buf) == 0xfeedface)
if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
{
header->byteorder = BFD_ENDIAN_BIG;
header->magic = 0xfeedface;
header->magic = BFD_MACH_O_MH_MAGIC;
header->version = 1;
get32 = bfd_getb32;
}
else if (bfd_getl32 (buf) == 0xfeedface)
else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
{
header->byteorder = BFD_ENDIAN_LITTLE;
header->magic = 0xfeedface;
header->magic = BFD_MACH_O_MH_MAGIC;
header->version = 1;
get32 = bfd_getl32;
}
else if (bfd_getb32 (buf) == 0xfeedfacf)
else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
{
header->byteorder = BFD_ENDIAN_BIG;
header->magic = 0xfeedfacf;
header->magic = BFD_MACH_O_MH_MAGIC_64;
header->version = 2;
get32 = bfd_getb32;
}
else if (bfd_getl32 (buf) == 0xfeedfacf)
else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
{
header->byteorder = BFD_ENDIAN_LITTLE;
header->magic = 0xfeedfacf;
header->magic = BFD_MACH_O_MH_MAGIC_64;
header->version = 2;
get32 = bfd_getl32;
}
else
{
header->byteorder = BFD_ENDIAN_UNKNOWN;
return -1;
return FALSE;
}
/* Once the size of the header is known, read the full header. */
size = (header->version == 2) ? 32 : 28;
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 -1;
return FALSE;
header->cputype = (*get32) (buf + 4);
header->cpusubtype = (*get32) (buf + 8);
@ -772,7 +977,7 @@ bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
if (header->version == 2)
header->reserved = (*get32) (buf + 28);
return 0;
return TRUE;
}
static asection *
@ -781,41 +986,12 @@ bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
{
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);
sname = bfd_mach_o_convert_section_name_to_bfd (abfd, section);
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
@ -853,10 +1029,11 @@ bfd_mach_o_scan_read_section_32 (bfd *abfd,
bfd_vma offset,
unsigned long prot)
{
unsigned char buf[68];
unsigned char buf[BFD_MACH_O_SECTION_SIZE];
bfd_seek (abfd, offset, SEEK_SET);
if (bfd_bread ((PTR) buf, 68, abfd) != 68)
if (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
!= BFD_MACH_O_SECTION_SIZE)
return -1;
memcpy (section->sectname, buf, 16);
@ -887,10 +1064,11 @@ bfd_mach_o_scan_read_section_64 (bfd *abfd,
bfd_vma offset,
unsigned long prot)
{
unsigned char buf[80];
unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
bfd_seek (abfd, offset, SEEK_SET);
if (bfd_bread ((PTR) buf, 80, abfd) != 80)
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);
@ -1551,10 +1729,6 @@ bfd_mach_o_scan_read_segment (bfd *abfd,
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)
{
@ -1597,45 +1771,22 @@ bfd_mach_o_scan_read_segment (bfd *abfd,
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));
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 (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)
@ -1667,9 +1818,9 @@ bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
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 = 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);
? TRUE : FALSE);
command->len = bfd_h_get_32 (abfd, buf + 4);
switch (command->type)
@ -1876,12 +2027,13 @@ bfd_mach_o_scan (bfd *abfd,
unsigned long cpusubtype;
unsigned int hdrsize;
hdrsize = (header->version == 2) ? 32 : 28;
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 | BFD_IO_FUNCS);
abfd->flags = abfd->flags & BFD_IN_MEMORY;
switch (header->filetype)
{
case BFD_MACH_O_MH_OBJECT:
@ -1940,7 +2092,7 @@ bfd_mach_o_scan (bfd *abfd,
}
bfd_boolean
bfd_mach_o_mkobject (bfd *abfd)
bfd_mach_o_mkobject_init (bfd *abfd)
{
bfd_mach_o_data_struct *mdata = NULL;
@ -1968,13 +2120,15 @@ bfd_mach_o_mkobject (bfd *abfd)
}
const bfd_target *
bfd_mach_o_object_p (bfd *abfd)
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) != 0)
if (!bfd_mach_o_read_header (abfd, &header))
goto wrong;
if (! (header.byteorder == BFD_ENDIAN_BIG
@ -1993,6 +2147,42 @@ bfd_mach_o_object_p (bfd *abfd)
&& 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))
@ -2014,54 +2204,16 @@ bfd_mach_o_object_p (bfd *abfd)
return NULL;
}
const bfd_target *
bfd_mach_o_core_p (bfd *abfd)
static const bfd_target *
bfd_mach_o_gen_object_p (bfd *abfd)
{
struct bfd_preserve preserve;
bfd_mach_o_header header;
return bfd_mach_o_header_p (abfd, 0, 0);
}
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;
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
@ -2370,7 +2522,7 @@ bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
}
}
static bfd_boolean
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;

View File

@ -1,5 +1,5 @@
/* Mach-O support for BFD.
Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008
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,6 +40,15 @@
#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,
@ -134,6 +143,12 @@ typedef enum bfd_mach_o_cpu_type
}
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,
@ -225,8 +240,6 @@ bfd_mach_o_section_type;
/* 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;
@ -243,6 +256,9 @@ typedef struct bfd_mach_o_header
}
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;
@ -260,6 +276,8 @@ typedef struct bfd_mach_o_section
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
{
@ -276,6 +294,8 @@ typedef struct bfd_mach_o_segment_command
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
@ -506,7 +526,7 @@ bfd_mach_o_uuid_command;
typedef struct bfd_mach_o_load_command
{
bfd_mach_o_load_command_type type;
unsigned int type_required;
bfd_boolean type_required;
bfd_vma offset;
bfd_vma len;
union
@ -540,26 +560,44 @@ mach_o_data_struct;
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_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;

View File

@ -747,6 +747,7 @@ extern const bfd_target m88kopenbsd_vec;
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;
@ -1115,6 +1116,7 @@ static const bfd_target * const _bfd_target_vector[] =
&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,