Messages in this thread Patch in this message | | | Date | Fri, 26 Feb 2021 11:57:43 +0100 | From | Peter Zijlstra <> | Subject | [PATCH 1/3] objtool: Add --backup |
| |
Teach objtool to write backups files, such that it becomes easier to see what objtool did to the object file.
Backup files will be ${name}bj, such that file.o becomes file.obj.
Suggested-by: Borislav Petkov <bp@alien8.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- tools/objtool/builtin-check.c | 4 +- tools/objtool/include/objtool/builtin.h | 3 + tools/objtool/objtool.c | 64 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-)
--- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -18,7 +18,8 @@ #include <objtool/builtin.h> #include <objtool/objtool.h> -bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux; +bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats; +bool validate_dup, vmlinux, backup; static const char * const check_usage[] = { "objtool check [<options>] file.o", @@ -35,6 +36,7 @@ const struct option check_options[] = { OPT_BOOLEAN('s', "stats", &stats, "print statistics"), OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"), OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"), + OPT_BOOLEAN('B', "backup", &backup, "create .obj files before modification"), OPT_END(), }; --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -8,7 +8,8 @@ #include <subcmd/parse-options.h> extern const struct option check_options[]; -extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, validate_dup, vmlinux; +extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats; +extern bool validate_dup, vmlinux, backup; extern int cmd_check(int argc, const char **argv); extern int cmd_orc(int argc, const char **argv); --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -17,6 +17,7 @@ #include <stdbool.h> #include <string.h> #include <stdlib.h> +#include <unistd.h> #include <subcmd/exec-cmd.h> #include <subcmd/pager.h> #include <linux/kernel.h> @@ -44,6 +45,64 @@ bool help; const char *objname; static struct objtool_file file; +static bool objtool_create_backup(const char *_objname) +{ + int len = strlen(_objname); + char *buf, *base, *name = malloc(len+3); + int s, d, l, t; + + if (!name) { + WARN("failed backup name malloc"); + return false; + } + + strcpy(name, _objname); + strcpy(name + len, "bj"); + + d = open(name, O_CREAT|O_WRONLY|O_TRUNC); + if (d < 0) { + WARN("failed to create backup file"); + return false; + } + + s = open(_objname, O_RDONLY); + if (s < 0) { + WARN("failed to open orig file"); + return false; + } + + buf = malloc(4096); + if (!buf) { + WARN("failed backup data malloc"); + return false; + } + + while ((l = read(s, buf, 4096)) > 0) { + base = buf; + do { + t = write(d, base, l); + if (t < 0) { + WARN("failed backup write"); + return false; + } + base += t; + l -= t; + } while (l); + } + + if (l < 0) { + WARN("failed backup read"); + return false; + } + + free(name); + free(buf); + close(d); + close(s); + + return true; +} + struct objtool_file *objtool_open_read(const char *_objname) { if (objname) { @@ -59,6 +118,11 @@ struct objtool_file *objtool_open_read(c if (!file.elf) return NULL; + if (backup && !objtool_create_backup(objname)) { + WARN("can't create backup file"); + return NULL; + } + INIT_LIST_HEAD(&file.insn_list); hash_init(file.insn_hash); INIT_LIST_HEAD(&file.static_call_list);
| |