[PATCH 5/8] gdbserver: Move target description from being per-process to being per-thread

Thiago Jung Bauermann thiago.bauermann@linaro.org
Thu Sep 8 06:41:48 GMT 2022


This change allows aarch64-linux to support debugging programs where
different threads have different SVE vector length.  This requires gdbserver
to support different inferior threads having different target descriptions.

After this change, all targets except aarch64-linux will still use one
target description for all threads in the inferior process (their tdesc
member in struct thread_info will point to the same target description).
This is done by linux_process_target::handle_extended_wait which copies the
target description from the original thread to the new thread if
low_new_thread doesn't provide one.

In the case of aarch64-linux, the low_new_thread method probes the thread's
architecture features and assigns a description to it.
---
 gdbserver/gdbthread.h            |  2 ++
 gdbserver/inferiors.h            |  2 --
 gdbserver/linux-aarch64-low.cc   | 48 ++++++++++++++++++++++++++++++--
 gdbserver/linux-arc-low.cc       |  6 ++--
 gdbserver/linux-arm-low.cc       |  4 +--
 gdbserver/linux-ia64-low.cc      |  2 +-
 gdbserver/linux-loongarch-low.cc |  2 +-
 gdbserver/linux-low.cc           | 24 ++++++++++------
 gdbserver/linux-m68k-low.cc      |  2 +-
 gdbserver/linux-mips-low.cc      |  8 +++---
 gdbserver/linux-nios2-low.cc     |  2 +-
 gdbserver/linux-or1k-low.cc      |  2 +-
 gdbserver/linux-ppc-low.cc       | 10 +++----
 gdbserver/linux-riscv-low.cc     |  2 +-
 gdbserver/linux-s390-low.cc      |  4 +--
 gdbserver/linux-sh-low.cc        |  2 +-
 gdbserver/linux-sparc-low.cc     |  2 +-
 gdbserver/linux-tic6x-low.cc     |  2 +-
 gdbserver/linux-x86-low.cc       |  2 +-
 gdbserver/linux-xtensa-low.cc    |  2 +-
 gdbserver/netbsd-aarch64-low.cc  |  2 +-
 gdbserver/netbsd-amd64-low.cc    |  2 +-
 gdbserver/netbsd-i386-low.cc     |  2 +-
 gdbserver/regcache.cc            |  6 ++--
 gdbserver/tdesc.cc               |  2 +-
 25 files changed, 95 insertions(+), 49 deletions(-)

diff --git a/gdbserver/gdbthread.h b/gdbserver/gdbthread.h
index 8b897e73d33b..47b44d03b8e0 100644
--- a/gdbserver/gdbthread.h
+++ b/gdbserver/gdbthread.h
@@ -80,6 +80,8 @@ struct thread_info
 
   /* Branch trace target information for this thread.  */
   struct btrace_target_info *btrace = nullptr;
+
+  const struct target_desc *tdesc = nullptr;
 };
 
 extern std::list<thread_info *> all_threads;
diff --git a/gdbserver/inferiors.h b/gdbserver/inferiors.h
index 6de746cb228f..cdb39dd90d54 100644
--- a/gdbserver/inferiors.h
+++ b/gdbserver/inferiors.h
@@ -65,8 +65,6 @@ struct process_info
      for unfiltered syscall reporting.  */
   std::vector<int> syscalls_to_catch;
 
-  const struct target_desc *tdesc = NULL;
-
   /* Private target data.  */
   struct process_info_private *priv = NULL;
 
diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc
index 9b57be73818e..8c4306ab8794 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -191,9 +191,26 @@ struct arch_process_info
 static int
 is_64bit_tdesc (void)
 {
+  const target_desc *tdesc;
+
+  if (current_thread && current_thread->tdesc)
+    tdesc = current_thread->tdesc;
+  else
+    {
+      /* Find some thread that has a target description.  */
+      const struct thread_info *thread
+	  = find_thread (current_process ()->pid, [] (thread_info *thr) {
+	      return thr->tdesc != nullptr;
+	    });
+
+      gdb_assert (thread != nullptr);
+
+      tdesc = thread->tdesc;
+    }
+
   /* We may not have a current thread at this point, so go straight to
      the process's target description.  */
-  return register_size (current_process ()->tdesc, 0) == 8;
+  return register_size (tdesc, 0) == 8;
 }
 
 static void
