Messages in this thread | | | Date | Wed, 24 Aug 2022 15:04:08 +0200 | Subject | Re: [PATCH] ARM: module: Teach unwinder about PLTs | From | Alexander Sverdlin <> |
| |
Hello Russel,
shall I add this one to your patch tracker? There is little interest to this patch, but also no complaints, as I can tell.
On 06/07/2022 18:31, Alexander A Sverdlin wrote: > From: Alexander Sverdlin <alexander.sverdlin@nokia.com> > > "unwind: Index not found eef26358" warnings keep popping up on > CONFIG_ARM_MODULE_PLTS-enabled systems if the PC points to a PLT veneer. > Teach the unwinder how to deal with them, taking into account they don't > change state of the stack or register file except loading PC. > > Tested-by: Kursad Oney <kursad.oney@broadcom.com> > Link: https://lore.kernel.org/linux-arm-kernel/20200402153845.30985-1-kursad.oney@broadcom.com/ > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> > --- > arch/arm/include/asm/module.h | 5 +++++ > arch/arm/kernel/module-plts.c | 14 ++++++++++++++ > arch/arm/kernel/unwind.c | 13 ++++++++++++- > 3 files changed, 31 insertions(+), 1 deletion(-) > > diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h > index 5546c9751478c..07c51a34f77d5 100644 > --- a/arch/arm/include/asm/module.h > +++ b/arch/arm/include/asm/module.h > @@ -37,6 +37,11 @@ struct mod_arch_specific { > > struct module; > u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val); > +#ifdef CONFIG_ARM_MODULE_PLTS > +bool in_module_plt(unsigned long loc); > +#else > +static inline bool in_module_plt(unsigned long loc) { return false; } > +#endif > > #ifdef CONFIG_THUMB2_KERNEL > #define HAVE_ARCH_KALLSYMS_SYMBOL_VALUE > diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c > index 1fc309b41f944..af7c322ebed68 100644 > --- a/arch/arm/kernel/module-plts.c > +++ b/arch/arm/kernel/module-plts.c > @@ -284,3 +284,17 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, > mod->arch.core.plt->sh_size, mod->arch.init.plt->sh_size); > return 0; > } > + > +bool in_module_plt(unsigned long loc) > +{ > + struct module *mod; > + bool ret; > + > + preempt_disable(); > + mod = __module_text_address(loc); > + ret = mod && (loc - (u32)mod->arch.core.plt_ent < mod->arch.core.plt_count * PLT_ENT_SIZE || > + loc - (u32)mod->arch.init.plt_ent < mod->arch.init.plt_count * PLT_ENT_SIZE); > + preempt_enable(); > + > + return ret; > +} > diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c > index a37ea6c772cd5..53be7ea6181b3 100644 > --- a/arch/arm/kernel/unwind.c > +++ b/arch/arm/kernel/unwind.c > @@ -28,6 +28,7 @@ > #include <linux/slab.h> > #include <linux/spinlock.h> > #include <linux/list.h> > +#include <linux/module.h> > > #include <asm/stacktrace.h> > #include <asm/traps.h> > @@ -395,8 +396,18 @@ int unwind_frame(struct stackframe *frame) > > idx = unwind_find_idx(frame->pc); > if (!idx) { > - if (frame->pc && kernel_text_address(frame->pc)) > + if (frame->pc && kernel_text_address(frame->pc)) { > + if (in_module_plt(frame->pc) && frame->pc != frame->lr) { > + /* > + * Quoting Ard: Veneers only set PC using a > + * PC+immediate LDR, and so they don't affect > + * the state of the stack or the register file > + */ > + frame->pc = frame->lr; > + return URC_OK; > + } > pr_warn("unwind: Index not found %08lx\n", frame->pc); > + } > return -URC_FAILURE; > } >
-- Best regards, Alexander Sverdlin.
| |