/* Functions for generic Darwin as target machine for GNU C compiler.
   Copyright (C) 1989-2022 Free Software Foundation, Inc.
   Contributed by Apple Computer Inc.

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "attribs.h"
#include "insn-config.h"
#include "emit-rtl.h"
#include "cgraph.h"
#include "lto-streamer.h"
#include "output.h"
#include "varasm.h"
#include "stor-layout.h"
#include "explow.h"
#include "expr.h"
#include "langhooks.h"
#include "targhooks.h"
#include "toplev.h"
#include "lto-section-names.h"
#include "intl.h"
#include "optabs.h"
#include "flags.h"
#include "opts.h"

/* Fix and Continue.

   NOTES:
   1) this facility requires suitable support from a modified version
   of GDB, which is not provided on any system after MacOS 10.7/Darwin11.
   2) There is no support for this in any X86 version of the FSF compiler.

   Fix and continue was used on some earlier MacOS systems for rapid turn
   around debugging.  When code is compiled with the -mfix-and-continue
   flag, two changes are made to the generated code that allow the system
   to do things that it would normally not be able to do easily.  These
   changes allow gdb to load in recompilation of a translation unit that
   has been changed into a running program and replace existing functions
   and methods of that translation unit with versions of those functions
   and methods from the newly compiled translation unit.  The new functions
   access the existing static symbols from the old translation unit, if the
   symbol existed in the unit to be replaced, and from the new translation
   unit, otherwise.

   The changes are to insert 5 nops at the beginning of all functions
   and to use indirection to get at static symbols.  The 5 nops
   are required by consumers of the generated code.  Currently, gdb
   uses this to patch in a jump to the overriding function, this
   allows all uses of the old name to forward to the replacement,
   including existing function pointers and virtual methods.  See
   rs6000_emit_prologue for the code that handles the nop insertions.

   The added indirection allows gdb to redirect accesses to static
   symbols from the newly loaded translation unit to the existing
   symbol, if any.  @code{static} symbols are special and are handled by
   setting the second word in the .non_lazy_symbol_pointer data
   structure to symbol.  See indirect_data for the code that handles
   the extra indirection, and machopic_output_indirection and its use
   of MACHO_SYMBOL_FLAG_STATIC for the code that handles @code{static}
   symbol indirection.  */

typedef struct GTY(()) cdtor_record {
  rtx symbol;
  int priority;		/* [con/de]structor priority */
  int position;		/* original position */
} cdtor_record;

static GTY(()) vec<cdtor_record, va_gc> *ctors = NULL;
static GTY(()) vec<cdtor_record, va_gc> *dtors = NULL;

/* A flag to determine whether we are running c++ or obj-c++.  This has to be
   settable from non-c-family contexts too (i.e. we can't use the c_dialect_
   functions).  */
int darwin_running_cxx;

/* Some code-gen now depends on OS major version numbers (at least).  */
int generating_for_darwin_version ;

/* For older linkers we need to emit special sections (marked 'coalesced') for
   for weak or single-definition items.  */
static bool ld_uses_coal_sects = false;

/* Very old (ld_classic) linkers need a symbol to mark the start of
   each FDE.  */
static bool ld_needs_eh_markers = false;

/* Emit a section-start symbol for mod init and term sections.  */
static bool ld_init_term_start_labels = false;

/* Section names.  */
section * darwin_sections[NUM_DARWIN_SECTIONS];

/* While we transition to using in-tests instead of ifdef'd code.  */
#if !HAVE_lo_sum
#define gen_macho_high(m,a,b) (a)
#define gen_macho_low(m,a,b,c) (a)
#endif

/* True if we're setting __attribute__ ((ms_struct)).  */
int darwin_ms_struct = false;

/* Earlier versions of Darwin as do not recognize an alignment field in
   .comm directives, this should be set for versions that allow it.  */
int emit_aligned_common = false;

/* A get_unnamed_section callback used to switch to an ObjC section.
   DIRECTIVE is as for output_section_asm_op.  */

static void
output_objc_section_asm_op (const char *directive)
{
  static bool been_here = false;

  /* The NeXT ObjC Runtime requires these sections to be present and in
     order in the object.  The code below implements this by emitting
     a section header for each ObjC section the first time that an ObjC
     section is requested.  */
  if (darwin_symbol_stubs && ! been_here)
    {
      section *saved_in_section = in_section;
      static const enum darwin_section_enum tomark[] =
	{
	  /* written, cold -> hot */
	  objc_cat_cls_meth_section,
	  objc_cat_inst_meth_section,
	  objc_string_object_section,
	  objc_constant_string_object_section,
	  objc_selector_refs_section,
	  objc_selector_fixup_section,
	  objc_cls_refs_section,
	  objc_class_section,
	  objc_meta_class_section,
	  /* shared, hot -> cold */
	  objc_cls_meth_section,
	  objc_inst_meth_section,
	  objc_protocol_section,
	  objc_class_names_section,
	  objc_meth_var_types_section,
	  objc_meth_var_names_section,
	  objc_category_section,
	  objc_class_vars_section,
	  objc_instance_vars_section,
	  objc_module_info_section,
	  objc_symbols_section,
	};
      /* ABI=1 */
      static const enum darwin_section_enum tomarkv1[] =
	{
	  objc1_protocol_ext_section,
	  objc1_class_ext_section,
	  objc1_prop_list_section
	} ;
      /* ABI=2 */
      static const enum darwin_section_enum tomarkv2[] =
	{
	  objc2_method_names_section,
	  objc2_message_refs_section,
	  objc2_selector_refs_section,
	  objc2_ivar_section,
	  objc2_classdefs_section,
	  objc2_metadata_section,
	  objc2_classrefs_section,
	  objc2_class_names_section,
	  objc2_classlist_section,
	  objc2_categorylist_section,
	  objc2_nonlazy_class_section,
	  objc2_nonlazy_category_section,
	  objc2_protocollist_section,
	  objc2_protocolrefs_section,
	  objc2_super_classrefs_section,
	  objc2_constant_string_object_section,
	  objc2_image_info_section,
	} ;
      size_t i;

      been_here = true;
      if (flag_objc_abi < 2)
	{
	  for (i = 0; i < ARRAY_SIZE (tomark); i++)
	    switch_to_section (darwin_sections[tomark[i]]);
	  if (flag_objc_abi == 1)
	    for (i = 0; i < ARRAY_SIZE (tomarkv1); i++)
	      switch_to_section (darwin_sections[tomarkv1[i]]);
	}
      else
	for (i = 0; i < ARRAY_SIZE (tomarkv2); i++)
	  switch_to_section (darwin_sections[tomarkv2[i]]);
      /* Make sure we don't get varasm.cc out of sync with us.  */
      switch_to_section (saved_in_section);
    }
  output_section_asm_op (directive);
}


/* Private flag applied to disable section-anchors in a particular section.  */
#define SECTION_NO_ANCHOR SECTION_MACH_DEP


/* Implement TARGET_ASM_INIT_SECTIONS.  */

void
darwin_init_sections (void)
{
#define DEF_SECTION(NAME, FLAGS, DIRECTIVE, OBJC)		\
  darwin_sections[NAME] =					\
    get_unnamed_section (FLAGS, (OBJC				\
				 ? output_objc_section_asm_op	\
				 : output_section_asm_op),	\
			 "\t" DIRECTIVE);
#include "config/darwin-sections.def"
#undef DEF_SECTION

  readonly_data_section = darwin_sections[const_section];
  exception_section = darwin_sections[darwin_exception_section];
  eh_frame_section = darwin_sections[darwin_eh_frame_section];

  /* If our linker is new enough to coalesce weak symbols, then we
     can just put picbase_thunks into the text section.  */
  if (! ld_uses_coal_sects )
    darwin_sections[picbase_thunk_section] = text_section;
}

int
name_needs_quotes (const char *name)
{
  int c;
  while ((c = *name++) != '\0')
    if (! ISIDNUM (c)
	  && c != '.' && c != '$' && c != '_' )
      return 1;
  return 0;
}

/* Return true if SYM_REF can be used without an indirection.  */
int
machopic_symbol_defined_p (rtx sym_ref)
{
  if (MACHO_SYMBOL_DEFINED_P (sym_ref))
    return true;

  /* If a symbol references local and is not an extern to this
     file, then the symbol might be able to declared as defined.  */
  if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
    {
      /* If the symbol references a variable and the variable is a
	 common symbol, then this symbol is not defined.  */
      if (MACHO_SYMBOL_VARIABLE_P (sym_ref))
	{
	  tree decl = SYMBOL_REF_DECL (sym_ref);
	  if (!decl)
	    return true;
	  if (DECL_COMMON (decl))
	    return false;
	}
      return true;
    }
  return false;
}

/* This module assumes that (const (symbol_ref "foo")) is a legal pic
   reference, which will not be changed.  */

enum machopic_addr_class
machopic_classify_symbol (rtx sym_ref)
{
  bool function_p;

  function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
  if (machopic_symbol_defined_p (sym_ref))
    return (function_p
	    ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
  else
    return (function_p
	    ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
}

#ifndef TARGET_FIX_AND_CONTINUE
#define TARGET_FIX_AND_CONTINUE 0
#endif

/* Indicate when fix-and-continue style code generation is being used
   and when a reference to data should be indirected so that it can be
   rebound in a new translation unit to reference the original instance
   of that data.  Symbol names that are for code generation local to
   the translation unit are bound to the new translation unit;
   currently this means symbols that begin with L or _OBJC_;
   otherwise, we indicate that an indirect reference should be made to
   permit the runtime to rebind new instances of the translation unit
   to the original instance of the data.  */

static int
indirect_data (rtx sym_ref)
{
  int lprefix;
  const char *name;

  /* If we aren't generating fix-and-continue code, don't do anything
     special.  */
  if (TARGET_FIX_AND_CONTINUE == 0)
    return 0;

  /* Otherwise, all symbol except symbols that begin with L or _OBJC_
     are indirected.  Symbols that begin with L and _OBJC_ are always
     bound to the current translation unit as they are used for
     generated local data of the translation unit.  */

  name = XSTR (sym_ref, 0);

  lprefix = (((name[0] == '*' || name[0] == '&')
              && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
	     || (startswith (name, "_OBJC_")));

  return ! lprefix;
}

static int
machopic_data_defined_p (rtx sym_ref)
{
  if (indirect_data (sym_ref))
    return 0;

  switch (machopic_classify_symbol (sym_ref))
    {
    case MACHOPIC_DEFINED_DATA:
    case MACHOPIC_DEFINED_FUNCTION:
      return 1;
    default:
      return 0;
    }
}

void
machopic_define_symbol (rtx mem)
{
  rtx sym_ref;

  gcc_assert (GET_CODE (mem) == MEM);
  sym_ref = XEXP (mem, 0);
  SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
}

/* Return either ORIG or:

     (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET))

   depending on MACHO_DYNAMIC_NO_PIC_P.  */
rtx
machopic_gen_offset (rtx orig)
{
  if (MACHO_DYNAMIC_NO_PIC_P)
    return orig;
  else
    {
      /* Play games to avoid marking the function as needing pic if we
	 are being called as part of the cost-estimation process.  */
      if (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl)
	crtl->uses_pic_offset_table = 1;
      orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
			     UNSPEC_MACHOPIC_OFFSET);
      return gen_rtx_CONST (Pmode, orig);
    }
}

static GTY(()) const char * function_base_func_name = NULL;
static GTY(()) unsigned current_pic_label_num = 0;
static GTY(()) unsigned emitted_pic_label_num = 0;

/* We need to keep one picbase label per function, but (when we emit code
   to reload the picbase for setjump receiver) we might need to check for
   a second use.  So, only update the picbase label counter when we see a
   new function.  When there's no function decl, we assume that the call is
   from the x86 stub generation code.  */
static void
update_pic_label_number_if_needed (void)
{
  if (current_function_decl)
    {

      const char *current_name =
	IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
      if (function_base_func_name != current_name)
	{
	  ++current_pic_label_num;
	  function_base_func_name = current_name;
	}
    }
  else
    {
      ++current_pic_label_num;
      function_base_func_name = "L_machopic_stub_dummy";
    }
}

void
machopic_output_function_base_name (FILE *file)
{
  /* We should only get here for -fPIC.  */
  gcc_checking_assert (MACHOPIC_PURE);

  update_pic_label_number_if_needed ();
  fprintf (file, "L%u$pb", current_pic_label_num);
}

char curr_picbasename[32];

const char *
machopic_get_function_picbase (void)
{
  /* We should only get here for -fPIC.  */
  gcc_checking_assert (MACHOPIC_PURE);

  update_pic_label_number_if_needed ();
  snprintf (curr_picbasename, 32, "L%u$pb", current_pic_label_num);
  return (const char *) curr_picbasename;
}

bool
machopic_should_output_picbase_label (void)
{
  update_pic_label_number_if_needed ();

  if (current_pic_label_num == emitted_pic_label_num)
    return false;

  emitted_pic_label_num = current_pic_label_num;
  return true;
}

/* The suffix attached to non-lazy pointer symbols.  */
#define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
/* The suffix attached to stub symbols.  */
#define STUB_SUFFIX "$stub"

typedef struct GTY ((for_user)) machopic_indirection
{
  /* The SYMBOL_REF for the entity referenced.  */
  rtx symbol;
  /* The name of the stub or non-lazy pointer.  */
  const char * ptr_name;
  /* True iff this entry is for a stub (as opposed to a non-lazy
     pointer).  */
  bool stub_p;
  /* True iff this stub or pointer has been referenced.  */
  bool used;
  /* True iff a non-lazy symbol pointer should be emitted into the .data
     section, rather than the non-lazy symbol pointers section.  The cases
     for which this occurred seem to have been unintentional, and later
     toolchains emit all of the indirections to the 'usual' section.  We
     are keeping this in case it is necessary to preserve compatibility with
     older toolchains.  */
  bool nlsp_in_data_section;
} machopic_indirection;

struct indirection_hasher : ggc_ptr_hash<machopic_indirection>
{
  typedef const char *compare_type;
  static hashval_t hash (machopic_indirection *);
  static bool equal (machopic_indirection *, const char *);
};

/* A table mapping stub names and non-lazy pointer names to
   SYMBOL_REFs for the stubbed-to and pointed-to entities.  */

static GTY (()) hash_table<indirection_hasher> *machopic_indirections;

/* Return a hash value for a SLOT in the indirections hash table.  */

hashval_t
indirection_hasher::hash (machopic_indirection *p)
{
  return htab_hash_string (p->ptr_name);
}

/* Returns true if the KEY is the same as that associated with
   SLOT.  */

bool
indirection_hasher::equal (machopic_indirection *s, const char *k)
{
  return strcmp (s->ptr_name, k) == 0;
}

/* Return the name of the non-lazy pointer (if STUB_P is false) or
   stub (if STUB_B is true) corresponding to the given name.

  PR71767 - If we have a situation like:

global_weak_symbol:
  ....
Lnon_weak_local:
  ....

  ld64 will be unable to split this into two atoms (because the "L" makes
  the second symbol 'invisible').  This means that legitimate direct accesses
  to the second symbol will appear to be direct accesses to an atom of type
  weak, global which are not allowed.

  To avoid this, we make any data-section indirections have a leading 'l'
  (lower-case L) which has a special meaning: linker can see this and use
  it to determine  atoms, but it is not placed into the final symbol table.

  Symbols in the non-lazy symbol pointers section (or stubs) do not have this
  problem because ld64 already knows the size of each entry.
*/

const char *
machopic_indirection_name (rtx sym_ref, bool stub_p)
{
  const char *name = XSTR (sym_ref, 0);
  tree id = maybe_get_identifier (name);
  if (id)
    {
      tree id_orig = id;

      while (IDENTIFIER_TRANSPARENT_ALIAS (id))
	id = TREE_CHAIN (id);
      if (id != id_orig)
	name = IDENTIFIER_POINTER (id);
    }

  const char *prefix = user_label_prefix;
  /* If we are emitting the label 'verbatim' then omit the U_L_P and count
     the name without the leading '*'.  */
  if (name[0] == '*')
    {
      prefix = "";
      ++name;
    }

  /* Here we are undoing a number of causes that placed some indirections
     (apparently erroneously) into the .data section.  Specifically, some
     symbols that are ABI mandated indirections and some hidden symbols
     were being placed there - which cause difficulties with later
     versions of ld64.  Iff (after these checks) some symbol still gets an
     indirection in the data section, we want to adjust the indirection
     name to be linker visible to deal with PR71767 (notes above).  */
  bool nlsp_in_data_section =
       ! MACHO_SYMBOL_MUST_INDIRECT_P (sym_ref)
    && ! MACHO_SYMBOL_HIDDEN_VIS_P (sym_ref)
    && (machopic_symbol_defined_p (sym_ref) || SYMBOL_REF_LOCAL_P (sym_ref))
    && ! indirect_data (sym_ref);

  const char *suffix = stub_p ? STUB_SUFFIX : NON_LAZY_POINTER_SUFFIX;
  /* If the indirection is in the data section, let the linker see it.  */
  char L_or_l = (!stub_p && nlsp_in_data_section) ? 'l' : 'L';
  /* We have mangled symbols with spaces and punctuation which typically
     need surrounding in quotes for the assembler to consume them.  */
  const char *quote = name_needs_quotes (name) ? "\"" : "";
  char *buffer = XALLOCAVEC (char, 2  /* strlen ("&L") or ("&l") */
			     + strlen (prefix)
			     + strlen (name)
			     + strlen (suffix)
			     + 2 * strlen (quote)
			     + 1 /* '\0' */);

  /* Construct the name of the non-lazy pointer or stub.  */
  sprintf (buffer, "&%s%c%s%s%s%s", quote, L_or_l, prefix, name,
	   suffix, quote);

  if (!machopic_indirections)
    machopic_indirections = hash_table<indirection_hasher>::create_ggc (37);

  machopic_indirection **slot
    = machopic_indirections->find_slot_with_hash (buffer,
						  htab_hash_string (buffer),
						  INSERT);
  machopic_indirection *p;
  if (*slot)
    p = *slot;
  else
    {
      p = ggc_alloc<machopic_indirection> ();
      p->symbol = sym_ref;
      p->ptr_name = xstrdup (buffer);
      p->stub_p = stub_p;
      p->used = false;
      p->nlsp_in_data_section = nlsp_in_data_section;
      *slot = p;
    }

  return p->ptr_name;
}

/* If NAME is the name of a stub or a non-lazy pointer , mark the stub
   or non-lazy pointer as used -- and mark the object to which the
   pointer/stub refers as used as well, since the pointer/stub will
   emit a reference to it.  */

void
machopic_validate_stub_or_non_lazy_ptr (const char *name)
{
  machopic_indirection *p
    = machopic_indirections->find_with_hash (name, htab_hash_string (name));
  if (p && ! p->used)
    {
      const char *real_name;
      tree id;

      p->used = true;

      /* Do what output_addr_const will do when we actually call it.  */
      if (SYMBOL_REF_DECL (p->symbol))
	mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));

      real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));

      id = maybe_get_identifier (real_name);
      if (id)
	mark_referenced (id);
    }
}

