summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/objtool/arch/loongarch/special.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/tools/objtool/arch/loongarch/special.c b/tools/objtool/arch/loongarch/special.c
index 4fa6877d5b2b..e39f86d97002 100644
--- a/tools/objtool/arch/loongarch/special.c
+++ b/tools/objtool/arch/loongarch/special.c
@@ -116,6 +116,30 @@ static struct reloc *find_reloc_by_table_annotate(struct objtool_file *file,
return NULL;
}
+static struct reloc *find_reloc_of_rodata_c_jump_table(struct section *sec,
+ unsigned long offset,
+ unsigned long *table_size)
+{
+ struct section *rsec;
+ struct reloc *reloc;
+
+ rsec = sec->rsec;
+ if (!rsec)
+ return NULL;
+
+ for_each_reloc(rsec, reloc) {
+ if (reloc_offset(reloc) > offset)
+ break;
+
+ if (!strcmp(reloc->sym->sec->name, C_JUMP_TABLE_SECTION)) {
+ *table_size = 0;
+ return reloc;
+ }
+ }
+
+ return NULL;
+}
+
struct reloc *arch_find_switch_table(struct objtool_file *file,
struct instruction *insn,
unsigned long *table_size)
@@ -126,8 +150,12 @@ struct reloc *arch_find_switch_table(struct objtool_file *file,
unsigned long table_offset;
annotate_reloc = find_reloc_by_table_annotate(file, insn, table_size);
- if (!annotate_reloc)
- return NULL;
+ if (!annotate_reloc) {
+ annotate_reloc = find_reloc_of_rodata_c_jump_table(
+ insn->sec, insn->offset, table_size);
+ if (!annotate_reloc)
+ return NULL;
+ }
table_sec = annotate_reloc->sym->sec;
table_offset = annotate_reloc->sym->offset + reloc_addend(annotate_reloc);