]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Objective-C, Darwin: Do not overalign CFStrings and Objective-C metadata.
authorIain Sandoe <iain@sandoe.co.uk>
Thu, 25 Jan 2024 20:11:09 +0000 (20:11 +0000)
committerIain Sandoe <iain@sandoe.co.uk>
Sun, 28 Jan 2024 11:46:27 +0000 (11:46 +0000)
We have reports of regressions in both Objective-C and Objective-C++ on
Darwin23 (macOS 14).  In some cases, these are linker warnings about the
alignment of CFString constants; in other cases the built executables
crash during runtime initialization.  The underlying issue is the same in
both cases; since the objects (CFStrings, Objective-C meta-data) are TU-
local, we are choosing to increase their alignment for efficiency - to
values greater than ABI alignment.

However, although these objects are TU-local, they are also visible to the
linker (since they are placed in specific named sections).  In many cases
the metadata can be regarded as tables of data, and thus it is expected
that these sections can be concatenated from multiple TUs and the data
treated as tabular.  In order for this to work the data cannot be allowed
to exceed ABI alignment - which leads to the crashes.

For GCC-15+ it would be nice to find a more elegant solution to this issue
(perhaps by adjusting the concept of binds-locally to exclude specific
named sections) - but I do not want to do that in stage 4.

The solution here is to force the alignment to be preserved as created by
setting DECL_USER_ALIGN on the relevant objects.

gcc/ChangeLog:

* config/darwin.cc (darwin_build_constant_cfstring): Prevent over-
alignment of CFString constants by setting DECL_USER_ALIGN.

gcc/objc/ChangeLog:

* objc-next-runtime-abi-02.cc (build_v2_address_table): Prevent
over-alignment of Objective-C metadata by setting DECL_USER_ALIGN
on relevant variables.
(build_v2_protocol_list_address_table): Likewise.
(generate_v2_protocol_list): Likewise.
(generate_v2_meth_descriptor_table): Likewise.
(generate_v2_meth_type_list): Likewise.
(generate_v2_property_table): Likewise.
(generate_v2_dispatch_table): Likewise.
(generate_v2_ivars_list): Likewise.
(generate_v2_class_structs): Likewise.
(build_ehtype): Likewise.
* objc-runtime-shared-support.cc (generate_strings): Likewise.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
gcc/config/darwin.cc
gcc/objc/objc-next-runtime-abi-02.cc
gcc/objc/objc-runtime-shared-support.cc

index 7f43718820bdadb6475caee080ddee1f8ac82a48..9e5d64e6f32cd8d6addf47a30b4ec2d653da6b06 100644 (file)
@@ -3909,6 +3909,7 @@ darwin_build_constant_cfstring (tree str)
       /* global namespace.  */
       DECL_CONTEXT (var) = NULL_TREE;
       DECL_INITIAL (var) = constructor;
+      DECL_USER_ALIGN (var) = 1;
       lang_hooks.decls.pushdecl (var);
       rest_of_decl_compilation (var, 1, 0);
       desc->ccf_str = var;
index a622f4cbf4eee799098b9095ae4856e1c577f204..b3de6d789a5b1f57324bc6a864264c851fef165a 100644 (file)
@@ -2249,6 +2249,7 @@ build_v2_address_table (vec<tree, va_gc> *src, const char *nam, tree attr)
   DECL_PRESERVE_P (decl) = 1;
   expr = objc_build_constructor (type, initlist);
   OBJCMETA (decl, objc_meta, attr);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl, expr);
 }
 
@@ -2323,8 +2324,9 @@ build_v2_protocol_list_address_table (void)
        decl = create_global_decl (objc_protocol_type, buf, /*is def=*/true);
       expr = convert (objc_protocol_type, build_fold_addr_expr (ref->refdecl));
       OBJCMETA (decl, objc_meta, meta_label_protocollist);
-      finish_var_decl (decl, expr);
       DECL_PRESERVE_P (decl) = 1;
+      DECL_USER_ALIGN (decl) = 1;
+      finish_var_decl (decl, expr);
     }
 
     /* TODO: delete the vec.  */
@@ -2402,6 +2404,7 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt)
   /* ObjC2 puts all these in the base section.  */
   OBJCMETA (refs_decl, objc_meta, meta_base);
   DECL_PRESERVE_P (refs_decl) = 1;
+  DECL_USER_ALIGN (refs_decl) = 1;
   finish_var_decl (refs_decl,
                   objc_build_constructor (TREE_TYPE (refs_decl),initlist));
   return refs_decl;
@@ -2510,6 +2513,7 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol,
   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
   /* Get into the right section.  */
   OBJCMETA (decl, objc_meta, attr);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl, objc_build_constructor (method_list_template, v));
   return decl;
 }