/* Transform ORIG, which may be any data source, to the corresponding
   source using indirections.  */

rtx
machopic_indirect_data_reference (rtx orig, rtx reg)
{
  rtx ptr_ref = orig;

  if (! MACHOPIC_INDIRECT)
    return orig;

  if (GET_CODE (orig) == SYMBOL_REF)
    {
      int defined = machopic_data_defined_p (orig);

      if (defined && MACHO_DYNAMIC_NO_PIC_P)
	{
	  if (DARWIN_PPC)
	    {
	  /* Create a new register for CSE opportunities.  */
	  rtx hi_reg = (!can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode));
	  emit_insn (gen_macho_high (Pmode, hi_reg, orig));
	  emit_insn (gen_macho_low (Pmode, reg, hi_reg, orig));
	      return reg;
 	    }
	  else if (DARWIN_X86)
	    return orig;
	  else
	   /* some other cpu -- writeme!  */
	   gcc_unreachable ();
	}
      else if (defined && ! MACHO_SYMBOL_MUST_INDIRECT_P (orig))
	{
	  rtx offset = NULL;
	  if (DARWIN_PPC || HAVE_lo_sum)
	    offset = machopic_gen_offset (orig);

	  if (DARWIN_PPC)
	    {
	  rtx hi_sum_reg = (!can_create_pseudo_p ()
			    ? reg
			    : gen_reg_rtx (Pmode));

	  gcc_assert (reg);

	  emit_insn (gen_rtx_SET (hi_sum_reg,
			      gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
				       gen_rtx_HIGH (Pmode, offset))));
	  emit_insn (gen_rtx_SET (reg,
				  gen_rtx_LO_SUM (Pmode, hi_sum_reg,
						  copy_rtx (offset))));

	  orig = reg;
	    }
	  else if (HAVE_lo_sum)
	    {
	  gcc_assert (reg);

	  emit_insn (gen_rtx_SET (reg, gen_rtx_HIGH (Pmode, offset)));
	  emit_insn (gen_rtx_SET (reg, gen_rtx_LO_SUM (Pmode, reg,
						       copy_rtx (offset))));
	  emit_use (pic_offset_table_rtx);

	  orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
	    }
	  return orig;
	}

      ptr_ref = (gen_rtx_SYMBOL_REF
		 (Pmode,
		  machopic_indirection_name (orig, /*stub_p=*/false)));

      SYMBOL_REF_DATA (ptr_ref) = SYMBOL_REF_DATA (orig);
      SYMBOL_REF_FLAGS (ptr_ref) |= MACHO_SYMBOL_FLAG_INDIRECTION;

      ptr_ref = gen_const_mem (Pmode, ptr_ref);
      machopic_define_symbol (ptr_ref);

      if (DARWIN_X86
          && reg
          && MACHO_DYNAMIC_NO_PIC_P)
	{
	    emit_insn (gen_rtx_SET (reg, ptr_ref));
	    ptr_ref = reg;
	}

      return ptr_ref;
    }
  else if (GET_CODE (orig) == CONST)
    {
      /* If "(const (plus ...", walk the PLUS and return that result.
	 PLUS processing (below) will restore the "(const ..." if
	 appropriate.  */
      if (GET_CODE (XEXP (orig, 0)) == PLUS)
	return machopic_indirect_data_reference (XEXP (orig, 0), reg);
      else
	return orig;
    }
  else if (GET_CODE (orig) == MEM)
    {
      XEXP (ptr_ref, 0) =
		machopic_indirect_data_reference (XEXP (orig, 0), reg);
      return ptr_ref;
    }
  else if (GET_CODE (orig) == PLUS)
    {
      rtx base, result;

      /* Legitimize both operands of the PLUS.  */
      base = machopic_indirect_data_reference (XEXP (orig, 0), reg);
      orig = machopic_indirect_data_reference (XEXP (orig, 1),
					       (base == reg ? 0 : reg));
      if (MACHOPIC_INDIRECT && (GET_CODE (orig) == CONST_INT))
	result = plus_constant (Pmode, base, INTVAL (orig));
      else
	result = gen_rtx_PLUS (Pmode, base, orig);

      if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
	{
	  if (reg)
	    {
	      emit_move_insn (reg, result);
	      result = reg;
	    }
	  else
	    {
	      result = force_reg (GET_MODE (result), result);
	    }
	}

      return result;
    }
  return ptr_ref;
}

/* Transform TARGET (a MEM), which is a function call target, to the
   corresponding symbol_stub if necessary.  Return a new MEM.  */

rtx
machopic_indirect_call_target (rtx target)
{
  if (! darwin_symbol_stubs)
    return target;

  if (GET_CODE (target) != MEM)
    return target;

  if (MACHOPIC_INDIRECT
      && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
      && ! MACHO_SYMBOL_DEFINED_P (XEXP (target, 0)))
    {
      rtx sym_ref = XEXP (target, 0);
      const char *stub_name = machopic_indirection_name (sym_ref,
							 /*stub_p=*/true);
      machine_mode mode = GET_MODE (sym_ref);

      XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
      SYMBOL_REF_DATA (XEXP (target, 0)) = SYMBOL_REF_DATA (sym_ref);
      SYMBOL_REF_FLAGS (XEXP (target, 0)) |= MACHO_SYMBOL_FLAG_INDIRECTION;
      MEM_READONLY_P (target) = 1;
      MEM_NOTRAP_P (target) = 1;
    }

  return target;
}

rtx
machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
{
  rtx pic_ref = orig;

  if (! MACHOPIC_INDIRECT)
    return orig;

  /* First handle a simple SYMBOL_REF or LABEL_REF */
  if (GET_CODE (orig) == LABEL_REF
      || GET_CODE (orig) == SYMBOL_REF)
    {
      /* addr(foo) = &func+(foo-func) */
      orig = machopic_indirect_data_reference (orig, reg);

      if (GET_CODE (orig) == PLUS
	  && GET_CODE (XEXP (orig, 0)) == REG)
	{
	  if (reg == 0)
	    return force_reg (mode, orig);

	  emit_move_insn (reg, orig);
	  return reg;
	}

      if (GET_CODE (orig) == MEM)
	{
	  if (reg == 0)
	    {
	      gcc_assert (!lra_in_progress);
	      reg = gen_reg_rtx (Pmode);
	    }

#if HAVE_lo_sum
	  if (MACHO_DYNAMIC_NO_PIC_P
	      && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
		  || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
	    {
#if defined (TARGET_TOC)	/* ppc  */
	      rtx temp_reg = (!can_create_pseudo_p ()
			      ? reg :
			      gen_reg_rtx (Pmode));
	      rtx asym = XEXP (orig, 0);
	      rtx mem;

	      emit_insn (gen_macho_high (Pmode, temp_reg, asym));
	      mem = gen_const_mem (GET_MODE (orig),
				   gen_rtx_LO_SUM (Pmode, temp_reg,
						   copy_rtx (asym)));
	      emit_insn (gen_rtx_SET (reg, mem));
#else
	      /* Some other CPU -- WriteMe! but right now there are no other
		 platforms that can use dynamic-no-pic  */
	      gcc_unreachable ();
#endif
	      pic_ref = reg;
	    }
	  else
	  if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
	      || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
	    {
	      rtx offset = machopic_gen_offset (XEXP (orig, 0));
#if defined (TARGET_TOC) /* i.e., PowerPC */
	      /* Generating a new reg may expose opportunities for
		 common subexpression elimination.  */
              rtx hi_sum_reg = (!can_create_pseudo_p ()
				? reg
				: gen_reg_rtx (Pmode));
	      rtx mem;
	      rtx sum;

	      sum = gen_rtx_HIGH (Pmode, offset);
	      if (! MACHO_DYNAMIC_NO_PIC_P)
		sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);

	      emit_insn (gen_rtx_SET (hi_sum_reg, sum));

	      mem = gen_const_mem (GET_MODE (orig),
				  gen_rtx_LO_SUM (Pmode,
						  hi_sum_reg,
						  copy_rtx (offset)));
	      rtx_insn *insn = emit_insn (gen_rtx_SET (reg, mem));
	      set_unique_reg_note (insn, REG_EQUAL, pic_ref);

	      pic_ref = reg;
#else
	      emit_use (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));

	      emit_insn (gen_rtx_SET (reg,
				      gen_rtx_HIGH (Pmode,
						    gen_rtx_CONST (Pmode,
								   offset))));
	      emit_insn (gen_rtx_SET (reg,
				  gen_rtx_LO_SUM (Pmode, reg,
					   gen_rtx_CONST (Pmode,
						   	  copy_rtx (offset)))));
	      pic_ref = gen_rtx_PLUS (Pmode,
				      pic_offset_table_rtx, reg);
#endif
	    }
	  else
#endif  /* HAVE_lo_sum */
	    {
	      rtx pic = pic_offset_table_rtx;
	      if (GET_CODE (pic) != REG)
		{
		  emit_move_insn (reg, pic);
		  pic = reg;
		}

	      if (lra_in_progress && HARD_REGISTER_P (pic))
		df_set_regs_ever_live (REGNO (pic), true);
	      pic_ref = gen_rtx_PLUS (Pmode, pic,
				      machopic_gen_offset (XEXP (orig, 0)));
	    }

#if !defined (TARGET_TOC)
	  emit_move_insn (reg, pic_ref);
	  pic_ref = gen_const_mem (GET_MODE (orig), reg);
#endif
	}
      else
	{

#if HAVE_lo_sum
	  if (GET_CODE (orig) == SYMBOL_REF
	      || GET_CODE (orig) == LABEL_REF)
	    {
	      rtx offset = machopic_gen_offset (orig);
#if defined (TARGET_TOC) /* i.e., PowerPC */
              rtx hi_sum_reg;

	      if (reg == 0)
		{
		  gcc_assert (!lra_in_progress);
		  reg = gen_reg_rtx (Pmode);
		}

	      hi_sum_reg = reg;

	      emit_insn (gen_rtx_SET (hi_sum_reg,
				      (MACHO_DYNAMIC_NO_PIC_P)
				      ? gen_rtx_HIGH (Pmode, offset)
				      : gen_rtx_PLUS (Pmode,
						      pic_offset_table_rtx,
						      gen_rtx_HIGH (Pmode,
								    offset))));
	      emit_insn (gen_rtx_SET (reg,
				      gen_rtx_LO_SUM (Pmode,
						      hi_sum_reg,
						      copy_rtx (offset))));
	      pic_ref = reg;
#else
	      emit_insn (gen_rtx_SET (reg, gen_rtx_HIGH (Pmode, offset)));
	      emit_insn (gen_rtx_SET (reg,
				      gen_rtx_LO_SUM (Pmode, reg,
						      copy_rtx (offset))));
	      pic_ref = gen_rtx_PLUS (Pmode,
				      pic_offset_table_rtx, reg);
#endif
	    }
	  else
#endif  /*  HAVE_lo_sum  */
	    {
	      if (REG_P (orig)
	          || GET_CODE (orig) == SUBREG)
		{
		  return orig;
		}
	      else
		{
		  rtx pic = pic_offset_table_rtx;
		  if (GET_CODE (pic) != REG)
		    {
		      emit_move_insn (reg, pic);
		      pic = reg;
		    }

		  if (lra_in_progress && HARD_REGISTER_P (pic))
		    df_set_regs_ever_live (REGNO (pic), true);
		  pic_ref = gen_rtx_PLUS (Pmode,
					  pic,
					  machopic_gen_offset (orig));
		}
	    }
	}

      if (GET_CODE (pic_ref) != REG)
	{
	  if (reg != 0)
	    {
	      emit_move_insn (reg, pic_ref);
	      return reg;
	    }
	  else
	    {
	      return force_reg (mode, pic_ref);
	    }
	}
      else
	{
	  return pic_ref;
	}
    }
  else if (GET_CODE (orig) == PLUS
	   && (GET_CODE (XEXP (orig, 0)) == MEM
	       || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
	       || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
	   && XEXP (orig, 0) != pic_offset_table_rtx
	   && GET_CODE (XEXP (orig, 1)) != REG)

    {
      rtx base;
      int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);

      base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
      orig = machopic_legitimize_pic_address (XEXP (orig, 1),
					      Pmode, (base == reg ? 0 : reg));
      if (GET_CODE (orig) == CONST_INT)
	{
	  pic_ref = plus_constant (Pmode, base, INTVAL (orig));
	  is_complex = 1;
	}
      else
	pic_ref = gen_rtx_PLUS (Pmode, base, orig);

      if (reg && is_complex)
	{
	  emit_move_insn (reg, pic_ref);
	  pic_ref = reg;
	}
      /* Likewise, should we set special REG_NOTEs here?  */
    }
  else if (GET_CODE (orig) == CONST)
    {
      return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
    }
  else if (GET_CODE (orig) == MEM
	   && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
    {
      rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
      addr = replace_equiv_address (orig, addr);
      emit_move_insn (reg, addr);
      pic_ref = reg;
    }

  return pic_ref;
}

