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