/* Mach-O object file format
   Copyright (C) 2009-2016 Free Software Foundation, Inc.

   This file is part of GAS, the GNU Assembler.

   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 3,
   or (at your option) any later version.

   GAS is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
   the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to the Free
   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 "subsegs.h"
#include "symbols.h"
#include "write.h"
#include "mach-o.h"
#include "mach-o/loader.h"
#include "obj-macho.h"

#include <string.h>

/* Forward decls.  */
static segT obj_mach_o_segT_from_bfd_name (const char *, int);

/* TODO: Implement "-dynamic"/"-static" command line options.  */

static int obj_mach_o_is_static;

/* TODO: Implement the "-n" command line option to suppress the initial
   switch to the text segment.  */

static int obj_mach_o_start_with_text_section = 1;

/* Allow for special re-ordering on output.  */

static int obj_mach_o_seen_objc_section;

/* Start-up: At present, just create the sections we want.  */
void
mach_o_begin (void)
{
  /* Mach-O only defines the .text section by default, and even this can
     be suppressed by a flag.  In the latter event, the first code MUST
     be a section definition.  */
  if (obj_mach_o_start_with_text_section)
    {
      text_section = obj_mach_o_segT_from_bfd_name (TEXT_SECTION_NAME, 1);
      subseg_set (text_section, 0);
      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;
	}
    }
}

/* Remember the subsections_by_symbols state in case we need to reset
   the file flags.  */

static int obj_mach_o_subsections_by_symbols;

/* 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;
}

static int
obj_mach_o_get_section_names (char *seg, char *sec,
			      unsigned segl, unsigned secl)
{
  /* Zero-length segment and section names are allowed.  */
  /* Parse segment name.  */
  memset (seg, 0, segl);
  if (collect_16char_name (seg, "segment", 1))
    {
      ignore_rest_of_line ();
      return 0;
    }
  input_line_pointer++; /* Skip the terminating ',' */

  /* Parse section name, which can be empty.  */
  memset (sec, 0, secl);
  collect_16char_name (sec, "section", 0);
  return 1;
}

/* Build (or get) a section from the mach-o description - which includes
   optional definitions for type, attributes, alignment and stub size.

   BFD supplies default values for sections which have a canonical name.  */

#define SECT_TYPE_SPECIFIED 0x0001
#define SECT_ATTR_SPECIFIED 0x0002
#define SECT_ALGN_SPECIFIED 0x0004
#define SECT_STUB_SPECIFIED 0x0008

static segT
obj_mach_o_make_or_get_sect (char * segname, char * sectname,
			     unsigned int specified_mask,
			     unsigned int usectype, unsigned int usecattr,
			     unsigned int ualign, offsetT stub_size)
{
  unsigned int sectype, secattr, secalign;
  flagword oldflags, flags;
  const char *name;
  segT sec;
  bfd_mach_o_section *msect;
  const mach_o_section_name_xlat *xlat;

  /* 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);

  /* TODO: more checking of whether overides are acually allowed.  */

  if (xlat != NULL)
    {
      name = xstrdup (xlat->bfd_name);
      sectype = xlat->macho_sectype;
      if (specified_mask & SECT_TYPE_SPECIFIED)
	{
	  if ((sectype == BFD_MACH_O_S_ZEROFILL
	       || sectype == BFD_MACH_O_S_GB_ZEROFILL)
	      && sectype != usectype)
	    as_bad (_("cannot overide zerofill section type for `%s,%s'"),
		    segname, sectname);
	  else
	    sectype = usectype;
	}
      secattr = xlat->macho_secattr;
      secalign = xlat->sectalign;
      flags = xlat->bfd_flags;
    }
  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
         on disk.  */
      name = concat (segname, ".", sectname, (char *) NULL);
      if (specified_mask & SECT_TYPE_SPECIFIED)
	sectype = usectype;
      else
	sectype = BFD_MACH_O_S_REGULAR;
      secattr = BFD_MACH_O_S_ATTR_NONE;
      secalign = 0;
      flags = SEC_NO_FLAGS;
    }

  /* For now, just use what the user provided.  */

  if (specified_mask & SECT_ATTR_SPECIFIED)
    secattr = usecattr;

  if (specified_mask & SECT_ALGN_SPECIFIED)
    secalign = ualign;

  /* Sub-segments don't exists as is on Mach-O.  */
  sec = subseg_new (name, 0);

  oldflags = bfd_get_section_flags (stdoutput, sec);
  msect = bfd_mach_o_get_mach_o_section (sec);

  if (oldflags == SEC_NO_FLAGS)
    {
      /* In the absence of canonical information, try to determine CODE and
	 DEBUG section flags from the mach-o section data.  */
      if (flags == SEC_NO_FLAGS
	  && (specified_mask & SECT_ATTR_SPECIFIED)
	  && (secattr & BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS))
	flags |= SEC_CODE;

      if (flags == SEC_NO_FLAGS
	  && (specified_mask & SECT_ATTR_SPECIFIED)
	  && (secattr & BFD_MACH_O_S_ATTR_DEBUG))
	flags |= SEC_DEBUGGING;

      /* New, so just use the defaults or what's specified.  */
      if (! bfd_set_section_flags (stdoutput, sec, flags))
	as_warn (_("failed to set flags for \"%s\": %s"),
		 bfd_section_name (stdoutput, sec),
		 bfd_errmsg (bfd_get_error ()));

      strncpy (msect->segname, segname, sizeof (msect->segname));
      strncpy (msect->sectname, sectname, sizeof (msect->sectname));

      msect->align = secalign;
      msect->flags = sectype | secattr;

      if (sectype == BFD_MACH_O_S_ZEROFILL
	  || sectype == BFD_MACH_O_S_GB_ZEROFILL)
        seg_info (sec)->bss = 1;
    }
  else if (flags != SEC_NO_FLAGS)
    {
      if (flags != oldflags
	  || msect->flags != (secattr | sectype))
	as_warn (_("Ignoring changed section attributes for %s"), name);
    }

  if (specified_mask & SECT_STUB_SPECIFIED)
    /* At present, the stub size is not supplied from the BFD tables.  */
    msect->reserved2 = stub_size;

  return sec;
}

