diff options
Diffstat (limited to 'tools/objtool/objtool.c')
| -rw-r--r-- | tools/objtool/objtool.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c new file mode 100644 index 000000000000..46c326db4f46 --- /dev/null +++ b/tools/objtool/objtool.c | |||
| @@ -0,0 +1,136 @@ | |||
| 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 | } | ||
