diff options
author | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-18 00:07:38 +0000 |
---|---|---|
committer | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-18 00:07:38 +0000 |
commit | 267785bc5842cf1338043dd2e5581c1a3db645ef (patch) | |
tree | c0b6f091c931f0a65e3fb59fbd9fff3f5ba9bde9 /gcc/config/darwin.c | |
parent | d2807aa3377e3c4fc328896869e094f04bfd8022 (diff) | |
download | gcc-267785bc5842cf1338043dd2e5581c1a3db645ef.tar.gz |
Added support for the 64-bit Apple Objective-C runtime
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@170260 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/darwin.c')
-rw-r--r-- | gcc/config/darwin.c | 325 |
1 files changed, 312 insertions, 13 deletions
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index c31aeed4c4e..2969f1020e6 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); |