1 /* 2 * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com> 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /* 19 * objtool: 20 * 21 * The 'check' subcmd analyzes every .o file and ensures the validity of its 22 * stack trace metadata. It enforces a set of rules on asm code and C inline 23 * assembly code so that stack traces can be reliable. 24 * 25 * For more information, see tools/objtool/Documentation/stack-validation.txt. 26 */ 27 28 #include <stdio.h> 29 #include <stdbool.h> 30 #include <string.h> 31 #include <stdlib.h> 32 #include <subcmd/exec-cmd.h> 33 #include <subcmd/pager.h> 34 #include <linux/kernel.h> 35 36 #include "builtin.h" 37 38 struct cmd_struct { 39 const char *name; 40 int (*fn)(int, const char **); 41 const char *help; 42 }; 43 44 static const char objtool_usage_string[] = 45 "objtool [OPTIONS] COMMAND [ARGS]"; 46 47 static struct cmd_struct objtool_cmds[] = { 48 {"check", cmd_check, "Perform stack metadata validation on an object file" }, 49 }; 50 51 bool help; 52 53 static void cmd_usage(void) 54 { 55 unsigned int i, longest = 0; 56 57 printf("\n usage: %s\n\n", objtool_usage_string); 58 59 for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { 60 if (longest < strlen(objtool_cmds[i].name)) 61 longest = strlen(objtool_cmds[i].name); 62 } 63 64 puts(" Commands:"); 65 for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { 66 printf(" %-*s ", longest, objtool_cmds[i].name); 67 puts(objtool_cmds[i].help); 68 } 69 70 printf("\n"); 71 72 exit(1); 73 } 74 75 static void handle_options(int *argc, const char ***argv) 76 { 77 while (*argc > 0) { 78 const char *cmd = (*argv)[0]; 79 80 if (cmd[0] != '-') 81 break; 82 83 if (!strcmp(cmd, "--help") || !strcmp(cmd, "-h")) { 84 help = true; 85 break; 86 } else { 87 fprintf(stderr, "Unknown option: %s\n", cmd); 88 fprintf(stderr, "\n Usage: %s\n", 89 objtool_usage_string); 90 exit(1); 91 } 92 93 (*argv)++; 94 (*argc)--; 95 } 96 } 97 98 static void handle_internal_command(int argc, const char **argv) 99 { 100 const char *cmd = argv[0]; 101 unsigned int i, ret; 102 103 for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { 104 struct cmd_struct *p = objtool_cmds+i; 105 106 if (strcmp(p->name, cmd)) 107 continue; 108 109 ret = p->fn(argc, argv); 110 111 exit(ret); 112 } 113 114 cmd_usage(); 115 } 116 117 int main(int argc, const char **argv) 118 { 119 static const char *UNUSED = "OBJTOOL_NOT_IMPLEMENTED"; 120 121 /* libsubcmd init */ 122 exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED); 123 pager_init(UNUSED); 124 125 argv++; 126 argc--; 127 handle_options(&argc, &argv); 128 129 if (!argc || help) 130 cmd_usage(); 131 132 handle_internal_command(argc, argv); 133 134 return 0; 135 } 136