File gperftools-s390.patch of Package gperftools

commit bf8eacce69df877d1cecdab8c7a6cc3f218ebcc2
Author: Bryan Chan <bryanpkc@gmail.com>
Date:   Wed Jun 15 00:10:45 2016 -0400

    Add support for 31-bit s390; merge linux_syscall_support.h changes from upstream.

diff --git a/configure.ac b/configure.ac
index c7221ca..a688a25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,8 +53,8 @@ case "$host" in
    *-darwin*) default_enable_heap_checker=no;;
 esac
 
-# Currently only backtrace works on s390x.
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __s390x__])],
+# Currently only backtrace works on s390.
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __s390__])],
                   [default_enable_libunwind=no
                    default_enable_backtrace=yes],
                   [default_enable_libunwind=yes
diff --git a/m4/pc_from_ucontext.m4 b/m4/pc_from_ucontext.m4
index d743fa4..c9224bc 100644
--- a/m4/pc_from_ucontext.m4
+++ b/m4/pc_from_ucontext.m4
@@ -27,7 +27,7 @@ AC_DEFUN([AC_PC_FROM_UCONTEXT],
    pc_fields="$pc_fields uc_mcontext.sc_ip"            # Linux (ia64)
    pc_fields="$pc_fields uc_mcontext.pc"               # Linux (mips)
    pc_fields="$pc_fields uc_mcontext.uc_regs->gregs[[PT_NIP]]" # Linux (ppc)
-   pc_fields="$pc_fields uc_mcontext.psw.addr"         # Linux (s390x)
+   pc_fields="$pc_fields uc_mcontext.psw.addr"         # Linux (s390)
    pc_fields="$pc_fields uc_mcontext.gregs[[R15]]"     # Linux (arm old [untested])
    pc_fields="$pc_fields uc_mcontext.arm_pc"           # Linux (arm arch 5)
    pc_fields="$pc_fields uc_mcontext.gp_regs[[PT_NIP]]"  # Suse SLES 11 (ppc64)
diff --git a/src/base/basictypes.h b/src/base/basictypes.h
index b628709..72c27b4 100644
--- a/src/base/basictypes.h
+++ b/src/base/basictypes.h
@@ -363,7 +363,7 @@ class AssignAttributeStartEnd {
 # elif (defined(__aarch64__))
 #   define CACHELINE_ALIGNED __attribute__((aligned(64)))
     // implementation specific, Cortex-A53 and 57 should have 64 bytes
-# elif (defined(__s390x__))
+# elif (defined(__s390__))
 #   define CACHELINE_ALIGNED __attribute__((aligned(256)))
 # else
 #   error Could not determine cache line length - unknown architecture
diff --git a/src/base/linux_syscall_support.h b/src/base/linux_syscall_support.h
index 5d578cd..235f2ad 100644
--- a/src/base/linux_syscall_support.h
+++ b/src/base/linux_syscall_support.h
@@ -130,12 +130,13 @@
 #ifndef SYS_LINUX_SYSCALL_SUPPORT_H
 #define SYS_LINUX_SYSCALL_SUPPORT_H
 
-/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64, Aarch64 and s390x on Linux.
+/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64, Aarch64, s390 and s390x
+ * on Linux.
  * Porting to other related platforms should not be difficult.
  */
 #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
      defined(__mips__) || defined(__PPC__) || \
-     defined(__aarch64__) || defined(__s390x__)) \
+     defined(__aarch64__) || defined(__s390__)) \
   && (defined(__linux))
 
 #ifndef SYS_CPLUSPLUS
@@ -247,7 +248,8 @@ struct kernel_rusage {
   long               ru_nivcsw;
 };
 
-#if defined(__i386__) || defined(__arm__) || defined(__PPC__)
+#if defined(__i386__) || defined(__arm__) \
+  || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__))
 
 /* include/asm-{arm,i386,mips,ppc}/signal.h                                  */
 struct kernel_old_sigaction {
@@ -261,8 +263,8 @@ struct kernel_old_sigaction {
 } __attribute__((packed,aligned(4)));
 #elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
   #define kernel_old_sigaction kernel_sigaction
-#elif defined(__aarch64__) || defined(__s390x__)
-  // No kernel_old_sigaction defined for arm64 or s390x.
+#elif defined(__aarch64__)
+  // No kernel_old_sigaction defined for arm64.
 #endif
 
 /* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
@@ -306,7 +308,7 @@ struct kernel_sigaction {
 #endif
 };
 
-/* include/asm-{arm,i386,mips,ppc}/stat.h                                    */
+/* include/asm-{arm,i386,mips,ppc,s390}/stat.h                               */
 #ifdef __mips__
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 struct kernel_stat {
@@ -514,6 +516,29 @@ struct kernel_stat {
   long               st_blocks;
   unsigned long      __unused[3];
 };
+#elif defined(__s390__)
+struct kernel_stat {
+  unsigned short     st_dev;
+  unsigned short     __pad1;
+  unsigned long      st_ino;
+  unsigned short     st_mode;
+  unsigned short     st_nlink;
+  unsigned short     st_uid;
+  unsigned short     st_gid;
+  unsigned short     st_rdev;
+  unsigned short     __pad2;
+  unsigned long      st_size;
+  unsigned long      st_blksize;
+  unsigned long      st_blocks;
+  unsigned long      st_atime_;
+  unsigned long      st_atime_nsec_;
+  unsigned long      st_mtime_;
+  unsigned long      st_mtime_nsec_;
+  unsigned long      st_ctime_;
+  unsigned long      st_ctime_nsec_;
+  unsigned long      __unused4;
+  unsigned long      __unused5;
+};
 #endif
 
 
@@ -728,7 +753,7 @@ struct kernel_stat {
 #define __NR_fstatat             79
 #endif
 /* End of aarch64 defininitions                                              */
-#elif defined(__s390x__)
+#elif defined(__s390__)
 #ifndef __NR_quotactl
 #define __NR_quotactl           131
 #endif
@@ -753,27 +778,6 @@ struct kernel_stat {
 #ifndef __NR_pwrite64
 #define __NR_pwrite64           181
 #endif
-#ifndef __NR_getrlimit
-#define __NR_getrlimit          191
-#endif
-#ifndef __NR_setresuid
-#define __NR_setresuid          208
-#endif
-#ifndef __NR_getresuid
-#define __NR_getresuid          209
-#endif
-#ifndef __NR_setresgid
-#define __NR_setresgid          210
-#endif
-#ifndef __NR_getresgid
-#define __NR_getresgid          211
-#endif
-#ifndef __NR_setfsuid
-#define __NR_setfsuid           215
-#endif
-#ifndef __NR_setfsgid
-#define __NR_setfsgid           216
-#endif
 #ifndef __NR_getdents64
 #define __NR_getdents64         220
 #endif
@@ -816,9 +820,6 @@ struct kernel_stat {
 #ifndef __NR_set_tid_address
 #define __NR_set_tid_address    252
 #endif
-#ifndef __NR_fadvise64
-#define __NR_fadvise64          253
-#endif
 #ifndef __NR_clock_gettime
 #define __NR_clock_gettime      260
 #endif
@@ -840,9 +841,6 @@ struct kernel_stat {
 #ifndef __NR_openat
 #define __NR_openat             288
 #endif
-#ifndef __NR_newfstatat
-#define __NR_newfstatat         293
-#endif
 #ifndef __NR_unlinkat
 #define __NR_unlinkat           294
 #endif
@@ -855,7 +853,89 @@ struct kernel_stat {
 #ifndef __NR_fallocate
 #define __NR_fallocate          314
 #endif
-/* End of s390x definitions                                                  */
+/* Some syscalls are named/numbered differently between s390 and s390x. */
+#ifdef __s390x__
+# ifndef __NR_getrlimit
+# define __NR_getrlimit          191
+# endif
+# ifndef __NR_setresuid
+# define __NR_setresuid          208
+# endif
+# ifndef __NR_getresuid
+# define __NR_getresuid          209
+# endif
+# ifndef __NR_setresgid
+# define __NR_setresgid          210
+# endif
+# ifndef __NR_getresgid
+# define __NR_getresgid          211
+# endif
+# ifndef __NR_setfsuid
+# define __NR_setfsuid           215
+# endif
+# ifndef __NR_setfsgid
+# define __NR_setfsgid           216
+# endif
+# ifndef __NR_fadvise64
+# define __NR_fadvise64          253
+# endif
+# ifndef __NR_newfstatat
+# define __NR_newfstatat         293
+# endif
+#else /* __s390x__ */
+# ifndef __NR_getrlimit
+# define __NR_getrlimit          76
+# endif
+# ifndef __NR_setfsuid
+# define __NR_setfsuid           138
+# endif
+# ifndef __NR_setfsgid
+# define __NR_setfsgid           139
+# endif
+# ifndef __NR_setresuid
+# define __NR_setresuid          164
+# endif
+# ifndef __NR_getresuid
+# define __NR_getresuid          165
+# endif
+# ifndef __NR_setresgid
+# define __NR_setresgid          170
+# endif
+# ifndef __NR_getresgid
+# define __NR_getresgid          171
+# endif
+# ifndef __NR_ugetrlimit
+# define __NR_ugetrlimit         191
+# endif
+# ifndef __NR_mmap2
+# define __NR_mmap2              192
+# endif
+# ifndef __NR_setresuid32
+# define __NR_setresuid32        208
+# endif
+# ifndef __NR_getresuid32
+# define __NR_getresuid32        209
+# endif
+# ifndef __NR_setresgid32
+# define __NR_setresgid32        210
+# endif
+# ifndef __NR_getresgid32
+# define __NR_getresgid32        211
+# endif
+# ifndef __NR_setfsuid32
+# define __NR_setfsuid32         215
+# endif
+# ifndef __NR_setfsgid32
+# define __NR_setfsgid32         216
+# endif
+# ifndef __NR_fadvise64_64
+# define __NR_fadvise64_64       264
+# endif
+# ifndef __NR_fstatat64
+# define __NR_fstatat64          293
+# endif
+#endif /* __s390__ */
+/* End of s390/s390x definitions                                             */
 #endif
 
 
@@ -919,7 +999,7 @@ struct kernel_stat {
 
   #undef  LSS_RETURN
   #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) ||        \
-       defined(__aarch64__) || defined(__s390x__))
+       defined(__aarch64__) || defined(__s390__))
   /* Failing system calls return a negative result in the range of
    * -1..-4095. These are "errno" values with the sign inverted.
    */
@@ -2236,19 +2316,20 @@ struct kernel_stat {
       }
       LSS_RETURN(int, __res);
     }
-  #elif defined(__s390x__)
+  #elif defined(__s390__)
     #undef  LSS_REG
     #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a
     #undef  LSS_BODY
     #define LSS_BODY(type, name, args...)                                     \
+        register unsigned long __nr __asm__("r1")                             \
+            = (unsigned long)(__NR_##name);                                   \
         register long __res_r2 __asm__("r2");                                 \
         long __res;                                                           \
         __asm__ __volatile__                                                  \
-            ("lgfi %%r1, %1\n\t"                                              \
-             "svc 0\n\t"                                                      \
-             : "=&r"(__res_r2)                                                \
-             : "i"(__NR_##name), ## args                                      \
-             : "r1", "memory");                                               \
+            ("svc 0\n\t"                                                      \
+             : "=d"(__res_r2)                                                 \
+             : "d"(__nr), ## args                                             \
+             : "memory");                                                     \
         __res = __res_r2;                                                     \
         LSS_RETURN(type, __res)
     #undef _syscall0
@@ -2266,13 +2347,13 @@ struct kernel_stat {
     #define _syscall2(type, name, type1, arg1, type2, arg2)                   \
        type LSS_NAME(name)(type1 arg1, type2 arg2) {                          \
           LSS_REG(2, arg1); LSS_REG(3, arg2);                                 \
-          LSS_BODY(type, name, "0"(__r2), "r"(__r3));                         \
+          LSS_BODY(type, name, "0"(__r2), "d"(__r3));                         \
        }
     #undef _syscall3
     #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \
        type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {              \
           LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
-          LSS_BODY(type, name, "0"(__r2), "r"(__r3), "r"(__r4));              \
+          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4));              \
        }
     #undef _syscall4
     #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \
@@ -2281,8 +2362,8 @@ struct kernel_stat {
                            type4 arg4) {                                      \
           LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
           LSS_REG(5, arg4);                                                   \
-          LSS_BODY(type, name, "0"(__r2), "r"(__r3), "r"(__r4),               \
-                               "r"(__r5));                                    \
+          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
+                               "d"(__r5));                                    \
        }
     #undef _syscall5
     #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \
@@ -2291,8 +2372,8 @@ struct kernel_stat {
                            type4 arg4, type5 arg5) {                          \
           LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
           LSS_REG(5, arg4); LSS_REG(6, arg5);                                 \
-          LSS_BODY(type, name, "0"(__r2), "r"(__r3), "r"(__r4),               \
-                               "r"(__r5), "r"(__r6));                         \
+          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
+                               "d"(__r5), "d"(__r6));                         \
        }
     #undef _syscall6
     #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \
@@ -2301,8 +2382,8 @@ struct kernel_stat {
                            type4 arg4, type5 arg5, type6 arg6) {              \
           LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3);               \
           LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6);               \
-          LSS_BODY(type, name, "0"(__r2), "r"(__r3), "r"(__r4),               \
-                               "r"(__r5), "r"(__r6), "r"(__r7));              \
+          LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4),               \
+                               "d"(__r5), "d"(__r6), "d"(__r7));              \
        }
     LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
                                    int flags, void *arg, int *parent_tidptr,
