^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * objtool check:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This command analyzes every .o file and ensures the validity of its stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * trace metadata. It enforces a set of rules on asm code and C inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * assembly code so that stack traces can be reliable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * For more information, see tools/objtool/Documentation/stack-validation.txt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "objtool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux, mcount, noinstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static const char * const check_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) "objtool check [<options>] file.o",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const struct option check_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) OPT_BOOLEAN('s', "stats", &stats, "print statistics"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) OPT_END(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int cmd_check(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const char *objname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct objtool_file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) argc = parse_options(argc, argv, check_options, check_usage, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (argc != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) usage_with_options(check_usage, check_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) objname = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) file = objtool_open_read(objname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ret = check(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (file->elf->changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return elf_write(file->elf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }