Commit b51277eb authored by Josh Poimboeuf's avatar Josh Poimboeuf Committed by Peter Zijlstra
Browse files

objtool: Ditch subcommands



Objtool has a fairly singular focus.  It runs on object files and does
validations and transformations which can be combined in various ways.
The subcommand model has never been a good fit, making it awkward to
combine and remove options.

Remove the "check" and "orc" subcommands in favor of a more traditional
cmdline option model.  This makes it much more flexible to use, and
easier to port individual features to other arches.

Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarMiroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/5c61ebf805e90aefc5fa62bc63468ffae53b9df6.1650300597.git.jpoimboe@redhat.com
parent 2daf7fab
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -227,9 +227,9 @@ ifdef CONFIG_STACK_VALIDATION
objtool := $(objtree)/tools/objtool/objtool

objtool_args =								\
	$(if $(CONFIG_UNWINDER_ORC),orc generate,check)			\
	$(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt)			\
	$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount)		\
	$(if $(CONFIG_UNWINDER_ORC), --orc)				\
	$(if $(CONFIG_RETPOLINE), --retpoline)				\
	$(if $(CONFIG_SLS), --sls)					\
	$(if $(CONFIG_X86_SMAP), --uaccess)				\
+5 −8
Original line number Diff line number Diff line
@@ -113,9 +113,6 @@ objtool_link()

		# Don't perform vmlinux validation unless explicitly requested,
		# but run objtool on vmlinux.o now that we have an object file.
		if is_enabled CONFIG_UNWINDER_ORC; then
			objtoolcmd="orc generate"
		fi

		if is_enabled CONFIG_X86_KERNEL_IBT; then
			objtoolopt="${objtoolopt} --ibt"
@@ -125,6 +122,10 @@ objtool_link()
			objtoolopt="${objtoolopt} --mcount"
		fi

		if is_enabled CONFIG_UNWINDER_ORC; then
			objtoolopt="${objtoolopt} --orc"
		fi

		objtoolopt="${objtoolopt} --lto"
	fi

@@ -134,10 +135,6 @@ objtool_link()

	if [ -n "${objtoolopt}" ]; then

		if [ -z "${objtoolcmd}" ]; then
			objtoolcmd="check"
		fi

		if is_enabled CONFIG_RETPOLINE; then
			objtoolopt="${objtoolopt} --retpoline"
		fi
@@ -161,7 +158,7 @@ objtool_link()
		objtoolopt="${objtoolopt} --vmlinux"

		info OBJTOOL ${1}
		tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1}
		tools/objtool/objtool ${objtoolopt} ${1}
	fi
}

+5 −7
Original line number Diff line number Diff line
@@ -2,17 +2,15 @@ objtool-y += arch/$(SRCARCH)/

objtool-y += weak.o

objtool-$(SUBCMD_CHECK) += check.o
objtool-$(SUBCMD_CHECK) += special.o
objtool-$(SUBCMD_ORC) += check.o
objtool-$(SUBCMD_ORC) += orc_gen.o
objtool-$(SUBCMD_ORC) += orc_dump.o

objtool-y += check.o
objtool-y += special.o
objtool-y += builtin-check.o
objtool-y += builtin-orc.o
objtool-y += elf.o
objtool-y += objtool.o

objtool-$(BUILD_ORC) += orc_gen.o
objtool-$(BUILD_ORC) += orc_dump.o

objtool-y += libstring.o
objtool-y += libctype.o
objtool-y += str_error_r.o
+3 −5
Original line number Diff line number Diff line
@@ -39,15 +39,13 @@ CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)

AWK = awk

SUBCMD_CHECK := n
SUBCMD_ORC := n
BUILD_ORC := n

ifeq ($(SRCARCH),x86)
	SUBCMD_CHECK := y
	SUBCMD_ORC := y
	BUILD_ORC := y
endif

export SUBCMD_CHECK SUBCMD_ORC
export BUILD_ORC
export srctree OUTPUT CFLAGS SRCARCH AWK
include $(srctree)/tools/build/Makefile.include

+44 −12
Original line number Diff line number Diff line
@@ -3,16 +3,6 @@
 * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
 */

/*
 * objtool check:
 *
 * This command analyzes every .o file and ensures the validity of its stack
 * trace metadata.  It enforces a set of rules on asm code and C inline
 * assembly code so that stack traces can be reliable.
 *
 * For more information, see tools/objtool/Documentation/stack-validation.txt.
 */

#include <subcmd/parse-options.h>
#include <string.h>
#include <stdlib.h>
@@ -22,7 +12,7 @@
struct opts opts;

static const char * const check_usage[] = {
	"objtool check <actions> [<options>] file.o",
	"objtool <actions> [<options>] file.o",
	NULL,
};

@@ -31,14 +21,26 @@ static const char * const env_usage[] = {
	NULL,
};

static int parse_dump(const struct option *opt, const char *str, int unset)
{
	if (!str || !strcmp(str, "orc")) {
		opts.dump_orc = true;
		return 0;
	}

	return -1;
}

const struct option check_options[] = {
	OPT_GROUP("Actions:"),
	OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"),
	OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"),
	OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"),
	OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"),
	OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"),
	OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"),
	OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"),
	OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump),

	OPT_GROUP("Options:"),
	OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"),
@@ -81,7 +83,31 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[])
	return argc;
}

int cmd_check(int argc, const char **argv)
static bool opts_valid(void)
{
	if (opts.ibt		||
	    opts.mcount		||
	    opts.noinstr	||
	    opts.orc		||
	    opts.retpoline	||
	    opts.sls		||
	    opts.uaccess) {
		if (opts.dump_orc) {
			fprintf(stderr, "--dump can't be combined with other options\n");
			return false;
		}

		return true;
	}

	if (opts.dump_orc)
		return true;

	fprintf(stderr, "At least one command required\n");
	return false;
}

int objtool_run(int argc, const char **argv)
{
	const char *objname;
	struct objtool_file *file;
@@ -90,6 +116,12 @@ int cmd_check(int argc, const char **argv)
	argc = cmd_parse_options(argc, argv, check_usage);
	objname = argv[0];

	if (!opts_valid())
		return 1;

	if (opts.dump_orc)
		return orc_dump(objname);

	file = objtool_open_read(objname);
	if (!file)
		return 1;
Loading