This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch mach-o 1/3] section directives needed to support GCC


These patches build on the work done by Tristan (it happened that we were both working on sections at the same time).
.. this is one step further towards support for GCC's output for mach- o...


The first patch implements all the short-hand section directives and other special combinations currently emitted by GCC.
It is entirely local to mach-o


The test-suite additions got this are in patch 2.

The third patch is just to adjust the default sections (which differ for mach-o from those normally created by gas).

cheers
Iain

bfd:

* 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:

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

gas:

* 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.
(OBJ_MACH_O_SET_BACKEND_SECT_DATA): Define.




bfd/mach-o-i386.c | 55 +++
bfd/mach-o-target.c | 3 +-
bfd/mach-o-x86-64.c | 1 +
bfd/mach-o.c | 481 +++++++++++++++++------
bfd/mach-o.h | 52 ++-
gas/config/obj-macho.c | 669 ++++++++++++++++++++++++ ++++-----
gas/config/obj-macho.h | 27 ++-
gas/testsuite/gas/mach-o/comm-1.d | 13 +
gas/testsuite/gas/mach-o/comm-1.s | 12 +
gas/testsuite/gas/mach-o/lcomm-1.s | 2 +-
gas/testsuite/gas/mach-o/mach-o.exp | 4 +-
gas/testsuite/gas/mach-o/sections-1.d | 384 +++++++++++++++++++
gas/testsuite/gas/mach-o/sections-1.s | 87 +++++
gas/testsuite/gas/mach-o/warn-1.s | 4 +-
include/mach-o/loader.h | 3 +
15 files changed, 1548 insertions(+), 249 deletions(-)


diff --git a/bfd/mach-o-i386.c b/bfd/mach-o-i386.c
index 1191560..c5e3884 100644
--- a/bfd/mach-o-i386.c
+++ b/bfd/mach-o-i386.c
@@ -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


diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c
index 29682c9..f22aa18 100644
--- a/bfd/mach-o-target.c
+++ b/bfd/mach-o-target.c
@@ -96,7 +96,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 =
diff --git a/bfd/mach-o-x86-64.c b/bfd/mach-o-x86-64.c
index 2248d97..1bc3bf8 100644
--- a/bfd/mach-o-x86-64.c
+++ b/bfd/mach-o-x86-64.c
@@ -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"
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index a386604..2e45282 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -89,118 +89,310 @@ 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;
-
-  /* List of known sections for the segment.  */
-  const struct mach_o_section_name_xlat *sections;
-};
-
-/* List of known segment names.  */
+/* __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}
+  };

-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;
+  /* 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, 16) == 0)
+	for (sec = seg->sections; sec->mach_o_name; sec++)
+	  if (strncmp (sec->mach_o_name, sectname, 16) == 0)
+	    return sec;

+ /* ... 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)
- {
- const struct mach_o_section_name_xlat *sec;
+ if (strncmp (seg->segname, segname, 16) == 0)
+ for (sec = seg->sections; sec->mach_o_name; sec++)
+ if (strncmp (sec->mach_o_name, sectname, 16) == 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;
-        }
-    }
+  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;

@@ -217,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, 17);
+  memset (section->sectname, 0, 17);

-        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;

@@ -273,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.
@@ -339,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;
}


@@ -1101,6 +1313,11 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
if (strtab == NULL)
return FALSE;


+  /* 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;
@@ -1417,22 +1634,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)
         {
@@ -1574,11 +1791,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)
@@ -1586,21 +1805,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);
@@ -1616,6 +1838,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. */
@@ -3444,6 +3669,7 @@ static 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}
};
@@ -3460,6 +3686,7 @@ static 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}
};


@@ -3507,7 +3734,7 @@ static const bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
{ 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)
@@ -3517,7 +3744,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. */
@@ -4160,6 +4388,7 @@ bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
#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"
diff --git a/bfd/mach-o.h b/bfd/mach-o.h
index f199016..84ed9a1 100644
--- a/bfd/mach-o.h
+++ b/bfd/mach-o.h
@@ -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;
@@ -520,15 +520,6 @@ typedef struct mach_o_data_struct
 bfd_mach_o_data_struct;

