[PATCH v2 5/8] objtool, x86: add facility for asm code to provide unwind hints

2017-06-28 Thread Josh Poimboeuf
Some asm (and inline asm) code does special things to the stack which
objtool can't understand.  (Nor can GCC or GNU assembler, for that
matter.)  In such cases we need a facility for the code to provide
annotations, so the unwinder can unwind through it.

This provides such a facility, in the form of unwind hints.  They're
similar to the GNU assembler .cfi* directives, but they give more
information, and are needed in far fewer places, because objtool can
fill in the blanks by following branches and adjusting the stack pointer
for pushes and pops.

Signed-off-by: Josh Poimboeuf 
---
 .../x86/include/asm}/undwarf-types.h   |  18 +++
 arch/x86/include/asm/undwarf.h | 103 
 tools/objtool/Makefile |   3 +
 tools/objtool/check.c  | 179 -
 tools/objtool/check.h  |   4 +-
 tools/objtool/undwarf-types.h  |  18 +++
 6 files changed, 317 insertions(+), 8 deletions(-)
 copy {tools/objtool => arch/x86/include/asm}/undwarf-types.h (84%)
 create mode 100644 arch/x86/include/asm/undwarf.h

diff --git a/tools/objtool/undwarf-types.h 
b/arch/x86/include/asm/undwarf-types.h
similarity index 84%
copy from tools/objtool/undwarf-types.h
copy to arch/x86/include/asm/undwarf-types.h
index ef92a1d..4e5e283 100644
--- a/tools/objtool/undwarf-types.h
+++ b/arch/x86/include/asm/undwarf-types.h
@@ -57,11 +57,17 @@
  *
  * UNDWARF_TYPE_REGS_IRET: Used in entry code to indicate that
  * cfa_reg+cfa_offset points to the iret return frame.
+ *
+ * The UNWIND_HINT macros are only used for the unwind_hint struct.  They are
+ * not used for the undwarf struct due to size and complexity constraints.
  */
 #define UNDWARF_TYPE_CFA   0
 #define UNDWARF_TYPE_REGS  1
 #define UNDWARF_TYPE_REGS_IRET 2
+#define UNWIND_HINT_TYPE_SAVE  3
+#define UNWIND_HINT_TYPE_RESTORE   4
 
+#ifndef __ASSEMBLY__
 /*
  * This struct contains a simplified version of the DWARF Call Frame
  * Information standard.  It contains only the necessary parts of the real
@@ -78,4 +84,16 @@ struct undwarf {
unsigned type:2;
 };
 
+/*
+ * This struct is used by asm and inline asm code to manually annotate the
+ * location of registers on the stack for the undwarf unwinder.
+ */
+struct unwind_hint {
+   unsigned int ip;
+   short cfa_offset;
+   unsigned char cfa_reg;
+   unsigned char type;
+};
+#endif /* __ASSEMBLY__ */
+
 #endif /* _UNDWARF_TYPES_H */
diff --git a/arch/x86/include/asm/undwarf.h b/arch/x86/include/asm/undwarf.h
new file mode 100644
index 000..41384e6
--- /dev/null
+++ b/arch/x86/include/asm/undwarf.h
@@ -0,0 +1,103 @@
+#ifndef _ASM_X86_UNDWARF_H
+#define _ASM_X86_UNDWARF_H
+
+#include "undwarf-types.h"
+
+#ifdef __ASSEMBLY__
+
+/*
+ * In asm, there are two kinds of code: normal C-type callable functions and
+ * the rest.  The normal callable functions can be called by other code, and
+ * don't do anything unusual with the stack.  Such normal callable functions
+ * are annotated with the ENTRY/ENDPROC macros.  Most asm code falls in this
+ * category.  In this case, no special debugging annotations are needed because
+ * objtool can automatically generate the .undwarf section which the undwarf
+ * unwinder reads at runtime.
+ *
+ * Anything which doesn't fall into the above category, such as syscall and
+ * interrupt handlers, tends to not be called directly by other functions, and
+ * often does unusual non-C-function-type things with the stack pointer.  Such
+ * code needs to be annotated such that objtool can understand it.  The
+ * following CFI hint macros are for this type of code.
+ *
+ * These macros provide hints to objtool about the state of the stack at each
+ * instruction.  Objtool starts from the hints and follows the code flow,
+ * making automatic CFI adjustments when it sees pushes and pops, filling out
+ * the debuginfo as necessary.  It will also warn if it sees any
+ * inconsistencies.
+ */
+.macro UNWIND_HINT cfa_reg=UNDWARF_REG_SP cfa_offset=0 type=UNDWARF_TYPE_CFA
+#ifdef CONFIG_STACK_VALIDATION
+.Lunwind_hint_ip_\@:
+   .pushsection .discard.unwind_hints
+   /* struct unwind_hint */
+   .long .Lunwind_hint_ip_\@ - .
+   .short \cfa_offset
+   .byte \cfa_reg
+   .byte \type
+   .popsection
+#endif
+.endm
+
+.macro UNWIND_HINT_EMPTY
+   UNWIND_HINT cfa_reg=UNDWARF_REG_UNDEFINED
+.endm
+
+.macro UNWIND_HINT_REGS base=rsp offset=0 indirect=0 extra=1 iret=0
+   .if \base == rsp && \indirect
+   .set cfa_reg, UNDWARF_REG_SP_INDIRECT
+   .elseif \base == rsp
+   .set cfa_reg, UNDWARF_REG_SP
+   .elseif \base == rbp
+   .set cfa_reg, UNDWARF_REG_BP
+   .elseif \base == rdi
+   .set cfa_reg, UNDWARF_REG_DI
+   .elseif \base == rdx
+   

