sync backport patch of varasm COMDAT function symbol.
This commit is contained in:
parent
6f369a4235
commit
d732cdff91
296
0305-Backport-varasm-Handle-private-COMDAT-function-symbo.patch
Normal file
296
0305-Backport-varasm-Handle-private-COMDAT-function-symbo.patch
Normal file
@ -0,0 +1,296 @@
|
||||
From bbb4954294d010977fcfb96931384101cf015a44 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Mon, 26 Feb 2024 17:55:07 +0100
|
||||
Subject: [PATCH] [Backport]varasm: Handle private COMDAT function symbol
|
||||
reference in readonly data section [PR113617]
|
||||
|
||||
If default_elf_select_rtx_section is called to put a reference to some
|
||||
local symbol defined in a comdat section into memory, which happens more often
|
||||
since the r14-4944 RA change, linking might fail.
|
||||
default_elf_select_rtx_section puts such constants into .data.rel.ro.local
|
||||
etc. sections and if linker chooses comdat sections from some other TU
|
||||
and discards the one to which a relocation in .data.rel.ro.local remains,
|
||||
linker diagnoses error. References to private comdat symbols can only appear
|
||||
from functions or data objects in the same comdat group, so the following
|
||||
patch arranges using .data.rel.ro.local.pool.<comdat_name> and similar sections.
|
||||
|
||||
2024-02-26 Jakub Jelinek <jakub@redhat.com>
|
||||
H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
PR rtl-optimization/113617
|
||||
* varasm.cc (default_elf_select_rtx_section): For
|
||||
references to private symbols in comdat sections
|
||||
use .data.relro.local.pool.<comdat>, .data.relro.pool.<comdat>
|
||||
or .rodata.<comdat> comdat sections.
|
||||
|
||||
* g++.dg/other/pr113617.C: New test.
|
||||
* g++.dg/other/pr113617.h: New test.
|
||||
* g++.dg/other/pr113617-aux.cc: New test.
|
||||
---
|
||||
gcc/testsuite/g++.dg/other/pr113617-aux.cc | 9 ++
|
||||
gcc/testsuite/g++.dg/other/pr113617.C | 27 +++++
|
||||
gcc/testsuite/g++.dg/other/pr113617.h | 132 +++++++++++++++++++++
|
||||
gcc/varasm.cc | 48 +++++++-
|
||||
4 files changed, 215 insertions(+), 1 deletion(-)
|
||||
create mode 100644 gcc/testsuite/g++.dg/other/pr113617-aux.cc
|
||||
create mode 100644 gcc/testsuite/g++.dg/other/pr113617.C
|
||||
create mode 100644 gcc/testsuite/g++.dg/other/pr113617.h
|
||||
|
||||
diff --git a/gcc/testsuite/g++.dg/other/pr113617-aux.cc b/gcc/testsuite/g++.dg/other/pr113617-aux.cc
|
||||
new file mode 100644
|
||||
index 000000000..e6900e05a
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/other/pr113617-aux.cc
|
||||
@@ -0,0 +1,9 @@
|
||||
+// PR rtl-optimization/113617
|
||||
+// { dg-do link { target { c++17 && c++14_down } } }
|
||||
+
|
||||
+#include "pr113617.h"
|
||||
+
|
||||
+void qux() {
|
||||
+ A<long long> a;
|
||||
+ a.foo(0, 0);
|
||||
+}
|
||||
diff --git a/gcc/testsuite/g++.dg/other/pr113617.C b/gcc/testsuite/g++.dg/other/pr113617.C
|
||||
new file mode 100644
|
||||
index 000000000..a02dda142
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/other/pr113617.C
|
||||
@@ -0,0 +1,27 @@
|
||||
+// PR rtl-optimization/113617
|
||||
+// { dg-do link { target c++11 } }
|
||||
+// { dg-options "-O2" }
|
||||
+// { dg-additional-options "-fPIC" { target fpic } } */
|
||||
+// { dg-additional-options "-shared" { target shared } } */
|
||||
+// { dg-additional-sources pr113617-aux.cc }
|
||||
+
|
||||
+#include "pr113617.h"
|
||||
+
|
||||
+int z;
|
||||
+long xx1;
|
||||
+void corge() {
|
||||
+ A<long long> a;
|
||||
+ a.foo(xx1, 0);
|
||||
+}
|
||||
+
|
||||
+typedef unsigned long int VV __attribute__((vector_size (2 * sizeof (long))));
|
||||
+VV vv;
|
||||
+__attribute__((noipa)) static void fn1 (void) {}
|
||||
+__attribute__((noipa)) static void fn2 (void) {}
|
||||
+
|
||||
+void
|
||||
+fn3 ()
|
||||
+{
|
||||
+ VV a = { (unsigned long) &fn1, (unsigned long) &fn2 };
|
||||
+ vv = a;
|
||||
+}
|
||||
diff --git a/gcc/testsuite/g++.dg/other/pr113617.h b/gcc/testsuite/g++.dg/other/pr113617.h
|
||||
new file mode 100644
|
||||
index 000000000..4d30eddbc
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/other/pr113617.h
|
||||
@@ -0,0 +1,132 @@
|
||||
+namespace {
|
||||
+template <int V> struct J { static constexpr int value = V; };
|
||||
+template <bool V> using K = J<V>;
|
||||
+using M = K<true>;
|
||||
+template <int> struct L { template <typename _Tp, typename> using type = _Tp; };
|
||||
+template <bool _Cond, typename _If, typename _Else> using N = typename L<_Cond>::type<_If, _Else>;
|
||||
+M k;
|
||||
+template <typename _Tp> struct O { using type = _Tp; };
|
||||
+template <typename _Up>
|
||||
+struct P : N<M ::value, O<_Up>, _Up> {};
|
||||
+template <typename _Tp> struct Q { using type = typename P<_Tp>::type; };
|
||||
+}
|
||||
+namespace R {
|
||||
+struct H;
|
||||
+enum G {};
|
||||
+template <typename> class S;
|
||||
+struct T { using U = bool (*) (H &, const H &, G); U F; };
|
||||
+template <typename, typename> class B;
|
||||
+template <typename _R, typename _F, typename... _A>
|
||||
+struct B<_R(_A...), _F> {
|
||||
+ static bool F(H &, const H &, G) { return false; }
|
||||
+ __attribute__((noipa)) static _R bar(const H &) {}
|
||||
+};
|
||||
+template <typename _R, typename... _A>
|
||||
+struct S<_R(_A...)> : T {
|
||||
+ template <typename _F> using AH = B<_R(), _F>;
|
||||
+ template <typename _F> S(_F) {
|
||||
+ using AG = AH<_F>;
|
||||
+ barr = AG::bar;
|
||||
+ F = AG::F;
|
||||
+ }
|
||||
+ using AF = _R (*)(const H &);
|
||||
+ AF barr;
|
||||
+};
|
||||
+template <typename> class I;
|
||||
+template <typename _F, typename... _B>
|
||||
+struct I<_F(_B...)> {};
|
||||
+template <typename> using W = decltype(k);
|
||||
+template <int, typename _F, typename... _B> struct V {
|
||||
+ typedef I<typename Q<_F>::type(typename Q<_B>::type...)> type;
|
||||
+};
|
||||
+template <typename _F, typename... _B>
|
||||
+__attribute__((noipa)) typename V<W<_F>::value, _F, _B...>::type
|
||||
+baz(_F, _B...) { return typename V<W<_F>::value, _F, _B...>::type (); }
|
||||
+template <typename _Tp> struct AJ {
|
||||
+ template <typename _Up> struct _Ptr { using type = _Up *; };
|
||||
+ using AI = typename _Ptr<_Tp>::type;
|
||||
+};
|
||||
+template <typename _Tp> struct Y {
|
||||
+ using AI = typename AJ<_Tp>::AI;
|
||||
+ AI operator->();
|
||||
+};
|
||||
+}
|
||||
+extern int z;
|
||||
+namespace N1 {
|
||||
+namespace N2 {
|
||||
+namespace N3 {
|
||||
+enum Z { Z1, Z2 };
|
||||
+template <int> struct X {
|
||||
+ template <typename _F>
|
||||
+ __attribute__((noipa)) void boo(long long, long long, long long, _F &) {}
|
||||
+};
|
||||
+struct AC {
|
||||
+ AC(int);
|
||||
+ void m1(R::S<void()>);
|
||||
+};
|
||||
+template <typename>
|
||||
+__attribute__((noipa)) void garply(void *, long long, long long, long long) {}
|
||||
+template <>
|
||||
+template <typename _F>
|
||||
+void X<Z2>::boo(long long, long long x, long long y, _F &fi) {
|
||||
+ AC pool(z);
|
||||
+ for (;;) {
|
||||
+ auto job = R::baz(garply<_F>, &fi, y, y, x);
|
||||
+ pool.m1(job);
|
||||
+ }
|
||||
+}
|
||||
+struct AB {
|
||||
+ static AB &bleh();
|
||||
+ template <typename _F>
|
||||
+ void boo(long first, long x, long y, _F fi) {
|
||||
+ switch (ab1) {
|
||||
+ case Z1:
|
||||
+ ab2->boo(first, x, y, fi);
|
||||
+ case Z2:
|
||||
+ ab3->boo(first, x, y, fi);
|
||||
+ }
|
||||
+ }
|
||||
+ Z ab1;
|
||||
+ R::Y<X<Z1>> ab2;
|
||||
+ R::Y<X<Z2>> ab3;
|
||||
+};
|
||||
+template <typename, bool> struct C;
|
||||
+template <typename _F> struct C<_F, false> {
|
||||
+ __attribute__((noipa)) C(_F) {}
|
||||
+ void boo(long first, long x, long y) {
|
||||
+ auto u = AB::bleh();
|
||||
+ u.boo(first, x, y, *this);
|
||||
+ }
|
||||
+};
|
||||
+template <typename _F> struct AA { typedef C<_F, 0> type; };
|
||||
+}
|
||||
+}
|
||||
+}
|
||||
+struct AD {
|
||||
+ template <typename _F>
|
||||
+ static void boo(long first, long x, long y, _F f) {
|
||||
+ typename N1::N2::N3::AA<_F>::type fi(f);
|
||||
+ fi.boo(first, x, y);
|
||||
+ }
|
||||
+ template <typename _F>
|
||||
+ static void boo(long first, long x, _F f) {
|
||||
+ boo(first, x, 0, f);
|
||||
+ }
|
||||
+};
|
||||
+template <typename> struct A {
|
||||
+ void foo(long long, long long);
|
||||
+ int *c;
|
||||
+};
|
||||
+namespace {
|
||||
+template <typename> struct D { __attribute__((noipa)) D(int *) {} };
|
||||
+}
|
||||
+template <typename T>
|
||||
+void A<T>::foo(long long x, long long y)
|
||||
+{
|
||||
+ int e;
|
||||
+ D<T> d(&e);
|
||||
+ AD::boo(0, y, d);
|
||||
+ long p;
|
||||
+ for (p = 0; p < x; p++)
|
||||
+ c[p] = c[p - 1];
|
||||
+}
|
||||
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
|
||||
index bae935694..d122730b5 100644
|
||||
--- a/gcc/varasm.cc
|
||||
+++ b/gcc/varasm.cc
|
||||
@@ -7317,17 +7317,63 @@ default_elf_select_rtx_section (machine_mode mode, rtx x,
|
||||
unsigned HOST_WIDE_INT align)
|
||||
{
|
||||
int reloc = compute_reloc_for_rtx (x);
|
||||
+ tree decl = nullptr;
|
||||
+ const char *prefix = nullptr;
|
||||
+ int flags = 0;
|
||||
+
|
||||
+ /* If it is a private COMDAT function symbol reference, call
|
||||
+ function_rodata_section for the read-only or relocated read-only
|
||||
+ data section associated with function DECL so that the COMDAT
|
||||
+ section will be used for the private COMDAT function symbol. */
|
||||
+ if (HAVE_COMDAT_GROUP)
|
||||
+ {
|
||||
+ if (GET_CODE (x) == CONST
|
||||
+ && GET_CODE (XEXP (x, 0)) == PLUS
|
||||
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
|
||||
+ x = XEXP (XEXP (x, 0), 0);
|
||||
+
|
||||
+ if (GET_CODE (x) == SYMBOL_REF)
|
||||
+ {
|
||||
+ decl = SYMBOL_REF_DECL (x);
|
||||
+ if (decl
|
||||
+ && (TREE_CODE (decl) != FUNCTION_DECL
|
||||
+ || !DECL_COMDAT_GROUP (decl)
|
||||
+ || TREE_PUBLIC (decl)))
|
||||
+ decl = nullptr;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* ??? Handle small data here somehow. */
|
||||
|
||||
if (reloc & targetm.asm_out.reloc_rw_mask ())
|
||||
{
|
||||
- if (reloc == 1)
|
||||
+ if (decl)
|
||||
+ {
|
||||
+ prefix = reloc == 1 ? ".data.rel.ro.local" : ".data.rel.ro";
|
||||
+ flags = SECTION_WRITE | SECTION_RELRO;
|
||||
+ }
|
||||
+ else if (reloc == 1)
|
||||
return get_named_section (NULL, ".data.rel.ro.local", 1);
|
||||
else
|
||||
return get_named_section (NULL, ".data.rel.ro", 3);
|
||||
}
|
||||
|
||||
+ if (decl)
|
||||
+ {
|
||||
+ const char *comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (decl));
|
||||
+ if (!prefix)
|
||||
+ prefix = ".rodata";
|
||||
+ size_t prefix_len = strlen (prefix);
|
||||
+ size_t comdat_len = strlen (comdat);
|
||||
+ size_t len = prefix_len + sizeof (".pool.") + comdat_len;
|
||||
+ char *name = XALLOCAVEC (char, len);
|
||||
+ memcpy (name, prefix, prefix_len);
|
||||
+ memcpy (name + prefix_len, ".pool.", sizeof (".pool.") - 1);
|
||||
+ memcpy (name + prefix_len + sizeof (".pool.") - 1, comdat,
|
||||
+ comdat_len + 1);
|
||||
+ return get_section (name, flags | SECTION_LINKONCE, decl);
|
||||
+ }
|
||||
+
|
||||
return mergeable_constant_section (mode, align, 0);
|
||||
}
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
10
gcc.spec
10
gcc.spec
@ -2,7 +2,7 @@
|
||||
%global gcc_major 12
|
||||
# Note, gcc_release must be integer, if you want to add suffixes to
|
||||
# %%{release}, append them after %%{gcc_release} on Release: line.
|
||||
%global gcc_release 41
|
||||
%global gcc_release 42
|
||||
|
||||
%global _unpackaged_files_terminate_build 0
|
||||
%global _performance_build 1
|
||||
@ -411,6 +411,7 @@ Patch301: 0301-Add-required-check-for-iteration-through-uses.patch
|
||||
Patch302: 0302-Added-param-for-optimization-for-merging-bb-s-with-c.patch
|
||||
Patch303: 0303-Add-generation-of-stream-in-functions-for-pre-versio.patch
|
||||
Patch304: 0304-Add-multi-version-lto-symbol-parse-cross-lto-units-i.patch
|
||||
Patch305: 0305-Backport-varasm-Handle-private-COMDAT-function-symbo.patch
|
||||
|
||||
|
||||
# Part 3000 ~ 4999
|
||||
@ -1479,6 +1480,7 @@ not stable, so plugins must be rebuilt any time GCC is updated.
|
||||
%patch302 -p1
|
||||
%patch303 -p1
|
||||
%patch304 -p1
|
||||
%patch305 -p1
|
||||
|
||||
|
||||
%ifarch loongarch64
|
||||
@ -4071,6 +4073,12 @@ end
|
||||
%doc rpm.doc/changelogs/libcc1/ChangeLog*
|
||||
|
||||
%changelog
|
||||
* Thu Nov 21 2024 Feiyang Liu <liufeiyang6@huawei.com> - 12.3.1-42
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:Sync backport patch varasm-Handle-private-COMDAT from upstream.
|
||||
|
||||
* Thu Nov 21 2024 liyancheng <412998149@qq.com> - 12.3.1-41
|
||||
- Type:Sync
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user