@@ -2528,13 +2532,14 @@ generate_v2_meth_type_list (vec<tree>& all_meths, tree protocol,
            IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
   tree decl = start_var_decl (list_type, nam);
   free (nam);
-  OBJCMETA (decl, objc_meta, meta_base);
   vec<constructor_elt, va_gc> *v = NULL;
 
   for (unsigned i = 0; i < size; ++i)
     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
                            add_objc_string (METHOD_ENCODING (all_meths[i]),
                                             meth_var_types));
+  OBJCMETA (decl, objc_meta, meta_base);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl, objc_build_constructor (list_type, v));
   return decl;
 }
@@ -2657,6 +2662,7 @@ generate_v2_property_table (tree context, tree klass_ctxt)
   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
 
   OBJCMETA (decl, objc_meta, meta_base);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits));
   return decl;
 }
@@ -2868,6 +2874,7 @@ generate_v2_dispatch_table (tree chain, const char *name, tree attr)
   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
 
   OBJCMETA (decl, objc_meta, attr);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl,
                   objc_build_constructor (TREE_TYPE (decl), v));
   return decl;
@@ -3165,6 +3172,7 @@ generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ)
                          build_int_cst (integer_type_node, size));
   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
   OBJCMETA (decl, objc_meta, attr);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), inits));
   generating_instance_variables = 0;
   return decl;
@@ -3432,7 +3440,6 @@ generate_v2_class_structs (struct imp_entry *impent)
   decl = start_var_decl (objc_v2_class_ro_template,
                         newabi_append_ro (IDENTIFIER_POINTER
                                                (DECL_NAME (metaclass_decl))));
-
   /* TODO: ivarLayout needs t be built.  */
   initlist =
        build_v2_class_ro_t_initializer (TREE_TYPE (decl), name_expr,
@@ -3442,6 +3449,7 @@ generate_v2_class_structs (struct imp_entry *impent)
                                        class_ivars, NULL_TREE);
   /* The ROs sit in the default const section.  */
   OBJCMETA (decl, objc_meta, meta_base);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl, initlist);
 
   /* static struct class_t _OBJC_METACLASS_Foo = { ... }; */
@@ -3453,6 +3461,7 @@ generate_v2_class_structs (struct imp_entry *impent)
                                      build_fold_addr_expr (UOBJC_V2_CACHE_decl),
                                      build_fold_addr_expr (UOBJC_V2_VTABLE_decl));
   /* The class section attributes are set when they are created.  */
+  DECL_USER_ALIGN (metaclass_decl) = 1;
   finish_var_decl (metaclass_decl, initlist);
   impent->meta_decl = metaclass_decl;
 
@@ -3532,6 +3541,7 @@ generate_v2_class_structs (struct imp_entry *impent)
                                         inst_ivars, props);
   /* The ROs sit in the default const section.  */
   OBJCMETA (decl, objc_meta, meta_base);
+  DECL_USER_ALIGN (decl) = 1;
   finish_var_decl (decl, initlist);
 
   /* static struct class_t _OBJC_CLASS_Foo = { ... }; */
@@ -3543,6 +3553,7 @@ generate_v2_class_structs (struct imp_entry *impent)
                                        build_fold_addr_expr (UOBJC_V2_VTABLE_decl));
 
   /* The class section attributes are set when they are created.  */
+  DECL_USER_ALIGN (class_decl) = 1;
   finish_var_decl (class_decl, initlist);
   impent->class_decl = class_decl;
 
@@ -3717,6 +3728,7 @@ build_ehtype (tree name, const char *eh_name, bool weak)
     DECL_WEAK (ehtype_decl) = 1;
   inits = objc2_build_ehtype_initializer (name_expr, class_name_expr);
   OBJCMETA (ehtype_decl, objc_meta, meta_ehtype);
+  DECL_USER_ALIGN (ehtype_decl) = 1;
   finish_var_decl (ehtype_decl, inits);
   return ehtype_decl;
 }
index 49dac5ea1dbc79ee1f433bc3e88c1e09e6ba23fb..21a88224a0a810ea5abb94fbd01c5ac1981309f1 100644 (file)
@@ -684,6 +684,7 @@ generate_strings (void)
       decl = TREE_PURPOSE (chain);
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                     IDENTIFIER_POINTER (string));
+      DECL_USER_ALIGN (decl) = 1;
       finish_var_decl (decl, string_expr);
     }
 
@@ -693,6 +694,7 @@ generate_strings (void)
       decl = TREE_PURPOSE (chain);
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                     IDENTIFIER_POINTER (string));
+      DECL_USER_ALIGN (decl) = 1;
       finish_var_decl (decl, string_expr);
     }
 
@@ -702,6 +704,7 @@ generate_strings (void)
       decl = TREE_PURPOSE (chain);
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                     IDENTIFIER_POINTER (string));
+      DECL_USER_ALIGN (decl) = 1;
       finish_var_decl (decl, string_expr);
     }
 
@@ -711,6 +714,7 @@ generate_strings (void)
       decl = TREE_PURPOSE (chain);
       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
                                     IDENTIFIER_POINTER (string));
+      DECL_USER_ALIGN (decl) = 1;
       finish_var_decl (decl, string_expr);
     }
 }