/* .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)
{
  unsigned int sectype = BFD_MACH_O_S_REGULAR;
  unsigned int specified_mask = 0;
  unsigned int secattr = 0;
  offsetT sizeof_stub = 0;
  segT new_seg;
  char segname[17];
  char sectname[17];

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  /* Get the User's segment annd section names.  */
  if (! obj_mach_o_get_section_names (segname, sectname, 17, 17))
    return;

  /* Parse section type, if present.  */
  if (*input_line_pointer == ',')
    {
      char *p;
      char c;
      char tmpc;
      int len;
      input_line_pointer++;
      SKIP_WHITESPACE ();
      p = input_line_pointer;
      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 (stdoutput, p);
      if (sectype > 255) /* Max Section ID == 255.  */
        {
          as_bad (_("unknown or invalid section type '%s'"), p);
	  p[len] = tmpc;
	  ignore_rest_of_line ();
	  return;
        }
      else
	specified_mask |= SECT_TYPE_SPECIFIED;
      /* Restore.  */
      p[len] = tmpc;

      /* Parse attributes.
	 TODO: check validity of attributes for section type.  */
      if ((specified_mask & SECT_TYPE_SPECIFIED)
	  && c == ',')
        {
          do
            {
              int attr;

	      /* Skip initial `,' and subsequent `+'.  */
              input_line_pointer++;
	      SKIP_WHITESPACE ();
	      p = input_line_pointer;
	      while ((c = *input_line_pointer) != '+'
		      && c != ','
		      && !is_end_of_line[(unsigned char) c])
		input_line_pointer++;

	      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)
		{
                  as_bad (_("unknown or invalid section attribute '%s'"), p);
		  p[len] = tmpc;
		  ignore_rest_of_line ();
		  return;
                }
              else
		{
		  specified_mask |= SECT_ATTR_SPECIFIED;
                  secattr |= attr;
		}
	      /* Restore.  */
	      p[len] = tmpc;
            }
          while (*input_line_pointer == '+');

          /* Parse sizeof_stub.  */
          if ((specified_mask & SECT_ATTR_SPECIFIED)
	      && *input_line_pointer == ',')
            {
              if (sectype != BFD_MACH_O_S_SYMBOL_STUBS)
                {
		  as_bad (_("unexpected section size information"));
		  ignore_rest_of_line ();
		  return;
		}

	      input_line_pointer++;
              sizeof_stub = get_absolute_expression ();
              specified_mask |= SECT_STUB_SPECIFIED;
            }
          else if ((specified_mask & SECT_ATTR_SPECIFIED)
		   && sectype == BFD_MACH_O_S_SYMBOL_STUBS)
            {
              as_bad (_("missing sizeof_stub expression"));
	      ignore_rest_of_line ();
	      return;
            }
        }
    }

  new_seg = obj_mach_o_make_or_get_sect (segname, sectname, specified_mask,
					 sectype, secattr, 0 /*align */,
					 sizeof_stub);
  if (new_seg != NULL)
    {
      subseg_set (new_seg, 0);
      demand_empty_rest_of_line ();
    }
}

/* .zerofill segname, sectname [, symbolname, size [, align]]

   Zerofill switches, temporarily, to a sect of type 'zerofill'.

   If a variable name is given, it defines that in the section.
   Otherwise it just creates the section if it doesn't exist.  */

static void
obj_mach_o_zerofill (int ignore ATTRIBUTE_UNUSED)
{
  char segname[17];
  char sectname[17];
  segT old_seg = now_seg;
  segT new_seg;
  symbolS *sym = NULL;
  unsigned int align = 0;
  unsigned int specified_mask = 0;
  offsetT size = 0;

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  /* Get the User's segment annd section names.  */
  if (! obj_mach_o_get_section_names (segname, sectname, 17, 17))
    return;

  /* Parse variable definition, if present.  */
  if (*input_line_pointer == ',')
    {
      /* Parse symbol, size [.align]
         We follow the method of s_common_internal, with the difference
         that the symbol cannot be a duplicate-common.  */
      char *name;
      char c;
      char *p;
      expressionS exp;

      input_line_pointer++; /* Skip ',' */
      SKIP_WHITESPACE ();
      c = get_symbol_name (&name);
      /* Just after name is now '\0'.  */
      p = input_line_pointer;
      *p = c;

      if (name == p)
	{
	  as_bad (_("expected symbol name"));
	  ignore_rest_of_line ();
	  goto done;
	}

      SKIP_WHITESPACE_AFTER_NAME ();
      if (*input_line_pointer == ',')
	input_line_pointer++;

      expression_and_evaluate (&exp);
      if (exp.X_op != O_constant
	  && exp.X_op != O_absent)
	{
	    as_bad (_("bad or irreducible absolute expression"));
	  ignore_rest_of_line ();
	  goto done;
	}
      else if (exp.X_op == O_absent)
	{
	  as_bad (_("missing size expression"));
	  ignore_rest_of_line ();
	  goto done;
	}

      size = exp.X_add_number;
      size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
      if (exp.X_add_number != size || !exp.X_unsigned)
	{
	  as_warn (_("size (%ld) out of range, ignored"),
		   (long) exp.X_add_number);
	  ignore_rest_of_line ();
	  goto done;
	}

     *p = 0; /* Make the name into a c string for err messages.  */
     sym = symbol_find_or_make (name);
     if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
	{
	  as_bad (_("symbol `%s' is already defined"), name);
	  *p = c;
	  ignore_rest_of_line ();
	   goto done;
	}

      size = S_GET_VALUE (sym);
      if (size == 0)
	size = exp.X_add_number;
      else if (size != exp.X_add_number)
	as_warn (_("size of \"%s\" is already %ld; not changing to %ld"),
		   name, (long) size, (long) exp.X_add_number);

      *p = c;  /* Restore the termination char.  */

      SKIP_WHITESPACE ();
      if (*input_line_pointer == ',')
	{
	  align = (unsigned int) parse_align (0);
	  if (align == (unsigned int) -1)
	    {
	      as_warn (_("align value not recognized, using size"));
	      align = size;
	    }
	  if (align > 15)
	    {
	      as_warn (_("Alignment (%lu) too large: 15 assumed."),
			(unsigned long)align);
	      align = 15;
	    }
	  specified_mask |= SECT_ALGN_SPECIFIED;
	}
    }
 /* else just a section definition.  */

  specified_mask |= SECT_TYPE_SPECIFIED;
  new_seg = obj_mach_o_make_or_get_sect (segname, sectname, specified_mask,
					 BFD_MACH_O_S_ZEROFILL,
					 BFD_MACH_O_S_ATTR_NONE,
					 align, (offsetT) 0 /*stub size*/);
  if (new_seg == NULL)
    return;

  /* In case the user specifies the bss section by mach-o name.
     Create it on demand */
  if (strcmp (new_seg->name, BSS_SECTION_NAME) == 0
      && bss_section == NULL)
    bss_section = new_seg;

  subseg_set (new_seg, 0);

  if (sym != NULL)
    {
      char *pfrag;

      if (align)
	{
	  record_alignment (new_seg, align);
	  frag_align (align, 0, 0);
	}

      /* Detach from old frag.  */
      if (S_GET_SEGMENT (sym) == new_seg)
	symbol_get_frag (sym)->fr_symbol = NULL;

      symbol_set_frag (sym, frag_now);
      pfrag = frag_var (rs_org, 1, 1, 0, sym, size, NULL);
      *pfrag = 0;

      S_SET_SEGMENT (sym, new_seg);
      if (new_seg == bss_section)
	S_CLEAR_EXTERNAL (sym);
    }

done:
  /* switch back to the section that was current before the .zerofill.  */
  subseg_set (old_seg, 0);
}

