From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Chen Zhongjin <chenzhongjin@huawei.com>
Cc: alexander.sverdlin@nokia.com, ardb@kernel.org,
linus.walleij@linaro.org, nico@fluxnic.net,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] ARM: module: Add all unwind tables when load module
Date: Thu, 31 Mar 2022 07:55:24 +0100 [thread overview]
Message-ID: <YkVQXPYkae41B7Z2@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220325011252.55844-1-chenzhongjin@huawei.com>
Hi,
On Fri, Mar 25, 2022 at 09:12:52AM +0800, Chen Zhongjin wrote:
> For EABI stack unwinding, when loading .ko module
> the EXIDX sections will be added to a unwind_table list.
>
> However not all EXIDX sections are added because EXIDX
> sections are searched by hardcoded section names.
>
> For functions in other sections such as .ref.text
> or .kprobes.text, gcc generates seprated EXIDX sections
> (such as .ARM.exidx.ref.text or .ARM.exidx.kprobes.text).
>
> These extra EXIDX sections are not loaded, so when unwinding
> functions in these sections, we will failed with:
>
> unwind: Index not found xxx
>
> To fix that, I refactor the code for searching and adding
> EXIDX sections:
>
> - Check section type to search EXIDX tables (0x70000001)
> instead of strcmp() the hardcoded names. Then find the
> corresponding text sections by their section names.
>
> - Add a unwind_table list in module->arch to save their own
> unwind_table instead of the fixed-lenth array.
>
> - Save .ARM.exidx.init.text section ptr, because it should
> be cleaned after module init.
>
> Now all EXIDX sections of .ko can be added correctly.
>
> Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
> ---
> arch/arm/include/asm/module.h | 17 ++------
> arch/arm/include/asm/unwind.h | 1 +
> arch/arm/kernel/module.c | 73 +++++++++++++++++------------------
> 3 files changed, 40 insertions(+), 51 deletions(-)
>
> diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
> index cfffae67c04e..8139b6a33a22 100644
> --- a/arch/arm/include/asm/module.h
> +++ b/arch/arm/include/asm/module.h
> @@ -3,20 +3,10 @@
> #define _ASM_ARM_MODULE_H
>
> #include <asm-generic/module.h>
> -
> -struct unwind_table;
> +#include <asm/unwind.h>
>
> #ifdef CONFIG_ARM_UNWIND
> -enum {
> - ARM_SEC_INIT,
> - ARM_SEC_DEVINIT,
> - ARM_SEC_CORE,
> - ARM_SEC_EXIT,
> - ARM_SEC_DEVEXIT,
> - ARM_SEC_HOT,
> - ARM_SEC_UNLIKELY,
> - ARM_SEC_MAX,
> -};
> +#define ELF_SECTION_UNWIND 0x70000001
> #endif
>
> #define PLT_ENT_STRIDE L1_CACHE_BYTES
> @@ -36,7 +26,8 @@ struct mod_plt_sec {
>
> struct mod_arch_specific {
> #ifdef CONFIG_ARM_UNWIND
> - struct unwind_table *unwind[ARM_SEC_MAX];
> + struct unwind_table unwind_list;
> + struct unwind_table *init_table;
> #endif
> #ifdef CONFIG_ARM_MODULE_PLTS
> struct mod_plt_sec core;
> diff --git a/arch/arm/include/asm/unwind.h b/arch/arm/include/asm/unwind.h
> index 0f8a3439902d..b51f85417f58 100644
> --- a/arch/arm/include/asm/unwind.h
> +++ b/arch/arm/include/asm/unwind.h
> @@ -24,6 +24,7 @@ struct unwind_idx {
>
> struct unwind_table {
> struct list_head list;
> + struct list_head mod_list;
> const struct unwind_idx *start;
> const struct unwind_idx *origin;
> const struct unwind_idx *stop;
> diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
> index 549abcedf795..272f9bdeb1ed 100644
> --- a/arch/arm/kernel/module.c
> +++ b/arch/arm/kernel/module.c
> @@ -459,46 +459,36 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
> #ifdef CONFIG_ARM_UNWIND
> const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
> const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;
> - struct mod_unwind_map maps[ARM_SEC_MAX];
> - int i;
> + struct unwind_table *table_list = &mod->arch.unwind_list;
Please rename "table_list" to "unwind_list" so we use a consistent name
for this.
>
> - memset(maps, 0, sizeof(maps));
> + INIT_LIST_HEAD(&table_list->mod_list);
> + mod->arch.init_table = NULL;
>
> for (s = sechdrs; s < sechdrs_end; s++) {
> - const char *secname = secstrs + s->sh_name;
> + const unsigned int sectype = s->sh_type;
Please loose this local variable.
>
> if (!(s->sh_flags & SHF_ALLOC))
> continue;
>
> - if (strcmp(".ARM.exidx.init.text", secname) == 0)
> - maps[ARM_SEC_INIT].unw_sec = s;
> - else if (strcmp(".ARM.exidx", secname) == 0)
> - maps[ARM_SEC_CORE].unw_sec = s;
> - else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
> - maps[ARM_SEC_EXIT].unw_sec = s;
> - else if (strcmp(".ARM.exidx.text.unlikely", secname) == 0)
> - maps[ARM_SEC_UNLIKELY].unw_sec = s;
> - else if (strcmp(".ARM.exidx.text.hot", secname) == 0)
> - maps[ARM_SEC_HOT].unw_sec = s;
> - else if (strcmp(".init.text", secname) == 0)
> - maps[ARM_SEC_INIT].txt_sec = s;
> - else if (strcmp(".text", secname) == 0)
> - maps[ARM_SEC_CORE].txt_sec = s;
> - else if (strcmp(".exit.text", secname) == 0)
> - maps[ARM_SEC_EXIT].txt_sec = s;
> - else if (strcmp(".text.unlikely", secname) == 0)
> - maps[ARM_SEC_UNLIKELY].txt_sec = s;
> - else if (strcmp(".text.hot", secname) == 0)
> - maps[ARM_SEC_HOT].txt_sec = s;
> + if (sectype == ELF_SECTION_UNWIND) {
I think given the amouont of indentation this causes, that:
if (!(s->sh_flags & SHF_ALLOC)) ||
s->sh_type != ELF_SECTION_UNWIND)
continue;
would be preferred here.
Other than that, patch looks fine, thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Chen Zhongjin <chenzhongjin@huawei.com>
Cc: alexander.sverdlin@nokia.com, ardb@kernel.org,
linus.walleij@linaro.org, nico@fluxnic.net,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] ARM: module: Add all unwind tables when load module
Date: Thu, 31 Mar 2022 07:55:24 +0100 [thread overview]
Message-ID: <YkVQXPYkae41B7Z2@shell.armlinux.org.uk> (raw)
In-Reply-To: <20220325011252.55844-1-chenzhongjin@huawei.com>
Hi,
On Fri, Mar 25, 2022 at 09:12:52AM +0800, Chen Zhongjin wrote:
> For EABI stack unwinding, when loading .ko module
> the EXIDX sections will be added to a unwind_table list.
>
> However not all EXIDX sections are added because EXIDX
> sections are searched by hardcoded section names.
>
> For functions in other sections such as .ref.text
> or .kprobes.text, gcc generates seprated EXIDX sections
> (such as .ARM.exidx.ref.text or .ARM.exidx.kprobes.text).
>
> These extra EXIDX sections are not loaded, so when unwinding
> functions in these sections, we will failed with:
>
> unwind: Index not found xxx
>
> To fix that, I refactor the code for searching and adding
> EXIDX sections:
>
> - Check section type to search EXIDX tables (0x70000001)
> instead of strcmp() the hardcoded names. Then find the
> corresponding text sections by their section names.
>
> - Add a unwind_table list in module->arch to save their own
> unwind_table instead of the fixed-lenth array.
>
> - Save .ARM.exidx.init.text section ptr, because it should
> be cleaned after module init.
>
> Now all EXIDX sections of .ko can be added correctly.
>
> Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
> ---
> arch/arm/include/asm/module.h | 17 ++------
> arch/arm/include/asm/unwind.h | 1 +
> arch/arm/kernel/module.c | 73 +++++++++++++++++------------------
> 3 files changed, 40 insertions(+), 51 deletions(-)
>
> diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
> index cfffae67c04e..8139b6a33a22 100644
> --- a/arch/arm/include/asm/module.h
> +++ b/arch/arm/include/asm/module.h
> @@ -3,20 +3,10 @@
> #define _ASM_ARM_MODULE_H
>
> #include <asm-generic/module.h>
> -
> -struct unwind_table;
> +#include <asm/unwind.h>
>
> #ifdef CONFIG_ARM_UNWIND
> -enum {
> - ARM_SEC_INIT,
> - ARM_SEC_DEVINIT,
> - ARM_SEC_CORE,
> - ARM_SEC_EXIT,
> - ARM_SEC_DEVEXIT,
> - ARM_SEC_HOT,
> - ARM_SEC_UNLIKELY,
> - ARM_SEC_MAX,
> -};
> +#define ELF_SECTION_UNWIND 0x70000001
> #endif
>
> #define PLT_ENT_STRIDE L1_CACHE_BYTES
> @@ -36,7 +26,8 @@ struct mod_plt_sec {
>
> struct mod_arch_specific {
> #ifdef CONFIG_ARM_UNWIND
> - struct unwind_table *unwind[ARM_SEC_MAX];
> + struct unwind_table unwind_list;
> + struct unwind_table *init_table;
> #endif
> #ifdef CONFIG_ARM_MODULE_PLTS
> struct mod_plt_sec core;
> diff --git a/arch/arm/include/asm/unwind.h b/arch/arm/include/asm/unwind.h
> index 0f8a3439902d..b51f85417f58 100644
> --- a/arch/arm/include/asm/unwind.h
> +++ b/arch/arm/include/asm/unwind.h
> @@ -24,6 +24,7 @@ struct unwind_idx {
>
> struct unwind_table {
> struct list_head list;
> + struct list_head mod_list;
> const struct unwind_idx *start;
> const struct unwind_idx *origin;
> const struct unwind_idx *stop;
> diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
> index 549abcedf795..272f9bdeb1ed 100644
> --- a/arch/arm/kernel/module.c
> +++ b/arch/arm/kernel/module.c
> @@ -459,46 +459,36 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
> #ifdef CONFIG_ARM_UNWIND
> const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
> const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;
> - struct mod_unwind_map maps[ARM_SEC_MAX];
> - int i;
> + struct unwind_table *table_list = &mod->arch.unwind_list;
Please rename "table_list" to "unwind_list" so we use a consistent name
for this.
>
> - memset(maps, 0, sizeof(maps));
> + INIT_LIST_HEAD(&table_list->mod_list);
> + mod->arch.init_table = NULL;
>
> for (s = sechdrs; s < sechdrs_end; s++) {
> - const char *secname = secstrs + s->sh_name;
> + const unsigned int sectype = s->sh_type;
Please loose this local variable.
>
> if (!(s->sh_flags & SHF_ALLOC))
> continue;
>
> - if (strcmp(".ARM.exidx.init.text", secname) == 0)
> - maps[ARM_SEC_INIT].unw_sec = s;
> - else if (strcmp(".ARM.exidx", secname) == 0)
> - maps[ARM_SEC_CORE].unw_sec = s;
> - else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
> - maps[ARM_SEC_EXIT].unw_sec = s;
> - else if (strcmp(".ARM.exidx.text.unlikely", secname) == 0)
> - maps[ARM_SEC_UNLIKELY].unw_sec = s;
> - else if (strcmp(".ARM.exidx.text.hot", secname) == 0)
> - maps[ARM_SEC_HOT].unw_sec = s;
> - else if (strcmp(".init.text", secname) == 0)
> - maps[ARM_SEC_INIT].txt_sec = s;
> - else if (strcmp(".text", secname) == 0)
> - maps[ARM_SEC_CORE].txt_sec = s;
> - else if (strcmp(".exit.text", secname) == 0)
> - maps[ARM_SEC_EXIT].txt_sec = s;
> - else if (strcmp(".text.unlikely", secname) == 0)
> - maps[ARM_SEC_UNLIKELY].txt_sec = s;
> - else if (strcmp(".text.hot", secname) == 0)
> - maps[ARM_SEC_HOT].txt_sec = s;
> + if (sectype == ELF_SECTION_UNWIND) {
I think given the amouont of indentation this causes, that:
if (!(s->sh_flags & SHF_ALLOC)) ||
s->sh_type != ELF_SECTION_UNWIND)
continue;
would be preferred here.
Other than that, patch looks fine, thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
next prev parent reply other threads:[~2022-03-31 6:56 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-25 1:12 [PATCH] ARM: module: Add all unwind tables when load module Chen Zhongjin
2022-03-25 1:12 ` Chen Zhongjin
2022-03-31 2:18 ` Chen Zhongjin
2022-03-31 2:18 ` Chen Zhongjin
2022-03-31 6:55 ` Russell King (Oracle) [this message]
2022-03-31 6:55 ` Russell King (Oracle)
2022-03-31 10:15 ` Chen Zhongjin
2022-03-31 10:15 ` Chen Zhongjin
2022-03-31 10:35 ` Russell King (Oracle)
2022-03-31 10:35 ` Russell King (Oracle)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YkVQXPYkae41B7Z2@shell.armlinux.org.uk \
--to=linux@armlinux.org.uk \
--cc=alexander.sverdlin@nokia.com \
--cc=ardb@kernel.org \
--cc=chenzhongjin@huawei.com \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nico@fluxnic.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.