The following commit has been merged into the objtool/core branch of tip: Commit-ID: eda3dc905834dc9c99132f987f77b68cf53a8682 Gitweb: https://git.kernel.org/tip/eda3dc905834dc9c99132f987f77b68cf53a8682 Author: Julien Thierry <jthierry@xxxxxxxxxx> AuthorDate: Fri, 04 Sep 2020 16:30:22 +01:00 Committer: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> CommitterDate: Thu, 10 Sep 2020 10:43:13 -05:00 objtool: Abstract alternative special case handling Some alternatives associated with a specific feature need to be treated in a special way. Since the features and how to treat them vary from one architecture to another, move the special case handling to arch specific code. Reviewed-by: Miroslav Benes <mbenes@xxxxxxx> Signed-off-by: Julien Thierry <jthierry@xxxxxxxxxx> Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> --- tools/objtool/arch/x86/Build | 1 +- tools/objtool/arch/x86/special.c | 37 +++++++++++++++++++++++++++++++- tools/objtool/objtool.h | 2 ++- tools/objtool/special.c | 32 ++++----------------------- tools/objtool/special.h | 2 ++- tools/objtool/weak.c | 2 +-- 6 files changed, 47 insertions(+), 29 deletions(-) create mode 100644 tools/objtool/arch/x86/special.c diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build index 7c50040..9f7869b 100644 --- a/tools/objtool/arch/x86/Build +++ b/tools/objtool/arch/x86/Build @@ -1,3 +1,4 @@ +objtool-y += special.o objtool-y += decode.o inat_tables_script = ../arch/x86/tools/gen-insn-attr-x86.awk diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c new file mode 100644 index 0000000..823561e --- /dev/null +++ b/tools/objtool/arch/x86/special.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "../../special.h" +#include "../../builtin.h" + +#define X86_FEATURE_POPCNT (4 * 32 + 23) +#define X86_FEATURE_SMAP (9 * 32 + 20) + +void arch_handle_alternative(unsigned short feature, struct special_alt *alt) +{ + switch (feature) { + case X86_FEATURE_SMAP: + /* + * If UACCESS validation is enabled; force that alternative; + * otherwise force it the other way. + * + * What we want to avoid is having both the original and the + * alternative code flow at the same time, in that case we can + * find paths that see the STAC but take the NOP instead of + * CLAC and the other way around. + */ + if (uaccess) + alt->skip_orig = true; + else + alt->skip_alt = true; + break; + case X86_FEATURE_POPCNT: + /* + * It has been requested that we don't validate the !POPCNT + * feature path which is a "very very small percentage of + * machines". + */ + alt->skip_orig = true; + break; + default: + break; + } +} diff --git a/tools/objtool/objtool.h b/tools/objtool/objtool.h index a635f68..4125d45 100644 --- a/tools/objtool/objtool.h +++ b/tools/objtool/objtool.h @@ -12,6 +12,8 @@ #include "elf.h" +#define __weak __attribute__((weak)) + struct objtool_file { struct elf *elf; struct list_head insn_list; diff --git a/tools/objtool/special.c b/tools/objtool/special.c index b04f395..1a2420f 100644 --- a/tools/objtool/special.c +++ b/tools/objtool/special.c @@ -16,9 +16,6 @@ #include "warn.h" #include "arch_special.h" -#define X86_FEATURE_POPCNT (4*32+23) -#define X86_FEATURE_SMAP (9*32+20) - struct special_entry { const char *sec; bool group, jump_or_nop; @@ -54,6 +51,10 @@ struct special_entry entries[] = { {}, }; +void __weak arch_handle_alternative(unsigned short feature, struct special_alt *alt) +{ +} + static int get_alt_entry(struct elf *elf, struct special_entry *entry, struct section *sec, int idx, struct special_alt *alt) @@ -78,30 +79,7 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry, feature = *(unsigned short *)(sec->data->d_buf + offset + entry->feature); - - /* - * It has been requested that we don't validate the !POPCNT - * feature path which is a "very very small percentage of - * machines". - */ - if (feature == X86_FEATURE_POPCNT) - alt->skip_orig = true; - - /* - * If UACCESS validation is enabled; force that alternative; - * otherwise force it the other way. - * - * What we want to avoid is having both the original and the - * alternative code flow at the same time, in that case we can - * find paths that see the STAC but take the NOP instead of - * CLAC and the other way around. - */ - if (feature == X86_FEATURE_SMAP) { - if (uaccess) - alt->skip_orig = true; - else - alt->skip_alt = true; - } + arch_handle_alternative(feature, alt); } orig_reloc = find_reloc_by_dest(elf, sec, offset + entry->orig); diff --git a/tools/objtool/special.h b/tools/objtool/special.h index 3506153..44da89a 100644 --- a/tools/objtool/special.h +++ b/tools/objtool/special.h @@ -28,4 +28,6 @@ struct special_alt { int special_get_alts(struct elf *elf, struct list_head *alts); +void arch_handle_alternative(unsigned short feature, struct special_alt *alt); + #endif /* _SPECIAL_H */ diff --git a/tools/objtool/weak.c b/tools/objtool/weak.c index 29180d5..7843e9a 100644 --- a/tools/objtool/weak.c +++ b/tools/objtool/weak.c @@ -9,8 +9,6 @@ #include <errno.h> #include "objtool.h" -#define __weak __attribute__((weak)) - #define UNSUPPORTED(name) \ ({ \ fprintf(stderr, "error: objtool: " name " not implemented\n"); \