2011-12-14  Iain Sandoe  <iains@gcc.gnu.org>

	* mach-o-i386.c (text_section_names_xlat): New table.
	(data_section_names_xlat): Likewise.
	(import_section_names_xlat): Likewise.
	(mach_o_i386_segsec_names_xlat): Likewise.
	(bfd_mach_o_tgt_seg_table): Use new tables.
	* mach-o-x86-64.c (bfd_mach_o_tgt_seg_table): Set NULL.
	* mach-o.c (mach_o_section_name_xlat, mach_o_segment_name_xlat):
	Move to mach-o.h as   typedefs.
	(text_section_names_xlat): Update for current GCC usage.
	(data_section_names_xlat): Likewise.
	(dwarf_section_names_xlat): Likewise.
	(objc_section_names_xlat): New table.
	(segsec_names_xlat): Add objc table.
	(bfd_mach_o_normalize_section_name):  Replace with...
	(bfd_mach_o_section_data_for_mach_sect): New.
	(bfd_mach_o_section_data_for_bfd_name): New.
	(bfd_mach_o_section_data_for_bfd_name): Update to use additional data.
	(bfd_mach_o_convert_section_name_to_mach_o): Likewise.
	(bfd_mach_o_bfd_copy_private_section_data): Implement.
	(bfd_mach_o_write_symtab): Write a zero-length string as the first entry
	for compatibility with system tools.
	(bfd_mach_o_build_commands): Update section alignment info.
	(bfd_mach_o_new_section_hook): Use translation table data to define
	default section flags, type, attributes and alignment, when available.
	(bfd_mach_o_init_section_from_mach_o): Add TODO comment.
	(bfd_mach_o_section_type_name): Add 'symbol_stubs'.
	(bfd_mach_o_section_attribute_name): Add 'self_modifying_code'.
	(bfd_mach_o_get_section_type_from_name): Change "not-found" return
	value.
	(bfd_mach_o_tgt_seg_table): Set default NULL.
	* mach-o.h (bfd_mach_o_segment_command):  Use define for name length.
	(bfd_mach_o_backend_data): Move until after contents are defined.
	(bfd_mach_o_normalize_section_name): Remove.
	(bfd_mach_o_convert_section_name_to_bfd): Declare.
	(mach_o_section_name_xlat): Declare.
	(mach_o_segment_name_xlat): Declare.
	(bfd_mach_o_section_data_for_mach_sect): Declare.
	(bfd_mach_o_section_data_for_bfd_name): Declare.

include/
2011-12-14  Iain Sandoe  <iains@gcc.gnu.org>

	* mach-o/loader.h (bfd_mach_o_section_type): define
	BFD_MACH_O_S_ATTR_NONE to 0.


gas/
2011-12-14  Iain Sandoe  <iains@gcc.gnu.org>

	* config/obj-macho.c: Add some more top-level comments.
	(collect_16char_name): New.
	(obj_mach_o_section): Amend to allow syntax compatible with existing system
	tools.  Use section translation data when available.
	(obj_mach_o_segT_from_bfd_name): New.
	(known_sections): Update.
	(obj_mach_o_known_section): Use obj_mach_o_segT_from_bfd_name.
	(objc_sections): New.
	(obj_mach_o_objc_section): New.
	(debug_sections): New.
	(obj_mach_o_debug_section): New.
	(tgt_sections): New.
	(obj_mach_o_opt_tgt_section): New.
	(obj_mach_o_base_section): New.
	(obj_mach_o_common_parse): Update to create BSS on demand and to handle
	lcomm optional alignment param.
	(obj_mach_o_comm): Update parameter name.
	(obj_mach_o_placeholder): New.
	(mach_o_pseudo_table): Update for GCC section directives.
	* config/obj-macho.h (_OBJ_MACH_O_H): New.
	(USE_ALIGN_PTWO): Define.
	(S_SET_ALIGN) Define.
This commit is contained in:
Tristan Gingold 2011-12-14 10:30:09 +00:00
parent d14c4eb729
commit a455111938
11 changed files with 1121 additions and 242 deletions

View file

@ -1,3 +1,44 @@
2011-12-14 Iain Sandoe <iains@gcc.gnu.org>
* mach-o-i386.c (text_section_names_xlat): New table.
(data_section_names_xlat): Likewise.
(import_section_names_xlat): Likewise.
(mach_o_i386_segsec_names_xlat): Likewise.
(bfd_mach_o_tgt_seg_table): Use new tables.
* mach-o-x86-64.c (bfd_mach_o_tgt_seg_table): Set NULL.
* mach-o.c (mach_o_section_name_xlat, mach_o_segment_name_xlat):
Move to mach-o.h as typedefs.
(text_section_names_xlat): Update for current GCC usage.
(data_section_names_xlat): Likewise.
(dwarf_section_names_xlat): Likewise.
(objc_section_names_xlat): New table.
(segsec_names_xlat): Add objc table.
(bfd_mach_o_normalize_section_name): Replace with...
(bfd_mach_o_section_data_for_mach_sect): New.
(bfd_mach_o_section_data_for_bfd_name): New.
(bfd_mach_o_section_data_for_bfd_name): Update to use additional data.
(bfd_mach_o_convert_section_name_to_mach_o): Likewise.
(bfd_mach_o_bfd_copy_private_section_data): Implement.
(bfd_mach_o_write_symtab): Write a zero-length string as the first entry
for compatibility with system tools.
(bfd_mach_o_build_commands): Update section alignment info.
(bfd_mach_o_new_section_hook): Use translation table data to define
default section flags, type, attributes and alignment, when available.
(bfd_mach_o_init_section_from_mach_o): Add TODO comment.
(bfd_mach_o_section_type_name): Add 'symbol_stubs'.
(bfd_mach_o_section_attribute_name): Add 'self_modifying_code'.
(bfd_mach_o_get_section_type_from_name): Change "not-found" return
value.
(bfd_mach_o_tgt_seg_table): Set default NULL.
* mach-o.h (bfd_mach_o_segment_command): Use define for name length.
(bfd_mach_o_backend_data): Move until after contents are defined.
(bfd_mach_o_normalize_section_name): Remove.
(bfd_mach_o_convert_section_name_to_bfd): Declare.
(mach_o_section_name_xlat): Declare.
(mach_o_segment_name_xlat): Declare.
(bfd_mach_o_section_data_for_mach_sect): Declare.
(bfd_mach_o_section_data_for_bfd_name): Declare.
2011-12-13 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
* dwarf2.c (bfd_dwarf2_cleanup_debug_info): Accept stash as an

View file

@ -280,10 +280,65 @@ bfd_mach_o_i386_print_thread (bfd *abfd, bfd_mach_o_thread_flavour *thread,
return FALSE;
}
static const mach_o_section_name_xlat text_section_names_xlat[] =
{
{ ".symbol_stub", "__symbol_stub",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS,
BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
0},
{ ".picsymbol_stub", "__picsymbol_stub",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS,
BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
0},
{ NULL, NULL, 0, 0, 0, 0}
};
static const mach_o_section_name_xlat data_section_names_xlat[] =
{
/* The first two are recognized by i386, but not emitted for x86 by
modern GCC. */
{ ".non_lazy_symbol_pointer", "__nl_symbol_ptr",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ ".lazy_symbol_pointer", "__la_symbol_ptr",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ ".lazy_symbol_pointer2", "__la_sym_ptr2",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ ".lazy_symbol_pointer3", "__la_sym_ptr3",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ NULL, NULL, 0, 0, 0, 0}
};
static const mach_o_section_name_xlat import_section_names_xlat[] =
{
{ ".picsymbol_stub3", "__jump_table",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS,
BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
| BFD_MACH_O_S_SELF_MODIFYING_CODE,
6},
{ ".non_lazy_symbol_pointer_x86", "__pointers",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ NULL, NULL, 0, 0, 0, 0}
};
const mach_o_segment_name_xlat mach_o_i386_segsec_names_xlat[] =
{
{ "__TEXT", text_section_names_xlat },
{ "__DATA", data_section_names_xlat },
{ "__IMPORT", import_section_names_xlat },
{ NULL, NULL }
};
#define bfd_mach_o_swap_reloc_in bfd_mach_o_i386_swap_reloc_in
#define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out
#define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread
#define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat
#define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_i386_bfd_reloc_type_lookup
#define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_i386_bfd_reloc_name_lookup

