Rebased & reworked: [Patch mach-o 1/3] section directives needed to support GCC

Iain Sandoe developer@sandoe-acoustics.co.uk
Tue Dec 13 13:46:00 GMT 2011


rebased to use objdump -P.
plus changes per your comments (with some specific observations as  
below).

On 13 Dec 2011, at 09:44, Tristan Gingold wrote:
> See enclosing comments,

 >> +     0 entry.  */
 >> +  _bfd_stringtab_add (strtab, "", TRUE, FALSE);
 >> +

 >Ah, yes.  BTW I think that the string is padded to 4 or 8 bytes too.

not for XCode 3.1.4 or 3.2.5 (I don't have XC 4.x yet) -
however, I did notice it should not be emitted unless there is at  
least one symbol - amended.

 >> +          *input_line_pointer = '\0'; /* make a temp string.  */
 >> +	  as_warn (_("the %s name '%s' exceeds 16 characters, truncated"),
 >> +		     msg, namstart);

 >Warning or error ?
thanks, it should be error - to match system tools, amended.

 >> +  /* 10 */ {".picsymbol_stub2", 25, 0}, /* X86 - extension */
 >> +  /* 11 */ {".picsymbol_stub3", 5, 0}, /* X86 - extension  */
 >> +};

 >Should we #if/#endif arch extensions ?

.. as it is, it allows us to make a more specific and User-friendly  
error message than
the generic "Unknown pseudo-op"... but if you would prefer to ifdef -  
I think it should
be in the main table below - or we'll have to keep track of changing  
indices.

 >> static symbolS *

 > Usually we let a blank line between the comment and the  
definition.  There are many occurrences and I am not sure the existing  
code always follow this rule.

I've changed all the occurances in this file, will try to catch others  
as I go.

 > +  { "picsymbol_stub2", obj_mach_o_opt_tgt_section, 4}, /*  
extension.  */
 > +  { "picsymbol_stub3", obj_mach_o_opt_tgt_section, 4}, /*  
extension.  */

#if/#endif arch specific pseudo ?

here if at all - but comment as above.

 >> +  (BFDSEC)->used_by_bfd = (MACHOSEC)
 >> +
 >> +#define OBJ_MACH_O_GET_BACKEND_SECT_DATA(ABFD, BFDSEC) (BFDSEC)- 
 >used_by_bfd

 >Doesn't this duplicate mach-o.h: bfd_mach_o_get_mach_o_section ?

removed.

========

Hopefully, OK now.
cheers
Iain



  bfd/mach-o-i386.c                     |   55 +++
  bfd/mach-o-target.c                   |    3 +-
  bfd/mach-o-x86-64.c                   |    1 +
  bfd/mach-o.c                          |  488 ++++++++++++++++++-------
  bfd/mach-o.h                          |   52 ++-
  gas/config/obj-macho.c                |  676 ++++++++++++++++++++++++ 
++++-----
  gas/config/obj-macho.h                |   20 +-
  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/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 +
  14 files changed, 1553 insertions(+), 247 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 5e12f84..316b7b9 100644
--- a/bfd/mach-o-target.c
+++ b/bfd/mach-o-target.c
@@ -97,7 +97,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 0a614c3..e40fc0e 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -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;
-
-  /* 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, 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;

+  /* ... 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, 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;

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

@@ -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;
-
-        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;
-              }
-          }
-      }
+  memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1);
+  memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1);
+
+  /* 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.  */
@@ -3486,6 +3717,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 d85224e..334b1e5 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;
@@ -527,15 +527,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) \
@@ -588,8 +579,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 *);

  unsigned int bfd_mach_o_section_get_nbr_indirect (bfd *,  
bfd_mach_o_section *);
  unsigned int bfd_mach_o_section_get_entry_size (bfd *,  
bfd_mach_o_section *);
@@ -601,4 +593,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_ */
diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 5f1255d..018f653 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,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))
-    {
-      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 != ',')
+  memset (segname, 0, sizeof(segname));
+  if (collect_16char_name (segname, "segment", 1))
      {
-      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 +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
+
+  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)
+    {
+      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

-  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 = 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
+    }
+}

-      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 (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);
  }

-/* 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 +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}
diff --git a/gas/config/obj-macho.h b/gas/config/obj-macho.h
index d7e9bda..94c1cde 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,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 */
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,




More information about the Binutils mailing list