Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 131484c8 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

x86/debug: Remove perpetually broken, unmaintainable dwarf annotations



So the dwarf2 annotations in low level assembly code have
become an increasing hindrance: unreadable, messy macros
mixed into some of the most security sensitive code paths
of the Linux kernel.

These debug info annotations don't even buy the upstream
kernel anything: dwarf driven stack unwinding has caused
problems in the past so it's out of tree, and the upstream
kernel only uses the much more robust framepointers based
stack unwinding method.

In addition to that there's a steady, slow bitrot going
on with these annotations, requiring frequent fixups.
There's no tooling and no functionality upstream that
keeps it correct.

So burn down the sick forest, allowing new, healthier growth:

   27 files changed, 350 insertions(+), 1101 deletions(-)

Someone who has the willingness and time to do this
properly can attempt to reintroduce dwarf debuginfo in x86
assembly code plus dwarf unwinding from first principles,
with the following conditions:

 - it should be maximally readable, and maximally low-key to
   'ordinary' code reading and maintenance.

 - find a build time method to insert dwarf annotations
   automatically in the most common cases, for pop/push
   instructions that manipulate the stack pointer. This could
   be done for example via a preprocessing step that just
   looks for common patterns - plus special annotations for
   the few cases where we want to depart from the default.
   We have hundreds of CFI annotations, so automating most of
   that makes sense.

 - it should come with build tooling checks that ensure that
   CFI annotations are sensible. We've seen such efforts from
   the framepointer side, and there's no reason it couldn't be
   done on the dwarf side.

Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent cdeb6048
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -149,12 +149,6 @@ endif
sp-$(CONFIG_X86_32) := esp
sp-$(CONFIG_X86_64) := rsp

# do binutils support CFI?
cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1)
# is .cfi_signal_frame supported too?
cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1)

# does binutils support specific instructions?
asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1)
asinstr += $(call as-instr,pshufb %xmm0$(comma)%xmm0,-DCONFIG_AS_SSSE3=1)
@@ -162,8 +156,8 @@ asinstr += $(call as-instr,crc32l %eax$(comma)%eax,-DCONFIG_AS_CRC32=1)
avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1)
avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1)

KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr)
KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr)
KBUILD_AFLAGS += $(asinstr) $(avx_instr) $(avx2_instr)
KBUILD_CFLAGS += $(asinstr) $(avx_instr) $(avx2_instr)

LDFLAGS := -m elf_$(UTS_MACHINE)

+32 −101
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@
 * Copyright 2000-2002 Andi Kleen, SuSE Labs.
 */		 

#include <asm/dwarf2.h>
#include <asm/calling.h>
#include <asm/asm-offsets.h>
#include <asm/current.h>
@@ -60,17 +59,6 @@
	movl %eax,%eax			/* zero extension */
	.endm
	
	.macro CFI_STARTPROC32 simple
	CFI_STARTPROC	\simple
	CFI_UNDEFINED	r8
	CFI_UNDEFINED	r9
	CFI_UNDEFINED	r10
	CFI_UNDEFINED	r11
	CFI_UNDEFINED	r12
	CFI_UNDEFINED	r13
	CFI_UNDEFINED	r14
	CFI_UNDEFINED	r15
	.endm

#ifdef CONFIG_PARAVIRT
ENTRY(native_usergs_sysret32)
@@ -102,11 +90,6 @@ ENDPROC(native_usergs_sysret32)
 * with the int 0x80 path.
 */
ENTRY(ia32_sysenter_target)
	CFI_STARTPROC32	simple
	CFI_SIGNAL_FRAME
	CFI_DEF_CFA	rsp,0
	CFI_REGISTER	rsp,rbp

	/*
	 * Interrupts are off on entry.
	 * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
@@ -121,25 +104,21 @@ ENTRY(ia32_sysenter_target)
	movl	%eax, %eax

	movl	ASM_THREAD_INFO(TI_sysenter_return, %rsp, 0), %r10d
	CFI_REGISTER rip,r10

	/* Construct struct pt_regs on stack */
	pushq_cfi	$__USER32_DS		/* pt_regs->ss */
	pushq_cfi	%rbp			/* pt_regs->sp */
	CFI_REL_OFFSET	rsp,0
	pushfq_cfi				/* pt_regs->flags */
	pushq_cfi	$__USER32_CS		/* pt_regs->cs */
	pushq_cfi	%r10 /* pt_regs->ip = thread_info->sysenter_return */
	CFI_REL_OFFSET	rip,0
	pushq_cfi_reg	rax			/* pt_regs->orig_ax */
	pushq_cfi_reg	rdi			/* pt_regs->di */
	pushq_cfi_reg	rsi			/* pt_regs->si */
	pushq_cfi_reg	rdx			/* pt_regs->dx */
	pushq_cfi_reg	rcx			/* pt_regs->cx */
	pushq_cfi	$-ENOSYS		/* pt_regs->ax */
	pushq	$__USER32_DS		/* pt_regs->ss */
	pushq	%rbp			/* pt_regs->sp */
	pushfq				/* pt_regs->flags */
	pushq	$__USER32_CS		/* pt_regs->cs */
	pushq	%r10 /* pt_regs->ip = thread_info->sysenter_return */
	pushq	%rax			/* pt_regs->orig_ax */
	pushq	%rdi			/* pt_regs->di */
	pushq	%rsi			/* pt_regs->si */
	pushq	%rdx			/* pt_regs->dx */
	pushq	%rcx			/* pt_regs->cx */
	pushq	$-ENOSYS		/* pt_regs->ax */
	cld
	sub	$(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */
	CFI_ADJUST_CFA_OFFSET 10*8

	/*
	 * no need to do an access_ok check here because rbp has been
@@ -161,8 +140,8 @@ sysenter_flags_fixed:

	orl     $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
	testl   $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
	CFI_REMEMBER_STATE
	jnz  sysenter_tracesys

sysenter_do_call:
	/* 32bit syscall -> 64bit C ABI argument conversion */
	movl	%edi,%r8d	/* arg5 */
@@ -193,14 +172,12 @@ sysexit_from_sys_call:
	 */
	andl    $~TS_COMPAT,ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
	movl	RIP(%rsp),%ecx		/* User %eip */
	CFI_REGISTER rip,rcx
	RESTORE_RSI_RDI
	xorl	%edx,%edx		/* avoid info leaks */
	xorq	%r8,%r8
	xorq	%r9,%r9
	xorq	%r10,%r10
	movl	EFLAGS(%rsp),%r11d	/* User eflags */
	/*CFI_RESTORE rflags*/
	TRACE_IRQS_ON

	/*
@@ -231,8 +208,6 @@ sysexit_from_sys_call:
	 */
	USERGS_SYSRET32

	CFI_RESTORE_STATE

#ifdef CONFIG_AUDITSYSCALL
	.macro auditsys_entry_common
	movl %esi,%r8d			/* 5th arg: 4th syscall arg */
@@ -282,8 +257,8 @@ sysexit_audit:
#endif

sysenter_fix_flags:
	pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_FIXED)
	popfq_cfi
	pushq $(X86_EFLAGS_IF|X86_EFLAGS_FIXED)
	popfq
	jmp sysenter_flags_fixed

sysenter_tracesys:
@@ -298,7 +273,6 @@ sysenter_tracesys:
	LOAD_ARGS32  /* reload args from stack in case ptrace changed it */
	RESTORE_EXTRA_REGS
	jmp	sysenter_do_call
	CFI_ENDPROC
ENDPROC(ia32_sysenter_target)

/*
@@ -332,12 +306,6 @@ ENDPROC(ia32_sysenter_target)
 * with the int 0x80 path.
 */
ENTRY(ia32_cstar_target)
	CFI_STARTPROC32	simple
	CFI_SIGNAL_FRAME
	CFI_DEF_CFA	rsp,0
	CFI_REGISTER	rip,rcx
	/*CFI_REGISTER	rflags,r11*/

	/*
	 * Interrupts are off on entry.
	 * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
@@ -345,7 +313,6 @@ ENTRY(ia32_cstar_target)
	 */
	SWAPGS_UNSAFE_STACK
	movl	%esp,%r8d
	CFI_REGISTER	rsp,r8
	movq	PER_CPU_VAR(cpu_current_top_of_stack),%rsp
	ENABLE_INTERRUPTS(CLBR_NONE)

