ARM: 9252/1: module: Teach unwinder about PLTs
"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. Link: https://lore.kernel.org/linux-arm-kernel/20200402153845.30985-1-kursad.oney@broadcom.com/ Tested-by: Kursad Oney <kursad.oney@broadcom.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
This commit is contained in:
parent
e66372ecb8
commit
4ab07fd3fb
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user