static segT
obj_mach_o_segT_from_bfd_name (const char *nam, int must_succeed)
{
  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"
};

/* Interface for a known non-optional section directive.  */

static void
obj_mach_o_known_section (int sect_index)
{
  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)
    {
      obj_mach_o_seen_objc_section = 1; /* We need to ensure that certain
					   sections are present and in the
					   right order.  */
      subseg_set (section, 0);
    }

  /* else, we leave the section as it was; there was a fatal error anyway.  */
}

/* Debug section directives.  */

static const char * const debug_sections[] =
{
  /*  0 */ NULL,
  /* __DWARF */
  /*  1 */ ".debug_frame",
  /*  2 */ ".debug_info",
  /*  3 */ ".debug_abbrev",
  /*  4 */ ".debug_aranges",
  /*  5 */ ".debug_macinfo",
  /*  6 */ ".debug_line",
  /*  7 */ ".debug_loc",
  /*  8 */ ".debug_pubnames",
  /*  9 */ ".debug_pubtypes",
  /* 10 */ ".debug_str",
  /* 11 */ ".debug_ranges",
  /* 12 */ ".debug_macro"
};

/* ??? Maybe these should be conditional on gdwarf-*.
   It`s also likely that we will need to be able to set them from the cfi
   code.  */

static void
obj_mach_o_debug_section (int sect_index)
{
  segT section;

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  section = obj_mach_o_segT_from_bfd_name (debug_sections[sect_index], 1);
  if (section != NULL)
    subseg_set (section, 0);

  /* else, we leave the section as it was; there was a fatal error anyway.  */
}

/* This could be moved to the tc-xx files, but there is so little dependency
   there, that the code might as well be shared.  */

struct opt_tgt_sect
{
 const char *name;
 unsigned x86_val;
 unsigned ppc_val;
};

/* The extensions here are for specific sections that are generated by GCC
   and Darwin system tools, but don't have directives in the `system as'.  */

static const struct opt_tgt_sect tgt_sections[] =
{
  /*  0 */ { NULL, 0, 0},
  /*  1 */ { ".lazy_symbol_pointer", 0, 0},
  /*  2 */ { ".lazy_symbol_pointer2", 0, 0}, /* X86 - extension */
  /*  3 */ { ".lazy_symbol_pointer3", 0, 0}, /* X86 - extension */
  /*  4 */ { ".non_lazy_symbol_pointer", 0, 0},
  /*  5 */ { ".non_lazy_symbol_pointer_x86", 0, 0}, /* X86 - extension */
  /*  6 */ { ".symbol_stub", 16, 20},
  /*  7 */ { ".symbol_stub1", 0, 16}, /* PPC - extension */
  /*  8 */ { ".picsymbol_stub", 26, 36},
  /*  9 */ { ".picsymbol_stub1", 0, 32}, /* PPC - extension */
  /* 10 */ { ".picsymbol_stub2", 25, 0}, /* X86 - extension */
  /* 11 */ { ".picsymbol_stub3", 5, 0}, /* X86 - extension  */
};

/* Interface for an optional section directive.  */

static void
obj_mach_o_opt_tgt_section (int sect_index)
{
  const struct opt_tgt_sect *tgtsct = &tgt_sections[sect_index];
  segT section;

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  section = obj_mach_o_segT_from_bfd_name (tgtsct->name, 0);
  if (section == NULL)
    {
      as_bad (_("%s is not used for the selected target"), tgtsct->name);
      /* Leave the section as it is.  */
    }
  else
    {
      bfd_mach_o_section *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
    }
}

/* We don't necessarily have the three 'base' sections on mach-o.
   Normally, we would start up with only the 'text' section defined.
   However, even that can be suppressed with (TODO) c/l option "-n".
   Thus, we have to be able to create all three sections on-demand.  */

static void
obj_mach_o_base_section (int sect_index)
{
  segT section;

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  /* We don't support numeric (or any other) qualifications on the
     well-known section shorthands.  */
  demand_empty_rest_of_line ();

  switch (sect_index)
    {
      /* Handle the three sections that are globally known within GAS.
	 For Mach-O, these are created on demand rather than at startup.  */
      case 1:
	if (text_section == NULL)
	  text_section = obj_mach_o_segT_from_bfd_name (TEXT_SECTION_NAME, 1);
	if (obj_mach_o_is_static)
	  {
	    bfd_mach_o_section *mo_sec
		= bfd_mach_o_get_mach_o_section (text_section);
	    mo_sec->flags &= ~BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS;
	  }
	section = text_section;
	break;
      case 2:
	if (data_section == NULL)
	  data_section = obj_mach_o_segT_from_bfd_name (DATA_SECTION_NAME, 1);
	section = data_section;
	break;
      case 3:
        /* ??? maybe this achieves very little, as an addition.  */
	if (bss_section == NULL)
	  {
	    bss_section = obj_mach_o_segT_from_bfd_name (BSS_SECTION_NAME, 1);
	    seg_info (bss_section)->bss = 1;
	  }
	section = bss_section;
	break;
      default:
        as_fatal (_("internal error: base section index out of range"));
        return;
	break;
    }
  subseg_set (section, 0);
}

/* This finishes off parsing a .comm or .lcomm statement, which both can have
   an (optional) alignment field.  It also allows us to create the bss section
   on demand.  */

static symbolS *
obj_mach_o_common_parse (int is_local, symbolS *symbolP,
			 addressT size)
{
  addressT align = 0;
  bfd_mach_o_asymbol *s;

  SKIP_WHITESPACE ();

  /* 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 = (bfd_mach_o_asymbol *) symbol_get_bfdsym (symbolP);
  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->n_type = BFD_MACH_O_N_SECT;
      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);
      s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
    }

  /* This is a data object (whatever we choose that to mean).  */
  s->symbol.flags |= BSF_OBJECT;

  /* We've set symbol qualifiers, so validate if you can.  */
  s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;

  return symbolP;
}