@@ -353,22 +320,19 @@ ENTRY(ia32_cstar_target)
	movl	%eax,%eax

	/* Construct struct pt_regs on stack */
	pushq_cfi	$__USER32_DS		/* pt_regs->ss */
	pushq_cfi	%r8			/* pt_regs->sp */
	CFI_REL_OFFSET rsp,0
	pushq_cfi	%r11			/* pt_regs->flags */
	pushq_cfi	$__USER32_CS		/* pt_regs->cs */
	pushq_cfi	%rcx			/* pt_regs->ip */
	CFI_REL_OFFSET rip,0
	pushq_cfi_reg	rax			/* pt_regs->orig_ax */
	pushq_cfi_reg	rdi			/* pt_regs->di */
	pushq_cfi_reg	rsi			/* pt_regs->si */
	pushq_cfi_reg	rdx			/* pt_regs->dx */
	pushq_cfi_reg	rbp			/* pt_regs->cx */
	pushq	$__USER32_DS		/* pt_regs->ss */
	pushq	%r8			/* pt_regs->sp */
	pushq	%r11			/* pt_regs->flags */
	pushq	$__USER32_CS		/* pt_regs->cs */
	pushq	%rcx			/* pt_regs->ip */
	pushq	%rax			/* pt_regs->orig_ax */
	pushq	%rdi			/* pt_regs->di */
	pushq	%rsi			/* pt_regs->si */
	pushq	%rdx			/* pt_regs->dx */
	pushq	%rbp			/* pt_regs->cx */
	movl	%ebp,%ecx
	pushq_cfi	$-ENOSYS		/* pt_regs->ax */
	pushq	$-ENOSYS		/* pt_regs->ax */
	sub	$(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */
	CFI_ADJUST_CFA_OFFSET 10*8

	/*
	 * no need to do an access_ok check here because r8 has been
@@ -380,8 +344,8 @@ ENTRY(ia32_cstar_target)
	ASM_CLAC
	orl     $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
	testl   $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
	CFI_REMEMBER_STATE
	jnz   cstar_tracesys

cstar_do_call:
	/* 32bit syscall -> 64bit C ABI argument conversion */
	movl	%edi,%r8d	/* arg5 */
@@ -403,15 +367,12 @@ sysretl_from_sys_call:
	andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
	RESTORE_RSI_RDI_RDX
	movl RIP(%rsp),%ecx
	CFI_REGISTER rip,rcx
	movl EFLAGS(%rsp),%r11d
	/*CFI_REGISTER rflags,r11*/
	xorq	%r10,%r10
	xorq	%r9,%r9
	xorq	%r8,%r8
	TRACE_IRQS_ON
	movl RSP(%rsp),%esp
	CFI_RESTORE rsp
	/*
	 * 64bit->32bit SYSRET restores eip from ecx,
	 * eflags from r11 (but RF and VM bits are forced to 0),
@@ -430,7 +391,6 @@ sysretl_from_sys_call:

#ifdef CONFIG_AUDITSYSCALL
cstar_auditsys:
	CFI_RESTORE_STATE
	movl %r9d,R9(%rsp)	/* register to be clobbered by call */
	auditsys_entry_common
	movl R9(%rsp),%r9d	/* reload 6th syscall arg */
@@ -460,7 +420,6 @@ ia32_badarg:
	ASM_CLAC
	movq $-EFAULT,%rax
	jmp ia32_sysret
	CFI_ENDPROC

/*
 * Emulated IA32 system calls via int 0x80.
@@ -484,15 +443,6 @@ ia32_badarg:
 */

ENTRY(ia32_syscall)
	CFI_STARTPROC32	simple
	CFI_SIGNAL_FRAME
	CFI_DEF_CFA	rsp,5*8
	/*CFI_REL_OFFSET	ss,4*8 */
	CFI_REL_OFFSET	rsp,3*8
	/*CFI_REL_OFFSET	rflags,2*8 */
	/*CFI_REL_OFFSET	cs,1*8 */
	CFI_REL_OFFSET	rip,0*8

	/*
	 * Interrupts are off on entry.
	 * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
@@ -506,15 +456,14 @@ ENTRY(ia32_syscall)
	movl	%eax,%eax

	/* Construct struct pt_regs on stack (iret frame is already on stack) */
	pushq_cfi_reg	rax			/* pt_regs->orig_ax */
	pushq_cfi_reg	rdi			/* pt_regs->di */
	pushq_cfi_reg	rsi			/* pt_regs->si */
	pushq_cfi_reg	rdx			/* pt_regs->dx */
	pushq_cfi_reg	rcx			/* pt_regs->cx */
	pushq_cfi	$-ENOSYS		/* pt_regs->ax */
	pushq	%rax			/* pt_regs->orig_ax */
	pushq	%rdi			/* pt_regs->di */
	pushq	%rsi			/* pt_regs->si */
	pushq	%rdx			/* pt_regs->dx */
	pushq	%rcx			/* pt_regs->cx */
	pushq	$-ENOSYS		/* pt_regs->ax */
	cld
	sub	$(10*8),%rsp /* pt_regs->r8-11,bp,bx,r12-15 not saved */
	CFI_ADJUST_CFA_OFFSET 10*8

	orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
	testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
@@ -544,7 +493,6 @@ ia32_tracesys:
	LOAD_ARGS32	/* reload args from stack in case ptrace changed it */
	RESTORE_EXTRA_REGS
	jmp ia32_do_call
	CFI_ENDPROC
END(ia32_syscall)

	.macro PTREGSCALL label, func
@@ -554,8 +502,6 @@ GLOBAL(\label)
	jmp  ia32_ptregs_common	
	.endm

	CFI_STARTPROC32

	PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn
	PTREGSCALL stub32_sigreturn, sys32_sigreturn
	PTREGSCALL stub32_fork, sys_fork
@@ -569,23 +515,8 @@ GLOBAL(stub32_clone)

	ALIGN
ia32_ptregs_common:
	CFI_ENDPROC
	CFI_STARTPROC32	simple
	CFI_SIGNAL_FRAME
	CFI_DEF_CFA	rsp,SIZEOF_PTREGS
	CFI_REL_OFFSET	rax,RAX
	CFI_REL_OFFSET	rcx,RCX
	CFI_REL_OFFSET	rdx,RDX
	CFI_REL_OFFSET	rsi,RSI
	CFI_REL_OFFSET	rdi,RDI
	CFI_REL_OFFSET	rip,RIP
/*	CFI_REL_OFFSET	cs,CS*/
/*	CFI_REL_OFFSET	rflags,EFLAGS*/
	CFI_REL_OFFSET	rsp,RSP
/*	CFI_REL_OFFSET	ss,SS*/
	SAVE_EXTRA_REGS 8
	call *%rax
	RESTORE_EXTRA_REGS 8
	ret
	CFI_ENDPROC
END(ia32_ptregs_common)
+45 −49
Original line number Diff line number Diff line
@@ -46,8 +46,6 @@ For 32-bit we have the following conventions - kernel is built with

*/

#include <asm/dwarf2.h>

#ifdef CONFIG_X86_64

/*
@@ -92,27 +90,26 @@ For 32-bit we have the following conventions - kernel is built with

	.macro ALLOC_PT_GPREGS_ON_STACK addskip=0
	subq	$15*8+\addskip, %rsp
	CFI_ADJUST_CFA_OFFSET 15*8+\addskip
	.endm

	.macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1
	.if \r11
	movq_cfi r11, 6*8+\offset
	movq %r11, 6*8+\offset(%rsp)
	.endif
	.if \r8910
	movq_cfi r10, 7*8+\offset
	movq_cfi r9,  8*8+\offset
	movq_cfi r8,  9*8+\offset
	movq %r10, 7*8+\offset(%rsp)
	movq %r9,  8*8+\offset(%rsp)
	movq %r8,  9*8+\offset(%rsp)
	.endif
	.if \rax
	movq_cfi rax, 10*8+\offset
	movq %rax, 10*8+\offset(%rsp)
	.endif
	.if \rcx
	movq_cfi rcx, 11*8+\offset
	movq %rcx, 11*8+\offset(%rsp)
	.endif
	movq_cfi rdx, 12*8+\offset
	movq_cfi rsi, 13*8+\offset
	movq_cfi rdi, 14*8+\offset
	movq %rdx, 12*8+\offset(%rsp)
	movq %rsi, 13*8+\offset(%rsp)
	movq %rdi, 14*8+\offset(%rsp)
	.endm
	.macro SAVE_C_REGS offset=0
	SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1
@@ -131,24 +128,24 @@ For 32-bit we have the following conventions - kernel is built with
	.endm

	.macro SAVE_EXTRA_REGS offset=0
	movq_cfi r15, 0*8+\offset
	movq_cfi r14, 1*8+\offset
	movq_cfi r13, 2*8+\offset
	movq_cfi r12, 3*8+\offset
	movq_cfi rbp, 4*8+\offset
	movq_cfi rbx, 5*8+\offset
	movq %r15, 0*8+\offset(%rsp)
	movq %r14, 1*8+\offset(%rsp)
	movq %r13, 2*8+\offset(%rsp)
	movq %r12, 3*8+\offset(%rsp)
	movq %rbp, 4*8+\offset(%rsp)
	movq %rbx, 5*8+\offset(%rsp)
	.endm
	.macro SAVE_EXTRA_REGS_RBP offset=0
	movq_cfi rbp, 4*8+\offset
	movq %rbp, 4*8+\offset(%rsp)
	.endm

	.macro RESTORE_EXTRA_REGS offset=0
	movq_cfi_restore 0*8+\offset, r15
	movq_cfi_restore 1*8+\offset, r14
	movq_cfi_restore 2*8+\offset, r13
	movq_cfi_restore 3*8+\offset, r12
	movq_cfi_restore 4*8+\offset, rbp
	movq_cfi_restore 5*8+\offset, rbx
	movq 0*8+\offset(%rsp), %r15
	movq 1*8+\offset(%rsp), %r14
	movq 2*8+\offset(%rsp), %r13
	movq 3*8+\offset(%rsp), %r12
	movq 4*8+\offset(%rsp), %rbp
	movq 5*8+\offset(%rsp), %rbx
	.endm

	.macro ZERO_EXTRA_REGS
@@ -162,24 +159,24 @@ For 32-bit we have the following conventions - kernel is built with

	.macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1
	.if \rstor_r11
	movq_cfi_restore 6*8, r11
	movq 6*8(%rsp), %r11
	.endif
	.if \rstor_r8910
	movq_cfi_restore 7*8, r10
	movq_cfi_restore 8*8, r9
	movq_cfi_restore 9*8, r8
	movq 7*8(%rsp), %r10
	movq 8*8(%rsp), %r9
	movq 9*8(%rsp), %r8
	.endif
	.if \rstor_rax
	movq_cfi_restore 10*8, rax
	movq 10*8(%rsp), %rax
	.endif
	.if \rstor_rcx
	movq_cfi_restore 11*8, rcx
	movq 11*8(%rsp), %rcx
	.endif
	.if \rstor_rdx
	movq_cfi_restore 12*8, rdx
	movq 12*8(%rsp), %rdx
	.endif
	movq_cfi_restore 13*8, rsi
	movq_cfi_restore 14*8, rdi
	movq 13*8(%rsp), %rsi
	movq 14*8(%rsp), %rdi
	.endm
	.macro RESTORE_C_REGS
	RESTORE_C_REGS_HELPER 1,1,1,1,1
@@ -205,7 +202,6 @@ For 32-bit we have the following conventions - kernel is built with

	.macro REMOVE_PT_GPREGS_FROM_STACK addskip=0
	addq $15*8+\addskip, %rsp
	CFI_ADJUST_CFA_OFFSET -(15*8+\addskip)
	.endm

	.macro icebp
@@ -224,23 +220,23 @@ For 32-bit we have the following conventions - kernel is built with
 */

	.macro SAVE_ALL
	pushl_cfi_reg eax
	pushl_cfi_reg ebp
	pushl_cfi_reg edi
	pushl_cfi_reg esi
	pushl_cfi_reg edx
	pushl_cfi_reg ecx
	pushl_cfi_reg ebx
	pushl %eax
	pushl %ebp
	pushl %edi
	pushl %esi
	pushl %edx
	pushl %ecx
	pushl %ebx
	.endm

	.macro RESTORE_ALL
	popl_cfi_reg ebx
	popl_cfi_reg ecx
	popl_cfi_reg edx
	popl_cfi_reg esi
	popl_cfi_reg edi
	popl_cfi_reg ebp
	popl_cfi_reg eax
	popl %ebx
	popl %ecx
	popl %edx
	popl %esi
	popl %edi
	popl %ebp
	popl %eax
	.endm

#endif /* CONFIG_X86_64 */

arch/x86/include/asm/dwarf2.h

deleted100644 → 0
+0 −170
Original line number Diff line number Diff line
#ifndef _ASM_X86_DWARF2_H
#define _ASM_X86_DWARF2_H

#ifndef __ASSEMBLY__
#warning "asm/dwarf2.h should be only included in pure assembly files"
#endif

/*
 * Macros for dwarf2 CFI unwind table entries.
 * See "as.info" for details on these pseudo ops. Unfortunately
 * they are only supported in very new binutils, so define them
 * away for older version.
 */

#ifdef CONFIG_AS_CFI

#define CFI_STARTPROC		.cfi_startproc
#define CFI_ENDPROC		.cfi_endproc
#define CFI_DEF_CFA		.cfi_def_cfa
#define CFI_DEF_CFA_REGISTER	.cfi_def_cfa_register
#define CFI_DEF_CFA_OFFSET	.cfi_def_cfa_offset
#define CFI_ADJUST_CFA_OFFSET	.cfi_adjust_cfa_offset
#define CFI_OFFSET		.cfi_offset
#define CFI_REL_OFFSET		.cfi_rel_offset
#define CFI_REGISTER		.cfi_register
#define CFI_RESTORE		.cfi_restore
#define CFI_REMEMBER_STATE	.cfi_remember_state
#define CFI_RESTORE_STATE	.cfi_restore_state
#define CFI_UNDEFINED		.cfi_undefined
#define CFI_ESCAPE		.cfi_escape

#ifdef CONFIG_AS_CFI_SIGNAL_FRAME
#define CFI_SIGNAL_FRAME	.cfi_signal_frame
#else
#define CFI_SIGNAL_FRAME
#endif

#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__)
	/*
	 * Emit CFI data in .debug_frame sections, not .eh_frame sections.
	 * The latter we currently just discard since we don't do DWARF
	 * unwinding at runtime.  So only the offline DWARF information is
	 * useful to anyone.  Note we should not use this directive if this
	 * file is used in the vDSO assembly, or if vmlinux.lds.S gets
	 * changed so it doesn't discard .eh_frame.
	 */
	.cfi_sections .debug_frame
#endif

#else

/*
 * Due to the structure of pre-exisiting code, don't use assembler line
 * comment character # to ignore the arguments. Instead, use a dummy macro.
 */
.macro cfi_ignore a=0, b=0, c=0, d=0
.endm

#define CFI_STARTPROC		cfi_ignore
#define CFI_ENDPROC		cfi_ignore
#define CFI_DEF_CFA		cfi_ignore
#define CFI_DEF_CFA_REGISTER	cfi_ignore
#define CFI_DEF_CFA_OFFSET	cfi_ignore
#define CFI_ADJUST_CFA_OFFSET	cfi_ignore
#define CFI_OFFSET		cfi_ignore
#define CFI_REL_OFFSET		cfi_ignore
#define CFI_REGISTER		cfi_ignore
#define CFI_RESTORE		cfi_ignore
#define CFI_REMEMBER_STATE	cfi_ignore
#define CFI_RESTORE_STATE	cfi_ignore
#define CFI_UNDEFINED		cfi_ignore
#define CFI_ESCAPE		cfi_ignore
#define CFI_SIGNAL_FRAME	cfi_ignore

#endif

/*
 * An attempt to make CFI annotations more or less
 * correct and shorter. It is implied that you know
 * what you're doing if you use them.
 */
#ifdef __ASSEMBLY__
#ifdef CONFIG_X86_64
	.macro pushq_cfi reg
	pushq \reg
	CFI_ADJUST_CFA_OFFSET 8
	.endm

	.macro pushq_cfi_reg reg
	pushq %\reg
	CFI_ADJUST_CFA_OFFSET 8
	CFI_REL_OFFSET \reg, 0
	.endm

	.macro popq_cfi reg
	popq \reg
	CFI_ADJUST_CFA_OFFSET -8
	.endm

	.macro popq_cfi_reg reg
	popq %\reg
	CFI_ADJUST_CFA_OFFSET -8
	CFI_RESTORE \reg
	.endm

	.macro pushfq_cfi
	pushfq
	CFI_ADJUST_CFA_OFFSET 8
	.endm

	.macro popfq_cfi
	popfq
	CFI_ADJUST_CFA_OFFSET -8
	.endm

	.macro movq_cfi reg offset=0
	movq %\reg, \offset(%rsp)
	CFI_REL_OFFSET \reg, \offset
	.endm

	.macro movq_cfi_restore offset reg
	movq \offset(%rsp), %\reg
	CFI_RESTORE \reg
	.endm
#else /*!CONFIG_X86_64*/
	.macro pushl_cfi reg
	pushl \reg
	CFI_ADJUST_CFA_OFFSET 4
	.endm

	.macro pushl_cfi_reg reg
	pushl %\reg
	CFI_ADJUST_CFA_OFFSET 4
	CFI_REL_OFFSET \reg, 0
	.endm

	.macro popl_cfi reg
	popl \reg
	CFI_ADJUST_CFA_OFFSET -4
	.endm

	.macro popl_cfi_reg reg
	popl %\reg
	CFI_ADJUST_CFA_OFFSET -4
	CFI_RESTORE \reg
	.endm

	.macro pushfl_cfi
	pushfl
	CFI_ADJUST_CFA_OFFSET 4
	.endm

	.macro popfl_cfi
	popfl
	CFI_ADJUST_CFA_OFFSET -4
	.endm

	.macro movl_cfi reg offset=0
	movl %\reg, \offset(%esp)
	CFI_REL_OFFSET \reg, \offset
	.endm

	.macro movl_cfi_restore offset reg
	movl \offset(%esp), %\reg
	CFI_RESTORE \reg
	.endm
#endif /*!CONFIG_X86_64*/
#endif /*__ASSEMBLY__*/

#endif /* _ASM_X86_DWARF2_H */
+2 −5
Original line number Diff line number Diff line
#ifdef __ASSEMBLY__

#include <asm/asm.h>
#include <asm/dwarf2.h>

/* The annotation hides the frame from the unwinder and makes it look
   like a ordinary ebp save/restore. This avoids some special cases for
   frame pointer later */
#ifdef CONFIG_FRAME_POINTER
	.macro FRAME
	__ASM_SIZE(push,_cfi)	%__ASM_REG(bp)
	CFI_REL_OFFSET		__ASM_REG(bp), 0
	__ASM_SIZE(push,)	%__ASM_REG(bp)
	__ASM_SIZE(mov)		%__ASM_REG(sp), %__ASM_REG(bp)
	.endm
	.macro ENDFRAME
	__ASM_SIZE(pop,_cfi)	%__ASM_REG(bp)
	CFI_RESTORE		__ASM_REG(bp)
	__ASM_SIZE(pop,)	%__ASM_REG(bp)
	.endm
#else
	.macro FRAME
Loading