@@ -2317,6 +2398,27 @@ struct kernel_stat {
         register void  *__newtls         __asm__ ("r6")  = newtls;
         register int   *__ctidptr        __asm__ ("r5")  = child_tidptr;
         __asm__ __volatile__ (
+    #ifndef __s390x__
+                                  /* arg already in r0 */
+          "ltr %4, %4\n\t"        /* check fn, which is already in r1 */
+          "jz 1f\n\t"             /* NULL function pointer, return -EINVAL */
+          "ltr %5, %5\n\t"        /* check child_stack, which is already in r2 */
+          "jz 1f\n\t"             /* NULL stack pointer, return -EINVAL */
+                                  /* flags already in r3 */
+                                  /* parent_tidptr already in r4 */
+                                  /* child_tidptr already in r5 */
+                                  /* newtls already in r6 */
+          "svc %2\n\t"            /* invoke clone syscall */
+          "ltr %0,%%r2\n\t"       /* load return code into __ret and test */
+          "jnz 1f\n\t"            /* return to parent if non-zero */
+                                  /* start child thread */
+          "lr %%r2, %7\n\t"       /* set first parameter to void *arg */
+          "ahi %%r15, -96\n\t"    /* make room on the stack for the save area */
+          "xc 0(4,%%r15), 0(%%r15)\n\t"
+          "basr %%r14, %4\n\t"    /* jump to fn */
+          "svc %3\n"              /* invoke exit syscall */
+          "1:\n"
+    #else
                                   /* arg already in r0 */
           "ltgr %4, %4\n\t"       /* check fn, which is already in r1 */
           "jz 1f\n\t"             /* NULL function pointer, return -EINVAL */
@@ -2335,12 +2437,12 @@ struct kernel_stat {
           "xc 0(8,%%r15), 0(%%r15)\n\t"
           "basr %%r14, %4\n\t"    /* jump to fn */
           "svc %3\n"              /* invoke exit syscall */
-
           "1:\n"
+    #endif
           : "=r" (__ret)
           : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit),
-            "r" (__fn), "r" (__cstack), "r" (__flags), "r" (__arg),
-            "r" (__ptidptr), "r" (__newtls), "r" (__ctidptr)
+            "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg),
+            "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr)
           : "cc", "r14", "memory"
         );
       }