/* 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) \
@@ -582,9 +573,44 @@ 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 *);


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_ */
diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 5f1255d..1aa24f7 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -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,13 @@
 #include "write.h"
 #include "mach-o.h"
 #include "mach-o/loader.h"
+#include "obj-macho.h"
+
+/* TODO: Implement "-dynamic"/"-static" command line options.  */
+int is_static;
+
+/* Allow for special re-ordering on output.  */
+int seen_objc_section;

 static void
 obj_mach_o_weak (int ignore ATTRIBUTE_UNUSED)
@@ -53,104 +77,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_warn (_("the %s name '%s' exceeds 16 characters, truncated"),
+ 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;
-
-      /* Parse attributes.  */
-      if (*input_line_pointer == ',')
+      else
+	sectype_given = 1;
+      /* Restore.  */
+      tmpc = p[len];
+
+      /* Parse attributes.
+	 TODO: check validity of attributes for section type.  */
+      if (sectype_given && c == ',')
         {
           do
             {
               int attr;

+ /* Skip initial `,' and subsequent `+'. */
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 ();
-
+ SKIP_WHITESPACE ();
+ p = input_line_pointer;
+ while ((c = *input_line_pointer) != '+'
+ && c != ','
+ && !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';
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 +252,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 +261,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 +298,360 @@ 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;

-static const struct known_section known_sections[] =
- {
- /* 0 */ { NULL, 0},
- /* 1 */ { ".cstring", BFD_MACH_O_S_CSTRING_LITERALS }
- };
+ /* 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 *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"
+};
+
+/* 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
+
+ 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 *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)
+ {
+ 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 *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

- old_sec = bfd_get_section_by_name (stdoutput, sect->name);
- if (old_sec)
+ section = obj_mach_o_segT_from_bfd_name (tgtsct->name, 0);
+ if (section == NULL)
{
- /* Section already present. */
- sec = old_sec;
- subseg_set (sec, 0);
+ as_bad (_("%s is not used for the selected target"), tgtsct- >name);
+ /* Leave the section as it is. */
}
else
{
- bfd_mach_o_section *msect;
+ bfd_mach_o_section *mo_sec =
+ OBJ_MACH_O_GET_BACKEND_SECT_DATA (stdoutput, 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
+ }
+}


-      sec = subseg_force_new (sect->name, 0);
+/* 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.  */

- /* Set default flags. */
- msect = bfd_mach_o_get_mach_o_section (sec);
- msect->flags = sect->flags;
+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 (is_static)
+ {
+ bfd_mach_o_section *mo_sec
+ = OBJ_MACH_O_GET_BACKEND_SECT_DATA (stdoutput, 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);
}


-/* Called from read.c:s_comm after we've parsed .comm symbol, size.
- Parse a possible alignment value. */
-
+/* 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 +659,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 +671,100 @@ 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}
diff --git a/gas/config/obj-macho.h b/gas/config/obj-macho.h
index d7e9bda..1203cd8 100644
--- a/gas/config/obj-macho.h
+++ b/gas/config/obj-macho.h
@@ -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,12 @@ extern const pseudo_typeS mach_o_pseudo_table[];
 #define obj_symbol_new_hook(s)	{;}

#define EMIT_SECTION_SYMBOLS 0
+
+/* Accessor macros for the Mach-O backend data, in case we need to change how
+ this is done. */
+#define OBJ_MACH_O_SET_BACKEND_SECT_DATA(ABFD, BFDSEC, MACHOSEC) \
+ (BFDSEC)->used_by_bfd = (MACHOSEC)
+
+#define OBJ_MACH_O_GET_BACKEND_SECT_DATA(ABFD, BFDSEC) (BFDSEC)- >used_by_bfd
+
+#endif /* _OBJ_MACH_O_H */
diff --git a/include/mach-o/loader.h b/include/mach-o/loader.h
index 357f65e..296782f 100644
--- a/include/mach-o/loader.h
+++ b/include/mach-o/loader.h
@@ -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,




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]