static void
obj_mach_o_comm (int is_local)
{
  s_comm_internal (is_local, obj_mach_o_common_parse);
}

/* Set properties that apply to the whole file.  At present, the only
   one defined, is subsections_via_symbols.  */

typedef enum obj_mach_o_file_properties {
  OBJ_MACH_O_FILE_PROP_NONE = 0,
  OBJ_MACH_O_FILE_PROP_SUBSECTS_VIA_SYMS,
  OBJ_MACH_O_FILE_PROP_MAX
} obj_mach_o_file_properties;

static void
obj_mach_o_fileprop (int prop)
{
  if (prop < 0 || prop >= OBJ_MACH_O_FILE_PROP_MAX)
    as_fatal (_("internal error: bad file property ID %d"), prop);

  switch ((obj_mach_o_file_properties) prop)
    {
      case OBJ_MACH_O_FILE_PROP_SUBSECTS_VIA_SYMS:
        obj_mach_o_subsections_by_symbols = 1;
	if (!bfd_set_private_flags (stdoutput,
				    BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS))
	  as_bad (_("failed to set subsections by symbols"));
	demand_empty_rest_of_line ();
	break;
      default:
	break;
    }
}

/* Temporary markers for symbol reference data.
   Lazy will remain in place.  */
#define LAZY 0x01
#define REFE 0x02

/* We have a bunch of qualifiers that may be applied to symbols.
   .globl is handled here so that we might make sure that conflicting qualifiers
   are caught where possible.  */

typedef enum obj_mach_o_symbol_type {
  OBJ_MACH_O_SYM_UNK = 0,
  OBJ_MACH_O_SYM_LOCAL = 1,
  OBJ_MACH_O_SYM_GLOBL = 2,
  OBJ_MACH_O_SYM_REFERENCE = 3,
  OBJ_MACH_O_SYM_WEAK_REF = 4,
  OBJ_MACH_O_SYM_LAZY_REF = 5,
  OBJ_MACH_O_SYM_WEAK_DEF = 6,
  OBJ_MACH_O_SYM_PRIV_EXT = 7,
  OBJ_MACH_O_SYM_NO_DEAD_STRIP = 8,
  OBJ_MACH_O_SYM_WEAK = 9
} obj_mach_o_symbol_type;

/* Set Mach-O-specific symbol qualifiers. */

static int
obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
{
  int is_defined;
  bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sym);
  bfd_mach_o_section *sec;
  int sectype = -1;

  /* If the symbol is defined, then we can do more rigorous checking on
     the validity of the qualifiers.  Otherwise, we are stuck with waiting
     until it's defined - or until write the file.

     In certain cases (e.g. when a symbol qualifier is intended to introduce
     an undefined symbol in a stubs section) we should check that the current
     section is appropriate to the qualifier.  */

  is_defined = s->symbol.section != bfd_und_section_ptr;
  if (is_defined)
    sec = bfd_mach_o_get_mach_o_section (s->symbol.section) ;
  else
    sec = bfd_mach_o_get_mach_o_section (now_seg) ;

  if (sec != NULL)
    sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;

  switch ((obj_mach_o_symbol_type) type)
    {
      case OBJ_MACH_O_SYM_LOCAL:
	/* This is an extension over the system tools.  */
        if (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
	  {
	    as_bad (_("'%s' previously declared as '%s'."), s->symbol.name,
		      (s->n_type & BFD_MACH_O_N_PEXT) ? "private extern"
						      : "global" );
	    s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
	    return 1;
	  }
	else
	  {
	    s->n_type &= ~BFD_MACH_O_N_EXT;
	    S_CLEAR_EXTERNAL (sym);
	  }
	break;

      case OBJ_MACH_O_SYM_PRIV_EXT:
	s->n_type |= BFD_MACH_O_N_PEXT ;
	s->n_desc &= ~LAZY; /* The native tool switches this off too.  */
	/* We follow the system tools in marking PEXT as also global.  */
	/* Fall through.  */

      case OBJ_MACH_O_SYM_GLOBL:
	/* It's not an error to define a symbol and then make it global.  */
	s->n_type |= BFD_MACH_O_N_EXT;
	S_SET_EXTERNAL (sym);
	break;

      case OBJ_MACH_O_SYM_REFERENCE:
        if (is_defined)
          s->n_desc |= BFD_MACH_O_N_NO_DEAD_STRIP;
        else
          s->n_desc |= (REFE | BFD_MACH_O_N_NO_DEAD_STRIP);
	break;

      case OBJ_MACH_O_SYM_LAZY_REF:
        if (is_defined)
          s->n_desc |= BFD_MACH_O_N_NO_DEAD_STRIP;
        else
          s->n_desc |= (REFE | LAZY | BFD_MACH_O_N_NO_DEAD_STRIP);
	break;

      /* Force ld to retain the symbol - even if it appears unused.  */
      case OBJ_MACH_O_SYM_NO_DEAD_STRIP:
	s->n_desc |= BFD_MACH_O_N_NO_DEAD_STRIP ;
	break;

      /* Mach-O's idea of weak ...  */
      case OBJ_MACH_O_SYM_WEAK_REF:
	s->n_desc |= BFD_MACH_O_N_WEAK_REF ;
	break;

      case OBJ_MACH_O_SYM_WEAK_DEF:
	if (is_defined && sectype != BFD_MACH_O_S_COALESCED)
	  {
	    as_bad (_("'%s' can't be a weak_definition (currently only"
		      " supported in sections of type coalesced)"),
		      s->symbol.name);
	    s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
	    return 1;
	  }
	else
	  s->n_desc |= BFD_MACH_O_N_WEAK_DEF;
	break;

      case OBJ_MACH_O_SYM_WEAK:
        /* A generic 'weak' - we try to figure out what it means at
	   symbol frob time.  */
	S_SET_WEAK (sym);
	break;

      default:
	break;
    }

    /* We've seen some kind of qualifier - check validity if or when the entity
     is defined.  */
  s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
  return 0;
}

/* Respond to symbol qualifiers.
   All of the form:
   .<qualifier> symbol [, symbol]*
   a list of symbols is an extension over the Darwin system as.  */

static void
obj_mach_o_sym_qual (int ntype)
{
  char *name;
  char c;
  symbolS *symbolP;

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  do
    {
      c = get_symbol_name (&name);
      symbolP = symbol_find_or_make (name);
      obj_mach_o_set_symbol_qualifier (symbolP, ntype);
      *input_line_pointer = c;
      SKIP_WHITESPACE_AFTER_NAME ();
      c = *input_line_pointer;
      if (c == ',')
	{
	  input_line_pointer++;
	  SKIP_WHITESPACE ();
	  if (is_end_of_line[(unsigned char) *input_line_pointer])
	    c = '\n';
	}
    }
  while (c == ',');

  demand_empty_rest_of_line ();
}

