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> 187786032eSVasily Gorbik #include <objtool/builtin.h> 197786032eSVasily Gorbik #include <objtool/objtool.h> 20442f04c3SJosh Poimboeuf 218ad15c69SPeter Zijlstra bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, 228ad15c69SPeter Zijlstra validate_dup, vmlinux, mcount, noinstr, backup; 23442f04c3SJosh Poimboeuf 24dcc914f4SJosh Poimboeuf static const char * const check_usage[] = { 25442f04c3SJosh Poimboeuf "objtool check [<options>] file.o", 26442f04c3SJosh Poimboeuf NULL, 27442f04c3SJosh Poimboeuf }; 28442f04c3SJosh Poimboeuf 29dcc914f4SJosh Poimboeuf const struct option check_options[] = { 30867ac9d7SJosh Poimboeuf OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"), 31867ac9d7SJosh Poimboeuf OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"), 32b5bc2231SPeter Zijlstra OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"), 33ca41b97eSPeter Zijlstra OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"), 347697eee3SPeter Zijlstra OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"), 35ea24213dSPeter Zijlstra OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"), 361e11f3fdSPeter Zijlstra OPT_BOOLEAN('s', "stats", &stats, "print statistics"), 37c4a33939SPeter Zijlstra OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"), 3841425ebeSSami Tolvanen OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"), 39c4a33939SPeter Zijlstra OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"), 4099d00215SPeter Zijlstra OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"), 418ad15c69SPeter Zijlstra OPT_BOOLEAN('B', "backup", &backup, "create .orig files before modification"), 42442f04c3SJosh Poimboeuf OPT_END(), 43442f04c3SJosh Poimboeuf }; 44442f04c3SJosh Poimboeuf 45*a2f605f9SPeter Zijlstra int cmd_parse_options(int argc, const char **argv, const char * const usage[]) 46*a2f605f9SPeter Zijlstra { 47*a2f605f9SPeter Zijlstra argc = parse_options(argc, argv, check_options, usage, 0); 48*a2f605f9SPeter Zijlstra if (argc != 1) 49*a2f605f9SPeter Zijlstra usage_with_options(usage, check_options); 50*a2f605f9SPeter Zijlstra return argc; 51*a2f605f9SPeter Zijlstra } 52*a2f605f9SPeter Zijlstra 53dcc914f4SJosh Poimboeuf int cmd_check(int argc, const char **argv) 54dcc914f4SJosh Poimboeuf { 550e731dbcSSami Tolvanen const char *objname; 566545eb03SJulien Thierry struct objtool_file *file; 57d44becb9SJulien Thierry int ret; 58dcc914f4SJosh Poimboeuf 59*a2f605f9SPeter Zijlstra argc = cmd_parse_options(argc, argv, check_usage); 60442f04c3SJosh Poimboeuf objname = argv[0]; 61442f04c3SJosh Poimboeuf 626545eb03SJulien Thierry file = objtool_open_read(objname); 636545eb03SJulien Thierry if (!file) 646545eb03SJulien Thierry return 1; 656545eb03SJulien Thierry 66d44becb9SJulien Thierry ret = check(file); 67d44becb9SJulien Thierry if (ret) 68d44becb9SJulien Thierry return ret; 69d44becb9SJulien Thierry 70d44becb9SJulien Thierry if (file->elf->changed) 71d44becb9SJulien Thierry return elf_write(file->elf); 72d44becb9SJulien Thierry 73d44becb9SJulien Thierry return 0; 74442f04c3SJosh Poimboeuf } 75