xref: /openbmc/linux/tools/objtool/builtin-check.c (revision 41425ebe20245c99b44d6ba0f017be9bfc28414f)
11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2442f04c3SJosh Poimboeuf /*
3dcc914f4SJosh Poimboeuf  * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
4442f04c3SJosh Poimboeuf  */
5442f04c3SJosh Poimboeuf 
6442f04c3SJosh Poimboeuf /*
7442f04c3SJosh Poimboeuf  * objtool check:
8442f04c3SJosh Poimboeuf  *
9442f04c3SJosh Poimboeuf  * This command analyzes every .o file and ensures the validity of its stack
10442f04c3SJosh Poimboeuf  * trace metadata.  It enforces a set of rules on asm code and C inline
11442f04c3SJosh Poimboeuf  * assembly code so that stack traces can be reliable.
12442f04c3SJosh Poimboeuf  *
13442f04c3SJosh Poimboeuf  * For more information, see tools/objtool/Documentation/stack-validation.txt.
14442f04c3SJosh Poimboeuf  */
15442f04c3SJosh Poimboeuf 
16442f04c3SJosh Poimboeuf #include <subcmd/parse-options.h>
17c4a33939SPeter Zijlstra #include <string.h>
18442f04c3SJosh Poimboeuf #include "builtin.h"
190decf1f8SMatt Helsley #include "objtool.h"
20442f04c3SJosh Poimboeuf 
21*41425ebeSSami Tolvanen bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount, noinstr;
22442f04c3SJosh Poimboeuf 
23dcc914f4SJosh Poimboeuf static const char * const check_usage[] = {
24442f04c3SJosh Poimboeuf 	"objtool check [<options>] file.o",
25442f04c3SJosh Poimboeuf 	NULL,
26442f04c3SJosh Poimboeuf };
27442f04c3SJosh Poimboeuf 
28dcc914f4SJosh Poimboeuf const struct option check_options[] = {
29867ac9d7SJosh Poimboeuf 	OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"),
30867ac9d7SJosh Poimboeuf 	OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"),
31b5bc2231SPeter Zijlstra 	OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
32ca41b97eSPeter Zijlstra 	OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
337697eee3SPeter Zijlstra 	OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"),
34ea24213dSPeter Zijlstra 	OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
351e11f3fdSPeter Zijlstra 	OPT_BOOLEAN('s', "stats", &stats, "print statistics"),
36c4a33939SPeter Zijlstra 	OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"),
37*41425ebeSSami Tolvanen 	OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"),
38c4a33939SPeter Zijlstra 	OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"),
3999d00215SPeter Zijlstra 	OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"),
40442f04c3SJosh Poimboeuf 	OPT_END(),
41442f04c3SJosh Poimboeuf };
42442f04c3SJosh Poimboeuf 
43dcc914f4SJosh Poimboeuf int cmd_check(int argc, const char **argv)
44dcc914f4SJosh Poimboeuf {
450e731dbcSSami Tolvanen 	const char *objname;
466545eb03SJulien Thierry 	struct objtool_file *file;
47d44becb9SJulien Thierry 	int ret;
48dcc914f4SJosh Poimboeuf 
49dcc914f4SJosh Poimboeuf 	argc = parse_options(argc, argv, check_options, check_usage, 0);
50442f04c3SJosh Poimboeuf 
51442f04c3SJosh Poimboeuf 	if (argc != 1)
52dcc914f4SJosh Poimboeuf 		usage_with_options(check_usage, check_options);
53442f04c3SJosh Poimboeuf 
54442f04c3SJosh Poimboeuf 	objname = argv[0];
55442f04c3SJosh Poimboeuf 
566545eb03SJulien Thierry 	file = objtool_open_read(objname);
576545eb03SJulien Thierry 	if (!file)
586545eb03SJulien Thierry 		return 1;
596545eb03SJulien Thierry 
60d44becb9SJulien Thierry 	ret = check(file);
61d44becb9SJulien Thierry 	if (ret)
62d44becb9SJulien Thierry 		return ret;
63d44becb9SJulien Thierry 
64d44becb9SJulien Thierry 	if (file->elf->changed)
65d44becb9SJulien Thierry 		return elf_write(file->elf);
66d44becb9SJulien Thierry 
67d44becb9SJulien Thierry 	return 0;
68442f04c3SJosh Poimboeuf }
69