/* Callbacks to output the stub or non-lazy pointers.
   Each works on the item in *SLOT,if it has been used.
   DATA is the FILE* for assembly output.
   Called from htab_traverses, invoked from machopic_finish().  */

int
machopic_output_data_section_indirection (machopic_indirection **slot,
					  FILE *out_file)
{
  machopic_indirection *p = *slot;

  if (!p->used || !p->nlsp_in_data_section)
    return 1;

  rtx symbol = p->symbol;
  /* The original symbol name.  */
  const char *sym_name = XSTR (symbol, 0);
  /* The name of the indirection symbol.  */
  const char *ptr_name = p->ptr_name;

  switch_to_section (data_section);
  assemble_align (GET_MODE_ALIGNMENT (Pmode));
  assemble_label (out_file, ptr_name);
  assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
		    GET_MODE_SIZE (Pmode),
		    GET_MODE_ALIGNMENT (Pmode), 1);

  return 1;
}

int
machopic_output_stub_indirection (machopic_indirection **slot,
				  FILE *out_file)
{
  machopic_indirection *p = *slot;

  if (!p->used || !p->stub_p)
    return 1;

  rtx symbol = p->symbol;
  /* The original symbol name.  */
  const char *sym_name = XSTR (symbol, 0);
  /* The name of the stub symbol.  */
  const char *ptr_name = p->ptr_name;

  tree id = maybe_get_identifier (sym_name);
  if (id)
    {
      tree id_orig = id;

      while (IDENTIFIER_TRANSPARENT_ALIAS (id))
	id = TREE_CHAIN (id);
      if (id != id_orig)
	sym_name = IDENTIFIER_POINTER (id);
    }

  char *sym = XALLOCAVEC (char, strlen (sym_name) + 2);
  if (sym_name[0] == '*' || sym_name[0] == '&')
    strcpy (sym, sym_name + 1);
  else if (sym_name[0] == '-' || sym_name[0] == '+')
    strcpy (sym, sym_name);
  else
    sprintf (sym, "%s%s", user_label_prefix, sym_name);

  char *stub = XALLOCAVEC (char, strlen (ptr_name) + 2);
  if (ptr_name[0] == '*' || ptr_name[0] == '&')
    strcpy (stub, ptr_name + 1);
  else
    sprintf (stub, "%s%s", user_label_prefix, ptr_name);

  machopic_output_stub (out_file, sym, stub);

  return 1;
}

int
machopic_output_indirection (machopic_indirection **slot, FILE *out_file)
{
  machopic_indirection *p = *slot;

  if (!p->used || p->stub_p || p->nlsp_in_data_section)
    return 1;

  rtx symbol = p->symbol;
  /* The original symbol name.  */
  const char *sym_name = XSTR (symbol, 0);
  /* The nonlazy-stub symbol name.  */
  const char *ptr_name = p->ptr_name;

  switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);

  /* Mach-O symbols are passed around in code through indirect references and
     the original symbol_ref hasn't passed through the generic handling and
     reference-catching in output_operand, so we need to manually mark weak
     references as such.  */

  if (SYMBOL_REF_WEAK (symbol))
    {
      tree decl = SYMBOL_REF_DECL (symbol);
      gcc_checking_assert (DECL_P (decl));

      if (decl != NULL_TREE
	  && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
	  /* Handle only actual external-only definitions, not
	     e.g. extern inline code or variables for which
	     storage has been allocated.  */
	  && !TREE_STATIC (decl))
	{
	  fputs ("\t.weak_reference ", out_file);
	  assemble_name (out_file, sym_name);
	  fputc ('\n', out_file);
	}
    }

  assemble_name (out_file, ptr_name);
  fprintf (out_file, ":\n");

  fprintf (out_file, "\t.indirect_symbol ");
  assemble_name (out_file, sym_name);
  fprintf (out_file, "\n");

  /* Variables that are marked with MACHO_SYMBOL_FLAG_STATIC need to
     have their symbol name instead of 0 in the second entry of
     the non-lazy symbol pointer data structure when they are
     defined.  This allows the runtime to rebind newer instances
     of the translation unit with the original instance of the
     symbol.  */

  rtx init = const0_rtx;
  if (MACHO_SYMBOL_STATIC_P (symbol) && machopic_symbol_defined_p (symbol))
    init = gen_rtx_SYMBOL_REF (Pmode, sym_name);

  assemble_integer (init, GET_MODE_SIZE (Pmode),
		    GET_MODE_ALIGNMENT (Pmode), 1);

  return 1;
}

static void
machopic_finish (FILE *out_file)
{
  if (!machopic_indirections)
    return;

  /* First output an symbol indirections that have been placed into .data
     (we don't expect these now).  */
  machopic_indirections->traverse_noresize
    <FILE *, machopic_output_data_section_indirection> (out_file);

  machopic_indirections->traverse_noresize
    <FILE *, machopic_output_stub_indirection> (out_file);

  machopic_indirections->traverse_noresize
    <FILE *, machopic_output_indirection> (out_file);
}

int
machopic_operand_p (rtx op)
{
  if (MACHOPIC_JUST_INDIRECT)
    return (GET_CODE (op) == SYMBOL_REF
	    && machopic_symbol_defined_p (op));
  else
    return (GET_CODE (op) == CONST
	    && GET_CODE (XEXP (op, 0)) == UNSPEC
	    && XINT (XEXP (op, 0), 1) == UNSPEC_MACHOPIC_OFFSET);
}

/* This function:
   computes and caches a series of flags that characterise the symbol's
   properties that affect Mach-O code gen (including accidental cases
   from older toolchains).

   TODO:
   Here we also need to do enough analysis to determine if a symbol's
   name needs to be made linker-visible.  This is more tricky - since
   it depends on whether we've previously seen a global weak definition
   in the same section.
   */

void
darwin_encode_section_info (tree decl, rtx rtl, int first)
{
  /* Careful not to prod global register variables.  */
  if (!MEM_P (rtl))
    return;

  /* Do the standard encoding things first; this sets:
     SYMBOL_FLAG_FUNCTION,
     SYMBOL_FLAG_LOCAL, (binds_local_p)
     TLS_MODEL, SYMBOL_FLAG_SMALL
     SYMBOL_FLAG_EXTERNAL.  */
  default_encode_section_info (decl, rtl, first);

  if (! VAR_OR_FUNCTION_DECL_P (decl))
    return;

  rtx sym_ref = XEXP (rtl, 0);
  if (VAR_P (decl))
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;

  /* Only really common if there's no initialiser.  */
  bool really_common_p = (DECL_COMMON (decl)
			  && (DECL_INITIAL (decl) == NULL
			      || (!in_lto_p
				  && DECL_INITIAL (decl) == error_mark_node)));

  /* For Darwin, if we have specified visibility and it's not the default
     that's counted 'hidden'.  */
  if (DECL_VISIBILITY_SPECIFIED (decl)
      && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT)
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_HIDDEN_VIS;

  if (!DECL_EXTERNAL (decl)
      && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
      && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
      && ((TREE_STATIC (decl)
	   && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
	  || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
	      && DECL_INITIAL (decl) != error_mark_node)))
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;

  if (! TREE_PUBLIC (decl))
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_STATIC;

  /* Short cut check for Darwin 'must indirect' rules.  */
  if (really_common_p
      || (DECL_WEAK (decl) && ! MACHO_SYMBOL_HIDDEN_VIS_P (sym_ref))
      || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_MUST_INDIRECT;

#if DARWIN_PPC
  /* Objective C V2 (m64) IVAR offset refs from Apple GCC-4.x have an
     indirection for m64 code on PPC.  Historically, these indirections
     also appear in the .data section.  */
  tree o2meta = lookup_attribute ("OBJC2META", DECL_ATTRIBUTES (decl));
  o2meta = o2meta ? TREE_VALUE (o2meta) : NULL_TREE;

  if (o2meta && startswith (IDENTIFIER_POINTER (o2meta), "V2_IVRF"))
    SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_MUST_INDIRECT;
#endif
}

void
darwin_mark_decl_preserved (const char *name)
{
  /* Actually we shouldn't mark any local symbol this way, but for now
     this only happens with ObjC meta-data.  */
  if (darwin_label_is_anonymous_local_objc_name (name))
    return;

  fprintf (asm_out_file, "\t.no_dead_strip ");
  assemble_name (asm_out_file, name);
  fputc ('\n', asm_out_file);
}

static section *
darwin_rodata_section (int use_coal, bool zsize, int reloc)
{
  return (use_coal
	  ? darwin_sections[const_coal_section]
	  : (zsize ? darwin_sections[zobj_const_section]
		   : reloc ? darwin_sections[const_data_section]
			   : darwin_sections[const_section]));
}

static section *
darwin_mergeable_string_section (tree exp,
				 unsigned HOST_WIDE_INT align)
{
  /* Darwin's ld expects to see non-writable string literals in the .cstring
     section.  Later versions of ld check and complain when CFStrings are
     enabled.  Therefore we shall force the strings into .cstring since we
     don't support writable ones anyway.  */
  if ((darwin_constant_cfstrings || flag_merge_constants)
      && TREE_CODE (exp) == STRING_CST
      && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
      && align <= 256
      && (int_size_in_bytes (TREE_TYPE (exp))
	  == TREE_STRING_LENGTH (exp))
      && ((size_t) TREE_STRING_LENGTH (exp)
	  == strlen (TREE_STRING_POINTER (exp)) + 1))
    return darwin_sections[cstring_section];

  if (DARWIN_SECTION_ANCHORS && flag_section_anchors
      && TREE_CODE (exp) == STRING_CST
      && TREE_STRING_LENGTH (exp) == 0)
    return darwin_sections[zobj_const_section];

  return readonly_data_section;
}

#ifndef HAVE_GAS_LITERAL16
#define HAVE_GAS_LITERAL16 0
#endif

static section *
darwin_mergeable_constant_section (tree exp,
				   unsigned HOST_WIDE_INT align,
				   bool zsize)
{
  if (zsize)
    return darwin_sections[zobj_const_section];

  machine_mode mode = DECL_MODE (exp);
  if (!flag_merge_constants
      || mode == VOIDmode
      || mode == BLKmode
      || align < 8
      || align > 256
      || (align & (align -1)) != 0)
    return readonly_data_section;

  /* This will ICE if the mode is not a constant size, but that is reasonable,
     since one cannot put a variable-sized thing into a constant section, we
     shouldn't be trying.  */
  const unsigned int modesize = GET_MODE_BITSIZE (mode).to_constant ();

  if (modesize > align)
    return readonly_data_section;

  tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));

  if (TREE_CODE (size) != INTEGER_CST)
    return readonly_data_section;

  unsigned isize = TREE_INT_CST_LOW (size);
  if (isize == 4)
    return darwin_sections[literal4_section];
  else if (isize == 8)
    return darwin_sections[literal8_section];
  else if (HAVE_GAS_LITERAL16
	   && TARGET_64BIT
	   && isize == 16)
    return darwin_sections[literal16_section];

  return readonly_data_section;
}

section *
darwin_tm_clone_table_section (void)
{
  return get_named_section (NULL,
			    "__DATA,__tm_clone_table,regular,no_dead_strip",
			    3);
}

int
machopic_reloc_rw_mask (void)
{
  return MACHOPIC_INDIRECT ? 3 : 0;
}

/* We have to deal with ObjC/C++ metadata section placement in the common
   code, since it will also be called from LTO.

   Return metadata attributes, if present (searching for ABI=2 first)
   Return NULL_TREE if no such attributes are found.  */

static tree
is_objc_metadata (tree decl)
{
  if (DECL_P (decl)
      && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == CONST_DECL)
      && DECL_ATTRIBUTES (decl))
    {
      tree meta = lookup_attribute ("OBJC2META", DECL_ATTRIBUTES (decl));
      if (meta)
	return meta;
      meta = lookup_attribute ("OBJC1META", DECL_ATTRIBUTES (decl));
      if (meta)
	return meta;
    }
  return NULL_TREE;
}

static int classes_seen;
static int objc_metadata_seen;

/* Return the section required for Objective C ABI 2 metadata.  */
static section *
darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
{
  const char *p;
  tree ident = TREE_VALUE (meta);
  gcc_assert (TREE_CODE (ident) == IDENTIFIER_NODE);
  p = IDENTIFIER_POINTER (ident);

  gcc_checking_assert (flag_next_runtime >= 1 && flag_objc_abi == 2);

  objc_metadata_seen = 1;

  if (base == data_section)
    base = darwin_sections[objc2_metadata_section];

  /* Most of the OBJC2 META-data end up in the base section, so check it
     first.  */
  if      (startswith (p, "V2_BASE"))
    return base;
  else if (startswith (p, "V2_CNAM"))
    return darwin_sections[objc2_class_names_section];
  else if (startswith (p, "V2_MNAM"))
    return darwin_sections[objc2_method_names_section];
  else if (startswith (p, "V2_MTYP"))
    return darwin_sections[objc2_method_types_section];
  else if (startswith (p, "V2_STRG"))
    return darwin_sections[cstring_section];

  else if (startswith (p, "G2_META") || startswith (p, "G2_CLAS"))
    return darwin_sections[objc2_classdefs_section];
  else if (startswith (p, "V2_PCOL"))
    return ld_uses_coal_sects ? darwin_sections[data_coal_section]
			      : darwin_sections[objc2_data_section];
  else if (startswith (p, "V2_MREF"))
    return darwin_sections[objc2_message_refs_section];
  else if (startswith (p, "V2_CLRF"))
    return darwin_sections[objc2_classrefs_section];
  else if (startswith (p, "V2_SURF"))
    return darwin_sections[objc2_super_classrefs_section];
  else if (startswith (p, "V2_NLCL"))
    return darwin_sections[objc2_nonlazy_class_section];
  else if (startswith (p, "V2_CLAB"))
    {
      classes_seen = 1;
      return darwin_sections[objc2_classlist_section];
    }
  else if (startswith (p, "V2_SRFS"))
    return darwin_sections[objc2_selector_refs_section];
  else if (startswith (p, "V2_NLCA"))
    return darwin_sections[objc2_nonlazy_category_section];
  else if (startswith (p, "V2_CALA"))
    return darwin_sections[objc2_categorylist_section];

  else if (startswith (p, "V2_PLST"))
    return darwin_sections[objc2_protocollist_section];
  else if (startswith (p, "V2_PRFS"))
    return darwin_sections[objc2_protocolrefs_section];

  else if (startswith (p, "V2_INFO"))
    return darwin_sections[objc2_image_info_section];

  else if (startswith (p, "V2_EHTY"))
    return ld_uses_coal_sects ? darwin_sections[data_coal_section]
                              : data_section;

  else if (startswith (p, "V2_CSTR"))
    return darwin_sections[objc2_constant_string_object_section];

  else if (startswith (p, "V2_IVRF"))
    return darwin_sections[objc2_ivar_section];

  /* Not recognized, default.  */
  return base;
}

