From: Sathvika Vasireddy <sv@linux.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: peterz@infradead.org, linux-kernel@vger.kernel.org,
rostedt@goodmis.org, aik@ozlabs.ru, sv@linux.ibm.com,
jpoimboe@redhat.com, naveen.n.rao@linux.vnet.ibm.com
Subject: [RFC PATCH 1/3] objtool: Move common code to utils.c
Date: Fri, 18 Mar 2022 16:21:38 +0530 [thread overview]
Message-ID: <20220318105140.43914-2-sv@linux.ibm.com> (raw)
In-Reply-To: <20220318105140.43914-1-sv@linux.ibm.com>
This patch moves common code to utils.c file. Code from this file will
be reused across check.c and mcount.c (will be introduced in the coming
patches). Also, ensure that this change works well with existing
commands.
Signed-off-by: Sathvika Vasireddy <sv@linux.ibm.com>
---
tools/objtool/Build | 1 +
tools/objtool/check.c | 178 +-----------------------
tools/objtool/include/objtool/check.h | 2 -
tools/objtool/include/objtool/utils.h | 28 ++++
tools/objtool/orc_gen.c | 1 +
tools/objtool/utils.c | 192 ++++++++++++++++++++++++++
6 files changed, 223 insertions(+), 179 deletions(-)
create mode 100644 tools/objtool/include/objtool/utils.h
create mode 100644 tools/objtool/utils.c
diff --git a/tools/objtool/Build b/tools/objtool/Build
index b7222d5cc7bc..161fd451241a 100644
--- a/tools/objtool/Build
+++ b/tools/objtool/Build
@@ -12,6 +12,7 @@ objtool-y += builtin-check.o
objtool-y += builtin-orc.o
objtool-y += elf.o
objtool-y += objtool.o
+objtool-y += utils.o
objtool-y += libstring.o
objtool-y += libctype.o
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 7c33ec67c4a9..161dd181d9d4 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -12,6 +12,7 @@
#include <objtool/cfi.h>
#include <objtool/arch.h>
#include <objtool/check.h>
+#include <objtool/utils.h>
#include <objtool/special.h>
#include <objtool/warn.h>
#include <objtool/endianness.h>
@@ -33,19 +34,6 @@ static struct cfi_init_state initial_func_cfi;
static struct cfi_state init_cfi;
static struct cfi_state func_cfi;
-struct instruction *find_insn(struct objtool_file *file,
- struct section *sec, unsigned long offset)
-{
- struct instruction *insn;
-
- hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, offset)) {
- if (insn->sec == sec && insn->offset == offset)
- return insn;
- }
-
- return NULL;
-}
-
static struct instruction *next_insn_same_sec(struct objtool_file *file,
struct instruction *insn)
{
@@ -342,86 +330,8 @@ static void *cfi_hash_alloc(unsigned long size)
return cfi_hash;
}
-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);
-
- 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;
-
- 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 (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.
*/
@@ -731,49 +641,6 @@ static int create_retpoline_sites_sections(struct objtool_file *file)
return 0;
}
-static int create_mcount_loc_sections(struct objtool_file *file)
-{
- struct section *sec;
- unsigned long *loc;
- struct instruction *insn;
- int idx;
-
- sec = find_section_by_name(file->elf, "__mcount_loc");
- if (sec) {
- INIT_LIST_HEAD(&file->mcount_loc_list);
- WARN("file already has __mcount_loc section, skipping");
- return 0;
- }
-
- if (list_empty(&file->mcount_loc_list))
- return 0;
-
- idx = 0;
- list_for_each_entry(insn, &file->mcount_loc_list, call_node)
- idx++;
-
- sec = elf_create_section(file->elf, "__mcount_loc", 0, sizeof(unsigned long), idx);
- if (!sec)
- return -1;
-
- idx = 0;
- list_for_each_entry(insn, &file->mcount_loc_list, call_node) {
-
- loc = (unsigned long *)sec->data->d_buf + idx;
- memset(loc, 0, sizeof(unsigned long));
-
- if (elf_add_reloc_to_insn(file->elf, sec,
- idx * sizeof(unsigned long),
- R_X86_64_64,
- insn->sec, insn->offset))
- return -1;
-
- idx++;
- }
-
- return 0;
-}
-
/*
* Warnings shouldn't be reported for ignored functions.
*/
@@ -1013,38 +880,6 @@ __weak bool arch_is_retpoline(struct symbol *sym)
return false;
}
-#define NEGATIVE_RELOC ((void *)-1L)
-
-static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn)
-{
- if (insn->reloc == NEGATIVE_RELOC)
- return NULL;
-
- if (!insn->reloc) {
- if (!file)
- return NULL;
-
- insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec,
- insn->offset, insn->len);
- if (!insn->reloc) {
- insn->reloc = NEGATIVE_RELOC;
- return NULL;
- }
- }
-
- return insn->reloc;
-}
-
-static void remove_insn_ops(struct instruction *insn)
-{
- struct stack_op *op, *tmp;
-
- list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
- list_del(&op->list);
- free(op);
- }
-}
-
static void annotate_call_site(struct objtool_file *file,
struct instruction *insn, bool sibling)
{
@@ -1256,17 +1091,6 @@ static int add_jump_destinations(struct objtool_file *file)
return 0;
}
-static struct symbol *find_call_destination(struct section *sec, unsigned long offset)
-{
- struct symbol *call_dest;
-
- call_dest = find_func_by_offset(sec, offset);
- if (!call_dest)
- call_dest = find_symbol_by_offset(sec, offset);
-
- return call_dest;
-}
-
/*
* Find the destination instructions for all calls.
*/
diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h
index 6cfff078897f..d4e378c7aa30 100644
--- a/tools/objtool/include/objtool/check.h
+++ b/tools/objtool/include/objtool/check.h
@@ -79,8 +79,6 @@ static inline bool is_jump(struct instruction *insn)
return is_static_jump(insn) || is_dynamic_jump(insn);
}
-struct instruction *find_insn(struct objtool_file *file,
- struct section *sec, unsigned long offset);
#define for_each_insn(file, insn) \
list_for_each_entry(insn, &file->insn_list, list)
diff --git a/tools/objtool/include/objtool/utils.h b/tools/objtool/include/objtool/utils.h
new file mode 100644
index 000000000000..f808a66dd0a8
--- /dev/null
+++ b/tools/objtool/include/objtool/utils.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <stdbool.h>
+#include <objtool/cfi.h>
+#include <objtool/arch.h>
+
+int decode_instructions(struct objtool_file *file);
+struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn);
+void remove_insn_ops(struct instruction *insn);
+struct symbol *find_call_destination(struct section *sec, unsigned long offset);
+int create_mcount_loc_sections(struct objtool_file *file);
+struct instruction *find_insn(struct objtool_file *file,
+ struct section *sec, unsigned long offset);
+
+#define sym_for_each_insn(file, sym, insn) \
+ for (insn = find_insn(file, sym->sec, sym->offset); \
+ insn && &insn->list != &file->insn_list && \
+ insn->sec == sym->sec && \
+ insn->offset < sym->offset + sym->len; \
+ insn = list_next_entry(insn, list))
+
+#endif /* UTILS_H */
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index dd3c64af9db2..383c5f2f0658 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -10,6 +10,7 @@
#include <asm/orc_types.h>
#include <objtool/check.h>
+#include <objtool/utils.h>
#include <objtool/warn.h>
#include <objtool/endianness.h>
diff --git a/tools/objtool/utils.c b/tools/objtool/utils.c
new file mode 100644
index 000000000000..d1fc6a123a6e
--- /dev/null
+++ b/tools/objtool/utils.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include <objtool/builtin.h>
+#include <objtool/check.h>
+#include <objtool/utils.h>
+#include <objtool/warn.h>
+
+#include <linux/objtool.h>
+#include <linux/hashtable.h>
+#include <linux/kernel.h>
+#include <linux/static_call_types.h>
+
+struct instruction *find_insn(struct objtool_file *file,
+ struct section *sec, unsigned long offset)
+{
+ struct instruction *insn;
+
+ hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, offset)) {
+ if (insn->sec == sec && insn->offset == offset)
+ return insn;
+ }
+
+ return NULL;
+}
+
+#define NEGATIVE_RELOC ((void *)-1L)
+
+struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn)
+{
+ if (insn->reloc == NEGATIVE_RELOC)
+ return NULL;
+
+ if (!insn->reloc) {
+ if (!file)
+ return NULL;
+
+ insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec,
+ insn->offset, insn->len);
+ if (!insn->reloc) {
+ insn->reloc = NEGATIVE_RELOC;
+ return NULL;
+ }
+ }
+
+ return insn->reloc;
+}
+void remove_insn_ops(struct instruction *insn)
+{
+ struct stack_op *op, *tmp;
+
+ list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
+ list_del(&op->list);
+ free(op);
+ }
+}
+
+
+struct symbol *find_call_destination(struct section *sec, unsigned long offset)
+{
+ struct symbol *call_dest;
+
+ call_dest = find_func_by_offset(sec, offset);
+ if (!call_dest)
+ call_dest = find_symbol_by_offset(sec, offset);
+
+ return call_dest;
+}
+
+static unsigned long nr_insns;
+
+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);
+
+ 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;
+
+ 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 (stats)
+ printf("nr_insns: %lu\n", nr_insns);
+
+ return 0;
+
+err:
+ free(insn);
+ return ret;
+}
+
+int create_mcount_loc_sections(struct objtool_file *file)
+{
+ struct section *sec;
+ unsigned long *loc;
+ struct instruction *insn;
+ int idx;
+
+ sec = find_section_by_name(file->elf, "__mcount_loc");
+ if (sec) {
+ INIT_LIST_HEAD(&file->mcount_loc_list);
+ WARN("file already has __mcount_loc section, skipping");
+ return 0;
+ }
+
+ if (list_empty(&file->mcount_loc_list))
+ return 0;
+
+ idx = 0;
+ list_for_each_entry(insn, &file->mcount_loc_list, call_node)
+ idx++;
+
+ sec = elf_create_section(file->elf, "__mcount_loc", 0, sizeof(unsigned long), idx);
+ if (!sec)
+ return -1;
+
+ idx = 0;
+ list_for_each_entry(insn, &file->mcount_loc_list, call_node) {
+
+ loc = (unsigned long *)sec->data->d_buf + idx;
+ memset(loc, 0, sizeof(unsigned long));
+
+ if (elf_add_reloc_to_insn(file->elf, sec,
+ idx * sizeof(unsigned long),
+ R_X86_64_64,
+ insn->sec, insn->offset))
+ return -1;
+
+ idx++;
+ }
+
+ return 0;
+}
--
2.31.1
next prev parent reply other threads:[~2022-03-18 21:46 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-18 10:51 [RFC PATCH 0/3] objtool: Add mcount sub-command Sathvika Vasireddy
2022-03-18 10:51 ` Sathvika Vasireddy [this message]
2022-03-23 18:02 ` [RFC PATCH 1/3] objtool: Move common code to utils.c Miroslav Benes
2022-03-18 10:51 ` [RFC PATCH 2/3] objtool: Enable and implement 'mcount' subcommand Sathvika Vasireddy
2022-03-21 7:06 ` Christophe Leroy
2022-03-21 8:19 ` Naveen N. Rao
2022-03-21 8:26 ` Christophe Leroy
2022-03-21 9:48 ` Naveen N. Rao
2022-03-18 10:51 ` [RFC PATCH 3/3] objtool/mcount: Add powerpc specific functions Sathvika Vasireddy
2022-03-18 12:26 ` Peter Zijlstra
2022-03-18 13:59 ` Christophe Leroy
2022-03-21 2:27 ` Michael Ellerman
2022-03-21 6:47 ` Christophe Leroy
2022-03-21 7:46 ` Christophe Leroy
2022-03-21 7:56 ` Christophe Leroy
2022-03-21 8:30 ` Christophe Leroy
2022-03-21 8:59 ` Christophe Leroy
2022-03-26 7:58 ` Christophe Leroy
2022-03-21 6:25 ` Naveen N. Rao
2022-03-27 9:09 ` Christophe Leroy
2022-03-28 19:59 ` Josh Poimboeuf
2022-03-28 20:14 ` Peter Zijlstra
2022-03-28 20:15 ` Peter Zijlstra
2022-03-28 20:21 ` Josh Poimboeuf
2022-03-29 12:01 ` Michael Ellerman
2022-03-29 17:32 ` Christophe Leroy
2022-03-30 4:26 ` Josh Poimboeuf
2022-03-30 18:40 ` Naveen N. Rao
2022-05-12 14:52 ` Christophe Leroy
2022-05-12 15:12 ` Josh Poimboeuf
2022-05-21 9:38 ` Christophe Leroy
2022-05-21 10:57 ` Peter Zijlstra
2022-05-23 5:39 ` Naveen N. Rao
2022-03-19 1:35 ` [RFC PATCH 0/3] objtool: Add mcount sub-command Josh Poimboeuf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220318105140.43914-2-sv@linux.ibm.com \
--to=sv@linux.ibm.com \
--cc=aik@ozlabs.ru \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=naveen.n.rao@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).