Is it OK for trunk or I need to change something? By the way, I'm seeking a possibility to include this into 12.2. Then we leaves only 12.1 without this attribute, and we can just say "building the kernel needs GCC 12.2 or later".
On Mon, 2022-08-01 at 18:07 +0800, Xi Ruoyao wrote: > Changes v4 -> v5: Fix changelog. No code change. > > Changes v3 -> v4: > > * Use "movable" as the attribute name as Huacai says it's already > used > in downstream GCC fork. > * Remove an inaccurate line from the doc. (Initially I tried to > implement a "model(...)" like IA64 or M32R. Then I changed my mind > but forgot to remove the line copied from M32R doc.) > > -- >8 -- > > 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. > This > happens when the Linux kernel loads a module with "local" per-CPU > variables. > > 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. > > gcc/ChangeLog: > > * config/loongarch/loongarch.cc (loongarch_attribute_table): > New attribute table. > (TARGET_ATTRIBUTE_TABLE): Define the target hook. > (loongarch_handle_addr_global_attribute): New static function. > (loongarch_classify_symbol): Return SYMBOL_GOT_DISP for > SYMBOL_REF_DECL with addr_global attribute. > (loongarch_use_anchors_for_symbol_p): New static function. > (TARGET_USE_ANCHORS_FOR_SYMBOL_P): Define the target hook. > * doc/extend.texi (Variable Attributes): Document new > LoongArch specific attribute. > > gcc/testsuite/ChangeLog: > > * gcc.target/loongarch/addr-global.c: New test. > --- > gcc/config/loongarch/loongarch.cc | 63 > +++++++++++++++++++ > gcc/doc/extend.texi | 16 +++++ > .../gcc.target/loongarch/attr-movable.c | 29 +++++++++ > 3 files changed, 108 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-movable.c > > diff --git a/gcc/config/loongarch/loongarch.cc > b/gcc/config/loongarch/loongarch.cc > index 79687340dfd..6b6026700a6 100644 > --- a/gcc/config/loongarch/loongarch.cc > +++ b/gcc/config/loongarch/loongarch.cc > @@ -1643,6 +1643,15 @@ loongarch_classify_symbol (const_rtx x) > && !loongarch_symbol_binds_local_p (x)) > return SYMBOL_GOT_DISP; > > + if (SYMBOL_REF_P (x)) > + { > + tree decl = SYMBOL_REF_DECL (x); > + /* A movable symbol may be moved away from the +/- 2GiB range > around > + the PC, so we have to use GOT. */ > + if (decl && lookup_attribute ("movable", DECL_ATTRIBUTES > (decl))) > + return SYMBOL_GOT_DISP; > + } > + > return SYMBOL_PCREL; > } > > @@ -6068,6 +6077,54 @@ loongarch_starting_frame_offset (void) > return crtl->outgoing_args_size; > } > > +static tree > +loongarch_handle_movable_attribute (tree *node, tree name, tree, int, > + bool *no_add_attrs) > +{ > + tree decl = *node; > + if (TREE_CODE (decl) == VAR_DECL) > + { > + if (DECL_CONTEXT (decl) > + && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL > + && !TREE_STATIC (decl)) > + { > + error_at (DECL_SOURCE_LOCATION (decl), > + "%qE attribute cannot be specified for local " > + "variables", name); > + *no_add_attrs = true; > + } > + } > + else > + { > + warning (OPT_Wattributes, "%qE attribute ignored", name); > + *no_add_attrs = true; > + } > + return NULL_TREE; > +} > + > +static const struct attribute_spec loongarch_attribute_table[] = > +{ > + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, > + affects_type_identity, handler, exclude } */ > + { "movable", 0, 0, true, false, false, false, > + loongarch_handle_movable_attribute, NULL }, > + /* The last attribute spec is set to be NULL. */ > + {} > +}; > + > +bool > +loongarch_use_anchors_for_symbol_p (const_rtx symbol) > +{ > + tree decl = SYMBOL_REF_DECL (symbol); > + > + /* A movable attribute indicates the linker may move the symbol > away, > + so the use of anchor may cause relocation overflow. */ > + if (decl && lookup_attribute ("movable", DECL_ATTRIBUTES (decl))) > + return false; > + > + return default_use_anchors_for_symbol_p (symbol); > +} > + > /* Initialize the GCC target structure. */ > #undef TARGET_ASM_ALIGNED_HI_OP > #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" > @@ -6256,6 +6313,12 @@ loongarch_starting_frame_offset (void) > #undef TARGET_HAVE_SPECULATION_SAFE_VALUE > #define TARGET_HAVE_SPECULATION_SAFE_VALUE > speculation_safe_value_not_needed > > +#undef TARGET_ATTRIBUTE_TABLE > +#define TARGET_ATTRIBUTE_TABLE loongarch_attribute_table > + > +#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P > +#define TARGET_USE_ANCHORS_FOR_SYMBOL_P > loongarch_use_anchors_for_symbol_p > + > struct gcc_target targetm = TARGET_INITIALIZER; > > #include "gt-loongarch.h" > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 7fe7f8817cd..322d8c05a04 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -7314,6 +7314,7 @@ attributes. > * Blackfin Variable Attributes:: > * H8/300 Variable Attributes:: > * IA-64 Variable Attributes:: > +* LoongArch Variable Attributes:: > * M32R/D Variable Attributes:: > * MeP Variable Attributes:: > * Microsoft Windows Variable Attributes:: > @@ -8098,6 +8099,21 @@ defined by shared libraries. > > @end table > > +@node LoongArch Variable Attributes > +@subsection LoongArch Variable Attributes > + > +One attribute is currently defined for the LoongArch. > + > +@table @code > +@item movable > +@cindex @code{movable} variable attribute, LoongArch > +Use this attribute on the LoongArch to mark an object possible to be > moved > +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. > This > +attribute is mostly useful if a @code{section} attribute and/or a > linker > +script will move the object somewhere unexpected by the code model. > +@end table > + > @node M32R/D Variable Attributes > @subsection M32R/D Variable Attributes > > diff --git a/gcc/testsuite/gcc.target/loongarch/attr-movable.c > b/gcc/testsuite/gcc.target/loongarch/attr-movable.c > new file mode 100644 > index 00000000000..85b1dd4c59a > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/attr-movable.c > @@ -0,0 +1,29 @@ > +/* { dg-do compile } */ > +/* { dg-options "-mexplicit-relocs -mcmodel=normal -O2" } */ > +/* { dg-final { scan-assembler-not "%pc" } } */ > +/* { dg-final { scan-assembler-times "%got_pc_hi20" 3 } } */ > + > +/* movable attribute should mark x and y possibly outside of the > local > + data range defined by the code model, so GOT should be used > instead of > + PC-relative. */ > + > +int x __attribute__((movable)); > +int y __attribute__((movable)); > + > +int > +test(void) > +{ > + 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"), > movable)); > + > +void > +inc_counter(void) > +{ > + int *ptr = (int *)(per_cpu_base + (long)&counter); > + (*ptr)++; > +} -- Xi Ruoyao <xry...@xry111.site> School of Aerospace Science and Technology, Xidian University