/* Return the section required for Objective C ABI 0/1 metadata.  */
static section *
darwin_objc1_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
{
  const char *p;
  tree ident = TREE_VALUE (meta);
  gcc_assert (TREE_CODE (ident) == IDENTIFIER_NODE);
  p = IDENTIFIER_POINTER (ident);

  gcc_checking_assert (flag_next_runtime >= 1 && flag_objc_abi < 2);

  objc_metadata_seen = 1;

  /* String sections first, cos there are lots of strings.  */
  if      (startswith (p, "V1_STRG"))
    return darwin_sections[cstring_section];
  else if (startswith (p, "V1_CLSN"))
    return darwin_sections[objc_class_names_section];
  else if (startswith (p, "V1_METN"))
    return darwin_sections[objc_meth_var_names_section];
  else if (startswith (p, "V1_METT"))
    return darwin_sections[objc_meth_var_types_section];

  else if (startswith (p, "V1_CLAS"))
    {
      classes_seen = 1;
      return darwin_sections[objc_class_section];
    }
  else if (startswith (p, "V1_META"))
    return darwin_sections[objc_meta_class_section];
  else if (startswith (p, "V1_CATG"))
    return darwin_sections[objc_category_section];
  else if (startswith (p, "V1_PROT"))
    return darwin_sections[objc_protocol_section];

  else if (startswith (p, "V1_CLCV"))
    return darwin_sections[objc_class_vars_section];
  else if (startswith (p, "V1_CLIV"))
    return darwin_sections[objc_instance_vars_section];

  else if (startswith (p, "V1_CLCM"))
    return darwin_sections[objc_cls_meth_section];
  else if (startswith (p, "V1_CLIM"))
    return darwin_sections[objc_inst_meth_section];
  else if (startswith (p, "V1_CACM"))
    return darwin_sections[objc_cat_cls_meth_section];
  else if (startswith (p, "V1_CAIM"))
    return darwin_sections[objc_cat_inst_meth_section];
  else if (startswith (p, "V1_PNSM"))
    return darwin_sections[objc_cat_inst_meth_section];
  else if (startswith (p, "V1_PCLM"))
    return darwin_sections[objc_cat_cls_meth_section];

  else if (startswith (p, "V1_CLPR"))
    return darwin_sections[objc_cat_cls_meth_section];
  else if (startswith (p, "V1_CAPR"))
    return darwin_sections[objc_category_section]; /* ??? CHECK me.  */

  else if (startswith (p, "V1_PRFS"))
    return darwin_sections[objc_cat_cls_meth_section];
  else if (startswith (p, "V1_CLRF"))
    return darwin_sections[objc_cls_refs_section];
  else if (startswith (p, "V1_SRFS"))
    return darwin_sections[objc_selector_refs_section];

  else if (startswith (p, "V1_MODU"))
    return darwin_sections[objc_module_info_section];
  else if (startswith (p, "V1_SYMT"))
    return darwin_sections[objc_symbols_section];
  else if (startswith (p, "V1_INFO"))
    return darwin_sections[objc_image_info_section];

  else if (startswith (p, "V1_PLST"))
    return darwin_sections[objc1_prop_list_section];
  else if (startswith (p, "V1_PEXT"))
    return darwin_sections[objc1_protocol_ext_section];
  else if (startswith (p, "V1_CEXT"))
    return darwin_sections[objc1_class_ext_section];

  else if (startswith (p, "V2_CSTR"))
    return darwin_sections[objc_constant_string_object_section];

  return base;
}

section *
machopic_select_section (tree decl,
			 int reloc,
			 unsigned HOST_WIDE_INT align)
{
  bool zsize, one, weak, use_coal, ro;
  section *base_section = NULL;

  weak = (DECL_P (decl)
	  && DECL_WEAK (decl)
	  && !lookup_attribute ("weak_import", DECL_ATTRIBUTES (decl)));

  /* Darwin pads zero-sized objects with at least one byte, so that the ld64
     atom model is preserved (objects must have distinct regions starting with
     a unique linker-visible symbol).
     In order to support section anchors, we need to move objects with zero
     size into sections which are marked as "no section anchors"; the padded
     objects, obviously, have real sizes that differ from their DECL sizes.  */
  zsize = DARWIN_SECTION_ANCHORS && flag_section_anchors;

  /* In the streaming of LTO symbol data, we might have a situation where the
     var is incomplete or layout not finished (DECL_SIZE_UNIT is NULL_TREE).
     We cannot tell if it is zero-sized then, but we can get the section
     category correct so that nm reports the right kind of section
     (e.g. BSS c.f. data).  */
  zsize = (zsize
	   && DECL_P (decl)
	   && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == CONST_DECL)
	   && DECL_SIZE_UNIT (decl)
	   && tree_to_uhwi (DECL_SIZE_UNIT (decl)) == 0);

  one = DECL_P (decl)
	&& TREE_CODE (decl) == VAR_DECL
	&& DECL_COMDAT_GROUP (decl);

  use_coal = (weak || one) && ld_uses_coal_sects;

  ro = TREE_READONLY (decl) || TREE_CONSTANT (decl) ;

  switch (categorize_decl_for_section (decl, reloc))
    {
    case SECCAT_TEXT:
      gcc_unreachable ();
      break;

    case SECCAT_RODATA:
    case SECCAT_SRODATA:
      base_section = darwin_rodata_section (use_coal, zsize, reloc);
      break;

    case SECCAT_RODATA_MERGE_STR:
      base_section = darwin_mergeable_string_section (decl, align);
      break;

    case SECCAT_RODATA_MERGE_STR_INIT:
      base_section = darwin_mergeable_string_section (DECL_INITIAL (decl), align);
      break;

    case SECCAT_RODATA_MERGE_CONST:
      base_section =  darwin_mergeable_constant_section (decl, align, zsize);
      break;

    case SECCAT_DATA:
    case SECCAT_DATA_REL:
    case SECCAT_DATA_REL_LOCAL:
    case SECCAT_DATA_REL_RO:
    case SECCAT_DATA_REL_RO_LOCAL:
    case SECCAT_SDATA:
    case SECCAT_TDATA:
      if (use_coal)
	{
	  if (ro)
	    base_section = darwin_sections[const_data_coal_section];
	  else
	    base_section = darwin_sections[data_coal_section];
	}
      else if (zsize)
	{
	  /* If we're doing section anchors, then punt zero-sized objects into
	     their own sections so that they don't interfere with offset
	     computation for the remaining vars.  */
	  if (ro)
	    base_section = darwin_sections[zobj_const_data_section];
	  else
	    base_section = darwin_sections[zobj_data_section];
	}
      else if (ro)
	base_section = darwin_sections[const_data_section];
      else
	base_section = data_section;
      break;
    case SECCAT_BSS:
    case SECCAT_SBSS:
    case SECCAT_TBSS:
      if (use_coal)
	base_section = darwin_sections[data_coal_section];
      else
	{
	  if (!TREE_PUBLIC (decl))
	    base_section = lcomm_section;
	  else if (bss_noswitch_section)
	    base_section = bss_noswitch_section;
	  else
	    base_section = data_section;
	}
      break;

    default:
      gcc_unreachable ();
    }

  /* Darwin weird special cases.
     a) OBJC Meta-data. */
  if (DECL_P (decl)
      && (TREE_CODE (decl) == VAR_DECL
	  || TREE_CODE (decl) == CONST_DECL)
      && DECL_ATTRIBUTES (decl))
    {
      tree meta = lookup_attribute ("OBJC2META", DECL_ATTRIBUTES (decl));
      if (meta)
	return darwin_objc2_section (decl, meta, base_section);
      meta = lookup_attribute ("OBJC1META", DECL_ATTRIBUTES (decl));
      if (meta)
	return darwin_objc1_section (decl, meta, base_section);
      meta = lookup_attribute ("OBJC1METG", DECL_ATTRIBUTES (decl));
      if (meta)
	return base_section; /* GNU runtime is happy with it all in one pot.  */
    }

  /* b) Constant string objects.  */
  if (TREE_CODE (decl) == CONSTRUCTOR
      && TREE_TYPE (decl)
      && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
      && TYPE_NAME (TREE_TYPE (decl)))
    {
      tree name = TYPE_NAME (TREE_TYPE (decl));
      if (TREE_CODE (name) == TYPE_DECL)
        name = DECL_NAME (name);

      if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
	{
	  if (flag_next_runtime)
	    {
	      if (flag_objc_abi == 2)
		return darwin_sections[objc2_constant_string_object_section];
	      else
		return darwin_sections[objc_constant_string_object_section];
	    }
	  else
	    return darwin_sections[objc_string_object_section];
	}
      else if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_CFString"))
	return darwin_sections[cfstring_constant_object_section];
      else
	return base_section;
    }
  else if (flag_next_runtime
	   && VAR_P (decl)
	   && DECL_NAME (decl)
	   && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
	   && IDENTIFIER_POINTER (DECL_NAME (decl))
	   && startswith (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_"))
    /* c) legacy meta-data selection was deprecated at 4.6, removed now.  */
    gcc_unreachable ();

  return base_section;
}

/* This can be called with address expressions as "rtx".
   They must go in "const".  */

section *
machopic_select_rtx_section (machine_mode mode, rtx x,
			     unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
  if (known_eq (GET_MODE_SIZE (mode), 8)
      && (GET_CODE (x) == CONST_INT
	  || GET_CODE (x) == CONST_WIDE_INT
	  || GET_CODE (x) == CONST_DOUBLE))
    return darwin_sections[literal8_section];
  else if (known_eq (GET_MODE_SIZE (mode), 4)
	   && (GET_CODE (x) == CONST_INT
	       || GET_CODE (x) == CONST_WIDE_INT
	       || GET_CODE (x) == CONST_DOUBLE))
    return darwin_sections[literal4_section];
  else if (HAVE_GAS_LITERAL16
	   && TARGET_64BIT
	   && known_eq (GET_MODE_SIZE (mode), 16)
	   && (GET_CODE (x) == CONST_INT
	       || GET_CODE (x) == CONST_WIDE_INT
	       || GET_CODE (x) == CONST_DOUBLE
	       || GET_CODE (x) == CONST_VECTOR))
    return darwin_sections[literal16_section];
  else if (MACHOPIC_INDIRECT
	   && (GET_CODE (x) == SYMBOL_REF
	       || GET_CODE (x) == CONST
	       || GET_CODE (x) == LABEL_REF))
    return darwin_sections[const_data_section];
  else
    return darwin_sections[const_section];
}

void
machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  cdtor_record new_elt = {symbol, priority, vec_safe_length (ctors)};

  vec_safe_push (ctors, new_elt);

  if (! MACHOPIC_INDIRECT)
    fprintf (asm_out_file, ".reference .constructors_used\n");
}

void
machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  cdtor_record new_elt = {symbol, priority, vec_safe_length (dtors)};

  vec_safe_push (dtors, new_elt);

  if (! MACHOPIC_INDIRECT)
    fprintf (asm_out_file, ".reference .destructors_used\n");
}

static int
sort_cdtor_records (const void * a, const void * b)
{
  const cdtor_record *cda = (const cdtor_record *)a;
  const cdtor_record *cdb = (const cdtor_record *)b;
  if (cda->priority > cdb->priority)
    return 1;
  if (cda->priority < cdb->priority)
    return -1;
  if (cda->position > cdb->position)
    return 1;
  if (cda->position < cdb->position)
    return -1;
  return 0;
}

static void
finalize_ctors ()
{
  unsigned int i;
  cdtor_record *elt;

  if (MACHOPIC_INDIRECT)
    switch_to_section (darwin_sections[mod_init_section]);
  else
    switch_to_section (darwin_sections[constructor_section]);

  /* Where needed, provide a linker-visible section-start symbol so that we
     have stable output between debug and non-debug.  */
  if (ld_init_term_start_labels)
    fputs (MACHOPIC_INDIRECT ? "_Mod.init:\n" : "_CTOR.sect:\n", asm_out_file);

  if (vec_safe_length (ctors) > 1)
    ctors->qsort (sort_cdtor_records);
  FOR_EACH_VEC_SAFE_ELT (ctors, i, elt)
    {
      assemble_align (POINTER_SIZE);
      assemble_integer (elt->symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
    }
}

static void
finalize_dtors ()
{
  unsigned int i;
  cdtor_record *elt;

  if (MACHOPIC_INDIRECT)
    switch_to_section (darwin_sections[mod_term_section]);
  else
    switch_to_section (darwin_sections[destructor_section]);

  /* Where needed, provide a linker-visible section-start symbol so that we
     have stable output between debug and non-debug.  */
  if (ld_init_term_start_labels)
    fputs (MACHOPIC_INDIRECT ? "_Mod.term:\n" : "_DTOR.sect:\n", asm_out_file);

  if (vec_safe_length (dtors) > 1)
    dtors->qsort (sort_cdtor_records);
  FOR_EACH_VEC_SAFE_ELT (dtors, i, elt)
    {
      assemble_align (POINTER_SIZE);
      assemble_integer (elt->symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
    }
}

void
darwin_globalize_label (FILE *stream, const char *name)
{
  if (!startswith (name, "_OBJC_"))
    default_globalize_label (stream, name);
  /* We have some Objective C cases that need to be global, but only on newer
     OS versions.  */
  if (flag_objc_abi < 2 || flag_next_runtime < 100700)
    return;
  if (startswith (name+6, "LabelPro"))
    default_globalize_label (stream, name);
  if (startswith (name+6, "Protocol_"))
    default_globalize_label (stream, name);
}

/* This routine returns non-zero if 'name' starts with the special objective-c
   anonymous file-scope static name.  It accommodates c++'s mangling of such
   symbols (in this case the symbols will have form _ZL{d}*_OBJC_* d=digit).  */

int
darwin_label_is_anonymous_local_objc_name (const char *name)
{
  const unsigned char *p = (const unsigned char *) name;
  if (*p != '_')
    return 0;
  if (p[1] == 'Z' && p[2] == 'L')
  {
    p += 3;
    while (*p >= '0' && *p <= '9')
      p++;
  }
  if (!startswith ((const char *)p, "_OBJC_"))
    return false;

  /* We need some of the objective c meta-data symbols to be visible to the
     linker (when the target OS version is newer).  FIXME: this is horrible,
     we need a better mechanism.  */

  if (flag_objc_abi < 2 || flag_next_runtime < 100700)
    return true;

  p += 6;
  if (startswith ((const char *)p, "ClassRef"))
    return false;
  else if (startswith ((const char *)p, "SelRef"))
    return false;
  else if (startswith ((const char *)p, "Category"))
    {
      if (p[8] == '_' || p[8] == 'I' || p[8] == 'P' || p[8] == 'C' )
	return false;
      return true;
    }
  else if (startswith ((const char *)p, "ClassMethods"))
    return false;
  else if (startswith ((const char *)p, "ClassProtocols"))
    return false;
  else if (startswith ((const char *)p, "Instance"))
    {
      if (p[8] == 'I' || p[8] == 'M')
	return false;
      return true;
    }
  else if (startswith ((const char *)p, "CLASS_RO"))
    return false;
  else if (startswith ((const char *)p, "METACLASS_RO"))
    return false;
  else if (startswith ((const char *)p, "Protocol"))
    {
      if (p[8] == '_' || p[8] == 'I' || p[8] == 'P'
	  || p[8] == 'M' || p[8] == 'C' || p[8] == 'O')
	return false;
      return true;
    }
  else if (startswith ((const char *)p, "LabelPro"))
    return false;
  return true;
}

/* LTO support for Mach-O.

   This version uses three mach-o sections to encapsulate the (unlimited
   number of) lto sections.

   __GNU_LTO, __lto_sections  contains the concatented GNU LTO section data.
   __GNU_LTO, __section_names contains the GNU LTO section names.
   __GNU_LTO, __section_index contains an array of values that index these.

   Indexed thus:
     <section offset from the start of __GNU_LTO, __lto_sections>,
     <section length>
     <name offset from the start of __GNU_LTO, __section_names,
     <name length>.

   At present, for both m32 and m64 mach-o files each of these fields is
   represented  by a uint32_t.  This is because, AFAICT, a mach-o object
   cannot exceed 4Gb because the section_64 offset field (see below) is 32bits.

    uint32_t offset;
   "offset  An integer specifying the offset to this section in the file."  */

/* Count lto section numbers.  */
static unsigned int lto_section_num = 0;

/* A vector of information about LTO sections, at present, we only have
   the name.  TODO: see if we can get the data length somehow.  */
typedef struct GTY (()) darwin_lto_section_e {
  const char *sectname;
} darwin_lto_section_e ;

static GTY (()) vec<darwin_lto_section_e, va_gc> *lto_section_names;

/* Section wrapper scheme (used here to wrap the unlimited number of LTO
   sections into three Mach-O ones).
   NOTE: These names MUST be kept in sync with those in
	 libiberty/simple-object-mach-o.  */
#define LTO_SECTS_SECTION "__wrapper_sects"
#define LTO_NAMES_SECTION "__wrapper_names"
#define LTO_INDEX_SECTION "__wrapper_index"

/* File to temporarily store LTO data.  This is appended to asm_out_file
   in darwin_end_file.  */
static FILE *lto_asm_out_file, *saved_asm_out_file;
static char *lto_asm_out_name;
static enum debug_info_levels saved_debug_info_level;

/* Prepare asm_out_file for LTO output.  For darwin, this means hiding
   asm_out_file and switching to an alternative output file.  */
void
darwin_asm_lto_start (void)
{
  gcc_assert (! saved_asm_out_file);
  saved_asm_out_file = asm_out_file;
  saved_debug_info_level = debug_info_level;
  debug_info_level = DINFO_LEVEL_NONE;
  if (! lto_asm_out_name)
    lto_asm_out_name = make_temp_file (".lto.s");
  lto_asm_out_file = fopen (lto_asm_out_name, "a");
  if (lto_asm_out_file == NULL)
    fatal_error (input_location,
		 "failed to open temporary file %s for LTO output",
		 lto_asm_out_name);
  asm_out_file = lto_asm_out_file;
}

/* Restore asm_out_file.  */
void
darwin_asm_lto_end (void)
{
  gcc_assert (saved_asm_out_file);
  fclose (lto_asm_out_file);
  asm_out_file = saved_asm_out_file;
  saved_asm_out_file = NULL;
  debug_info_level = saved_debug_info_level;
}

static void
darwin_asm_dwarf_section (const char *name, unsigned int flags,
			  tree decl, bool is_for_lto);

/*  Called for the TARGET_ASM_NAMED_SECTION hook.  */

void
darwin_asm_named_section (const char *name,
			  unsigned int flags,
			  tree decl ATTRIBUTE_UNUSED)
{
  /* LTO sections go in a special section that encapsulates the (unlimited)
     number of GNU LTO sections within a single mach-o one.  */
  if (startswith (name, LTO_SECTION_NAME_PREFIX))
    {
      darwin_lto_section_e e;
      /* We expect certain flags to be set...  */
      gcc_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
		  == (SECTION_DEBUG | SECTION_NAMED));

      /* Switch to our combined section.  */
      fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
	       LTO_SEGMENT_NAME, LTO_SECTS_SECTION);
      /* Output a label for the start of this sub-section.  */
      fprintf (asm_out_file, "L_GNU_LTO%d:\t;# %s\n",
	       lto_section_num, name);
      /* We have to jump through hoops to get the values of the intra-section
         offsets... */
      fprintf (asm_out_file, "\t.set L$gnu$lto$offs%d,L_GNU_LTO%d-L_GNU_LTO0\n",
	       lto_section_num, lto_section_num);
      fprintf (asm_out_file,
	       "\t.set L$gnu$lto$size%d,L_GNU_LTO%d-L_GNU_LTO%d\n",
	       lto_section_num, lto_section_num+1, lto_section_num);
      lto_section_num++;
      e.sectname = xstrdup (name);
      /* Keep the names, we'll need to make a table later.
         TODO: check that we do not revisit sections, that would break
         the assumption of how this is done.  */
      if (lto_section_names == NULL)
        vec_alloc (lto_section_names, 16);
      vec_safe_push (lto_section_names, e);
   }
  else if (startswith (name, "__DWARF,"))
    darwin_asm_dwarf_section (name, flags, decl, false);
  else if (startswith (name, "__GNU_DWARF_LTO,"))
    darwin_asm_dwarf_section (name, flags, decl, true);
  else
    fprintf (asm_out_file, "\t.section %s\n", name);
}

void
darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
{
  /* Darwin does not use unique sections.  */
}

/* Handle __attribute__ ((apple_kext_compatibility)).
   This only applies to darwin kexts for 2.95 compatibility -- it shrinks the
   vtable for classes with this attribute (and their descendants) by not
   outputting the new 3.0 nondeleting destructor.  This means that such
   objects CANNOT be allocated on the stack or as globals UNLESS they have
   a completely empty `operator delete'.
   Luckily, this fits in with the Darwin kext model.

   This attribute also disables gcc3's potential overlaying of derived
   class data members on the padding at the end of the base class.  */

tree
darwin_handle_kext_attribute (tree *node, tree name,
			      tree args ATTRIBUTE_UNUSED,
			      int flags ATTRIBUTE_UNUSED,
			      bool *no_add_attrs)
{
  /* APPLE KEXT stuff -- only applies with pure static C++ code.  */
  if (! TARGET_KEXTABI)
    {
      warning (0, "%qE 2.95 vtable-compatibility attribute applies "
	       "only when compiling a kext", name);

      *no_add_attrs = true;
    }
  else if (TREE_CODE (*node) != RECORD_TYPE)
    {
      warning (0, "%qE 2.95 vtable-compatibility attribute applies "
	       "only to C++ classes", name);

      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "weak_import" attribute; arguments as in
   struct attribute_spec.handler.  */

tree
darwin_handle_weak_import_attribute (tree *node, tree name,
				     tree ARG_UNUSED (args),
				     int ARG_UNUSED (flags),
				     bool * no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored",
	       name);
      *no_add_attrs = true;
    }
  else
    declare_weak (*node);

  return NULL_TREE;
}

/* Emit a label for an FDE, making it global and/or weak if appropriate.
   The third parameter is nonzero if this is for exception handling.
   The fourth parameter is nonzero if this is just a placeholder for an
   FDE that we are omitting. */

void
darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
{
  char *lab ;
  char buf[32];
  static int invok_count = 0;
  static tree last_fun_decl = NULL_TREE;

  /* Modern linkers can produce distinct FDEs without compiler support.  */
  if (! for_eh || ! ld_needs_eh_markers)
    return;

  /* FIXME: This only works when the eh for all sections of a function are
     emitted at the same time.  If that changes, we would need to use a lookup
     table of some form to determine what to do.  Also, we should emit the
     unadorned label for the partition containing the public label for a
     function.  This is of limited use, probably, since we do not currently
     enable partitioning.  */
  strcpy (buf, ".eh");
  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
    {
      if (decl == last_fun_decl)
        {
	  invok_count++;
	  snprintf (buf, 31, "$$part$$%d.eh", invok_count);
	}
      else
	{
	  last_fun_decl = decl;
	  invok_count = 0;
	}
    }

  lab = concat (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), buf, NULL);

  if (TREE_PUBLIC (decl))
    {
      targetm.asm_out.globalize_label (file, lab);
      if (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN)
	{
	  fputs ("\t.private_extern ", file);
	  assemble_name (file, lab);
	  fputc ('\n', file);
	}
    }

  if (DECL_WEAK (decl))
    {
      fputs ("\t.weak_definition ", file);
      assemble_name (file, lab);
      fputc ('\n', file);
    }

  assemble_name (file, lab);
  if (empty)
    {
      fputs (" = 0\n", file);

      /* Mark the absolute .eh and .eh1 style labels as needed to
	 ensure that we don't dead code strip them and keep such
	 labels from another instantiation point until we can fix this
	 properly with group comdat support.  */
      darwin_mark_decl_preserved (lab);
    }
  else
    fputs (":\n", file);

  free (lab);
}

static GTY(()) unsigned long except_table_label_num;

void
darwin_emit_except_table_label (FILE *file)
{
  char section_start_label[30];

  ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
			       except_table_label_num++);
  ASM_OUTPUT_LABEL (file, section_start_label);
}

rtx
darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis))
{
  if (DARWIN_PPC == 0 && TARGET_64BIT)
    return orig;

  return gen_rtx_SYMBOL_REF (Pmode,
			     machopic_indirection_name (orig,
							/*stub_p=*/false));
}

/* The unwinders in earlier Darwin versions are based on an old version
   of libgcc_s and need current frame address stateto be reset after a
   DW_CFA_restore_state recovers the register values.  */

bool
darwin_should_restore_cfa_state (void)
{
  return generating_for_darwin_version <= 10;
}

/* Return, and mark as used, the name of the stub for the mcount function.
   Currently, this is only called by X86 code in the expansion of the
   FUNCTION_PROFILER macro, when stubs are enabled.  */

const char*
machopic_mcount_stub_name (void)
{
  rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
  const char *name = machopic_indirection_name (symbol, /*stub_p=*/true);
  machopic_validate_stub_or_non_lazy_ptr (name);
  return name;
}

/* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */

void
darwin_non_lazy_pcrel (FILE *file, rtx addr)
{
  const char *nlp_name;

  gcc_assert (GET_CODE (addr) == SYMBOL_REF);

  nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
  fputs ("\t.long\t", file);
  ASM_OUTPUT_LABELREF (file, nlp_name);
  fputs ("-.", file);
}

/* If this is uncommented, details of each allocation will be printed
   in the asm right before the actual code.  WARNING - this will cause some
   test-suite fails (since the printout will contain items that some tests
   are not expecting) -- so don't leave it on by default (it bloats the
   asm too).  */
/*#define DEBUG_DARWIN_MEM_ALLOCATORS*/

/* The first two of these routines are ostensibly just intended to put
   names into the asm.  However, they are both hijacked in order to ensure
   that zero-sized items do not make their way into the output.  Consequently,
   we also need to make these participate in provisions for dealing with
   such items in section anchors.  */

/* The implementation of ASM_DECLARE_OBJECT_NAME.  */
/* The RTTI data (e.g., __ti4name) is common and public (and static),
   but it does need to be referenced via indirect PIC data pointers.
   The machopic_define_symbol calls are telling the machopic subsystem
   that the name *is* defined in this module, so it doesn't need to
   make them indirect.  */
