From: Matthew Fortune <[email protected]>
Read a list of explicitly named sections and make each matching section
unique by appending the associated symbol name. This allows functions
and variables to be emitted separately while retaining their requested
base section.
gcc/ChangeLog:
* 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/ChangeLog:
* 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]>
Signed-off-by: Eldar Osmanovic <[email protected]>
---
gcc/config/mips/mips.cc | 54 +++++++++++++++++--
gcc/config/mips/mips.opt | 4 ++
gcc/doc/invoke.texi | 11 ++++
gcc/testsuite/gcc.target/mips/mips.exp | 19 +++++++
.../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, 116 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 6e5e7afe80b..8ff3ed0d309 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -646,9 +646,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];
@@ -660,7 +661,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;
}
@@ -9905,16 +9906,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. */
static 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))
{
@@ -20700,7 +20742,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 5012515df15..1c07bc78de4 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -541,3 +541,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 8be323969a4..e3a3ddc2324 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1238,6 +1238,7 @@ Objective-C and Objective-C++ Dialects}.
-membedded-data -muninit-const-in-rodata
-msdata-num=@var{num}
-msdata-opt-list=@var{file}
+-munique-sections=@var{file}
-mcode-readable=@var{setting} -mno-data-in-code -mcode-xonly
-mdead-loads -mno-dead-loads
-msplit-addresses -mexplicit-relocs -mexplicit-relocs=@var{release}
@@ -29621,6 +29622,16 @@ 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 06795fdc253..493ec85225e 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -318,6 +318,7 @@ foreach option {
sdata-num
sdata-opt-list
tune
+ unique-sections
} {
lappend mips_option_groups $option "-m$option=.*"
}
@@ -1041,6 +1042,24 @@ 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 0dbc35d926a..8cebfd6d561 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -496,6 +496,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
@@ -7572,6 +7578,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.43.0