Commit 7bceec4e authored by Hendrik Brueckner's avatar Hendrik Brueckner Committed by Martin Schwidefsky

s390/vdso: revise CFI annotations of vDSO functions

Revise and add CFI CFA and register rule annotations to the vDSO
functions for proper stack unwinding and debugging.

Because glibc might call the vDSO in special ways, the vDSO code
does not rely on a stack frame created by the caller.  The TOD clock
value can be therefore not stored in the pre-allocated stack area
and additional stack space is required.
To correctly annotate these situations with CFI, the .cfi_val_offset
directive is required to create relative offsets on the value of the
stack register %r15.  Because the .cfi_val_offset directive is
available with recent GNU assembler versions only, additional checks
are necessary.

Note that if the vDSO is assembled with an older assembler version,
stack unwinding and debugging from within the vDSO code might not
be possible.
Signed-off-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent bc3703f2
...@@ -88,10 +88,13 @@ KBUILD_CFLAGS += -DCC_USING_HOTPATCH ...@@ -88,10 +88,13 @@ KBUILD_CFLAGS += -DCC_USING_HOTPATCH
endif endif
endif endif
# Test CFI features of binutils
cfi := $(call as-instr,.cfi_startproc\n.cfi_val_offset 15$(comma)-160\n.cfi_endproc,-DCONFIG_AS_CFI_VAL_OFFSET=1)
KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y) KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y)
KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += -fno-asynchronous-unwind-tables $(cfi)
KBUILD_AFLAGS += $(aflags-y) KBUILD_AFLAGS += $(aflags-y) $(cfi)
OBJCOPYFLAGS := -O binary OBJCOPYFLAGS := -O binary
......
...@@ -4,6 +4,18 @@ ...@@ -4,6 +4,18 @@
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
#define CFI_RESTORE .cfi_restore
#ifdef CONFIG_AS_CFI_VAL_OFFSET
#define CFI_VAL_OFFSET .cfi_val_offset
#else
#define CFI_VAL_OFFSET #
#endif
#ifndef BUILD_VDSO #ifndef BUILD_VDSO
/* /*
* Emit CFI data in .debug_frame sections and not in .eh_frame * Emit CFI data in .debug_frame sections and not in .eh_frame
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
.globl __kernel_clock_getres .globl __kernel_clock_getres
.type __kernel_clock_getres,@function .type __kernel_clock_getres,@function
__kernel_clock_getres: __kernel_clock_getres:
.cfi_startproc CFI_STARTPROC
basr %r1,0 basr %r1,0
la %r1,4f-.(%r1) la %r1,4f-.(%r1)
chi %r2,__CLOCK_REALTIME chi %r2,__CLOCK_REALTIME
...@@ -38,7 +38,7 @@ __kernel_clock_getres: ...@@ -38,7 +38,7 @@ __kernel_clock_getres:
3: lhi %r1,__NR_clock_getres /* fallback to svc */ 3: lhi %r1,__NR_clock_getres /* fallback to svc */
svc 0 svc 0
br %r14 br %r14
CFI_ENDPROC
4: .long __CLOCK_REALTIME_RES 4: .long __CLOCK_REALTIME_RES
5: .long __CLOCK_COARSE_RES 5: .long __CLOCK_COARSE_RES
.cfi_endproc
.size __kernel_clock_getres,.-__kernel_clock_getres .size __kernel_clock_getres,.-__kernel_clock_getres
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
.globl __kernel_clock_gettime .globl __kernel_clock_gettime
.type __kernel_clock_gettime,@function .type __kernel_clock_gettime,@function
__kernel_clock_gettime: __kernel_clock_gettime:
.cfi_startproc CFI_STARTPROC
ahi %r15,-16 ahi %r15,-16
CFI_DEF_CFA_OFFSET 176
CFI_VAL_OFFSET 15, -160
basr %r5,0 basr %r5,0
0: al %r5,21f-0b(%r5) /* get &_vdso_data */ 0: al %r5,21f-0b(%r5) /* get &_vdso_data */
chi %r2,__CLOCK_REALTIME_COARSE chi %r2,__CLOCK_REALTIME_COARSE
...@@ -70,9 +72,13 @@ __kernel_clock_gettime: ...@@ -70,9 +72,13 @@ __kernel_clock_gettime:
st %r1,4(%r3) /* store tp->tv_nsec */ st %r1,4(%r3) /* store tp->tv_nsec */
lhi %r2,0 lhi %r2,0
ahi %r15,16 ahi %r15,16
CFI_DEF_CFA_OFFSET 160
CFI_RESTORE 15
br %r14 br %r14
/* CLOCK_MONOTONIC_COARSE */ /* CLOCK_MONOTONIC_COARSE */
CFI_DEF_CFA_OFFSET 176
CFI_VAL_OFFSET 15, -160
9: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 9: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
tml %r4,0x0001 /* pending update ? loop */ tml %r4,0x0001 /* pending update ? loop */
jnz 9b jnz 9b
...@@ -152,15 +158,21 @@ __kernel_clock_gettime: ...@@ -152,15 +158,21 @@ __kernel_clock_gettime:
st %r1,4(%r3) /* store tp->tv_nsec */ st %r1,4(%r3) /* store tp->tv_nsec */
lhi %r2,0 lhi %r2,0
ahi %r15,16 ahi %r15,16
CFI_DEF_CFA_OFFSET 160
CFI_RESTORE 15
br %r14 br %r14
/* Fallback to system call */ /* Fallback to system call */
CFI_DEF_CFA_OFFSET 176
CFI_VAL_OFFSET 15, -160
19: lhi %r1,__NR_clock_gettime 19: lhi %r1,__NR_clock_gettime
svc 0 svc 0
ahi %r15,16 ahi %r15,16
CFI_DEF_CFA_OFFSET 160
CFI_RESTORE 15
br %r14 br %r14
CFI_ENDPROC
20: .long 1000000000 20: .long 1000000000
21: .long _vdso_data - 0b 21: .long _vdso_data - 0b
.cfi_endproc
.size __kernel_clock_gettime,.-__kernel_clock_gettime .size __kernel_clock_gettime,.-__kernel_clock_gettime
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
.globl __kernel_getcpu .globl __kernel_getcpu
.type __kernel_getcpu,@function .type __kernel_getcpu,@function
__kernel_getcpu: __kernel_getcpu:
.cfi_startproc CFI_STARTPROC
la %r4,0 la %r4,0
sacf 256 sacf 256
l %r5,__VDSO_CPU_NR(%r4) l %r5,__VDSO_CPU_NR(%r4)
...@@ -29,5 +29,5 @@ __kernel_getcpu: ...@@ -29,5 +29,5 @@ __kernel_getcpu:
st %r4,0(%r3) st %r4,0(%r3)
3: lhi %r2,0 3: lhi %r2,0
br %r14 br %r14
.cfi_endproc CFI_ENDPROC
.size __kernel_getcpu,.-__kernel_getcpu .size __kernel_getcpu,.-__kernel_getcpu
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
.globl __kernel_gettimeofday .globl __kernel_gettimeofday
.type __kernel_gettimeofday,@function .type __kernel_gettimeofday,@function
__kernel_gettimeofday: __kernel_gettimeofday:
.cfi_startproc CFI_STARTPROC
ahi %r15,-16 ahi %r15,-16
CFI_ADJUST_CFA_OFFSET 16
CFI_VAL_OFFSET 15, -160
basr %r5,0 basr %r5,0
0: al %r5,13f-0b(%r5) /* get &_vdso_data */ 0: al %r5,13f-0b(%r5) /* get &_vdso_data */
1: ltr %r3,%r3 /* check if tz is NULL */ 1: ltr %r3,%r3 /* check if tz is NULL */
...@@ -90,9 +92,11 @@ __kernel_gettimeofday: ...@@ -90,9 +92,11 @@ __kernel_gettimeofday:
st %r0,4(%r2) /* store tv->tv_usec */ st %r0,4(%r2) /* store tv->tv_usec */
10: slr %r2,%r2 10: slr %r2,%r2
ahi %r15,16 ahi %r15,16
CFI_ADJUST_CFA_OFFSET -16
CFI_RESTORE 15
br %r14 br %r14
CFI_ENDPROC
11: .long 1000000000 11: .long 1000000000
12: .long 274877907 12: .long 274877907
13: .long _vdso_data - 0b 13: .long _vdso_data - 0b
.cfi_endproc
.size __kernel_gettimeofday,.-__kernel_gettimeofday .size __kernel_gettimeofday,.-__kernel_gettimeofday
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
.globl __kernel_clock_getres .globl __kernel_clock_getres
.type __kernel_clock_getres,@function .type __kernel_clock_getres,@function
__kernel_clock_getres: __kernel_clock_getres:
.cfi_startproc CFI_STARTPROC
larl %r1,4f larl %r1,4f
cghi %r2,__CLOCK_REALTIME_COARSE cghi %r2,__CLOCK_REALTIME_COARSE
je 0f je 0f
...@@ -44,7 +44,7 @@ __kernel_clock_getres: ...@@ -44,7 +44,7 @@ __kernel_clock_getres:
2: lghi %r1,__NR_clock_getres /* fallback to svc */ 2: lghi %r1,__NR_clock_getres /* fallback to svc */
svc 0 svc 0
br %r14 br %r14
CFI_ENDPROC
3: .quad __CLOCK_REALTIME_RES 3: .quad __CLOCK_REALTIME_RES
4: .quad __CLOCK_COARSE_RES 4: .quad __CLOCK_COARSE_RES
.cfi_endproc
.size __kernel_clock_getres,.-__kernel_clock_getres .size __kernel_clock_getres,.-__kernel_clock_getres
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
.globl __kernel_clock_gettime .globl __kernel_clock_gettime
.type __kernel_clock_gettime,@function .type __kernel_clock_gettime,@function
__kernel_clock_gettime: __kernel_clock_gettime:
.cfi_startproc CFI_STARTPROC
aghi %r15,-16 aghi %r15,-16
CFI_DEF_CFA_OFFSET 176
CFI_VAL_OFFSET 15, -160
larl %r5,_vdso_data larl %r5,_vdso_data
cghi %r2,__CLOCK_REALTIME_COARSE cghi %r2,__CLOCK_REALTIME_COARSE
je 4f je 4f
...@@ -54,9 +56,13 @@ __kernel_clock_gettime: ...@@ -54,9 +56,13 @@ __kernel_clock_gettime:
stg %r1,8(%r3) /* store tp->tv_nsec */ stg %r1,8(%r3) /* store tp->tv_nsec */
lghi %r2,0 lghi %r2,0
aghi %r15,16 aghi %r15,16
CFI_DEF_CFA_OFFSET 160
CFI_RESTORE 15
br %r14 br %r14
/* CLOCK_MONOTONIC_COARSE */ /* CLOCK_MONOTONIC_COARSE */
CFI_DEF_CFA_OFFSET 176
CFI_VAL_OFFSET 15, -160
3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ 3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
tmll %r4,0x0001 /* pending update ? loop */ tmll %r4,0x0001 /* pending update ? loop */
jnz 3b jnz 3b
...@@ -109,9 +115,13 @@ __kernel_clock_gettime: ...@@ -109,9 +115,13 @@ __kernel_clock_gettime:
stg %r1,8(%r3) /* store tp->tv_nsec */ stg %r1,8(%r3) /* store tp->tv_nsec */
lghi %r2,0 lghi %r2,0
aghi %r15,16 aghi %r15,16
CFI_DEF_CFA_OFFSET 160
CFI_RESTORE 15
br %r14 br %r14
/* CPUCLOCK_VIRT for this thread */ /* CPUCLOCK_VIRT for this thread */
CFI_DEF_CFA_OFFSET 176
CFI_VAL_OFFSET 15, -160
9: lghi %r4,0 9: lghi %r4,0
icm %r0,15,__VDSO_ECTG_OK(%r5) icm %r0,15,__VDSO_ECTG_OK(%r5)
jz 12f jz 12f
...@@ -132,15 +142,21 @@ __kernel_clock_gettime: ...@@ -132,15 +142,21 @@ __kernel_clock_gettime:
stg %r4,8(%r3) stg %r4,8(%r3)
lghi %r2,0 lghi %r2,0
aghi %r15,16 aghi %r15,16
CFI_DEF_CFA_OFFSET 160
CFI_RESTORE 15
br %r14 br %r14
/* Fallback to system call */ /* Fallback to system call */
CFI_DEF_CFA_OFFSET 176
CFI_VAL_OFFSET 15, -160
12: lghi %r1,__NR_clock_gettime 12: lghi %r1,__NR_clock_gettime
svc 0 svc 0
aghi %r15,16 aghi %r15,16
CFI_DEF_CFA_OFFSET 160
CFI_RESTORE 15
br %r14 br %r14
CFI_ENDPROC
13: .quad 1000000000 13: .quad 1000000000
14: .quad 19342813113834067 14: .quad 19342813113834067
.cfi_endproc
.size __kernel_clock_gettime,.-__kernel_clock_gettime .size __kernel_clock_gettime,.-__kernel_clock_gettime
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
.globl __kernel_getcpu .globl __kernel_getcpu
.type __kernel_getcpu,@function .type __kernel_getcpu,@function
__kernel_getcpu: __kernel_getcpu:
.cfi_startproc CFI_STARTPROC
la %r4,0 la %r4,0
sacf 256 sacf 256
l %r5,__VDSO_CPU_NR(%r4) l %r5,__VDSO_CPU_NR(%r4)
...@@ -29,5 +29,5 @@ __kernel_getcpu: ...@@ -29,5 +29,5 @@ __kernel_getcpu:
st %r4,0(%r3) st %r4,0(%r3)
3: lghi %r2,0 3: lghi %r2,0
br %r14 br %r14
.cfi_endproc CFI_ENDPROC
.size __kernel_getcpu,.-__kernel_getcpu .size __kernel_getcpu,.-__kernel_getcpu
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
.globl __kernel_gettimeofday .globl __kernel_gettimeofday
.type __kernel_gettimeofday,@function .type __kernel_gettimeofday,@function
__kernel_gettimeofday: __kernel_gettimeofday:
.cfi_startproc CFI_STARTPROC
aghi %r15,-16 aghi %r15,-16
CFI_ADJUST_CFA_OFFSET 16
CFI_VAL_OFFSET 15, -160
larl %r5,_vdso_data larl %r5,_vdso_data
0: ltgr %r3,%r3 /* check if tz is NULL */ 0: ltgr %r3,%r3 /* check if tz is NULL */
je 1f je 1f
...@@ -59,8 +61,10 @@ __kernel_gettimeofday: ...@@ -59,8 +61,10 @@ __kernel_gettimeofday:
stg %r0,8(%r2) /* store tv->tv_usec */ stg %r0,8(%r2) /* store tv->tv_usec */
4: lghi %r2,0 4: lghi %r2,0
aghi %r15,16 aghi %r15,16
CFI_ADJUST_CFA_OFFSET -16
CFI_RESTORE 15
br %r14 br %r14
CFI_ENDPROC
5: .quad 1000000000 5: .quad 1000000000
.long 274877907 .long 274877907
.cfi_endproc
.size __kernel_gettimeofday,.-__kernel_gettimeofday .size __kernel_gettimeofday,.-__kernel_gettimeofday
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