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 35 #include "builtin.h" 36 37 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 38 39 struct cmd_struct { 40 const char *name; 41 int (*fn)(int, const char **); 42 const char *help; 43 }; 44 45 static const char objtool_usage_string[] = 46 "objtool [OPTIONS] COMMAND [ARGS]"; 47 48 static struct cmd_struct objtool_cmds[] = { 49 {"check", cmd_check, "Perform stack metadata validation on an object file" }, 50 }; 51 52 bool help; 53 54 static void cmd_usage(void) 55 { 56 unsigned int i, longest = 0; 57 58 printf("\n usage: %s\n\n", objtool_usage_string); 59 60 for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { 61 if (longest < strlen(objtool_cmds[i].name)) 62 longest = strlen(objtool_cmds[i].name); 63 } 64 65 puts(" Commands:"); 66 for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { 67 printf(" %-*s ", longest, objtool_cmds[i].name); 68 puts(objtool_cmds[i].help); 69 } 70 71 printf("\n"); 72 73 exit(1); 74 } 75 76 static void handle_options(int *argc, const char ***argv) 77 { 78 while (*argc > 0) { 79 const char *cmd = (*argv)[0]; 80 81 if (cmd[0] != '-') 82 break; 83 84 if (!strcmp(cmd, "--help") || !strcmp(cmd, "-h")) { 85 help = true; 86 break; 87 } else { 88 fprintf(stderr, "Unknown option: %s\n", cmd); 89 fprintf(stderr, "\n Usage: %s\n", 90 objtool_usage_string); 91 exit(1); 92 } 93 94 (*argv)++; 95 (*argc)--; 96 } 97 } 98 99 static void handle_internal_command(int argc, const char **argv) 100 { 101 const char *cmd = argv[0]; 102 unsigned int i, ret; 103 104 for (i = 0; i < ARRAY_SIZE(objtool_cmds); i++) { 105 struct cmd_struct *p = objtool_cmds+i; 106 107 if (strcmp(p->name, cmd)) 108 continue; 109 110 ret = p->fn(argc, argv); 111 112 exit(ret); 113 } 114 115 cmd_usage(); 116 } 117 118 int main(int argc, const char **argv) 119 { 120 static const char *UNUSED = "OBJTOOL_NOT_IMPLEMENTED"; 121 122 /* libsubcmd init */ 123 exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED); 124 pager_init(UNUSED); 125 126 argv++; 127 argc--; 128 handle_options(&argc, &argv); 129 130 if (!argc || help) 131 cmd_usage(); 132 133 handle_internal_command(argc, argv); 134 135 return 0; 136 } 137