typedef struct obj_mach_o_indirect_sym
{
  symbolS *sym;
  segT sect;
  struct obj_mach_o_indirect_sym *next;
} obj_mach_o_indirect_sym;

/* We store in order an maintain a pointer to the last one - to save reversing
   later.  */
obj_mach_o_indirect_sym *indirect_syms;
obj_mach_o_indirect_sym *indirect_syms_tail;

static void
obj_mach_o_indirect_symbol (int arg ATTRIBUTE_UNUSED)
{
  bfd_mach_o_section *sec = bfd_mach_o_get_mach_o_section (now_seg);

#ifdef md_flush_pending_output
  md_flush_pending_output ();
#endif

  if (obj_mach_o_is_static)
    as_bad (_("use of .indirect_symbols requires `-dynamic'"));

  switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
    {
      case BFD_MACH_O_S_SYMBOL_STUBS:
      case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
      case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
        {
          obj_mach_o_indirect_sym *isym;
	  char *name;
	  char c = get_symbol_name (&name);
	  symbolS *sym = symbol_find_or_make (name);
	  unsigned int elsize =
			bfd_mach_o_section_get_entry_size (stdoutput, sec);

	  if (elsize == 0)
	    {
	      as_bad (_("attempt to add an indirect_symbol to a stub or"
			" reference section with a zero-sized element at %s"),
			name);
	      (void) restore_line_pointer (c);
	      ignore_rest_of_line ();
	      return;
	    }
	  (void) restore_line_pointer (c);

	  /* The indirect symbols are validated after the symbol table is
	     frozen, we must make sure that if a local symbol is used as an
	     indirect, it is promoted to a 'real' one.  Fetching the bfd sym
	     achieves this.  */
	  symbol_get_bfdsym (sym);
	  isym = XNEW (obj_mach_o_indirect_sym);

	  /* Just record the data for now, we will validate it when we
	     compute the output in obj_mach_o_set_indirect_symbols.  */
	  isym->sym = sym;
	  isym->sect = now_seg;
	  isym->next = NULL;
	  if (indirect_syms == NULL)
	    indirect_syms = isym;
	  else
	    indirect_syms_tail->next = isym;
	  indirect_syms_tail = isym;
	}
        break;

      default:
	as_bad (_("an .indirect_symbol must be in a symbol pointer"
		  " or stub section."));
	ignore_rest_of_line ();
	return;
    }
  demand_empty_rest_of_line ();
}

const pseudo_typeS mach_o_pseudo_table[] =
{
  /* 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},
  { "zerofill", obj_mach_o_zerofill, 0},

  /* Symbol qualifiers.  */
  {"local",		obj_mach_o_sym_qual, OBJ_MACH_O_SYM_LOCAL},
  {"globl",		obj_mach_o_sym_qual, OBJ_MACH_O_SYM_GLOBL},
  {"reference",		obj_mach_o_sym_qual, OBJ_MACH_O_SYM_REFERENCE},
  {"weak_reference",	obj_mach_o_sym_qual, OBJ_MACH_O_SYM_WEAK_REF},
  {"lazy_reference",	obj_mach_o_sym_qual, OBJ_MACH_O_SYM_LAZY_REF},
  {"weak_definition",	obj_mach_o_sym_qual, OBJ_MACH_O_SYM_WEAK_DEF},
  {"private_extern",	obj_mach_o_sym_qual, OBJ_MACH_O_SYM_PRIV_EXT},
  {"no_dead_strip",	obj_mach_o_sym_qual, OBJ_MACH_O_SYM_NO_DEAD_STRIP},
  {"weak",		obj_mach_o_sym_qual, OBJ_MACH_O_SYM_WEAK}, /* ext */

  { "indirect_symbol",	obj_mach_o_indirect_symbol, 0},

  /* File flags.  */
  { "subsections_via_symbols", obj_mach_o_fileprop,
			       OBJ_MACH_O_FILE_PROP_SUBSECTS_VIA_SYMS},

  {NULL, NULL, 0}
};

/* Determine the default n_type value for a symbol from its section.  */

static unsigned
obj_mach_o_type_for_symbol (bfd_mach_o_asymbol *s)
{
  if (s->symbol.section == bfd_abs_section_ptr)
    return BFD_MACH_O_N_ABS;
  else if (s->symbol.section == bfd_com_section_ptr
	   || s->symbol.section == bfd_und_section_ptr)
    return BFD_MACH_O_N_UNDF;
  else
    return BFD_MACH_O_N_SECT;
}

void
obj_mach_o_frob_colon (const char *name)
{
  if (!bfd_is_local_label_name (stdoutput, name))
    {
      /* A non-local label will create a new subsection, so start a new
         frag.  */
      frag_wane (frag_now);
      frag_new (0);
    }
}

/* We need to check the correspondence between some kinds of symbols and their
   sections.  Common and BSS vars will seen via the obj_macho_comm() function.

   The earlier we can pick up a problem, the better the diagnostics will be.

   However, when symbol type information is attached, the symbol section will
   quite possibly be unknown.  So we are stuck with checking (most of the)
   validity at the time the file is written (unfortunately, then one doesn't
   get line number information in the diagnostic).  */

/* Here we pick up the case where symbol qualifiers have been applied that
   are possibly incompatible with the section etc. that the symbol is defined
   in.  */

void obj_mach_o_frob_label (struct symbol *sp)
{
  bfd_mach_o_asymbol *s;
  unsigned base_type;
  bfd_mach_o_section *sec;
  int sectype = -1;

  if (!bfd_is_local_label_name (stdoutput, S_GET_NAME (sp)))
    {
      /* If this is a non-local label, it should have started a new sub-
	 section.  */
      gas_assert (frag_now->obj_frag_data.subsection == NULL);
      frag_now->obj_frag_data.subsection = sp;
    }

  /* Leave local symbols alone.  */

  if (S_IS_LOCAL (sp))
    return;

  s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sp);
  /* Leave debug symbols alone.  */
  if ((s->n_type & BFD_MACH_O_N_STAB) != 0)
    return;

  /* This is the base symbol type, that we mask in.  */
  base_type = obj_mach_o_type_for_symbol (s);

  sec = bfd_mach_o_get_mach_o_section (s->symbol.section);
  if (sec != NULL)
    sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;

  /* If there is a pre-existing qualifier, we can make some checks about
     validity now.  */

  if(s->symbol.udata.i == SYM_MACHO_FIELDS_NOT_VALIDATED)
    {
      if ((s->n_desc & BFD_MACH_O_N_WEAK_DEF)
	  && sectype != BFD_MACH_O_S_COALESCED)
	{
	  as_bad (_("'%s' can't be a weak_definition (currently only supported"
		    " in sections of type coalesced)"), s->symbol.name);
	  /* Don't cascade errors.  */
	  s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
	}

      /* Have we changed from an undefined to defined ref? */
      s->n_desc &= ~(REFE | LAZY);
    }

  s->n_type &= ~BFD_MACH_O_N_TYPE;
  s->n_type |= base_type;
}