void
darwin_asm_declare_object_name (FILE *file,
				const char *nam, tree decl)
{
  const char *xname = nam;
  unsigned HOST_WIDE_INT size;
  bool local_def, weak;

  weak = (DECL_P (decl)
	  && DECL_WEAK (decl)
	  && !lookup_attribute ("weak_import",
				 DECL_ATTRIBUTES (decl)));

  local_def = DECL_INITIAL (decl) || (TREE_STATIC (decl)
				      && (!DECL_COMMON (decl)
					  || !TREE_PUBLIC (decl)));

  if (GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
    xname = IDENTIFIER_POINTER (DECL_NAME (decl));

  if (local_def)
    {
      (* targetm.encode_section_info) (decl, DECL_RTL (decl), false);
      if (!weak)
	machopic_define_symbol (DECL_RTL (decl));
    }

  size = tree_to_uhwi (DECL_SIZE_UNIT (decl));

#ifdef DEBUG_DARWIN_MEM_ALLOCATORS
fprintf (file, "# dadon: %s %s (%llu, %u) local %d weak %d"
	       " stat %d com %d pub %d t-const %d t-ro %d init %lx\n",
	xname, (TREE_CODE (decl) == VAR_DECL?"var":"const"),
	(unsigned long long)size, DECL_ALIGN (decl), local_def,
	DECL_WEAK (decl), TREE_STATIC (decl), DECL_COMMON (decl),
	TREE_PUBLIC (decl), TREE_CONSTANT (decl), TREE_READONLY (decl),
	(unsigned long)DECL_INITIAL (decl));
#endif

  /* Darwin needs help to support local zero-sized objects.
     They must be made at least one byte, and the section containing must be
     marked as unsuitable for section-anchors (see storage allocators below).

     For non-zero objects this output is handled by varasm.cc.
  */
  if (!size)
    {
      unsigned int l2align = 0;

      /* The align must be honored, even for zero-sized.  */
      if (DECL_ALIGN (decl))
	{
	  l2align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
	  fprintf (file, "\t.align\t%u\n", l2align);
	}

      ASM_OUTPUT_LABEL (file, xname);
      size = 1;
      fprintf (file, "\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);

      /* Check that we've correctly picked up the zero-sized item and placed it
         properly.  */
      gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
		  || (in_section
		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
    }
  else
    ASM_OUTPUT_LABEL (file, xname);
}

/* The implementation of ASM_DECLARE_CONSTANT_NAME.  */
void
darwin_asm_declare_constant_name (FILE *file, const char *name,
				  const_tree exp ATTRIBUTE_UNUSED,
				  HOST_WIDE_INT size)
{
  assemble_label (file, name);
  /* As for other items, we need at least one byte.  */
  if (!size)
    {
      fputs ("\t.space\t1\n", file);
      /* Check that we've correctly picked up the zero-sized item and placed it
         properly.  */
      gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
		  || (in_section
		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
    }
}

/* Darwin storage allocators.

   Zerofill sections are desirable for large blank data since, otherwise, these
   data bloat objects (PR33210).

   However, section anchors don't work in .zerofill sections (one cannot switch
   to a zerofill section).  Ergo, for Darwin targets using section anchors we need
   to put (at least some) data into 'normal' switchable sections.

   Here we set a relatively arbitrary value for the size of an object to trigger
   zerofill when section anchors are enabled (anything bigger than a page for
   current Darwin implementations).  FIXME: there ought to be some objective way
   to make this choice.

   When section anchor are off this is ignored anyway.  */

#define BYTES_ZFILL 4096

/* Emit a chunk of data for items coalesced by the linker.  */
static void
darwin_emit_weak_or_comdat (FILE *fp, tree decl, const char *name,
				  unsigned HOST_WIDE_INT size,
				  bool use_coal,
				  unsigned int align)
{
  /* Since the sections used here are coalesced, they will not be eligible
     for section anchors, and therefore we don't need to break that out.
     CHECKME: for modern linker on PowerPC.  */
 if (TREE_READONLY (decl) || TREE_CONSTANT (decl))
    switch_to_section (use_coal ? darwin_sections[const_data_coal_section]
				: darwin_sections[const_data_section]);
  else
    switch_to_section (use_coal ? darwin_sections[data_coal_section]
				: data_section);

  /* To be consistent, we'll allow darwin_asm_declare_object_name to assemble
     the align info for zero-sized items... but do it here otherwise.  */
  if (size && align)
    fprintf (fp, "\t.align\t%d\n", floor_log2 (align / BITS_PER_UNIT));

  if (TREE_PUBLIC (decl))
    darwin_globalize_label (fp, name);

  /* ... and we let it deal with outputting one byte of zero for them too.  */
  darwin_asm_declare_object_name (fp, name, decl);
  if (size)
    assemble_zeros (size);
}

/* Emit a chunk of data for ObjC meta-data that got placed in BSS erroneously.  */
static void
darwin_emit_objc_zeroed (FILE *fp, tree decl, const char *name,
				  unsigned HOST_WIDE_INT size,
				  unsigned int align, tree meta)
{
  section *ocs = data_section;

  if (TREE_PURPOSE (meta) == get_identifier("OBJC2META"))
    ocs = darwin_objc2_section (decl, meta, ocs);
  else
    ocs = darwin_objc1_section (decl, meta, ocs);

  switch_to_section (ocs);

  /* We shall declare that zero-sized meta-data are not valid (yet).  */
  gcc_assert (size);
  fprintf (fp, "\t.align\t%d\n", floor_log2 (align / BITS_PER_UNIT));

  /* ... and we let it deal with outputting one byte of zero for them too.  */
  darwin_asm_declare_object_name (fp, name, decl);
  assemble_zeros (size);
}

/* This routine emits 'local' storage:

   When Section Anchors are off this routine emits .zerofill commands in
   sections named for their alignment.

   When Section Anchors are on, smaller (non-zero-sized) items are placed in
   the .static_data section so that the section anchoring system can see them.
   Larger items are still placed in .zerofill sections, addressing PR33210.
   The routine has no checking - it is all assumed to be done by the caller.
*/
static void
darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
			unsigned HOST_WIDE_INT size,
			unsigned int l2align)
{
   if (DARWIN_SECTION_ANCHORS && flag_section_anchors && size < BYTES_ZFILL)
    {
      /* Put smaller objects in _static_data, where the section anchors system
	 can get them.
	 However, if they are zero-sized punt them to yet a different section
	 (that is not allowed to participate in anchoring).  */
      if (!size)
	{
	  fputs ("\t.section\t__DATA,__zobj_bss\n", fp);
	  in_section = darwin_sections[zobj_bss_section];
	  size = 1;
	}
      else
	{
	  fputs ("\t.static_data\n", fp);
	  in_section = darwin_sections[static_data_section];
	}

      if (l2align)
	fprintf (fp, "\t.align\t%u\n", l2align);

      assemble_name (fp, name);
      fprintf (fp, ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
    }
  else
    {
      /* When we are on a non-section anchor target (or not using section
	 anchors, we can get zero-sized items here.  However, all we need to
	 do is to bump them to one byte and the section alignment will take
	 care of the rest.  */
      char secnam[64];
      snprintf (secnam, 64, "__DATA,__bss");
      unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
      in_section = get_section (secnam, flags, NULL);
      fprintf (fp, "\t.zerofill %s,", secnam);
      assemble_name (fp, name);
      if (!size)
	size = 1;

      if (l2align)
	fprintf (fp, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
		 size, (unsigned) l2align);
      else
	fprintf (fp, "," HOST_WIDE_INT_PRINT_UNSIGNED",0\n", size);
    }

  (*targetm.encode_section_info) (decl, DECL_RTL (decl), false);
  /* This is defined as a file-scope var, so we know to notify machopic.  */
  machopic_define_symbol (DECL_RTL (decl));
}

/* Emit a chunk of common.  */
static void
darwin_emit_common (FILE *fp, const char *name,
		    unsigned HOST_WIDE_INT size, unsigned int align)
{
  unsigned HOST_WIDE_INT rounded;
  unsigned int l2align;

  /* Earlier systems complain if the alignment exceeds the page size.
     The magic number is 4096 * 8 - hard-coded for legacy systems.  */
  if (!emit_aligned_common && (align > 32768UL))
    align = 4096UL; /* In units.  */
  else
    align /= BITS_PER_UNIT;

  /* Make sure we have a meaningful align.  */
  if (!align)
    align = 1;

  /* For earlier toolchains, we need to emit the var as a rounded size to
     tell ld the alignment.  */
  if (size < align)
    rounded = align;
  else
    rounded = (size + (align-1)) & ~(align-1);

  l2align = floor_log2 (align);

  in_section = comm_section;
  /* We mustn't allow multiple public symbols to share an address when using
     the normal OSX toolchain.  */
  if (!size)
    {
      /* Put at least one byte.  */
      size = 1;
      /* This section can no longer participate in section anchoring.  */
      comm_section->common.flags |= SECTION_NO_ANCHOR;
    }

  fputs ("\t.comm\t", fp);
  assemble_name (fp, name);
  fprintf (fp, "," HOST_WIDE_INT_PRINT_UNSIGNED,
	   emit_aligned_common?size:rounded);
  if (l2align && emit_aligned_common)
    fprintf (fp, ",%u", l2align);
  fputs ("\n", fp);
}

/* Output a var which is all zero - into aligned BSS sections, common, lcomm
   or coalescable data sections (for weak or comdat) as appropriate.  */

void
darwin_output_aligned_bss (FILE *fp, tree decl, const char *name,
			  unsigned HOST_WIDE_INT size, unsigned int align)
{
  unsigned int l2align;
  bool one, pub, weak;
  tree meta;

  pub = TREE_PUBLIC (decl);
  one = DECL_ONE_ONLY (decl);
  weak = (DECL_P (decl)
	  && DECL_WEAK (decl)
	  && !lookup_attribute ("weak_import",
				 DECL_ATTRIBUTES (decl)));

#ifdef DEBUG_DARWIN_MEM_ALLOCATORS
fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
	     " pub %d weak %d one %d init %lx\n",
	name, (long long)size, (int)align, TREE_READONLY (decl),
	TREE_CONSTANT (decl), TREE_STATIC (decl), DECL_COMMON (decl),
	pub, weak, one, (unsigned long)DECL_INITIAL (decl));
#endif

  /* ObjC metadata can get put in BSS because varasm.cc decides it's BSS
     before the target has a chance to comment.  */
  if ((meta = is_objc_metadata (decl)))
    {
      darwin_emit_objc_zeroed (fp, decl, name, size, DECL_ALIGN (decl), meta);
      return;
    }

  /* Check that any initializer is valid.  */
  gcc_assert ((DECL_INITIAL (decl) == NULL)
	       || (DECL_INITIAL (decl) == error_mark_node)
	       || initializer_zerop (DECL_INITIAL (decl)));

  gcc_assert (DECL_SECTION_NAME (decl) == NULL);
  gcc_assert (!DECL_COMMON (decl));

  /*  Pick up the correct alignment.  */
  if (!size || !align)
    align = DECL_ALIGN (decl);

  l2align = floor_log2 (align / BITS_PER_UNIT);
  gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);

  last_assemble_variable_decl = decl;

  /* We would rather not have to check this here - but it seems that we might
     be passed a decl that should be in coalesced space.  */
  if (one || weak)
    {
      /* Weak or COMDAT objects are put in mergeable sections.  */
      darwin_emit_weak_or_comdat (fp, decl, name, size,
				  ld_uses_coal_sects, DECL_ALIGN (decl));
      return;
    }

  /* If this is not public, then emit according to local rules.  */
  if (!pub)
    {
      darwin_emit_local_bss (fp, decl, name, size, l2align);
      return;
    }

  /* So we have a public symbol.  */
  if (DARWIN_SECTION_ANCHORS && flag_section_anchors && size < BYTES_ZFILL)
    {
      /* Put smaller objects in data, where the section anchors system can get
	 them.  However, if they are zero-sized punt them to yet a different
	 section (that is not allowed to participate in anchoring).  */
      if (!size)
	{
	  fputs ("\t.section\t__DATA,__zobj_data\n", fp);
	  in_section = darwin_sections[zobj_data_section];
	  size = 1;
	}
      else
	{
	  fputs ("\t.data\n", fp);
	  in_section = data_section;
	}

      if (l2align)
	fprintf (fp, "\t.align\t%u\n", l2align);

      assemble_name (fp, name);
      fprintf (fp, ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
    }
  else
    {
      /* Section anchors not in use.  */
      unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
      char secnam[64];
      snprintf (secnam, 64, "__DATA,__common");
      in_section = get_section (secnam, flags, NULL);
      fprintf (fp, "\t.zerofill %s,", secnam);
      assemble_name (fp, name);
      if (!size)
	size = 1;

      if (l2align)
	fprintf (fp, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", size, l2align);
      else
	fprintf (fp, "," HOST_WIDE_INT_PRINT_UNSIGNED",0\n", size);
    }
  (* targetm.encode_section_info) (decl, DECL_RTL (decl), false);
}

/* Output a chunk of common, with alignment specified (where the target
   supports this).  */
void
darwin_asm_output_aligned_decl_common (FILE *fp, tree decl, const char *name,
				       unsigned HOST_WIDE_INT size,
				       unsigned int align)
{
  unsigned int l2align;
  bool one, weak;
  tree meta;

  /* No corresponding var.  */
  if (decl==NULL)
    {
#ifdef DEBUG_DARWIN_MEM_ALLOCATORS
fprintf (fp, "# adcom: %s (%d,%d) decl=0x0\n", name, (int)size, (int)align);
#endif
     /* Common variables are limited to a maximum alignment of 2^15.  */
      if (align > 32768)
	error_at (UNKNOWN_LOCATION, "common variables must have an alignment"
		  " of 32678 or less");
      darwin_emit_common (fp, name, size, align);
      return;
    }

  one = DECL_ONE_ONLY (decl);
  weak = (DECL_P (decl)
	  && DECL_WEAK (decl)
	  && !lookup_attribute ("weak_import",
				 DECL_ATTRIBUTES (decl)));

#ifdef DEBUG_DARWIN_MEM_ALLOCATORS
fprintf (fp, "# adcom: %s (%lld,%d) ro %d cst %d stat %d com %d pub %d"
	     " weak %d one %d init %lx\n",
	name,  (long long)size, (int)align, TREE_READONLY (decl),
	TREE_CONSTANT (decl), TREE_STATIC (decl), DECL_COMMON (decl),
	TREE_PUBLIC (decl), weak, one, (unsigned long)DECL_INITIAL (decl));
#endif

  /* ObjC metadata can get put in BSS because varasm.cc decides it's BSS
     before the target has a chance to comment.  */
  if ((meta = is_objc_metadata (decl)))
    {
      darwin_emit_objc_zeroed (fp, decl, name, size, DECL_ALIGN (decl), meta);
      return;
    }

  /* We shouldn't be messing with this if the decl has a section name.  */
  gcc_checking_assert (DECL_SECTION_NAME (decl) == NULL);

  /* We would rather not have to check this here - but it seems that we might
     be passed a decl that should be in coalesced space.  */
  if (one || weak)
    {
      /* Weak or COMDAT objects are put in mergable sections.  */
      darwin_emit_weak_or_comdat (fp, decl, name, size,
				  ld_uses_coal_sects, DECL_ALIGN (decl));
      return;
    }

  /* We should only get here for DECL_COMMON, with a zero init (and, in
     principle, only for public symbols too - although we deal with local
     ones below).  */

  /* Check the initializer is OK.  */
  gcc_assert (DECL_COMMON (decl)
	      && ((DECL_INITIAL (decl) == NULL)
	       || (DECL_INITIAL (decl) == error_mark_node)
	       || initializer_zerop (DECL_INITIAL (decl))));

  last_assemble_variable_decl = decl;

  if (!size || !align)
    align = DECL_ALIGN (decl);

  l2align = floor_log2 (align / BITS_PER_UNIT);
  /* Check we aren't asking for more aligment than the platform allows.  */
  gcc_checking_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);

  if (TREE_PUBLIC (decl) != 0)
    {
      /* Common variables are limited to a maximum alignment of 2^15.  */
      if (l2align > 15)
	error_at (DECL_SOURCE_LOCATION (decl), "common variables must have"
		  " an alignment of 32678 or less");
      darwin_emit_common (fp, name, size, align);
    }
  else
    darwin_emit_local_bss (fp, decl, name, size, l2align);
}

/* Output a chunk of BSS with alignment specfied.  */
void
darwin_asm_output_aligned_decl_local (FILE *fp, tree decl, const char *name,
				      unsigned HOST_WIDE_INT size,
				      unsigned int align)
{
  unsigned long l2align;
  bool one, weak;
  tree meta;

  one = DECL_ONE_ONLY (decl);
  weak = (DECL_P (decl)
	  && DECL_WEAK (decl)
	  && !lookup_attribute ("weak_import",
				 DECL_ATTRIBUTES (decl)));

#ifdef DEBUG_DARWIN_MEM_ALLOCATORS
fprintf (fp, "# adloc: %s (%lld,%d) ro %d cst %d stat %d one %d pub %d"
	     " weak %d init %lx\n",
	name, (long long)size, (int)align, TREE_READONLY (decl),
	TREE_CONSTANT (decl), TREE_STATIC (decl), one, TREE_PUBLIC (decl),
	weak , (unsigned long)DECL_INITIAL (decl));
#endif

  /* ObjC metadata can get put in BSS because varasm.cc decides it's BSS
     before the target has a chance to comment.  */
  if ((meta = is_objc_metadata (decl)))
    {
      darwin_emit_objc_zeroed (fp, decl, name, size, DECL_ALIGN (decl), meta);
      return;
    }

  /* We shouldn't be messing with this if the decl has a section name.  */
  gcc_assert (DECL_SECTION_NAME (decl) == NULL);

  /* We would rather not have to check this here - but it seems that we might
     be passed a decl that should be in coalesced space.  */
  if (one || weak)
    {
      /* Weak or COMDAT objects are put in mergable sections.  */
      darwin_emit_weak_or_comdat (fp, decl, name, size,
				  ld_uses_coal_sects, DECL_ALIGN (decl));
      return;
    }

  /* .. and it should be suitable for placement in local mem.  */
  gcc_assert(!TREE_PUBLIC (decl) && !DECL_COMMON (decl));
  /* .. and any initializer must be all-zero.  */
  gcc_assert ((DECL_INITIAL (decl) == NULL)
	       || (DECL_INITIAL (decl) == error_mark_node)
	       || initializer_zerop (DECL_INITIAL (decl)));

  last_assemble_variable_decl = decl;

  if (!size || !align)
    align = DECL_ALIGN (decl);

  l2align = floor_log2 (align / BITS_PER_UNIT);
  gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);

  darwin_emit_local_bss (fp, decl, name, size, l2align);
}

/* Emit an assembler directive to set visibility for a symbol.  The
   only supported visibilities are VISIBILITY_DEFAULT and
   VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
   extern".  There is no MACH-O equivalent of ELF's
   VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */

void
darwin_assemble_visibility (tree decl, int vis)
{
  if (vis == VISIBILITY_DEFAULT)
    ;
  else if (vis == VISIBILITY_HIDDEN || vis == VISIBILITY_INTERNAL)
    {
      fputs ("\t.private_extern ", asm_out_file);
      assemble_name (asm_out_file,
		     (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
      fputs ("\n", asm_out_file);
    }
  else
    warning (OPT_Wattributes, "protected visibility attribute "
	     "not supported in this configuration; ignored");
}

/* vec used by darwin_asm_dwarf_section.
   Maybe a hash tab would be better here - but the intention is that this is
   a very short list (fewer than 16 items) and each entry should (ideally,
   eventually) only be presented once.

   A structure to hold a dwarf debug section used entry.  */

typedef struct GTY(()) dwarf_sect_used_entry {
  const char *name;
  unsigned count;
}
dwarf_sect_used_entry;


/* A list of used __DWARF sections.  */
static GTY (()) vec<dwarf_sect_used_entry, va_gc> *dwarf_sect_names_table;

/* This is called when we are asked to assemble a named section and the
   name begins with __DWARF,.  We keep a list of the section names (without
   the __DWARF, prefix) and use this to emit our required start label on the
   first switch to each section.  */

static void
darwin_asm_dwarf_section (const char *name, unsigned int flags,
			  tree ARG_UNUSED (decl), bool is_for_lto)
{
  unsigned i;
  int namelen, extra = 0;
  const char *sect, *lto_add = "";
  char sname[64];
  dwarf_sect_used_entry *ref;
  bool found = false;

  gcc_checking_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
			== (SECTION_DEBUG | SECTION_NAMED));

  /* We know that the name starts with __DWARF, or __GNU_DAWRF_LTO  */
  sect = strchr (name, ',') + 1;
  namelen = strchr (sect, ',') - sect;
  gcc_checking_assert (namelen);

  /* The section switch is output as written...  */
  fprintf (asm_out_file, "\t.section %s\n", name);

  /* ... but the string we keep to make section start labels needs
     adjustment for lto cases.  */
  if (is_for_lto)
    {
      lto_add = "_lto";
      extra = 4;
    }

  snprintf (sname, 64, "%.*s%.*s", namelen, sect, extra, lto_add);
  namelen += extra;

  if (dwarf_sect_names_table == NULL)
    vec_alloc (dwarf_sect_names_table, 16);
  else
    for (i = 0;
	 dwarf_sect_names_table->iterate (i, &ref);
	 i++)
      {
	if (!ref)
	  break;
	if (!strcmp (ref->name, sname))
	  {
	    found = true;
	    ref->count++;
	    break;
	  }
      }

  if (!found)
    {
      dwarf_sect_used_entry e;
      fprintf (asm_out_file, "Lsection%.*s:\n", namelen, sname);
      e.count = 1;
      e.name = xstrdup (sname);
      vec_safe_push (dwarf_sect_names_table, e);
    }
}

/* Output a difference of two labels that will be an assembly time
   constant if the two labels are local.  (.long lab1-lab2 will be
   very different if lab1 is at the boundary between two sections; it
   will be relocated according to the second section, not the first,
   so one ends up with a difference between labels in different
   sections, which is bad in the dwarf2 eh context for instance.)  */

static int darwin_dwarf_label_counter;

void
darwin_asm_output_dwarf_delta (FILE *file, int size,
			       const char *lab1, const char *lab2,
			       HOST_WIDE_INT offset)
{
  int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
		     && lab2[0] == '*' && lab2[1] == 'L');
  const char *directive = (size == 8 ? ".quad" : ".long");

  if (islocaldiff)
    fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
  else
    fprintf (file, "\t%s\t", directive);

  assemble_name_raw (file, lab1);
  fprintf (file, "-");
  assemble_name_raw (file, lab2);
  if (offset != 0)
    fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
  if (islocaldiff)
    fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
}

/* Output an offset in a DWARF section on Darwin.  On Darwin, DWARF section
   offsets are not represented using relocs in .o files; either the
   section never leaves the .o file, or the linker or other tool is
   responsible for parsing the DWARF and updating the offsets.  */

void
darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
				HOST_WIDE_INT offset, section *base)
{
  char sname[64];
  int namelen, extra = 0;
  bool is_for_lto;
  const char *lto_add = "";

  gcc_checking_assert (base->common.flags & SECTION_NAMED);
  is_for_lto = startswith (base->named.name, "__GNU_DWARF_LTO,");
  gcc_checking_assert (is_for_lto
		       || startswith (base->named.name, "__DWARF,"));
  const char *name = strchr (base->named.name, ',') + 1;
  gcc_checking_assert (name);

  namelen = strchr (name, ',') - (name);
  if (is_for_lto)
    {
      lto_add = "_lto";
      extra = 4;
    }
  snprintf (sname, 64, "*Lsection%.*s%.*s", namelen, name, extra, lto_add);
  darwin_asm_output_dwarf_delta (file, size, lab, sname, offset);
}

/* Called from the within the TARGET_ASM_FILE_START for each target.  */

void
darwin_file_start (void)
{
  /* Nothing to do.  */
}

/* Called for the TARGET_ASM_FILE_END hook.
   Emit the mach-o pic indirection data, the lto data and, finally a flag
   to tell the linker that it can break the file object into sections and
   move those around for efficiency.  */

void
darwin_file_end (void)
{
  if (!vec_safe_is_empty (ctors))
    finalize_ctors ();
  if (!vec_safe_is_empty (dtors))
    finalize_dtors ();

  /* If we are expecting to output NeXT ObjC meta-data, (and we actually see
     some) then we output the fix-and-continue marker (Image Info).
     This applies to Objective C, Objective C++ and LTO with either language
     as part of the input.  */
  if (flag_next_runtime && objc_metadata_seen)
    {
      unsigned int flags = 0;
      if (flag_objc_abi >= 2)
	{
	  flags = 16;
          switch_to_section (darwin_sections[objc2_image_info_section]);
	}
      else
	switch_to_section (darwin_sections[objc_image_info_section]);

      ASM_OUTPUT_ALIGN (asm_out_file, 2);
      fputs ("L_OBJC_ImageInfo:\n", asm_out_file);

      flags |= (flag_replace_objc_classes && classes_seen) ? 1 : 0;
      flags |= flag_objc_gc ? 2 : 0;

      fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags);
     }

  machopic_finish (asm_out_file);
  if (flag_apple_kext)
    {
      /* These sections are only used for kernel code.  */
      switch_to_section (darwin_sections[constructor_section]);
      switch_to_section (darwin_sections[destructor_section]);
      ASM_OUTPUT_ALIGN (asm_out_file, 1);
    }

  /* If there was LTO assembler output, append it to asm_out_file.  */
  if (lto_asm_out_name)
    {
      int n;
      char *buf, *lto_asm_txt;

      /* Shouldn't be here if we failed to switch back.  */
      gcc_assert (! saved_asm_out_file);

      lto_asm_out_file = fopen (lto_asm_out_name, "r");
      if (lto_asm_out_file == NULL)
	fatal_error (input_location,
		     "failed to open temporary file %s with LTO output",
		     lto_asm_out_name);
      fseek (lto_asm_out_file, 0, SEEK_END);
      n = ftell (lto_asm_out_file);
      if (n > 0)
        {
	  fseek (lto_asm_out_file, 0, SEEK_SET);
	  lto_asm_txt = buf = (char *) xmalloc (n + 1);
	  while (fgets (lto_asm_txt, n, lto_asm_out_file))
	    fputs (lto_asm_txt, asm_out_file);
	  /* Put a termination label.  */
	  fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
		   LTO_SEGMENT_NAME, LTO_SECTS_SECTION);
	  fprintf (asm_out_file, "L_GNU_LTO%d:\t;# end of lto\n",
		   lto_section_num);
	  /* Make sure our termination label stays in this section.  */
	  fputs ("\t.space\t1\n", asm_out_file);
	}

      /* Remove the temporary file.  */
      fclose (lto_asm_out_file);
      unlink_if_ordinary (lto_asm_out_name);
      free (lto_asm_out_name);
    }

  /* Output the names and indices.  */
  if (lto_section_names && lto_section_names->length ())
    {
      int count;
      darwin_lto_section_e *ref;
      /* For now, we'll make the offsets 4 bytes and unaligned - we'll fix
         the latter up ourselves.  */
      const char *op = integer_asm_op (4,0);

      /* Emit the names.  */
      fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
	       LTO_SEGMENT_NAME, LTO_NAMES_SECTION);
      FOR_EACH_VEC_ELT (*lto_section_names, count, ref)
	{
	  fprintf (asm_out_file, "L_GNU_LTO_NAME%d:\n", count);
         /* We have to jump through hoops to get the values of the intra-section
            offsets... */
	  fprintf (asm_out_file,
		   "\t.set L$gnu$lto$noff%d,L_GNU_LTO_NAME%d-L_GNU_LTO_NAME0\n",
		   count, count);
	  fprintf (asm_out_file,
		   "\t.set L$gnu$lto$nsiz%d,L_GNU_LTO_NAME%d-L_GNU_LTO_NAME%d\n",
		   count, count+1, count);
	  fprintf (asm_out_file, "\t.asciz\t\"%s\"\n", ref->sectname);
	}
      fprintf (asm_out_file, "L_GNU_LTO_NAME%d:\t;# end\n", lto_section_num);
      /* make sure our termination label stays in this section.  */
      fputs ("\t.space\t1\n", asm_out_file);

      /* Emit the Index.  */
      fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
	       LTO_SEGMENT_NAME, LTO_INDEX_SECTION);
      fputs ("\t.align\t2\n", asm_out_file);
      fputs ("# Section offset, Section length, Name offset, Name length\n",
	     asm_out_file);
      FOR_EACH_VEC_ELT (*lto_section_names, count, ref)
	{
	  fprintf (asm_out_file, "%s L$gnu$lto$offs%d\t;# %s\n",
		   op, count, ref->sectname);
	  fprintf (asm_out_file, "%s L$gnu$lto$size%d\n", op, count);
	  fprintf (asm_out_file, "%s L$gnu$lto$noff%d\n", op, count);
	  fprintf (asm_out_file, "%s L$gnu$lto$nsiz%d\n", op, count);
	}
    }

  /* If we have section anchors, then we must prevent the linker from
     re-arranging data.  */
  if (!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
    fprintf (asm_out_file, "\t.subsections_via_symbols\n");

  /* We rely on this being NULL at the start of compilation; reset it here
     so that JIT can reuse a context.  */
  if (dwarf_sect_names_table != NULL)
    {
      dwarf_sect_names_table->truncate (0);
      dwarf_sect_names_table = NULL;
    }
}

