Skip to content

Commit 45245f5

Browse files
Julien Thierryjpoimboe
authored andcommitted
objtool: Make relocation in alternative handling arch dependent
As pointed out by the comment in handle_group_alt(), support of relocation for instructions in an alternative group depends on whether arch specific kernel code handles it. So, let objtool arch specific code decide whether a relocation for the alternative section should be accepted. Reviewed-by: Miroslav Benes <mbenes@suse.cz> Signed-off-by: Julien Thierry <jthierry@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
1 parent eda3dc9 commit 45245f5

4 files changed

Lines changed: 29 additions & 13 deletions

File tree

tools/objtool/arch/x86/special.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,16 @@ void arch_handle_alternative(unsigned short feature, struct special_alt *alt)
3535
break;
3636
}
3737
}
38+
39+
bool arch_support_alt_relocation(struct special_alt *special_alt,
40+
struct instruction *insn,
41+
struct reloc *reloc)
42+
{
43+
/*
44+
* The x86 alternatives code adjusts the offsets only when it
45+
* encounters a branch instruction at the very beginning of the
46+
* replacement group.
47+
*/
48+
return insn->offset == special_alt->new_off &&
49+
(insn->type == INSN_CALL || is_static_jump(insn));
50+
}

tools/objtool/check.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,6 @@ static struct instruction *prev_insn_same_sym(struct objtool_file *file,
110110
for (insn = next_insn_same_sec(file, insn); insn; \
111111
insn = next_insn_same_sec(file, insn))
112112

113-
static bool is_static_jump(struct instruction *insn)
114-
{
115-
return insn->type == INSN_JUMP_CONDITIONAL ||
116-
insn->type == INSN_JUMP_UNCONDITIONAL;
117-
}
118-
119113
static bool is_sibling_call(struct instruction *insn)
120114
{
121115
/* An indirect jump is either a sibling call or a jump to a table. */
@@ -972,6 +966,8 @@ static int handle_group_alt(struct objtool_file *file,
972966
alt_group = alt_group_next_index++;
973967
insn = *new_insn;
974968
sec_for_each_insn_from(file, insn) {
969+
struct reloc *alt_reloc;
970+
975971
if (insn->offset >= special_alt->new_off + special_alt->new_len)
976972
break;
977973

@@ -988,14 +984,11 @@ static int handle_group_alt(struct objtool_file *file,
988984
* .altinstr_replacement section, unless the arch's
989985
* alternatives code can adjust the relative offsets
990986
* accordingly.
991-
*
992-
* The x86 alternatives code adjusts the offsets only when it
993-
* encounters a branch instruction at the very beginning of the
994-
* replacement group.
995987
*/
996-
if ((insn->offset != special_alt->new_off ||
997-
(insn->type != INSN_CALL && !is_static_jump(insn))) &&
998-
find_reloc_by_dest_range(file->elf, insn->sec, insn->offset, insn->len)) {
988+
alt_reloc = find_reloc_by_dest_range(file->elf, insn->sec,
989+
insn->offset, insn->len);
990+
if (alt_reloc &&
991+
!arch_support_alt_relocation(special_alt, insn, alt_reloc)) {
999992

1000993
WARN_FUNC("unsupported relocation in alternatives section",
1001994
insn->sec, insn->offset);

tools/objtool/check.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ struct instruction {
4848
#endif
4949
};
5050

51+
static inline bool is_static_jump(struct instruction *insn)
52+
{
53+
return insn->type == INSN_JUMP_CONDITIONAL ||
54+
insn->type == INSN_JUMP_UNCONDITIONAL;
55+
}
56+
5157
struct instruction *find_insn(struct objtool_file *file,
5258
struct section *sec, unsigned long offset);
5359

tools/objtool/special.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define _SPECIAL_H
88

99
#include <stdbool.h>
10+
#include "check.h"
1011
#include "elf.h"
1112

1213
struct special_alt {
@@ -30,4 +31,7 @@ int special_get_alts(struct elf *elf, struct list_head *alts);
3031

3132
void arch_handle_alternative(unsigned short feature, struct special_alt *alt);
3233

34+
bool arch_support_alt_relocation(struct special_alt *special_alt,
35+
struct instruction *insn,
36+
struct reloc *reloc);
3337
#endif /* _SPECIAL_H */

0 commit comments

Comments
 (0)