From: Matthew Fortune <matthew.fort...@imgtec.com> gcc/ * config/mips/mips.cc (mips_unique_sections_list): New global variable. (mips_read_list): Update prototype and error message. (ultimate_transparent_alias_target): New function. Copied from varasm.c. (mips_asm_unique_section): Update to rename unique sections. (mips_option_override): Read the unique_sections file. * config/mips/mips.opt: Add -munique-sections option. * doc/invoke.texi: Document -munique-sections * varasm.cc (resolve_unique_section): Try to create a unique section even for explicitly provided section names. (default_unique_section): Do nothing if a section is already set.
gcc/testsuite/ * gcc.target/mips/mips.exp: Support -munique-sections. (mips-dg-options): Translate filename argument to -munique-sections. * gcc.target/mips/unique-sections-bad.c: New file. * gcc.target/mips/unique-sections.c: Likewise. * gcc.target/mips/unique-sections.txt: Likewise. Cherry-picked 9cd38c0b698287caff43d0aac3c963bb425391d8 from https://github.com/MIPS/gcc Signed-off-by: Matthew Fortune <matthew.fort...@imgtec.com> Signed-off-by: Faraz Shahbazker <fshahbaz...@wavecomp.com> Signed-off-by: Aleksandar Rakic <aleksandar.ra...@htecgroup.com> --- gcc/config/mips/mips.cc | 54 +++++++++++++++++-- gcc/config/mips/mips.opt | 4 ++ gcc/doc/invoke.texi | 10 ++++ gcc/testsuite/gcc.target/mips/mips.exp | 18 +++++++ .../gcc.target/mips/unique-sections-bad.c | 3 ++ .../gcc.target/mips/unique-sections.c | 15 ++++++ .../gcc.target/mips/unique-sections.txt | 3 ++ gcc/varasm.cc | 11 ++++ 8 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/unique-sections-bad.c create mode 100644 gcc/testsuite/gcc.target/mips/unique-sections.c create mode 100644 gcc/testsuite/gcc.target/mips/unique-sections.txt diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index 6e48feeb560..55d06b87c0d 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -647,9 +647,10 @@ struct mips_sdata_entry }; static struct mips_sdata_entry *mips_sdata_opt_list; +static struct mips_sdata_entry *mips_unique_sections_list; static struct mips_sdata_entry * -mips_read_list (const char * filename) +mips_read_list (const char * filename, const char *opt_name) { FILE *fd; char line[256]; @@ -661,7 +662,7 @@ mips_read_list (const char * filename) fd = fopen (filename, "r"); if (fd == NULL) { - error ("Bad filename for -msdata-opt-list: %s\n", filename); + error ("Bad filename for %s: %s\n", opt_name, filename); return NULL; } @@ -9884,16 +9885,57 @@ mips_encode_section_info (tree decl, rtx rtl, int first) } } +/* This should be the same as ultimate_transparent_alias_target from + gcc/varasm.c. */ + +static inline tree +ultimate_transparent_alias_target (tree *alias) +{ + tree target = *alias; + + if (IDENTIFIER_TRANSPARENT_ALIAS (target)) + { + gcc_assert (TREE_CHAIN (target)); + target = ultimate_transparent_alias_target (&TREE_CHAIN (target)); + gcc_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target) + && ! TREE_CHAIN (target)); + *alias = target; + } + + return target; +} + /* Implement TARGET_ASM_UNIQUE_SECTION. */ void mips_asm_unique_section (tree decl, int reloc) { + const char *old_secname = DECL_SECTION_NAME (decl); + + if (old_secname != NULL + && mips_find_list (old_secname, mips_unique_sections_list)) + { + tree id = DECL_ASSEMBLER_NAME (decl); + ultimate_transparent_alias_target (&id); + const char *name = IDENTIFIER_POINTER (id); + name = targetm.strip_name_encoding (name); + + /* We may end up here twice for data symbols, + so we need to prevent renaming sections twice. */ + char *suffix = ACONCAT ((".", name, NULL)); + if (strstr (old_secname, suffix) == NULL) + { + char *new_secname = ACONCAT ((old_secname, suffix, NULL)); + set_decl_section_name (decl, new_secname); + } + } + default_unique_section (decl, reloc); const char *name = DECL_SECTION_NAME (decl); - if (mips_sdata_section_num > -1 + if (old_secname == NULL + && mips_sdata_section_num > -1 && (strncmp (".sdata", name, 6) == 0 || strncmp (".sbss", name, 5) == 0)) { @@ -20664,7 +20706,11 @@ mips_option_override (void) if (TARGET_FLIP_MIPS16) TARGET_INTERLINK_COMPRESSED = 1; - mips_sdata_opt_list = mips_read_list (mips_sdata_opt_list_file); + mips_sdata_opt_list = mips_read_list (mips_sdata_opt_list_file, + "-msdata-opt-list"); + + mips_unique_sections_list = mips_read_list (mips_unique_sections_file, + "-munique-sections"); /* Set the small data limit. */ mips_small_data_threshold = (OPTION_SET_P (g_switch_value) diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index ca7d064dd6e..e0a305aec22 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -548,3 +548,7 @@ Place all gp relative data in sdata section number NUM. msdata-opt-list= Target RejectNegative Joined Var(mips_sdata_opt_list_file) msdata-opt-list=FILE Use to specify variables to go in the .sdata section. + +munique-sections= +Target RejectNegative Joined Var(mips_unique_sections_file) +munique-sections=FILE Use to specify sections that should be made unique. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d3b0187daff..952baf872ec 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1153,6 +1153,7 @@ Objective-C and Objective-C++ Dialects}. -membedded-data -mno-embedded-data -msdata-num=@var{num} -msdata-opt-list=@var{file} +-munique-sections=@var{file} -muninit-const-in-rodata -mno-uninit-const-in-rodata -mcode-readable=@var{setting} -mdead-loads -mno-dead-loads @@ -28842,6 +28843,15 @@ small data model. This is equivalent to adding For this option to take effect on uninitialised globals then @option{-fno-common} must also be used. +@opindex -munique-sections +@item -munique-sections +Read a list of section names from a file that specify which of the explicitly +named sections should have unique names. This is the equivalent of adding +@code{__attribute__((section ("section_name.symbol_name")))} to the source code +declaration. +Having a data symbol which is matched by both @option{-msdata-opt-list} and +@option{-munique-sections} will cause a compilation error. + @opindex muninit-const-in-rodata @opindex mno-uninit-const-in-rodata @item -muninit-const-in-rodata diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index bce662842f2..b0825ca4339 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -315,6 +315,7 @@ foreach option { nan r10k-cache-barrier tune + unique-sections } { lappend mips_option_groups $option "-m$option=.*" } @@ -1038,6 +1039,23 @@ proc mips-dg-options { args } { } } + # Pass an absolute file path to -munique-sections=. + set unq_sec_test_option_p [mips_test_option_p options unique-sections] + + if { $unq_sec_test_option_p } { + set unq_sec [mips_option options unique-sections] + if { ![regexp {=.*$} $unq_sec filename] } { + error "Unrecognized specification: $unq_sec" + } + set filename [string trimleft $filename "="] + + global srcdir + global subdir + set new_unq_sec "-munique-sections=$srcdir/$subdir/$filename" + + set options(option,[mips_option_group $new_unq_sec]) $new_unq_sec + } + # Handle dependencies between the test options and the optimization ones. mips_option_dependency options "-fno-unroll-loops" "-fno-unroll-all-loops" mips_option_dependency options "-pg" "-fno-omit-frame-pointer" diff --git a/gcc/testsuite/gcc.target/mips/unique-sections-bad.c b/gcc/testsuite/gcc.target/mips/unique-sections-bad.c new file mode 100644 index 00000000000..be75ffd999b --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/unique-sections-bad.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-munique-sections=non-existent-file.txt" } */ +/* { dg-error "Bad filename for -munique-sections:" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/mips/unique-sections.c b/gcc/testsuite/gcc.target/mips/unique-sections.c new file mode 100644 index 00000000000..7f2ca62ec1a --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/unique-sections.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-munique-sections=unique-sections.txt" } */ +/* { dg-final { scan-assembler "\t.section\tfoo.f" } } */ +/* { dg-final { scan-assembler "\t.section\tfoof" } } */ +/* { dg-final { scan-assembler "\t.section\tbar.h" } } */ +/* { dg-final { scan-assembler "\t.section\tbaz" } } */ +/* { dg-final { scan-assembler "\t.section\tbar.k" } } */ + +int __attribute__((section("foo"))) f (void) { return 0; } +int __attribute__((section("foof"))) g (void) { return 0; } +int __attribute__((section("bar"))) h (void) { return 0; } +int __attribute__((section("baz"))) i (void) { return 0; } +int j (void) { return 0; } +int __attribute__((section("bar"))) k; +int l; diff --git a/gcc/testsuite/gcc.target/mips/unique-sections.txt b/gcc/testsuite/gcc.target/mips/unique-sections.txt new file mode 100644 index 00000000000..b16db8d3be9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/unique-sections.txt @@ -0,0 +1,3 @@ +foo +bar +none diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 0712b486029..db603e44e55 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -491,6 +491,12 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, symtab_node::get (decl)->call_for_symbol_and_aliases (set_implicit_section, NULL, true); } + + /* Allow target specific handling of unique sections even if an explicit + section name is used. */ + else if (DECL_SECTION_NAME (decl) != NULL + && targetm_common.have_named_sections) + targetm.asm_out.unique_section (decl, reloc); } #ifdef BSS_SECTION_ASM_OP @@ -7353,6 +7359,11 @@ default_unique_section (tree decl, int reloc) char *string; tree id; + /* If the symbol has a section name assigned at this point, then it is the + name of a user-specified unique section and we should leave it alone. */ + if (DECL_SECTION_NAME (decl) != NULL) + return; + switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_TEXT: -- 2.34.1