View file

@ -95,7 +95,8 @@ static const bfd_mach_o_backend_data TARGET_NAME_BACKEND =
TARGET_ARCHITECTURE,
bfd_mach_o_swap_reloc_in,
bfd_mach_o_swap_reloc_out,
bfd_mach_o_print_thread
bfd_mach_o_print_thread,
bfd_mach_o_tgt_seg_table
};
const bfd_target TARGET_NAME =

View file

@ -287,6 +287,7 @@ bfd_mach_o_x86_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
#define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_x86_64_bfd_reloc_type_lookup
#define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_x86_64_bfd_reloc_name_lookup
#define bfd_mach_o_print_thread NULL
#define bfd_mach_o_tgt_seg_table NULL
#define TARGET_NAME mach_o_x86_64_vec
#define TARGET_STRING "mach-o-x86-64"

View file

@ -87,118 +87,312 @@ bfd_mach_o_wide_p (bfd *abfd)
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;
flagword flags;
};
static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
/* __TEXT Segment. */
static const mach_o_section_name_xlat text_section_names_xlat[] =
{
{ ".debug_frame", "__debug_frame", SEC_DEBUGGING },
{ ".debug_info", "__debug_info", SEC_DEBUGGING },
{ ".debug_abbrev", "__debug_abbrev", SEC_DEBUGGING },
{ ".debug_aranges", "__debug_aranges", SEC_DEBUGGING },
{ ".debug_macinfo", "__debug_macinfo", SEC_DEBUGGING },
{ ".debug_line", "__debug_line", SEC_DEBUGGING },
{ ".debug_loc", "__debug_loc", SEC_DEBUGGING },
{ ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING },
{ ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING },
{ ".debug_str", "__debug_str", SEC_DEBUGGING },
{ ".debug_ranges", "__debug_ranges", SEC_DEBUGGING },
{ NULL, NULL, 0}
{ ".text", "__text",
SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, 0},
{ ".const", "__const",
SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".static_const", "__static_const",
SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".cstring", "__cstring",
SEC_READONLY | SEC_DATA | SEC_LOAD | SEC_MERGE | SEC_STRINGS,
BFD_MACH_O_S_CSTRING_LITERALS,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".literal4", "__literal4",
SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_4BYTE_LITERALS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ ".literal8", "__literal8",
SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_8BYTE_LITERALS,
BFD_MACH_O_S_ATTR_NONE, 3},
{ ".literal16", "__literal16",
SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_16BYTE_LITERALS,
BFD_MACH_O_S_ATTR_NONE, 4},
{ ".constructor", "__constructor",
SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".destructor", "__destructor",
SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".eh_frame", "__eh_frame",
SEC_READONLY | SEC_LOAD, BFD_MACH_O_S_COALESCED,
BFD_MACH_O_S_ATTR_LIVE_SUPPORT
| BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
| BFD_MACH_O_S_ATTR_NO_TOC, 3},
{ NULL, NULL, 0, 0, 0, 0}
};
static const struct mach_o_section_name_xlat text_section_names_xlat[] =
/* __DATA Segment. */
static const mach_o_section_name_xlat data_section_names_xlat[] =
{
{ ".text", "__text", SEC_CODE | SEC_LOAD },
{ ".const", "__const", SEC_READONLY | SEC_DATA | SEC_LOAD },
{ ".cstring", "__cstring", SEC_READONLY | SEC_DATA | SEC_LOAD },
{ ".eh_frame", "__eh_frame", SEC_READONLY | SEC_LOAD },
{ NULL, NULL, 0}
{ ".data", "__data",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".bss", "__bss",
SEC_NO_FLAGS, BFD_MACH_O_S_ZEROFILL,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".const_data", "__const",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".static_data", "__static_data",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".mod_init_func", "__mod_init_func",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ ".mod_term_func", "__mod_term_func",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS,
BFD_MACH_O_S_ATTR_NONE, 2},
{ ".dyld", "__dyld",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 0},
{ ".cfstring", "__cfstring",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NONE, 2},
{ NULL, NULL, 0, 0, 0, 0}
};
static const struct mach_o_section_name_xlat data_section_names_xlat[] =
/* __DWARF Segment. */
static const mach_o_section_name_xlat dwarf_section_names_xlat[] =
{
{ ".data", "__data", SEC_DATA | SEC_LOAD },
{ ".const_data", "__const", SEC_DATA | SEC_LOAD },
{ ".dyld", "__dyld", SEC_DATA | SEC_LOAD },
{ ".lazy_symbol_ptr", "__la_symbol_ptr", SEC_DATA | SEC_LOAD },
{ ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD },
{ ".bss", "__bss", SEC_NO_FLAGS },
{ NULL, NULL, 0}
{ ".debug_frame", "__debug_frame",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_info", "__debug_info",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_abbrev", "__debug_abbrev",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_aranges", "__debug_aranges",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_macinfo", "__debug_macinfo",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_line", "__debug_line",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_loc", "__debug_loc",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_pubnames", "__debug_pubnames",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_pubtypes", "__debug_pubtypes",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_str", "__debug_str",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_ranges", "__debug_ranges",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ ".debug_macro", "__debug_macro",
SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_DEBUG, 0},
{ NULL, NULL, 0, 0, 0, 0}
};
struct mach_o_segment_name_xlat
{
/* Segment name. */
const char *segname;
/* __OBJC Segment. */
static const mach_o_section_name_xlat objc_section_names_xlat[] =
{
{ ".objc_class", "__class",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_meta_class", "__meta_class",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_cat_cls_meth", "__cat_cls_meth",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_cat_inst_meth", "__cat_inst_meth",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_protocol", "__protocol",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_string_object", "__string_object",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_cls_meth", "__cls_meth",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_inst_meth", "__inst_meth",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_cls_refs", "__cls_refs",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_message_refs", "__message_refs",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_symbols", "__symbols",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_category", "__category",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_class_vars", "__class_vars",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_instance_vars", "__instance_vars",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_module_info", "__module_info",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_selector_strs", "__selector_strs",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_CSTRING_LITERALS,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_image_info", "__image_info",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc_selector_fixup", "__sel_fixup",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
/* Objc V1 */
{ ".objc1_class_ext", "__class_ext",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc1_property_list", "__property",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ ".objc1_protocol_ext", "__protocol_ext",
SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
{ NULL, NULL, 0, 0, 0, 0}
};
/* List of known sections for the segment. */
const struct mach_o_section_name_xlat *sections;
};
/* List of known segment names. */
static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
static const mach_o_segment_name_xlat segsec_names_xlat[] =
{
{ "__TEXT", text_section_names_xlat },
{ "__DATA", data_section_names_xlat },
{ "__DWARF", dwarf_section_names_xlat },
{ "__OBJC", objc_section_names_xlat },
{ NULL, NULL }
};
/* Mach-O to bfd names. */
/* For both cases bfd-name => mach-o name and vice versa, the specific target
is checked before the generic. This allows a target (e.g. ppc for cstring)
to override the generic definition with a more specific one. */
void
bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
const char **name, flagword *flags)
/* Fetch the translation from a Mach-O section designation (segment, section)
as a bfd short name, if one exists. Otherwise return NULL.
Allow the segment and section names to be unterminated 16 byte arrays. */
const mach_o_section_name_xlat *
bfd_mach_o_section_data_for_mach_sect (bfd *abfd, const char *segname,
const char *sectname)
{
const struct mach_o_segment_name_xlat *seg;
const mach_o_section_name_xlat *sec;
bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
*name = NULL;
*flags = SEC_NO_FLAGS;
for (seg = segsec_names_xlat; seg->segname; seg++)
{
/* First try any target-specific translations defined... */
if (bed->segsec_names_xlat)
for (seg = bed->segsec_names_xlat; seg->segname; seg++)
if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
{
const struct mach_o_section_name_xlat *sec;
for (sec = seg->sections; sec->mach_o_name; sec++)
if (strncmp (sec->mach_o_name, sectname,
BFD_MACH_O_SECTNAME_SIZE) == 0)
return sec;
for (sec = seg->sections; sec->mach_o_name; sec++)
{
if (strncmp (sec->mach_o_name, sectname,
BFD_MACH_O_SECTNAME_SIZE) == 0)
{
*name = sec->bfd_name;
*flags = sec->flags;
return;
}
}
return;
}
}
/* ... and then the Mach-O generic ones. */
for (seg = segsec_names_xlat; seg->segname; seg++)
if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
for (sec = seg->sections; sec->mach_o_name; sec++)
if (strncmp (sec->mach_o_name, sectname,
BFD_MACH_O_SECTNAME_SIZE) == 0)
return sec;
return NULL;
}
/* Convert Mach-O section name to BFD. Try to use standard names, otherwise
forge a new name. SEGNAME and SECTNAME are 16 bytes strings. */
/* If the bfd_name for this section is a 'canonical' form for which we
know the Mach-O data, return the segment name and the data for the
Mach-O equivalent. Otherwise return NULL. */
static void
bfd_mach_o_convert_section_name_to_bfd
(bfd *abfd, const char *segname, const char *sectname,
const char **name, flagword *flags)
const mach_o_section_name_xlat *
bfd_mach_o_section_data_for_bfd_name (bfd *abfd, const char *bfd_name,
const char **segname)
{
const struct mach_o_segment_name_xlat *seg;
const mach_o_section_name_xlat *sec;
bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
*segname = NULL;
if (bfd_name[0] != '.')
return NULL;
/* First try any target-specific translations defined... */
if (bed->segsec_names_xlat)
for (seg = bed->segsec_names_xlat; seg->segname; seg++)
for (sec = seg->sections; sec->bfd_name; sec++)
if (strcmp (bfd_name, sec->bfd_name) == 0)
{
*segname = seg->segname;
return sec;
}
/* ... and then the Mach-O generic ones. */
for (seg = segsec_names_xlat; seg->segname; seg++)
for (sec = seg->sections; sec->bfd_name; sec++)
if (strcmp (bfd_name, sec->bfd_name) == 0)
{
*segname = seg->segname;
return sec;
}
return NULL;
}
/* Convert Mach-O section name to BFD.
Try to use standard/canonical names, for which we have tables including
default flag settings - which are returned. Otherwise forge a new name
in the form "<segmentname>.<sectionname>" this will be prefixed with
LC_SEGMENT. if the segment name does not begin with an underscore.
SEGNAME and SECTNAME are 16 byte arrays (they do not need to be NUL-
terminated if the name length is exactly 16 bytes - but must be if the name
length is less than 16 characters). */
void
bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
const char *secname, const char **name,
flagword *flags)
{
const mach_o_section_name_xlat *xlat;
char *res;
unsigned int len;
const char *pfx = "";
/* First search for a canonical name. */
bfd_mach_o_normalize_section_name (segname, sectname, name, flags);
*name = NULL;
*flags = SEC_NO_FLAGS;
/* Return now if found. */
if (*name)
return;
/* First search for a canonical name...
xlat will be non-null if there is an entry for segname, secname. */
xlat = bfd_mach_o_section_data_for_mach_sect (abfd, segname, secname);
if (xlat)
{
len = strlen (xlat->bfd_name);
res = bfd_alloc (abfd, len+1);
if (res == NULL)
return;
memcpy (res, xlat->bfd_name, len+1);
*name = res;
*flags = xlat->bfd_flags;
return;
}
/* ... else we make up a bfd name from the segment concatenated with the
section. */
len = 16 + 1 + 16 + 1;
@ -215,43 +409,46 @@ bfd_mach_o_convert_section_name_to_bfd
res = bfd_alloc (abfd, len);
if (res == NULL)
return;
snprintf (res, len, "%s%.16s.%.16s", pfx, segname, sectname);
snprintf (res, len, "%s%.16s.%.16s", pfx, segname, secname);
*name = res;
*flags = SEC_NO_FLAGS;
}
/* Convert a bfd section name to a Mach-O segment + section name. */
/* Convert a bfd section name to a Mach-O segment + section name.
static void
If the name is a canonical one for which we have a Darwin match
return the translation table - which contains defaults for flags,
type, attribute and default alignment data.
Otherwise, expand the bfd_name (assumed to be in the form
"[LC_SEGMENT.]<segmentname>.<sectionname>") and return NULL. */
static const mach_o_section_name_xlat *
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 mach_o_section_name_xlat *xlat;
const char *name = bfd_get_section_name (abfd, sect);
const char *segname;
const char *dot;
unsigned int len;
unsigned int seglen;
unsigned int seclen;
/* List of well known names. They all start with a dot. */
if (name[0] == '.')
for (seg = segsec_names_xlat; seg->segname; seg++)
{
const struct mach_o_section_name_xlat *sec;
memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1);
memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1);
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;
}
}
}
/* See if is a canonical name ... */
xlat = bfd_mach_o_section_data_for_bfd_name (abfd, name, &segname);
if (xlat)
{
strcpy (section->segname, segname);
strcpy (section->sectname, xlat->mach_o_name);
return xlat;
}
/* Strip LC_SEGMENT. prefix. */
/* .. else we convert our constructed one back to Mach-O.
Strip LC_SEGMENT. prefix, if present. */
if (strncmp (name, "LC_SEGMENT.", 11) == 0)
name += 11;
@ -271,16 +468,23 @@ bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
section->segname[seglen] = 0;
memcpy (section->sectname, dot + 1, seclen);
section->sectname[seclen] = 0;
return;
return NULL;
}
}
/* The segment and section names are both missing - don't make them
into dots. */
if (dot && dot == name)
return NULL;
/* Just duplicate the name into both segment and section. */
if (len > 16)
len = 16;
memcpy (section->segname, name, len);
section->segname[len] = 0;
memcpy (section->sectname, name, len);
section->sectname[len] = 0;
return NULL;
}
/* Return the size of an entry for section SEC.
@ -337,10 +541,20 @@ bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
bfd_boolean
bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
asection *isection ATTRIBUTE_UNUSED,
asection *isection,
bfd *obfd ATTRIBUTE_UNUSED,
asection *osection ATTRIBUTE_UNUSED)
asection *osection)
{
if (osection->used_by_bfd == NULL)
osection->used_by_bfd = isection->used_by_bfd;
else
if (isection->used_by_bfd != NULL)
memcpy (osection->used_by_bfd, isection->used_by_bfd,
sizeof (bfd_mach_o_section));
if (osection->used_by_bfd != NULL)
((bfd_mach_o_section *)osection->used_by_bfd)->bfdsection = osection;
return TRUE;
}
@ -1099,6 +1313,12 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
if (strtab == NULL)
return FALSE;
if (sym->nsyms > 0)
/* Although we don't strictly need to do this, for compatibility with
Darwin system tools, actually output an empty string for the index
0 entry. */
_bfd_stringtab_add (strtab, "", TRUE, FALSE);
for (i = 0; i < sym->nsyms; i++)
{
bfd_size_type str_index;
@ -1415,22 +1635,22 @@ bfd_mach_o_build_commands (bfd *abfd)
seg->sect_head = NULL;
seg->sect_tail = NULL;
/* Create Mach-O sections. */
/* Create Mach-O sections.
Section type, attribute and align should have been set when the
section was created - either read in or specified. */
target_index = 0;
for (sec = abfd->sections; sec; sec = sec->next)
{
unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
bfd_mach_o_append_section_to_segment (seg, sec);
if (msect->flags == 0)
{
/* We suppose it hasn't been set. Convert from BFD flags. */
bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
}
msect->addr = bfd_get_section_vma (abfd, sec);
msect->size = bfd_get_section_size (sec);
msect->align = bfd_get_section_alignment (abfd, sec);
/* Use the largest alignment set, in case it was bumped after the
section was created. */
msect->align = msect->align > bfd_align ? msect->align : bfd_align;
if (msect->size != 0)
{
@ -1572,11 +1792,13 @@ bfd_boolean
bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
{
bfd_mach_o_section *s;
unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
s = bfd_mach_o_get_mach_o_section (sec);
if (s == NULL)
{
flagword bfd_flags;
static const mach_o_section_name_xlat * xlat;
s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
if (s == NULL)
@ -1584,21 +1806,24 @@ bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
sec->used_by_bfd = s;
s->bfdsection = sec;
/* Create default name. */
bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
/* Create default flags. */
bfd_flags = bfd_get_section_flags (abfd, sec);
if ((bfd_flags & SEC_CODE) == SEC_CODE)
s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
| BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
| BFD_MACH_O_S_REGULAR;
else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
s->flags = BFD_MACH_O_S_ZEROFILL;
else if (bfd_flags & SEC_DEBUGGING)
s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
/* Create the Darwin seg/sect name pair from the bfd name.
If this is a canonical name for which a specific paiting exists
there will also be defined flags, type, attribute and alignment
values. */
xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
if (xlat != NULL)
{
s->flags = xlat->macho_sectype | xlat->macho_secattr;
s->align = xlat->sectalign > bfdalign ? xlat->sectalign
: bfdalign;
bfd_set_section_alignment (abfd, sec, s->align);
bfd_flags = bfd_get_section_flags (abfd, sec);
if (bfd_flags == SEC_NO_FLAGS)
bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
}
else
s->flags = BFD_MACH_O_S_REGULAR;
/* Create default flags. */
bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
}
return _bfd_generic_new_section_hook (abfd, sec);
@ -1614,6 +1839,9 @@ bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
flags = bfd_get_section_flags (abfd, sec);
section = bfd_mach_o_get_mach_o_section (sec);
/* TODO: see if we should use the xlat system for doing this by
preference and fall back to this for unknown sections. */
if (flags == SEC_NO_FLAGS)
{
/* Try to guess flags. */
@ -3323,6 +3551,7 @@ const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
{ "interposing", BFD_MACH_O_S_INTERPOSING},
{ "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
{ "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
{ "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
{ "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
{ NULL, 0}
};
@ -3339,10 +3568,11 @@ const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
{ "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
{ "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
{ "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
{ "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
{ NULL, 0}
};
/* Get the section type from NAME. Return -1 if NAME is unknown. */
/* Get the section type from NAME. Return 256 if NAME is unknown. */
unsigned int
bfd_mach_o_get_section_type_from_name (const char *name)
@ -3352,7 +3582,8 @@ bfd_mach_o_get_section_type_from_name (const char *name)
for (x = bfd_mach_o_section_type_name; x->name; x++)
if (strcmp (x->name, name) == 0)
return x->val;
return (unsigned int)-1;
/* Maximum section ID = 0xff. */
return 256;
}
/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
@ -3518,6 +3749,7 @@ bfd_mach_o_close_and_cleanup (bfd *abfd)
#define bfd_mach_o_swap_reloc_in NULL
#define bfd_mach_o_swap_reloc_out NULL
#define bfd_mach_o_print_thread NULL
#define bfd_mach_o_tgt_seg_table NULL
#define TARGET_NAME mach_o_be_vec
#define TARGET_STRING "mach-o-be"

View file

@ -1,5 +1,5 @@
/* Mach-O support for BFD.
Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009
Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2011
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -70,7 +70,7 @@ bfd_mach_o_section;
typedef struct bfd_mach_o_segment_command
{
char segname[16 + 1];
char segname[BFD_MACH_O_SEGNAME_SIZE + 1];
bfd_vma vmaddr;
bfd_vma vmsize;
bfd_vma fileoff;
@ -530,15 +530,6 @@ typedef struct bfd_mach_o_xlat_name
bfd_mach_o_xlat_name;
/* Target specific routines. */
typedef struct bfd_mach_o_backend_data
{
enum bfd_architecture arch;
bfd_boolean (*_bfd_mach_o_swap_reloc_in)(arelent *, bfd_mach_o_reloc_info *);
bfd_boolean (*_bfd_mach_o_swap_reloc_out)(arelent *, bfd_mach_o_reloc_info *);
bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *,
void *, char *);
}
bfd_mach_o_backend_data;
#define bfd_mach_o_get_data(abfd) ((abfd)->tdata.mach_o_data)
#define bfd_mach_o_get_backend_data(abfd) \
@ -591,8 +582,9 @@ unsigned int bfd_mach_o_version (bfd *);
unsigned int bfd_mach_o_get_section_type_from_name (const char *);
unsigned int bfd_mach_o_get_section_attribute_from_name (const char *);
void bfd_mach_o_normalize_section_name (const char *, const char *,
const char **, flagword *);
void bfd_mach_o_convert_section_name_to_bfd (bfd *, const char *, const char *,
const char **, flagword *);
bfd_boolean bfd_mach_o_find_nearest_line (bfd *, asection *, asymbol **,
bfd_vma, const char **,
const char **, unsigned int *);
@ -608,4 +600,38 @@ extern const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[];
extern const bfd_target mach_o_fat_vec;
/* Interfaces between BFD names and Mach-O names. */
typedef struct mach_o_section_name_xlat
{
const char *bfd_name;
const char *mach_o_name;
flagword bfd_flags;
unsigned int macho_sectype;
unsigned int macho_secattr;
unsigned int sectalign;
} mach_o_section_name_xlat;
typedef struct mach_o_segment_name_xlat
{
const char *segname;
const mach_o_section_name_xlat *sections;
} mach_o_segment_name_xlat;
const mach_o_section_name_xlat *
bfd_mach_o_section_data_for_mach_sect (bfd *, const char *, const char *);
const mach_o_section_name_xlat *
bfd_mach_o_section_data_for_bfd_name (bfd *, const char *, const char **);
typedef struct bfd_mach_o_backend_data
{
enum bfd_architecture arch;
bfd_boolean (*_bfd_mach_o_swap_reloc_in)(arelent *, bfd_mach_o_reloc_info *);
bfd_boolean (*_bfd_mach_o_swap_reloc_out)(arelent *, bfd_mach_o_reloc_info *);
bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *,
void *, char *);
const mach_o_segment_name_xlat *segsec_names_xlat;
}
bfd_mach_o_backend_data;
#endif /* _BFD_MACH_O_H_ */

View file

@ -1,3 +1,28 @@
2011-12-14 Iain Sandoe <iains@gcc.gnu.org>
* config/obj-macho.c: Add some more top-level comments.
(collect_16char_name): New.
(obj_mach_o_section): Amend to allow syntax compatible with
existing system tools. Use section translation data when available.
(obj_mach_o_segT_from_bfd_name): New.
(known_sections): Update.
(obj_mach_o_known_section): Use obj_mach_o_segT_from_bfd_name.
(objc_sections): New.
(obj_mach_o_objc_section): New.
(debug_sections): New.
(obj_mach_o_debug_section): New.
(tgt_sections): New.
(obj_mach_o_opt_tgt_section): New.
(obj_mach_o_base_section): New.
(obj_mach_o_common_parse): Update to create BSS on demand and to handle
lcomm optional alignment param.
(obj_mach_o_comm): Update parameter name.
(obj_mach_o_placeholder): New.
(mach_o_pseudo_table): Update for GCC section directives.
* config/obj-macho.h (_OBJ_MACH_O_H): New.
(USE_ALIGN_PTWO): Define.
(S_SET_ALIGN) Define.
2011-12-13 Andrew Burgess <aburgess@broadcom.com>
* doc/internals.texi (TC_FORCE_RELOCATION_SUB_SAME): Update

View file

@ -1,5 +1,5 @@
/* Mach-O object file format
Copyright 2009 Free Software Foundation, Inc.
Copyright 2009, 2011 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -18,6 +18,23 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
/* Here we handle the mach-o directives that are common to all architectures.
Most significant are mach-o named sections and a variety of symbol type
decorations. */
/* Mach-O supports multiple, named segments each of which may contain
multiple named sections. Thus the concept of subsectioning is
handled by (say) having a __TEXT segment with appropriate flags from
which subsections are generated like __text, __const etc.
The well-known as short-hand section switch directives like .text, .data
etc. are mapped onto predefined segment/section pairs using facilites
supplied by the mach-o port of bfd.
A number of additional mach-o short-hand section switch directives are
also defined. */
#define OBJ_HEADER "obj-macho.h"
#include "as.h"
@ -26,6 +43,15 @@
#include "write.h"
#include "mach-o.h"
#include "mach-o/loader.h"
#include "obj-macho.h"
/* TODO: Implement "-dynamic"/"-static" command line options. */
static int obj_mach_o_is_static;
/* Allow for special re-ordering on output. */
static int seen_objc_section;
static void
obj_mach_o_weak (int ignore ATTRIBUTE_UNUSED)
@ -53,104 +79,172 @@ obj_mach_o_weak (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
/* Parse:
.section segname,sectname[,type[,attribute[,sizeof_stub]]]
*/
/* This will put at most 16 characters (terminated by a ',' or newline) from
the input stream into dest. If there are more than 16 chars before the
delimiter, a warning is given and the string is truncated. On completion of
this function, input_line_pointer will point to the char after the ',' or
to the newline.
It trims leading and trailing space. */
static int
collect_16char_name (char *dest, const char *msg, int require_comma)
{
char c, *namstart;
SKIP_WHITESPACE ();
namstart = input_line_pointer;
while ( (c = *input_line_pointer) != ','
&& !is_end_of_line[(unsigned char) c])
input_line_pointer++;
{
int len = input_line_pointer - namstart; /* could be zero. */
/* lose any trailing space. */
while (len > 0 && namstart[len-1] == ' ')
len--;
if (len > 16)
{
*input_line_pointer = '\0'; /* make a temp string. */
as_bad (_("the %s name '%s' is too long (maximum 16 characters)"),
msg, namstart);
*input_line_pointer = c; /* restore for printing. */
len = 16;
}
if (len > 0)
memcpy (dest, namstart, len);
}
if (c != ',' && require_comma)
{
as_bad (_("expected a %s name followed by a `,'"), msg);
return 1;
}
return 0;
}
/* .section
The '.section' specification syntax looks like:
.section <segment> , <section> [, type [, attribs [, size]]]
White space is allowed everywhere between elements.
<segment> and <section> may be from 0 to 16 chars in length - they may
contain spaces but leading and trailing space will be trimmed. It is
mandatory that they be present (or that zero-length names are indicated
by ",,").
There is only a single section type for any entry.
There may be multiple attributes, they are delimited by `+'.
Not all section types and attributes are accepted by the Darwin system
assemblers as user-specifiable - although, at present, we do here. */
static void
obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
{
char *p;
char *segname;
char *sectname;
char c;
int sectype = BFD_MACH_O_S_REGULAR;
unsigned int sectype = BFD_MACH_O_S_REGULAR;
unsigned int defsectype = BFD_MACH_O_S_REGULAR;
unsigned int sectype_given = 0;
unsigned int secattr = 0;
unsigned int defsecattr = 0;
int secattr_given = 0;
unsigned int secalign = 0;
offsetT sizeof_stub = 0;
const mach_o_section_name_xlat * xlat;
const char *name;
flagword oldflags, flags;
asection *sec;
bfd_mach_o_section *msect;
char segname[17];
char sectname[17];
/* Zero-length segment and section names are allowed. */
/* Parse segment name. */
if (!is_name_beginner (*input_line_pointer))
memset (segname, 0, sizeof(segname));
if (collect_16char_name (segname, "segment", 1))
{
as_bad (_("missing segment name"));
ignore_rest_of_line ();
return;
}
p = input_line_pointer;
c = get_symbol_end ();
segname = alloca (input_line_pointer - p + 1);
strcpy (segname, p);
*input_line_pointer = c;
if (*input_line_pointer != ',')
{
as_bad (_("missing comma after segment name"));
ignore_rest_of_line ();
return;
}
input_line_pointer++;
input_line_pointer++; /* Skip the terminating ',' */
/* Parse section name. */
if (!is_name_beginner (*input_line_pointer))
{
as_bad (_("missing section name"));
ignore_rest_of_line ();
return;
}
p = input_line_pointer;
c = get_symbol_end ();
sectname = alloca (input_line_pointer - p + 1);
strcpy (sectname, p);
*input_line_pointer = c;
memset (sectname, 0, sizeof(sectname));
collect_16char_name (sectname, "section", 0);
/* Parse type. */
if (*input_line_pointer == ',')
{
char tmpc;
int len;
input_line_pointer++;
if (!is_name_beginner (*input_line_pointer))
{
as_bad (_("missing section type name"));
ignore_rest_of_line ();
return;
}
SKIP_WHITESPACE ();
p = input_line_pointer;
c = get_symbol_end ();
while ((c = *input_line_pointer) != ','
&& !is_end_of_line[(unsigned char) c])
input_line_pointer++;
len = input_line_pointer - p;
/* strip trailing spaces. */
while (len > 0 && p[len-1] == ' ')
len--;
tmpc = p[len];
/* Temporarily make a string from the token. */
p[len] = 0;
sectype = bfd_mach_o_get_section_type_from_name (p);
if (sectype == -1)
if (sectype > 255) /* Max Section ID == 255. */
{
as_bad (_("unknown or invalid section type '%s'"), p);
sectype = BFD_MACH_O_S_REGULAR;
}
*input_line_pointer = c;
else
sectype_given = 1;
/* Restore. */
tmpc = p[len];
/* Parse attributes. */
if (*input_line_pointer == ',')
/* Parse attributes.
TODO: check validity of attributes for section type. */
if (sectype_given && c == ',')
{
do
{
int attr;
/* Skip initial `,' and subsequent `+'. */
input_line_pointer++;
SKIP_WHITESPACE ();
p = input_line_pointer;
while ((c = *input_line_pointer) != '+'
&& c != ','
&& !is_end_of_line[(unsigned char) c])
input_line_pointer++;
if (!is_name_beginner (*input_line_pointer))
{
as_bad (_("missing section attribute identifier"));
ignore_rest_of_line ();
break;
}
p = input_line_pointer;
c = get_symbol_end ();
len = input_line_pointer - p;
/* strip trailing spaces. */
while (len > 0 && p[len-1] == ' ')
len--;
tmpc = p[len];
/* Temporarily make a string from the token. */
p[len] ='\0';
attr = bfd_mach_o_get_section_attribute_from_name (p);
if (attr == -1)
if (attr == -1)
as_bad (_("unknown or invalid section attribute '%s'"), p);
else
secattr |= attr;
*input_line_pointer = c;
{
secattr_given = 1;
secattr |= attr;
}
/* Restore. */
p[len] = tmpc;
}
while (*input_line_pointer == '+');
@ -160,6 +254,7 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
if (sectype != BFD_MACH_O_S_SYMBOL_STUBS)
as_bad (_("unexpected sizeof_stub expression"));
input_line_pointer++;
sizeof_stub = get_absolute_expression ();
}
else if (sectype == BFD_MACH_O_S_SYMBOL_STUBS)
@ -168,8 +263,19 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
}
demand_empty_rest_of_line ();
bfd_mach_o_normalize_section_name (segname, sectname, &name, &flags);
if (name == NULL)
flags = SEC_NO_FLAGS;
/* This provides default bfd flags and default mach-o section type and
attributes along with the canonical name. */
xlat = bfd_mach_o_section_data_for_mach_sect (stdoutput, segname, sectname);
if (xlat != NULL)
{
name = xstrdup (xlat->bfd_name);
flags = xlat->bfd_flags;
defsectype = xlat->macho_sectype;
defsecattr = xlat->macho_secattr;
secalign = xlat->sectalign;
}
else
{
/* There is no normal BFD section name for this section. Create one.
The name created doesn't really matter as it will never be written
@ -194,90 +300,368 @@ obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
sec = subseg_new (name, 0);
oldflags = bfd_get_section_flags (stdoutput, sec);
if (oldflags == SEC_NO_FLAGS)
msect = bfd_mach_o_get_mach_o_section (sec);
if (oldflags == SEC_NO_FLAGS)
{
bfd_mach_o_section *msect;
if (! bfd_set_section_flags (stdoutput, sec, flags))
as_warn (_("error setting flags for \"%s\": %s"),
bfd_section_name (stdoutput, sec),
bfd_errmsg (bfd_get_error ()));
msect = bfd_mach_o_get_mach_o_section (sec);
strncpy (msect->segname, segname, sizeof (msect->segname));
msect->segname[16] = 0;
strncpy (msect->sectname, sectname, sizeof (msect->sectname));
msect->sectname[16] = 0;
msect->flags = secattr | sectype;
msect->align = secalign;
if (sectype_given)
{
msect->flags = sectype;
if (secattr_given)
msect->flags |= secattr;
else
msect->flags |= defsecattr;
}
else
msect->flags = defsectype | defsecattr;
msect->reserved2 = sizeof_stub;
}
else if (flags != SEC_NO_FLAGS)
{
if (flags != oldflags)
if (flags != oldflags
|| msect->flags != (secattr | sectype))
as_warn (_("Ignoring changed section attributes for %s"), name);
}
}
struct known_section
static segT
obj_mach_o_segT_from_bfd_name (const char *nam, int must_succeed)
{
const char *name;
unsigned int flags;
const mach_o_section_name_xlat *xlat;
const char *segn;
segT sec;
/* BFD has tables of flags and default attributes for all the sections that
have a 'canonical' name. */
xlat = bfd_mach_o_section_data_for_bfd_name (stdoutput, nam, &segn);
if (xlat == NULL)
{
if (must_succeed)
as_fatal (_("BFD is out of sync with GAS, "
"unhandled well-known section type `%s'"), nam);
return NULL;
}
sec = bfd_get_section_by_name (stdoutput, nam);
if (sec == NULL)
{
bfd_mach_o_section *msect;
sec = subseg_force_new (xlat->bfd_name, 0);
/* Set default type, attributes and alignment. */
msect = bfd_mach_o_get_mach_o_section (sec);
msect->flags = xlat->macho_sectype | xlat->macho_secattr;
msect->align = xlat->sectalign;
if ((msect->flags & BFD_MACH_O_SECTION_TYPE_MASK)
== BFD_MACH_O_S_ZEROFILL)
seg_info (sec)->bss = 1;
}
return sec;
}
static const char * const known_sections[] =
{
/* 0 */ NULL,
/* __TEXT */
/* 1 */ ".const",
/* 2 */ ".static_const",
/* 3 */ ".cstring",
/* 4 */ ".literal4",
/* 5 */ ".literal8",
/* 6 */ ".literal16",
/* 7 */ ".constructor",
/* 8 */ ".destructor",
/* 9 */ ".eh_frame",
/* __DATA */
/* 10 */ ".const_data",
/* 11 */ ".static_data",
/* 12 */ ".mod_init_func",
/* 13 */ ".mod_term_func",
/* 14 */ ".dyld",
/* 15 */ ".cfstring"
};
static const struct known_section known_sections[] =
{
/* 0 */ { NULL, 0},
/* 1 */ { ".cstring", BFD_MACH_O_S_CSTRING_LITERALS }
};
/* Interface for a known non-optional section directive. */
static void
obj_mach_o_known_section (int sect_index)
{
const struct known_section *sect = &known_sections[sect_index];
asection *old_sec;
segT sec;
segT section;
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
old_sec = bfd_get_section_by_name (stdoutput, sect->name);
if (old_sec)
section = obj_mach_o_segT_from_bfd_name (known_sections[sect_index], 1);
if (section != NULL)
subseg_set (section, 0);
/* else, we leave the section as it was; there was a fatal error anyway. */
}
static const char * const objc_sections[] =
{
/* 0 */ NULL,
/* 1 */ ".objc_class",
/* 2 */ ".objc_meta_class",
/* 3 */ ".objc_cat_cls_meth",
/* 4 */ ".objc_cat_inst_meth",
/* 5 */ ".objc_protocol",
/* 6 */ ".objc_string_object",
/* 7 */ ".objc_cls_meth",
/* 8 */ ".objc_inst_meth",
/* 9 */ ".objc_cls_refs",
/* 10 */ ".objc_message_refs",
/* 11 */ ".objc_symbols",
/* 12 */ ".objc_category",
/* 13 */ ".objc_class_vars",
/* 14 */ ".objc_instance_vars",
/* 15 */ ".objc_module_info",
/* 16 */ ".cstring", /* objc_class_names Alias for .cstring */
/* 17 */ ".cstring", /* Alias objc_meth_var_types for .cstring */
/* 18 */ ".cstring", /* objc_meth_var_names Alias for .cstring */
/* 19 */ ".objc_selector_strs",
/* 20 */ ".objc_image_info", /* extension. */
/* 21 */ ".objc_selector_fixup", /* extension. */
/* 22 */ ".objc1_class_ext", /* ObjC-1 extension. */
/* 23 */ ".objc1_property_list", /* ObjC-1 extension. */
/* 24 */ ".objc1_protocol_ext" /* ObjC-1 extension. */
};
/* This currently does the same as known_sections, but kept separate for
ease of maintenance. */
static void
obj_mach_o_objc_section (int sect_index)
{
segT section;
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
section = obj_mach_o_segT_from_bfd_name (objc_sections[sect_index], 1);
if (section != NULL)
{
/* Section already present. */
sec = old_sec;
subseg_set (sec, 0);
seen_objc_section = 1; /* We need to ensure that certain sections are
present and in the right order. */
subseg_set (section, 0);
}
/* else, we leave the section as it was; there was a fatal error anyway. */
}
/* Debug section directives. */
static const char * const debug_sections[] =
{
/* 0 */ NULL,
/* __DWARF */
/* 1 */ ".debug_frame",
/* 2 */ ".debug_info",
/* 3 */ ".debug_abbrev",
/* 4 */ ".debug_aranges",
/* 5 */ ".debug_macinfo",
/* 6 */ ".debug_line",
/* 7 */ ".debug_loc",
/* 8 */ ".debug_pubnames",
/* 9 */ ".debug_pubtypes",
/* 10 */ ".debug_str",
/* 11 */ ".debug_ranges",
/* 12 */ ".debug_macro"
};
/* ??? Maybe these should be conditional on gdwarf-*.
It`s also likely that we will need to be able to set them from the cfi
code. */
static void
obj_mach_o_debug_section (int sect_index)
{
segT section;
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
section = obj_mach_o_segT_from_bfd_name (debug_sections[sect_index], 1);
if (section != NULL)
subseg_set (section, 0);
/* else, we leave the section as it was; there was a fatal error anyway. */
}
/* This could be moved to the tc-xx files, but there is so little dependency
there, that the code might as well be shared. */
struct opt_tgt_sect
{
const char *name;
unsigned x86_val;
unsigned ppc_val;
};
/* The extensions here are for specific sections that are generated by GCC
and Darwin system tools, but don't have directives in the `system as'. */
static const struct opt_tgt_sect tgt_sections[] =
{
/* 0 */ { NULL, 0, 0},
/* 1 */ { ".lazy_symbol_pointer", 0, 0},
/* 2 */ { ".lazy_symbol_pointer2", 0, 0}, /* X86 - extension */
/* 3 */ { ".lazy_symbol_pointer3", 0, 0}, /* X86 - extension */
/* 4 */ { ".non_lazy_symbol_pointer", 0, 0},
/* 5 */ { ".non_lazy_symbol_pointer_x86", 0, 0}, /* X86 - extension */
/* 6 */ { ".symbol_stub", 16, 20},
/* 7 */ { ".symbol_stub1", 0, 16}, /* PPC - extension */
/* 8 */ { ".picsymbol_stub", 26, 36},
/* 9 */ { ".picsymbol_stub1", 0, 32}, /* PPC - extension */
/* 10 */ { ".picsymbol_stub2", 25, 0}, /* X86 - extension */
/* 11 */ { ".picsymbol_stub3", 5, 0}, /* X86 - extension */
};
/* Interface for an optional section directive. */
static void
obj_mach_o_opt_tgt_section (int sect_index)
{
const struct opt_tgt_sect *tgtsct = &tgt_sections[sect_index];
segT section;
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
section = obj_mach_o_segT_from_bfd_name (tgtsct->name, 0);
if (section == NULL)
{
as_bad (_("%s is not used for the selected target"), tgtsct->name);
/* Leave the section as it is. */
}
else
{
bfd_mach_o_section *msect;
sec = subseg_force_new (sect->name, 0);
/* Set default flags. */
msect = bfd_mach_o_get_mach_o_section (sec);
msect->flags = sect->flags;
bfd_mach_o_section *mo_sec = bfd_mach_o_get_mach_o_section (section);
subseg_set (section, 0);
#if defined (TC_I386)
mo_sec->reserved2 = tgtsct->x86_val;
#elif defined (TC_PPC)
mo_sec->reserved2 = tgtsct->ppc_val;
#else
mo_sec->reserved2 = 0;
#endif
}
}
/* Called from read.c:s_comm after we've parsed .comm symbol, size.
Parse a possible alignment value. */
/* We don't necessarily have the three 'base' sections on mach-o.
Normally, we would start up with only the 'text' section defined.
However, even that can be suppressed with (TODO) c/l option "-n".
Thus, we have to be able to create all three sections on-demand. */
static void
obj_mach_o_base_section (int sect_index)
{
segT section;
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
/* We don't support numeric (or any other) qualifications on the
well-known section shorthands. */
demand_empty_rest_of_line ();
switch (sect_index)
{
/* Handle the three sections that are globally known within GAS.
For Mach-O, these are created on demand rather than at startup. */
case 1:
if (text_section == NULL)
text_section = obj_mach_o_segT_from_bfd_name (TEXT_SECTION_NAME, 1);
if (obj_mach_o_is_static)
{
bfd_mach_o_section *mo_sec
= bfd_mach_o_get_mach_o_section (text_section);
mo_sec->flags &= ~BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS;
}
section = text_section;
break;
case 2:
if (data_section == NULL)
data_section = obj_mach_o_segT_from_bfd_name (DATA_SECTION_NAME, 1);
section = data_section;
break;
case 3:
/* ??? maybe this achieves very little, as an addition. */
if (bss_section == NULL)
{
bss_section = obj_mach_o_segT_from_bfd_name (BSS_SECTION_NAME, 1);
seg_info (bss_section)->bss = 1;
}
section = bss_section;
break;
default:
as_fatal (_("internal error: base section index out of range"));
return;
break;
}
subseg_set (section, 0);
}
/* This finishes off parsing a .comm or .lcomm statement, which both can have
an (optional) alignment field. It also allows us to create the bss section
on demand. */
static symbolS *
obj_mach_o_common_parse (int ignore ATTRIBUTE_UNUSED,
symbolS *symbolP, addressT size)
obj_mach_o_common_parse (int is_local, symbolS *symbolP,
addressT size)
{
addressT align = 0;
/* Both comm and lcomm take an optional alignment, as a power
of two between 1 and 15. */
if (*input_line_pointer == ',')
{
/* We expect a power of 2. */
align = parse_align (0);
if (align == (addressT) -1)
return NULL;
if (align > 15)
{
as_warn (_("Alignment (%lu) too large: 15 assumed."),
(unsigned long)align);
align = 15;
}
}
S_SET_VALUE (symbolP, size);
S_SET_EXTERNAL (symbolP);
S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
if (is_local)
{
/* Create the BSS section on demand. */
if (bss_section == NULL)
{
bss_section = obj_mach_o_segT_from_bfd_name (BSS_SECTION_NAME, 1);
seg_info (bss_section)->bss = 1;
}
bss_alloc (symbolP, size, align);
S_CLEAR_EXTERNAL (symbolP);
}
else
{
S_SET_VALUE (symbolP, size);
S_SET_ALIGN (symbolP, align);
S_SET_EXTERNAL (symbolP);
S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
}
symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
@ -285,9 +669,9 @@ obj_mach_o_common_parse (int ignore ATTRIBUTE_UNUSED,
}
static void
obj_mach_o_comm (int ignore ATTRIBUTE_UNUSED)
obj_mach_o_comm (int is_local)
{
s_comm_internal (ignore, obj_mach_o_common_parse);
s_comm_internal (is_local, obj_mach_o_common_parse);
}
static void
@ -297,13 +681,101 @@ obj_mach_o_subsections_via_symbols (int arg ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
/* Dummy function to allow test-code to work while we are working
on things. */
static void
obj_mach_o_placeholder (int arg ATTRIBUTE_UNUSED)
{
ignore_rest_of_line ();
}
const pseudo_typeS mach_o_pseudo_table[] =
{
{ "weak", obj_mach_o_weak, 0},
{ "section", obj_mach_o_section, 0},
{ "cstring", obj_mach_o_known_section, 1},
{ "lcomm", s_lcomm, 1 },
/* Section directives. */
{ "comm", obj_mach_o_comm, 0 },
{ "lcomm", obj_mach_o_comm, 1 },
{ "text", obj_mach_o_base_section, 1},
{ "data", obj_mach_o_base_section, 2},
{ "bss", obj_mach_o_base_section, 3}, /* extension */
{ "const", obj_mach_o_known_section, 1},
{ "static_const", obj_mach_o_known_section, 2},
{ "cstring", obj_mach_o_known_section, 3},
{ "literal4", obj_mach_o_known_section, 4},
{ "literal8", obj_mach_o_known_section, 5},
{ "literal16", obj_mach_o_known_section, 6},
{ "constructor", obj_mach_o_known_section, 7},
{ "destructor", obj_mach_o_known_section, 8},
{ "eh_frame", obj_mach_o_known_section, 9},
{ "const_data", obj_mach_o_known_section, 10},
{ "static_data", obj_mach_o_known_section, 11},
{ "mod_init_func", obj_mach_o_known_section, 12},
{ "mod_term_func", obj_mach_o_known_section, 13},
{ "dyld", obj_mach_o_known_section, 14},
{ "cfstring", obj_mach_o_known_section, 15},
{ "objc_class", obj_mach_o_objc_section, 1},
{ "objc_meta_class", obj_mach_o_objc_section, 2},
{ "objc_cat_cls_meth", obj_mach_o_objc_section, 3},
{ "objc_cat_inst_meth", obj_mach_o_objc_section, 4},
{ "objc_protocol", obj_mach_o_objc_section, 5},
{ "objc_string_object", obj_mach_o_objc_section, 6},
{ "objc_cls_meth", obj_mach_o_objc_section, 7},
{ "objc_inst_meth", obj_mach_o_objc_section, 8},
{ "objc_cls_refs", obj_mach_o_objc_section, 9},
{ "objc_message_refs", obj_mach_o_objc_section, 10},
{ "objc_symbols", obj_mach_o_objc_section, 11},
{ "objc_category", obj_mach_o_objc_section, 12},
{ "objc_class_vars", obj_mach_o_objc_section, 13},
{ "objc_instance_vars", obj_mach_o_objc_section, 14},
{ "objc_module_info", obj_mach_o_objc_section, 15},
{ "objc_class_names", obj_mach_o_objc_section, 16}, /* Alias for .cstring */
{ "objc_meth_var_types", obj_mach_o_objc_section, 17}, /* Alias for .cstring */
{ "objc_meth_var_names", obj_mach_o_objc_section, 18}, /* Alias for .cstring */
{ "objc_selector_strs", obj_mach_o_objc_section, 19},
{ "objc_image_info", obj_mach_o_objc_section, 20}, /* extension. */
{ "objc_selector_fixup", obj_mach_o_objc_section, 21}, /* extension. */
{ "objc1_class_ext", obj_mach_o_objc_section, 22}, /* ObjC-1 extension. */
{ "objc1_property_list", obj_mach_o_objc_section, 23}, /* ObjC-1 extension. */
{ "objc1_protocol_ext", obj_mach_o_objc_section, 24}, /* ObjC-1 extension. */
{ "debug_frame", obj_mach_o_debug_section, 1}, /* extension. */
{ "debug_info", obj_mach_o_debug_section, 2}, /* extension. */
{ "debug_abbrev", obj_mach_o_debug_section, 3}, /* extension. */
{ "debug_aranges", obj_mach_o_debug_section, 4}, /* extension. */
{ "debug_macinfo", obj_mach_o_debug_section, 5}, /* extension. */
{ "debug_line", obj_mach_o_debug_section, 6}, /* extension. */
{ "debug_loc", obj_mach_o_debug_section, 7}, /* extension. */
{ "debug_pubnames", obj_mach_o_debug_section, 8}, /* extension. */
{ "debug_pubtypes", obj_mach_o_debug_section, 9}, /* extension. */
{ "debug_str", obj_mach_o_debug_section, 10}, /* extension. */
{ "debug_ranges", obj_mach_o_debug_section, 11}, /* extension. */
{ "debug_macro", obj_mach_o_debug_section, 12}, /* extension. */
{ "lazy_symbol_pointer", obj_mach_o_opt_tgt_section, 1},
{ "lazy_symbol_pointer2", obj_mach_o_opt_tgt_section, 2}, /* extension. */
{ "lazy_symbol_pointer3", obj_mach_o_opt_tgt_section, 3}, /* extension. */
{ "non_lazy_symbol_pointer", obj_mach_o_opt_tgt_section, 4},
{ "non_lazy_symbol_pointer_x86", obj_mach_o_opt_tgt_section, 5}, /* extension. */
{ "symbol_stub", obj_mach_o_opt_tgt_section, 6},
{ "symbol_stub1", obj_mach_o_opt_tgt_section, 7}, /* extension. */
{ "picsymbol_stub", obj_mach_o_opt_tgt_section, 8}, /* extension. */
{ "picsymbol_stub1", obj_mach_o_opt_tgt_section, 9}, /* extension. */
{ "picsymbol_stub2", obj_mach_o_opt_tgt_section, 4}, /* extension. */
{ "picsymbol_stub3", obj_mach_o_opt_tgt_section, 4}, /* extension. */
{ "section", obj_mach_o_section, 0},
/* Symbol-related. */
{ "indirect_symbol", obj_mach_o_placeholder, 0},
{ "weak_definition", obj_mach_o_placeholder, 0},
{ "private_extern", obj_mach_o_placeholder, 0},
{ "weak", obj_mach_o_weak, 0}, /* extension */
/* File flags. */
{ "subsections_via_symbols", obj_mach_o_subsections_via_symbols, 0 },
{NULL, NULL, 0}

View file

@ -1,5 +1,5 @@
/* Mach-O object file format for gas, the assembler.
Copyright 2009 Free Software Foundation, Inc.
Copyright 2009, 2011 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -18,13 +18,29 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#ifndef _OBJ_MACH_O_H
#define _OBJ_MACH_O_H
/* Tag to validate Mach-O object file format processing */
#define OBJ_MACH_O 1
#include "bfd/mach-o.h"
#include "targ-cpu.h"
#define OUTPUT_FLAVOR bfd_target_mach_o_flavour
/* All our align expressions are power of two. */
#define USE_ALIGN_PTWO
/* Common symbols can carry alignment information. */
#ifndef S_SET_ALIGN
#define S_SET_ALIGN(S,V) do {\
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (S);\
s->n_desc = (s->n_desc & 0xf0ff) | (((V) & 0x0f) << 8);\
} while (0)
#endif
extern const pseudo_typeS mach_o_pseudo_table[];
#ifndef obj_pop_insert
@ -37,3 +53,5 @@ extern const pseudo_typeS mach_o_pseudo_table[];
#define obj_symbol_new_hook(s) {;}
#define EMIT_SECTION_SYMBOLS 0
#endif /* _OBJ_MACH_O_H */

View file

@ -1,3 +1,8 @@
2011-12-14 Iain Sandoe <iains@gcc.gnu.org>
* mach-o/loader.h (bfd_mach_o_section_type): define
BFD_MACH_O_S_ATTR_NONE to 0.
2011-11-07 Richard Henderson <rth@redhat.com>
Merged from transactional-memory.

View file

@ -246,6 +246,9 @@ bfd_mach_o_section_type;
typedef enum bfd_mach_o_section_attribute
{
/* Section has no specified attibutes. */
BFD_MACH_O_S_ATTR_NONE = 0,
/* Section has local relocation entries. */
BFD_MACH_O_S_ATTR_LOC_RELOC = 0x00000100,