From: Matthew Fortune <[email protected]>
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 <[email protected]>
Signed-off-by: Faraz Shahbazker <[email protected]>
Signed-off-by: Aleksandar Rakic <[email protected]>
---
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