@@ -2429,18 +2531,6 @@ struct kernel_stat {
                          int,                     t, int,       p)
   #endif
   #if defined(__x86_64__) || defined(__s390x__)
-    #if defined(__s390x__)
-    LSS_INLINE _syscall1(void*, mmap, void*, a)
-    #else
-    /* Need to make sure __off64_t isn't truncated to 32-bits under x32.  */
-    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
-                                    __off64_t o) {
-      LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
-                               LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
-                               LSS_SYSCALL_ARG(d), (uint64_t)(o));
-    }
-    #endif
-
     LSS_INLINE int LSS_NAME(sigaction)(int signum,
                                        const struct kernel_sigaction *act,
                                        struct kernel_sigaction *oldact) {
@@ -2458,10 +2548,8 @@ struct kernel_stat {
                                       (KERNEL_NSIG+7)/8);
       } else
       #endif
-      {
         return LSS_NAME(rt_sigaction)(signum, act, oldact,
                                       (KERNEL_NSIG+7)/8);
-      }
     }
 
     LSS_INLINE int LSS_NAME(sigprocmask)(int how,
@@ -2542,26 +2630,30 @@ struct kernel_stat {
     }
   }
 
-  #if defined(__i386__) || \
-      defined(__arm__) || \
-     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__)
+  #if defined(__i386__) ||                                                    \
+      defined(__arm__) ||                                                     \
+     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) ||                   \
+      defined(__PPC__) ||                                                     \
+     (defined(__s390__) && !defined(__s390x__))
     #define __NR__sigaction   __NR_sigaction
     #define __NR__sigprocmask __NR_sigprocmask
     LSS_INLINE _syscall2(int, fstat64,             int, f,
                          struct kernel_stat64 *, b)
     LSS_INLINE _syscall5(int, _llseek,     uint, fd, ulong, hi, ulong, lo,
                          loff_t *, res, uint, wh)
