diff options
-rw-r--r-- | tools/objtool/builtin-check.c | 68 | ||||
-rw-r--r-- | tools/objtool/include/objtool/builtin.h | 1 | ||||
-rw-r--r-- | tools/objtool/objtool.c | 63 |
3 files changed, 65 insertions, 67 deletions
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index c201650efe49..39ddca64cb58 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -91,7 +91,6 @@ static const struct option check_options[] = { OPT_GROUP("Options:"), OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), - OPT_BOOLEAN(0, "backup", &opts.backup, "create .orig files before modification"), OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), OPT_BOOLEAN(0, "link", &opts.link, "object is a linked object"), OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"), @@ -228,10 +227,39 @@ static int copy_file(const char *src, const char *dst) return 0; } +static char **save_argv(int argc, const char **argv) +{ + char **orig_argv; + + orig_argv = calloc(argc, sizeof(char *)); + if (!orig_argv) { + perror("calloc"); + return NULL; + } + + for (int i = 0; i < argc; i++) { + orig_argv[i] = strdup(argv[i]); + if (!orig_argv[i]) { + perror("strdup"); + return NULL; + } + }; + + return orig_argv; +} + +#define ORIG_SUFFIX ".orig" + int objtool_run(int argc, const char **argv) { struct objtool_file *file; - int ret; + char *backup = NULL; + char **orig_argv; + int ret = 0; + + orig_argv = save_argv(argc, argv); + if (!orig_argv) + return 1; cmd_parse_options(argc, argv, check_usage); @@ -271,8 +299,42 @@ int objtool_run(int argc, const char **argv) return 0; err: - if (opts.output) + if (opts.dryrun) + goto err_msg; + + if (opts.output) { unlink(opts.output); + goto err_msg; + } + + /* + * Make a backup before kbuild deletes the file so the error + * can be recreated without recompiling or relinking. + */ + backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1); + if (!backup) { + perror("malloc"); + return 1; + } + + strcpy(backup, objname); + strcat(backup, ORIG_SUFFIX); + if (copy_file(objname, backup)) + return 1; + +err_msg: + fprintf(stderr, "%s", orig_argv[0]); + + for (int i = 1; i < argc; i++) { + char *arg = orig_argv[i]; + + if (backup && !strcmp(arg, objname)) + fprintf(stderr, " %s -o %s", backup, objname); + else + fprintf(stderr, " %s", arg); + } + + fprintf(stderr, "\n"); return 1; } diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index b18f114cdaa4..0fafd0f7a209 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -29,7 +29,6 @@ struct opts { /* options: */ bool backtrace; - bool backup; bool dryrun; bool link; bool mnop; diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index 53cd881c6b95..1c73fb62fd57 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -20,64 +20,6 @@ bool help; static struct objtool_file file; -static bool objtool_create_backup(const char *_objname) -{ - int len = strlen(_objname); - char *buf, *base, *name = malloc(len+6); - int s, d, l, t; - - if (!name) { - perror("failed backup name malloc"); - return false; - } - - strcpy(name, _objname); - strcpy(name + len, ".orig"); - - d = open(name, O_CREAT|O_WRONLY|O_TRUNC, 0644); - if (d < 0) { - perror("failed to create backup file"); - return false; - } - - s = open(_objname, O_RDONLY); - if (s < 0) { - perror("failed to open orig file"); - return false; - } - - buf = malloc(4096); - if (!buf) { - perror("failed backup data malloc"); - return false; - } - - while ((l = read(s, buf, 4096)) > 0) { - base = buf; - do { - t = write(d, base, l); - if (t < 0) { - perror("failed backup write"); - return false; - } - base += t; - l -= t; - } while (l); - } - - if (l < 0) { - perror("failed backup read"); - return false; - } - - free(name); - free(buf); - close(d); - close(s); - - return true; -} - struct objtool_file *objtool_open_read(const char *filename) { if (file.elf) { @@ -89,11 +31,6 @@ struct objtool_file *objtool_open_read(const char *filename) if (!file.elf) return NULL; - if (opts.backup && !objtool_create_backup(objname)) { - WARN("can't create backup file"); - return NULL; - } - hash_init(file.insn_hash); INIT_LIST_HEAD(&file.retpoline_call_list); INIT_LIST_HEAD(&file.return_thunk_list); |