All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] LoongArch: Support new relocation types
@ 2022-07-28 11:49 Xi Ruoyao
  2022-07-28 11:54 ` [PATCH v2 1/4] LoongArch: Add section of GOT for kernel module Xi Ruoyao
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 11:49 UTC (permalink / raw)
  To: loongarch
  Cc: linux-kernel, WANG Xuerui, Huacai Chen, Youling Tang, Jinyang He

The version 2.00 of LoongArch ELF ABI specification introduced new
relocation types, and the development tree of Binutils and GCC has
started to use them.  If the kernel is built with the latest snapshot of
Binutils or GCC, it will fail to load the modules because of unrecognized
relocation types in modules.

Add support for GOT and new relocation types for the module loader, so
the kernel (with modules) can be built with the "normal" code model and
function properly.

Tested by building the kernel with Binutils & GCC master branch,
running the kernel with 35 in-tree modules loaded, and loading one
module with 20 GOT loads (both old SOP_PUSH_GPREL and new
GOT_PC_HI20/GOT_PC_LO12 relocations tested, and loaded addresses
verified by comparing with /proc/kallsyms).

Link: https://github.com/loongson/LoongArch-Documentation/pull/57
Link: https://gcc.gnu.org/r13-1834
Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f09482a

Changes from v1 to v2:

- Fix a stupid programming error (confusion between the number of PLT
  entries and the number of GOT entries).  (Bug spotted by Youling).
- Synthesize the _GLOBAL_OFFSET_TABLE_ symbol with module.lds, instead
  of faking it at runtime.  The 3rd patch from V1 is now merged into
  the 1st patch because it would be a one-line change.  (Suggested by
  Jinyang).
- Keep reloc_rela_handlers[] ordered by the relocation type ID.
  (Suggested by Youling).
- Remove -fplt along with -Wa,-mla-* options because it's the default.
  (Suggested by Youling).

Xi Ruoyao (4):
  LoongArch: Add section of GOT for kernel module
  LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in kernel
    module
  LoongArch: Stop using undocumented assembler options
  LoongArch: Support modules with new relocation types

 arch/loongarch/Makefile                 |  4 --
 arch/loongarch/include/asm/elf.h        | 37 ++++++++++
 arch/loongarch/include/asm/module.h     | 23 ++++++
 arch/loongarch/include/asm/module.lds.h |  1 +
 arch/loongarch/kernel/head.S            | 10 +--
 arch/loongarch/kernel/module-sections.c | 51 ++++++++++++--
 arch/loongarch/kernel/module.c          | 94 +++++++++++++++++++++++++
 7 files changed, 207 insertions(+), 13 deletions(-)

-- 
2.37.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/4] LoongArch: Add section of GOT for kernel module
  2022-07-28 11:49 [PATCH v2 0/4] LoongArch: Support new relocation types Xi Ruoyao
@ 2022-07-28 11:54 ` Xi Ruoyao
  2022-07-28 11:59 ` [PATCH 2/4] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in " Xi Ruoyao
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 11:54 UTC (permalink / raw)
  To: loongarch
  Cc: linux-kernel, WANG Xuerui, Huacai Chen, Youling Tang, Jinyang He

The address of external symbols will locate more than 32-bit offset.  We
were using the `-Wa,-mla-global-with-abs` and `-Wa,-mla-local-with-abs`
to prevent the compiler and assembler from generating GOT relocations,
but these options are undocumented hacks and do not work anymore with
GAS 2.40 and GCC 13.

Let the module loader emit GOT entries for data symbols so we would be
able to handle GOT relocations.  The GOT entry is just the data symbol
address.

In module.lds, emit a stub .got section for a section header entry.
The actual content of the entry will be filled at runtime by
module_frob_arch_sections.

A special symbol named "_GLOBAL_OFFSET_TABLE_" is used by stack-based
relocations for the PC-relative offset of a GOT entry, like:

    R_LARCH_SOP_PUSH_PCREL _GLOBAL_OFFSET_TABLE_
    R_LARCH_SOP_PUSH_GPREL foo
    R_LARCH_SOP_ADD

Each kernel module has its own GOT (like a shared object), so we need
to generate _GLOBAL_OFFSET_TABLE_ as a local symbol for each module.

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
 arch/loongarch/include/asm/module.h     | 23 +++++++++++++
 arch/loongarch/include/asm/module.lds.h |  1 +
 arch/loongarch/kernel/module-sections.c | 43 ++++++++++++++++++++++---
 3 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/arch/loongarch/include/asm/module.h b/arch/loongarch/include/asm/module.h
index 9f6718df1854..76a98a0ab8a0 100644
--- a/arch/loongarch/include/asm/module.h
+++ b/arch/loongarch/include/asm/module.h
@@ -19,6 +19,7 @@ struct mod_section {
 struct mod_arch_specific {
 	struct mod_section plt;
 	struct mod_section plt_idx;
+	struct mod_section got;
 };
 
 struct plt_entry {
@@ -28,11 +29,16 @@ struct plt_entry {
 	u32 inst_jirl;
 };
 
+struct got_entry {
+	Elf_Addr symbol_addr;
+};
+
 struct plt_idx_entry {
 	unsigned long symbol_addr;
 };
 
 Elf_Addr module_emit_plt_entry(struct module *mod, unsigned long val);
+Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val);
 
 static inline struct plt_entry emit_plt_entry(unsigned long val)
 {
@@ -51,6 +57,11 @@ static inline struct plt_idx_entry emit_plt_idx_entry(unsigned long val)
 	return (struct plt_idx_entry) { val };
 }
 
+static inline struct got_entry emit_got_entry(Elf_Addr val)
+{
+	return (struct got_entry) { val };
+}
+
 static inline int get_plt_idx(unsigned long val, const struct mod_section *sec)
 {
 	int i;
@@ -77,4 +88,16 @@ static inline struct plt_entry *get_plt_entry(unsigned long val,
 	return plt + plt_idx;
 }
 
+static inline struct got_entry *get_got_entry(Elf_Addr val,
+					      const struct mod_section *sec)
+{
+	struct got_entry *got = (struct got_entry *)sec->shdr->sh_addr;
+	int i;
+
+	for (i = 0; i < sec->num_entries; i++)
+		if (got[i].symbol_addr == val)
+			return &got[i];
+	return NULL;
+}
+
 #endif /* _ASM_MODULE_H */
diff --git a/arch/loongarch/include/asm/module.lds.h b/arch/loongarch/include/asm/module.lds.h
index 31c1c0db11a3..42b7cca0b947 100644
--- a/arch/loongarch/include/asm/module.lds.h
+++ b/arch/loongarch/include/asm/module.lds.h
@@ -4,4 +4,5 @@ SECTIONS {
 	. = ALIGN(4);
 	.plt : { BYTE(0) }
 	.plt.idx : { BYTE(0) }
+	.got : { HIDDEN(_GLOBAL_OFFSET_TABLE_ = .); BYTE(0) }
 }
diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kernel/module-sections.c
index 6d498288977d..36a77771d18c 100644
--- a/arch/loongarch/kernel/module-sections.c
+++ b/arch/loongarch/kernel/module-sections.c
@@ -33,6 +33,25 @@ Elf_Addr module_emit_plt_entry(struct module *mod, unsigned long val)
 	return (Elf_Addr)&plt[nr];
 }
 
+Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val)
+{
+	struct mod_section *got_sec = &mod->arch.got;
+	int i = got_sec->num_entries;
+	struct got_entry *got = get_got_entry(val, got_sec);
+
+	if (got)
+		return (Elf_Addr)got;
+
+	/* There is no GOT entry existing for val yet.  Create a new one.  */
+	got = (struct got_entry *)got_sec->shdr->sh_addr;
+	got[i] = emit_got_entry(val);
+
+	got_sec->num_entries++;
+	BUG_ON(got_sec->num_entries > got_sec->max_entries);
+
+	return (Elf_Addr)&got[i];
+}
+
 static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y)
 {
 	return x->r_info == y->r_info && x->r_addend == y->r_addend;
@@ -50,7 +69,8 @@ static bool duplicate_rela(const Elf_Rela *rela, int idx)
 	return false;
 }
 
-static void count_max_entries(Elf_Rela *relas, int num, unsigned int *plts)
+static void count_max_entries(Elf_Rela *relas, int num,
+			      unsigned int *plts, unsigned int *gots)
 {
 	unsigned int i, type;
 
@@ -59,14 +79,16 @@ static void count_max_entries(Elf_Rela *relas, int num, unsigned int *plts)
 		if (type == R_LARCH_SOP_PUSH_PLT_PCREL) {
 			if (!duplicate_rela(relas, i))
 				(*plts)++;
-		}
+		} else if (type == R_LARCH_SOP_PUSH_GPREL)
+			if (!duplicate_rela(relas, i))
+				(*gots)++;
 	}
 }
 
 int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 			      char *secstrings, struct module *mod)
 {
-	unsigned int i, num_plts = 0;
+	unsigned int i, num_plts = 0, num_gots = 0;
 
 	/*
 	 * Find the empty .plt sections.
@@ -76,6 +98,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 			mod->arch.plt.shdr = sechdrs + i;
 		else if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt.idx"))
 			mod->arch.plt_idx.shdr = sechdrs + i;
+		else if (!strcmp(secstrings + sechdrs[i].sh_name, ".got"))
+			mod->arch.got.shdr = sechdrs + i;
 	}
 
 	if (!mod->arch.plt.shdr) {
@@ -86,6 +110,10 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 		pr_err("%s: module PLT.IDX section(s) missing\n", mod->name);
 		return -ENOEXEC;
 	}
+	if (!mod->arch.got.shdr) {
+		pr_err("%s: module GOT section(s) missing\n", mod->name);
+		return -ENOEXEC;
+	}
 
 	/* Calculate the maxinum number of entries */
 	for (i = 0; i < ehdr->e_shnum; i++) {
@@ -100,7 +128,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 		if (!(dst_sec->sh_flags & SHF_EXECINSTR))
 			continue;
 
-		count_max_entries(relas, num_rela, &num_plts);
+		count_max_entries(relas, num_rela, &num_plts, &num_gots);
 	}
 
 	mod->arch.plt.shdr->sh_type = SHT_NOBITS;
@@ -117,5 +145,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 	mod->arch.plt_idx.num_entries = 0;
 	mod->arch.plt_idx.max_entries = num_plts;
 
+	mod->arch.got.shdr->sh_type = SHT_NOBITS;
+	mod->arch.got.shdr->sh_flags = SHF_ALLOC;
+	mod->arch.got.shdr->sh_addralign = L1_CACHE_BYTES;
+	mod->arch.got.shdr->sh_size = (num_gots + 1) * sizeof(struct got_entry);
+	mod->arch.got.num_entries = 0;
+	mod->arch.got.max_entries = num_gots;
+
 	return 0;
 }
-- 
2.37.0



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/4] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in kernel module
  2022-07-28 11:49 [PATCH v2 0/4] LoongArch: Support new relocation types Xi Ruoyao
  2022-07-28 11:54 ` [PATCH v2 1/4] LoongArch: Add section of GOT for kernel module Xi Ruoyao