-#ifdef __PPC64__
-    LSS_INLINE _syscall6(void*, mmap,              void*, s,
-                         size_t,                   l, int,               p,
-                         int,                      f, int,               d,
-                         off_t,                    o)
-#else
-    #ifndef __ARM_EABI__
-    /* Not available on ARM EABI Linux.  */
-    LSS_INLINE _syscall1(void*, mmap,              void*, a)
-    #endif
-    LSS_INLINE _syscall6(void*, mmap2,             void*, s,
+#if defined(__s390__) && !defined(__s390x__)
+    /* On s390, mmap2() arguments are passed in memory. */
+    LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d,
+                                      off_t o) {
+      unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
+                               (unsigned long) p, (unsigned long) f,
+                               (unsigned long) d, (unsigned long) o };
+      LSS_REG(2, buf);
+      LSS_BODY(void*, mmap2, "0"(__r2));
+    }
+#elif !defined(__PPC64__)
+    #define __NR__mmap2 __NR_mmap2
+    LSS_INLINE _syscall6(void*, _mmap2,            void*, s,
                          size_t,                   l, int,               p,
                          int,                      f, int,               d,
                          off_t,                    o)
@@ -2654,11 +2746,48 @@ struct kernel_stat {
       return rc;
     }
   #endif
+  #if defined(__i386__) ||                                                    \
+      defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) ||                     \
+     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) ||                   \
+     (defined(__PPC__) && !defined(__PPC64__)) ||                             \
+     (defined(__s390__) && !defined(__s390x__))
+    /* On these architectures, implement mmap() with mmap2(). */
+    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
+                                    int64_t o) {
+      if (o % 4096) {
+        LSS_ERRNO = EINVAL;
+        return (void *) -1;
+      }
+      return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096));
+    }
+  #elif defined(__s390x__)
+    /* On s390x, mmap() arguments are passed in memory. */
+    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
+                                    int64_t o) {
+      unsigned long buf[6] = { (unsigned long) s, (unsigned long) l,
+                               (unsigned long) p, (unsigned long) f,
+                               (unsigned long) d, (unsigned long) o };
+      LSS_REG(2, buf);
+      LSS_BODY(void*, mmap, "0"(__r2));
+    }
+  #elif defined(__x86_64__)
+    /* Need to make sure __off64_t isn't truncated to 32-bits under x32.  */
+    LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
+                                    int64_t o) {
+      LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
+                               LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
+                               LSS_SYSCALL_ARG(d), (uint64_t)(o));
+    }
+  #else
+    /* Remaining 64-bit architectures. */
+    LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot,
+                         int, flags, int, fd, int64_t, offset)
+  #endif
   #if defined(__i386__) || \
       defined(__PPC__) || \
       (defined(__arm__) && !defined(__ARM_EABI__)) || \
       (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \
-      defined(__s390x__)
+      defined(__s390__)
 
     /* See sys_socketcall in net/socket.c in kernel source.
      * It de-multiplexes on its first arg and unpacks the arglist
diff --git a/src/base/linuxthreads.h b/src/base/linuxthreads.h
index b715190..09ce45f 100644
--- a/src/base/linuxthreads.h
+++ b/src/base/linuxthreads.h
@@ -42,7 +42,7 @@
  */
 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
      defined(__mips__) || defined(__PPC__) || defined(__aarch64__) ||       \
-     defined(__s390x__)) && defined(__linux)
+     defined(__s390__)) && defined(__linux)
 
 /* Define the THREADS symbol to make sure that there is exactly one core dumper
  * built into the library.
diff --git a/src/getpc.h b/src/getpc.h
index 25fee39..163873e 100644
--- a/src/getpc.h
+++ b/src/getpc.h
@@ -179,7 +179,12 @@ inline void* GetPC(const struct ucontext_t& signal_ucontext) {
 // configure.ac (or set it manually in your config.h).
 #else
 inline void* GetPC(const ucontext_t& signal_ucontext) {
+#if defined(__s390__) && !defined(__s390x__)
+  // Mask out the AMODE31 bit from the PC recorded in the context.
+  return (void*)((unsigned long)signal_ucontext.PC_FROM_UCONTEXT & 0x7fffffffUL);
+#else
   return (void*)signal_ucontext.PC_FROM_UCONTEXT;   // defined in config.h
+#endif
 }
 
 #endif
diff --git a/src/malloc_hook_mmap_linux.h b/src/malloc_hook_mmap_linux.h
index 1c4c766..4b13861 100755
--- a/src/malloc_hook_mmap_linux.h
+++ b/src/malloc_hook_mmap_linux.h
@@ -52,7 +52,7 @@
 
 // I test for 64-bit first so I don't have to do things like
 // '#if (defined(__mips__) && !defined(__MIPS64__))' as a mips32 check.
-#if defined(__x86_64__) || defined(__PPC64__) || defined(__aarch64__) || (defined(_MIPS_SIM) && _MIPS_SIM == _ABI64)
+#if defined(__x86_64__) || defined(__PPC64__) || defined(__aarch64__) || (defined(_MIPS_SIM) && _MIPS_SIM == _ABI64) || defined(__s390__)
 
 static inline void* do_mmap64(void *start, size_t length,
                               int prot, int flags,
@@ -119,20 +119,6 @@ static inline void* do_mmap64(void *start, size_t length,
 
 #define MALLOC_HOOK_HAVE_DO_MMAP64 1
 
-#elif defined(__s390x__)
-
-static inline void* do_mmap64(void *start, size_t length,
-                              int prot, int flags,
-                              int fd, __off64_t offset) __THROW {
-  // mmap on s390x uses the old syscall interface
-  unsigned long args[6] = { (unsigned long) start, (unsigned long) length,
-                            (unsigned long) prot, (unsigned long) flags,
-                            (unsigned long) fd, (unsigned long) offset };
-  return sys_mmap(args);
-}
-
-#define MALLOC_HOOK_HAVE_DO_MMAP64 1
-
 #endif  // #if defined(__x86_64__)
 
 
openSUSE Build Service is sponsored by