From 627fce14809ba5610b0cb476cd0186d3fcedecfc Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Tue, 11 Jul 2017 10:33:42 -0500 Subject: objtool: Add ORC unwind table generation Now that objtool knows the states of all registers on the stack for each instruction, it's straightforward to generate debuginfo for an unwinder to use. Instead of generating DWARF, generate a new format called ORC, which is more suitable for an in-kernel unwinder. See Documentation/x86/orc-unwinder.txt for a more detailed description of this new debuginfo format and why it's preferable to DWARF. Signed-off-by: Josh Poimboeuf Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Jiri Slaby Cc: Linus Torvalds Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: live-patching@vger.kernel.org Link: http://lkml.kernel.org/r/c9b9f01ba6c5ed2bdc9bb0957b78167fdbf9632e.1499786555.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/check.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'tools/objtool/check.h') diff --git a/tools/objtool/check.h b/tools/objtool/check.h index da85f5b00ec6..046874bbe226 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h @@ -22,12 +22,14 @@ #include "elf.h" #include "cfi.h" #include "arch.h" +#include "orc.h" #include struct insn_state { struct cfi_reg cfa; struct cfi_reg regs[CFI_NUM_REGS]; int stack_size; + unsigned char type; bool bp_scratch; bool drap; int drap_reg; @@ -48,6 +50,7 @@ struct instruction { struct symbol *func; struct stack_op stack_op; struct insn_state state; + struct orc_entry orc; }; struct objtool_file { @@ -58,9 +61,19 @@ struct objtool_file { bool ignore_unreachables, c_file; }; -int check(const char *objname, bool nofp); +int check(const char *objname, bool nofp, bool orc); + +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) +#define sec_for_each_insn(file, sec, insn) \ + for (insn = find_insn(file, sec, 0); \ + insn && &insn->list != &file->insn_list && \ + insn->sec == sec; \ + insn = list_next_entry(insn, list)) + + #endif /* _CHECK_H */ -- cgit v1.2.3