/* This is the fall-back, we come here when we get to the end of the file and
   the symbol is not defined - or there are combinations of qualifiers required
   (e.g. global + weak_def).  */

int
obj_mach_o_frob_symbol (struct symbol *sp)
{
  bfd_mach_o_asymbol *s;
  unsigned base_type;
  bfd_mach_o_section *sec;
  int sectype = -1;

  /* Leave local symbols alone.  */
  if (S_IS_LOCAL (sp))
    return 0;

  s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sp);
  /* Leave debug symbols alone.  */
  if ((s->n_type & BFD_MACH_O_N_STAB) != 0)
    return 0;

  base_type = obj_mach_o_type_for_symbol (s);
  sec = bfd_mach_o_get_mach_o_section (s->symbol.section);
  if (sec != NULL)
    sectype = sec->flags & BFD_MACH_O_SECTION_TYPE_MASK;

  if (s->symbol.section == bfd_und_section_ptr)
    {
      /* ??? Do we really gain much from implementing this as well as the
	 mach-o specific ones?  */
      if (s->symbol.flags & BSF_WEAK)
	s->n_desc |= BFD_MACH_O_N_WEAK_REF;

      /* Undefined syms, become extern.  */
      s->n_type |= BFD_MACH_O_N_EXT;
      S_SET_EXTERNAL (sp);
    }
  else if (s->symbol.section == bfd_com_section_ptr)
    {
      /* ... so do comm.  */
      s->n_type |= BFD_MACH_O_N_EXT;
      S_SET_EXTERNAL (sp);
    }
  else
    {
      if ((s->symbol.flags & BSF_WEAK)
	   && (sectype == BFD_MACH_O_S_COALESCED)
	   && (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
	s->n_desc |= BFD_MACH_O_N_WEAK_DEF;
/* ??? we should do this - but then that reveals that the semantics of weak
       are different from what's supported in mach-o object files.
      else
	as_bad (_("'%s' can't be a weak_definition."),
		s->symbol.name); */
    }

  if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET)
    {
      /* Anything here that should be added that is non-standard.  */
      s->n_desc &= ~BFD_MACH_O_REFERENCE_MASK;
    }
  else if (s->symbol.udata.i == SYM_MACHO_FIELDS_NOT_VALIDATED)
    {
      /* Try to validate any combinations.  */
      if (s->n_desc & BFD_MACH_O_N_WEAK_DEF)
	{
	  if (s->symbol.section == bfd_und_section_ptr)
	    as_bad (_("'%s' can't be a weak_definition (since it is"
		      " undefined)"), s->symbol.name);
	  else if (sectype != BFD_MACH_O_S_COALESCED)
	    as_bad (_("'%s' can't be a weak_definition (currently only supported"
		      " in sections of type coalesced)"), s->symbol.name);
	  else if (! (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
	    as_bad (_("Non-global symbol: '%s' can't be a weak_definition."),
		    s->symbol.name);
	}

    }
  else
    as_bad (_("internal error: [%s] unexpected code [%lx] in frob symbol"),
	    s->symbol.name, (unsigned long)s->symbol.udata.i);

  s->n_type &= ~BFD_MACH_O_N_TYPE;
  s->n_type |= base_type;

  if (s->symbol.flags & BSF_GLOBAL)
    s->n_type |= BFD_MACH_O_N_EXT;

  /* This cuts both ways - we promote some things to external above.  */
  if (s->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
    S_SET_EXTERNAL (sp);

  return 0;
}

/* Support stabs for mach-o.  */

void
obj_mach_o_process_stab (int what, const char *string,
			 int type, int other, int desc)
{
  symbolS *symbolP;
  bfd_mach_o_asymbol *s;

  switch (what)
    {
      case 'd':
	symbolP = symbol_new ("", now_seg, frag_now_fix (), frag_now);
	/* Special stabd NULL name indicator.  */
	S_SET_NAME (symbolP, NULL);
	break;

      case 'n':
      case 's':
	symbolP = symbol_new (string, undefined_section, (valueT) 0,
			      &zero_address_frag);
	pseudo_set (symbolP);
	break;

      default:
	as_bad(_("unrecognized stab type '%c'"), (char)what);
	abort ();
	break;
    }

  s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (symbolP);
  s->n_type = type;
  s->n_desc = desc;
  /* For stabd, this will eventually get overwritten by the section number.  */
  s->n_sect = other;

  /* It's a debug symbol.  */
  s->symbol.flags |= BSF_DEBUGGING;

  /* We've set it - so check it, if you can, but don't try to create the
     flags.  */
  s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
}

/* This is a place to check for any errors that we can't detect until we know
   what remains undefined at the end of assembly.  */

static void
obj_mach_o_check_before_writing (bfd *abfd ATTRIBUTE_UNUSED,
				 asection *sec,
				 void *unused ATTRIBUTE_UNUSED)
{
  fixS *fixP;
  struct frchain *frchp;
  segment_info_type *seginfo = seg_info (sec);

  if (seginfo == NULL)
    return;

  /* We are not allowed subtractions where either of the operands is
     undefined.  So look through the frags for any fixes to check.  */
  for (frchp = seginfo->frchainP; frchp != NULL; frchp = frchp->frch_next)
   for (fixP = frchp->fix_root; fixP != NULL; fixP = fixP->fx_next)
    {
      if (fixP->fx_addsy != NULL
	  && fixP->fx_subsy != NULL
	  && (! S_IS_DEFINED (fixP->fx_addsy)
	      || ! S_IS_DEFINED (fixP->fx_subsy)))
	{
	  segT add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy);
	  segT sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy);

	  if (! S_IS_DEFINED (fixP->fx_addsy)
	      && S_IS_DEFINED (fixP->fx_subsy))
	    {
	      as_bad_where (fixP->fx_file, fixP->fx_line,
		_("`%s' can't be undefined in `%s' - `%s' {%s section}"),
		S_GET_NAME (fixP->fx_addsy), S_GET_NAME (fixP->fx_addsy),
		S_GET_NAME (fixP->fx_subsy), segment_name (sub_symbol_segment));
	    }
	  else if (! S_IS_DEFINED (fixP->fx_subsy)
		   && S_IS_DEFINED (fixP->fx_addsy))
	    {
	      as_bad_where (fixP->fx_file, fixP->fx_line,
		_("`%s' can't be undefined in `%s' {%s section} - `%s'"),
		S_GET_NAME (fixP->fx_subsy), S_GET_NAME (fixP->fx_addsy),
		segment_name (add_symbol_segment), S_GET_NAME (fixP->fx_subsy));
	    }
	  else
	    {
	      as_bad_where (fixP->fx_file, fixP->fx_line,
		_("`%s' and `%s' can't be undefined in `%s' - `%s'"),
		S_GET_NAME (fixP->fx_addsy), S_GET_NAME (fixP->fx_subsy),
		S_GET_NAME (fixP->fx_addsy), S_GET_NAME (fixP->fx_subsy));
	    }
	}
    }
}

/* Do any checks that we can't complete without knowing what's undefined.  */
void
obj_mach_o_pre_output_hook (void)
{
  bfd_map_over_sections (stdoutput, obj_mach_o_check_before_writing, (char *) 0);
}

/* Here we count up frags in each subsection (where a sub-section is defined
   as starting with a non-local symbol).
   Note that, if there are no non-local symbols in a section, all the frags will
   be attached as one anonymous subsection.  */

static void
obj_mach_o_set_subsections (bfd *abfd ATTRIBUTE_UNUSED,
                            asection *sec,
                            void *unused ATTRIBUTE_UNUSED)
{
  segment_info_type *seginfo = seg_info (sec);
  symbolS *cur_subsection = NULL;
  struct obj_mach_o_symbol_data *cur_subsection_data = NULL;
  fragS *frag;
  frchainS *chain;

  /* Protect against sections not created by gas.  */
  if (seginfo == NULL)
    return;

  /* Attach every frag to a subsection.  */
  for (chain = seginfo->frchainP; chain != NULL; chain = chain->frch_next)
    for (frag = chain->frch_root; frag != NULL; frag = frag->fr_next)
      {
        if (frag->obj_frag_data.subsection == NULL)
          frag->obj_frag_data.subsection = cur_subsection;
        else
          {
            cur_subsection = frag->obj_frag_data.subsection;
            cur_subsection_data = symbol_get_obj (cur_subsection);
            cur_subsection_data->subsection_size = 0;
          }
        if (cur_subsection_data != NULL)
          {
            /* Update subsection size.  */
            cur_subsection_data->subsection_size += frag->fr_fix;
          }
      }
}

/* Handle mach-o subsections-via-symbols counting up frags belonging to each
   sub-section.  */

void
obj_mach_o_pre_relax_hook (void)
{
  bfd_map_over_sections (stdoutput, obj_mach_o_set_subsections, (char *) 0);
}

/* Zerofill and GB Zerofill sections must be sorted to follow all other
   sections in their segments.

   The native 'as' leaves the sections physically in the order they appear in
   the source, and adjusts the section VMAs to meet the constraint.

   We follow this for now - if nothing else, it makes comparison easier.

   An alternative implementation would be to sort the sections as ld requires.
   It might be advantageous to implement such a scheme in the future (or even
   to make the style of section ordering user-selectable).  */

typedef struct obj_mach_o_set_vma_data
{
  bfd_vma vma;
  unsigned vma_pass;
  unsigned zerofill_seen;
  unsigned gb_zerofill_seen;
} obj_mach_o_set_vma_data;

/* We do (possibly) three passes through to set the vma, so that:

   zerofill sections get VMAs after all others in their segment
   GB zerofill get VMAs last.

   As we go, we notice if we see any Zerofill or GB Zerofill sections, so that
   we can skip the additional passes if there's nothing to do.  */

static void
obj_mach_o_set_section_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *v_p)
{
  bfd_mach_o_section *ms = bfd_mach_o_get_mach_o_section (sec);
  unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
  obj_mach_o_set_vma_data *p = (struct obj_mach_o_set_vma_data *)v_p;
  unsigned sectype = (ms->flags & BFD_MACH_O_SECTION_TYPE_MASK);
  unsigned zf;

  zf = 0;
  if (sectype == BFD_MACH_O_S_ZEROFILL)
    {
      zf = 1;
      p->zerofill_seen = zf;
    }
  else if (sectype == BFD_MACH_O_S_GB_ZEROFILL)
    {
      zf = 2;
      p->gb_zerofill_seen = zf;
    }

  if (p->vma_pass != zf)
    return;

  /* We know the section size now - so make a vma for the section just
     based on order.  */
  ms->size = bfd_get_section_size (sec);

  /* Make sure that the align agrees, and set to the largest value chosen.  */
  ms->align = ms->align > bfd_align ? ms->align : bfd_align;
  bfd_set_section_alignment (abfd, sec, ms->align);

  p->vma += (1 << ms->align) - 1;
  p->vma &= ~((1 << ms->align) - 1);
  ms->addr = p->vma;
  bfd_set_section_vma (abfd, sec, p->vma);
  p->vma += ms->size;
}

