From nobody Wed Apr 15 02:40:32 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 267F9C04A68 for ; Wed, 27 Jul 2022 16:35:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238390AbiG0Qfo (ORCPT ); Wed, 27 Jul 2022 12:35:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238160AbiG0QeE (ORCPT ); Wed, 27 Jul 2022 12:34:04 -0400 Received: from xry111.site (xry111.site [IPv6:2001:470:683e::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B6B155091 for ; Wed, 27 Jul 2022 09:26:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1658939182; bh=gPikXEVTEkOizm6Y/+JWUlq+5aMwIx1THz9Lm+KZLn8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=MDmd+PGp48e5VAE0kCqQTD9VpKg/H6SZ0c64YHgS3sZGgvne8pnzEX+s4zZ/FQSJS ekzrN07IzxucwhUjz8NfIjwW3raIEI2b0Ous2hDdQLgGFusdtd+GCDw/lc5aMm1how LxKoQi6FF8hPVPD9cFZW2eMRLwXyAJ4UZLEAPRDo= Received: from localhost.localdomain (xry111.site [IPv6:2001:470:683e::1]) (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 1437166986; Wed, 27 Jul 2022 12:26:20 -0400 (EDT) Message-ID: <3f43d51d530344f73a0a7087407799ff9dff3ba8.camel@xry111.site> Subject: [PATCH 1/5] LoongArch: Add section of GOT for kernel module From: Xi Ruoyao To: loongarch@lists.linux.dev Cc: linux-kernel@vger.kernel.org, WANG Xuerui , Huacai Chen Date: Thu, 28 Jul 2022 00:26:19 +0800 In-Reply-To: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> References: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.3 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Xi Ruoyao --- 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/a= sm/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; }; =20 struct plt_entry { @@ -28,11 +29,16 @@ struct plt_entry { u32 inst_jirl; }; =20 +struct got_entry { + Elf_Addr symbol_addr; +}; + struct plt_idx_entry { unsigned long symbol_addr; }; =20 Elf_Addr module_emit_plt_entry(struct module *mod, unsigned long val); +Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val); =20 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(un= signed long val) return (struct plt_idx_entry) { val }; } =20 +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 l= ong val, return plt + plt_idx; } =20 +static inline struct got_entry *get_got_entry(Elf_Addr val, + const struct mod_section *sec) +{ + struct got_entry *got =3D (struct got_entry *)sec->shdr->sh_addr; + int i; + + for (i =3D 0; i < sec->num_entries; i++) + if (got[i].symbol_addr =3D=3D val) + return &got[i]; + return NULL; +} + #endif /* _ASM_MODULE_H */ diff --git a/arch/loongarch/include/asm/module.lds.h b/arch/loongarch/inclu= de/asm/module.lds.h index 31c1c0db11a3..57bbd0cedd26 100644 --- a/arch/loongarch/include/asm/module.lds.h +++ b/arch/loongarch/include/asm/module.lds.h @@ -4,4 +4,5 @@ SECTIONS { . =3D ALIGN(4); .plt : { BYTE(0) } .plt.idx : { BYTE(0) } + .got : { BYTE(0) } } diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kerne= l/module-sections.c index 6d498288977d..509c0b86b1e9 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, unsig= ned long val) return (Elf_Addr)&plt[nr]; } =20 +Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val) +{ + struct mod_section *got_sec =3D &mod->arch.got; + int i =3D got_sec->num_entries; + struct got_entry *got =3D 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 =3D (struct got_entry *)got_sec->shdr->sh_addr; + got[i] =3D 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 =3D=3D y->r_info && x->r_addend =3D=3D y->r_addend; @@ -50,7 +69,8 @@ static bool duplicate_rela(const Elf_Rela *rela, int idx) return false; } =20 -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; =20 @@ -59,14 +79,16 @@ static void count_max_entries(Elf_Rela *relas, int num,= unsigned int *plts) if (type =3D=3D R_LARCH_SOP_PUSH_PLT_PCREL) { if (!duplicate_rela(relas, i)) (*plts)++; - } + } else if (type =3D=3D R_LARCH_SOP_PUSH_GPREL) + if (!duplicate_rela(relas, i)) + (*gots)++; } } =20 int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod) { - unsigned int i, num_plts =3D 0; + unsigned int i, num_plts =3D 0, num_gots =3D 0; =20 /* * Find the empty .plt sections. @@ -76,6 +98,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *s= echdrs, mod->arch.plt.shdr =3D sechdrs + i; else if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt.idx")) mod->arch.plt_idx.shdr =3D sechdrs + i; + else if (!strcmp(secstrings + sechdrs[i].sh_name, ".got")) + mod->arch.got.shdr =3D sechdrs + i; } =20 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; + } =20 /* Calculate the maxinum number of entries */ for (i =3D 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; =20 - count_max_entries(relas, num_rela, &num_plts); + count_max_entries(relas, num_rela, &num_plts, &num_gots); } =20 mod->arch.plt.shdr->sh_type =3D SHT_NOBITS; @@ -117,5 +145,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr= *sechdrs, mod->arch.plt_idx.num_entries =3D 0; mod->arch.plt_idx.max_entries =3D num_plts; =20 + mod->arch.got.shdr->sh_type =3D SHT_NOBITS; + mod->arch.got.shdr->sh_flags =3D SHF_ALLOC; + mod->arch.got.shdr->sh_addralign =3D L1_CACHE_BYTES; + mod->arch.got.shdr->sh_size =3D (num_plts + 1) * sizeof(struct plt_entry); + mod->arch.got.num_entries =3D 0; + mod->arch.got.max_entries =3D num_plts; + return 0; } --=20 2.37.0 From nobody Wed Apr 15 02:40:32 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0DE5C04A68 for ; Wed, 27 Jul 2022 16:37:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238961AbiG0QhO (ORCPT ); Wed, 27 Jul 2022 12:37:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238347AbiG0QfT (ORCPT ); Wed, 27 Jul 2022 12:35:19 -0400 Received: from xry111.site (xry111.site [89.208.246.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 328C356BB2 for ; Wed, 27 Jul 2022 09:27:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1658939237; bh=w78BZb3/xqbgYQ+T36abwKpBBa08iLK+uJwtwbDSaKg=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=HrXKGczgsN/yeNOdBYgBvIkK2za43JLopbFjIe09dStH7jCVaz901Wnmb3OlH8/HG dZ1f5HK6FVF06WYvVUwtGqx23jJwLaT21lZhoEGuo/HbfWGUVLy2vuwes/QSAkUXs3 ep6P+ub1a17cbpCpEzrRQo7O7rqOdecgo/1byKao= Received: from localhost.localdomain (xry111.site [IPv6:2001:470:683e::1]) (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 EC28766986; Wed, 27 Jul 2022 12:27:15 -0400 (EDT) Message-ID: <26cf3550ce5f6a02631da29361b3fcac30a598d9.camel@xry111.site> Subject: [PATCH 2/5] LoongArch: Support R_LARCH_SOP_PUSH_GPREL relocation type in kernel module From: Xi Ruoyao To: loongarch@lists.linux.dev Cc: linux-kernel@vger.kernel.org, WANG Xuerui , Huacai Chen Date: Thu, 28 Jul 2022 00:27:14 +0800 In-Reply-To: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> References: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.3 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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..e5f1fd022cd0 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 mod= ule *mod, u32 *location, E return apply_r_larch_sop_push_pcrel(mod, location, v, rela_stack, rela_st= ack_top, type); } =20 +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 =3D module_emit_got_entry(mod, v); + ptrdiff_t offset =3D (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) { @@ -310,6 +320,7 @@ static reloc_rela_handler reloc_rela_handlers[] =3D { [R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE] =3D apply_r_larch_sop, [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] =3D apply_r_larch_so= p_imm_field, [R_LARCH_ADD32 ... R_LARCH_SUB64] =3D apply_r_larch_add_sub, + [R_LARCH_SOP_PUSH_GPREL] =3D apply_r_larch_sop_push_gprel, }; =20 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, --=20 2.37.0 From nobody Wed Apr 15 02:40:32 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8202C04A68 for ; Wed, 27 Jul 2022 16:40:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239283AbiG0QkA (ORCPT ); Wed, 27 Jul 2022 12:40:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239463AbiG0QjQ (ORCPT ); Wed, 27 Jul 2022 12:39:16 -0400 Received: from xry111.site (xry111.site [IPv6:2001:470:683e::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B3035926A for ; Wed, 27 Jul 2022 09:28:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1658939322; bh=Iwt8WdYsuC5jK4JTIRtEaA1Ad9D4kr5a9YoeDI0+3FU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=ggUT3csrm6pEJ5Wmol1fudCE/EKG7wqnSEXfikmrzN+PId1w+FCAFt1KI5jXx5vR4 EQZyhh27swq4ZjBoxFDDvhO+wRGLrlculT22SI0eE9uJGohhNj36eaiR7l3vP3UqnI kQtnSlTbcHEX26UpQspAh35ZnYqaKnIyHzJEXjN0= Received: from localhost.localdomain (xry111.site [IPv6:2001:470:683e::1]) (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 0E74266986; Wed, 27 Jul 2022 12:28:40 -0400 (EDT) Message-ID: <99733532831377ab6585d43ee40bf314a2d4c5a3.camel@xry111.site> Subject: [PATCH 3/5] LoongArch: Support relocation against _GLOBAL_OFFSET_TABLE_ From: Xi Ruoyao To: loongarch@lists.linux.dev Cc: linux-kernel@vger.kernel.org, WANG Xuerui , Huacai Chen Date: Thu, 28 Jul 2022 00:28:39 +0800 In-Reply-To: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> References: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.3 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" With the stack-based relocations, the assembler emits three relocations to push the PC-relative offset of a GOT entry: R_LARCH_SOP_PUSH_PCREL _GLOBAL_OFFSET_TABLE_ R_LARCH_SOP_PUSH_GPREL foo R_LARCH_SOP_ADD "_GLOBAL_OFFSET_TABLE_" does not really exist in the symtab and the BFD linker handles it with special hack. Implement a similar hack for kernel so we will be able to really use R_LARCH_SOP_PUSH_GPREL relocation. Signed-off-by: Xi Ruoyao Suggested-by: Jinyang He --- arch/loongarch/kernel/module-sections.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kerne= l/module-sections.c index 509c0b86b1e9..73976addbf60 100644 --- a/arch/loongarch/kernel/module-sections.c +++ b/arch/loongarch/kernel/module-sections.c @@ -89,6 +89,9 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *s= echdrs, char *secstrings, struct module *mod) { unsigned int i, num_plts =3D 0, num_gots =3D 0; + Elf_Shdr *symtab =3D NULL; + Elf_Sym *symbols; + char *strings; =20 /* * Find the empty .plt sections. @@ -100,6 +103,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr = *sechdrs, mod->arch.plt_idx.shdr =3D sechdrs + i; else if (!strcmp(secstrings + sechdrs[i].sh_name, ".got")) mod->arch.got.shdr =3D sechdrs + i; + else if (sechdrs[i].sh_type =3D=3D SHT_SYMTAB) + symtab =3D sechdrs + i; } =20 if (!mod->arch.plt.shdr) { @@ -115,6 +120,22 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr= *sechdrs, return -ENOEXEC; } =20 + if (!symtab) { + pr_err("%s: module symbol table missing\n", mod->name); + return -ENOEXEC; + } + + symbols =3D (void *) ehdr + symtab->sh_offset; + strings =3D (void *) ehdr + sechdrs[symtab->sh_link].sh_offset; + + for (i =3D 0; i < symtab->sh_size / sizeof(Elf_Sym); i++) + if (symbols[i].st_shndx =3D=3D SHN_UNDEF && + strcmp(strings + symbols[i].st_name, + "_GLOBAL_OFFSET_TABLE_") =3D=3D 0) { + symbols[i].st_shndx =3D mod->arch.got.shdr - sechdrs; + symbols[i].st_value =3D 0; + } + /* Calculate the maxinum number of entries */ for (i =3D 0; i < ehdr->e_shnum; i++) { int num_rela =3D sechdrs[i].sh_size / sizeof(Elf_Rela); --=20 2.37.0 From nobody Wed Apr 15 02:40:32 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 505FFC04A68 for ; Wed, 27 Jul 2022 16:42:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239616AbiG0QmX (ORCPT ); Wed, 27 Jul 2022 12:42:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239238AbiG0Qli (ORCPT ); Wed, 27 Jul 2022 12:41:38 -0400 Received: from xry111.site (xry111.site [IPv6:2001:470:683e::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1F1E5B783 for ; Wed, 27 Jul 2022 09:29:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1658939381; bh=5uWlBqSdy2RPXpPwAJasX2ffP9FsCCAt1xQrucd15uE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=OpQy5wSbA7dWTR3bn656uDvmG/mlT/P6ZI96Voa5qTeK1Vq4TWpncb5MS+OaJX+mz 1XQ0HhQ+DX1OP+BOznPPVsBVcB2raCCtbmA4XY1/CS2PZW6Agv/tj+ujn2wV8rdrks ndK8/A+E1blc08HcrDtXY/pHtkmPR+sB3UUeDcv0= Received: from localhost.localdomain (xry111.site [IPv6:2001:470:683e::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384)) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 40DDD66986; Wed, 27 Jul 2022 12:29:39 -0400 (EDT) Message-ID: <4f09c81c22d0a16883a6914a8f7209957386c07c.camel@xry111.site> Subject: [PATCH 4/5] LoongArch: Stop using undocumented assembler options From: Xi Ruoyao To: loongarch@lists.linux.dev Cc: linux-kernel@vger.kernel.org, WANG Xuerui , Huacai Chen Date: Thu, 28 Jul 2022 00:29:38 +0800 In-Reply-To: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> References: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.3 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Now we can handle GOT and GOT-based relocations properly, remove the undocumented `-Wa,-mla-{global,local}-with-{pcrel,abs}` assembler hacks. Adjust assembly code to explicitly use "la.pcrel" where necessary. Signed-off-by: Xi Ruoyao --- arch/loongarch/Makefile | 5 +---- arch/loongarch/kernel/head.S | 10 +++++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile index 039dcc4fe1f3..9552c7880d34 100644 --- a/arch/loongarch/Makefile +++ b/arch/loongarch/Makefile @@ -40,10 +40,7 @@ endif =20 cflags-y +=3D -G0 -pipe -msoft-float LDFLAGS_vmlinux +=3D -G0 -static -n -nostdlib -KBUILD_AFLAGS_KERNEL +=3D -Wa,-mla-global-with-pcrel -KBUILD_CFLAGS_KERNEL +=3D -Wa,-mla-global-with-pcrel -KBUILD_AFLAGS_MODULE +=3D -Wa,-mla-global-with-abs -KBUILD_CFLAGS_MODULE +=3D -fplt -Wa,-mla-global-with-abs,-mla-local-with-= abs +KBUILD_CFLAGS_MODULE +=3D -fplt =20 cflags-y +=3D -ffreestanding cflags-y +=3D $(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 =20 - 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 =20 /* 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 =20 - 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 --=20 2.37.0 From nobody Wed Apr 15 02:40:32 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0AC60C3F6B0 for ; Wed, 27 Jul 2022 16:45:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240363AbiG0Qpp (ORCPT ); Wed, 27 Jul 2022 12:45:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240482AbiG0Qo3 (ORCPT ); Wed, 27 Jul 2022 12:44:29 -0400 Received: from xry111.site (xry111.site [IPv6:2001:470:683e::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D5B025F108 for ; Wed, 27 Jul 2022 09:31:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1658939469; bh=HrNxPzF6dJ12J1BPkZaz5pUYuW251mjEZT0aRcTaEHQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=XIRjQux7MbnnW0Aj0AGPLttXUPm8Yw+iCdS0o3c7e7/Gy0uXgEXPAHrwHhZ72i6Lf fqaVEsfKo4q64xC5x21iUOLSzZi6rftk8SS/xchNMpz8KvjB77nmvW0kI/w8j3rk/N kM4u3WWUKTS7rNAQ9S2LjSh8OcZGrTGTfKbHLQqM= Received: from localhost.localdomain (xry111.site [IPv6:2001:470:683e::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384)) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 4B3016698A; Wed, 27 Jul 2022 12:31:08 -0400 (EDT) Message-ID: <4007f3ef167f93ffd9fcae841e144a0fc89f0117.camel@xry111.site> Subject: [PATCH 5/5] LoongArch: Support modules with new relocation types From: Xi Ruoyao To: loongarch@lists.linux.dev Cc: linux-kernel@vger.kernel.org, WANG Xuerui , Huacai Chen Date: Thu, 28 Jul 2022 00:31:07 +0800 In-Reply-To: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> References: <385f63bcbee8e37c42f479ce9cdc7e7d731d419b.camel@xry111.site> Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.3 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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 f3960b18a90e..aeca7a9924ea 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 =20 #ifndef ELF_ARCH =20 diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kerne= l/module-sections.c index 73976addbf60..9baf119388b9 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, =20 for (i =3D 0; i < num; i++) { type =3D ELF_R_TYPE(relas[i].r_info); - if (type =3D=3D 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 =3D=3D 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. */ + } } } =20 diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c index e5f1fd022cd0..1aa6a58b1c21 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, u= 32 *location, Elf_Addr v, } } =20 +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 =3D (void *)v - (void *)location; + + if (offset >=3D SZ_128M) + v =3D module_emit_plt_entry(mod, v); + + if (offset < -SZ_128M) + v =3D module_emit_plt_entry(mod, v); + + offset =3D (void *)v - (void *)location; + + if (!signed_imm_check(offset, 28)) { + pr_err("module %s: jump offset =3D 0x%llx overflow! dangerous R_LARCH_B2= 6 (%u) relocation\n", + mod->name, (long long)offset, type); + return -ENOEXEC; + } + + if (offset & 3) { + pr_err("module %s: jump offset =3D 0x%llx unaligned! dangerous R_LARCH_B= 26 (%u) relocation\n", + mod->name, (long long)offset, type); + return -ENOEXEC; + } + + *location &=3D ~(u32)0x3ffffff; + *location |=3D (offset >> 18) & 0x3ff; + *location |=3D ((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 =3D (void *)((v + 0x800) & ~0xfff) - + (void *)((Elf_Addr)location & ~0xfff); + + if (!signed_imm_check(offset, 32)) { + pr_err("module %s: PCALA offset =3D 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 &=3D ~((u32)0xfffff << 5); + *location |=3D ((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 =3D 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 &=3D ~((u32)0xfff << 10); + *location |=3D ((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 =3D 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[] =3D { [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] =3D apply_r_larch_so= p_imm_field, [R_LARCH_ADD32 ... R_LARCH_SUB64] =3D apply_r_larch_add_sub, [R_LARCH_SOP_PUSH_GPREL] =3D apply_r_larch_sop_push_gprel, + [R_LARCH_B26] =3D apply_r_larch_b26, + [R_LARCH_PCALA_HI20] =3D apply_r_larch_pcala_hi20, + [R_LARCH_PCALA_LO12] =3D apply_r_larch_pcala_lo12, + [R_LARCH_GOT_PC_HI20] =3D apply_r_larch_got_pc_hi20, + [R_LARCH_GOT_PC_LO12] =3D apply_r_larch_got_pc_lo12, }; =20 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, --=20 2.37.0