[PATCH v2 5/8] objtool, x86: add facility for asm code to provide unwind hints

2017-06-28 Thread Josh Poimboeuf
Some asm (and inline asm) code does special things to the stack which
objtool can't understand.  (Nor can GCC or GNU assembler, for that
matter.)  In such cases we need a facility for the code to provide
annotations, so the unwinder can unwind through it.

This provides such a facility, in the form of unwind hints.  They're
similar to the GNU assembler .cfi* directives, but they give more
information, and are needed in far fewer places, because objtool can
fill in the blanks by following branches and adjusting the stack pointer
for pushes and pops.

Signed-off-by: Josh Poimboeuf 
---
 .../x86/include/asm}/undwarf-types.h   |  18 +++
 arch/x86/include/asm/undwarf.h | 103 
 tools/objtool/Makefile |   3 +
 tools/objtool/check.c  | 179 -
 tools/objtool/check.h  |   4 +-
 tools/objtool/undwarf-types.h  |  18 +++
 6 files changed, 317 insertions(+), 8 deletions(-)
 copy {tools/objtool => arch/x86/include/asm}/undwarf-types.h (84%)
 create mode 100644 arch/x86/include/asm/undwarf.h

diff --git a/tools/objtool/undwarf-types.h 
b/arch/x86/include/asm/undwarf-types.h
similarity index 84%
copy from tools/objtool/undwarf-types.h
copy to arch/x86/include/asm/undwarf-types.h
index ef92a1d..4e5e283 100644
--- a/tools/objtool/undwarf-types.h
+++ b/arch/x86/include/asm/undwarf-types.h
@@ -57,11 +57,17 @@
  *
  * UNDWARF_TYPE_REGS_IRET: Used in entry code to indicate that
  * cfa_reg+cfa_offset points to the iret return frame.
+ *
+ * The UNWIND_HINT macros are only used for the unwind_hint struct.  They are
+ * not used for the undwarf struct due to size and complexity constraints.
  */
 #define UNDWARF_TYPE_CFA   0
 #define UNDWARF_TYPE_REGS  1
 #define UNDWARF_TYPE_REGS_IRET 2
+#define UNWIND_HINT_TYPE_SAVE  3
+#define UNWIND_HINT_TYPE_RESTORE   4
 
+#ifndef __ASSEMBLY__
 /*
  * This struct contains a simplified version of the DWARF Call Frame
  * Information standard.  It contains only the necessary parts of the real
@@ -78,4 +84,16 @@ struct undwarf {
unsigned type:2;
 };
 
+/*
+ * This struct is used by asm and inline asm code to manually annotate the
+ * location of registers on the stack for the undwarf unwinder.
+ */
+struct unwind_hint {
+   unsigned int ip;
+   short cfa_offset;
+   unsigned char cfa_reg;
+   unsigned char type;
+};
+#endif /* __ASSEMBLY__ */
+
 #endif /* _UNDWARF_TYPES_H */
diff --git a/arch/x86/include/asm/undwarf.h b/arch/x86/include/asm/undwarf.h
new file mode 100644
index 000..41384e6
--- /dev/null
+++ b/arch/x86/include/asm/undwarf.h
@@ -0,0 +1,103 @@
+#ifndef _ASM_X86_UNDWARF_H
+#define _ASM_X86_UNDWARF_H
+
+#include "undwarf-types.h"
+
+#ifdef __ASSEMBLY__
+
+/*
+ * In asm, there are two kinds of code: normal C-type callable functions and
+ * the rest.  The normal callable functions can be called by other code, and
+ * don't do anything unusual with the stack.  Such normal callable functions
+ * are annotated with the ENTRY/ENDPROC macros.  Most asm code falls in this
+ * category.  In this case, no special debugging annotations are needed because
+ * objtool can automatically generate the .undwarf section which the undwarf
+ * unwinder reads at runtime.
+ *
+ * Anything which doesn't fall into the above category, such as syscall and
+ * interrupt handlers, tends to not be called directly by other functions, and
+ * often does unusual non-C-function-type things with the stack pointer.  Such
+ * code needs to be annotated such that objtool can understand it.  The
+ * following CFI hint macros are for this type of code.
+ *
+ * These macros provide hints to objtool about the state of the stack at each
+ * instruction.  Objtool starts from the hints and follows the code flow,
+ * making automatic CFI adjustments when it sees pushes and pops, filling out
+ * the debuginfo as necessary.  It will also warn if it sees any
+ * inconsistencies.
+ */
+.macro UNWIND_HINT cfa_reg=UNDWARF_REG_SP cfa_offset=0 type=UNDWARF_TYPE_CFA
+#ifdef CONFIG_STACK_VALIDATION
+.Lunwind_hint_ip_\@:
+   .pushsection .discard.unwind_hints
+   /* struct unwind_hint */
+   .long .Lunwind_hint_ip_\@ - .
+   .short \cfa_offset
+   .byte \cfa_reg
+   .byte \type
+   .popsection
+#endif
+.endm
+
+.macro UNWIND_HINT_EMPTY
+   UNWIND_HINT cfa_reg=UNDWARF_REG_UNDEFINED
+.endm
+
+.macro UNWIND_HINT_REGS base=rsp offset=0 indirect=0 extra=1 iret=0
+   .if \base == rsp && \indirect
+   .set cfa_reg, UNDWARF_REG_SP_INDIRECT
+   .elseif \base == rsp
+   .set cfa_reg, UNDWARF_REG_SP
+   .elseif \base == rbp
+   .set cfa_reg, UNDWARF_REG_BP
+   .elseif \base == rdi
+   .set cfa_reg, UNDWARF_REG_DI
+   .elseif \base == rdx
+   .set cfa_reg,