[PATCH v3 33/64] objtool: Resurrect --backup option

From: Josh Poimboeuf
Date: Thu Jun 26 2025 - 20:02:24 EST


The --backup option was removed with the following commit:

aa8b3e64fd39 ("objtool: Create backup on error and print args")

... which tied the backup functionality to --verbose, and only for
warnings/errors.

It's a bit inelegant and out of scope to tie that to --verbose.

Bring back the old --backup option, but with the new behavior: only on
warnings/errors, and print the args to make it easier to recreate.

Suggested-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
tools/objtool/builtin-check.c | 25 +++++++++++--------------
tools/objtool/check.c | 4 +++-
tools/objtool/include/objtool/builtin.h | 3 ++-
3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 43139143edf8..a8c349f2273d 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -91,6 +91,7 @@ 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 backup (.orig) file on warning/error"),
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"),
@@ -244,12 +245,9 @@ static void save_argv(int argc, const char **argv)
};
}

-void print_args(void)
+int make_backup(void)
{
- char *backup = NULL;
-
- if (opts.output || opts.dryrun)
- goto print;
+ char *backup;

/*
* Make a backup before kbuild deletes the file so the error
@@ -258,33 +256,32 @@ void print_args(void)
backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1);
if (!backup) {
ERROR_GLIBC("malloc");
- goto print;
+ return 1;
}

strcpy(backup, objname);
strcat(backup, ORIG_SUFFIX);
- if (copy_file(objname, backup)) {
- backup = NULL;
- goto print;
- }
+ if (copy_file(objname, backup))
+ return 1;

-print:
/*
- * Print the cmdline args to make it easier to recreate. If '--output'
- * wasn't used, add it to the printed args with the backup as input.
+ * Print the cmdline args to make it easier to recreate.
*/
+
fprintf(stderr, "%s", orig_argv[0]);

for (int i = 1; i < orig_argc; i++) {
char *arg = orig_argv[i];

- if (backup && !strcmp(arg, objname))
+ /* Modify the printed args to use the backup */
+ if (!opts.output && !strcmp(arg, objname))
fprintf(stderr, " %s -o %s", backup, objname);
else
fprintf(stderr, " %s", arg);
}

fprintf(stderr, "\n");
+ return 0;
}

int objtool_run(int argc, const char **argv)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 87d2ba7739d5..46ace2c80317 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4745,9 +4745,11 @@ int check(struct objtool_file *file)
if (opts.verbose) {
if (opts.werror && warnings)
WARN("%d warning(s) upgraded to errors", warnings);
- print_args();
disas_warned_funcs(file);
}

+ if (opts.backup && make_backup())
+ return 1;
+
return ret;
}
diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h
index 6b08666fa69d..de6c08f8e060 100644
--- a/tools/objtool/include/objtool/builtin.h
+++ b/tools/objtool/include/objtool/builtin.h
@@ -29,6 +29,7 @@ struct opts {

/* options: */
bool backtrace;
+ bool backup;
bool dryrun;
bool link;
bool mnop;
@@ -47,6 +48,6 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[]);

int objtool_run(int argc, const char **argv);

-void print_args(void);
+int make_backup(void);

#endif /* _BUILTIN_H */
--
2.49.0