https://gcc.gnu.org/g:e38a8582d5b490976e72b7dbcd388e6b81f338c0

commit r16-3103-ge38a8582d5b490976e72b7dbcd388e6b81f338c0
Author: Iain Sandoe <i...@sandoe.co.uk>
Date:   Thu Aug 7 17:51:14 2025 +0100

    Darwin: Anchor block internal symbols must not be linker-visible.
    
    When we are using section anchors, there's a requirement that the
    sequence of the content is an unbroken block.  If we allow linker-
    visible symbols in that block, ld(64) would be able to break it
    into sub-sections on those symbol boundaries.
    
    Do not allow symbols that should be visible to be anchored.
    Do not make anchor block internal symbols linker-visible.
    
    gcc/ChangeLog:
    
            * config/darwin.cc (darwin_encode_section_info): Do not
            make anchored symbols linker-visible.
            (darwin_use_anchors_for_symbol_p): Disallow anchoring on
            symbols that must be linker-visible (or external), even
            if the definitions are in this TU.
    
    Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>

Diff:
---
 gcc/config/darwin.cc | 38 +++++++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc
index be2daed4f66a..1724084b6287 100644
--- a/gcc/config/darwin.cc
+++ b/gcc/config/darwin.cc
@@ -1298,6 +1298,29 @@ darwin_encode_section_info (tree decl, rtx rtl, int 
first)
      SYMBOL_FLAG_EXTERNAL.  */
   default_encode_section_info (decl, rtl, first);
 
+  if (CONSTANT_CLASS_P (decl))
+    {
+      bool is_str = TREE_CODE (decl) == STRING_CST;
+      rtx sym_ref = XEXP (rtl, 0);
+
+      /* If this is a string cst or not anchored we have nothing to do.  */
+      if (is_str || !SYMBOL_REF_HAS_BLOCK_INFO_P (sym_ref))
+       return;
+
+      tree sym_decl = SYMBOL_REF_DECL (sym_ref);
+      const char *name = XSTR (sym_ref, 0);
+      gcc_checking_assert (strncmp ("*lC", name, 3) == 0);
+
+      char *buf;
+      /* Lets identify anchored constants with a different prefix, for the
+         sake of inspection only.  */
+      buf = xasprintf ("*LaC%s", &name[3]);
+      if (sym_decl)
+       DECL_NAME (sym_decl) = get_identifier (buf);
+      XSTR (sym_ref, 0) = ggc_strdup (buf);
+      free (buf);
+    }
+
   if (! VAR_OR_FUNCTION_DECL_P (decl))
     return;
 
@@ -3297,11 +3320,16 @@ 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.  */
+      tree decl = SYMBOL_REF_DECL (symbol);
+      /* If the symbol would be linker-visible, then it can split at that
+        so we must disallow.  This is more strict than the default impl.
+        TODO: add other cases.  */
+      if (decl && DECL_P (decl)
+         && (TREE_PUBLIC (decl) || !DECL_ARTIFICIAL (decl)))
+       return false;
+
+      /* We mark sections containing unsuitable entries.  */
+      section *sect = SYMBOL_REF_BLOCK (symbol)->sect;
       if (sect->common.flags & SECTION_NO_ANCHOR)
        return false;

Reply via email to