objtool: Move object file loading out of check()
authorJulien Thierry <jthierry@redhat.com>
Tue, 25 Aug 2020 12:47:39 +0000 (13:47 +0100)
committerJosh Poimboeuf <jpoimboe@redhat.com>
Tue, 1 Sep 2020 22:19:07 +0000 (17:19 -0500)
Structure objtool_file can be used by different subcommands. In fact
it already is, by check and orc.

Provide a function that allows to initialize objtool_file, that builtin
can call, without relying on check to do the correct setup for them and
explicitly hand the objtool_file to them.

Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Julien Thierry <jthierry@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
tools/objtool/builtin-check.c
tools/objtool/builtin-orc.c
tools/objtool/check.c
tools/objtool/objtool.c
tools/objtool/objtool.h
tools/objtool/weak.c

index 7a44174..0126ec3 100644 (file)
@@ -41,6 +41,7 @@ const struct option check_options[] = {
 int cmd_check(int argc, const char **argv)
 {
        const char *objname, *s;
+       struct objtool_file *file;
 
        argc = parse_options(argc, argv, check_options, check_usage, 0);
 
@@ -53,5 +54,9 @@ int cmd_check(int argc, const char **argv)
        if (s && !s[9])
                vmlinux = true;
 
-       return check(objname, false);
+       file = objtool_open_read(objname);
+       if (!file)
+               return 1;
+
+       return check(file, false);
 }
index b1dfe20..3979f27 100644 (file)
@@ -31,13 +31,19 @@ int cmd_orc(int argc, const char **argv)
                usage_with_options(orc_usage, check_options);
 
        if (!strncmp(argv[0], "gen", 3)) {
+               struct objtool_file *file;
+
                argc = parse_options(argc, argv, check_options, orc_usage, 0);
                if (argc != 1)
                        usage_with_options(orc_usage, check_options);
 
                objname = argv[0];
 
-               return check(objname, true);
+               file = objtool_open_read(objname);
+               if (!file)
+                       return 1;
+
+               return check(file, true);
        }
 
        if (!strcmp(argv[0], "dump")) {
index 75d0cd2..9d4efa3 100644 (file)
@@ -28,7 +28,6 @@ struct alternative {
        bool skip_orig;
 };
 
-const char *objname;
 struct cfi_init_state initial_func_cfi;
 
 struct instruction *find_insn(struct objtool_file *file,
@@ -2909,37 +2908,22 @@ static int validate_reachable_instructions(struct objtool_file *file)
        return 0;
 }
 
-static struct objtool_file file;
-
-int check(const char *_objname, bool orc)
+int check(struct objtool_file *file, bool orc)
 {
        int ret, warnings = 0;
 
-       objname = _objname;
-
-       file.elf = elf_open_read(objname, O_RDWR);
-       if (!file.elf)
-               return 1;
-
-       INIT_LIST_HEAD(&file.insn_list);
-       hash_init(file.insn_hash);
-       INIT_LIST_HEAD(&file.static_call_list);
-       file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
-       file.ignore_unreachables = no_unreachable;
-       file.hints = false;
-
        arch_initial_func_cfi_state(&initial_func_cfi);
 
-       ret = decode_sections(&file);
+       ret = decode_sections(file);
        if (ret < 0)
                goto out;
        warnings += ret;
 
-       if (list_empty(&file.insn_list))
+       if (list_empty(&file->insn_list))
                goto out;
 
        if (vmlinux && !validate_dup) {
-               ret = validate_vmlinux_functions(&file);
+               ret = validate_vmlinux_functions(file);
                if (ret < 0)
                        goto out;
 
@@ -2948,46 +2932,46 @@ int check(const char *_objname, bool orc)
        }
 
        if (retpoline) {
-               ret = validate_retpoline(&file);
+               ret = validate_retpoline(file);
                if (ret < 0)
                        return ret;
                warnings += ret;
        }
 
-       ret = validate_functions(&file);
+       ret = validate_functions(file);
        if (ret < 0)
                goto out;
        warnings += ret;
 
-       ret = validate_unwind_hints(&file, NULL);
+       ret = validate_unwind_hints(file, NULL);
        if (ret < 0)
                goto out;
        warnings += ret;
 
        if (!warnings) {
-               ret = validate_reachable_instructions(&file);
+               ret = validate_reachable_instructions(file);
                if (ret < 0)
                        goto out;
                warnings += ret;
        }
 
-       ret = create_static_call_sections(&file);
+       ret = create_static_call_sections(file);
        if (ret < 0)
                goto out;
        warnings += ret;
 
        if (orc) {
-               ret = create_orc(&file);
+               ret = create_orc(file);
                if (ret < 0)
                        goto out;
 
-               ret = create_orc_sections(&file);
+               ret = create_orc_sections(file);
                if (ret < 0)
                        goto out;
        }
 
-       if (file.elf->changed) {
-               ret = elf_write(file.elf);
+       if (file->elf->changed) {
+               ret = elf_write(file->elf);
                if (ret < 0)
                        goto out;
        }
index 58fdda5..9df0cd8 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 
 #include "builtin.h"
+#include "objtool.h"
+#include "warn.h"
 
 struct cmd_struct {
        const char *name;
@@ -39,6 +41,34 @@ static struct cmd_struct objtool_cmds[] = {
 
 bool help;
 
+const char *objname;
+static struct objtool_file file;
+
+struct objtool_file *objtool_open_read(const char *_objname)
+{
+       if (objname) {
+               if (strcmp(objname, _objname)) {
+                       WARN("won't handle more than one file at a time");
+                       return NULL;
+               }
+               return &file;
+       }
+       objname = _objname;
+
+       file.elf = elf_open_read(objname, O_RDWR);
+       if (!file.elf)
+               return NULL;
+
+       INIT_LIST_HEAD(&file.insn_list);
+       hash_init(file.insn_hash);
+       INIT_LIST_HEAD(&file.static_call_list);
+       file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
+       file.ignore_unreachables = no_unreachable;
+       file.hints = false;
+
+       return &file;
+}
+
 static void cmd_usage(void)
 {
        unsigned int i, longest = 0;
index 9a7cd0b..7efc43f 100644 (file)
@@ -20,7 +20,9 @@ struct objtool_file {
        bool ignore_unreachables, c_file, hints, rodata;
 };
 
-int check(const char *objname, bool orc);
+struct objtool_file *objtool_open_read(const char *_objname);
+
+int check(struct objtool_file *file, bool orc);
 int orc_dump(const char *objname);
 int create_orc(struct objtool_file *file);
 int create_orc_sections(struct objtool_file *file);
index 942ea5e..8269831 100644 (file)
@@ -17,9 +17,7 @@
        return ENOSYS;                                                  \
 })
 
-const char __weak *objname;
-
-int __weak check(const char *_objname, bool orc)
+int __weak check(struct objtool_file *file, bool orc)
 {
        UNSUPPORTED("check subcommand");
 }