]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Internal TLS support for aarch64, x86_64, riscv, ppc64, and s390x
authorKevin Buettner <kevinb@redhat.com>
Thu, 24 Apr 2025 04:39:29 +0000 (21:39 -0700)
committerKevin Buettner <kevinb@redhat.com>
Thu, 24 Apr 2025 16:54:42 +0000 (09:54 -0700)
For each architecture, aarch64, x86_64, riscv, ppc64, and s390x,
this commit defines a suitable 'get_tls_dtv_addr' method and,
when necessary, a 'get_tls_dtp_offset' method.

It also registers svr4_tls_get_thread_local_address, defined in
svr4-tls-tdep.c (in an earlier commit), as the
get_thread_local_address gdbarch method.  It also registers its
architecture specific code using svr4_tls_register_tls_methods().

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24548
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31563

Tested-By: Luis Machado <luis.machado@arm.com>
Approved-By: Luis Machado <luis.machado@arm.com>
gdb/aarch64-linux-tdep.c
gdb/amd64-linux-tdep.c
gdb/configure.tgt
gdb/ppc-linux-tdep.c
gdb/riscv-linux-tdep.c
gdb/s390-linux-tdep.c

index 9cee35541875b808d6d51ccc51ed34bd59b5a678..b6cdcf03072ecf13c0d1ffff59c7607a0deb5251 100644 (file)
@@ -24,6 +24,7 @@
 #include "gdbarch.h"
 #include "glibc-tdep.h"
 #include "linux-tdep.h"
+#include "svr4-tls-tdep.h"
 #include "aarch64-tdep.h"
 #include "aarch64-linux-tdep.h"
 #include "osabi.h"
@@ -35,6 +36,7 @@
 #include "target/target.h"
 #include "expop.h"
 #include "auxv.h"
+#include "inferior.h"
 
 #include "regcache.h"
 #include "regset.h"
@@ -2701,6 +2703,57 @@ aarch64_use_target_description_from_corefile_notes (gdbarch *gdbarch,
   return true;
 }
 
