From 794fa8a6ab0a9fa4541e9528d7c6595299385e5f Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 27 Nov 2016 14:34:54 +0000 Subject: [PATCH] [Darwin] Fix PR71767 - adjust the sections used where necessary. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit (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 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 | 16 +++++++++ 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 +- 6 files changed, 83 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 27e0615..ba2526c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,22 @@ 2016-11-27 Iain Sandoe 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 + + PR target/71767 * configure.ac (with-ld64): New var, set for Darwin, set on detection of ld64, gcc_cv_ld64_export_dynamic: New, New test. * config/darwin.h: Use LD64_HAS_DYNAMIC export. DEF_LD64: New, 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 1a67c4c..316e217 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 @@ -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 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 a96d597..1dd5669 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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); -- 2.7.4