/* (potentially) three passes over the sections, setting VMA.  We skip the
  {gb}zerofill passes if we didn't see any of the relevant sections.  */

void obj_mach_o_post_relax_hook (void)
{
  obj_mach_o_set_vma_data d;

  memset (&d, 0, sizeof (d));

  bfd_map_over_sections (stdoutput, obj_mach_o_set_section_vma, (char *) &d);
  if ((d.vma_pass = d.zerofill_seen) != 0)
    bfd_map_over_sections (stdoutput, obj_mach_o_set_section_vma, (char *) &d);
  if ((d.vma_pass = d.gb_zerofill_seen) != 0)
    bfd_map_over_sections (stdoutput, obj_mach_o_set_section_vma, (char *) &d);
}

static void
obj_mach_o_set_indirect_symbols (bfd *abfd, asection *sec,
				 void *xxx ATTRIBUTE_UNUSED)
{
  bfd_vma sect_size = bfd_section_size (abfd, sec);
  bfd_mach_o_section *ms = bfd_mach_o_get_mach_o_section (sec);
  unsigned lazy = 0;

  /* See if we have any indirect syms to consider.  */
  if (indirect_syms == NULL)
    return;

  /* Process indirect symbols.
     Check for errors, if OK attach them as a flat array to the section
     for which they are defined.  */

  switch (ms->flags & BFD_MACH_O_SECTION_TYPE_MASK)
    {
      case BFD_MACH_O_S_SYMBOL_STUBS:
      case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
	lazy = LAZY;
	/* Fall through.  */
      case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
	{
	  unsigned int nactual = 0;
	  unsigned int ncalc;
	  obj_mach_o_indirect_sym *isym;
	  obj_mach_o_indirect_sym *list = NULL;
	  obj_mach_o_indirect_sym *list_tail = NULL;
	  unsigned long eltsiz =
			bfd_mach_o_section_get_entry_size (abfd, ms);

	  for (isym = indirect_syms; isym != NULL; isym = isym->next)
	    {
	      if (isym->sect == sec)
		{
		  nactual++;
		  if (list == NULL)
		    list = isym;
		  else
		    list_tail->next = isym;
		  list_tail = isym;
		}
	    }

	  /* If none are in this section, stop here.  */
	  if (nactual == 0)
	    break;

	  /* If we somehow added indirect symbols to a section with a zero
	     entry size, we're dead ... */
	  gas_assert (eltsiz != 0);

	  ncalc = (unsigned int) (sect_size / eltsiz);
	  if (nactual != ncalc)
	    as_bad (_("the number of .indirect_symbols defined in section %s"
		      " does not match the number expected (%d defined, %d"
		      " expected)"), sec->name, nactual, ncalc);
	  else
	    {
	      unsigned n;
	      bfd_mach_o_asymbol *sym;
	      ms->indirect_syms =
			bfd_zalloc (abfd,
				    nactual * sizeof (bfd_mach_o_asymbol *));

	      if (ms->indirect_syms == NULL)
		{
		  as_fatal (_("internal error: failed to allocate %d indirect"
			      "symbol pointers"), nactual);
		}

	      for (isym = list, n = 0; isym != NULL; isym = isym->next, n++)
		{
		  sym = (bfd_mach_o_asymbol *)symbol_get_bfdsym (isym->sym);
		  /* Array is init to NULL & NULL signals a local symbol
		     If the section is lazy-bound, we need to keep the
		     reference to the symbol, since dyld can override.

		     Absolute symbols are handled specially.  */
		  if (sym->symbol.section == bfd_abs_section_ptr)
		    ms->indirect_syms[n] = sym;
		  else if (S_IS_LOCAL (isym->sym) && ! lazy)
		    ;
		  else
		    {
		      if (sym == NULL)
		        ;
		      /* If the symbols is external ...  */
		      else if (S_IS_EXTERNAL (isym->sym)
			       || (sym->n_type & BFD_MACH_O_N_EXT)
			       || ! S_IS_DEFINED (isym->sym)
			       || lazy)
			{
			  sym->n_desc &= ~LAZY;
			  /* ... it can be lazy, if not defined or hidden.  */
			  if ((sym->n_type & BFD_MACH_O_N_TYPE)
			       == BFD_MACH_O_N_UNDF
			      && ! (sym->n_type & BFD_MACH_O_N_PEXT)
			      && (sym->n_type & BFD_MACH_O_N_EXT))
			    sym->n_desc |= lazy;
			  ms->indirect_syms[n] = sym;
		        }
		    }
		}
	    }
	}
	break;

      default:
	break;
    }
}

