Commit 7effaa88 authored by Jan Beulich's avatar Jan Beulich Committed by Linus Torvalds

[PATCH] x86-64: Fix CFI information

Being the foundation for reliable stack unwinding, this fixes CFI unwind
annotations in many low-level x86_64 routines, plus a config option
(available to all architectures, and also present in the previously sent
patch adding such annotations to i386 code) to enable them separatly
rather than only along with adding full debug information.
Signed-off-by: default avatarJan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b3ab8382
...@@ -55,20 +55,34 @@ ...@@ -55,20 +55,34 @@
* with the int 0x80 path. * with the int 0x80 path.
*/ */
ENTRY(ia32_sysenter_target) ENTRY(ia32_sysenter_target)
CFI_STARTPROC CFI_STARTPROC simple
CFI_DEF_CFA rsp,0
CFI_REGISTER rsp,rbp
swapgs swapgs
movq %gs:pda_kernelstack, %rsp movq %gs:pda_kernelstack, %rsp
addq $(PDA_STACKOFFSET),%rsp addq $(PDA_STACKOFFSET),%rsp
sti sti
movl %ebp,%ebp /* zero extension */ movl %ebp,%ebp /* zero extension */
pushq $__USER32_DS pushq $__USER32_DS
CFI_ADJUST_CFA_OFFSET 8
/*CFI_REL_OFFSET ss,0*/
pushq %rbp pushq %rbp
CFI_ADJUST_CFA_OFFSET 8
CFI_REL_OFFSET rsp,0
pushfq pushfq
CFI_ADJUST_CFA_OFFSET 8
/*CFI_REL_OFFSET rflags,0*/
movl $VSYSCALL32_SYSEXIT, %r10d movl $VSYSCALL32_SYSEXIT, %r10d
CFI_REGISTER rip,r10
pushq $__USER32_CS pushq $__USER32_CS
CFI_ADJUST_CFA_OFFSET 8
/*CFI_REL_OFFSET cs,0*/
movl %eax, %eax movl %eax, %eax
pushq %r10 pushq %r10
CFI_ADJUST_CFA_OFFSET 8
CFI_REL_OFFSET rip,0
pushq %rax pushq %rax
CFI_ADJUST_CFA_OFFSET 8
cld cld
SAVE_ARGS 0,0,1 SAVE_ARGS 0,0,1
/* no need to do an access_ok check here because rbp has been /* no need to do an access_ok check here because rbp has been
...@@ -79,6 +93,7 @@ ENTRY(ia32_sysenter_target) ...@@ -79,6 +93,7 @@ ENTRY(ia32_sysenter_target)
.previous .previous
GET_THREAD_INFO(%r10) GET_THREAD_INFO(%r10)
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
CFI_REMEMBER_STATE
jnz sysenter_tracesys jnz sysenter_tracesys
sysenter_do_call: sysenter_do_call:
cmpl $(IA32_NR_syscalls),%eax cmpl $(IA32_NR_syscalls),%eax
...@@ -94,14 +109,20 @@ sysenter_do_call: ...@@ -94,14 +109,20 @@ sysenter_do_call:
andl $~0x200,EFLAGS-R11(%rsp) andl $~0x200,EFLAGS-R11(%rsp)
RESTORE_ARGS 1,24,1,1,1,1 RESTORE_ARGS 1,24,1,1,1,1
popfq popfq
CFI_ADJUST_CFA_OFFSET -8
/*CFI_RESTORE rflags*/
popq %rcx /* User %esp */ popq %rcx /* User %esp */
CFI_ADJUST_CFA_OFFSET -8
CFI_REGISTER rsp,rcx
movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */ movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */
CFI_REGISTER rip,rdx
swapgs swapgs
sti /* sti only takes effect after the next instruction */ sti /* sti only takes effect after the next instruction */
/* sysexit */ /* sysexit */
.byte 0xf, 0x35 .byte 0xf, 0x35
sysenter_tracesys: sysenter_tracesys:
CFI_RESTORE_STATE
SAVE_REST SAVE_REST
CLEAR_RREGS CLEAR_RREGS
movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq $-ENOSYS,RAX(%rsp) /* really needed? */
...@@ -140,21 +161,28 @@ sysenter_tracesys: ...@@ -140,21 +161,28 @@ sysenter_tracesys:
* with the int 0x80 path. * with the int 0x80 path.
*/ */
ENTRY(ia32_cstar_target) ENTRY(ia32_cstar_target)
CFI_STARTPROC CFI_STARTPROC simple
CFI_DEF_CFA rsp,0
CFI_REGISTER rip,rcx
/*CFI_REGISTER rflags,r11*/
swapgs swapgs
movl %esp,%r8d movl %esp,%r8d
CFI_REGISTER rsp,r8
movq %gs:pda_kernelstack,%rsp movq %gs:pda_kernelstack,%rsp
sti sti
SAVE_ARGS 8,1,1 SAVE_ARGS 8,1,1
movl %eax,%eax /* zero extension */ movl %eax,%eax /* zero extension */
movq %rax,ORIG_RAX-ARGOFFSET(%rsp) movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
movq %rcx,RIP-ARGOFFSET(%rsp) movq %rcx,RIP-ARGOFFSET(%rsp)
CFI_REL_OFFSET rip,RIP-ARGOFFSET
movq %rbp,RCX-ARGOFFSET(%rsp) /* this lies slightly to ptrace */ movq %rbp,RCX-ARGOFFSET(%rsp) /* this lies slightly to ptrace */
movl %ebp,%ecx movl %ebp,%ecx
movq $__USER32_CS,CS-ARGOFFSET(%rsp) movq $__USER32_CS,CS-ARGOFFSET(%rsp)
movq $__USER32_DS,SS-ARGOFFSET(%rsp) movq $__USER32_DS,SS-ARGOFFSET(%rsp)
movq %r11,EFLAGS-ARGOFFSET(%rsp) movq %r11,EFLAGS-ARGOFFSET(%rsp)
/*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
movq %r8,RSP-ARGOFFSET(%rsp) movq %r8,RSP-ARGOFFSET(%rsp)
CFI_REL_OFFSET rsp,RSP-ARGOFFSET
/* no need to do an access_ok check here because r8 has been /* no need to do an access_ok check here because r8 has been
32bit zero extended */ 32bit zero extended */
/* hardware stack frame is complete now */ /* hardware stack frame is complete now */
...@@ -164,6 +192,7 @@ ENTRY(ia32_cstar_target) ...@@ -164,6 +192,7 @@ ENTRY(ia32_cstar_target)
.previous .previous
GET_THREAD_INFO(%r10) GET_THREAD_INFO(%r10)
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
CFI_REMEMBER_STATE
jnz cstar_tracesys jnz cstar_tracesys
cstar_do_call: cstar_do_call:
cmpl $IA32_NR_syscalls,%eax cmpl $IA32_NR_syscalls,%eax
...@@ -177,12 +206,16 @@ cstar_do_call: ...@@ -177,12 +206,16 @@ cstar_do_call:
jnz int_ret_from_sys_call jnz int_ret_from_sys_call
RESTORE_ARGS 1,-ARG_SKIP,1,1,1 RESTORE_ARGS 1,-ARG_SKIP,1,1,1
movl RIP-ARGOFFSET(%rsp),%ecx movl RIP-ARGOFFSET(%rsp),%ecx
CFI_REGISTER rip,rcx
movl EFLAGS-ARGOFFSET(%rsp),%r11d movl EFLAGS-ARGOFFSET(%rsp),%r11d
/*CFI_REGISTER rflags,r11*/
movl RSP-ARGOFFSET(%rsp),%esp movl RSP-ARGOFFSET(%rsp),%esp
CFI_RESTORE rsp
swapgs swapgs
sysretl sysretl
cstar_tracesys: cstar_tracesys:
CFI_RESTORE_STATE
SAVE_REST SAVE_REST
CLEAR_RREGS CLEAR_RREGS
movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq $-ENOSYS,RAX(%rsp) /* really needed? */
...@@ -226,11 +259,18 @@ ia32_badarg: ...@@ -226,11 +259,18 @@ ia32_badarg:
*/ */
ENTRY(ia32_syscall) ENTRY(ia32_syscall)
CFI_STARTPROC CFI_STARTPROC simple
CFI_DEF_CFA rsp,SS+8-RIP
/*CFI_REL_OFFSET ss,SS-RIP*/
CFI_REL_OFFSET rsp,RSP-RIP
/*CFI_REL_OFFSET rflags,EFLAGS-RIP*/
/*CFI_REL_OFFSET cs,CS-RIP*/
CFI_REL_OFFSET rip,RIP-RIP
swapgs swapgs
sti sti
movl %eax,%eax movl %eax,%eax
pushq %rax pushq %rax
CFI_ADJUST_CFA_OFFSET 8
cld cld
/* note the registers are not zero extended to the sf. /* note the registers are not zero extended to the sf.
this could be a problem. */ this could be a problem. */
...@@ -278,6 +318,8 @@ quiet_ni_syscall: ...@@ -278,6 +318,8 @@ quiet_ni_syscall:
jmp ia32_ptregs_common jmp ia32_ptregs_common
.endm .endm
CFI_STARTPROC
PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
...@@ -290,8 +332,9 @@ quiet_ni_syscall: ...@@ -290,8 +332,9 @@ quiet_ni_syscall:
PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx
ENTRY(ia32_ptregs_common) ENTRY(ia32_ptregs_common)
CFI_STARTPROC
popq %r11 popq %r11
CFI_ADJUST_CFA_OFFSET -8
CFI_REGISTER rip, r11
SAVE_REST SAVE_REST
call *%rax call *%rax
RESTORE_REST RESTORE_REST
......
This diff is collapsed.
...@@ -65,27 +65,36 @@ ...@@ -65,27 +65,36 @@
.if \skipr11 .if \skipr11
.else .else
movq (%rsp),%r11 movq (%rsp),%r11
CFI_RESTORE r11
.endif .endif
.if \skipr8910 .if \skipr8910
.else .else
movq 1*8(%rsp),%r10 movq 1*8(%rsp),%r10
CFI_RESTORE r10
movq 2*8(%rsp),%r9 movq 2*8(%rsp),%r9
CFI_RESTORE r9
movq 3*8(%rsp),%r8 movq 3*8(%rsp),%r8
CFI_RESTORE r8
.endif .endif
.if \skiprax .if \skiprax
.else .else
movq 4*8(%rsp),%rax movq 4*8(%rsp),%rax
CFI_RESTORE rax
.endif .endif
.if \skiprcx .if \skiprcx
.else .else
movq 5*8(%rsp),%rcx movq 5*8(%rsp),%rcx
CFI_RESTORE rcx
.endif .endif
.if \skiprdx .if \skiprdx
.else .else
movq 6*8(%rsp),%rdx movq 6*8(%rsp),%rdx
CFI_RESTORE rdx
.endif .endif
movq 7*8(%rsp),%rsi movq 7*8(%rsp),%rsi
CFI_RESTORE rsi
movq 8*8(%rsp),%rdi movq 8*8(%rsp),%rdi
CFI_RESTORE rdi
.if ARG_SKIP+\addskip > 0 .if ARG_SKIP+\addskip > 0
addq $ARG_SKIP+\addskip,%rsp addq $ARG_SKIP+\addskip,%rsp
CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip) CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
...@@ -124,11 +133,17 @@ ...@@ -124,11 +133,17 @@
.macro RESTORE_REST .macro RESTORE_REST
movq (%rsp),%r15 movq (%rsp),%r15
CFI_RESTORE r15
movq 1*8(%rsp),%r14 movq 1*8(%rsp),%r14
CFI_RESTORE r14
movq 2*8(%rsp),%r13 movq 2*8(%rsp),%r13
CFI_RESTORE r13
movq 3*8(%rsp),%r12 movq 3*8(%rsp),%r12
CFI_RESTORE r12
movq 4*8(%rsp),%rbp movq 4*8(%rsp),%rbp
CFI_RESTORE rbp
movq 5*8(%rsp),%rbx movq 5*8(%rsp),%rbx
CFI_RESTORE rbx
addq $REST_SKIP,%rsp addq $REST_SKIP,%rsp
CFI_ADJUST_CFA_OFFSET -(REST_SKIP) CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
.endm .endm
...@@ -146,11 +161,3 @@ ...@@ -146,11 +161,3 @@
.macro icebp .macro icebp
.byte 0xf1 .byte 0xf1
.endm .endm
#ifdef CONFIG_FRAME_POINTER
#define ENTER enter
#define LEAVE leave
#else
#define ENTER
#define LEAVE
#endif
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset #define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
#define CFI_OFFSET .cfi_offset #define CFI_OFFSET .cfi_offset
#define CFI_REL_OFFSET .cfi_rel_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
#else #else
...@@ -36,6 +40,10 @@ ...@@ -36,6 +40,10 @@
#define CFI_ADJUST_CFA_OFFSET # #define CFI_ADJUST_CFA_OFFSET #
#define CFI_OFFSET # #define CFI_OFFSET #
#define CFI_REL_OFFSET # #define CFI_REL_OFFSET #
#define CFI_REGISTER #
#define CFI_RESTORE #
#define CFI_REMEMBER_STATE #
#define CFI_RESTORE_STATE #
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment