bfd/
authorTristan Gingold <gingold@adacore.com>
Wed, 14 Dec 2011 10:30:09 +0000 (10:30 +0000)
committerTristan Gingold <gingold@adacore.com>
Wed, 14 Dec 2011 10:30:09 +0000 (10:30 +0000)
2011-12-14  Iain Sandoe  <iains@gcc.gnu.org>

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

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

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

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

* config/obj-macho.c: Add some more top-level comments.
(collect_16char_name): New.
(obj_mach_o_section): Amend to allow syntax compatible with existing system
tools.  Use section translation data when available.
(obj_mach_o_segT_from_bfd_name): New.
(known_sections): Update.
(obj_mach_o_known_section): Use obj_mach_o_segT_from_bfd_name.
(objc_sections): New.
(obj_mach_o_objc_section): New.
(debug_sections): New.
(obj_mach_o_debug_section): New.
(tgt_sections): New.
(obj_mach_o_opt_tgt_section): New.
(obj_mach_o_base_section): New.
(obj_mach_o_common_parse): Update to create BSS on demand and to handle
lcomm optional alignment param.
(obj_mach_o_comm): Update parameter name.
(obj_mach_o_placeholder): New.
(mach_o_pseudo_table): Update for GCC section directives.
* config/obj-macho.h (_OBJ_MACH_O_H): New.
(USE_ALIGN_PTWO): Define.
(S_SET_ALIGN) Define.

bfd/ChangeLog
bfd/mach-o-i386.c
bfd/mach-o-target.c
bfd/mach-o-x86-64.c
bfd/mach-o.c
bfd/mach-o.h
gas/ChangeLog
gas/config/obj-macho.c
gas/config/obj-macho.h
include/ChangeLog
include/mach-o/loader.h

index cf07be2..164f231 100644 (file)
@@ -1,3 +1,44 @@
+2011-12-14  Iain Sandoe  <iains@gcc.gnu.org>
+
+       * mach-o-i386.c (text_section_names_xlat): New table.
+       (data_section_names_xlat): Likewise.
+       (import_section_names_xlat): Likewise.
+       (mach_o_i386_segsec_names_xlat): Likewise.
+       (bfd_mach_o_tgt_seg_table): Use new tables.
+       * mach-o-x86-64.c (bfd_mach_o_tgt_seg_table): Set NULL.
+       * mach-o.c (mach_o_section_name_xlat, mach_o_segment_name_xlat):
+       Move to mach-o.h as   typedefs.
+       (text_section_names_xlat): Update for current GCC usage.
+       (data_section_names_xlat): Likewise.
+       (dwarf_section_names_xlat): Likewise.
+       (objc_section_names_xlat): New table.
+       (segsec_names_xlat): Add objc table.
+       (bfd_mach_o_normalize_section_name):  Replace with...
+       (bfd_mach_o_section_data_for_mach_sect): New.
+       (bfd_mach_o_section_data_for_bfd_name): New.
+       (bfd_mach_o_section_data_for_bfd_name): Update to use additional data.
+       (bfd_mach_o_convert_section_name_to_mach_o): Likewise.
+       (bfd_mach_o_bfd_copy_private_section_data): Implement.
+       (bfd_mach_o_write_symtab): Write a zero-length string as the first entry
+       for compatibility with system tools.
+       (bfd_mach_o_build_commands): Update section alignment info.
+       (bfd_mach_o_new_section_hook): Use translation table data to define
+       default section flags, type, attributes and alignment, when available.
+       (bfd_mach_o_init_section_from_mach_o): Add TODO comment.
+       (bfd_mach_o_section_type_name): Add 'symbol_stubs'.
+       (bfd_mach_o_section_attribute_name): Add 'self_modifying_code'.
+       (bfd_mach_o_get_section_type_from_name): Change "not-found" return
+       value.
+       (bfd_mach_o_tgt_seg_table): Set default NULL.
+       * mach-o.h (bfd_mach_o_segment_command):  Use define for name length.
+       (bfd_mach_o_backend_data): Move until after contents are defined.
+       (bfd_mach_o_normalize_section_name): Remove.
+       (bfd_mach_o_convert_section_name_to_bfd): Declare.
+       (mach_o_section_name_xlat): Declare.
+       (mach_o_segment_name_xlat): Declare.
+       (bfd_mach_o_section_data_for_mach_sect): Declare.
+       (bfd_mach_o_section_data_for_bfd_name): Declare.
+
 2011-12-13  Shinichiro Hamaji  <shinichiro.hamaji@gmail.com>
 
        * dwarf2.c (bfd_dwarf2_cleanup_debug_info): Accept stash as an
