@@ -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)
@@ -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.
@@ -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
@@ -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"
new file mode 100644
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-munique-sections=non-existent-file.txt" } */
+/* { dg-error "Bad filename for -munique-sections:" "" { target *-*-* } 0 } */
new file mode 100644
@@ -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;
new file mode 100644
@@ -0,0 +1,3 @@
+foo
+bar
+none
@@ -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: