S390: Add CFI rule in _dl_runtime_resolve[_vx] for unwinding.

Message ID 242f3a72-516b-5aed-603f-b55cc21fe361@linux.vnet.ibm.com
State Committed
Headers

Commit Message

Stefan Liebler Dec. 4, 2017, 3:05 p.m. UTC
  Hi,

In _dl_runtime_resolve[_vx], unwinding fails after the new stack frame 
is created as there is no CFI rule for r15. This is also observable in 
GDB: Backtrace stopped: previous frame inner to this frame (corrupt stack?)

Therefore this patch is now storing r15 on stack and is using cfi_offset 
rule. The stmg/lmg instruction is used to store/load r14 and r15 with 
one instruction. On 64bit, the offsets of the fprs have moved to store 
r15 directly after r14. On 31bit, the r14/r15 is now stored between the 
other gprs and fprs as the space wasn't used.

Okay to commit?

Bye.
Stefan

ChangeLog:

	* sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_resolve):
	Store r15 on stack and add cfi rule.
	* sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_resolve):
	Likewise.
  

Comments

Stefan Liebler Dec. 11, 2017, 7:51 a.m. UTC | #1
On 12/04/2017 04:05 PM, Stefan Liebler wrote:
> Hi,
> 
> In _dl_runtime_resolve[_vx], unwinding fails after the new stack frame 
> is created as there is no CFI rule for r15. This is also observable in 
> GDB: Backtrace stopped: previous frame inner to this frame (corrupt stack?)
> 
> Therefore this patch is now storing r15 on stack and is using cfi_offset 
> rule. The stmg/lmg instruction is used to store/load r14 and r15 with 
> one instruction. On 64bit, the offsets of the fprs have moved to store 
> r15 directly after r14. On 31bit, the r14/r15 is now stored between the 
> other gprs and fprs as the space wasn't used.
> 
> Okay to commit?
> 
> Bye.
> Stefan
> 
> ChangeLog:
> 
>      * sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_resolve):
>      Store r15 on stack and add cfi rule.
>      * sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_resolve):
>      Likewise.

Committed
  

Patch

commit 54dea059004a57e1a415472f703c2b93eeacfc82
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
Date:   Mon Dec 4 15:32:46 2017 +0100

    S390: Add CFI rule in _dl_runtime_resolve[_vx] for unwinding.
    
    In _dl_runtime_resolve[_vx], unwinding fails after the new stack frame
    is created as there is no CFI rule for r15. This is also observeable in
    GDB: Backtrace stopped: previous frame inner to this frame (corrupt stack?)
    
    Therefore this patch is now storing r15 on stack and is using cfi_offset rule.
    The stmg/lmg instruction is used to store/load r14 and r15 with one instruction.
    On 64bit, the offsets of the fprs have moved to store r15 directly after r14.
    On 31bit, the r14/r15 is now stored between the other gprs and fprs as the space
    wasn't used.
    
    ChangeLog:
    
            * sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_resolve):
            Store r15 on stack and add cfi rule.
            * sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_resolve):
            Likewise.

diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h
index 19776ee..2d6a674 100644
--- a/sysdeps/s390/s390-32/dl-trampoline.h
+++ b/sysdeps/s390/s390-32/dl-trampoline.h
@@ -51,12 +51,13 @@  _dl_runtime_resolve:
 	cfi_offset (r3, -60)
 	cfi_offset (r4, -56)
 	cfi_offset (r5, -52)
+	stm    %r14,%r15,48(%r15)
+	cfi_offset (r14, -48)
+	cfi_offset (r15, -44)
 	std    %f0,56(%r15)
 	cfi_offset (f0, -40)
 	std    %f2,64(%r15)
 	cfi_offset (f2, -32)
-	st     %r14,8(%r15)
-	cfi_offset (r14, -88)
 	lr     %r0,%r15
 	lm     %r2,%r3,24(%r15)		# load args saved by PLT
 #ifdef RESTORE_VRS
@@ -90,13 +91,11 @@  _dl_runtime_resolve:
 	.machinemode "zarch_nohighgprs"
 	vlm    %v24,%v31,96(%r15)	# restore vector registers
 	.machine pop
-	ahi   %r15,224			# remove stack frame
-	cfi_adjust_cfa_offset (-224)
+	lm     %r14,%r15,272(%r15)# remove stack frame and restore registers
 #else
-	ahi    %r15,96			# remove stack frame
-	cfi_adjust_cfa_offset (-96)
+	lm     %r14,%r15,144(%r15)# remove stack frame and restore registers
 #endif
-	l      %r14,8(15)		# restore registers
+	cfi_def_cfa_offset (96)
 	ld     %f0,56(%r15)
 	ld     %f2,64(%r15)
 	lm     %r2,%r5,32(%r15)
diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h
index e1f95e2..29bdbb1 100644
--- a/sysdeps/s390/s390-64/dl-trampoline.h
+++ b/sysdeps/s390/s390-64/dl-trampoline.h
@@ -47,16 +47,17 @@  _dl_runtime_resolve:
 	cfi_offset (r3, -88)
 	cfi_offset (r4, -80)
 	cfi_offset (r5, -72)
-	std    %f0,104(%r15)
-	cfi_offset (f0, -56)
-	std    %f2,112(%r15)
-	cfi_offset (f2, -48)
-	std    %f4,120(%r15)
-	cfi_offset (f4, -40)
-	std    %f6,128(%r15)
-	cfi_offset (f6, -32)
-	stg    %r14,96(15)
+	stmg   %r14,%r15,96(%r15)
 	cfi_offset (r14, -64)
+	cfi_offset (r15, -56)
+	std    %f0,112(%r15)
+	cfi_offset (f0, -48)
+	std    %f2,120(%r15)
+	cfi_offset (f2, -40)
+	std    %f4,128(%r15)
+	cfi_offset (f4, -32)
+	std    %f6,136(%r15)
+	cfi_offset (f6, -24)
 	lmg    %r2,%r3,48(%r15) # load args for fixup saved by PLT
 	lgr    %r0,%r15
 #ifdef RESTORE_VRS
@@ -86,17 +87,15 @@  _dl_runtime_resolve:
 	.machine "z13"
 	vlm    %v24,%v31,160(%r15)# restore vector registers
 	.machine pop
-	aghi   %r15,288         # remove stack frame
-	cfi_adjust_cfa_offset (-288)
+	lmg    %r14,%r15,384(%r15)# remove stack frame and restore registers
 #else
-	aghi   %r15,160         # remove stack frame
-	cfi_adjust_cfa_offset (-160)
+	lmg    %r14,%r15,256(%r15)# remove stack frame and restore registers
 #endif
-	lg     %r14,96(%r15)	# restore registers
-	ld     %f0,104(%r15)
-	ld     %f2,112(%r15)
-	ld     %f4,120(%r15)
-	ld     %f6,128(%r15)
+	cfi_def_cfa_offset (160)
+	ld     %f0,112(%r15)
+	ld     %f2,120(%r15)
+	ld     %f4,128(%r15)
+	ld     %f6,136(%r15)
 	lmg    %r2,%r5,64(%r15)
 	br     %r1
 	cfi_endproc