@@ -678,6 +695,31 @@ void
 aarch64_target::low_new_thread (lwp_info *lwp)
 {
   aarch64_linux_new_thread (lwp);
+
+  ptid_t ptid = ptid_of_lwp (lwp);
+  process_info *proc = find_process_pid (ptid.pid ());
+
+  /* If the inferior is still going through the shell or the thread isn't
+     stopped we can't read its registers in order to read the target
+     description.  */
+  if (proc->starting_up)
+    return;
+
+  thread_info *thread = get_lwp_thread (lwp);
+  unsigned int machine;
+  gdb_assert (ptid.lwp_p ());
+  bool is_elf64 = linux_pid_exe_is_elf_64_file (ptid.lwp (), &machine);
+
+  if (is_elf64)
+    {
+      gdb::optional<struct aarch64_features> features
+	  = aarch64_get_arch_features (thread);
+
+      if (features.has_value())
+	thread->tdesc = aarch64_linux_read_description (*features);
+    }
+  else
+    thread->tdesc = aarch32_linux_read_description ();
 }
 
 void
@@ -848,14 +890,14 @@ aarch64_target::low_arch_setup ()
 	 succeeds so all we can do here is assert that features is valid.  */
       gdb_assert (features.has_value ());
 
-      current_process ()->tdesc = aarch64_linux_read_description (*features);
+      current_thread->tdesc = aarch64_linux_read_description (*features);
 
       /* Adjust the register sets we should use for this particular set of
 	 features.  */
       aarch64_adjust_register_sets (*features);
     }
   else
-    current_process ()->tdesc = aarch32_linux_read_description ();
+    current_thread->tdesc = aarch32_linux_read_description ();
 
   aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread));
 }
diff --git a/gdbserver/linux-arc-low.cc b/gdbserver/linux-arc-low.cc
index fee1dd33eb20..1727bdede452 100644
--- a/gdbserver/linux-arc-low.cc
+++ b/gdbserver/linux-arc-low.cc
@@ -123,19 +123,19 @@ arc_linux_read_description (void)
 void
 arc_target::low_arch_setup ()
 {
-  current_process ()->tdesc = arc_linux_read_description ();
+  current_thread->tdesc = arc_linux_read_description ();
 }
 
 bool
 arc_target::low_cannot_fetch_register (int regno)
 {
-  return (regno >= current_process ()->tdesc->reg_defs.size ());
+  return (regno >= current_thread->tdesc->reg_defs.size ());
 }
 
 bool
 arc_target::low_cannot_store_register (int regno)
 {
-  return (regno >= current_process ()->tdesc->reg_defs.size ());
+  return (regno >= current_thread->tdesc->reg_defs.size ());
 }
 
 /* This works for both endianness.  Below you see an illustration of how
diff --git a/gdbserver/linux-arm-low.cc b/gdbserver/linux-arm-low.cc
index d40ce412fe1c..5f52e061bcf6 100644
--- a/gdbserver/linux-arm-low.cc
+++ b/gdbserver/linux-arm-low.cc
@@ -998,7 +998,7 @@ arm_target::low_arch_setup ()
   /* Query hardware watchpoint/breakpoint capabilities.  */
   arm_linux_init_hwbp_cap (tid);
 
-  current_process ()->tdesc = arm_read_description ();
+  current_thread->tdesc = arm_read_description ();
 
   iov.iov_base = gpregs;
   iov.iov_len = sizeof (gpregs);
@@ -1118,7 +1118,7 @@ static struct regs_info regs_info_arm =
 const regs_info *
 arm_target::get_regs_info ()
 {
-  const struct target_desc *tdesc = current_process ()->tdesc;
+  const struct target_desc *tdesc = current_thread->tdesc;
 
   if (have_ptrace_getregset == 1
       && (is_aarch32_linux_description (tdesc)
diff --git a/gdbserver/linux-ia64-low.cc b/gdbserver/linux-ia64-low.cc
index 4530a283b376..3095038fc50e 100644
--- a/gdbserver/linux-ia64-low.cc
+++ b/gdbserver/linux-ia64-low.cc
@@ -382,7 +382,7 @@ ia64_target::get_regs_info ()
 void
 ia64_target::low_arch_setup ()
 {
-  current_process ()->tdesc = tdesc_ia64;
+  current_thread->tdesc = tdesc_ia64;
 }
 
 /* The linux target ops object.  */
diff --git a/gdbserver/linux-loongarch-low.cc b/gdbserver/linux-loongarch-low.cc
index cccf1ba780b3..50cca5b2da10 100644
--- a/gdbserver/linux-loongarch-low.cc
+++ b/gdbserver/linux-loongarch-low.cc
@@ -86,7 +86,7 @@ loongarch_target::low_arch_setup ()
 
   if (!tdesc->expedite_regs)
     init_target_desc (tdesc.get (), expedite_regs);
-  current_process ()->tdesc = tdesc.release ();
+  current_thread->tdesc = tdesc.release ();
 }
 
 /* Collect GPRs from REGCACHE into BUF.  */
diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc
index 9034a1d8fabe..d37eb120e114 100644
--- a/gdbserver/linux-low.cc
+++ b/gdbserver/linux-low.cc
@@ -585,8 +585,8 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
 	  clone_all_breakpoints (child_thr, event_thr);
 
 	  target_desc_up tdesc = allocate_target_description ();
-	  copy_target_description (tdesc.get (), parent_proc->tdesc);
-	  child_proc->tdesc = tdesc.release ();
+	  copy_target_description (tdesc.get (), event_thr->tdesc);
+	  child_thr->tdesc = tdesc.release ();
 
 	  /* Clone arch-specific process data.  */
 	  low_new_fork (parent_proc, child_proc);
@@ -642,6 +642,11 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
 	 before calling resume_one_lwp.  */
       new_lwp->stopped = 1;
 
+      /* If low_new_thread () wasn't able to set the target description, copy
+	 it from the original thread.  */
+      if (new_lwp->thread->tdesc == nullptr)
+	new_lwp->thread->tdesc = event_thr->tdesc;
+
       /* If we're suspending all threads, leave this one suspended
 	 too.  If the fork/clone parent is stepping over a breakpoint,
 	 all other threads have been suspended already.  Leave the
@@ -1209,7 +1214,7 @@ linux_process_target::attach (unsigned long pid)
 
       async_file_mark ();
 
-      gdb_assert (proc->tdesc != NULL);
+      gdb_assert (initial_thread->tdesc != NULL);
     }
 
   return 0;
@@ -2330,7 +2335,7 @@ linux_process_target::filter_event (int lwpid, int wstat)
 
       /* Architecture-specific setup after inferior is running.  */
       proc = find_process_pid (pid_of (thread));
-      if (proc->tdesc == NULL)
+      if (thread->tdesc == NULL || proc->starting_up)
 	{
 	  if (proc->attached)
 	    {
@@ -3966,14 +3971,13 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
 {
   struct thread_info *thread = get_lwp_thread (lwp);
   int ptrace_request;
-  struct process_info *proc = get_thread_process (thread);
 
   /* Note that target description may not be initialised
-     (proc->tdesc == NULL) at this point because the program hasn't
+     (thread->tdesc == NULL) at this point because the program hasn't
      stopped at the first instruction yet.  It means GDBserver skips
      the extra traps from the wrapper program (see option --wrapper).
      Code in this function that requires register access should be
-     guarded by proc->tdesc == NULL or something else.  */
+     guarded by thread->tdesc == NULL or something else.  */
 
   if (lwp->stopped == 0)
     return;
@@ -4090,7 +4094,9 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
       step = single_step (lwp);
     }
 
-  if (proc->tdesc != NULL && low_supports_breakpoints ())
+  process_info *proc = find_process_pid(thread->id.pid());
+
+  if (!proc->starting_up && low_supports_breakpoints ())
     {
       struct regcache *regcache = get_thread_regcache (current_thread, 1);
 
@@ -4349,7 +4355,7 @@ linux_process_target::thread_needs_step_over (thread_info *thread)
 
   /* GDBserver is skipping the extra traps from the wrapper program,
      don't have to do step over.  */
-  if (proc->tdesc == NULL)
+  if (proc->starting_up)
     return false;
 
   /* LWPs which will not be resumed are not interesting, because we
diff --git a/gdbserver/linux-m68k-low.cc b/gdbserver/linux-m68k-low.cc
index 7a433ffab5ef..5b17e21c5258 100644
--- a/gdbserver/linux-m68k-low.cc
+++ b/gdbserver/linux-m68k-low.cc
@@ -253,7 +253,7 @@ m68k_target::get_regs_info ()
 void
 m68k_target::low_arch_setup ()
 {
-  current_process ()->tdesc = tdesc_m68k;
+  current_thread->tdesc = tdesc_m68k;
 }
 
 /* The linux target ops object.  */
diff --git a/gdbserver/linux-mips-low.cc b/gdbserver/linux-mips-low.cc
index e72403bd91cb..6d9d110e412c 100644
--- a/gdbserver/linux-mips-low.cc
+++ b/gdbserver/linux-mips-low.cc
@@ -213,7 +213,7 @@ mips_read_description (void)
 void
 mips_target::low_arch_setup ()
 {
-  current_process ()->tdesc = mips_read_description ();
+  current_thread->tdesc = mips_read_description ();
 }
 
 /* Per-process arch-specific data we want to keep.  */
@@ -264,7 +264,7 @@ mips_target::low_cannot_fetch_register (int regno)
   if (get_regs_info ()->usrregs->regmap[regno] == -1)
     return true;
 
-  tdesc = current_process ()->tdesc;
+  tdesc = current_thread->tdesc;
 
   /* On n32 we can't access 64-bit registers via PTRACE_PEEKUSR.  */
   if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE))
@@ -284,7 +284,7 @@ mips_target::low_cannot_store_register (int regno)
   if (get_regs_info ()->usrregs->regmap[regno] == -1)
     return true;
 
-  tdesc = current_process ()->tdesc;
+  tdesc = current_thread->tdesc;
 
   /* On n32 we can't access 64-bit registers via PTRACE_POKEUSR.  */
   if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE))
@@ -308,7 +308,7 @@ mips_target::low_cannot_store_register (int regno)
 bool
 mips_target::low_fetch_register (regcache *regcache, int regno)
 {
-  const struct target_desc *tdesc = current_process ()->tdesc;
+  const struct target_desc *tdesc = current_thread->tdesc;
 
   if (find_regno (tdesc, "r0") == regno)
     {
diff --git a/gdbserver/linux-nios2-low.cc b/gdbserver/linux-nios2-low.cc
index e850fcfc1efc..675305f0de51 100644
--- a/gdbserver/linux-nios2-low.cc
+++ b/gdbserver/linux-nios2-low.cc
@@ -119,7 +119,7 @@ static int nios2_regmap[] = {
 void
 nios2_target::low_arch_setup ()
 {
-  current_process ()->tdesc = tdesc_nios2_linux;
+  current_thread->tdesc = tdesc_nios2_linux;
 }
 
 /* Implement the low_cannot_fetch_register linux target ops method.  */
diff --git a/gdbserver/linux-or1k-low.cc b/gdbserver/linux-or1k-low.cc
index 4c6d69496fb2..0288d634367e 100644
--- a/gdbserver/linux-or1k-low.cc
+++ b/gdbserver/linux-or1k-low.cc
@@ -115,7 +115,7 @@ static int or1k_regmap[] = {
 void
 or1k_target::low_arch_setup ()
 {
-  current_process ()->tdesc = tdesc_or1k_linux;
+  current_thread->tdesc = tdesc_or1k_linux;
 }
 
 /* Implement the low_cannot_fetch_register linux target ops method.  */
diff --git a/gdbserver/linux-ppc-low.cc b/gdbserver/linux-ppc-low.cc
index 08608b2dcc38..486574bd3dbb 100644
--- a/gdbserver/linux-ppc-low.cc
+++ b/gdbserver/linux-ppc-low.cc
@@ -212,7 +212,7 @@ ppc_check_regset (int tid, int regset_id, int regsetsize)
 bool
 ppc_target::low_cannot_store_register (int regno)
 {
-  const struct target_desc *tdesc = current_process ()->tdesc;
+  const struct target_desc *tdesc = current_thread->tdesc;
 
 #ifndef __powerpc64__
   /* Some kernels do not allow us to store fpscr.  */
@@ -890,9 +890,9 @@ ppc_target::low_arch_setup ()
   else
       tdesc = tdesc_powerpc_64l;
 
-  current_process ()->tdesc = tdesc;
+  current_thread->tdesc = tdesc;
 
-  /* The value of current_process ()->tdesc needs to be set for this
+  /* The value of current_thread->tdesc needs to be set for this
      call.  */
   ppc_hwcap = linux_get_hwcap (current_thread, features.wordsize);
   ppc_hwcap2 = linux_get_hwcap2 (current_thread, features.wordsize);
@@ -952,7 +952,7 @@ ppc_target::low_arch_setup ()
    }
 #endif
 
-  current_process ()->tdesc = tdesc;
+  current_thread->tdesc = tdesc;
 
   for (regset = ppc_regsets; regset->size >= 0; regset++)
     switch (regset->get_request)
@@ -1094,7 +1094,7 @@ is_elfv2_inferior (void)
   CORE_ADDR phdr;
   Elf64_Ehdr ehdr;
 
-  const struct target_desc *tdesc = current_process ()->tdesc;
+  const struct target_desc *tdesc = current_thread->tdesc;
   int wordsize = register_size (tdesc, 0);
 
   if (!linux_get_auxv (current_thread, wordsize, AT_PHDR, &phdr))
diff --git a/gdbserver/linux-riscv-low.cc b/gdbserver/linux-riscv-low.cc
index 6b2902e422d9..c1c3e5fa5cae 100644
--- a/gdbserver/linux-riscv-low.cc
+++ b/gdbserver/linux-riscv-low.cc
@@ -92,7 +92,7 @@ riscv_target::low_arch_setup ()
 
   if (!tdesc->expedite_regs)
     init_target_desc (tdesc.get (), expedite_regs);
-  current_process ()->tdesc = tdesc.release ();
+  current_thread->tdesc = tdesc.release ();
 }
 
 /* Collect GPRs from REGCACHE into BUF.  */
diff --git a/gdbserver/linux-s390-low.cc b/gdbserver/linux-s390-low.cc
index 0d01dffa64a4..4d3e81a05c76 100644
--- a/gdbserver/linux-s390-low.cc
+++ b/gdbserver/linux-s390-low.cc
@@ -697,7 +697,7 @@ s390_target::low_arch_setup ()
 	  break;
 	}
 
-  current_process ()->tdesc = tdesc;
+  current_thread->tdesc = tdesc;
 }
 
 
@@ -771,7 +771,7 @@ s390_target::get_regs_info ()
   if (have_hwcap_s390_high_gprs)
     {
 #ifdef __s390x__
-      const struct target_desc *tdesc = current_process ()->tdesc;
+      const struct target_desc *tdesc = current_thread->tdesc;
 
       if (register_size (tdesc, 0) == 4)
 	return &regs_info_3264;
diff --git a/gdbserver/linux-sh-low.cc b/gdbserver/linux-sh-low.cc
index 966bdeb8ba7a..bee46b8892a3 100644
--- a/gdbserver/linux-sh-low.cc
+++ b/gdbserver/linux-sh-low.cc
@@ -180,7 +180,7 @@ sh_target::get_regs_info ()
 void
 sh_target::low_arch_setup ()
 {
-  current_process ()->tdesc = tdesc_sh;
+  current_thread->tdesc = tdesc_sh;
 }
 
 /* The linux target ops object.  */
diff --git a/gdbserver/linux-sparc-low.cc b/gdbserver/linux-sparc-low.cc
index d4826d029a9d..7c9d4d456926 100644
--- a/gdbserver/linux-sparc-low.cc
+++ b/gdbserver/linux-sparc-low.cc
@@ -299,7 +299,7 @@ sparc_target::low_breakpoint_at (CORE_ADDR where)
 void
 sparc_target::low_arch_setup ()
 {
-  current_process ()->tdesc = tdesc_sparc64;
+  current_thread->tdesc = tdesc_sparc64;
 }
 
 static struct regset_info sparc_regsets[] = {
diff --git a/gdbserver/linux-tic6x-low.cc b/gdbserver/linux-tic6x-low.cc
index 893b5f795ac1..02032112a1be 100644
--- a/gdbserver/linux-tic6x-low.cc
+++ b/gdbserver/linux-tic6x-low.cc
@@ -389,7 +389,7 @@ tic6x_target::low_arch_setup ()
     }
   tic6x_usrregs_info.regmap = tic6x_regmap;
 
-  current_process ()->tdesc = tic6x_read_description (feature);
+  current_thread->tdesc = tic6x_read_description (feature);
 }
 
 static struct regsets_info tic6x_regsets_info =
diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
index d2b55f6f0d2b..14c42603a67e 100644
--- a/gdbserver/linux-x86-low.cc
+++ b/gdbserver/linux-x86-low.cc
@@ -1091,7 +1091,7 @@ x86_target::get_regs_info ()
 void
 x86_target::low_arch_setup ()
 {
-  current_process ()->tdesc = x86_linux_read_description ();
+  current_thread->tdesc = x86_linux_read_description ();
 }
 
 bool
diff --git a/gdbserver/linux-xtensa-low.cc b/gdbserver/linux-xtensa-low.cc
index 8e7c4c08b7bd..7035edff7bd2 100644
--- a/gdbserver/linux-xtensa-low.cc
+++ b/gdbserver/linux-xtensa-low.cc
@@ -311,7 +311,7 @@ static struct regs_info myregs_info =
 void
 xtensa_target::low_arch_setup ()
 {
-  current_process ()->tdesc = tdesc_xtensa;
+  current_thread->tdesc = tdesc_xtensa;
 }
 
 const regs_info *
diff --git a/gdbserver/netbsd-aarch64-low.cc b/gdbserver/netbsd-aarch64-low.cc
index f8447b0d1eec..211a0794b7fc 100644
--- a/gdbserver/netbsd-aarch64-low.cc
+++ b/gdbserver/netbsd-aarch64-low.cc
@@ -101,7 +101,7 @@ netbsd_aarch64_target::low_arch_setup ()
   static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL };
   init_target_desc (tdesc, expedite_regs_aarch64);
 
-  current_process ()->tdesc = tdesc;
+  current_thread->tdesc = tdesc;
 }
 
 /* The singleton target ops object.  */
