[Darwin] Fix PR71767 - adjust the sections used where necessary.
authorIain Sandoe <iain@codesourcery.com>
Sun, 27 Nov 2016 14:34:54 +0000 (14:34 +0000)
committerIain Sandoe <iains@gcc.gnu.org>
Sun, 27 Nov 2016 14:34:54 +0000 (14:34 +0000)
 (much) Older Darwin linkers needed separate sections marked "coalesce" to
 allow for weak symbol coalescing.  This has not been needed for some time
 and is now deprecated, newer assemblers warn if the old coalesced sections
 are used.

gcc/

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

PR target/71767
* config/darwin-sections.def (picbase_thunk_section): New.
* config/darwin.c (darwin_init_sections): Set up picbase thunk
section. (darwin_rodata_section, darwin_objc2_section,
machopic_select_section, darwin_asm_declare_constant_name,
darwin_emit_weak_or_comdat, darwin_function_section): Don’t use
coalesced with newer linkers.
(darwin_override_options): Decide on usage of coalesed sections
on the basis of the target linker version.
* config/darwin.h (MIN_LD64_NO_COAL_SECTS): New.
* config/darwin.opt  (mtarget-linker): New.
* config/i386/i386.c (ix86_code_end): Do not force the thunks into
a coalesced section, instead use a thunks section.

From-SVN: r242895

gcc/ChangeLog
gcc/config/darwin-sections.def
gcc/config/darwin.c
gcc/config/darwin.h
gcc/config/darwin.opt
gcc/config/i386/i386.c

index 27e0615c15d208e9a82ebf86c814870427e9ae42..ba2526c99c34fa024250c19de5bb23369e60a00d 100644 (file)
@@ -1,3 +1,19 @@
+2016-11-27  Iain Sandoe  <iain@codesourcery.com>
+
+       PR target/71767
+       * config/darwin-sections.def (picbase_thunk_section): New.
+       * config/darwin.c (darwin_init_sections): Set up picbase thunk
+       section. (darwin_rodata_section, darwin_objc2_section,
+       machopic_select_section, darwin_asm_declare_constant_name,
+       darwin_emit_weak_or_comdat, darwin_function_section): Don’t use
+       coalesced with newer linkers.
+       (darwin_override_options): Decide on usage of coalesed sections
+       on the basis of the target linker version.
+       * config/darwin.h (MIN_LD64_NO_COAL_SECTS): New.
+       * config/darwin.opt  (mtarget-linker): New.
+       * config/i386/i386.c (ix86_code_end): Do not force the thunks into
+       a coalesced section, instead use a thunks section.
+
 2016-11-27  Iain Sandoe  <iain@codesourcery.com>
 
        PR target/71767
index cbf3e41e9ac67f373a940d77da470eb57b183429..8a7e985c85faca9694585ba262fa452ba1c28ce3 100644 (file)
@@ -31,6 +31,11 @@ along with GCC; see the file COPYING3.  If not see
 DEF_SECTION (text_coal_section, SECTION_CODE|SECTION_NO_ANCHOR,
             ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", 0)
 
+/* We define a picbase thunks section separately, so that we can override the
+   def to be '.text' for versions of ld64 that handle coalescing.  */
+DEF_SECTION (picbase_thunk_section, SECTION_CODE|SECTION_NO_ANCHOR,
+            ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", 0)
+
 DEF_SECTION (text_hot_section, SECTION_CODE,
             ".section __TEXT,__text_hot,regular,pure_instructions", 0)
 DEF_SECTION (text_cold_section, SECTION_CODE,
index 1a67c4ce4e331536467cbcf3831fd5a21c593ab7..316e2178f5bbf1a9cd91c6fc09b7ac4ca2f1d6d8 100644 (file)
@@ -97,6 +97,10 @@ int darwin_running_cxx;
 /* Some code-gen now depends on OS major version numbers (at least).  */
 int generating_for_darwin_version ;
 
+/* For older linkers we need to emit special sections (marked 'coalesced') for
+   for weak or single-definition items.  */
+static bool ld_uses_coal_sects = false;
+
 /* Section names.  */
 section * darwin_sections[NUM_DARWIN_SECTIONS];
 
@@ -220,6 +224,11 @@ darwin_init_sections (void)
   readonly_data_section = darwin_sections[const_section];
   exception_section = darwin_sections[darwin_exception_section];
   eh_frame_section = darwin_sections[darwin_eh_frame_section];
+
+  /* If our linker is new enough to coalesce weak symbols, then we
+     can just put picbase_thunks into the text section.  */
+  if (! ld_uses_coal_sects )
+    darwin_sections[picbase_thunk_section] = text_section;
 }
 
 int
@@ -1246,9 +1255,9 @@ darwin_mark_decl_preserved (const char *name)
 }
 
 static section *
-darwin_rodata_section (int weak, bool zsize)
+darwin_rodata_section (int use_coal, bool zsize)
 {
-  return (weak
+  return (use_coal
          ? darwin_sections[const_coal_section]
          : (zsize ? darwin_sections[zobj_const_section]
                   : darwin_sections[const_section]));
@@ -1417,7 +1426,8 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
     return darwin_sections[objc2_image_info_section];
 
   else if (!strncmp (p, "V2_EHTY", 7))
-    return darwin_sections[data_coal_section];
+    return ld_uses_coal_sects ? darwin_sections[data_coal_section]
+                              : data_section;
 
   else if (!strncmp (p, "V2_CSTR", 7))
     return darwin_sections[objc2_constant_string_object_section];
@@ -1516,21 +1526,23 @@ machopic_select_section (tree decl,
                         int reloc,
                         unsigned HOST_WIDE_INT align)
 {
-  bool zsize, one, weak, ro;
+  bool zsize, one, weak, use_coal, ro;
   section *base_section = NULL;
 
   weak = (DECL_P (decl)
          && DECL_WEAK (decl)
          && !lookup_attribute ("weak_import", DECL_ATTRIBUTES (decl)));
 
-  zsize = (DECL_P (decl) 
+  zsize = (DECL_P (decl)
           && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == CONST_DECL) 
           && tree_to_uhwi (DECL_SIZE_UNIT (decl)) == 0);
 
-  one = DECL_P (decl) 
+  one = DECL_P (decl)
        && TREE_CODE (decl) == VAR_DECL 
        && DECL_COMDAT_GROUP (decl);
 
+  use_coal = (weak || one) && ld_uses_coal_sects;
+
   ro = TREE_READONLY (decl) || TREE_CONSTANT (decl) ;
 
   switch (categorize_decl_for_section (decl, reloc))
@@ -1541,7 +1553,7 @@ machopic_select_section (tree decl,
 
     case SECCAT_RODATA:
     case SECCAT_SRODATA:
-      base_section = darwin_rodata_section (weak, zsize);
+      base_section = darwin_rodata_section (use_coal, zsize);
       break;
 
     case SECCAT_RODATA_MERGE_STR:
@@ -1563,7 +1575,7 @@ machopic_select_section (tree decl,
     case SECCAT_DATA_REL_RO_LOCAL:
     case SECCAT_SDATA:
     case SECCAT_TDATA:
-      if (weak || one)
+      if (use_coal)
        {
          if (ro)
            base_section = darwin_sections[const_data_coal_section];
@@ -1592,7 +1604,7 @@ machopic_select_section (tree decl,
     case SECCAT_BSS:
     case SECCAT_SBSS:
     case SECCAT_TBSS:
-      if (weak || one) 
+      if (use_coal)
        base_section = darwin_sections[data_coal_section];
       else
        {
@@ -2288,14 +2300,18 @@ darwin_asm_declare_constant_name (FILE *file, const char *name,
 static void
 darwin_emit_weak_or_comdat (FILE *fp, tree decl, const char *name,
                                  unsigned HOST_WIDE_INT size, 
+                                 bool use_coal,
                                  unsigned int align)
 {
-  /* Since the sections used here are coalesed, they will not be eligible
-     for section anchors, and therefore we don't need to break that out.  */
+  /* Since the sections used here are coalesced, they will not be eligible
+     for section anchors, and therefore we don't need to break that out.
+     CHECKME: for modern linker on PowerPC.  */
  if (TREE_READONLY (decl) || TREE_CONSTANT (decl))
-    switch_to_section (darwin_sections[const_data_coal_section]);
+    switch_to_section (use_coal ? darwin_sections[const_data_coal_section]
+                               : darwin_sections[const_data_section]);
   else
-    switch_to_section (darwin_sections[data_coal_section]);
+    switch_to_section (use_coal ? darwin_sections[data_coal_section]
+                               : data_section);
 
   /* To be consistent, we'll allow darwin_asm_declare_object_name to assemble
      the align info for zero-sized items... but do it here otherwise.  */
@@ -2514,7 +2530,7 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
     {
       /* Weak or COMDAT objects are put in mergeable sections.  */
       darwin_emit_weak_or_comdat (fp, decl, name, size, 
-                                       DECL_ALIGN (decl));
+                                 ld_uses_coal_sects, DECL_ALIGN (decl));
       return;
     } 
 
@@ -2628,7 +2644,7 @@ fprintf (fp, "# adcom: %s (%lld,%d) ro %d cst %d stat %d com %d pub %d"
     {
       /* Weak or COMDAT objects are put in mergable sections.  */
       darwin_emit_weak_or_comdat (fp, decl, name, size, 
-                                       DECL_ALIGN (decl));
+                                 ld_uses_coal_sects, DECL_ALIGN (decl));
       return;
     } 
 
@@ -2698,7 +2714,7 @@ fprintf (fp, "# adloc: %s (%lld,%d) ro %d cst %d stat %d one %d pub %d"
     {
       /* Weak or COMDAT objects are put in mergable sections.  */
       darwin_emit_weak_or_comdat (fp, decl, name, size, 
-                                       DECL_ALIGN (decl));
+                                 ld_uses_coal_sects, DECL_ALIGN (decl));
       return;
     } 
 
@@ -3083,6 +3099,12 @@ darwin_override_options (void)
       /* Earlier versions are not specifically accounted, until required.  */
     }
 
+  /* Older Darwin ld could not coalesce weak entities without them being
+     placed in special sections.  */
+  if (darwin_target_linker
+      && (strverscmp (darwin_target_linker, MIN_LD64_NO_COAL_SECTS) < 0))
+    ld_uses_coal_sects = true;
+
   /* In principle, this should be c-family only.  However, we really need to
      set sensible defaults for LTO as well, since the section selection stuff
      should check for correctness re. the ABI.  TODO: check and provide the
@@ -3608,12 +3630,13 @@ darwin_function_section (tree decl, enum node_frequency freq,
                          bool startup, bool exit)
 {
   /* Decide if we need to put this in a coalescable section.  */
-  bool weak = (decl 
+  bool weak = (decl
               && DECL_WEAK (decl)
               && (!DECL_ATTRIBUTES (decl)
                   || !lookup_attribute ("weak_import", 
                                          DECL_ATTRIBUTES (decl))));
 
+  bool use_coal = weak && ld_uses_coal_sects;
   /* If there is a specified section name, we should not be trying to
      override.  */
   if (decl && DECL_SECTION_NAME (decl) != NULL)
@@ -3621,8 +3644,8 @@ darwin_function_section (tree decl, enum node_frequency freq,
 
   /* We always put unlikely executed stuff in the cold section.  */
   if (freq == NODE_FREQUENCY_UNLIKELY_EXECUTED)
-    return (weak) ? darwin_sections[text_cold_coal_section]
-                 : darwin_sections[text_cold_section];
+    return (use_coal) ? darwin_sections[text_cold_coal_section]
+                     : darwin_sections[text_cold_section];
 
   /* If we have LTO *and* feedback information, then let LTO handle
      the function ordering, it makes a better job (for normal, hot,
@@ -3632,23 +3655,23 @@ darwin_function_section (tree decl, enum node_frequency freq,
 
   /* Non-cold startup code should go to startup subsection.  */
   if (startup)
-    return (weak) ? darwin_sections[text_startup_coal_section]
-                 : darwin_sections[text_startup_section];
+    return (use_coal) ? darwin_sections[text_startup_coal_section]
+                     : darwin_sections[text_startup_section];
 
   /* Similarly for exit.  */
   if (exit)
-    return (weak) ? darwin_sections[text_exit_coal_section]
-                 : darwin_sections[text_exit_section];
+    return (use_coal) ? darwin_sections[text_exit_coal_section]
+                     : darwin_sections[text_exit_section];
 
   /* Place hot code.  */
   if (freq == NODE_FREQUENCY_HOT)
-    return (weak) ? darwin_sections[text_hot_coal_section]
-                 : darwin_sections[text_hot_section];
+    return (use_coal) ? darwin_sections[text_hot_coal_section]
+                     : darwin_sections[text_hot_section];
 
   /* Otherwise, default to the 'normal' non-reordered sections.  */
 default_function_sections:
-  return (weak) ? darwin_sections[text_coal_section]
-               : text_section;
+  return (use_coal) ? darwin_sections[text_coal_section]
+                   : text_section;
 }
 
 /* When a function is partitioned between sections, we need to insert a label
index 541bcb3c8e5c3c72ab07be84bf3f57f16302d5ae..79fc50637e367f67594a9829622c0a72e310d5d3 100644 (file)
@@ -940,6 +940,11 @@ extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **);
    fall-back default.  */
 #define DEF_MIN_OSX_VERSION "10.5"
 
+/* Later versions of ld64 support coalescing weak code/data without requiring
+   that they be placed in specially identified sections.  This is the earliest
+   _tested_ version known to support this so far.  */
+#define MIN_LD64_NO_COAL_SECTS "236.4"
+
 #ifndef LD64_VERSION
 #define LD64_VERSION "85.2"
 #else
index 509373154386618652ad17cfe21facb9383ef3a5..7f2e394ae79cd44b870bbfb090676c631be265fb 100644 (file)
@@ -391,5 +391,11 @@ Driver Separate
 sub_umbrella
 Driver Separate
 
+; Certain aspects of code-gen may be improved / adjusted if the version of ld64
+; is sufficiently modern.
+mtarget-linker
+Target RejectNegative Joined Separate Report Var(darwin_target_linker) Init(LD64_VERSION)
+The version of ld64 in use for this toolchain.
+
 undefined
 Driver Separate
index a96d597d0ed00280c6240b3ea8afe5c9d03ee574..1dd5669bfea9623cb508e16364f975f5c440574f 100644 (file)
@@ -11886,7 +11886,7 @@ ix86_code_end (void)
 #if TARGET_MACHO
       if (TARGET_MACHO)
        {
-         switch_to_section (darwin_sections[text_coal_section]);
+         switch_to_section (darwin_sections[picbase_thunk_section]);
          fputs ("\t.weak_definition\t", asm_out_file);
          assemble_name (asm_out_file, name);
          fputs ("\n\t.private_extern\t", asm_out_file);