xref: /openbmc/linux/tools/objtool/builtin-check.c (revision 0e731dbc18241d68318e0a7d2c2c0087c9073fb9)
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 
2199d00215SPeter Zijlstra bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount;
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"),
37c4a33939SPeter Zijlstra 	OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"),
3899d00215SPeter Zijlstra 	OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"),
39442f04c3SJosh Poimboeuf 	OPT_END(),
40442f04c3SJosh Poimboeuf };
41442f04c3SJosh Poimboeuf 
42dcc914f4SJosh Poimboeuf int cmd_check(int argc, const char **argv)
43dcc914f4SJosh Poimboeuf {
44*0e731dbcSSami Tolvanen 	const char *objname;
456545eb03SJulien Thierry 	struct objtool_file *file;
46d44becb9SJulien Thierry 	int ret;
47dcc914f4SJosh Poimboeuf 
48dcc914f4SJosh Poimboeuf 	argc = parse_options(argc, argv, check_options, check_usage, 0);
49442f04c3SJosh Poimboeuf 
50442f04c3SJosh Poimboeuf 	if (argc != 1)
51dcc914f4SJosh Poimboeuf 		usage_with_options(check_usage, check_options);
52442f04c3SJosh Poimboeuf 
53442f04c3SJosh Poimboeuf 	objname = argv[0];
54442f04c3SJosh Poimboeuf 
556545eb03SJulien Thierry 	file = objtool_open_read(objname);
566545eb03SJulien Thierry 	if (!file)
576545eb03SJulien Thierry 		return 1;
586545eb03SJulien Thierry 
59d44becb9SJulien Thierry 	ret = check(file);
60d44becb9SJulien Thierry 	if (ret)
61d44becb9SJulien Thierry 		return ret;
62d44becb9SJulien Thierry 
63d44becb9SJulien Thierry 	if (file->elf->changed)
64d44becb9SJulien Thierry 		return elf_write(file->elf);
65d44becb9SJulien Thierry 
66d44becb9SJulien Thierry 	return 0;
67442f04c3SJosh Poimboeuf }
68