On Sun, Nov 6, 2016 at 8:40 PM, Iain Sandoe <iain_san...@mentor.com> wrote:
> Hi Folks,
>
> (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.  We need to switch to using the regular sections when a new enough 
> linker is available.
>
> There’s a small change to i386.c to make it possible to switch thunk output 
> between coalesced and “regular’ sections in response to the relevant linker 
> info.

Anything protected by "#if TARGET_MACHO" can be considered as Darwin
specific patch and thus under Darwin port maintainer's approval.

Uros.

> OK for trunk?
> OK for open branches?
> Iain
>
> gcc/
>
> 2016-11-06  Iain Sandoe  <i...@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.
>
>
> ---
>  gcc/config/darwin-sections.def |  5 +++
>  gcc/config/darwin.c            | 77 
> +++++++++++++++++++++++++++---------------
>  gcc/config/darwin.h            |  5 +++
>  gcc/config/darwin.opt          |  6 ++++
>  gcc/config/i386/i386.c         |  2 +-
>  5 files changed, 67 insertions(+), 28 deletions(-)
>
> diff --git a/gcc/config/darwin-sections.def b/gcc/config/darwin-sections.def
> index cbf3e41..8a7e985 100644
> --- a/gcc/config/darwin-sections.def
> +++ b/gcc/config/darwin-sections.def
> @@ -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,
> diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
> index 210c2da..baca46c 100644
> --- a/gcc/config/darwin.c
> +++ b/gcc/config/darwin.c
> @@ -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
> @@ -1247,9 +1256,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]));
> @@ -1418,7 +1427,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];
> @@ -1517,21 +1527,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))
> @@ -1542,7 +1554,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:
> @@ -1564,7 +1576,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];
> @@ -1593,7 +1605,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
>         {
> @@ -2289,14 +2301,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.  */
> @@ -2515,7 +2531,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;
>      }
>
> @@ -2629,7 +2645,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;
>      }
>
> @@ -2699,7 +2715,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;
>      }
>
> @@ -3084,6 +3100,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
> @@ -3609,12 +3631,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)
> @@ -3622,8 +3645,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,
> @@ -3633,23 +3656,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
> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
> index 541bcb3..79fc506 100644
> --- a/gcc/config/darwin.h
> +++ b/gcc/config/darwin.h
> @@ -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
> diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt
> index 5093731..7f2e394 100644
> --- a/gcc/config/darwin.opt
> +++ b/gcc/config/darwin.opt
> @@ -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
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index bffba80..9e9fe02 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -11832,7 +11832,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);
> --
> 2.8.1
>
>

Reply via email to