This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix default_binds_local_p_2 for extern protected data
- From: Szabolcs Nagy <szabolcs dot nagy at arm dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Marcus Shawcroft <marcus dot shawcroft at arm dot com>, Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>, Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>, "H.J. Lu" <hjl dot tools at gmail dot com>
- Date: Wed, 22 Jul 2015 18:01:48 +0100
- Subject: [PATCH] Fix default_binds_local_p_2 for extern protected data
- Authentication-results: sourceware.org; auth=none
The commit
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=222184
changed a true to false in varasm.c:
bool
default_binds_local_p_2 (const_tree exp)
{
- return default_binds_local_p_3 (exp, flag_shlib != 0, true, true);
+ return default_binds_local_p_3 (exp, flag_shlib != 0, true, false,
+ !flag_pic);
}
where
default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate,
- bool extern_protected_data)
+ bool extern_protected_data, bool common_local_p)
{
false means that extern protected data binds locally,
which is wrong if the target can have copy relocations
against it (then the address must be loaded from GOT
otherwise the main executable will see different address).
Currently S/390, ARM and AArch64 targets use this predicate
and the current default is wrong for all of them (they can
have copy relocs) so I changed the default instead of doing
it in a target specific way.
The equivalent x86_64 bug was
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248
the default was changed for
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65780
now i opened
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66912
for arm and aarch64.
Needs a further binutils patch too to emit R_*_GLOB_DAT
instead of R_*_RELATIVE relocs for protected data.
The glibc elf/tst-protected1a and elf/tst-protected1b
tests depend on this.
Tested ARM and AArch64 targets.
gcc/ChangeLog:
2015-07-22 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR target/66912
* varasm.c (default_binds_local_p_2): Turn on extern_protected_data.
gcc/testsuite/ChangeLog:
2015-07-22 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR target/66912
* gcc.target/aarch64/pr66912.c: New.
* gcc.target/arm/pr66912.c: New.
diff --git a/gcc/testsuite/gcc.target/aarch64/pr66912.c b/gcc/testsuite/gcc.target/aarch64/pr66912.c
new file mode 100644
index 0000000..b8aabcd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr66912.c
@@ -0,0 +1,42 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+__attribute__((visibility("protected")))
+int n_common;
+
+__attribute__((weak, visibility("protected")))
+int n_weak_common;
+
+__attribute__((visibility("protected")))
+int n_init = -1;
+
+__attribute__((weak, visibility("protected")))
+int n_weak_init = -1;
+
+int
+f1 ()
+{
+ /* { dg-final { scan-assembler ":got(page_lo15)?:n_common" } } */
+ return n_common;
+}
+
+int
+f2 ()
+{
+ /* { dg-final { scan-assembler ":got(page_lo15)?:n_weak_common" } } */
+ return n_weak_common;
+}
+
+int
+f3 ()
+{
+ /* { dg-final { scan-assembler ":got(page_lo15)?:n_init" } } */
+ return n_init;
+}
+
+int
+f4 ()
+{
+ /* { dg-final { scan-assembler ":got(page_lo15)?:n_weak_init" } } */
+ return n_weak_init;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr66912.c b/gcc/testsuite/gcc.target/arm/pr66912.c
new file mode 100644
index 0000000..27e4c45
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr66912.c
@@ -0,0 +1,42 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic" } */
+
+__attribute__((visibility("protected")))
+int n_common;
+
+__attribute__((weak, visibility("protected")))
+int n_weak_common;
+
+__attribute__((visibility("protected")))
+int n_init = -1;
+
+__attribute__((weak, visibility("protected")))
+int n_weak_init = -1;
+
+int
+f1 ()
+{
+ /* { dg-final { scan-assembler "\\.word\\tn_common\\(GOT\\)" } } */
+ return n_common;
+}
+
+int
+f2 ()
+{
+ /* { dg-final { scan-assembler "\\.word\\tn_weak_common\\(GOT\\)" } } */
+ return n_weak_common;
+}
+
+int
+f3 ()
+{
+ /* { dg-final { scan-assembler "\\.word\\tn_init\\(GOT\\)" } } */
+ return n_init;
+}
+
+int
+f4 ()
+{
+ /* { dg-final { scan-assembler "\\.word\\tn_weak_init\\(GOT\\)" } } */
+ return n_weak_init;
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 6a4ba0b..a056792 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6907,12 +6907,13 @@ default_binds_local_p (const_tree exp)
return default_binds_local_p_3 (exp, flag_shlib != 0, true, false, false);
}
-/* Similar to default_binds_local_p, but common symbol may be local. */
+/* Similar to default_binds_local_p, but common symbol may be local and
+ extern protected data is non-local. */
bool
default_binds_local_p_2 (const_tree exp)
{
- return default_binds_local_p_3 (exp, flag_shlib != 0, true, false,
+ return default_binds_local_p_3 (exp, flag_shlib != 0, true, true,
!flag_pic);
}