@ 2022-07-28 11:59 ` Xi Ruoyao
  2022-07-28 12:30   ` Huacai Chen
  2022-07-28 12:03 ` [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options Xi Ruoyao
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 11:59 UTC (permalink / raw)
  To: loongarch
  Cc: linux-kernel, WANG Xuerui, Huacai Chen, Youling Tang, Jinyang He

This relocation type pushes the offset of the GOT entry for a symbol
from the beginning of GOT into the relocation stack.  Our linker script
has initialized an empty GOT, so we need to create a new GOT entry if
there is no exist one for a symbol.

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
 arch/loongarch/kernel/module.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
index 638427ff0d51..3ac4fbb5f109 100644
--- a/arch/loongarch/kernel/module.c
+++ b/arch/loongarch/kernel/module.c
@@ -122,6 +122,16 @@ static int apply_r_larch_sop_push_plt_pcrel(struct module *mod, u32 *location, E
 	return apply_r_larch_sop_push_pcrel(mod, location, v, rela_stack, rela_stack_top, type);
 }
 
+static int apply_r_larch_sop_push_gprel(struct module *mod, u32 *location,
+			Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
+			unsigned int type)
+{
+	Elf_Addr got = module_emit_got_entry(mod, v);
+	ptrdiff_t offset = (void *)got - (void *)mod->arch.got.shdr->sh_addr;
+
+	return rela_stack_push(offset, rela_stack, rela_stack_top);
+}
+
 static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v,
 			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
@@ -306,6 +316,7 @@ static reloc_rela_handler reloc_rela_handlers[] = {
 	[R_LARCH_SOP_PUSH_PCREL]			     = apply_r_larch_sop_push_pcrel,
 	[R_LARCH_SOP_PUSH_ABSOLUTE]			     = apply_r_larch_sop_push_absolute,
 	[R_LARCH_SOP_PUSH_DUP]				     = apply_r_larch_sop_push_dup,
+	[R_LARCH_SOP_PUSH_GPREL]			     = apply_r_larch_sop_push_gprel,
 	[R_LARCH_SOP_PUSH_PLT_PCREL]			     = apply_r_larch_sop_push_plt_pcrel,
 	[R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE] 	     = apply_r_larch_sop,
 	[R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field,
-- 
2.37.0



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options
  2022-07-28 11:49 [PATCH v2 0/4] LoongArch: Support new relocation types Xi Ruoyao
  2022-07-28 11:54 ` [PATCH v2 1/4] LoongArch: Add section of GOT for kernel module Xi Ruoyao
  2022-07-28 11:59 ` [PATCH 2/4] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in " Xi Ruoyao
@ 2022-07-28 12:03 ` Xi Ruoyao
  2022-07-28 12:25   ` Huacai Chen
  2022-07-28 12:04 ` [PATCH v2 4/4] LoongArch: Support modules with new relocation types Xi Ruoyao
  2022-07-28 12:33 ` [PATCH v2 0/4] LoongArch: Support " Huacai Chen
  4 siblings, 1 reply; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 12:03 UTC (permalink / raw)
  To: loongarch
  Cc: linux-kernel, WANG Xuerui, Huacai Chen, Youling Tang, Jinyang He

Now we can handle GOT and GOT-based relocations properly, remove the
undocumented `-Wa,-mla-{global,local}-with-{pcrel,abs}` assembler hacks.

And, -fplt is the default of all supported compilers (GCC, and maybe
Clang in the future), so it can be removed as well.

Adjust assembly code to explicitly use "la.pcrel" where necessary.

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
 arch/loongarch/Makefile      |  4 ----
 arch/loongarch/kernel/head.S | 10 +++++-----
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
index 039dcc4fe1f3..800349ea9310 100644
--- a/arch/loongarch/Makefile
+++ b/arch/loongarch/Makefile
@@ -40,10 +40,6 @@ endif
 
 cflags-y			+= -G0 -pipe -msoft-float
 LDFLAGS_vmlinux			+= -G0 -static -n -nostdlib
-KBUILD_AFLAGS_KERNEL		+= -Wa,-mla-global-with-pcrel
-KBUILD_CFLAGS_KERNEL		+= -Wa,-mla-global-with-pcrel
-KBUILD_AFLAGS_MODULE		+= -Wa,-mla-global-with-abs
-KBUILD_CFLAGS_MODULE		+= -fplt -Wa,-mla-global-with-abs,-mla-local-with-abs
 
 cflags-y += -ffreestanding
 cflags-y += $(call cc-option, -mno-check-zero-division)
diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index 74ea7bf6c8d6..193329ed6e8c 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -60,17 +60,17 @@ SYM_CODE_START(kernel_entry)			# kernel entry point
 	la.abs		t0, 0f
 	jirl		zero, t0, 0
 0:
-	la		t0, __bss_start		# clear .bss
+	la.pcrel	t0, __bss_start		# clear .bss
 	st.d		zero, t0, 0
-	la		t1, __bss_stop - LONGSIZE
+	la.pcrel	t1, __bss_stop - LONGSIZE
 1:
 	addi.d		t0, t0, LONGSIZE
 	st.d		zero, t0, 0
 	bne		t0, t1, 1b
 
-	la		t0, fw_arg0
+	la.pcrel	t0, fw_arg0
 	st.d		a0, t0, 0		# firmware arguments
-	la		t0, fw_arg1
+	la.pcrel	t0, fw_arg1
 	st.d		a1, t0, 0
 
 	/* KSave3 used for percpu base, initialized as 0 */
@@ -78,7 +78,7 @@ SYM_CODE_START(kernel_entry)			# kernel entry point
 	/* GPR21 used for percpu base (runtime), initialized as 0 */
 	or		u0, zero, zero
 
-	la		tp, init_thread_union
+	la.pcrel	tp, init_thread_union
 	/* Set the SP after an empty pt_regs.  */
 	PTR_LI		sp, (_THREAD_SIZE - 32 - PT_SIZE)
 	PTR_ADD		sp, sp, tp
-- 
2.37.0



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 4/4] LoongArch: Support modules with new relocation types
  2022-07-28 11:49 [PATCH v2 0/4] LoongArch: Support new relocation types Xi Ruoyao
                   ` (2 preceding siblings ...)
  2022-07-28 12:03 ` [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options Xi Ruoyao
@ 2022-07-28 12:04 ` Xi Ruoyao
  2022-07-28 12:41   ` Youling Tang
  2022-07-28 12:33 ` [PATCH v2 0/4] LoongArch: Support " Huacai Chen
  4 siblings, 1 reply; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 12:04 UTC (permalink / raw)
  To: loongarch
  Cc: linux-kernel, WANG Xuerui, Huacai Chen, Youling Tang, Jinyang He