/* The process of relocation could alter what's externally visible, thus we
   leave setting the indirect symbols until last.  */

void
obj_mach_o_frob_file_after_relocs (void)
{
  bfd_map_over_sections (stdoutput, obj_mach_o_set_indirect_symbols, (char *) 0);
}

/* Reverse relocations order to make ld happy.  */

void
obj_mach_o_reorder_section_relocs (asection *sec, arelent **rels, unsigned int n)
{
  unsigned int i;
  unsigned int max = n / 2;

  for (i = 0; i < max; i++)
    {
      arelent *r = rels[i];
      rels[i] = rels[n - i - 1];
      rels[n - i - 1] = r;
    }
  bfd_set_reloc (stdoutput, sec, rels, n);
}

/* Relocation rules are different in frame sections.  */

static int
obj_mach_o_is_frame_section (segT sec)
{
  int l;
  l = strlen (segment_name (sec));
  if ((l == 9 && strncmp (".eh_frame", segment_name (sec), 9) == 0)
       || (l == 12 && strncmp (".debug_frame", segment_name (sec), 12) == 0))
    return 1;
  return 0;
}

/* Unless we're in a frame section, we need to force relocs to be generated for
   local subtractions.  We might eliminate them later (if they are within the
   same sub-section) but we don't know that at the point that this decision is
   being made.  */

int
obj_mach_o_allow_local_subtract (expressionS * left ATTRIBUTE_UNUSED,
				 expressionS * right ATTRIBUTE_UNUSED,
				 segT seg)
{
  /* Don't interfere if it's one of the GAS internal sections.  */
  if (! SEG_NORMAL (seg))
    return 1;

  /* Allow in frame sections, otherwise emit a reloc.  */
  return obj_mach_o_is_frame_section (seg);
}

int
obj_mach_o_in_different_subsection (symbolS *a, symbolS *b)
{
  fragS *fa;
  fragS *fb;

  if (S_GET_SEGMENT (a) != S_GET_SEGMENT (b)
      || !S_IS_DEFINED (a)
      || !S_IS_DEFINED (b))
    {
      /* Not in the same segment, or undefined symbol.  */
      return 1;
    }

  fa = symbol_get_frag (a);
  fb = symbol_get_frag (b);
  if (fa == NULL || fb == NULL)
    {
      /* One of the symbols is not in a subsection.  */
      return 1;
    }

  return fa->obj_frag_data.subsection != fb->obj_frag_data.subsection;
}

int
obj_mach_o_force_reloc_sub_same (fixS *fix, segT seg)
{
  if (! SEG_NORMAL (seg))
    return 1;
  return obj_mach_o_in_different_subsection (fix->fx_addsy, fix->fx_subsy);
}

int
obj_mach_o_force_reloc_sub_local (fixS *fix, segT seg ATTRIBUTE_UNUSED)
{
  return obj_mach_o_in_different_subsection (fix->fx_addsy, fix->fx_subsy);
}

int
obj_mach_o_force_reloc (fixS *fix)
{
  if (generic_force_reloc (fix))
    return 1;

  /* Force a reloc if the target is not in the same subsection.
     FIXME: handle (a - b) where a and b belongs to the same subsection ?  */
  if (fix->fx_addsy != NULL)
    {
      symbolS *subsec = fix->fx_frag->obj_frag_data.subsection;
      symbolS *targ = fix->fx_addsy;

      /* There might be no subsections at all.  */
      if (subsec == NULL)
        return 0;

      if (S_GET_SEGMENT (targ) == absolute_section)
        return 0;

      return obj_mach_o_in_different_subsection (targ, subsec);
    }
  return 0;
}
