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


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

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


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,



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