If GAS 2.40 and/or GCC 13 is used to build the kernel, the modules will
contain R_LARCH_B26, R_LARCH_PCALA_HI20, R_LARCH_PCALA_LO12,
R_LARCH_GOT_PC_HI20, and R_LARCH_GOT_PC_LO12 relocations.  Support them
in the module loader to allow a kernel built with latest toolchain
capable to load the modules.

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
 arch/loongarch/include/asm/elf.h        | 37 +++++++++++
 arch/loongarch/kernel/module-sections.c | 12 +++-
 arch/loongarch/kernel/module.c          | 83 +++++++++++++++++++++++++
 3 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h
index 5f3ff4781fda..7af0cebf28d7 100644
--- a/arch/loongarch/include/asm/elf.h
+++ b/arch/loongarch/include/asm/elf.h
@@ -74,6 +74,43 @@
 #define R_LARCH_SUB64				56
 #define R_LARCH_GNU_VTINHERIT			57
 #define R_LARCH_GNU_VTENTRY			58
+#define R_LARCH_B16				64
+#define R_LARCH_B21				65
+#define R_LARCH_B26				66
+#define R_LARCH_ABS_HI20			67
+#define R_LARCH_ABS_LO12			68
+#define R_LARCH_ABS64_LO20			69
+#define R_LARCH_ABS64_HI12			70
+#define R_LARCH_PCALA_HI20			71
+#define R_LARCH_PCALA_LO12			72
+#define R_LARCH_PCALA64_LO20			73
+#define R_LARCH_PCALA64_HI12			74
+#define R_LARCH_GOT_PC_HI20			75
+#define R_LARCH_GOT_PC_LO12			76
+#define R_LARCH_GOT64_PC_LO20			77
+#define R_LARCH_GOT64_PC_HI12			78
+#define R_LARCH_GOT_HI20			79
+#define R_LARCH_GOT_LO12			80
+#define R_LARCH_GOT64_LO20			81
+#define R_LARCH_GOT64_HI12			82
+#define R_LARCH_TLS_LE_HI20			83
+#define R_LARCH_TLS_LE_LO12			84
+#define R_LARCH_TLS_LE64_LO20			85
+#define R_LARCH_TLS_LE64_HI12			86
+#define R_LARCH_TLS_IE_PC_HI20			87
+#define R_LARCH_TLS_IE_PC_LO12			88
+#define R_LARCH_TLS_IE64_PC_LO20		89
+#define R_LARCH_TLS_IE64_PC_HI12		90
+#define R_LARCH_TLS_IE_HI20			91
+#define R_LARCH_TLS_IE_LO12			92
+#define R_LARCH_TLS_IE64_LO20			93
+#define R_LARCH_TLS_IE64_HI12			94
+#define R_LARCH_TLS_LD_PC_HI20			95
+#define R_LARCH_TLS_LD_HI20			96
+#define R_LARCH_TLS_GD_PC_HI20			97
+#define R_LARCH_TLS_GD_HI20			98
+#define R_LARCH_32_PCREL			99
+#define R_LARCH_RELAX				100
 
 #ifndef ELF_ARCH
 
diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kernel/module-sections.c
index 36a77771d18c..8c0e4ad048cc 100644
--- a/arch/loongarch/kernel/module-sections.c
+++ b/arch/loongarch/kernel/module-sections.c
@@ -76,12 +76,20 @@ static void count_max_entries(Elf_Rela *relas, int num,
 
 	for (i = 0; i < num; i++) {
 		type = ELF_R_TYPE(relas[i].r_info);
-		if (type == R_LARCH_SOP_PUSH_PLT_PCREL) {
+		switch (type) {
+		case R_LARCH_SOP_PUSH_PLT_PCREL:
+		case R_LARCH_B26:
 			if (!duplicate_rela(relas, i))
 				(*plts)++;
-		} else if (type == R_LARCH_SOP_PUSH_GPREL)
+			break;
+		case R_LARCH_SOP_PUSH_GPREL:
+		case R_LARCH_GOT_PC_HI20:
 			if (!duplicate_rela(relas, i))
 				(*gots)++;
+			break;
+		default:
+			/* Do nothing. */
+		}
 	}
 }
 
diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
index 3ac4fbb5f109..8954ac24d4ab 100644
--- a/arch/loongarch/kernel/module.c
+++ b/arch/loongarch/kernel/module.c
@@ -291,6 +291,84 @@ static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v,
 	}
 }
 