+/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID.
+   Throw a suitable TLS error if something goes wrong.  */
+
+static CORE_ADDR
+aarch64_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid,
+                               svr4_tls_libc libc)
+{
+  /* On aarch64, the thread pointer is found in the TPIDR register.
+     Note that this is the first register in the TLS feature - see
+     features/aarch64-tls.c - and it will always be present.  */
+  regcache *regcache
+    = get_thread_arch_regcache (current_inferior (), ptid, gdbarch);
+  aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
+  target_fetch_registers (regcache, tdep->tls_regnum_base);
+  ULONGEST thr_ptr;
+  if (regcache->cooked_read (tdep->tls_regnum_base, &thr_ptr) != REG_VALID)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer"));
+
+  CORE_ADDR dtv_ptr_addr;
+  switch (libc)
+    {
+    case svr4_tls_libc_musl:
+      /* MUSL: The DTV pointer is found at the very end of the pthread
+        struct which is located *before* the thread pointer.  I.e.
+        the thread pointer will be just beyond the end of the struct,
+        so the address of the DTV pointer is found one pointer-size
+        before the thread pointer.  */
+      dtv_ptr_addr = thr_ptr - (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+      break;
+    case svr4_tls_libc_glibc:
+      /* GLIBC: The thread pointer (tpidr) points at the TCB (thread control
+        block).  On aarch64, this struct (tcbhead_t) is defined to
+        contain two pointers.  The first is a pointer to the DTV and
+        the second is a pointer to private data.  So the DTV pointer
+        address is the same as the thread pointer.  */
+      dtv_ptr_addr = thr_ptr;
+      break;
+    default:
+      throw_error (TLS_GENERIC_ERROR, _("Unknown aarch64 C library"));
+      break;
+    }
+  gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+  if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address"));
+
+  const struct builtin_type *builtin = builtin_type (gdbarch);
+  CORE_ADDR dtv_addr = gdbarch_pointer_to_address
+                        (gdbarch, builtin->builtin_data_ptr, buf.data ());
+  return dtv_addr;
+}
+
 static void
 aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -2722,6 +2775,9 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
+  set_gdbarch_get_thread_local_address (gdbarch,
+                                       svr4_tls_get_thread_local_address);
+  svr4_tls_register_tls_methods (info, gdbarch, aarch64_linux_get_tls_dtv_addr);
 
   /* Shared library handling.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
index 494e744bd1ce4b311abfda9f56cc326fa827850d..e5a2ab9dd5265520d372b96e62a86c3c294332e2 100644 (file)
@@ -33,7 +33,9 @@
 #include "amd64-linux-tdep.h"
 #include "i386-linux-tdep.h"
 #include "linux-tdep.h"
+#include "svr4-tls-tdep.h"
 #include "gdbsupport/x86-xstate.h"
+#include "inferior.h"
 
 #include "amd64-tdep.h"
 #include "solib-svr4.h"
@@ -1832,6 +1834,39 @@ amd64_linux_remove_non_address_bits_watchpoint (gdbarch *gdbarch,
   return (addr & amd64_linux_lam_untag_mask ());
 }
 
+/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID.
+   Throw a suitable TLS error if something goes wrong.  */
+
+static CORE_ADDR
+amd64_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid,
+                             enum svr4_tls_libc libc)
+{
+  /* On x86-64, the thread pointer is found in the fsbase register.  */
+  regcache *regcache
+    = get_thread_arch_regcache (current_inferior (), ptid, gdbarch);
+  target_fetch_registers (regcache, AMD64_FSBASE_REGNUM);
+  ULONGEST fsbase;
+  if (regcache->cooked_read (AMD64_FSBASE_REGNUM, &fsbase) != REG_VALID)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer"));
+
+  /* The thread pointer (fsbase) points at the TCB (thread control
+     block).  The first two members of this struct are both pointers,
+     where the first will be a pointer to the TCB (i.e. it points at
+     itself) and the second will be a pointer to the DTV (dynamic
+     thread vector).  There are many other fields too, but the one
+     we care about here is the DTV pointer.  Compute the address
+     of the DTV pointer, fetch it, and convert it to an address.  */
+  CORE_ADDR dtv_ptr_addr = fsbase + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+  gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+  if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address"));
+
+  const struct builtin_type *builtin = builtin_type (gdbarch);
+  CORE_ADDR dtv_addr = gdbarch_pointer_to_address
+                        (gdbarch, builtin->builtin_data_ptr, buf.data ());
+  return dtv_addr;
+}
+
 static void
 amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch,
                            int num_disp_step_buffers)
@@ -1862,6 +1897,9 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch,
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
+  set_gdbarch_get_thread_local_address (gdbarch,
+                                       svr4_tls_get_thread_local_address);
+  svr4_tls_register_tls_methods (info, gdbarch, amd64_linux_get_tls_dtv_addr);
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
index 44da2257be85ab7d05b6d233d52fda3042634a26..72cdceeaed97b980a171009282612625192495ba 100644 (file)
@@ -150,7 +150,7 @@ aarch64*-*-linux*)
                        arch/aarch64-scalable-linux.o \
                        arch/arm.o arch/arm-linux.o arch/arm-get-next-pcs.o \
                        arm-tdep.o arm-linux-tdep.o \
-                       glibc-tdep.o linux-tdep.o solib-svr4.o \
+                       glibc-tdep.o linux-tdep.o solib-svr4.o svr4-tls-tdep.o \
                        symfile-mem.o linux-record.o"
        ;;
 
@@ -503,7 +503,7 @@ powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
 powerpc*-*-linux*)
        # Target: PowerPC running Linux
        gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
-                       ppc64-tdep.o solib-svr4.o \
+                       ppc64-tdep.o solib-svr4.o svr4-tls-tdep.o \
                        glibc-tdep.o symfile-mem.o linux-tdep.o \
                        ravenscar-thread.o ppc-ravenscar-thread.o \
                        linux-record.o \
@@ -524,7 +524,8 @@ powerpc*-*-*)
 s390*-*-linux*)
        # Target: S390 running Linux
        gdb_target_obs="s390-linux-tdep.o s390-tdep.o solib-svr4.o \
-                       linux-tdep.o linux-record.o symfile-mem.o"
+                       linux-tdep.o linux-record.o symfile-mem.o \
+                       svr4-tls-tdep.o"
        ;;
 
 riscv*-*-freebsd*)
