Skip to content

Commit a47bc95

Browse files
seehearfeelchenhuacai
authored andcommitted
objtool/LoongArch: Get table size correctly if LTO is enabled
When compiling with LLVM and CONFIG_LTO_CLANG is set, there exist many objtool warnings "sibling call from callable instruction with modified stack frame". For this special case, the related object file shows that there is no generated relocation section '.rela.discard.tablejump_annotate' for the table jump instruction jirl, thus objtool can not know that what is the actual destination address. It needs to do something on the LLVM side to make sure that there is the relocation section '.rela.discard.tablejump_annotate' if LTO is enabled, but in order to maintain compatibility for the current LLVM compiler, this can be done in the kernel Makefile for now. Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' needs to be passed via '-mllvm' to ld.lld. Before doing the above changes, it should handle the special case of the relocation section '.rela.discard.tablejump_annotate' to get the correct table size first, otherwise there are many objtool warnings and errors if LTO is enabled. There are many different rodata for each function if LTO is enabled, it is necessary to enhance get_rodata_table_size_by_table_annotate(). Fixes: b95f852 ("objtool/LoongArch: Add support for switch table") Closes: https://lore.kernel.org/loongarch/20250731175655.GA1455142@ax162/ Reported-by: Nathan Chancellor <nathan@kernel.org> Tested-by: Nathan Chancellor <nathan@kernel.org> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent c17b750 commit a47bc95

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

tools/objtool/arch/loongarch/special.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,
2727
struct table_info *next_table;
2828
unsigned long tmp_insn_offset;
2929
unsigned long tmp_rodata_offset;
30+
bool is_valid_list = false;
3031

3132
rsec = find_section_by_name(file->elf, ".rela.discard.tablejump_annotate");
3233
if (!rsec)
@@ -35,6 +36,12 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,
3536
INIT_LIST_HEAD(&table_list);
3637

3738
for_each_reloc(rsec, reloc) {
39+
if (reloc->sym->sec->rodata)
40+
continue;
41+
42+
if (strcmp(insn->sec->name, reloc->sym->sec->name))
43+
continue;
44+
3845
orig_table = malloc(sizeof(struct table_info));
3946
if (!orig_table) {
4047
WARN("malloc failed");
@@ -49,6 +56,22 @@ static void get_rodata_table_size_by_table_annotate(struct objtool_file *file,
4956

5057
if (reloc_idx(reloc) + 1 == sec_num_entries(rsec))
5158
break;
59+
60+
if (strcmp(insn->sec->name, (reloc + 1)->sym->sec->name)) {
61+
list_for_each_entry(orig_table, &table_list, jump_info) {
62+
if (orig_table->insn_offset == insn->offset) {
63+
is_valid_list = true;
64+
break;
65+
}
66+
}
67+
68+
if (!is_valid_list) {
69+
list_del_init(&table_list);
70+
continue;
71+
}
72+
73+
break;
74+
}
5275
}
5376

5477
list_for_each_entry(orig_table, &table_list, jump_info) {

0 commit comments

Comments
 (0)