index 1191560..c5e3884 100644 (file)
@@ -280,10 +280,65 @@ bfd_mach_o_i386_print_thread (bfd *abfd, bfd_mach_o_thread_flavour *thread,
   return FALSE;
 }
 
+static const mach_o_section_name_xlat text_section_names_xlat[] =
+  {
+    {  ".symbol_stub",                 "__symbol_stub",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_SYMBOL_STUBS,
+       BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
+                                       0},
+    {  ".picsymbol_stub",              "__picsymbol_stub",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_SYMBOL_STUBS,
+       BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
+                                       0},
+    { NULL, NULL, 0, 0, 0, 0}
+  };
+
+static const mach_o_section_name_xlat data_section_names_xlat[] =
+  {
+    /* The first two are recognized by i386, but not emitted for x86 by
+       modern GCC.  */
+    {  ".non_lazy_symbol_pointer",     "__nl_symbol_ptr",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    {  ".lazy_symbol_pointer",         "__la_symbol_ptr",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    {  ".lazy_symbol_pointer2",        "__la_sym_ptr2",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    {  ".lazy_symbol_pointer3",        "__la_sym_ptr3",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    { NULL, NULL, 0, 0, 0, 0}
+  };
+
+static const mach_o_section_name_xlat import_section_names_xlat[] =
+  {
+    {  ".picsymbol_stub3",             "__jump_table",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_SYMBOL_STUBS,
+       BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS 
+       | BFD_MACH_O_S_SELF_MODIFYING_CODE,
+                                       6},
+    {  ".non_lazy_symbol_pointer_x86", "__pointers",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    { NULL, NULL, 0, 0, 0, 0}
+  };
+
+const mach_o_segment_name_xlat mach_o_i386_segsec_names_xlat[] =
+  {
+    { "__TEXT", text_section_names_xlat },
+    { "__DATA", data_section_names_xlat },
+    { "__IMPORT", import_section_names_xlat },
+    { NULL, NULL }
+  };
+
 #define bfd_mach_o_swap_reloc_in bfd_mach_o_i386_swap_reloc_in
 #define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out
 #define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread
 
+#define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat
+
 #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_i386_bfd_reloc_type_lookup 
 #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_i386_bfd_reloc_name_lookup
 
index d92c58b..4d5690e 100644 (file)
@@ -95,7 +95,8 @@ static const bfd_mach_o_backend_data TARGET_NAME_BACKEND =
   TARGET_ARCHITECTURE,
   bfd_mach_o_swap_reloc_in,
   bfd_mach_o_swap_reloc_out,
-  bfd_mach_o_print_thread
+  bfd_mach_o_print_thread,
+  bfd_mach_o_tgt_seg_table
 };
 
 const bfd_target TARGET_NAME =
index 2248d97..1bc3bf8 100644 (file)
@@ -287,6 +287,7 @@ bfd_mach_o_x86_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_x86_64_bfd_reloc_type_lookup
 #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_x86_64_bfd_reloc_name_lookup
 #define bfd_mach_o_print_thread NULL
+#define bfd_mach_o_tgt_seg_table NULL
 
 #define TARGET_NAME            mach_o_x86_64_vec
 #define TARGET_STRING          "mach-o-x86-64"
index 54edd07..c768689 100644 (file)
@@ -87,118 +87,312 @@ bfd_mach_o_wide_p (bfd *abfd)
    names.  Use of canonical names (such as .text or .debug_frame) is required
    by gdb.  */
 
-struct mach_o_section_name_xlat
-{
-  const char *bfd_name;
-  const char *mach_o_name;
-  flagword flags;
-};
-
-static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
+/* __TEXT Segment.  */
+static const mach_o_section_name_xlat text_section_names_xlat[] =
   {
-    { ".debug_frame",    "__debug_frame",    SEC_DEBUGGING },
-    { ".debug_info",     "__debug_info",     SEC_DEBUGGING },
-    { ".debug_abbrev",   "__debug_abbrev",   SEC_DEBUGGING },
-    { ".debug_aranges",  "__debug_aranges",  SEC_DEBUGGING },
-    { ".debug_macinfo",  "__debug_macinfo",  SEC_DEBUGGING },
-    { ".debug_line",     "__debug_line",     SEC_DEBUGGING },
-    { ".debug_loc",      "__debug_loc",      SEC_DEBUGGING },
-    { ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING },
-    { ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING },
-    { ".debug_str",      "__debug_str",      SEC_DEBUGGING },
-    { ".debug_ranges",   "__debug_ranges",   SEC_DEBUGGING },
-    { NULL, NULL, 0}
+    {  ".text",                                "__text",       
+       SEC_CODE | SEC_LOAD,                    BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,    0},
+    {  ".const",                               "__const",
+       SEC_READONLY | SEC_DATA | SEC_LOAD,     BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,                 0},
+    {  ".static_const",                        "__static_const",
+       SEC_READONLY | SEC_DATA | SEC_LOAD,     BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,                 0},
+    {  ".cstring",                             "__cstring",
+       SEC_READONLY | SEC_DATA | SEC_LOAD | SEC_MERGE | SEC_STRINGS,
+                                               BFD_MACH_O_S_CSTRING_LITERALS,
+       BFD_MACH_O_S_ATTR_NONE,                 0},
+    {  ".literal4",                            "__literal4",
+       SEC_READONLY | SEC_DATA | SEC_LOAD,     BFD_MACH_O_S_4BYTE_LITERALS,
+       BFD_MACH_O_S_ATTR_NONE,                 2},
+    {  ".literal8",                            "__literal8",
+       SEC_READONLY | SEC_DATA | SEC_LOAD,     BFD_MACH_O_S_8BYTE_LITERALS,
+       BFD_MACH_O_S_ATTR_NONE,                 3},
+    {  ".literal16",                           "__literal16",
+       SEC_READONLY | SEC_DATA | SEC_LOAD,     BFD_MACH_O_S_16BYTE_LITERALS,
+       BFD_MACH_O_S_ATTR_NONE,                 4},
+    {  ".constructor",                         "__constructor",
+       SEC_CODE | SEC_LOAD,                    BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,                 0},
+    {  ".destructor",                          "__destructor",
+       SEC_CODE | SEC_LOAD,                    BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,                 0},
+    {  ".eh_frame",                            "__eh_frame",
+       SEC_READONLY | SEC_LOAD,                BFD_MACH_O_S_COALESCED,
+       BFD_MACH_O_S_ATTR_LIVE_SUPPORT
+       | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
+       | BFD_MACH_O_S_ATTR_NO_TOC,             3},
+    { NULL, NULL, 0, 0, 0, 0}
   };
 
-static const struct mach_o_section_name_xlat text_section_names_xlat[] =
+/* __DATA Segment.  */
+static const mach_o_section_name_xlat data_section_names_xlat[] =
   {
-    { ".text",     "__text",      SEC_CODE | SEC_LOAD },
-    { ".const",    "__const",     SEC_READONLY | SEC_DATA | SEC_LOAD },
-    { ".cstring",  "__cstring",   SEC_READONLY | SEC_DATA | SEC_LOAD },
-    { ".eh_frame", "__eh_frame",  SEC_READONLY | SEC_LOAD },
-    { NULL, NULL, 0}
+    {  ".data",                        "__data",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,         0},
+    {  ".bss",                         "__bss",
+       SEC_NO_FLAGS,                   BFD_MACH_O_S_ZEROFILL,
+       BFD_MACH_O_S_ATTR_NONE,         0},
+    {  ".const_data",                  "__const",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,         0},
+    {  ".static_data",                 "__static_data",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,         0},
+    {  ".mod_init_func",               "__mod_init_func",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    {  ".mod_term_func",               "__mod_term_func",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    {  ".dyld",                        "__dyld",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,         0},
+    {  ".cfstring",                    "__cfstring",
+       SEC_DATA | SEC_LOAD,            BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_NONE,         2},
+    { NULL, NULL, 0, 0, 0, 0}
   };
 
-static const struct mach_o_section_name_xlat data_section_names_xlat[] =
+/* __DWARF Segment.  */
+static const mach_o_section_name_xlat dwarf_section_names_xlat[] =
   {
-    { ".data",                "__data",          SEC_DATA | SEC_LOAD },
-    { ".const_data",          "__const",         SEC_DATA | SEC_LOAD },
-    { ".dyld",                "__dyld",          SEC_DATA | SEC_LOAD },
-    { ".lazy_symbol_ptr",     "__la_symbol_ptr", SEC_DATA | SEC_LOAD },
-    { ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD },
-    { ".bss",                 "__bss",           SEC_NO_FLAGS },
-    { NULL, NULL, 0}
+    {  ".debug_frame",                 "__debug_frame",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_info",                  "__debug_info",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_abbrev",                "__debug_abbrev",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_aranges",               "__debug_aranges",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_macinfo",               "__debug_macinfo",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_line",                  "__debug_line",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_loc",                   "__debug_loc",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_pubnames",              "__debug_pubnames",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_pubtypes",              "__debug_pubtypes",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_str",                   "__debug_str",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_ranges",                "__debug_ranges",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_macro",                 "__debug_macro",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
+    { NULL, NULL, 0, 0, 0, 0}
   };
 
-struct mach_o_segment_name_xlat
-{
-  /* Segment name.  */
-  const char *segname;
-
-  /* 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.  */
@@ -3518,6 +3749,7 @@ bfd_mach_o_close_and_cleanup (bfd *abfd)
 #define bfd_mach_o_swap_reloc_in NULL
 #define bfd_mach_o_swap_reloc_out NULL
 #define bfd_mach_o_print_thread NULL
+#define bfd_mach_o_tgt_seg_table NULL
 
 #define TARGET_NAME            mach_o_be_vec
 #define TARGET_STRING          "mach-o-be"
index 686bb90..0c6f4fd 100644 (file)
@@ -1,5 +1,5 @@
 /* Mach-O support for BFD.
-   Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009
+   Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2011
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -70,7 +70,7 @@ bfd_mach_o_section;
 
 typedef struct bfd_mach_o_segment_command
 {
-  char segname[16 + 1];
+  char segname[BFD_MACH_O_SEGNAME_SIZE + 1];
   bfd_vma vmaddr;
   bfd_vma vmsize;
   bfd_vma fileoff;
@@ -530,15 +530,6 @@ typedef struct bfd_mach_o_xlat_name
 bfd_mach_o_xlat_name;
 
 /* Target specific routines.  */
-typedef struct bfd_mach_o_backend_data
-{
-  enum bfd_architecture arch;
-  bfd_boolean (*_bfd_mach_o_swap_reloc_in)(arelent *, bfd_mach_o_reloc_info *);
-  bfd_boolean (*_bfd_mach_o_swap_reloc_out)(arelent *, bfd_mach_o_reloc_info *);
-  bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *,
-                                          void *, char *);
-}
-bfd_mach_o_backend_data;
 
 #define bfd_mach_o_get_data(abfd) ((abfd)->tdata.mach_o_data)
 #define bfd_mach_o_get_backend_data(abfd) \
@@ -591,8 +582,9 @@ unsigned int bfd_mach_o_version (bfd *);
 
 unsigned int bfd_mach_o_get_section_type_from_name (const char *);
 unsigned int bfd_mach_o_get_section_attribute_from_name (const char *);
-void bfd_mach_o_normalize_section_name (const char *, const char *,
-                                        const char **, flagword *);
+
+void bfd_mach_o_convert_section_name_to_bfd (bfd *, const char *, const char *,
+                                            const char **, flagword *);
 bfd_boolean bfd_mach_o_find_nearest_line (bfd *, asection *, asymbol **,
                                           bfd_vma, const char **,
                                           const char **, unsigned int *);
@@ -608,4 +600,38 @@ extern const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[];
 
 extern const bfd_target mach_o_fat_vec;
 
+/* Interfaces between BFD names and Mach-O names.  */
+
+typedef struct mach_o_section_name_xlat
+{
+  const char *bfd_name;
+  const char *mach_o_name;
+  flagword bfd_flags;
+  unsigned int macho_sectype;
+  unsigned int macho_secattr;
+  unsigned int sectalign;
+} mach_o_section_name_xlat;
+
+typedef struct mach_o_segment_name_xlat
+{
+  const char *segname;
+  const mach_o_section_name_xlat *sections;
+} mach_o_segment_name_xlat;
+
+const mach_o_section_name_xlat *
+bfd_mach_o_section_data_for_mach_sect (bfd *, const char *, const char *);
+const mach_o_section_name_xlat *
+bfd_mach_o_section_data_for_bfd_name (bfd *, const char *, const char **);
+
+typedef struct bfd_mach_o_backend_data
+{
+  enum bfd_architecture arch;
+  bfd_boolean (*_bfd_mach_o_swap_reloc_in)(arelent *, bfd_mach_o_reloc_info *);
+  bfd_boolean (*_bfd_mach_o_swap_reloc_out)(arelent *, bfd_mach_o_reloc_info *);
+  bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *,
+                                          void *, char *);
+  const mach_o_segment_name_xlat *segsec_names_xlat;
+}
+bfd_mach_o_backend_data;
+
 #endif /* _BFD_MACH_O_H_ */
index 6bf4355..e6b1666 100644 (file)
@@ -1,3 +1,28 @@
+2011-12-14  Iain Sandoe  <iains@gcc.gnu.org>
+
+       * config/obj-macho.c: Add some more top-level comments.
+       (collect_16char_name): New.
+       (obj_mach_o_section): Amend to allow syntax compatible with
+       existing system tools.  Use section translation data when available.
+       (obj_mach_o_segT_from_bfd_name): New.
+       (known_sections): Update.
+       (obj_mach_o_known_section): Use obj_mach_o_segT_from_bfd_name.
+       (objc_sections): New.
+       (obj_mach_o_objc_section): New.
+       (debug_sections): New.
+       (obj_mach_o_debug_section): New.
+       (tgt_sections): New.
+       (obj_mach_o_opt_tgt_section): New.
+       (obj_mach_o_base_section): New.
+       (obj_mach_o_common_parse): Update to create BSS on demand and to handle
+       lcomm optional alignment param.
+       (obj_mach_o_comm): Update parameter name.
+       (obj_mach_o_placeholder): New.
+       (mach_o_pseudo_table): Update for GCC section directives.
+       * config/obj-macho.h (_OBJ_MACH_O_H): New.
+       (USE_ALIGN_PTWO): Define.
+       (S_SET_ALIGN) Define.
+
 2011-12-13  Andrew Burgess  <aburgess@broadcom.com>
 
        * doc/internals.texi (TC_FORCE_RELOCATION_SUB_SAME): Update
index 5f1255d..018f653 100644 (file)
@@ -1,5 +1,5 @@
 /* Mach-O object file format
-   Copyright 2009 Free Software Foundation, Inc.
+   Copyright 2009, 2011 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    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"
 #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}
index d7e9bda..94c1cde 100644 (file)
@@ -1,5 +1,5 @@
 /* Mach-O object file format for gas, the assembler.
-   Copyright 2009 Free Software Foundation, Inc.
+   Copyright 2009, 2011 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    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 */
index 01854a4..cd5895d 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-14  Iain Sandoe  <iains@gcc.gnu.org>
+
+       * mach-o/loader.h (bfd_mach_o_section_type): define
+       BFD_MACH_O_S_ATTR_NONE to 0.
+
 2011-11-07  Richard Henderson  <rth@redhat.com>
 
        Merged from transactional-memory.
index 357f65e..296782f 100644 (file)
@@ -246,6 +246,9 @@ bfd_mach_o_section_type;
 
 typedef enum bfd_mach_o_section_attribute
 {
+  /* Section has no specified attibutes.  */
+  BFD_MACH_O_S_ATTR_NONE              = 0,
+
   /* Section has local relocation entries.  */
   BFD_MACH_O_S_ATTR_LOC_RELOC         = 0x00000100,