@@ -536,7 +537,7 @@ riscv*-*-linux*)
        # Target: Linux/RISC-V
        gdb_target_obs="riscv-linux-tdep.o riscv-canonicalize-syscall-gen.o \
                        glibc-tdep.o linux-tdep.o solib-svr4.o symfile-mem.o \
-                       linux-record.o"
+                       linux-record.o svr4-tls-tdep.o"
        ;;
 
 riscv*-*-*)
@@ -706,7 +707,7 @@ x86_64-*-elf*)
 x86_64-*-linux*)
        # Target: GNU/Linux x86-64
        gdb_target_obs="amd64-linux-tdep.o ${i386_tobjs}  \
-                       i386-linux-tdep.o glibc-tdep.o \
+                       i386-linux-tdep.o glibc-tdep.o svr4-tls-tdep.o \
                        solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o \
                        arch/i386-linux-tdesc.o arch/amd64-linux-tdesc.o \
                        arch/x86-linux-tdesc-features.o"
index 3050a9e217769d9517f63687ed71c1559b95eaba..441f31767510d3d64f6dba03464411e89b97e50e 100644 (file)
@@ -49,6 +49,7 @@
 #include "arch-utils.h"
 #include "xml-syscall.h"
 #include "linux-tdep.h"
+#include "svr4-tls-tdep.h"
 #include "linux-record.h"
 #include "record-full.h"
 #include "infrun.h"
@@ -2071,6 +2072,63 @@ ppc64_linux_gcc_target_options (struct gdbarch *gdbarch)
   return "";
 }
 
+/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID.
+   Throw a suitable TLS error if something goes wrong.  */
+
+static CORE_ADDR
+ppc64_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid,
+                             enum svr4_tls_libc libc)
+{
+  /* On ppc64, the thread pointer is found in r13.  Fetch this
+     register.  */
+  regcache *regcache
+    = get_thread_arch_regcache (current_inferior (), ptid, gdbarch);
+  int thread_pointer_regnum = PPC_R0_REGNUM + 13;
+  target_fetch_registers (regcache, thread_pointer_regnum);
+  ULONGEST thr_ptr;
+  if (regcache->cooked_read (thread_pointer_regnum, &thr_ptr) != REG_VALID)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer"));
+
+  /* The thread pointer (r13) is an address that is 0x7000 ahead of
+     the *end* of the TCB (thread control block).  The field
+     holding the DTV address is at the very end of the TCB.
+     Therefore, the DTV pointer address can be found by
+     subtracting (0x7000+8) from the thread pointer.  Compute the
+     address of the DTV pointer, fetch it, and convert it to an
+     address.  */
+  CORE_ADDR dtv_ptr_addr = thr_ptr - 0x7000 - 8;
+  gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+  if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address"));
+
+  const struct builtin_type *builtin = builtin_type (gdbarch);
+  CORE_ADDR dtv_addr = gdbarch_pointer_to_address
+                        (gdbarch, builtin->builtin_data_ptr, buf.data ());
+  return dtv_addr;
+}
+
+/* For internal TLS lookup, return the DTP offset, which is the offset
+   to subtract from a DTV entry, in order to obtain the address of the
+   TLS block.  */
+
+static ULONGEST
+ppc_linux_get_tls_dtp_offset (struct gdbarch *gdbarch, ptid_t ptid,
+                             svr4_tls_libc libc)
+{
+  if (libc == svr4_tls_libc_musl)
+    {
+      /* This value is DTP_OFFSET, which represents the value to
+        subtract from the DTV entry.  For PPC, it can be found in
+        MUSL's arch/powerpc64/pthread_arch.h and
+        arch/powerpc32/pthread_arch.h.  (Both values are the same.)
+        It represents the value to subtract from the DTV entry, once
+        it has been fetched from the DTV array.  */
+      return 0x8000;
+    }
+  else
+    return 0;
+}
+
 static displaced_step_prepare_status
 ppc_linux_displaced_step_prepare  (gdbarch *arch, thread_info *thread,
                                   CORE_ADDR &displaced_pc)