/* TODO: Add a language hook for identifying if a decl is a vtable.  */
#define DARWIN_VTABLE_P(DECL) 0

/* Cross-module name binding.  Darwin does not support overriding
   functions at dynamic-link time, except for vtables in kexts.  */

bool
darwin_binds_local_p (const_tree decl)
{
  /* We use the "shlib" input to indicate that a symbol should be
     considered overridable; only relevant for vtables in kernel modules
     on earlier system versions, and with a TODO to complete.  */
  bool force_overridable = TARGET_KEXTABI && DARWIN_VTABLE_P (decl);
  return default_binds_local_p_3 (decl, force_overridable /* shlib */,
				  false /* weak dominate */,
				  false /* extern_protected_data */,
				  false /* common_local_p */);
}

/* The Darwin's implementation of TARGET_ASM_OUTPUT_ANCHOR.  Define the
   anchor relative to ".", the current section position.  We cannot use
   the default one because ASM_OUTPUT_DEF is wrong for Darwin.  */
void
darwin_asm_output_anchor (rtx symbol)
{
  fprintf (asm_out_file, "\t.set\t");
  assemble_name (asm_out_file, XSTR (symbol, 0));
  fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
	   SYMBOL_REF_BLOCK_OFFSET (symbol));
}

/* Disable section anchoring on any section containing a zero-sized
   object.  */
bool
darwin_use_anchors_for_symbol_p (const_rtx symbol)
{
  if (DARWIN_SECTION_ANCHORS && flag_section_anchors)
    {
      section *sect;
      /* If the section contains a zero-sized object it's ineligible.  */
      sect = SYMBOL_REF_BLOCK (symbol)->sect;
      /* This should have the effect of disabling anchors for vars that follow
         any zero-sized one, in a given section.  */
      if (sect->common.flags & SECTION_NO_ANCHOR)
	return false;

      /* Also check the normal reasons for suppressing.  */
      return default_use_anchors_for_symbol_p (symbol);
    }
  else
    return false;
}

/* Set the darwin specific attributes on TYPE.  */
void
darwin_set_default_type_attributes (tree type)
{
  if (darwin_ms_struct
      && TREE_CODE (type) == RECORD_TYPE)
    TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("ms_struct"),
                                        NULL_TREE,
                                        TYPE_ATTRIBUTES (type));
}

/* True, iff we're generating code for loadable kernel extensions.  */

bool
darwin_kextabi_p (void) {
  return flag_apple_kext;
}

void
darwin_override_options (void)
{
  /* Keep track of which (major) version we're generating code for.  */
  if (darwin_macosx_version_min)
    {
      if (strverscmp (darwin_macosx_version_min, "10.7") >= 0)
	generating_for_darwin_version = 11;
      else if (strverscmp (darwin_macosx_version_min, "10.6") >= 0)
	generating_for_darwin_version = 10;
      else if (strverscmp (darwin_macosx_version_min, "10.5") >= 0)
	generating_for_darwin_version = 9;
      else if (strverscmp (darwin_macosx_version_min, "10.4") >= 0)
	generating_for_darwin_version = 8;

      /* Earlier versions are not specifically accounted, until required.  */
    }

  /* Some codegen needs to account for the capabilities of the target
     linker.  */
  if (darwin_target_linker)
    {
      /* Older Darwin ld could not coalesce weak entities without them being
	 placed in special sections.  */
      if (strverscmp (darwin_target_linker, MIN_LD64_NO_COAL_SECTS) < 0)
	ld_uses_coal_sects = true;

      /* Some newer assemblers emit section start temp symbols for mod init
	 and term sections if there is no suitable symbol present already.
	 The temp symbols are linker visible and therefore appear in the
	 symbol tables.  Since the temp symbol number can vary when debug is
	 enabled, that causes compare-debug fails.  The solution is to provide
	 a stable linker-visible symbol.  */
      if (strverscmp (darwin_target_linker,
		      MIN_LD64_INIT_TERM_START_LABELS) >= 0)
	ld_init_term_start_labels = true;
    }

  /* In principle, this should be c-family only.  However, we really need to
     set sensible defaults for LTO as well, since the section selection stuff
     should check for correctness re. the ABI.  TODO: check and provide the
     flags (runtime & ABI) from the lto wrapper).  */

  /* At present, make a hard update to the runtime version based on the target
     OS version.  */
  if (flag_next_runtime)
    {
      if (generating_for_darwin_version > 10)
	flag_next_runtime = 100705;
      else if (generating_for_darwin_version > 9)
	flag_next_runtime = 100608;
      else if (generating_for_darwin_version > 8)
	flag_next_runtime = 100508;
      else
	flag_next_runtime = 100000;
    }

  /* Unless set, force ABI=2 for NeXT and m64, 0 otherwise.  */
  if (!OPTION_SET_P (flag_objc_abi))
    global_options.x_flag_objc_abi
	= (!flag_next_runtime)
		? 0
		: (TARGET_64BIT ? 2
				: (generating_for_darwin_version >= 9) ? 1
								       : 0);

  if (OPTION_SET_P (flag_objc_abi) && flag_next_runtime)
    {
      if (TARGET_64BIT && global_options.x_flag_objc_abi != 2)
	/* The Objective-C family ABI 2 is the only valid version NeXT/m64.  */
	error_at (UNKNOWN_LOCATION,
		  "%<-fobjc-abi-version%> 2 must be used for 64 bit targets"
		  " with %<-fnext-runtime%>");
      else if (!TARGET_64BIT && global_options.x_flag_objc_abi >= 2)
	/* ABI versions 0 and 1 are the only valid versions NeXT/m32.  */
	error_at (UNKNOWN_LOCATION,
		  "%<-fobjc-abi-version%> %d is not supported for 32 bit"
		  " targets with %<-fnext-runtime%>",
		  global_options.x_flag_objc_abi);
    }

  /* Don't emit DWARF3/4 unless specifically selected.  This is a
     workaround for tool bugs.  */
  if (!OPTION_SET_P (dwarf_strict))
    dwarf_strict = 1;
  if (!OPTION_SET_P (dwarf_version))
    dwarf_version = 2;

  if (OPTION_SET_P (dwarf_split_debug_info))
    {
      inform (input_location,
	      "%<-gsplit-dwarf%> is not supported on this platform, ignored");
      dwarf_split_debug_info = 0;
      OPTION_SET_P (dwarf_split_debug_info) = 0;
    }

  /* Do not allow unwind tables to be generated by default for m32.
     fnon-call-exceptions will override this, regardless of what we do.  */
  if (generating_for_darwin_version < 10
      && !OPTION_SET_P (flag_asynchronous_unwind_tables)
      && !TARGET_64BIT)
    global_options.x_flag_asynchronous_unwind_tables = 0;

   /* Disable -freorder-blocks-and-partition when unwind tables are being
      emitted for Darwin < 9 (OSX 10.5).
      The strategy is, "Unless the user has specifically set/unset an unwind
      flag we will switch off -freorder-blocks-and-partition when unwind tables
      will be generated".  If the user specifically sets flags, we have to
      assume they know why.  */
   if (generating_for_darwin_version < 9
       && OPTION_SET_P (flag_reorder_blocks_and_partition)
       && flag_reorder_blocks_and_partition
       && ((global_options.x_flag_exceptions 		/* User, c++, java */
	    && !OPTION_SET_P (flag_exceptions)) 	/* User specified... */
	   || (global_options.x_flag_unwind_tables
	       && !OPTION_SET_P (flag_unwind_tables))
	   || (global_options.x_flag_non_call_exceptions
	       && !OPTION_SET_P (flag_non_call_exceptions))
	   || (global_options.x_flag_asynchronous_unwind_tables
	       && !OPTION_SET_P (flag_asynchronous_unwind_tables))))
    {
      inform (input_location,
	      "%<-freorder-blocks-and-partition%> does not work with "
	      "exceptions on this architecture");
      flag_reorder_blocks_and_partition = 0;
      flag_reorder_blocks = 1;
    }

    /* FIXME: flag_objc_sjlj_exceptions is no longer needed since there is only
       one valid choice of exception scheme for each runtime.  */
    if (!OPTION_SET_P (flag_objc_sjlj_exceptions))
      global_options.x_flag_objc_sjlj_exceptions =
				flag_next_runtime && !TARGET_64BIT;

    /* FIXME: and this could be eliminated then too.  */
    if (!OPTION_SET_P (flag_exceptions)
	&& flag_objc_exceptions
	&& TARGET_64BIT)
      flag_exceptions = 1;

  if (flag_mkernel || flag_apple_kext)
    {
      /* -mkernel implies -fapple-kext for C++ */
      if (lang_GNU_CXX ())
	flag_apple_kext = 1;

      flag_no_common = 1;

      /* No EH in kexts.  */
      flag_exceptions = 0;
      /* No -fnon-call-exceptions data in kexts.  */
      flag_non_call_exceptions = 0;
      /* so no tables either.. */
      flag_unwind_tables = 0;
      flag_asynchronous_unwind_tables = 0;
    }

  if (flag_var_tracking_uninit == 0
      && generating_for_darwin_version >= 9
      && (flag_gtoggle ? (debug_info_level == DINFO_LEVEL_NONE)
      : (debug_info_level >= DINFO_LEVEL_NORMAL))
      && dwarf_debuginfo_p ())
    flag_var_tracking_uninit = flag_var_tracking;

  /* Final check on PCI options; for Darwin these are not dependent on the PIE
     ones, although PIE does require PIC to support it.  */
  if (MACHO_DYNAMIC_NO_PIC_P)
    {
      if (flag_pic)
	warning_at (UNKNOWN_LOCATION, 0,
		 "%<-mdynamic-no-pic%> overrides %<-fpic%>, %<-fPIC%>,"
		 " %<-fpie%> or %<-fPIE%>");
      flag_pic = 0;
    }
  else if (flag_pic == 1
	   || (flag_pic == 0 && !(flag_mkernel || flag_apple_kext)))
    {
      /* Darwin's -fpic is -fPIC.
	 We only support "static" code in the kernel and kernel exts.  */
      flag_pic = 2;
    }

  /* Linkers >= ld64-62.1 (at least) are capable of making the necessary PIC
     indirections and we no longer need to emit pic symbol stubs.
     However, if we are generating code for earlier ones (or for use in the
     kernel) the stubs might still be required, and this will be set true.
     If the user sets it on or off - then that takes precedence.

     Linkers that don't need stubs, don't need the EH symbol markers either.
  */

  if (!OPTION_SET_P (darwin_symbol_stubs))
    {
      if (darwin_target_linker)
	{
	  if (strverscmp (darwin_target_linker, MIN_LD64_OMIT_STUBS) < 0)
	    {
	      darwin_symbol_stubs = true;
	      ld_needs_eh_markers = true;
	    }
	}
      else if (generating_for_darwin_version < 9)
	{
	  /* If we don't know the linker version and we're targeting an old
	     system, we know no better than to assume the use of an earlier
	     linker.  */
	  darwin_symbol_stubs = true;
	  ld_needs_eh_markers = true;
	}
    }
  else if (DARWIN_X86 && darwin_symbol_stubs && TARGET_64BIT)
    {
      inform (input_location,
	      "%<-mpic-symbol-stubs%> is not required for 64-bit code "
	      "(ignored)");
      darwin_symbol_stubs = false;
    }

  if (generating_for_darwin_version >= 9)
    /* Later systems can support aligned common.  */
    emit_aligned_common = true;

  /* The c_dialect...() macros are not available to us here.  */
  darwin_running_cxx = (strstr (lang_hooks.name, "C++") != 0);
}

