[RFC PATCH v2 10/20] objtool: arm64: Compute destinations for call and jump instructions
madvenka at linux.microsoft.com
madvenka at linux.microsoft.com
Mon May 23 17:16:27 PDT 2022
From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
Compute the destination address of each call and jump instruction after
decoding all the instructions.
Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
tools/objtool/arch/arm64/decode.c | 12 ++++++++
tools/objtool/fpv.c | 47 ++++++++++++++++++++++++++++++-
2 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c
index 8a9ff030085d..f9df8b321659 100644
--- a/tools/objtool/arch/arm64/decode.c
+++ b/tools/objtool/arch/arm64/decode.c
@@ -33,6 +33,18 @@ struct decode {
s64 *imm, struct list_head *stack_ops);
};
+/* --------------------- arch support functions ------------------------- */
+
+unsigned long arch_dest_reloc_offset(int addend)
+{
+ return addend;
+}
+
+unsigned long arch_jump_destination(struct instruction *insn)
+{
+ return insn->offset + insn->immediate;
+}
+
/* --------------------- miscellaneous functions --------------------------- */
static void reg_check(unsigned int sp_check, unsigned int fp_check,
diff --git a/tools/objtool/fpv.c b/tools/objtool/fpv.c
index 76f0f2e611a8..92ad0d0aac8e 100644
--- a/tools/objtool/fpv.c
+++ b/tools/objtool/fpv.c
@@ -13,7 +13,52 @@
#include <objtool/insn.h>
#include <objtool/warn.h>
+/*
+ * Find the destination instructions for all jumps.
+ */
+static void add_jump_destinations(struct objtool_file *file)
+{
+ struct instruction *insn;
+ struct reloc *reloc;
+ struct section *dest_sec;
+ unsigned long dest_off;
+
+ for_each_insn(file, insn) {
+ if (insn->type != INSN_CALL &&
+ insn->type != INSN_JUMP_CONDITIONAL &&
+ insn->type != INSN_JUMP_UNCONDITIONAL) {
+ continue;
+ }
+
+ reloc = insn_reloc(file, insn);
+ if (!reloc) {
+ dest_sec = insn->sec;
+ dest_off = arch_jump_destination(insn);
+ } else if (reloc->sym->type == STT_SECTION) {
+ dest_sec = reloc->sym->sec;
+ dest_off = arch_dest_reloc_offset(reloc->addend);
+ } else if (reloc->sym->sec->idx) {
+ dest_sec = reloc->sym->sec;
+ dest_off = reloc->sym->sym.st_value +
+ arch_dest_reloc_offset(reloc->addend);
+ } else {
+ /* non-func asm code jumping to another file */
+ continue;
+ }
+
+ insn->jump_dest = find_insn(file, dest_sec, dest_off);
+ }
+}
+
int fpv_decode(struct objtool_file *file)
{
- return decode_instructions(file);
+ int ret;
+
+ ret = decode_instructions(file);
+ if (ret)
+ return ret;
+
+ add_jump_destinations(file);
+
+ return 0;
}
--
2.25.1
More information about the linux-arm-kernel
mailing list