From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id D639A3858C74 for ; Mon, 15 Aug 2022 11:26:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D639A3858C74 Received: from [IPv6:240e:358:115c:cb00:dc73:854d:832e:2] (unknown [IPv6:240e:358:115c:cb00:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id D55F066893; Mon, 15 Aug 2022 07:26:41 -0400 (EDT) Message-ID: <6529f5cf76e4df3cdfb6c85ea9da962797f97437.camel@xry111.site> Subject: Re: [PATCH v6] LoongArch: add addr_global attribute From: Xi Ruoyao To: gcc-patches@gcc.gnu.org, Lulu Cheng Cc: Jinyang He , Chenghua Xu , Huacai Chen , Youling Tang , Wang Xuerui Date: Mon, 15 Aug 2022 19:26:33 +0800 In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.45.2 MIME-Version: 1.0 X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FROM_SUSPICIOUS_NTLD, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, LIKELY_SPAM_FROM, PDS_OTHER_BAD_TLD, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Aug 2022 11:26:49 -0000 Can we make a final solution to this soon? Now the merge window of Linux 6.0 is closed and we have two Linux kernel releases not possible to be built with Binutils or GCC with new relocation types. This is just ugly... On Fri, 2022-08-12 at 17:17 +0800, Xi Ruoyao via Gcc-patches wrote: > v5 -> v6: >=20 > * still use "addr_global" as we don't have a better name. > * add a test case with -mno-explicit-relocs. >=20 > -- >8 -- >=20 > A linker script and/or a section attribute may locate a local object > in > some way unexpected by the code model, leading to a link failure.=C2=A0 > This > happens when the Linux kernel loads a module with "local" per-CPU > variables. >=20 > Add an attribute to explicitly mark an variable with the address > unlimited by the code model so we would be able to work around such > problems. >=20 > gcc/ChangeLog: >=20 > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* config/loongarch/loonga= rch.cc (loongarch_attribute_table): > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0New attribute table. > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(TARGET_ATTRIBUTE_TABLE):= Define the target hook. > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(loongarch_handle_addr_gl= obal_attribute): New static function. > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(loongarch_classify_symbo= l): Return SYMBOL_GOT_DISP for > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0SYMBOL_REF_DECL with addr= _global attribute. > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(loongarch_use_anchors_fo= r_symbol_p): New static function. > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(TARGET_USE_ANCHORS_FOR_S= YMBOL_P): Define the target hook. > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* doc/extend.texi (Variab= le Attributes): Document new > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0LoongArch specific attrib= ute. >=20 > gcc/testsuite/ChangeLog: >=20 > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* gcc.target/loongarch/at= tr-addr_global-1.c: New test. > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* gcc.target/loongarch/at= tr-addr_global-2.c: New test. > --- > =C2=A0gcc/config/loongarch/loongarch.cc=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 63 > +++++++++++++++++++ > =C2=A0gcc/doc/extend.texi=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 17 +++++ > =C2=A0.../gcc.target/loongarch/attr-addr_global-1.c | 29 +++++++++ > =C2=A0.../gcc.target/loongarch/attr-addr_global-2.c | 29 +++++++++ > =C2=A04 files changed, 138 insertions(+) > =C2=A0create mode 100644 gcc/testsuite/gcc.target/loongarch/attr- > addr_global-1.c > =C2=A0create mode 100644 gcc/testsuite/gcc.target/loongarch/attr- > addr_global-2.c >=20 > diff --git a/gcc/config/loongarch/loongarch.cc > b/gcc/config/loongarch/loongarch.cc > index 79687340dfd..978e66ed549 100644 > --- a/gcc/config/loongarch/loongarch.cc > +++ b/gcc/config/loongarch/loongarch.cc > @@ -1643,6 +1643,15 @@ loongarch_classify_symbol (const_rtx x) > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && !loongarch_symbol_binds_local_p (= x)) > =C2=A0=C2=A0=C2=A0=C2=A0 return SYMBOL_GOT_DISP; > =C2=A0 > +=C2=A0 if (SYMBOL_REF_P (x)) > +=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tree decl =3D SYMBOL_REF_DECL (x); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* An addr_global symbol may be out of th= e +/- 2GiB range > around > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 the PC, so we have to use GOT= .=C2=A0 */ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (decl && lookup_attribute ("addr_globa= l", DECL_ATTRIBUTES > (decl))) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return SYMBOL_GOT_DISP; > +=C2=A0=C2=A0=C2=A0 } > + > =C2=A0=C2=A0 return SYMBOL_PCREL; > =C2=A0} > =C2=A0 > @@ -6068,6 +6077,54 @@ loongarch_starting_frame_offset (void) > =C2=A0=C2=A0 return crtl->outgoing_args_size; > =C2=A0} > =C2=A0 > +static tree > +loongarch_handle_addr_global_attribute (tree *node, tree name, tree, > int, > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0bool *no_add_attrs) > +{ > +=C2=A0 tree decl =3D *node; > +=C2=A0 if (TREE_CODE (decl) =3D=3D VAR_DECL) > +=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (DECL_CONTEXT (decl) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && TREE_CODE (DECL_CONT= EXT (decl)) =3D=3D FUNCTION_DECL > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && !TREE_STATIC (decl)) > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0{ > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 error_at (DECL_SOURCE_L= OCATION (decl), > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "%qE attribute cannot be specified for= local " > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "variables", name); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *no_add_attrs =3D true; > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0} > +=C2=A0=C2=A0=C2=A0 } > +=C2=A0 else > +=C2=A0=C2=A0=C2=A0 { > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 warning (OPT_Wattributes, "%qE attribute = ignored", name); > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *no_add_attrs =3D true; > +=C2=A0=C2=A0=C2=A0 } > +=C2=A0 return NULL_TREE; > +} > + > +static const struct attribute_spec loongarch_attribute_table[] =3D > +{ > +=C2=A0 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 affects_type_identity, handler, exc= lude } */ > +=C2=A0 { "addr_global", 0, 0, true, false, false, false, > +=C2=A0=C2=A0=C2=A0 loongarch_handle_addr_global_attribute, NULL }, > +=C2=A0 /* The last attribute spec is set to be NULL.=C2=A0 */ > +=C2=A0 {} > +}; > + > +bool > +loongarch_use_anchors_for_symbol_p (const_rtx symbol) > +{ > +=C2=A0 tree decl =3D SYMBOL_REF_DECL (symbol); > + > +=C2=A0 /* An addr_global attribute indicates the linker may move the > symbol away, > +=C2=A0=C2=A0=C2=A0=C2=A0 so the use of anchor may cause relocation overf= low.=C2=A0 */ > +=C2=A0 if (decl && lookup_attribute ("addr_global", DECL_ATTRIBUTES > (decl))) > +=C2=A0=C2=A0=C2=A0 return false; > + > +=C2=A0 return default_use_anchors_for_symbol_p (symbol); > +} > + > =C2=A0/* Initialize the GCC target structure.=C2=A0 */ > =C2=A0#undef TARGET_ASM_ALIGNED_HI_OP > =C2=A0#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" > @@ -6256,6 +6313,12 @@ loongarch_starting_frame_offset (void) > =C2=A0#undef=C2=A0 TARGET_HAVE_SPECULATION_SAFE_VALUE > =C2=A0#define TARGET_HAVE_SPECULATION_SAFE_VALUE > speculation_safe_value_not_needed > =C2=A0 > +#undef=C2=A0 TARGET_ATTRIBUTE_TABLE > +#define TARGET_ATTRIBUTE_TABLE loongarch_attribute_table > + > +#undef=C2=A0 TARGET_USE_ANCHORS_FOR_SYMBOL_P > +#define TARGET_USE_ANCHORS_FOR_SYMBOL_P > loongarch_use_anchors_for_symbol_p > + > =C2=A0struct gcc_target targetm =3D TARGET_INITIALIZER; > =C2=A0 > =C2=A0#include "gt-loongarch.h" > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 7fe7f8817cd..b1173e15c7c 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -7314,6 +7314,7 @@ attributes. > =C2=A0* Blackfin Variable Attributes:: > =C2=A0* H8/300 Variable Attributes:: > =C2=A0* IA-64 Variable Attributes:: > +* LoongArch Variable Attributes:: > =C2=A0* M32R/D Variable Attributes:: > =C2=A0* MeP Variable Attributes:: > =C2=A0* Microsoft Windows Variable Attributes:: > @@ -8098,6 +8099,22 @@ defined by shared libraries. > =C2=A0 > =C2=A0@end table > =C2=A0 > +@node LoongArch Variable Attributes > +@subsection LoongArch Variable Attributes > + > +One attribute is currently defined for the LoongArch. > + > +@table @code > +@item addr_global > +@cindex @code{addr_global} variable attribute, LoongArch > +Use this attribute on the LoongArch to mark an object possible to be > +located anywhere in the address space by the linker, so its address > is > +unlimited by the local data section range specified by the code model > even > +if the object is defined locally.=C2=A0 This attribute is mostly useful = if > a > +@code{section} attribute and/or a linker script will place the object > +somewhere unexpected by the code model. > +@end table > + > =C2=A0@node M32R/D Variable Attributes > =C2=A0@subsection M32R/D Variable Attributes > =C2=A0 > diff --git a/gcc/testsuite/gcc.target/loongarch/attr-addr_global-1.c > b/gcc/testsuite/gcc.target/loongarch/attr-addr_global-1.c > new file mode 100644 > index 00000000000..c1553713d9d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/attr-addr_global-1.c > @@ -0,0 +1,29 @@ > +/* { dg-do compile } */ > +/* { dg-options "-mexplicit-relocs -mcmodel=3Dnormal -O2" } */ > +/* { dg-final { scan-assembler-not "%pc" } } */ > +/* { dg-final { scan-assembler-times "%got_pc_hi20" 3 } } */ > + > +/* addr_global attribute should mark x and y possibly outside of the > local > +=C2=A0=C2=A0 data range defined by the code model, so GOT should be used > instead of > +=C2=A0=C2=A0 PC-relative.=C2=A0 */ > + > +int x __attribute__((addr_global)); > +int y __attribute__((addr_global)); > + > +int > +test(void) > +{ > +=C2=A0 return x + y; > +} > + > +/* The following will be used for kernel per-cpu storage > implemention. */ > + > +register char *per_cpu_base __asm__("r21"); > +static int counter __attribute__((section(".data..percpu"), > addr_global)); > + > +void > +inc_counter(void) > +{ > +=C2=A0 int *ptr =3D (int *)(per_cpu_base + (long)&counter); > +=C2=A0 (*ptr)++; > +} > diff --git a/gcc/testsuite/gcc.target/loongarch/attr-addr_global-2.c > b/gcc/testsuite/gcc.target/loongarch/attr-addr_global-2.c > new file mode 100644 > index 00000000000..708f163975f > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/attr-addr_global-2.c > @@ -0,0 +1,29 @@ > +/* { dg-do compile } */ > +/* { dg-options "-mno-explicit-relocs -mcmodel=3Dnormal -O2" } */ > +/* { dg-final { scan-assembler-not "la.local" } } */ > +/* { dg-final { scan-assembler-times "la.global" 3 } } */ > + > +/* addr_global attribute should mark x and y possibly outside of the > local > +=C2=A0=C2=A0 data range defined by the code model, so GOT should be used > instead of > +=C2=A0=C2=A0 PC-relative.=C2=A0 */ > + > +int x __attribute__((addr_global)); > +int y __attribute__((addr_global)); > + > +int > +test(void) > +{ > +=C2=A0 return x + y; > +} > + > +/* The following will be used for kernel per-cpu storage > implemention. */ > + > +register char *per_cpu_base __asm__("r21"); > +static int counter __attribute__((section(".data..percpu"), > addr_global)); > + > +void > +inc_counter(void) > +{ > +=C2=A0 int *ptr =3D (int *)(per_cpu_base + (long)&counter); > +=C2=A0 (*ptr)++; > +} --=20 Xi Ruoyao School of Aerospace Science and Technology, Xidian University