lkml.org 
[lkml]   [2022]   [May]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v2 03/20] objtool: Move decode_instructions() to a separate file
    Date
    From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>

    check.c implements static stack validation. But decode_instructions() which
    resides in it can be shared with other types of validation. E.g., dynamic
    FP validation. Move the function to its own file - decode.c.

    Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
    ---
    tools/objtool/Build | 2 +
    tools/objtool/check.c | 96 ------------------------
    tools/objtool/decode.c | 106 +++++++++++++++++++++++++++
    tools/objtool/include/objtool/insn.h | 1 +
    4 files changed, 109 insertions(+), 96 deletions(-)
    create mode 100644 tools/objtool/decode.c

    diff --git a/tools/objtool/Build b/tools/objtool/Build
    index 52ed2f710d2a..199561f86c1e 100644
    --- a/tools/objtool/Build
    +++ b/tools/objtool/Build
    @@ -5,10 +5,12 @@ objtool-y += weak.o
    objtool-$(SUBCMD_CHECK) += check.o
    objtool-$(SUBCMD_CHECK) += cfi.o
    objtool-$(SUBCMD_CHECK) += insn.o
    +objtool-$(SUBCMD_CHECK) += decode.o
    objtool-$(SUBCMD_CHECK) += special.o
    objtool-$(SUBCMD_ORC) += check.o
    objtool-$(SUBCMD_ORC) += cfi.o
    objtool-$(SUBCMD_ORC) += insn.o
    +objtool-$(SUBCMD_ORC) += decode.o
    objtool-$(SUBCMD_ORC) += orc_gen.o
    objtool-$(SUBCMD_ORC) += orc_dump.o

    diff --git a/tools/objtool/check.c b/tools/objtool/check.c
    index 78168e0ad2bf..334ddc737bf9 100644
    --- a/tools/objtool/check.c
    +++ b/tools/objtool/check.c
    @@ -163,104 +163,8 @@ static bool dead_end_function(struct objtool_file *file, struct symbol *func)
    return __dead_end_function(file, func, 0);
    }

    -static unsigned long nr_insns;
    static unsigned long nr_insns_visited;

    -/*
    - * Call the arch-specific instruction decoder for all the instructions and add
    - * them to the global instruction list.
    - */
    -static int decode_instructions(struct objtool_file *file)
    -{
    - struct section *sec;
    - struct symbol *func;
    - unsigned long offset;
    - struct instruction *insn;
    - int ret;
    -
    - for_each_sec(file, sec) {
    -
    - if (!(sec->sh.sh_flags & SHF_EXECINSTR))
    - continue;
    -
    - if (strcmp(sec->name, ".altinstr_replacement") &&
    - strcmp(sec->name, ".altinstr_aux") &&
    - strncmp(sec->name, ".discard.", 9))
    - sec->text = true;
    -
    - if (!strcmp(sec->name, ".noinstr.text") ||
    - !strcmp(sec->name, ".entry.text"))
    - sec->noinstr = true;
    -
    - for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) {
    - insn = malloc(sizeof(*insn));
    - if (!insn) {
    - WARN("malloc failed");
    - return -1;
    - }
    - memset(insn, 0, sizeof(*insn));
    - INIT_LIST_HEAD(&insn->alts);
    - INIT_LIST_HEAD(&insn->stack_ops);
    - INIT_LIST_HEAD(&insn->call_node);
    -
    - insn->sec = sec;
    - insn->offset = offset;
    -
    - ret = arch_decode_instruction(file, sec, offset,
    - sec->sh.sh_size - offset,
    - &insn->len, &insn->type,
    - &insn->immediate,
    - &insn->stack_ops);
    - if (ret)
    - goto err;
    -
    - /*
    - * By default, "ud2" is a dead end unless otherwise
    - * annotated, because GCC 7 inserts it for certain
    - * divide-by-zero cases.
    - */
    - if (insn->type == INSN_BUG)
    - insn->dead_end = true;
    -
    - hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset));
    - list_add_tail(&insn->list, &file->insn_list);
    - nr_insns++;
    - }
    -
    - list_for_each_entry(func, &sec->symbol_list, list) {
    - if (func->type != STT_FUNC || func->alias != func)
    - continue;
    -
    - if (!find_insn(file, sec, func->offset)) {
    - WARN("%s(): can't find starting instruction",
    - func->name);
    - return -1;
    - }
    -
    - sym_for_each_insn(file, func, insn) {
    - insn->func = func;
    - if (insn->type == INSN_ENDBR && list_empty(&insn->call_node)) {
    - if (insn->offset == insn->func->offset) {
    - list_add_tail(&insn->call_node, &file->endbr_list);
    - file->nr_endbr++;
    - } else {
    - file->nr_endbr_int++;
    - }
    - }
    - }
    - }
    - }
    -
    - if (stats)
    - printf("nr_insns: %lu\n", nr_insns);
    -
    - return 0;
    -
    -err:
    - free(insn);
    - return ret;
    -}
    -
    /*
    * Read the pv_ops[] .data table to find the static initialized values.
    */
    diff --git a/tools/objtool/decode.c b/tools/objtool/decode.c
    new file mode 100644
    index 000000000000..4ed438ccc07f
    --- /dev/null
    +++ b/tools/objtool/decode.c
    @@ -0,0 +1,106 @@
    +// SPDX-License-Identifier: GPL-2.0-or-later
    +/*
    + * Copyright (C) 2015-2017 Josh Poimboeuf <jpoimboe@redhat.com>
    + */
    +#include <linux/objtool.h>
    +
    +#include <objtool/builtin.h>
    +#include <objtool/insn.h>
    +#include <objtool/warn.h>
    +
    +static unsigned long nr_insns;
    +
    +/*
    + * Call the arch-specific instruction decoder for all the instructions and add
    + * them to the global instruction list.
    + */
    +int decode_instructions(struct objtool_file *file)
    +{
    + struct section *sec;
    + struct symbol *func;
    + unsigned long offset;
    + struct instruction *insn;
    + int ret;
    +
    + for_each_sec(file, sec) {
    +
    + if (!(sec->sh.sh_flags & SHF_EXECINSTR))
    + continue;
    +
    + if (strcmp(sec->name, ".altinstr_replacement") &&
    + strcmp(sec->name, ".altinstr_aux") &&
    + strncmp(sec->name, ".discard.", 9))
    + sec->text = true;
    +
    + if (!strcmp(sec->name, ".noinstr.text") ||
    + !strcmp(sec->name, ".entry.text"))
    + sec->noinstr = true;
    +
    + for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) {
    + insn = malloc(sizeof(*insn));
    + if (!insn) {
    + WARN("malloc failed");
    + return -1;
    + }
    + memset(insn, 0, sizeof(*insn));
    + INIT_LIST_HEAD(&insn->alts);
    + INIT_LIST_HEAD(&insn->stack_ops);
    + INIT_LIST_HEAD(&insn->call_node);
    +
    + insn->sec = sec;
    + insn->offset = offset;
    +
    + ret = arch_decode_instruction(file, sec, offset,
    + sec->sh.sh_size - offset,
    + &insn->len, &insn->type,
    + &insn->immediate,
    + &insn->stack_ops);
    + if (ret)
    + goto err;
    +
    + /*
    + * By default, "ud2" is a dead end unless otherwise
    + * annotated, because GCC 7 inserts it for certain
    + * divide-by-zero cases.
    + */
    + if (insn->type == INSN_BUG)
    + insn->dead_end = true;
    +
    + hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset));
    + list_add_tail(&insn->list, &file->insn_list);
    + nr_insns++;
    + }
    +
    + list_for_each_entry(func, &sec->symbol_list, list) {
    + if (func->type != STT_FUNC || func->alias != func)
    + continue;
    +
    + if (!find_insn(file, sec, func->offset)) {
    + WARN("%s(): can't find starting instruction",
    + func->name);
    + return -1;
    + }
    +
    + sym_for_each_insn(file, func, insn) {
    + insn->func = func;
    + if (insn->type == INSN_ENDBR && list_empty(&insn->call_node)) {
    + if (insn->offset == insn->func->offset) {
    + list_add_tail(&insn->call_node, &file->endbr_list);
    + file->nr_endbr++;
    + } else {
    + file->nr_endbr_int++;
    + }
    + }
    + }
    + }
    + }
    +
    + if (stats)
    + printf("nr_insns: %lu\n", nr_insns);
    +
    + return 0;
    +
    +err:
    + free(insn);
    + return ret;
    +}
    diff --git a/tools/objtool/include/objtool/insn.h b/tools/objtool/include/objtool/insn.h
    index 1b9fce586679..5f01fd0ce8ed 100644
    --- a/tools/objtool/include/objtool/insn.h
    +++ b/tools/objtool/include/objtool/insn.h
    @@ -83,6 +83,7 @@ struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn);
    bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2);
    bool same_function(struct instruction *insn1, struct instruction *insn2);
    bool is_first_func_insn(struct instruction *insn);
    +int decode_instructions(struct objtool_file *file);

    #define for_each_insn(file, insn) \
    list_for_each_entry(insn, &file->insn_list, list)
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-05-24 02:17    [W:4.031 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site