builtin-check.c (2daf7faba7ded8703e4b4ebc8b161f22272fc91a) | builtin-check.c (b51277eb9775ce916f9efd2c51533e481180c1e8) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com> 4 */ 5 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com> 4 */ 5 |
6/* 7 * objtool check: 8 * 9 * This command analyzes every .o file and ensures the validity of its stack 10 * trace metadata. It enforces a set of rules on asm code and C inline 11 * assembly code so that stack traces can be reliable. 12 * 13 * For more information, see tools/objtool/Documentation/stack-validation.txt. 14 */ 15 | |
16#include <subcmd/parse-options.h> 17#include <string.h> 18#include <stdlib.h> 19#include <objtool/builtin.h> 20#include <objtool/objtool.h> 21 22struct opts opts; 23 24static const char * const check_usage[] = { | 6#include <subcmd/parse-options.h> 7#include <string.h> 8#include <stdlib.h> 9#include <objtool/builtin.h> 10#include <objtool/objtool.h> 11 12struct opts opts; 13 14static const char * const check_usage[] = { |
25 "objtool check <actions> [<options>] file.o", | 15 "objtool <actions> [<options>] file.o", |
26 NULL, 27}; 28 29static const char * const env_usage[] = { 30 "OBJTOOL_ARGS=\"<options>\"", 31 NULL, 32}; 33 | 16 NULL, 17}; 18 19static const char * const env_usage[] = { 20 "OBJTOOL_ARGS=\"<options>\"", 21 NULL, 22}; 23 |
24static int parse_dump(const struct option *opt, const char *str, int unset) 25{ 26 if (!str || !strcmp(str, "orc")) { 27 opts.dump_orc = true; 28 return 0; 29 } 30 31 return -1; 32} 33 |
|
34const struct option check_options[] = { 35 OPT_GROUP("Actions:"), 36 OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), 37 OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), 38 OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), | 34const struct option check_options[] = { 35 OPT_GROUP("Actions:"), 36 OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), 37 OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls for ftrace"), 38 OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), |
39 OPT_BOOLEAN('o', "orc", &opts.orc, "generate ORC metadata"), |
|
39 OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), 40 OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), 41 OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), | 40 OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate retpoline usage"), 41 OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mitigations"), 42 OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), |
43 OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump), |
|
42 43 OPT_GROUP("Options:"), 44 OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), 45 OPT_BOOLEAN(0, "backup", &opts.backup, "create .orig files before modification"), 46 OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), 47 OPT_BOOLEAN(0, "lto", &opts.lto, "whole-archive like runs"), 48 OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"), 49 OPT_BOOLEAN(0, "no-fp", &opts.no_fp, "skip frame pointer validation"), --- 26 unchanged lines hidden (view full) --- 76 } 77 78 argc = parse_options(argc, argv, check_options, usage, 0); 79 if (argc != 1) 80 usage_with_options(usage, check_options); 81 return argc; 82} 83 | 44 45 OPT_GROUP("Options:"), 46 OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), 47 OPT_BOOLEAN(0, "backup", &opts.backup, "create .orig files before modification"), 48 OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), 49 OPT_BOOLEAN(0, "lto", &opts.lto, "whole-archive like runs"), 50 OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"), 51 OPT_BOOLEAN(0, "no-fp", &opts.no_fp, "skip frame pointer validation"), --- 26 unchanged lines hidden (view full) --- 78 } 79 80 argc = parse_options(argc, argv, check_options, usage, 0); 81 if (argc != 1) 82 usage_with_options(usage, check_options); 83 return argc; 84} 85 |
84int cmd_check(int argc, const char **argv) | 86static bool opts_valid(void) |
85{ | 87{ |
88 if (opts.ibt || 89 opts.mcount || 90 opts.noinstr || 91 opts.orc || 92 opts.retpoline || 93 opts.sls || 94 opts.uaccess) { 95 if (opts.dump_orc) { 96 fprintf(stderr, "--dump can't be combined with other options\n"); 97 return false; 98 } 99 100 return true; 101 } 102 103 if (opts.dump_orc) 104 return true; 105 106 fprintf(stderr, "At least one command required\n"); 107 return false; 108} 109 110int objtool_run(int argc, const char **argv) 111{ |
|
86 const char *objname; 87 struct objtool_file *file; 88 int ret; 89 90 argc = cmd_parse_options(argc, argv, check_usage); 91 objname = argv[0]; 92 | 112 const char *objname; 113 struct objtool_file *file; 114 int ret; 115 116 argc = cmd_parse_options(argc, argv, check_usage); 117 objname = argv[0]; 118 |
119 if (!opts_valid()) 120 return 1; 121 122 if (opts.dump_orc) 123 return orc_dump(objname); 124 |
|
93 file = objtool_open_read(objname); 94 if (!file) 95 return 1; 96 97 ret = check(file); 98 if (ret) 99 return ret; 100 101 if (file->elf->changed) 102 return elf_write(file->elf); 103 104 return 0; 105} | 125 file = objtool_open_read(objname); 126 if (!file) 127 return 1; 128 129 ret = check(file); 130 if (ret) 131 return ret; 132 133 if (file->elf->changed) 134 return elf_write(file->elf); 135 136 return 0; 137} |