diff --git a/gdbserver/netbsd-amd64-low.cc b/gdbserver/netbsd-amd64-low.cc
index d08e3489f580..024401a6418c 100644
--- a/gdbserver/netbsd-amd64-low.cc
+++ b/gdbserver/netbsd-amd64-low.cc
@@ -194,7 +194,7 @@ netbsd_amd64_target::low_arch_setup ()
 
   init_target_desc (tdesc, amd64_expedite_regs);
 
-  current_process ()->tdesc = tdesc;
+  current_thread->tdesc = tdesc;
 }
 
 /* The singleton target ops object.  */
diff --git a/gdbserver/netbsd-i386-low.cc b/gdbserver/netbsd-i386-low.cc
index f6fa40c144e3..eec149aa9f99 100644
--- a/gdbserver/netbsd-i386-low.cc
+++ b/gdbserver/netbsd-i386-low.cc
@@ -145,7 +145,7 @@ netbsd_i386_target::low_arch_setup ()
 
   init_target_desc (tdesc, i386_expedite_regs);
 
-  current_process ()->tdesc = tdesc;
+  current_thread->tdesc = tdesc;
 }
 
 /* The singleton target ops object.  */
diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc
index ebaeb5e86895..9e8572fbee50 100644
--- a/gdbserver/regcache.cc
+++ b/gdbserver/regcache.cc
@@ -39,11 +39,9 @@ get_thread_regcache (struct thread_info *thread, int fetch)
      have.  */
   if (regcache == NULL)
     {
-      struct process_info *proc = get_thread_process (thread);
+      gdb_assert (thread->tdesc != NULL);
 
-      gdb_assert (proc->tdesc != NULL);
-
-      regcache = new_register_cache (proc->tdesc);
+      regcache = new_register_cache (thread->tdesc);
       set_thread_regcache_data (thread, regcache);
     }
 
diff --git a/gdbserver/tdesc.cc b/gdbserver/tdesc.cc
index 5693cc6626fb..17666c33661f 100644
--- a/gdbserver/tdesc.cc
+++ b/gdbserver/tdesc.cc
@@ -129,7 +129,7 @@ current_target_desc (void)
   if (current_thread == NULL)
     return &default_description;
 
-  return current_process ()->tdesc;
+  return current_thread->tdesc;
 }
 
 /* An empty structure.  */


More information about the Gdb-patches mailing list