+static int apply_r_larch_b26(struct module *mod, u32 *location, Elf_Addr v,
+			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+{
+	ptrdiff_t offset = (void *)v - (void *)location;
+
+	if (offset >= SZ_128M)
+		v = module_emit_plt_entry(mod, v);
+
+	if (offset < -SZ_128M)
+		v = module_emit_plt_entry(mod, v);
+
+	offset = (void *)v - (void *)location;
+
+	if (!signed_imm_check(offset, 28)) {
+		pr_err("module %s: jump offset = 0x%llx overflow! dangerous R_LARCH_B26 (%u) relocation\n",
+				mod->name, (long long)offset, type);
+		return -ENOEXEC;
+	}
+
+	if (offset & 3) {
+		pr_err("module %s: jump offset = 0x%llx unaligned! dangerous R_LARCH_B26 (%u) relocation\n",
+				mod->name, (long long)offset, type);
+		return -ENOEXEC;
+	}
+
+	*location &= ~(u32)0x3ffffff;
+	*location |= (offset >> 18) & 0x3ff;
+	*location |= ((offset >> 2) & 0xffff) << 10;
+	return 0;
+}
+
+static int apply_r_larch_pcala_hi20(struct module *mod, u32 *location,
+		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
+		unsigned int type)
+{
+	ptrdiff_t offset = (void *)((v + 0x800) & ~0xfff) -
+		(void *)((Elf_Addr)location & ~0xfff);
+
+	if (!signed_imm_check(offset, 32)) {
+		pr_err("module %s: PCALA offset = 0x%llx does not fit in 32-bit signed and is unsupported by kernel! dangerous %s (%u) relocation\n",
+				mod->name, (long long)offset, __func__, type);
+		return -ENOEXEC;
+	}
+
+	*location &= ~((u32)0xfffff << 5);
+	*location |= ((offset >> 12) & 0xfffff) << 5;
+	return 0;
+}
+
+static int apply_r_larch_got_pc_hi20(struct module *mod, u32 *location,
+		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
+		unsigned int type)
+{
+	Elf_Addr got = module_emit_got_entry(mod, v);
+
+	return apply_r_larch_pcala_hi20(mod, location, got, rela_stack,
+			rela_stack_top, type);
+}
+
+static int apply_r_larch_pcala_lo12(struct module *mod, u32 *location,
+		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
+		unsigned int type)
+{
+	*location &= ~((u32)0xfff << 10);
+	*location |= ((u32)v & 0xfff) << 10;
+	return 0;
+}
+
+static int apply_r_larch_got_pc_lo12(struct module *mod, u32 *location,
+		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
+		unsigned int type)
+{
+	Elf_Addr got = module_emit_got_entry(mod, v);
+
+	return apply_r_larch_pcala_lo12(mod, location, got, rela_stack,
+			rela_stack_top, type);
+}
+
 /*
  * reloc_handlers_rela() - Apply a particular relocation to a module
  * @mod: the module to apply the reloc to
@@ -321,6 +399,11 @@ static reloc_rela_handler reloc_rela_handlers[] = {
 	[R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE] 	     = apply_r_larch_sop,
 	[R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field,
 	[R_LARCH_ADD32 ... R_LARCH_SUB64]		     = apply_r_larch_add_sub,
+	[R_LARCH_B26]					     = apply_r_larch_b26,
+	[R_LARCH_PCALA_HI20]				     = apply_r_larch_pcala_hi20,
+	[R_LARCH_PCALA_LO12]				     = apply_r_larch_pcala_lo12,
+	[R_LARCH_GOT_PC_HI20]				     = apply_r_larch_got_pc_hi20,
+	[R_LARCH_GOT_PC_LO12]				     = apply_r_larch_got_pc_lo12,
 };
 
 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
-- 
2.37.0



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options
  2022-07-28 12:03 ` [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options Xi Ruoyao
@ 2022-07-28 12:25   ` Huacai Chen
  2022-07-28 13:10     ` Xi Ruoyao
  0 siblings, 1 reply; 14+ messages in thread
From: Huacai Chen @ 2022-07-28 12:25 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: loongarch, LKML, WANG Xuerui, Youling Tang, Jinyang He

Hi, Ruoyao,

On Thu, Jul 28, 2022 at 8:03 PM Xi Ruoyao <xry111@xry111.site> wrote:
>
> Now we can handle GOT and GOT-based relocations properly, remove the
> undocumented `-Wa,-mla-{global,local}-with-{pcrel,abs}` assembler hacks.
I think "-Wa,-mla-{global,local}-with-{pcrel,abs}" may be regular
options rather than "hacks". If I'm right, the title and commit
message should be updated. And we can send patches to binutils to make
them "documented".

Huacai
>
> And, -fplt is the default of all supported compilers (GCC, and maybe
> Clang in the future), so it can be removed as well.
>
> Adjust assembly code to explicitly use "la.pcrel" where necessary.
>
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
>  arch/loongarch/Makefile      |  4 ----
>  arch/loongarch/kernel/head.S | 10 +++++-----
>  2 files changed, 5 insertions(+), 9 deletions(-)
>
> diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
> index 039dcc4fe1f3..800349ea9310 100644
> --- a/arch/loongarch/Makefile
> +++ b/arch/loongarch/Makefile
> @@ -40,10 +40,6 @@ endif
>
>  cflags-y                       += -G0 -pipe -msoft-float
>  LDFLAGS_vmlinux                        += -G0 -static -n -nostdlib
> -KBUILD_AFLAGS_KERNEL           += -Wa,-mla-global-with-pcrel
> -KBUILD_CFLAGS_KERNEL           += -Wa,-mla-global-with-pcrel
> -KBUILD_AFLAGS_MODULE           += -Wa,-mla-global-with-abs
> -KBUILD_CFLAGS_MODULE           += -fplt -Wa,-mla-global-with-abs,-mla-local-with-abs
>
>  cflags-y += -ffreestanding
>  cflags-y += $(call cc-option, -mno-check-zero-division)
> diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
> index 74ea7bf6c8d6..193329ed6e8c 100644
> --- a/arch/loongarch/kernel/head.S
> +++ b/arch/loongarch/kernel/head.S
> @@ -60,17 +60,17 @@ SYM_CODE_START(kernel_entry)                        # kernel entry point
>         la.abs          t0, 0f
>         jirl            zero, t0, 0
>  0:
> -       la              t0, __bss_start         # clear .bss
> +       la.pcrel        t0, __bss_start         # clear .bss
>         st.d            zero, t0, 0
> -       la              t1, __bss_stop - LONGSIZE
> +       la.pcrel        t1, __bss_stop - LONGSIZE
>  1:
>         addi.d          t0, t0, LONGSIZE
>         st.d            zero, t0, 0
>         bne             t0, t1, 1b
>
> -       la              t0, fw_arg0
> +       la.pcrel        t0, fw_arg0
>         st.d            a0, t0, 0               # firmware arguments
> -       la              t0, fw_arg1
> +       la.pcrel        t0, fw_arg1
>         st.d            a1, t0, 0
>
>         /* KSave3 used for percpu base, initialized as 0 */
> @@ -78,7 +78,7 @@ SYM_CODE_START(kernel_entry)                  # kernel entry point
>         /* GPR21 used for percpu base (runtime), initialized as 0 */
>         or              u0, zero, zero
>
> -       la              tp, init_thread_union
> +       la.pcrel        tp, init_thread_union
>         /* Set the SP after an empty pt_regs.  */
>         PTR_LI          sp, (_THREAD_SIZE - 32 - PT_SIZE)
>         PTR_ADD         sp, sp, tp
> --
> 2.37.0
>
>
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in kernel module
  2022-07-28 11:59 ` [PATCH 2/4] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in " Xi Ruoyao
@ 2022-07-28 12:30   ` Huacai Chen
  2022-07-28 12:33     ` Xi Ruoyao
  0 siblings, 1 reply; 14+ messages in thread
From: Huacai Chen @ 2022-07-28 12:30 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: loongarch, LKML, WANG Xuerui, Youling Tang, Jinyang He

Hi, Ruoyao,

Missing V2 in the title?

Huacai

On Thu, Jul 28, 2022 at 7:59 PM Xi Ruoyao <xry111@xry111.site> wrote:
>
> This relocation type pushes the offset of the GOT entry for a symbol
> from the beginning of GOT into the relocation stack.  Our linker script
> has initialized an empty GOT, so we need to create a new GOT entry if
> there is no exist one for a symbol.
>
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
>  arch/loongarch/kernel/module.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
> index 638427ff0d51..3ac4fbb5f109 100644
> --- a/arch/loongarch/kernel/module.c
> +++ b/arch/loongarch/kernel/module.c
> @@ -122,6 +122,16 @@ static int apply_r_larch_sop_push_plt_pcrel(struct module *mod, u32 *location, E
>         return apply_r_larch_sop_push_pcrel(mod, location, v, rela_stack, rela_stack_top, type);
>  }
>
> +static int apply_r_larch_sop_push_gprel(struct module *mod, u32 *location,
> +                       Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
> +                       unsigned int type)
> +{
> +       Elf_Addr got = module_emit_got_entry(mod, v);
> +       ptrdiff_t offset = (void *)got - (void *)mod->arch.got.shdr->sh_addr;
> +
> +       return rela_stack_push(offset, rela_stack, rela_stack_top);
> +}
> +
>  static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v,
>                         s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
>  {
> @@ -306,6 +316,7 @@ static reloc_rela_handler reloc_rela_handlers[] = {
>         [R_LARCH_SOP_PUSH_PCREL]                             = apply_r_larch_sop_push_pcrel,
>         [R_LARCH_SOP_PUSH_ABSOLUTE]                          = apply_r_larch_sop_push_absolute,
>         [R_LARCH_SOP_PUSH_DUP]                               = apply_r_larch_sop_push_dup,
> +       [R_LARCH_SOP_PUSH_GPREL]                             = apply_r_larch_sop_push_gprel,
>         [R_LARCH_SOP_PUSH_PLT_PCREL]                         = apply_r_larch_sop_push_plt_pcrel,
>         [R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE]            = apply_r_larch_sop,
>         [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field,
> --
> 2.37.0
>
>
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/4] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in kernel module
  2022-07-28 12:30   ` Huacai Chen
@ 2022-07-28 12:33     ` Xi Ruoyao
  0 siblings, 0 replies; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 12:33 UTC (permalink / raw)
  To: Huacai Chen; +Cc: loongarch, LKML, WANG Xuerui, Youling Tang, Jinyang He

On Thu, 2022-07-28 at 20:30 +0800, Huacai Chen wrote:
> Hi, Ruoyao,
> 
> Missing V2 in the title?

Yes :(.


-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 0/4] LoongArch: Support new relocation types
  2022-07-28 11:49 [PATCH v2 0/4] LoongArch: Support new relocation types Xi Ruoyao
                   ` (3 preceding siblings ...)
  2022-07-28 12:04 ` [PATCH v2 4/4] LoongArch: Support modules with new relocation types Xi Ruoyao
@ 2022-07-28 12:33 ` Huacai Chen
  2022-07-28 14:05   ` Xi Ruoyao
  4 siblings, 1 reply; 14+ messages in thread
From: Huacai Chen @ 2022-07-28 12:33 UTC (permalink / raw)
  To: Xi Ruoyao, Arnd Bergmann
  Cc: loongarch, LKML, WANG Xuerui, Youling Tang, Jinyang He

Hi, Arnd,


On Thu, Jul 28, 2022 at 7:49 PM Xi Ruoyao <xry111@xry111.site> wrote:
>
> The version 2.00 of LoongArch ELF ABI specification introduced new
> relocation types, and the development tree of Binutils and GCC has
> started to use them.  If the kernel is built with the latest snapshot of
> Binutils or GCC, it will fail to load the modules because of unrecognized
> relocation types in modules.
>
> Add support for GOT and new relocation types for the module loader, so
> the kernel (with modules) can be built with the "normal" code model and
> function properly.
>
> Tested by building the kernel with Binutils & GCC master branch,
> running the kernel with 35 in-tree modules loaded, and loading one
> module with 20 GOT loads (both old SOP_PUSH_GPREL and new
> GOT_PC_HI20/GOT_PC_LO12 relocations tested, and loaded addresses
> verified by comparing with /proc/kallsyms).
>
> Link: https://github.com/loongson/LoongArch-Documentation/pull/57
> Link: https://gcc.gnu.org/r13-1834
> Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f09482a
Could you update the cross-compilers here [1] to make this series be
possible upstream in the 5.20 cycle? Or we can only do that until new
binutils/gcc be released?

[1] https://mirrors.edge.kernel.org/pub/tools/crosstool/

Huacai
>
> Changes from v1 to v2:
>
> - Fix a stupid programming error (confusion between the number of PLT
>   entries and the number of GOT entries).  (Bug spotted by Youling).
> - Synthesize the _GLOBAL_OFFSET_TABLE_ symbol with module.lds, instead
>   of faking it at runtime.  The 3rd patch from V1 is now merged into
>   the 1st patch because it would be a one-line change.  (Suggested by
>   Jinyang).
> - Keep reloc_rela_handlers[] ordered by the relocation type ID.
>   (Suggested by Youling).
> - Remove -fplt along with -Wa,-mla-* options because it's the default.
>   (Suggested by Youling).
>
> Xi Ruoyao (4):
>   LoongArch: Add section of GOT for kernel module
>   LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in kernel
>     module
>   LoongArch: Stop using undocumented assembler options
>   LoongArch: Support modules with new relocation types
>
>  arch/loongarch/Makefile                 |  4 --
>  arch/loongarch/include/asm/elf.h        | 37 ++++++++++
>  arch/loongarch/include/asm/module.h     | 23 ++++++
>  arch/loongarch/include/asm/module.lds.h |  1 +
>  arch/loongarch/kernel/head.S            | 10 +--
>  arch/loongarch/kernel/module-sections.c | 51 ++++++++++++--
>  arch/loongarch/kernel/module.c          | 94 +++++++++++++++++++++++++
>  7 files changed, 207 insertions(+), 13 deletions(-)
>
> --
> 2.37.0
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 4/4] LoongArch: Support modules with new relocation types
  2022-07-28 12:04 ` [PATCH v2 4/4] LoongArch: Support modules with new relocation types Xi Ruoyao
@ 2022-07-28 12:41   ` Youling Tang
  2022-07-28 13:30     ` Xi Ruoyao
  0 siblings, 1 reply; 14+ messages in thread
From: Youling Tang @ 2022-07-28 12:41 UTC (permalink / raw)
  To: Xi Ruoyao, loongarch; +Cc: linux-kernel, WANG Xuerui, Huacai Chen, Jinyang He


On 07/28/2022 08:04 PM, Xi Ruoyao wrote:
> If GAS 2.40 and/or GCC 13 is used to build the kernel, the modules will
> contain R_LARCH_B26, R_LARCH_PCALA_HI20, R_LARCH_PCALA_LO12,
> R_LARCH_GOT_PC_HI20, and R_LARCH_GOT_PC_LO12 relocations.  Support them
> in the module loader to allow a kernel built with latest toolchain
> capable to load the modules.
>
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
>  arch/loongarch/include/asm/elf.h        | 37 +++++++++++
>  arch/loongarch/kernel/module-sections.c | 12 +++-
>  arch/loongarch/kernel/module.c          | 83 +++++++++++++++++++++++++
>  3 files changed, 130 insertions(+), 2 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h
> index 5f3ff4781fda..7af0cebf28d7 100644
> --- a/arch/loongarch/include/asm/elf.h
> +++ b/arch/loongarch/include/asm/elf.h
> @@ -74,6 +74,43 @@
>  #define R_LARCH_SUB64				56
>  #define R_LARCH_GNU_VTINHERIT			57
>  #define R_LARCH_GNU_VTENTRY			58
> +#define R_LARCH_B16				64
> +#define R_LARCH_B21				65
> +#define R_LARCH_B26				66
> +#define R_LARCH_ABS_HI20			67
> +#define R_LARCH_ABS_LO12			68
> +#define R_LARCH_ABS64_LO20			69
> +#define R_LARCH_ABS64_HI12			70
> +#define R_LARCH_PCALA_HI20			71
> +#define R_LARCH_PCALA_LO12			72
> +#define R_LARCH_PCALA64_LO20			73
> +#define R_LARCH_PCALA64_HI12			74
> +#define R_LARCH_GOT_PC_HI20			75
> +#define R_LARCH_GOT_PC_LO12			76
> +#define R_LARCH_GOT64_PC_LO20			77
> +#define R_LARCH_GOT64_PC_HI12			78
> +#define R_LARCH_GOT_HI20			79
> +#define R_LARCH_GOT_LO12			80
> +#define R_LARCH_GOT64_LO20			81
> +#define R_LARCH_GOT64_HI12			82
> +#define R_LARCH_TLS_LE_HI20			83
> +#define R_LARCH_TLS_LE_LO12			84
> +#define R_LARCH_TLS_LE64_LO20			85
> +#define R_LARCH_TLS_LE64_HI12			86
> +#define R_LARCH_TLS_IE_PC_HI20			87
> +#define R_LARCH_TLS_IE_PC_LO12			88
> +#define R_LARCH_TLS_IE64_PC_LO20		89
> +#define R_LARCH_TLS_IE64_PC_HI12		90
> +#define R_LARCH_TLS_IE_HI20			91
> +#define R_LARCH_TLS_IE_LO12			92
> +#define R_LARCH_TLS_IE64_LO20			93
> +#define R_LARCH_TLS_IE64_HI12			94
> +#define R_LARCH_TLS_LD_PC_HI20			95
> +#define R_LARCH_TLS_LD_HI20			96
> +#define R_LARCH_TLS_GD_PC_HI20			97
> +#define R_LARCH_TLS_GD_HI20			98
> +#define R_LARCH_32_PCREL			99
> +#define R_LARCH_RELAX				100
>
>  #ifndef ELF_ARCH
>
> diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kernel/module-sections.c
> index 36a77771d18c..8c0e4ad048cc 100644
> --- a/arch/loongarch/kernel/module-sections.c
> +++ b/arch/loongarch/kernel/module-sections.c
> @@ -76,12 +76,20 @@ static void count_max_entries(Elf_Rela *relas, int num,
>
>  	for (i = 0; i < num; i++) {
>  		type = ELF_R_TYPE(relas[i].r_info);
> -		if (type == R_LARCH_SOP_PUSH_PLT_PCREL) {
> +		switch (type) {
> +		case R_LARCH_SOP_PUSH_PLT_PCREL:
> +		case R_LARCH_B26:
>  			if (!duplicate_rela(relas, i))
>  				(*plts)++;
> -		} else if (type == R_LARCH_SOP_PUSH_GPREL)
> +			break;
> +		case R_LARCH_SOP_PUSH_GPREL:
> +		case R_LARCH_GOT_PC_HI20:
>  			if (!duplicate_rela(relas, i))
>  				(*gots)++;
> +			break;
> +		default:
> +			/* Do nothing. */
> +		}
>  	}
>  }
>
> diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
> index 3ac4fbb5f109..8954ac24d4ab 100644
> --- a/arch/loongarch/kernel/module.c
> +++ b/arch/loongarch/kernel/module.c
> @@ -291,6 +291,84 @@ static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v,
>  	}
>  }
>
> +static int apply_r_larch_b26(struct module *mod, u32 *location, Elf_Addr v,
> +			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
> +{
> +	ptrdiff_t offset = (void *)v - (void *)location;
> +
> +	if (offset >= SZ_128M)
> +		v = module_emit_plt_entry(mod, v);
> +
> +	if (offset < -SZ_128M)
> +		v = module_emit_plt_entry(mod, v);
> +
> +	offset = (void *)v - (void *)location;
> +
> +	if (!signed_imm_check(offset, 28)) {
> +		pr_err("module %s: jump offset = 0x%llx overflow! dangerous R_LARCH_B26 (%u) relocation\n",
> +				mod->name, (long long)offset, type);
> +		return -ENOEXEC;
> +	}
> +
> +	if (offset & 3) {
> +		pr_err("module %s: jump offset = 0x%llx unaligned! dangerous R_LARCH_B26 (%u) relocation\n",
> +				mod->name, (long long)offset, type);
> +		return -ENOEXEC;
> +	}
Unaligned is handled more efficiently before overflow checking, while
being consistent with apply_r_larch_sop_imm_field.

> +
> +	*location &= ~(u32)0x3ffffff;
> +	*location |= (offset >> 18) & 0x3ff;
> +	*location |= ((offset >> 2) & 0xffff) << 10;

It may be better to use the loongarch_instruction format to modify the
immediate field of the instruction, similar to the following:

union loongarch_instruction *insn = (union loongarch_instruction *)location;

offset >>= 2;
insn->reg0i26_format.immediate_l = offset & 0xffff;
insn->reg0i26_format.immediate_h = (offset >> 16) & 0x3ff;

> +	return 0;
> +}
> +
> +static int apply_r_larch_pcala_hi20(struct module *mod, u32 *location,
> +		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
> +		unsigned int type)
> +{
> +	ptrdiff_t offset = (void *)((v + 0x800) & ~0xfff) -
> +		(void *)((Elf_Addr)location & ~0xfff);
> +
> +	if (!signed_imm_check(offset, 32)) {
> +		pr_err("module %s: PCALA offset = 0x%llx does not fit in 32-bit signed and is unsupported by kernel! dangerous %s (%u) relocation\n",
> +				mod->name, (long long)offset, __func__, type);
> +		return -ENOEXEC;
> +	}
> +
> +	*location &= ~((u32)0xfffff << 5);
> +	*location |= ((offset >> 12) & 0xfffff) << 5;

Ditto.

> +	return 0;
> +}
> +
> +static int apply_r_larch_got_pc_hi20(struct module *mod, u32 *location,
> +		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
> +		unsigned int type)
> +{
> +	Elf_Addr got = module_emit_got_entry(mod, v);
> +
> +	return apply_r_larch_pcala_hi20(mod, location, got, rela_stack,
> +			rela_stack_top, type);
> +}
> +
> +static int apply_r_larch_pcala_lo12(struct module *mod, u32 *location,
> +		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
> +		unsigned int type)
> +{
> +	*location &= ~((u32)0xfff << 10);
> +	*location |= ((u32)v & 0xfff) << 10;

Ditto.

Thanks,
Youling
> +	return 0;
> +}
> +
> +static int apply_r_larch_got_pc_lo12(struct module *mod, u32 *location,
> +		Elf_Addr v, s64 *rela_stack, size_t *rela_stack_top,
> +		unsigned int type)
> +{
> +	Elf_Addr got = module_emit_got_entry(mod, v);
> +
> +	return apply_r_larch_pcala_lo12(mod, location, got, rela_stack,
> +			rela_stack_top, type);
> +}
> +
>  /*
>   * reloc_handlers_rela() - Apply a particular relocation to a module
>   * @mod: the module to apply the reloc to
> @@ -321,6 +399,11 @@ static reloc_rela_handler reloc_rela_handlers[] = {
>  	[R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE] 	     = apply_r_larch_sop,
>  	[R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field,
>  	[R_LARCH_ADD32 ... R_LARCH_SUB64]		     = apply_r_larch_add_sub,
> +	[R_LARCH_B26]					     = apply_r_larch_b26,
> +	[R_LARCH_PCALA_HI20]				     = apply_r_larch_pcala_hi20,
> +	[R_LARCH_PCALA_LO12]				     = apply_r_larch_pcala_lo12,
> +	[R_LARCH_GOT_PC_HI20]				     = apply_r_larch_got_pc_hi20,
> +	[R_LARCH_GOT_PC_LO12]				     = apply_r_larch_got_pc_lo12,
>  };
>
>  int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options
  2022-07-28 12:25   ` Huacai Chen
@ 2022-07-28 13:10     ` Xi Ruoyao
  2022-07-29  2:46       ` Huacai Chen
  0 siblings, 1 reply; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 13:10 UTC (permalink / raw)
  To: Huacai Chen; +Cc: loongarch, LKML, WANG Xuerui, Youling Tang, Jinyang He

On Thu, 2022-07-28 at 20:25 +0800, Huacai Chen wrote:
> Hi, Ruoyao,
> 
> On Thu, Jul 28, 2022 at 8:03 PM Xi Ruoyao <xry111@xry111.site> wrote:
> > 
> > Now we can handle GOT and GOT-based relocations properly, remove the
> > undocumented `-Wa,-mla-{global,local}-with-{pcrel,abs}` assembler
> > hacks.
> I think "-Wa,-mla-{global,local}-with-{pcrel,abs}" may be regular
> options rather than "hacks". If I'm right, the title and commit
> message should be updated. And we can send patches to binutils to make
> them "documented".

How about changing the message to:

   GCC 13 no longer generates la.global and la.local in assembly, but
   produces explicit PC-relative relocations to local symbols and GOT
   entries for global symbols instead.  As the result, -Wa,-mla-* are no
   longer sufficient to control the code generation for symbol address
   loading.  As now we can handle GOT and GOT-based relocations
   properly, remove those options to use GOT for global symbol address
   consistently.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 4/4] LoongArch: Support modules with new relocation types
  2022-07-28 12:41   ` Youling Tang
@ 2022-07-28 13:30     ` Xi Ruoyao
  0 siblings, 0 replies; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 13:30 UTC (permalink / raw)
  To: Youling Tang, loongarch
  Cc: linux-kernel, WANG Xuerui, Huacai Chen, Jinyang He

On Thu, 2022-07-28 at 20:41 +0800, Youling Tang wrote:
> Unaligned is handled more efficiently before overflow checking, while
> being consistent with apply_r_larch_sop_imm_field.

Will move unaligned before overflow in V3.

> > +
> > +       *location &= ~(u32)0x3ffffff;
> > +       *location |= (offset >> 18) & 0x3ff;
> > +       *location |= ((offset >> 2) & 0xffff) << 10;
> 
> It may be better to use the loongarch_instruction format to modify the
> immediate field of the instruction, similar to the following:
> 
> union loongarch_instruction *insn = (union loongarch_instruction *)location;
> 
> offset >>= 2;
> insn->reg0i26_format.immediate_l = offset & 0xffff;
> insn->reg0i26_format.immediate_h = (offset >> 16) & 0x3ff;

Will use union loongarch_instruction in V3.  Why didn't I notice it
before? :(

Thanks for the review!

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 0/4] LoongArch: Support new relocation types
  2022-07-28 12:33 ` [PATCH v2 0/4] LoongArch: Support " Huacai Chen
@ 2022-07-28 14:05   ` Xi Ruoyao
  0 siblings, 0 replies; 14+ messages in thread
From: Xi Ruoyao @ 2022-07-28 14:05 UTC (permalink / raw)
  To: Huacai Chen, Arnd Bergmann
  Cc: loongarch, LKML, WANG Xuerui, Youling Tang, Jinyang He

On Thu, 2022-07-28 at 20:33 +0800, Huacai Chen wrote:
> Hi, Arnd,

/* snip */

> Could you update the cross-compilers here [1] to make this series be
> possible upstream in the 5.20 cycle? Or we can only do that until new
> binutils/gcc be released?

Hi Huacai and Arnd,

The old toolchain will use

    R_LARCH_PUSH_PCREL _GLOBAL_OFFSET_TABLE_
    R_LARCH_PUSH_GPREL symbol
    R_LARCH_ADD

to perform a PC-relative addressing for a GOT entry, and the new
toolchain will use R_LARCH_GOT_PC_{HI20,LO12}.  Both way are supported
by this series.

I've tested the V3 patch (V2 + suggestions from Youling, I'll sent it
later after rewording the third patch) with both my system toolchain (no
new reloc support) and a toolchain built from binutils & gcc master. 
Both of the build works fine.

