aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/darwin.c
diff options
context:
space:
mode:
authorIain Sandoe <iains@gcc.gnu.org>2011-02-18 00:07:38 +0000
committerNicola Pero <nicola@gcc.gnu.org>2011-02-18 00:07:38 +0000
commitd764a8e6bdae09aecb7a8378def9d900f84ce53e (patch)
treec0b6f091c931f0a65e3fb59fbd9fff3f5ba9bde9 /gcc/config/darwin.c
parent0a8134cacea8b18b0e241cc492546cbb69ae598a (diff)
downloadgcc-d764a8e6bdae09aecb7a8378def9d900f84ce53e.zip
gcc-d764a8e6bdae09aecb7a8378def9d900f84ce53e.tar.gz
gcc-d764a8e6bdae09aecb7a8378def9d900f84ce53e.tar.bz2
Added support for the 64-bit Apple Objective-C runtime
From-SVN: r170260
Diffstat (limited to 'gcc/config/darwin.c')
-rw-r--r--gcc/config/darwin.c325
1 files changed, 312 insertions, 13 deletions
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index c31aeed..2969f10 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -148,13 +148,48 @@ output_objc_section_asm_op (const void *directive)
objc_class_vars_section,
objc_instance_vars_section,
objc_module_info_section,
- objc_symbols_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_message_refs_section,
+ objc2_classdefs_section,
+ objc2_metadata_section,
+ objc2_classrefs_section,
+ objc2_classlist_section,
+ objc2_categorylist_section,
+ objc2_selector_refs_section,
+ objc2_nonlazy_class_section,
+ objc2_nonlazy_category_section,
+ objc2_protocollist_section,
+ objc2_protocolrefs_section,
+ objc2_super_classrefs_section,
+ objc2_image_info_section,
+ objc2_constant_string_object_section
+ } ;
size_t i;
been_here = true;
- for (i = 0; i < ARRAY_SIZE (tomark); i++)
- switch_to_section (darwin_sections[tomark[i]]);
+ 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.c out of sync with us. */
switch_to_section (saved_in_section);
}
output_section_asm_op (directive);
@@ -277,7 +312,6 @@ indirect_data (rtx sym_ref)
return ! lprefix;
}
-
static int
machopic_data_defined_p (rtx sym_ref)
{
@@ -1233,6 +1267,177 @@ 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;
+}
+
+/* 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);
+
+ /* If we are in LTO, then we don't know the state of flag_next_runtime
+ or flag_objc_abi when the code was generated. We set these from the
+ meta-data - which is needed to deal with const string constructors. */
+
+ flag_next_runtime = 1;
+ flag_objc_abi = 2;
+
+ 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 (!strncmp (p, "V2_BASE", 7))
+ return base;
+ else if (!strncmp (p, "V2_STRG", 7))
+ return darwin_sections[cstring_section];
+
+ else if (!strncmp (p, "G2_META", 7) || !strncmp (p, "G2_CLAS", 7))
+ return darwin_sections[objc2_classdefs_section];
+ else if (!strncmp (p, "V2_MREF", 7))
+ return darwin_sections[objc2_message_refs_section];
+ else if (!strncmp (p, "V2_CLRF", 7))
+ return darwin_sections[objc2_classrefs_section];
+ else if (!strncmp (p, "V2_SURF", 7))
+ return darwin_sections[objc2_super_classrefs_section];
+ else if (!strncmp (p, "V2_NLCL", 7))
+ return darwin_sections[objc2_nonlazy_class_section];
+ else if (!strncmp (p, "V2_CLAB", 7))
+ return darwin_sections[objc2_classlist_section];
+ else if (!strncmp (p, "V2_SRFS", 7))
+ return darwin_sections[objc2_selector_refs_section];
+ else if (!strncmp (p, "V2_NLCA", 7))
+ return darwin_sections[objc2_nonlazy_category_section];
+ else if (!strncmp (p, "V2_CALA", 7))
+ return darwin_sections[objc2_categorylist_section];
+
+ else if (!strncmp (p, "V2_PLST", 7))
+ return darwin_sections[objc2_protocollist_section];
+ else if (!strncmp (p, "V2_PRFS", 7))
+ return darwin_sections[objc2_protocolrefs_section];
+
+ else if (!strncmp (p, "V2_INFO", 7))
+ return darwin_sections[objc2_image_info_section];
+
+ else if (!strncmp (p, "V2_EHTY", 7))
+ return darwin_sections[data_coal_section];
+
+ else if (!strncmp (p, "V2_CSTR", 7))
+ return darwin_sections[objc2_constant_string_object_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);
+
+ /* If we are in LTO, then we don't know the state of flag_next_runtime
+ or flag_objc_abi when the code was generated. We set these from the
+ meta-data - which is needed to deal with const string constructors. */
+ flag_next_runtime = 1;
+ if (!global_options_set.x_flag_objc_abi)
+ flag_objc_abi = 1;
+
+ /* String sections first, cos there are lots of strings. */
+ if (!strncmp (p, "V1_STRG", 7))
+ return darwin_sections[cstring_section];
+ else if (!strncmp (p, "V1_CLSN", 7))
+ return darwin_sections[objc_class_names_section];
+ else if (!strncmp (p, "V1_METN", 7))
+ return darwin_sections[objc_meth_var_names_section];
+ else if (!strncmp (p, "V1_METT", 7))
+ return darwin_sections[objc_meth_var_types_section];
+
+ else if (!strncmp (p, "V1_CLAS", 7))
+ return darwin_sections[objc_class_section];
+ else if (!strncmp (p, "V1_META", 7))
+ return darwin_sections[objc_meta_class_section];
+ else if (!strncmp (p, "V1_CATG", 7))
+ return darwin_sections[objc_category_section];
+ else if (!strncmp (p, "V1_PROT", 7))
+ return darwin_sections[objc_protocol_section];
+
+ else if (!strncmp (p, "V1_CLCV", 7))
+ return darwin_sections[objc_class_vars_section];
+ else if (!strncmp (p, "V1_CLIV", 7))
+ return darwin_sections[objc_instance_vars_section];
+
+ else if (!strncmp (p, "V1_CLCM", 7))
+ return darwin_sections[objc_cls_meth_section];
+ else if (!strncmp (p, "V1_CLIM", 7))
+ return darwin_sections[objc_inst_meth_section];
+ else if (!strncmp (p, "V1_CACM", 7))
+ return darwin_sections[objc_cat_cls_meth_section];
+ else if (!strncmp (p, "V1_CAIM", 7))
+ return darwin_sections[objc_cat_inst_meth_section];
+ else if (!strncmp (p, "V1_PNSM", 7))
+ return darwin_sections[objc_cat_inst_meth_section];
+ else if (!strncmp (p, "V1_PCLM", 7))
+ return darwin_sections[objc_cat_cls_meth_section];
+
+ else if (!strncmp (p, "V1_CLPR", 7))
+ return darwin_sections[objc_cat_cls_meth_section];
+ else if (!strncmp (p, "V1_CAPR", 7))
+ return darwin_sections[objc_category_section]; /* ??? CHECK me. */
+
+ else if (!strncmp (p, "V1_PRFS", 7))
+ return darwin_sections[objc_cat_cls_meth_section];
+ else if (!strncmp (p, "V1_CLRF", 7))
+ return darwin_sections[objc_cls_refs_section];
+ else if (!strncmp (p, "V1_SRFS", 7))
+ return darwin_sections[objc_selector_refs_section];
+
+ else if (!strncmp (p, "V1_MODU", 7))
+ return darwin_sections[objc_module_info_section];
+ else if (!strncmp (p, "V1_SYMT", 7))
+ return darwin_sections[objc_symbols_section];
+ else if (!strncmp (p, "V1_INFO", 7))
+ return darwin_sections[objc_image_info_section];
+
+ else if (!strncmp (p, "V1_PLST", 7))
+ return darwin_sections[objc1_prop_list_section];
+ else if (!strncmp (p, "V1_PEXT", 7))
+ return darwin_sections[objc1_protocol_ext_section];
+ else if (!strncmp (p, "V1_CEXT", 7))
+ return darwin_sections[objc1_class_ext_section];
+
+ else if (!strncmp (p, "V2_CSTR", 7))
+ return darwin_sections[objc_constant_string_object_section];
+
+ return base;
+}
+
section *
machopic_select_section (tree decl,
int reloc,
@@ -1331,7 +1536,25 @@ machopic_select_section (tree decl,
gcc_unreachable ();
}
- /* Darwin weird special cases. */
+ /* 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
@@ -1341,29 +1564,53 @@ machopic_select_section (tree decl,
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
+ /* FIXME: This is unsatisfactory for LTO, since it relies on other
+ metadata determining the source FE. */
if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
- {
- if (flag_next_runtime)
- return darwin_sections[objc_constant_string_object_section];
- else
- return darwin_sections[objc_string_object_section];
- }
+ {
+ 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;
+ return base_section;
}
+ /* c) legacy meta-data selection. */
else if (TREE_CODE (decl) == VAR_DECL
&& DECL_NAME (decl)
&& TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
&& IDENTIFIER_POINTER (DECL_NAME (decl))
+ && flag_next_runtime
&& !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_", 6))
{
const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
-
+ static bool warned_objc_46 = false;
/* We shall assert that zero-sized objects are an error in ObjC
meta-data. */
gcc_assert (tree_low_cst (DECL_SIZE_UNIT (decl), 1) != 0);
+
+ /* ??? This mechanism for determining the metadata section is
+ broken when LTO is in use, since the frontend that generated
+ the data is not identified. We will keep the capability for
+ the short term - in case any non-Objective-C programs are using
+ it to place data in specified sections. */
+ if (!warned_objc_46)
+ {
+ location_t loc = DECL_SOURCE_LOCATION (decl);
+ warning_at (loc, 0, "the use of _OBJC_-prefixed variable names"
+ " to select meta-data sections is deprecated at 4.6"
+ " and will be removed in 4.7");
+ warned_objc_46 = true;
+ }
+
if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
return darwin_sections[objc_cls_meth_section];
else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
@@ -1911,6 +2158,30 @@ darwin_emit_weak_or_comdat (FILE *fp, tree decl, const char *name,
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
@@ -2042,6 +2313,7 @@ darwin_output_aligned_bss (FILE *fp, tree decl, const char *name,
{
unsigned int l2align;
bool one, pub, weak;
+ tree meta;
pub = TREE_PUBLIC (decl);
one = DECL_ONE_ONLY (decl);
@@ -2058,6 +2330,14 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
pub, weak, one, (unsigned long)DECL_INITIAL (decl));
#endif
+ /* ObjC metadata can get put in BSS because varasm.c 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)
@@ -2152,6 +2432,8 @@ darwin_asm_output_aligned_decl_common (FILE *fp, tree decl, const char *name,
{
unsigned int l2align;
bool one, weak;
+ tree meta;
+
/* No corresponding var. */
if (decl==NULL)
{
@@ -2176,6 +2458,14 @@ fprintf (fp, "# adcom: %s (%lld,%d) ro %d cst %d stat %d com %d pub %d"
TREE_PUBLIC (decl), weak, one, (unsigned long)DECL_INITIAL (decl));
#endif
+ /* ObjC metadata can get put in BSS because varasm.c 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);
@@ -2222,6 +2512,7 @@ darwin_asm_output_aligned_decl_local (FILE *fp, tree decl, const char *name,
{
unsigned long l2align;
bool one, weak;
+ tree meta;
one = DECL_ONE_ONLY (decl);
weak = (DECL_P (decl)
@@ -2237,6 +2528,14 @@ fprintf (fp, "# adloc: %s (%lld,%d) ro %d cst %d stat %d one %d pub %d"
weak , (unsigned long)DECL_INITIAL (decl));
#endif
+ /* ObjC metadata can get put in BSS because varasm.c 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);