@@ -2284,6 +2342,11 @@ ppc_linux_init_abi (struct gdbarch_info info,
        set_gdbarch_gnu_triplet_regexp (gdbarch, ppc64_gnu_triplet_regexp);
       /* Set GCC target options.  */
       set_gdbarch_gcc_target_options (gdbarch, ppc64_linux_gcc_target_options);
+      /* Internal thread local address support.  */
+      set_gdbarch_get_thread_local_address (gdbarch,
+                                           svr4_tls_get_thread_local_address);
+      svr4_tls_register_tls_methods (info, gdbarch, ppc64_linux_get_tls_dtv_addr,
+                                    ppc_linux_get_tls_dtp_offset);
     }
 
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
index f21039a613c037a4ae086e6c658ea13cfc007c2a..e1ea6158a45c4a15311ff8f5fa31400d60c9c3b0 100644 (file)
@@ -20,6 +20,7 @@
 #include "osabi.h"
 #include "glibc-tdep.h"
 #include "linux-tdep.h"
+#include "svr4-tls-tdep.h"
 #include "solib-svr4.h"
 #include "regset.h"
 #include "tramp-frame.h"
@@ -28,6 +29,7 @@
 #include "record-full.h"
 #include "linux-record.h"
 #include "riscv-linux-tdep.h"
+#include "inferior.h"
 
 extern unsigned int record_debug;
 
@@ -426,6 +428,79 @@ riscv64_linux_record_tdep_init (struct gdbarch *gdbarch,
   riscv_linux_record_tdep.arg6 = RISCV_A5_REGNUM;
 }
 
