diff options
-rw-r--r-- | tools/objtool/arch/loongarch/decode.c | 17 | ||||
-rw-r--r-- | tools/objtool/arch/loongarch/include/arch/elf.h | 7 | ||||
-rw-r--r-- | tools/objtool/check.c | 7 | ||||
-rw-r--r-- | tools/objtool/include/objtool/arch.h | 1 |
4 files changed, 27 insertions, 5 deletions
diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c index b64205b89f6b..02e490555966 100644 --- a/tools/objtool/arch/loongarch/decode.c +++ b/tools/objtool/arch/loongarch/decode.c @@ -5,10 +5,7 @@ #include <asm/inst.h> #include <asm/orc_types.h> #include <linux/objtool_types.h> - -#ifndef EM_LOONGARCH -#define EM_LOONGARCH 258 -#endif +#include <arch/elf.h> int arch_ftrace_match(char *name) { @@ -374,3 +371,15 @@ unsigned int arch_reloc_size(struct reloc *reloc) return 8; } } + +unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table) +{ + switch (reloc_type(reloc)) { + case R_LARCH_32_PCREL: + case R_LARCH_64_PCREL: + return reloc->sym->offset + reloc_addend(reloc) - + (reloc_offset(reloc) - reloc_offset(table)); + default: + return reloc->sym->offset + reloc_addend(reloc); + } +} diff --git a/tools/objtool/arch/loongarch/include/arch/elf.h b/tools/objtool/arch/loongarch/include/arch/elf.h index 9623d663220e..ec79062c9554 100644 --- a/tools/objtool/arch/loongarch/include/arch/elf.h +++ b/tools/objtool/arch/loongarch/include/arch/elf.h @@ -18,6 +18,13 @@ #ifndef R_LARCH_32_PCREL #define R_LARCH_32_PCREL 99 #endif +#ifndef R_LARCH_64_PCREL +#define R_LARCH_64_PCREL 109 +#endif + +#ifndef EM_LOONGARCH +#define EM_LOONGARCH 258 +#endif #define R_NONE R_LARCH_NONE #define R_ABS32 R_LARCH_32 diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f762d231c747..7dbf22c6da9d 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1944,6 +1944,11 @@ out: return ret; } +__weak unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table) +{ + return reloc->sym->offset + reloc_addend(reloc); +} + static int add_jump_table(struct objtool_file *file, struct instruction *insn, struct reloc *next_table) { @@ -1972,7 +1977,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn, if (prev_offset && reloc_offset(reloc) != prev_offset + arch_reloc_size(reloc)) break; - sym_offset = reloc->sym->offset + reloc_addend(reloc); + sym_offset = arch_jump_table_sym_offset(reloc, table); /* Detect function pointers from contiguous objects: */ if (reloc->sym->sec == pfunc->sec && sym_offset == pfunc->offset) diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h index 396f7c6c81c0..089a1acc48a8 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -98,5 +98,6 @@ int arch_rewrite_retpolines(struct objtool_file *file); bool arch_pc_relative_reloc(struct reloc *reloc); unsigned int arch_reloc_size(struct reloc *reloc); +unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table); #endif /* _ARCH_H */ |