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

Reply via email to