#if DARWIN_PPC
/* Add $LDBL128 suffix to long double builtins for ppc darwin.  */

static void
darwin_patch_builtin (enum built_in_function fncode)
{
  tree fn = builtin_decl_explicit (fncode);
  tree sym;
  char *newname;

  if (!fn)
    return;

  sym = DECL_ASSEMBLER_NAME (fn);
  newname = ACONCAT (("_", IDENTIFIER_POINTER (sym), "$LDBL128", NULL));

  set_user_assembler_name (fn, newname);

  fn = builtin_decl_implicit (fncode);
  if (fn)
    set_user_assembler_name (fn, newname);
}

void
darwin_patch_builtins (void)
{
  if (LONG_DOUBLE_TYPE_SIZE != 128)
    return;

#define PATCH_BUILTIN(fncode) darwin_patch_builtin (fncode);
#define PATCH_BUILTIN_NO64(fncode)		\
  if (!TARGET_64BIT)				\
    darwin_patch_builtin (fncode);
#define PATCH_BUILTIN_VARIADIC(fncode)				  \
  if (!TARGET_64BIT						  \
      && (strverscmp (darwin_macosx_version_min, "10.3.9") >= 0)) \
    darwin_patch_builtin (fncode);
#include "darwin-ppc-ldouble-patch.def"
#undef PATCH_BUILTIN
#undef PATCH_BUILTIN_NO64
#undef PATCH_BUILTIN_VARIADIC
}
#endif

/*  CFStrings implementation.  */
static GTY(()) tree cfstring_class_reference = NULL_TREE;
static GTY(()) tree cfstring_type_node = NULL_TREE;
static GTY(()) tree ccfstring_type_node = NULL_TREE;
static GTY(()) tree pccfstring_type_node = NULL_TREE;
static GTY(()) tree pcint_type_node = NULL_TREE;
static GTY(()) tree pcchar_type_node = NULL_TREE;

static enum built_in_function darwin_builtin_cfstring;

/* Store all constructed constant CFStrings in a hash table so that
   they get uniqued properly.  */

typedef struct GTY ((for_user)) cfstring_descriptor {
  /* The string literal.  */
  tree literal;
  /* The resulting constant CFString.  */
  tree constructor;
} cfstring_descriptor;

struct cfstring_hasher : ggc_ptr_hash<cfstring_descriptor>
{
  static hashval_t hash (cfstring_descriptor *);
  static bool equal (cfstring_descriptor *, cfstring_descriptor *);
};

static GTY (()) hash_table<cfstring_hasher> *cfstring_htab;

static tree
add_builtin_field_decl (tree type, const char *name, tree **chain)
{
  tree field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			    get_identifier (name), type);

  if (*chain != NULL)
    **chain = field;
  *chain = &DECL_CHAIN (field);

  return field;
}

tree
darwin_init_cfstring_builtins (unsigned builtin_cfstring)
{
  tree cfsfun, fields, pccfstring_ftype_pcchar;
  tree *chain = NULL;

  darwin_builtin_cfstring =
    (enum built_in_function) builtin_cfstring;

  /* struct __builtin_CFString {
       const int *isa;		(will point at
       int flags;		 __CFConstantStringClassReference)
       const char *str;
       long length;
     };  */

  pcint_type_node = build_pointer_type
		   (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));

  pcchar_type_node = build_pointer_type
		   (build_qualified_type (char_type_node, TYPE_QUAL_CONST));

  cfstring_type_node = (*lang_hooks.types.make_type) (RECORD_TYPE);

  /* Have to build backwards for finish struct.  */
  fields = add_builtin_field_decl (long_integer_type_node, "length", &chain);
  add_builtin_field_decl (pcchar_type_node, "str", &chain);
  add_builtin_field_decl (integer_type_node, "flags", &chain);
  add_builtin_field_decl (pcint_type_node, "isa", &chain);
  finish_builtin_struct (cfstring_type_node, "__builtin_CFString",
			 fields, NULL_TREE);

  /* const struct __builtin_CFstring *
     __builtin___CFStringMakeConstantString (const char *); */

  ccfstring_type_node = build_qualified_type
			(cfstring_type_node, TYPE_QUAL_CONST);
  pccfstring_type_node = build_pointer_type (ccfstring_type_node);
  pccfstring_ftype_pcchar = build_function_type_list
			(pccfstring_type_node, pcchar_type_node, NULL_TREE);

  cfsfun  = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
			get_identifier ("__builtin___CFStringMakeConstantString"),
			pccfstring_ftype_pcchar);

  TREE_PUBLIC (cfsfun) = 1;
  DECL_EXTERNAL (cfsfun) = 1;
  DECL_ARTIFICIAL (cfsfun) = 1;
  /* Make a lang-specific section - dup_lang_specific_decl makes a new node
     in place of the existing, which may be NULL.  */
  DECL_LANG_SPECIFIC (cfsfun) = NULL;
  (*lang_hooks.dup_lang_specific_decl) (cfsfun);
  set_decl_built_in_function (cfsfun, BUILT_IN_MD, darwin_builtin_cfstring);
  lang_hooks.builtin_function (cfsfun);

  /* extern int __CFConstantStringClassReference[];  */
  cfstring_class_reference = build_decl (BUILTINS_LOCATION, VAR_DECL,
		 get_identifier ("__CFConstantStringClassReference"),
		 build_array_type (integer_type_node, NULL_TREE));

  TREE_PUBLIC (cfstring_class_reference) = 1;
  DECL_ARTIFICIAL (cfstring_class_reference) = 1;
  (*lang_hooks.decls.pushdecl) (cfstring_class_reference);
  DECL_EXTERNAL (cfstring_class_reference) = 1;
  rest_of_decl_compilation (cfstring_class_reference, 0, 0);

  /* Initialize the hash table used to hold the constant CFString objects.  */
  cfstring_htab = hash_table<cfstring_hasher>::create_ggc (31);

  return cfstring_type_node;
}

tree
darwin_fold_builtin (tree fndecl, int n_args, tree *argp,
		     bool ARG_UNUSED (ignore))
{
  int fcode = DECL_MD_FUNCTION_CODE (fndecl);

  if (fcode == darwin_builtin_cfstring)
    {
      if (!darwin_constant_cfstrings)
	{
	  error ("built-in function %qD requires the"
		 " %<-mconstant-cfstrings%> flag", fndecl);
	  return error_mark_node;
	}

      if (n_args != 1)
	{
	  error ("built-in function %qD takes one argument only", fndecl);
	  return error_mark_node;
	}

      return darwin_build_constant_cfstring (*argp);
    }

  return NULL_TREE;
}

void
darwin_rename_builtins (void)
{
}

/* Implementation for the TARGET_LIBC_HAS_FUNCTION hook.  */

bool
darwin_libc_has_function (enum function_class fn_class,
			  tree type ATTRIBUTE_UNUSED)
{
  if (fn_class == function_sincos && darwin_macosx_version_min)
    return (strverscmp (darwin_macosx_version_min, "10.9") >= 0);
#if DARWIN_PPC && SUPPORT_DARWIN_LEGACY
  if (fn_class == function_c99_math_complex
      || fn_class == function_c99_misc)
    return (TARGET_64BIT
	    || (darwin_macosx_version_min &&
		strverscmp (darwin_macosx_version_min, "10.3") >= 0));
#endif
  return default_libc_has_function (fn_class, type);
}

hashval_t
cfstring_hasher::hash (cfstring_descriptor *ptr)
{
  tree str = ptr->literal;
  const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
  int i, len = TREE_STRING_LENGTH (str);
  hashval_t h = len;

  for (i = 0; i < len; i++)
    h = ((h * 613) + p[i]);

  return h;
}

bool
cfstring_hasher::equal (cfstring_descriptor *ptr1, cfstring_descriptor *ptr2)
{
  tree str1 = ptr1->literal;
  tree str2 = ptr2->literal;
  int len1 = TREE_STRING_LENGTH (str1);

  return (len1 == TREE_STRING_LENGTH (str2)
	  && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
		      len1));
}

tree
darwin_build_constant_cfstring (tree str)
{
  struct cfstring_descriptor *desc, key;
  tree addr;

  if (!str)
    {
      error ("CFString literal is missing");
      return error_mark_node;
    }

  STRIP_NOPS (str);

  if (TREE_CODE (str) == ADDR_EXPR)
    str = TREE_OPERAND (str, 0);

  if (TREE_CODE (str) != STRING_CST)
    {
      error ("CFString literal expression is not a string constant");
      return error_mark_node;
    }

  /* Perhaps we already constructed a constant CFString just like this one? */
  key.literal = str;
  cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);
  desc = *loc;

  if (!desc)
    {
      tree var, constructor, field;
      vec<constructor_elt, va_gc> *v = NULL;
      int length = TREE_STRING_LENGTH (str) - 1;

      if (darwin_warn_nonportable_cfstrings)
	{
	  const char *s = TREE_STRING_POINTER (str);
	  int l = 0;

	  for (l = 0; l < length; l++)
	    if (!s[l] || !isascii (s[l]))
	      {
		warning (darwin_warn_nonportable_cfstrings,
			 s[l] ? G_("non-ASCII character in CFString literal")
			      : G_("embedded NUL in CFString literal"));
		break;
	      }
	}

      *loc = desc = ggc_cleared_alloc<cfstring_descriptor> ();
      desc->literal = str;

      /* isa *. */
      field = TYPE_FIELDS (ccfstring_type_node);
      CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
			     build1 (ADDR_EXPR,  TREE_TYPE (field),
				     cfstring_class_reference));
      /* flags */
      field = DECL_CHAIN (field);
      CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
			     build_int_cst (TREE_TYPE (field), 0x000007c8));
      /* string *. */
      field = DECL_CHAIN (field);
      CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
			     build1 (ADDR_EXPR, TREE_TYPE (field), str));
      /* length */
      field = DECL_CHAIN (field);
      CONSTRUCTOR_APPEND_ELT(v, NULL_TREE,
			     build_int_cst (TREE_TYPE (field), length));

      constructor = build_constructor (ccfstring_type_node, v);
      TREE_READONLY (constructor) = 1;
      TREE_CONSTANT (constructor) = 1;
      TREE_STATIC (constructor) = 1;

      /* Fromage: The C++ flavor of 'build_unary_op' expects constructor nodes
	 to have the TREE_HAS_CONSTRUCTOR (...) bit set.  However, this file is
	 being built without any knowledge of C++ tree accessors; hence, we shall
	 use the generic accessor that TREE_HAS_CONSTRUCTOR actually maps to!  */
      if (darwin_running_cxx)
	TREE_LANG_FLAG_4 (constructor) = 1;  /* TREE_HAS_CONSTRUCTOR  */

      /* Create an anonymous global variable for this CFString.  */
      var = build_decl (input_location, CONST_DECL,
			NULL, TREE_TYPE (constructor));
      DECL_ARTIFICIAL (var) = 1;
      TREE_STATIC (var) = 1;
      DECL_INITIAL (var) = constructor;
      /* FIXME: This should use a translation_unit_decl to indicate file scope.  */
      DECL_CONTEXT (var) = NULL_TREE;
      desc->constructor = var;
    }

  addr = build1 (ADDR_EXPR, pccfstring_type_node, desc->constructor);
  TREE_CONSTANT (addr) = 1;

  return addr;
}

bool
darwin_cfstring_p (tree str)
{
  struct cfstring_descriptor key;

  if (!str)
    return false;

  STRIP_NOPS (str);

  if (TREE_CODE (str) == ADDR_EXPR)
    str = TREE_OPERAND (str, 0);

  if (TREE_CODE (str) != STRING_CST)
    return false;

  key.literal = str;
  cfstring_descriptor **loc = cfstring_htab->find_slot (&key, NO_INSERT);

  if (loc)
    return true;

  return false;
}

void
darwin_enter_string_into_cfstring_table (tree str)
{
  struct cfstring_descriptor key;

  key.literal = str;
  cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);

  if (!*loc)
    {
      *loc = ggc_cleared_alloc<cfstring_descriptor> ();
      ((struct cfstring_descriptor *)*loc)->literal = str;
    }
}

/* Choose named function section based on its frequency.  */

section *
darwin_function_section (tree decl, enum node_frequency freq,
			  bool startup, bool exit)
{
  /* Decide if we need to put this in a coalescable section.  */
  bool weak = (decl
	       && DECL_WEAK (decl)
	       && (!DECL_ATTRIBUTES (decl)
		   || !lookup_attribute ("weak_import",
					  DECL_ATTRIBUTES (decl))));

  bool use_coal = weak && ld_uses_coal_sects;
  /* If there is a specified section name, we should not be trying to
     override.  */
  if (decl && DECL_SECTION_NAME (decl) != NULL)
    return get_named_section (decl, NULL, 0);

  /* We always put unlikely executed stuff in the cold section.  */
  if (freq == NODE_FREQUENCY_UNLIKELY_EXECUTED)
    return (use_coal) ? darwin_sections[text_cold_coal_section]
		      : darwin_sections[text_cold_section];

  /* If we have LTO *and* feedback information, then let LTO handle
     the function ordering, it makes a better job (for normal, hot,
     startup and exit - hence the bailout for cold above).  */
  if (in_lto_p && flag_profile_values)
    goto default_function_sections;

  /* Non-cold startup code should go to startup subsection.  */
  if (startup)
    return (use_coal) ? darwin_sections[text_startup_coal_section]
		      : darwin_sections[text_startup_section];

  /* Similarly for exit.  */
  if (exit)
    return (use_coal) ? darwin_sections[text_exit_coal_section]
		      : darwin_sections[text_exit_section];

  /* Place hot code.  */
  if (freq == NODE_FREQUENCY_HOT)
    return (use_coal) ? darwin_sections[text_hot_coal_section]
		      : darwin_sections[text_hot_section];

  /* Otherwise, default to the 'normal' non-reordered sections.  */
default_function_sections:
  return (use_coal) ? darwin_sections[text_coal_section]
		    : text_section;
}

#include "gt-darwin.h"
