Skip to content

Commit 43d5430

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
objtool: Keep track of retpoline call sites
Provide infrastructure for architectures to rewrite/augment compiler generated retpoline calls. Similar to what we do for static_call()s, keep track of the instructions that are retpoline calls. Use the same list_head, since a retpoline call cannot also be a static_call. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Reviewed-by: Miroslav Benes <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 2f2f7e4 commit 43d5430

File tree

5 files changed

+34
-6
lines changed

5 files changed

+34
-6
lines changed

tools/objtool/check.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ static int create_static_call_sections(struct objtool_file *file)
451451
return 0;
452452

453453
idx = 0;
454-
list_for_each_entry(insn, &file->static_call_list, static_call_node)
454+
list_for_each_entry(insn, &file->static_call_list, call_node)
455455
idx++;
456456

457457
sec = elf_create_section(file->elf, ".static_call_sites", SHF_WRITE,
@@ -460,7 +460,7 @@ static int create_static_call_sections(struct objtool_file *file)
460460
return -1;
461461

462462
idx = 0;
463-
list_for_each_entry(insn, &file->static_call_list, static_call_node) {
463+
list_for_each_entry(insn, &file->static_call_list, call_node) {
464464

465465
site = (struct static_call_site *)sec->data->d_buf + idx;
466466
memset(site, 0, sizeof(struct static_call_site));
@@ -829,13 +829,16 @@ static int add_jump_destinations(struct objtool_file *file)
829829
else
830830
insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL;
831831

832+
list_add_tail(&insn->call_node,
833+
&file->retpoline_call_list);
834+
832835
insn->retpoline_safe = true;
833836
continue;
834837
} else if (insn->func) {
835838
/* internal or external sibling call (with reloc) */
836839
insn->call_dest = reloc->sym;
837840
if (insn->call_dest->static_call_tramp) {
838-
list_add_tail(&insn->static_call_node,
841+
list_add_tail(&insn->call_node,
839842
&file->static_call_list);
840843
}
841844
continue;
@@ -897,7 +900,7 @@ static int add_jump_destinations(struct objtool_file *file)
897900
/* internal sibling call (without reloc) */
898901
insn->call_dest = insn->jump_dest->func;
899902
if (insn->call_dest->static_call_tramp) {
900-
list_add_tail(&insn->static_call_node,
903+
list_add_tail(&insn->call_node,
901904
&file->static_call_list);
902905
}
903906
}
@@ -981,14 +984,17 @@ static int add_call_destinations(struct objtool_file *file)
981984
insn->type = INSN_CALL_DYNAMIC;
982985
insn->retpoline_safe = true;
983986

987+
list_add_tail(&insn->call_node,
988+
&file->retpoline_call_list);
989+
984990
remove_insn_ops(insn);
985991
continue;
986992

987993
} else
988994
insn->call_dest = reloc->sym;
989995

990996
if (insn->call_dest && insn->call_dest->static_call_tramp) {
991-
list_add_tail(&insn->static_call_node,
997+
list_add_tail(&insn->call_node,
992998
&file->static_call_list);
993999
}
9941000

@@ -1714,6 +1720,11 @@ static void mark_rodata(struct objtool_file *file)
17141720
file->rodata = found;
17151721
}
17161722

1723+
__weak int arch_rewrite_retpolines(struct objtool_file *file)
1724+
{
1725+
return 0;
1726+
}
1727+
17171728
static int decode_sections(struct objtool_file *file)
17181729
{
17191730
int ret;
@@ -1742,6 +1753,10 @@ static int decode_sections(struct objtool_file *file)
17421753
if (ret)
17431754
return ret;
17441755

1756+
/*
1757+
* Must be before add_special_section_alts() as that depends on
1758+
* jump_dest being set.
1759+
*/
17451760
ret = add_jump_destinations(file);
17461761
if (ret)
17471762
return ret;
@@ -1778,6 +1793,15 @@ static int decode_sections(struct objtool_file *file)
17781793
if (ret)
17791794
return ret;
17801795

1796+
/*
1797+
* Must be after add_special_section_alts(), since this will emit
1798+
* alternatives. Must be after add_{jump,call}_destination(), since
1799+
* those create the call insn lists.
1800+
*/
1801+
ret = arch_rewrite_retpolines(file);
1802+
if (ret)
1803+
return ret;
1804+
17811805
return 0;
17821806
}
17831807

tools/objtool/include/objtool/arch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,6 @@ int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
8888

8989
bool arch_is_retpoline(struct symbol *sym);
9090

91+
int arch_rewrite_retpolines(struct objtool_file *file);
92+
9193
#endif /* _ARCH_H */

tools/objtool/include/objtool/check.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct alt_group {
3939
struct instruction {
4040
struct list_head list;
4141
struct hlist_node hash;
42-
struct list_head static_call_node;
42+
struct list_head call_node;
4343
struct list_head mcount_loc_node;
4444
struct section *sec;
4545
unsigned long offset;

tools/objtool/include/objtool/objtool.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct objtool_file {
1818
struct elf *elf;
1919
struct list_head insn_list;
2020
DECLARE_HASHTABLE(insn_hash, 20);
21+
struct list_head retpoline_call_list;
2122
struct list_head static_call_list;
2223
struct list_head mcount_loc_list;
2324
bool ignore_unreachables, c_file, hints, rodata;

tools/objtool/objtool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct objtool_file *objtool_open_read(const char *_objname)
6161

6262
INIT_LIST_HEAD(&file.insn_list);
6363
hash_init(file.insn_hash);
64+
INIT_LIST_HEAD(&file.retpoline_call_list);
6465
INIT_LIST_HEAD(&file.static_call_list);
6566
INIT_LIST_HEAD(&file.mcount_loc_list);
6667
file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");

0 commit comments

Comments
 (0)