S/390: Add SystemTap probes to longjmp and setjmp.

Message ID 543668CE.9090008@linux.vnet.ibm.com
State Committed
Headers

Commit Message

Stefan Liebler Oct. 9, 2014, 10:51 a.m. UTC
  Hi,

This patch adds support for the SystemTap probes setjmp, longjmp and 
longjmp_target.
The longjmp probe is needed by gdb to determine the target branch 
address while stepping over a longjmp call.

In order to have the demangled address as argument for the 
longjmp-probe, the demangling was reordered.

Tested on s390/s390x.
(For 31bit gdb, a gdb-patch is needed in order to step over a longjmp 
call, but the probes are okay.)

Bye
Stefan

---
2014-10-09  Stefan Liebler  <stli@linux.vnet.ibm.com>

	* sysdeps/s390/s390-32/setjmp.S (__sigsetjmp):
	Add setjmp LIBC_PROBE.
	* sysdeps/s390/s390-64/setjmp.S (__sigsetjmp):
	Likewise.
	* sysdeps/s390/s390-32/__longjmp.c (__longjmp):
	Add longjmp, longjmp_target LIBC_PROBE.
	* sysdeps/s390/s390-64/__longjmp.c (__longjmp):
	Likewise.
  

Comments

Stefan Liebler Oct. 15, 2014, 6:32 a.m. UTC | #1
Ping


See https://sourceware.org/ml/gdb-patches/2014-10/msg00200.html
for information about the mentioned gdb-patch for 31bit s390.

On 10/09/2014 12:51 PM, Stefan Liebler wrote:
> Hi,
>
> This patch adds support for the SystemTap probes setjmp, longjmp and
> longjmp_target.
> The longjmp probe is needed by gdb to determine the target branch
> address while stepping over a longjmp call.
>
> In order to have the demangled address as argument for the
> longjmp-probe, the demangling was reordered.
>
> Tested on s390/s390x.
> (For 31bit gdb, a gdb-patch is needed in order to step over a longjmp
> call, but the probes are okay.)
>
> Bye
> Stefan
>
> ---
> 2014-10-09  Stefan Liebler  <stli@linux.vnet.ibm.com>
>
>      * sysdeps/s390/s390-32/setjmp.S (__sigsetjmp):
>      Add setjmp LIBC_PROBE.
>      * sysdeps/s390/s390-64/setjmp.S (__sigsetjmp):
>      Likewise.
>      * sysdeps/s390/s390-32/__longjmp.c (__longjmp):
>      Add longjmp, longjmp_target LIBC_PROBE.
>      * sysdeps/s390/s390-64/__longjmp.c (__longjmp):
>      Likewise.
  
Andreas Krebbel Nov. 13, 2014, 9:48 a.m. UTC | #2
On 10/09/2014 12:51 PM, Stefan Liebler wrote:
> 2014-10-09  Stefan Liebler  <stli@linux.vnet.ibm.com>
> 
> 	* sysdeps/s390/s390-32/setjmp.S (__sigsetjmp):
> 	Add setjmp LIBC_PROBE.
> 	* sysdeps/s390/s390-64/setjmp.S (__sigsetjmp):
> 	Likewise.
> 	* sysdeps/s390/s390-32/__longjmp.c (__longjmp):
> 	Add longjmp, longjmp_target LIBC_PROBE.
> 	* sysdeps/s390/s390-64/__longjmp.c (__longjmp):
> 	Likewise.
> 

Applied.  Thanks!

-Andreas-
  

Patch

diff --git a/sysdeps/s390/s390-32/__longjmp.c b/sysdeps/s390/s390-32/__longjmp.c
index 5d46e21..54e5915 100644
--- a/sysdeps/s390/s390-32/__longjmp.c
+++ b/sysdeps/s390/s390-32/__longjmp.c
@@ -22,6 +22,7 @@ 
 #include <bits/setjmp.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <stap-probe.h>
 
 /* Jump to the position specified by ENV, causing the
    setjmp call there to return VAL, or 1 if VAL is 0.  */
@@ -42,17 +43,31 @@  __longjmp (__jmp_buf env, int val)
   register void *r1 __asm ("%r1") = (void *) env;
 #endif
   /* Restore registers and jump back.  */
