[Darwin, ld64] Make PIC indirections and constant labels linker-visible.
authorIain Sandoe <iain@codesourcery.com>
Sun, 27 Nov 2016 14:21:51 +0000 (14:21 +0000)
committerIain Sandoe <iains@gcc.gnu.org>
Sun, 27 Nov 2016 14:21:51 +0000 (14:21 +0000)
Indirections:

  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 non-allowed direct accesses to an
  atom of type weak, global which are not allowed.

  To avoid this, we make the 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.

  The implementation here is somewhat heavy-handed in that it will also mark
  indirections to the __IMPORT,__pointers section the same way which is
  really unnecessary, since ld64 _can_ split those into atoms as they are
  fixed size.  FIXME: determine if this is a penalty worth extra code to
  fix.

Similarly, with:

  .const
weak_global_constant:
  ....

LCxx:
  ...

 ld64 can't split the second, causing a warning when it's directly
accessed.

gcc/

2016-11-27  Iain Sandoe  <iain@codesourcery.com>

PR target/71767
* config/darwin.c (imachopic_indirection_name): Make data
section indirections linker-visible.
* config/darwin.h (ASM_GENERATE_INTERNAL_LABEL): Make local
constant labels linker-visible.

From-SVN: r242893

gcc/ChangeLog
gcc/config/darwin.c
gcc/config/darwin.h

index 80124c2091011ff4a1f03037619b1348a8a9cd23..450086ec386c2e25c139cdc3ace2bbec47724896 100644 (file)
@@ -1,3 +1,11 @@
+2016-11-27  Iain Sandoe  <iain@codesourcery.com>
+
+       PR target/71767
+       * config/darwin.c (imachopic_indirection_name): Make data
+       section indirections linker-visible.
+       * config/darwin.h (ASM_GENERATE_INTERNAL_LABEL): Make local
+       constant labels linker-visible.
+
 2016-11-26  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        * tree.c (build_common_tree_nodes): Initialize ptrdiff_type_node.
index e9ce6d2ffda5fe5be7dfa2846399aa76c4bc125a..1a67c4ce4e331536467cbcf3831fd5a21c593ab7 100644 (file)
@@ -474,7 +474,31 @@ indirection_hasher::equal (machopic_indirection *s, const char *k)
 }
 
 /* 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.  */
+   stub (if STUB_B is true) corresponding to the given name.
+
+  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 non-allowed direct accesses to an
+  atom of type weak, global which are not allowed.
+
+  To avoid this, we make the 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.
+
+  The implementation here is somewhat heavy-handed in that it will also mark
+  indirections to the __IMPORT,__pointers section the same way which is
+  really unnecessary, since ld64 _can_ split those into atoms as they are
+  fixed size.  FIXME: determine if this is a penalty worth extra code to
+  fix.
+
+*/
 
 const char *
 machopic_indirection_name (rtx sym_ref, bool stub_p)
@@ -485,6 +509,7 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
   machopic_indirection *p;
   bool needs_quotes;
   const char *suffix;
+  char L_or_l = 'L';
   const char *prefix = user_label_prefix;
   const char *quote = "";
   tree id;
@@ -519,9 +544,13 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
   if (stub_p)
     suffix = STUB_SUFFIX;
   else
-    suffix = NON_LAZY_POINTER_SUFFIX;
+    {
+      suffix = NON_LAZY_POINTER_SUFFIX;
+      /* Let the linker see this.  */
+      L_or_l = 'l';
+    }
 
-  buffer = XALLOCAVEC (char, strlen ("&L")
+  buffer = XALLOCAVEC (char, 2  /* strlen ("&L") or ("&l") */
                   + strlen (prefix)
                   + namelen
                   + strlen (suffix)
@@ -529,7 +558,7 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
                   + 1 /* '\0' */);
 
   /* Construct the name of the non-lazy pointer or stub.  */
-  sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
+  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);
index 98d2382009db113d2ea05586e9b804f1f3fabd94..045f70b2abb30dd762fdea11d07c042d06ce6aee 100644 (file)
@@ -716,9 +716,16 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
   { "weak_import", 0, 0, true, false, false,                                \
     darwin_handle_weak_import_attribute, false }
 
+/* Make local constant labels linker-visible, so that if one follows a
+   weak_global constant, ld64 will be able to separate the atoms.  */
 #undef ASM_GENERATE_INTERNAL_LABEL
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
-  sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM))
+  do {                                                 \
+    if (strcmp ("LC", PREFIX) == 0)                    \
+      sprintf (LABEL, "*%s%ld", "lC", (long)(NUM));    \
+    else                                               \
+      sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM));  \
+  } while (0)
 
 #undef TARGET_ASM_MARK_DECL_PRESERVED
 #define TARGET_ASM_MARK_DECL_PRESERVED darwin_mark_decl_preserved