In preparation for porting the checksum code to other arches, make its
functionality independent from validate_branch().

Signed-off-by: Josh Poimboeuf <[email protected]>
---
 tools/objtool/check.c                    | 71 +++++++++++++++++-------
 tools/objtool/include/objtool/checksum.h |  6 +-
 2 files changed, 53 insertions(+), 24 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index a30379e4ff97..f73cf1382e5c 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2633,8 +2633,7 @@ static bool validate_branch_enabled(void)
 {
        return opts.stackval ||
               opts.orc ||
-              opts.uaccess ||
-              opts.checksum;
+              opts.uaccess;
 }
 
 static int decode_sections(struct objtool_file *file)
@@ -3649,6 +3648,7 @@ static bool skip_alt_group(struct instruction *insn)
        return alt_insn->type == INSN_CLAC || alt_insn->type == INSN_STAC;
 }
 
+#ifdef BUILD_KLP
 static int checksum_debug_init(struct objtool_file *file)
 {
        char *dup, *s;
@@ -3691,9 +3691,30 @@ static void checksum_update_insn(struct objtool_file 
*file, struct symbol *func,
                                 struct instruction *insn)
 {
        struct reloc *reloc = insn_reloc(file, insn);
+       struct alternative *alt;
        unsigned long offset;
        struct symbol *sym;
 
+       for (alt = insn->alts; alt; alt = alt->next) {
+               struct alt_group *alt_group = alt->insn->alt_group;
+
+               checksum_update(func, insn, &alt->type, sizeof(alt->type));
+
+               if (alt_group && alt_group->orig_group) {
+                       struct instruction *alt_insn;
+
+                       checksum_update(func, insn, &alt_group->feature, 
sizeof(alt_group->feature));
+
+                       for (alt_insn = alt->insn; alt_insn; alt_insn = 
next_insn_same_sec(file, alt_insn)) {
+                               checksum_update_insn(file, func, alt_insn);
+                               if (alt_insn == alt_group->last_insn)
+                                       break;
+                       }
+               } else {
+                       checksum_update(func, insn, &alt->insn->offset, 
sizeof(alt->insn->offset));
+               }
+       }
+
        if (insn->fake)
                return;
 
@@ -3702,9 +3723,11 @@ static void checksum_update_insn(struct objtool_file 
*file, struct symbol *func,
        if (!reloc) {
                struct symbol *call_dest = insn_call_dest(insn);
 
-               if (call_dest)
+               if (call_dest) {
+                       /* intra-TU call without reloc */
                        checksum_update(func, insn, call_dest->demangled_name,
                                        strlen(call_dest->demangled_name));
+               }
                return;
        }
 
@@ -3731,6 +3754,29 @@ static void checksum_update_insn(struct objtool_file 
*file, struct symbol *func,
        checksum_update(func, insn, &offset, sizeof(offset));
 }
 
+static int calculate_checksums(struct objtool_file *file)
+{
+       struct instruction *insn;
+       struct symbol *func;
+
+       if (checksum_debug_init(file))
+               return -1;
+
+       for_each_sym(file->elf, func) {
+               if (!is_func_sym(func))
+                       continue;
+
+               checksum_init(func);
+
+               func_for_each_insn(file, func, insn)
+                       checksum_update_insn(file, func, insn);
+
+               checksum_finish(func);
+       }
+       return 0;
+}
+#endif /* BUILD_KLP */
+
 static int validate_branch(struct objtool_file *file, struct symbol *func,
                           struct instruction *insn, struct insn_state state);
 static int do_validate_branch(struct objtool_file *file, struct symbol *func,
@@ -4012,9 +4058,6 @@ static int do_validate_branch(struct objtool_file *file, 
struct symbol *func,
                insn->trace = 0;
                next_insn = next_insn_to_validate(file, insn);
 
-               if (opts.checksum && func && insn->sec)
-                       checksum_update_insn(file, func, insn);
-
                if (func && insn_func(insn) && func != insn_func(insn)->pfunc) {
                        /* Ignore KCFI type preambles, which always fall 
through */
                        if (is_prefix_func(func))
@@ -4080,9 +4123,6 @@ static int validate_unwind_hint(struct objtool_file *file,
                struct symbol *func = insn_func(insn);
                int ret;
 
-               if (opts.checksum)
-                       checksum_init(func);
-
                ret = validate_branch(file, func, insn, *state);
                if (ret)
                        BT_INSN(insn, "<=== (hint)");
@@ -4525,9 +4565,6 @@ static int validate_symbol(struct objtool_file *file, 
struct section *sec,
 
        func = insn_func(insn);
 
-       if (opts.checksum)
-               checksum_init(func);
-
        if (opts.trace && !fnmatch(opts.trace, sym->name, 0)) {
                trace_enable();
                TRACE("%s: validation begin\n", sym->name);
@@ -4540,9 +4577,6 @@ static int validate_symbol(struct objtool_file *file, 
struct section *sec,
        TRACE("%s: validation %s\n\n", sym->name, ret ? "failed" : "end");
        trace_disable();
 
-       if (opts.checksum)
-               checksum_finish(func);
-
        return ret;
 }
 
@@ -4997,10 +5031,6 @@ int check(struct objtool_file *file)
        cfi_hash_add(&init_cfi);
        cfi_hash_add(&func_cfi);
 
-       ret = checksum_debug_init(file);
-       if (ret)
-               goto out;
-
        ret = decode_sections(file);
        if (ret)
                goto out;
@@ -5091,6 +5121,9 @@ int check(struct objtool_file *file)
                warnings += check_abs_references(file);
 
        if (opts.checksum) {
+               ret = calculate_checksums(file);
+               if (ret)
+                       goto out;
                ret = create_sym_checksum_section(file);
                if (ret)
                        goto out;
diff --git a/tools/objtool/include/objtool/checksum.h 
b/tools/objtool/include/objtool/checksum.h
index 7fe21608722a..36a17688c716 100644
--- a/tools/objtool/include/objtool/checksum.h
+++ b/tools/objtool/include/objtool/checksum.h
@@ -32,11 +32,7 @@ static inline void checksum_finish(struct symbol *func)
 
 #else /* !BUILD_KLP */
 
-static inline void checksum_init(struct symbol *func) {}
-static inline void checksum_update(struct symbol *func,
-                                  struct instruction *insn,
-                                  const void *data, size_t size) {}
-static inline void checksum_finish(struct symbol *func) {}
+static inline int calculate_checksums(struct objtool_file *file) { return 
-ENOSYS; }
 
 #endif /* !BUILD_KLP */
 
-- 
2.53.0


Reply via email to