So a toolchain update seems not immediately required.
-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options
  2022-07-28 13:10     ` Xi Ruoyao
@ 2022-07-29  2:46       ` Huacai Chen
  0 siblings, 0 replies; 14+ messages in thread
From: Huacai Chen @ 2022-07-29  2:46 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: loongarch, LKML, WANG Xuerui, Youling Tang, Jinyang He

Hi, Ruoyao,

On Thu, Jul 28, 2022 at 9:10 PM Xi Ruoyao <xry111@xry111.site> wrote:
>
> On Thu, 2022-07-28 at 20:25 +0800, Huacai Chen wrote:
> > Hi, Ruoyao,
> >
> > On Thu, Jul 28, 2022 at 8:03 PM Xi Ruoyao <xry111@xry111.site> wrote:
> > >
> > > Now we can handle GOT and GOT-based relocations properly, remove the
> > > undocumented `-Wa,-mla-{global,local}-with-{pcrel,abs}` assembler
> > > hacks.
> > I think "-Wa,-mla-{global,local}-with-{pcrel,abs}" may be regular
> > options rather than "hacks". If I'm right, the title and commit
> > message should be updated. And we can send patches to binutils to make
> > them "documented".
>
> How about changing the message to:
>
>    GCC 13 no longer generates la.global and la.local in assembly, but
>    produces explicit PC-relative relocations to local symbols and GOT
>    entries for global symbols instead.  As the result, -Wa,-mla-* are no
>    longer sufficient to control the code generation for symbol address
>    loading.  As now we can handle GOT and GOT-based relocations
>    properly, remove those options to use GOT for global symbol address
>    consistently.
GCC 13 can still generate la.global and la.local, so "GCC 13 no longer
generates la.global and la.local in assembly by default" may be
better. And "undocumented" in the title should be "non-preferred", I
think.

Huacai

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-07-29  2:46 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-28 11:49 [PATCH v2 0/4] LoongArch: Support new relocation types Xi Ruoyao
2022-07-28 11:54 ` [PATCH v2 1/4] LoongArch: Add section of GOT for kernel module Xi Ruoyao
2022-07-28 11:59 ` [PATCH 2/4] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in " Xi Ruoyao
2022-07-28 12:30   ` Huacai Chen
2022-07-28 12:33     ` Xi Ruoyao
2022-07-28 12:03 ` [PATCH v2 3/4] LoongArch: Stop using undocumented assembler options Xi Ruoyao
2022-07-28 12:25   ` Huacai Chen
2022-07-28 13:10     ` Xi Ruoyao
2022-07-29  2:46       ` Huacai Chen
2022-07-28 12:04 ` [PATCH v2 4/4] LoongArch: Support modules with new relocation types Xi Ruoyao
2022-07-28 12:41   ` Youling Tang
2022-07-28 13:30     ` Xi Ruoyao
2022-07-28 12:33 ` [PATCH v2 0/4] LoongArch: Support " Huacai Chen
2022-07-28 14:05   ` Xi Ruoyao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.