+/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID.
+   Throw a suitable TLS error if something goes wrong.  */
+
+static CORE_ADDR
+riscv_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid,
+                             svr4_tls_libc libc)
+{
+  /* On RISC-V, the thread pointer is found in TP.  */
+  regcache *regcache
+    = get_thread_arch_regcache (current_inferior (), ptid, gdbarch);
+  int thread_pointer_regnum = RISCV_TP_REGNUM;
+  target_fetch_registers (regcache, thread_pointer_regnum);
+  ULONGEST thr_ptr;
+  if (regcache->cooked_read (thread_pointer_regnum, &thr_ptr) != REG_VALID)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer"));
+
+  CORE_ADDR dtv_ptr_addr;
+  switch (libc)
+    {
+      case svr4_tls_libc_musl:
+       /* MUSL: The DTV pointer is found at the very end of the pthread
+          struct which is located *before* the thread pointer.  I.e.
+          the thread pointer will be just beyond the end of the struct,
+          so the address of the DTV pointer is found one pointer-size
+          before the thread pointer.  */
+       dtv_ptr_addr
+         = thr_ptr - (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+       break;
+      case svr4_tls_libc_glibc:
+       /* GLIBC:  The thread pointer (TP) points just beyond the end of
+          the TCB (thread control block).  On RISC-V, this struct
+          (tcbhead_t) is defined to contain two pointers.  The first is
+          a pointer to the DTV and the second is a pointer to private
+          data.  So the DTV pointer address is 16 bytes (i.e. the size of
+          two pointers) before thread pointer.  */
+
+       dtv_ptr_addr
+         = thr_ptr - 2 * (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+       break;
+      default:
+       throw_error (TLS_GENERIC_ERROR, _("Unknown RISC-V C library"));
+       break;
+    }
+
+  gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+  if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address"));
+
+  const struct builtin_type *builtin = builtin_type (gdbarch);
+  CORE_ADDR dtv_addr = gdbarch_pointer_to_address
+                        (gdbarch, builtin->builtin_data_ptr, buf.data ());
+  return dtv_addr;
+}
+
+/* For internal TLS lookup, return the DTP offset, which is the offset
+   to subtract from a DTV entry, in order to obtain the address of the
+   TLS block.  */
+
+static ULONGEST
+riscv_linux_get_tls_dtp_offset (struct gdbarch *gdbarch, ptid_t ptid,
+                               svr4_tls_libc libc)
+{
+  if (libc == svr4_tls_libc_musl)
+    {
+      /* This value is DTP_OFFSET in MUSL's arch/riscv64/pthread_arch.h.
+        It represents the value to subtract from the DTV entry, once
+        it has been loaded.  */
+      return 0x800;
+    }
+  else
+    return 0;
+}
+
 /* Initialize RISC-V Linux ABI info.  */
 
 static void
@@ -451,6 +526,10 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
+  set_gdbarch_get_thread_local_address (gdbarch,
+                                       svr4_tls_get_thread_local_address);
+  svr4_tls_register_tls_methods (info, gdbarch, riscv_linux_get_tls_dtv_addr,
+                                riscv_linux_get_tls_dtp_offset);
 
   set_gdbarch_iterate_over_regset_sections
     (gdbarch, riscv_linux_iterate_over_regset_sections);
index 04c523b979bb0e3b169d11db19a07875fd887274..bd1f42ca8d25c53f82a28baccb51c55d1482a60d 100644 (file)
@@ -29,6 +29,7 @@
 #include "gdbcore.h"
 #include "linux-record.h"
 #include "linux-tdep.h"
+#include "svr4-tls-tdep.h"
 #include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
@@ -40,6 +41,7 @@
 #include "target.h"
 #include "trad-frame.h"
 #include "xml-syscall.h"
+#include "inferior.h"
 
 #include "features/s390-linux32v1.c"
 #include "features/s390-linux32v2.c"
@@ -1124,6 +1126,45 @@ s390_init_linux_record_tdep (struct linux_record_tdep *record_tdep,
   record_tdep->ioctl_FIOQSIZE = 0x545e;
 }
 
+/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID.
+   Throw a suitable TLS error if something goes wrong.  */
+
+static CORE_ADDR
+s390_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid,
+                            enum svr4_tls_libc libc)
+{
+  /* On S390, the thread pointer is found in two registers A0 and A1
+     (or, using gdb naming, acr0 and acr1) A0 contains the top 32
+     bits of the address and A1 contains the bottom 32 bits.  */
+  regcache *regcache
+    = get_thread_arch_regcache (current_inferior (), ptid, gdbarch);
+  target_fetch_registers (regcache, S390_A0_REGNUM);
+  target_fetch_registers (regcache, S390_A1_REGNUM);
+  ULONGEST thr_ptr_lo, thr_ptr_hi, thr_ptr;
+  if (regcache->cooked_read (S390_A0_REGNUM, &thr_ptr_hi) != REG_VALID
+      || regcache->cooked_read (S390_A1_REGNUM, &thr_ptr_lo) != REG_VALID)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer"));
+  thr_ptr = (thr_ptr_hi << 32) + thr_ptr_lo;
+
+  /* The thread pointer points at the TCB (thread control block).  The
+     first two members of this struct are both pointers, where the
+     first will be a pointer to the TCB (i.e.  it points at itself)
+     and the second will be a pointer to the DTV (dynamic thread
+     vector).  There are many other fields too, but the one we care
+     about here is the DTV pointer.  Compute the address of the DTV
+     pointer, fetch it, and convert it to an address.  */
+  CORE_ADDR dtv_ptr_addr
+    = thr_ptr + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+  gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+  if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0)
+    throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address"));
+
+  const struct builtin_type *builtin = builtin_type (gdbarch);
+  CORE_ADDR dtv_addr = gdbarch_pointer_to_address
+                        (gdbarch, builtin->builtin_data_ptr, buf.data ());
+  return dtv_addr;
+}
+
 /* Initialize OSABI common for GNU/Linux on 31- and 64-bit systems.  */
 
 static void
@@ -1152,6 +1193,9 @@ s390_linux_init_abi_any (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
+  set_gdbarch_get_thread_local_address (gdbarch,
+                                       svr4_tls_get_thread_local_address);
+  svr4_tls_register_tls_methods (info, gdbarch, s390_linux_get_tls_dtv_addr);
 
   /* Support reverse debugging.  */
   set_gdbarch_process_record_signal (gdbarch, s390_linux_record_signal);