]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
S390: Add cfi information for start routines in order to stop unwinding.
authorStefan Liebler <stli@linux.vnet.ibm.com>
Tue, 21 Nov 2017 07:45:28 +0000 (08:45 +0100)
committerStefan Liebler <stli@linux.vnet.ibm.com>
Tue, 21 Nov 2017 07:45:28 +0000 (08:45 +0100)
GDB failed to detect the outermost frame while showing the backtrace
within a thread:
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Before this patch, the start routines like thread_start had no cfi information.
GDB is then using the prologue unwinder if no cfi information is available.
This unwinder tries to unwind r15 and stops e.g. if r15 was updated or
on some jump-instructions.

On older glibc-versions (before commit "Remove cached PID/TID in clone"
c579f48edba88380635ab98cb612030e3ed8691e), the thread_start function used
such a jump-instruction and GDB did not fail with an error.

This patch adds cfi information for _start, thread_start and __makecontext_ret
and marks r14 as undefined which marks the frame as outermost frame and GDB
stops the backtrace. Also tested different gcc versions in order to test
_Unwind_Backtrace() in libgcc as this is used by backtrace() in glibc.

ChangeLog:

* sysdeps/s390/s390-64/start.S (_start): Add cfi information for r14.
* sysdeps/s390/s390-32/start.S: (_start): Likewise
* sysdeps/unix/sysv/linux/s390/s390-64/clone.S
(thread_start): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/clone.S
(thread_start): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
(__makecontext_ret): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
(__makecontext_ret): Likewise.

ChangeLog
sysdeps/s390/s390-32/start.S
sysdeps/s390/s390-64/start.S
sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
sysdeps/unix/sysv/linux/s390/s390-32/clone.S
sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
sysdeps/unix/sysv/linux/s390/s390-64/clone.S

index ca6024c35c3fa8d2ffcede4c54b6dbc7187f3d8d..f9e2e18e506af713ecf4d5329337882a6e8367f3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2017-11-21  Stefan Liebler  <stli@linux.vnet.ibm.com>
+
+       * sysdeps/s390/s390-64/start.S (_start): Add cfi information for r14.
+       * sysdeps/s390/s390-32/start.S (_start): Likewise
+       * sysdeps/unix/sysv/linux/s390/s390-64/clone.S
+       (thread_start): Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/clone.S
+       (thread_start): Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
+       (__makecontext_ret): Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
+       (__makecontext_ret): Likewise.
+
 2017-11-21  Stefan Liebler  <stli@linux.vnet.ibm.com>
 
        * include/wchar.h (__wcsnlen, __wcscat, __wcsncpy, __wcpncpy,
index 07400f17520e74185b75ae154eabe345f7aeccee..66c00f3b0a86616c99e7c9ff8ffa56c242354ee6 100644 (file)
@@ -34,6 +34,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sysdep.h>
+
 /*
    This is the canonical entry point, usually the first thing in the text
    segment. Most registers' values are unspecified, except for:
        .globl _start
        .type _start,@function
 _start:
+       cfi_startproc
+       /* Mark r14 as undefined in order to stop unwinding here!  */
+       cfi_undefined (r14)
+
        /* Check if the kernel provides highgprs facility if needed by
           the binary.  */
 
@@ -188,6 +194,7 @@ _start:
        /* crash if __libc_start_main returns */
        .word   0
 
+       cfi_endproc
 .Llit:
 #ifndef PIC
 .L1:    .long  __libc_csu_init
index d8e65450d88a55eb0b771af1f6997e45614e079a..d3e62d2ec78ca73014e70ed4836c76a447a30e3c 100644 (file)
@@ -34,6 +34,8 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sysdep.h>
+
 /*
    This is the canonical entry point, usually the first thing in the text
    segment. Most registers' values are unspecified, except for:
@@ -57,6 +59,9 @@
        .globl _start
        .type _start,@function
 _start:
+       cfi_startproc
+       /* Mark r14 as undefined in order to stop unwinding here!  */
+       cfi_undefined (r14)
        /* Load argc and argv from stack.  */
        la      %r4,8(%r15)             # get argv
        lg      %r3,0(%r15)             # get argc
@@ -91,6 +96,8 @@ _start:
        /* Crash if __libc_start_main returns.  */
        .word   0
 
+       cfi_endproc
+
        /* Define a symbol for the first piece of initialized data.  */
        .data
        .globl __data_start
index 887d841a871dfc6f4cc712950e23008c98a3c5d7..ba38a303eee15cba8abc43fa75b6e629050dbc6a 100644 (file)
 
 #include <sysdep.h>
 
-/* We do not want .eh_frame info so that __makecontext_ret stops unwinding
-   if backtrace was called within a context created by makecontext. (There
-   is also no .eh_frame info for _start or thread_start.)  */
-#undef cfi_startproc
-#define cfi_startproc
-#undef cfi_endproc
-#define cfi_endproc
-
 ENTRY(__makecontext_ret)
+       /* Mark r14 as undefined in order to stop unwinding here!  */
+       cfi_undefined (r14)
        basr  %r14,%r7
        ltr   %r8,%r8                   /* Check whether uc_link is 0.  */
        jz    1f
index a8b4dbc90f8af6a7d5f0274836b91fd9e4fb5c64..91f8ede966a12fcbbb41a2d896eed10656147e29 100644 (file)
@@ -54,12 +54,16 @@ error:
 PSEUDO_END (__clone)
 
 thread_start:
+       cfi_startproc
+       /* Mark r14 as undefined in order to stop unwinding here!  */
+       cfi_undefined (r14)
        /* fn is in gpr 1, arg in gpr 0 */
        lr      %r2,%r0         /* set first parameter to void *arg */
        ahi     %r15,-96        /* make room on the stack for the save area */
        xc      0(4,%r15),0(%r15)
        basr    %r14,%r1        /* jump to fn */
        DO_CALL (exit, 1)
+       cfi_endproc
 
 libc_hidden_def (__clone)
 weak_alias (__clone, clone)
index 16901638b5e51687b6739f6a301957fc3e10aa91..2dcd43ff6e6424f70fa55ef9cbf9fcbd5e582151 100644 (file)
 
 #include <sysdep.h>
 
-/* We do not want .eh_frame info so that __makecontext_ret stops unwinding
-   if backtrace was called within a context created by makecontext. (There
-   is also no .eh_frame info for _start or thread_start.)  */
-#undef cfi_startproc
-#define cfi_startproc
-#undef cfi_endproc
-#define cfi_endproc
-
 ENTRY(__makecontext_ret)
+       /* Mark r14 as undefined in order to stop unwinding here!  */
+       cfi_undefined (r14)
        basr    %r14,%r7
        ltgr    %r8,%r8                 /* Check whether uc_link is 0.  */
        jz      1f
index daf8a58326cd5145436eefb0c5beae7691de380d..8b0cc7e019af3e64b9e0ce7420052c02a13e7ce4 100644 (file)
@@ -55,12 +55,16 @@ error:
 PSEUDO_END (__clone)
 
 thread_start:
+       cfi_startproc
+       /* Mark r14 as undefined in order to stop unwinding here!  */
+       cfi_undefined (r14)
        /* fn is in gpr 1, arg in gpr 0 */
        lgr     %r2,%r0         /* set first parameter to void *arg */
        aghi    %r15,-160       /* make room on the stack for the save area */
        xc      0(8,%r15),0(%r15)
        basr    %r14,%r1        /* jump to fn */
        DO_CALL (exit, 1)
+       cfi_endproc
 
 libc_hidden_def (__clone)
 weak_alias (__clone, clone)