mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
![Josh Poimboeuf](/assets/img/avatar_default.png)
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 <jpoimboe@redhat.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: live-patching@vger.kernel.org Link: http://lkml.kernel.org/r/0f5f3c9104fca559ff4088bece1d14ae3bca52d5.1499786555.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
107 lines
3.5 KiB
C
107 lines
3.5 KiB
C
/*
|
|
* Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef _ORC_TYPES_H
|
|
#define _ORC_TYPES_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/compiler.h>
|
|
|
|
/*
|
|
* The ORC_REG_* registers are base registers which are used to find other
|
|
* registers on the stack.
|
|
*
|
|
* ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
|
|
* address of the previous frame: the caller's SP before it called the current
|
|
* function.
|
|
*
|
|
* ORC_REG_UNDEFINED means the corresponding register's value didn't change in
|
|
* the current frame.
|
|
*
|
|
* The most commonly used base registers are SP and BP -- which the previous SP
|
|
* is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is
|
|
* usually based on.
|
|
*
|
|
* The rest of the base registers are needed for special cases like entry code
|
|
* and GCC realigned stacks.
|
|
*/
|
|
#define ORC_REG_UNDEFINED 0
|
|
#define ORC_REG_PREV_SP 1
|
|
#define ORC_REG_DX 2
|
|
#define ORC_REG_DI 3
|
|
#define ORC_REG_BP 4
|
|
#define ORC_REG_SP 5
|
|
#define ORC_REG_R10 6
|
|
#define ORC_REG_R13 7
|
|
#define ORC_REG_BP_INDIRECT 8
|
|
#define ORC_REG_SP_INDIRECT 9
|
|
#define ORC_REG_MAX 15
|
|
|
|
/*
|
|
* ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the
|
|
* caller's SP right before it made the call). Used for all callable
|
|
* functions, i.e. all C code and all callable asm functions.
|
|
*
|
|
* ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points
|
|
* to a fully populated pt_regs from a syscall, interrupt, or exception.
|
|
*
|
|
* ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset
|
|
* points to the iret return frame.
|
|
*
|
|
* The UNWIND_HINT macros are used only for the unwind_hint struct. They
|
|
* aren't used in struct orc_entry due to size and complexity constraints.
|
|
* Objtool converts them to real types when it converts the hints to orc
|
|
* entries.
|
|
*/
|
|
#define ORC_TYPE_CALL 0
|
|
#define ORC_TYPE_REGS 1
|
|
#define ORC_TYPE_REGS_IRET 2
|
|
#define UNWIND_HINT_TYPE_SAVE 3
|
|
#define UNWIND_HINT_TYPE_RESTORE 4
|
|
|
|
#ifndef __ASSEMBLY__
|
|
/*
|
|
* This struct is more or less a vastly simplified version of the DWARF Call
|
|
* Frame Information standard. It contains only the necessary parts of DWARF
|
|
* CFI, simplified for ease of access by the in-kernel unwinder. It tells the
|
|
* unwinder how to find the previous SP and BP (and sometimes entry regs) on
|
|
* the stack for a given code address. Each instance of the struct corresponds
|
|
* to one or more code locations.
|
|
*/
|
|
struct orc_entry {
|
|
s16 sp_offset;
|
|
s16 bp_offset;
|
|
unsigned sp_reg:4;
|
|
unsigned bp_reg:4;
|
|
unsigned type:2;
|
|
} __packed;
|
|
|
|
/*
|
|
* This struct is used by asm and inline asm code to manually annotate the
|
|
* location of registers on the stack for the ORC unwinder.
|
|
*
|
|
* Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*.
|
|
*/
|
|
struct unwind_hint {
|
|
u32 ip;
|
|
s16 sp_offset;
|
|
u8 sp_reg;
|
|
u8 type;
|
|
};
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* _ORC_TYPES_H */
|