-  asm volatile ("ld   %%f6,48(%1)\n\t"
-		"ld   %%f4,40(%1)\n\t"
+  asm volatile (
+		/* longjmp probe expects longjmp first argument, second
+		   argument and target address.  */
 #ifdef PTR_DEMANGLE
-		"lm   %%r6,%%r13,0(%1)\n\t"
 		"lm   %%r4,%%r5,32(%1)\n\t"
 		"xr   %%r4,%2\n\t"
 		"xr   %%r5,%2\n\t"
+		LIBC_PROBE_ASM (longjmp, 4@%1 -4@%0 4@%%r4)
+#else
+		LIBC_PROBE_ASM (longjmp, 4@%1 -4@%0 4@%%r14)
+#endif
+
+		/* restore fpregs  */
+		"ld   %%f6,48(%1)\n\t"
+		"ld   %%f4,40(%1)\n\t"
+
+		/* restore gregs and return to jmp_buf target  */
+#ifdef PTR_DEMANGLE
+		"lm   %%r6,%%r13,0(%1)\n\t"
 		"lr   %%r15,%%r5\n\t"
+		LIBC_PROBE_ASM (longjmp_target, 4@%1 -4@%0 4@%%r4)
 		"br   %%r4"
 #else
 		"lm   %%r6,%%r15,0(%1)\n\t"
+		LIBC_PROBE_ASM (longjmp_target, 4@%1 -4@%0 4@%%r14)
 		"br   %%r14"
 #endif
 		: : "r" (r2),
diff --git a/sysdeps/s390/s390-32/setjmp.S b/sysdeps/s390/s390-32/setjmp.S
index 3ebc813..66555cb 100644
--- a/sysdeps/s390/s390-32/setjmp.S
+++ b/sysdeps/s390/s390-32/setjmp.S
@@ -22,6 +22,7 @@ 
 #define _SETJMP_H
 #include <bits/setjmp.h>
 #include <shlib-compat.h>
+#include <stap-probe.h>
 
 #if !defined IS_IN_rtld
 # if defined SHARED &&  SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
@@ -53,6 +54,9 @@  END (__setjmp)
 
 ENTRY(__sigsetjmp)
 .Linternal_sigsetjmp:
+	/* setjmp probe expects sig/setjmp first argument (4@%r2), second
+	   argument (-4@%r3) and target address (4@%r14).  */
+	LIBC_PROBE (setjmp, 3, 4@%r2, -4@%r3, 4@%r14)
 #ifdef PTR_MANGLE
 	stm    %r6,%r13,0(%r2)      /* store registers in jmp_buf */
 	lr     %r4,%r14
diff --git a/sysdeps/s390/s390-64/__longjmp.c b/sysdeps/s390/s390-64/__longjmp.c
index 168ebf5..e2b13f8 100644
--- a/sysdeps/s390/s390-64/__longjmp.c
+++ b/sysdeps/s390/s390-64/__longjmp.c
@@ -22,6 +22,7 @@ 
 #include <bits/setjmp.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <stap-probe.h>
 
 /* Jump to the position specified by ENV, causing the
    setjmp call there to return VAL, or 1 if VAL is 0.  */
@@ -42,7 +43,20 @@  __longjmp (__jmp_buf env, int val)
   register void *r1 __asm ("%r1") = (void *) env;
 #endif
   /* Restore registers and jump back.  */
-  asm volatile ("ld    %%f8,80(%1)\n\t"
+  asm volatile (
+		/* longjmp probe expects longjmp first argument, second
+		   argument and target address.  */
+#ifdef PTR_DEMANGLE
+		"lmg  %%r4,%%r5,64(%1)\n\t"
+		"xgr  %%r4,%2\n\t"
+		"xgr  %%r5,%2\n\t"
+		LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r4)
+#else
+		LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r14)
+#endif
+
+		/* restore fpregs  */
+		"ld    %%f8,80(%1)\n\t"
 		"ld    %%f9,88(%1)\n\t"
 		"ld    %%f10,96(%1)\n\t"
 		"ld    %%f11,104(%1)\n\t"
@@ -50,15 +64,16 @@  __longjmp (__jmp_buf env, int val)
 		"ld    %%f13,120(%1)\n\t"
 		"ld    %%f14,128(%1)\n\t"
 		"ld    %%f15,136(%1)\n\t"
+
+		/* restore gregs and return to jmp_buf target  */
 #ifdef PTR_DEMANGLE
 		"lmg  %%r6,%%r13,0(%1)\n\t"
-		"lmg  %%r4,%%r5,64(%1)\n\t"
-		"xgr  %%r4,%2\n\t"
-		"xgr  %%r5,%2\n\t"
 		"lgr  %%r15,%%r5\n\t"
+		LIBC_PROBE_ASM (longjmp_target, 8@%1 -4@%0 8@%%r4)
 		"br   %%r4"
 #else
 		"lmg  %%r6,%%r15,0(%1)\n\t"
+		LIBC_PROBE_ASM (longjmp_target, 8@%1 -4@%0 8@%%r14)
 		"br   %%r14"
 #endif
 		: : "r" (r2),
diff --git a/sysdeps/s390/s390-64/setjmp.S b/sysdeps/s390/s390-64/setjmp.S
index faa2784..03de2bf 100644
--- a/sysdeps/s390/s390-64/setjmp.S
+++ b/sysdeps/s390/s390-64/setjmp.S
@@ -22,6 +22,7 @@ 
 #define _SETJMP_H
 #include <bits/setjmp.h>
 #include <shlib-compat.h>
+#include <stap-probe.h>
 
 #if !defined IS_IN_rtld
 # if defined SHARED &&  SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20)
@@ -53,6 +54,9 @@  END (__setjmp)
 
 ENTRY(__sigsetjmp)
 .Linternal_sigsetjmp:
+	/* setjmp probe expects sig/setjmp first argument (8@%r2), second
+	   argument (-8@%r3) and target address (8@%r14).  */
+	LIBC_PROBE (setjmp, 3, 8@%r2, -4@%r3, 8@%r14)
 #ifdef PTR_MANGLE
 	stmg   %r6,%r13,0(%r2)      /* Store registers in jmp_buf.  */
 	lgr    %r4,%r14