gdb: introduce symtab_create_debug_printf
[binutils-gdb.git] / gdb / linux-thread-db.c
index 3027caa8b529f9ebccea9f4d84b432d2adb1b4eb..11da82a1abc7c4c321a4f3aae46864587a202113 100644 (file)
@@ -1,6 +1,6 @@
 /* libthread_db assisted debugging support, generic parts.
 
-   Copyright (C) 1999-2018 Free Software Foundation, Inc.
+   Copyright (C) 1999-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,7 +21,7 @@
 #include <dlfcn.h>
 #include "gdb_proc_service.h"
 #include "nat/gdb_thread_db.h"
-#include "gdb_vecs.h"
+#include "gdbsupport/gdb_vecs.h"
 #include "bfd.h"
 #include "command.h"
 #include "gdbcmd.h"
@@ -46,8 +46,9 @@
 #include <ctype.h>
 #include "nat/linux-namespaces.h"
 #include <algorithm>
-#include "common/pathstuff.h"
+#include "gdbsupport/pathstuff.h"
 #include "valprint.h"
+#include "cli/cli-style.h"
 
 /* GNU/Linux libthread_db support.
 
@@ -91,31 +92,33 @@ public:
   strata stratum () const override { return thread_stratum; }
 
   void detach (inferior *, int) override;
-  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
   void resume (ptid_t, int, enum gdb_signal) override;
   void mourn_inferior () override;
+  void follow_exec (inferior *, ptid_t, const char *) override;
   void update_thread_list () override;
-  const char *pid_to_str (ptid_t) override;
+  std::string pid_to_str (ptid_t) override;
   CORE_ADDR get_thread_local_address (ptid_t ptid,
                                      CORE_ADDR load_module_addr,
                                      CORE_ADDR offset) override;
   const char *extra_thread_info (struct thread_info *) override;
-  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+  ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
 
   thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle,
                                             int handle_len,
                                             inferior *inf) override;
+  gdb::byte_vector thread_info_to_thread_handle (struct thread_info *) override;
 };
 
-static char *libthread_db_search_path;
+static std::string libthread_db_search_path = LIBTHREAD_DB_SEARCH_PATH;
 
-/* Set to non-zero if thread_db auto-loading is enabled
+/* Set to true if thread_db auto-loading is enabled
    by the "set auto-load libthread-db" command.  */
-static int auto_load_thread_db = 1;
+static bool auto_load_thread_db = true;
 
-/* Set to non-zero if load-time libthread_db tests have been enabled
-   by the "maintenence set check-libthread-db" command.  */
-static int check_thread_db_on_load = 0;
+/* Set to true if load-time libthread_db tests have been enabled
+   by the "maintenance set check-libthread-db" command.  */
+static bool check_thread_db_on_load = false;
 
 /* "show" command for the auto_load_thread_db configuration variable.  */
 
@@ -123,20 +126,17 @@ static void
 show_auto_load_thread_db (struct ui_file *file, int from_tty,
                          struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Auto-loading of inferior specific libthread_db "
-                           "is %s.\n"),
-                   value);
+  gdb_printf (file, _("Auto-loading of inferior specific libthread_db "
+                     "is %s.\n"),
+             value);
 }
 
 static void
 set_libthread_db_search_path (const char *ignored, int from_tty,
                              struct cmd_list_element *c)
 {
-  if (*libthread_db_search_path == '\0')
-    {
-      xfree (libthread_db_search_path);
-      libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH);
-    }
+  if (libthread_db_search_path.empty ())
+    libthread_db_search_path = LIBTHREAD_DB_SEARCH_PATH;
 }
 
 /* If non-zero, print details of libthread_db processing.  */
@@ -147,7 +147,7 @@ static void
 show_libthread_db_debug (struct ui_file *file, int from_tty,
                         struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("libthread-db debugging is %s.\n"), value);
+  gdb_printf (file, _("libthread-db debugging is %s.\n"), value);
 }
 
 /* If we're running on GNU/Linux, we must explicitly attach to any new
@@ -159,13 +159,14 @@ static thread_db_target the_thread_db_target;
 /* Non-zero if we have determined the signals used by the threads
    library.  */
 static int thread_signals;
-static sigset_t thread_stop_set;
-static sigset_t thread_print_set;
 
 struct thread_db_info
 {
   struct thread_db_info *next;
 
+  /* The target this thread_db_info is bound to.  */
+  process_stratum_target *process_target;
+
   /* Process id this object refers to.  */
   int pid;
 
@@ -204,7 +205,7 @@ struct thread_db_info
 
 /* List of known processes using thread_db, and the required
    bookkeeping.  */
-struct thread_db_info *thread_db_list;
+static thread_db_info *thread_db_list;
 
 static void thread_db_find_new_threads_1 (thread_info *stopped);
 static void thread_db_find_new_threads_2 (thread_info *stopped,
@@ -226,12 +227,13 @@ add_thread_db_info (void *handle)
 {
   struct thread_db_info *info = XCNEW (struct thread_db_info);
 
+  info->process_target = current_inferior ()->process_target ();
   info->pid = inferior_ptid.pid ();
   info->handle = handle;
 
   /* The workaround works by reading from /proc/pid/status, so it is
      disabled for core files.  */
-  if (target_has_execution)
+  if (target_has_execution ())
     info->need_stale_parent_threads_check = 1;
 
   info->next = thread_db_list;
@@ -244,12 +246,12 @@ add_thread_db_info (void *handle)
    related to process PID, if any; NULL otherwise.  */
 
 static struct thread_db_info *
-get_thread_db_info (int pid)
+get_thread_db_info (process_stratum_target *targ, int pid)
 {
   struct thread_db_info *info;
 
   for (info = thread_db_list; info; info = info->next)
-    if (pid == info->pid)
+    if (targ == info->process_target && pid == info->pid)
       return info;
 
   return NULL;
@@ -263,14 +265,14 @@ static const char *thread_db_err_str (td_err_e err);
    LIBTHREAD_DB_SO's dlopen'ed handle.  */
 
 static void
-delete_thread_db_info (int pid)
+delete_thread_db_info (process_stratum_target *targ, int pid)
 {
   struct thread_db_info *info, *info_prev;
 
   info_prev = NULL;
 
   for (info = thread_db_list; info; info_prev = info, info = info->next)
-    if (pid == info->pid)
+    if (targ == info->process_target && pid == info->pid)
       break;
 
   if (info == NULL)
@@ -404,7 +406,7 @@ thread_from_lwp (thread_info *stopped, ptid_t ptid)
      LWP.  */
   gdb_assert (ptid.lwp () != 0);
 
-  info = get_thread_db_info (ptid.pid ());
+  info = get_thread_db_info (stopped->inf->process_target (), ptid.pid ());
 
   /* Access an lwp we know is stopped.  */
   info->proc_handle.thread = stopped;
@@ -420,7 +422,7 @@ thread_from_lwp (thread_info *stopped, ptid_t ptid)
           thread_db_err_str (err));
 
   /* Fill the cache.  */
-  tp = find_thread_ptid (ptid);
+  tp = find_thread_ptid (stopped->inf->process_target (), ptid);
   return record_thread (info, tp, ptid, &th, &ti);
 }
 \f
@@ -432,12 +434,12 @@ thread_db_notice_clone (ptid_t parent, ptid_t child)
 {
   struct thread_db_info *info;
 
-  info = get_thread_db_info (child.pid ());
+  info = get_thread_db_info (linux_target, child.pid ());
 
   if (info == NULL)
     return 0;
 
-  thread_info *stopped = find_thread_ptid (parent);
+  thread_info *stopped = find_thread_ptid (linux_target, parent);
 
   thread_from_lwp (stopped, child);
 
@@ -466,16 +468,17 @@ inferior_has_bug (const char *ver_symbol, int ver_major_min, int ver_minor_min)
 {
   struct bound_minimal_symbol version_msym;
   CORE_ADDR version_addr;
-  gdb::unique_xmalloc_ptr<char> version;
-  int err, got, retval = 0;
+  int got, retval = 0;
 
   version_msym = lookup_minimal_symbol (ver_symbol, NULL, NULL);
   if (version_msym.minsym == NULL)
     return 0;
 
-  version_addr = BMSYMBOL_VALUE_ADDRESS (version_msym);
-  got = target_read_string (version_addr, &version, 32, &err);
-  if (err == 0 && memchr (version.get (), 0, got) == version.get () + got - 1)
+  version_addr = version_msym.value_address ();
+  gdb::unique_xmalloc_ptr<char> version
+    = target_read_string (version_addr, 32, &got);
+  if (version != nullptr
+      && memchr (version.get (), 0, got) == version.get () + got - 1)
     {
       int major, minor;
 
@@ -497,12 +500,12 @@ static int
 thread_db_find_new_threads_silently (thread_info *stopped)
 {
 
-  TRY
+  try
     {
       thread_db_find_new_threads_2 (stopped, true);
     }
 
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       if (libthread_db_debug)
        exception_fprintf (gdb_stdlog, except,
@@ -524,7 +527,7 @@ thread_db_find_new_threads_silently (thread_info *stopped)
         corrupted.  For core files it does not apply, no 'later enumeration'
         is possible.  */
 
-      if (!target_has_execution || !inferior_has_bug ("nptl_version", 2, 7))
+      if (!target_has_execution () || !inferior_has_bug ("nptl_version", 2, 7))
        {
          exception_fprintf (gdb_stderr, except,
                             _("Warning: couldn't activate thread debugging "
@@ -532,7 +535,6 @@ thread_db_find_new_threads_silently (thread_info *stopped)
          return 1;
        }
     }
-  END_CATCH
 
   return 0;
 }
@@ -652,7 +654,7 @@ check_thread_db_callback (const td_thrhandle_t *th, void *arg)
   memset (&th2, 23, sizeof (td_thrhandle_t));
   CALL_UNCHECKED (td_ta_map_lwp2thr, th->th_ta_p, ti.ti_lid, &th2);
 
-  if (tdb_testinfo->last_result == TD_ERR && !target_has_execution)
+  if (tdb_testinfo->last_result == TD_ERR && !target_has_execution ())
     {
       /* Some platforms require execution for td_ta_map_lwp2thr.  */
       LOG (_("; can't map_lwp2thr"));
@@ -682,14 +684,14 @@ check_thread_db_callback (const td_thrhandle_t *th, void *arg)
      calls are made, we just assume they were; future changes
      to how GDB accesses TLS could result in this passing
      without exercising the calls it's supposed to.  */
-  ptid_t ptid = ptid_t (tdb_testinfo->info->pid, ti.ti_lid, 0);
-  struct thread_info *thread_info = find_thread_ptid (ptid);
+  ptid_t ptid = ptid_t (tdb_testinfo->info->pid, ti.ti_lid);
+  thread_info *thread_info = find_thread_ptid (linux_target, ptid);
   if (thread_info != NULL && thread_info->priv != NULL)
     {
       LOG ("; errno");
 
       scoped_restore_current_thread restore_current_thread;
-      switch_to_thread (ptid);
+      switch_to_thread (thread_info);
 
       expression_up expr = parse_expression ("(int) errno");
       struct value *val = evaluate_expression (expr.get ());
@@ -757,7 +759,7 @@ check_thread_db (struct thread_db_info *info, bool log_progress)
      fail.  */
   linux_stop_and_wait_all_lwps ();
 
-  TRY
+  try
     {
       td_err_e err = td_ta_thr_iter_p (info->thread_agent,
                                       check_thread_db_callback,
@@ -773,17 +775,16 @@ check_thread_db (struct thread_db_info *info, bool log_progress)
       if (!tdb_testinfo->threads_seen)
        error (_("no threads seen"));
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       if (warning_pre_print)
-       fputs_unfiltered (warning_pre_print, gdb_stderr);
+       gdb_puts (warning_pre_print, gdb_stderr);
 
       exception_fprintf (gdb_stderr, except,
                         _("libthread_db integrity checks failed: "));
 
       test_passed = false;
     }
-  END_CATCH
 
   if (test_passed && log_progress)
     debug_printf (_("libthread_db integrity checks passed.\n"));
@@ -795,13 +796,31 @@ check_thread_db (struct thread_db_info *info, bool log_progress)
   return test_passed;
 }
 
+/* Predicate which tests whether objfile OBJ refers to the library
+   containing pthread related symbols.  Historically, this library has
+   been named in such a way that looking for "libpthread" in the name
+   was sufficient to identify it.  As of glibc-2.34, the C library
+   (libc) contains the thread library symbols.  Therefore we check
+   that the name matches a possible thread library, but we also check
+   that it contains at least one of the symbols (pthread_create) that
+   we'd expect to find in the thread library.  */
+
+static bool
+libpthread_objfile_p (objfile *obj)
+{
+  return (libpthread_name_p (objfile_name (obj))
+          && lookup_minimal_symbol ("pthread_create",
+                                   NULL,
+                                   obj).minsym != NULL);
+}
+
 /* Attempt to initialize dlopen()ed libthread_db, described by INFO.
-   Return 1 on success.
+   Return true on success.
    Failure could happen if libthread_db does not have symbols we expect,
    or when it refuses to work with the current inferior (e.g. due to
    version mismatch between libthread_db and libpthread).  */
 
-static int
+static bool
 try_thread_db_load_1 (struct thread_db_info *info)
 {
   td_err_e err;
@@ -819,7 +838,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
   do                                                                   \
     {                                                                  \
       if ((a) == NULL)                                                 \
-       return 0;                                                       \
+       return false;                                                   \
   } while (0)
 
   CHK (TDB_VERBOSE_DLSYM (info, td_init));
@@ -829,7 +848,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
     {
       warning (_("Cannot initialize libthread_db: %s"),
               thread_db_err_str (err));
-      return 0;
+      return false;
     }
 
   CHK (TDB_VERBOSE_DLSYM (info, td_ta_new));
@@ -842,23 +861,23 @@ try_thread_db_load_1 (struct thread_db_info *info)
   if (err != TD_OK)
     {
       if (libthread_db_debug)
-       fprintf_unfiltered (gdb_stdlog, _("td_ta_new failed: %s\n"),
-                           thread_db_err_str (err));
+       gdb_printf (gdb_stdlog, _("td_ta_new failed: %s\n"),
+                   thread_db_err_str (err));
       else
-        switch (err)
-          {
-            case TD_NOLIBTHREAD:
+       switch (err)
+         {
+           case TD_NOLIBTHREAD:
 #ifdef THREAD_DB_HAS_TD_VERSION
-            case TD_VERSION:
+           case TD_VERSION:
 #endif
-              /* The errors above are not unexpected and silently ignored:
-                 they just mean we haven't found correct version of
-                 libthread_db yet.  */
-              break;
-            default:
-              warning (_("td_ta_new failed: %s"), thread_db_err_str (err));
-          }
-      return 0;
+             /* The errors above are not unexpected and silently ignored:
+                they just mean we haven't found correct version of
+                libthread_db yet.  */
+             break;
+           default:
+             warning (_("td_ta_new failed: %s"), thread_db_err_str (err));
+         }
+      return false;
     }
 
   /* These are essential.  */
@@ -879,7 +898,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
 
      td_ta_map_lwp2thr uses ps_get_thread_area, but we can't use that
      currently on core targets, as it uses ptrace directly.  */
-  if (target_has_execution
+  if (target_has_execution ()
       && linux_proc_task_list_dir_exists (inferior_ptid.pid ()))
     info->td_ta_thr_iter_p = NULL;
   else
@@ -893,18 +912,17 @@ try_thread_db_load_1 (struct thread_db_info *info)
   if (check_thread_db_on_load)
     {
       if (!check_thread_db (info, libthread_db_debug))
-       return 0;
+       return false;
     }
 
   if (info->td_ta_thr_iter_p == NULL)
     {
-      struct lwp_info *lp;
       int pid = inferior_ptid.pid ();
       thread_info *curr_thread = inferior_thread ();
 
       linux_stop_and_wait_all_lwps ();
 
-      ALL_LWPS (lp)
+      for (const lwp_info *lp : all_lwps ())
        if (lp->ptid.pid () == pid)
          thread_from_lwp (curr_thread, lp->ptid);
 
@@ -913,52 +931,44 @@ try_thread_db_load_1 (struct thread_db_info *info)
   else if (thread_db_find_new_threads_silently (inferior_thread ()) != 0)
     {
       /* Even if libthread_db initializes, if the thread list is
-         corrupted, we'd not manage to list any threads.  Better reject this
-         thread_db, and fall back to at least listing LWPs.  */
-      return 0;
+        corrupted, we'd not manage to list any threads.  Better reject this
+        thread_db, and fall back to at least listing LWPs.  */
+      return false;
     }
 
-  printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
+  gdb_printf (_("[Thread debugging using libthread_db enabled]\n"));
 
-  if (*libthread_db_search_path || libthread_db_debug)
+  if (!libthread_db_search_path.empty () || libthread_db_debug)
     {
-      struct ui_file *file;
       const char *library;
 
       library = dladdr_to_soname ((const void *) *info->td_ta_new_p);
       if (library == NULL)
        library = LIBTHREAD_DB_SO;
 
-      /* If we'd print this to gdb_stdout when debug output is
-        disabled, still print it to gdb_stdout if debug output is
-        enabled.  User visible output should not depend on debug
-        settings.  */
-      file = *libthread_db_search_path != '\0' ? gdb_stdout : gdb_stdlog;
-      fprintf_unfiltered (file, _("Using host libthread_db library \"%s\".\n"),
-                         library);
+      gdb_printf (_("Using host libthread_db library \"%ps\".\n"),
+                 styled_string (file_name_style.style (), library));
     }
 
   /* The thread library was detected.  Activate the thread_db target
-     if this is the first process using it.  */
-  if (thread_db_list->next == NULL)
-    push_target (&the_thread_db_target);
-
-  return 1;
+     for this process.  */
+  current_inferior ()->push_target (&the_thread_db_target);
+  return true;
 }
 
 /* Attempt to use LIBRARY as libthread_db.  LIBRARY could be absolute,
    relative, or just LIBTHREAD_DB.  */
 
-static int
-try_thread_db_load (const char *library, int check_auto_load_safe)
+static bool
+try_thread_db_load (const char *library, bool check_auto_load_safe)
 {
   void *handle;
   struct thread_db_info *info;
 
   if (libthread_db_debug)
-    fprintf_unfiltered (gdb_stdlog,
-                       _("Trying host libthread_db library: %s.\n"),
-                       library);
+    gdb_printf (gdb_stdlog,
+               _("Trying host libthread_db library: %s.\n"),
+               library);
 
   if (check_auto_load_safe)
     {
@@ -967,24 +977,25 @@ try_thread_db_load (const char *library, int check_auto_load_safe)
          /* Do not print warnings by file_is_auto_load_safe if the library does
             not exist at this place.  */
          if (libthread_db_debug)
-           fprintf_unfiltered (gdb_stdlog, _("open failed: %s.\n"),
-                               safe_strerror (errno));
-         return 0;
+           gdb_printf (gdb_stdlog, _("open failed: %s.\n"),
+                       safe_strerror (errno));
+         return false;
        }
 
-      if (!file_is_auto_load_safe (library, _("auto-load: Loading libthread-db "
-                                             "library \"%s\" from explicit "
-                                             "directory.\n"),
-                                  library))
-       return 0;
+      auto_load_debug_printf
+       ("Loading libthread-db library \"%s\" from explicit directory.",
+        library);
+
+      if (!file_is_auto_load_safe (library))
+       return false;
     }
 
   handle = dlopen (library, RTLD_NOW);
   if (handle == NULL)
     {
       if (libthread_db_debug)
-       fprintf_unfiltered (gdb_stdlog, _("dlopen failed: %s.\n"), dlerror ());
-      return 0;
+       gdb_printf (gdb_stdlog, _("dlopen failed: %s.\n"), dlerror ());
+      return false;
     }
 
   if (libthread_db_debug && strchr (library, '/') == NULL)
@@ -993,13 +1004,13 @@ try_thread_db_load (const char *library, int check_auto_load_safe)
 
       td_init = dlsym (handle, "td_init");
       if (td_init != NULL)
-        {
-          const char *const libpath = dladdr_to_soname (td_init);
+       {
+         const char *const libpath = dladdr_to_soname (td_init);
 
-          if (libpath != NULL)
-            fprintf_unfiltered (gdb_stdlog, _("Host %s resolved to: %s.\n"),
-                               library, libpath);
-        }
+         if (libpath != NULL)
+           gdb_printf (gdb_stdlog, _("Host %s resolved to: %s.\n"),
+                       library, libpath);
+       }
     }
 
   info = add_thread_db_info (handle);
@@ -1008,12 +1019,22 @@ try_thread_db_load (const char *library, int check_auto_load_safe)
   if (strchr (library, '/') != NULL)
     info->filename = gdb_realpath (library).release ();
 
-  if (try_thread_db_load_1 (info))
-    return 1;
+  try
+    {
+      if (try_thread_db_load_1 (info))
+       return true;
+    }
+  catch (const gdb_exception_error &except)
+    {
+      if (libthread_db_debug)
+       exception_fprintf (gdb_stdlog, except,
+                          "Warning: While trying to load libthread_db: ");
+    }
 
   /* This library "refused" to work on current inferior.  */
-  delete_thread_db_info (inferior_ptid.pid ());
-  return 0;
+  delete_thread_db_info (current_inferior ()->process_target (),
+                        inferior_ptid.pid ());
+  return false;
 }
 
 /* Subroutine of try_thread_db_load_from_pdir to simplify it.
@@ -1021,7 +1042,7 @@ try_thread_db_load (const char *library, int check_auto_load_safe)
    SUBDIR may be NULL.  It may also be something like "../lib64".
    The result is true for success.  */
 
-static int
+static bool
 try_thread_db_load_from_pdir_1 (struct objfile *obj, const char *subdir)
 {
   const char *obj_name = objfile_name (obj);
@@ -1029,8 +1050,9 @@ try_thread_db_load_from_pdir_1 (struct objfile *obj, const char *subdir)
   if (obj_name[0] != '/')
     {
       warning (_("Expected absolute pathname for libpthread in the"
-                " inferior, but got %s."), obj_name);
-      return 0;
+                " inferior, but got %ps."),
+              styled_string (file_name_style.style (), obj_name));
+      return false;
     }
 
   std::string path = obj_name;
@@ -1042,7 +1064,7 @@ try_thread_db_load_from_pdir_1 (struct objfile *obj, const char *subdir)
     path = path + subdir + "/";
   path += LIBTHREAD_DB_SO;
 
-  return try_thread_db_load (path.c_str (), 1);
+  return try_thread_db_load (path.c_str (), true);
 }
 
 /* Handle $pdir in libthread-db-search-path.
@@ -1050,19 +1072,17 @@ try_thread_db_load_from_pdir_1 (struct objfile *obj, const char *subdir)
    SUBDIR may be NULL.  It may also be something like "../lib64".
    The result is true for success.  */
 
-static int
+static bool
 try_thread_db_load_from_pdir (const char *subdir)
 {
-  struct objfile *obj;
-
   if (!auto_load_thread_db)
-    return 0;
+    return false;
 
-  ALL_OBJFILES (obj)
-    if (libpthread_name_p (objfile_name (obj)))
+  for (objfile *obj : current_program_space->objfiles ())
+    if (libpthread_objfile_p (obj))
       {
        if (try_thread_db_load_from_pdir_1 (obj, subdir))
-         return 1;
+         return true;
 
        /* We may have found the separate-debug-info version of
           libpthread, and it may live in a directory without a matching
@@ -1071,10 +1091,10 @@ try_thread_db_load_from_pdir (const char *subdir)
          return try_thread_db_load_from_pdir_1 (obj->separate_debug_objfile_backlink,
                                                 subdir);
 
-       return 0;
+       return false;
       }
 
-  return 0;
+  return false;
 }
 
 /* Handle $sdir in libthread-db-search-path.
@@ -1082,37 +1102,37 @@ try_thread_db_load_from_pdir (const char *subdir)
    dlopen(file_without_path) will look.
    The result is true for success.  */
 
-static int
+static bool
 try_thread_db_load_from_sdir (void)
 {
-  return try_thread_db_load (LIBTHREAD_DB_SO, 0);
+  return try_thread_db_load (LIBTHREAD_DB_SO, false);
 }
 
 /* Try to load libthread_db from directory DIR of length DIR_LEN.
    The result is true for success.  */
 
-static int
+static bool
 try_thread_db_load_from_dir (const char *dir, size_t dir_len)
 {
   if (!auto_load_thread_db)
-    return 0;
+    return false;
 
   std::string path = std::string (dir, dir_len) + "/" + LIBTHREAD_DB_SO;
 
-  return try_thread_db_load (path.c_str (), 1);
+  return try_thread_db_load (path.c_str (), true);
 }
 
 /* Search libthread_db_search_path for libthread_db which "agrees"
    to work on current inferior.
    The result is true for success.  */
 
-static int
+static bool
 thread_db_load_search (void)
 {
-  int rc = 0;
+  bool rc = false;
 
   std::vector<gdb::unique_xmalloc_ptr<char>> dir_vec
-    = dirnames_to_char_ptr_vec (libthread_db_search_path);
+    = dirnames_to_char_ptr_vec (libthread_db_search_path.c_str ());
 
   for (const gdb::unique_xmalloc_ptr<char> &this_dir_up : dir_vec)
     {
@@ -1157,49 +1177,53 @@ thread_db_load_search (void)
     }
 
   if (libthread_db_debug)
-    fprintf_unfiltered (gdb_stdlog,
-                       _("thread_db_load_search returning %d\n"), rc);
+    gdb_printf (gdb_stdlog,
+               _("thread_db_load_search returning %d\n"), rc);
   return rc;
 }
 
-/* Return non-zero if the inferior has a libpthread.  */
+/* Return true if the inferior has a libpthread.  */
 
-static int
+static bool
 has_libpthread (void)
 {
-  struct objfile *obj;
-
-  ALL_OBJFILES (obj)
-    if (libpthread_name_p (objfile_name (obj)))
-      return 1;
+  for (objfile *obj : current_program_space->objfiles ())
+    if (libpthread_objfile_p (obj))
+      return true;
 
-  return 0;
+  return false;
 }
 
 /* Attempt to load and initialize libthread_db.
    Return 1 on success.  */
 
-static int
+static bool
 thread_db_load (void)
 {
-  struct thread_db_info *info;
+  inferior *inf = current_inferior ();
+
+  /* When attaching / handling fork child, don't try loading libthread_db
+     until we know about all shared libraries.  */
+  if (inf->in_initial_library_scan)
+    return false;
 
-  info = get_thread_db_info (inferior_ptid.pid ());
+  thread_db_info *info = get_thread_db_info (inf->process_target (),
+                                            inferior_ptid.pid ());
 
   if (info != NULL)
-    return 1;
+    return true;
 
   /* Don't attempt to use thread_db on executables not running
      yet.  */
-  if (!target_has_registers)
-    return 0;
+  if (!target_has_registers ())
+    return false;
 
   /* Don't attempt to use thread_db for remote targets.  */
   if (!(target_can_run () || core_bfd))
-    return 0;
+    return false;
 
   if (thread_db_load_search ())
-    return 1;
+    return true;
 
   /* We couldn't find a libthread_db.
      If the inferior has a libpthread warn the user.  */
@@ -1207,13 +1231,13 @@ thread_db_load (void)
     {
       warning (_("Unable to find libthread_db matching inferior's thread"
                 " library, thread debugging will not be available."));
-      return 0;
+      return false;
     }
 
   /* Either this executable isn't using libpthread at all, or it is
      statically linked.  Since we can't easily distinguish these two cases,
      no warning is issued.  */
-  return 0;
+  return false;
 }
 
 static void
@@ -1221,23 +1245,14 @@ check_thread_signals (void)
 {
   if (!thread_signals)
     {
-      sigset_t mask;
       int i;
 
-      lin_thread_get_thread_signals (&mask);
-      sigemptyset (&thread_stop_set);
-      sigemptyset (&thread_print_set);
-
-      for (i = 1; i < NSIG; i++)
+      for (i = 0; i < lin_thread_get_thread_signal_num (); i++)
        {
-         if (sigismember (&mask, i))
-           {
-             if (signal_stop_update (gdb_signal_from_host (i), 0))
-               sigaddset (&thread_stop_set, i);
-             if (signal_print_update (gdb_signal_from_host (i), 0))
-               sigaddset (&thread_print_set, i);
-             thread_signals = 1;
-           }
+         int sig = lin_thread_get_thread_signal (i);
+         signal_stop_update (gdb_signal_from_host (sig), 0);
+         signal_print_update (gdb_signal_from_host (sig), 0);
+         thread_signals = 1;
        }
     }
 }
@@ -1246,7 +1261,7 @@ check_thread_signals (void)
    an inferior is created (or otherwise acquired, e.g. attached to)
    and when new shared libraries are loaded into a running process.  */
 
-void
+static void
 check_for_thread_db (void)
 {
   /* Do nothing if we couldn't load libthread_db.so.1.  */
@@ -1278,12 +1293,12 @@ thread_db_new_objfile (struct objfile *objfile)
         of the list of shared libraries to load, and in an app of several
         thousand shared libraries, this can otherwise be painful.  */
       && ((objfile->flags & OBJF_MAINLINE) != 0
-         || libpthread_name_p (objfile_name (objfile))))
+         || libpthread_objfile_p (objfile)))
     check_for_thread_db ();
 }
 
 static void
-check_pid_namespace_match (void)
+check_pid_namespace_match (inferior *inf)
 {
   /* Check is only relevant for local targets targets.  */
   if (target_can_run ())
@@ -1293,7 +1308,7 @@ check_pid_namespace_match (void)
         child's thread list, we'll mistakenly think it has no threads
         since the thread PID fields won't match the PID we give to
         libthread_db.  */
-      if (!linux_ns_same (inferior_ptid.pid (), LINUX_NS_PID))
+      if (!linux_ns_same (inf->pid, LINUX_NS_PID))
        {
          warning (_ ("Target and debugger are in different PID "
                      "namespaces; thread lists and other data are "
@@ -1307,9 +1322,9 @@ check_pid_namespace_match (void)
    This handles the case of debugging statically linked executables.  */
 
 static void
-thread_db_inferior_created (struct target_ops *target, int from_tty)
+thread_db_inferior_created (inferior *inf)
 {
-  check_pid_namespace_match ();
+  check_pid_namespace_match (inf);
   check_for_thread_db ();
 }
 
@@ -1351,11 +1366,11 @@ record_thread (struct thread_db_info *info,
      thread with this PTID, but it's marked exited, then the kernel
      reused the tid of an old thread.  */
   if (tp == NULL || tp->state == THREAD_EXITED)
-    tp = add_thread_with_info (ptid, priv);
+    tp = add_thread_with_info (info->process_target, ptid, priv);
   else
     tp->priv.reset (priv);
 
-  if (target_has_execution)
+  if (target_has_execution ())
     check_thread_signals ();
 
   return tp;
@@ -1364,54 +1379,45 @@ record_thread (struct thread_db_info *info,
 void
 thread_db_target::detach (inferior *inf, int from_tty)
 {
-  delete_thread_db_info (inf->pid);
+  delete_thread_db_info (inf->process_target (), inf->pid);
 
   beneath ()->detach (inf, from_tty);
 
   /* NOTE: From this point on, inferior_ptid is null_ptid.  */
 
-  /* If there are no more processes using libpthread, detach the
-     thread_db target ops.  */
-  if (!thread_db_list)
-    unpush_target (this);
+  /* Detach the thread_db target from this inferior.  */
+  inf->unpush_target (this);
 }
 
 ptid_t
 thread_db_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
-                       int options)
+                       target_wait_flags options)
 {
   struct thread_db_info *info;
 
-  ptid = beneath ()->wait (ptid, ourstatus, options);
+  process_stratum_target *beneath
+    = as_process_stratum_target (this->beneath ());
+
+  ptid = beneath->wait (ptid, ourstatus, options);
 
-  switch (ourstatus->kind)
+  switch (ourstatus->kind ())
     {
     case TARGET_WAITKIND_IGNORE:
     case TARGET_WAITKIND_EXITED:
     case TARGET_WAITKIND_THREAD_EXITED:
     case TARGET_WAITKIND_SIGNALLED:
+    case TARGET_WAITKIND_EXECD:
       return ptid;
     }
 
-  info = get_thread_db_info (ptid.pid ());
+  info = get_thread_db_info (beneath, ptid.pid ());
 
   /* If this process isn't using thread_db, we're done.  */
   if (info == NULL)
     return ptid;
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXECD)
-    {
-      /* New image, it may or may not end up using thread_db.  Assume
-        not unless we find otherwise.  */
-      delete_thread_db_info (ptid.pid ());
-      if (!thread_db_list)
-       unpush_target (&the_thread_db_target);
-
-      return ptid;
-    }
-
   /* Fill in the thread's user-level thread id and status.  */
-  thread_from_lwp (find_thread_ptid (ptid), ptid);
+  thread_from_lwp (find_thread_ptid (beneath, ptid), ptid);
 
   return ptid;
 }
@@ -1419,13 +1425,28 @@ thread_db_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 void
 thread_db_target::mourn_inferior ()
 {
-  delete_thread_db_info (inferior_ptid.pid ());
+  process_stratum_target *target_beneath
+    = as_process_stratum_target (this->beneath ());
+
+  delete_thread_db_info (target_beneath, inferior_ptid.pid ());
 
-  beneath ()->mourn_inferior ();
+  target_beneath->mourn_inferior ();
 
-  /* Detach thread_db target ops.  */
-  if (!thread_db_list)
-    unpush_target (&the_thread_db_target);
+  /* Detach the thread_db target from this inferior.  */
+  current_inferior ()->unpush_target (this);
+}
+
+void
+thread_db_target::follow_exec (inferior *follow_inf, ptid_t ptid,
+                              const char *execd_pathname)
+{
+  process_stratum_target *beneath
+    = as_process_stratum_target (this->beneath ());
+
+  delete_thread_db_info (beneath, ptid.pid ());
+
+  current_inferior ()->unpush_target (this);
+  beneath->follow_exec (follow_inf, ptid, execd_pathname);
 }
 
 struct callback_data
@@ -1457,10 +1478,10 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
         terminated and joined threads with kernel thread ID -1.  See
         glibc PR17707.  */
       if (libthread_db_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "thread_db: skipping exited and "
-                           "joined thread (0x%lx)\n",
-                           (unsigned long) ti.ti_tid);
+       gdb_printf (gdb_stdlog,
+                   "thread_db: skipping exited and "
+                   "joined thread (0x%lx)\n",
+                   (unsigned long) ti.ti_tid);
       return 0;
     }
 
@@ -1490,7 +1511,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
     }
 
   ptid_t ptid (info->pid, ti.ti_lid);
-  tp = find_thread_ptid (ptid);
+  tp = find_thread_ptid (info->process_target, ptid);
   if (tp == NULL || tp->priv == NULL)
     record_thread (info, tp, ptid, th_p, &ti);
 
@@ -1513,7 +1534,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
   /* See comment in thread_db_update_thread_list.  */
   gdb_assert (info->td_ta_thr_iter_p != NULL);
 
-  TRY
+  try
     {
       /* Iterate over all user-space threads to discover new threads.  */
       err = info->td_ta_thr_iter_p (info->thread_agent,
@@ -1524,7 +1545,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
                                    TD_SIGNO_MASK,
                                    TD_THR_ANY_USER_FLAGS);
     }
-  CATCH (except, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &except)
     {
       if (libthread_db_debug)
        {
@@ -1532,13 +1553,12 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
                             "Warning: find_new_threads_once: ");
        }
     }
-  END_CATCH
 
   if (libthread_db_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         _("Found %d new threads in iteration %d.\n"),
-                         data.new_threads, iteration);
+      gdb_printf (gdb_stdlog,
+                 _("Found %d new threads in iteration %d.\n"),
+                 data.new_threads, iteration);
     }
 
   if (errp != NULL)
@@ -1558,7 +1578,8 @@ thread_db_find_new_threads_2 (thread_info *stopped, bool until_no_new)
   struct thread_db_info *info;
   int i, loop;
 
-  info = get_thread_db_info (stopped->ptid.pid ());
+  info = get_thread_db_info (stopped->inf->process_target (),
+                            stopped->ptid.pid ());
 
   /* Access an lwp we know is stopped.  */
   info->proc_handle.thread = stopped;
@@ -1601,17 +1622,15 @@ thread_db_target::update_thread_list ()
 
   for (inferior *inf : all_inferiors ())
     {
-      struct thread_info *thread;
-
       if (inf->pid == 0)
        continue;
 
-      info = get_thread_db_info (inf->pid);
+      info = get_thread_db_info (inf->process_target (), inf->pid);
       if (info == NULL)
        continue;
 
-      thread = any_live_thread_of_inferior (inf);
-      if (thread == NULL || thread->executing)
+      thread_info *thread = any_live_thread_of_inferior (inf);
+      if (thread == NULL || thread->executing ())
        continue;
 
       /* It's best to avoid td_ta_thr_iter if possible.  That walks
@@ -1625,7 +1644,7 @@ thread_db_target::update_thread_list ()
         stop.  That uses thread_db entry points that do not walk
         libpthread's thread list, so should be safe, as well as more
         efficient.  */
-      if (target_has_execution_1 (thread->ptid))
+      if (thread->inf->has_execution ())
        continue;
 
       thread_db_find_new_threads_1 (thread);
@@ -1635,20 +1654,17 @@ thread_db_target::update_thread_list ()
   this->beneath ()->update_thread_list ();
 }
 
-const char *
+std::string
 thread_db_target::pid_to_str (ptid_t ptid)
 {
-  struct thread_info *thread_info = find_thread_ptid (ptid);
+  thread_info *thread_info = find_thread_ptid (current_inferior (), ptid);
 
   if (thread_info != NULL && thread_info->priv != NULL)
     {
-      static char buf[64];
       thread_db_thread_info *priv = get_thread_db_thread_info (thread_info);
 
-      snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
-               (unsigned long) priv->tid, ptid.lwp ());
-
-      return buf;
+      return string_printf ("Thread 0x%lx (LWP %ld)",
+                           (unsigned long) priv->tid, ptid.lwp ());
     }
 
   return beneath ()->pid_to_str (ptid);
@@ -1681,27 +1697,50 @@ thread_db_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
 {
   thread_t handle_tid;
 
-  /* Thread handle sizes must match in order to proceed.  We don't use an
-     assert here because the resulting internal error will cause GDB to
-     exit.  This isn't necessarily an internal error due to the possibility
-     of garbage being passed as the thread handle via the python interface.  */
-  if (handle_len != sizeof (handle_tid))
+  /* When debugging a 32-bit target from a 64-bit host, handle_len
+     will be 4 and sizeof (handle_tid) will be 8.  This requires
+     a different cast than the more straightforward case where
+     the sizes are the same.
+
+     Use "--target_board unix/-m32" from a native x86_64 linux build
+     to test the 32/64-bit case.  */
+  if (handle_len == 4 && sizeof (handle_tid) == 8)
+    handle_tid = (thread_t) * (const uint32_t *) thread_handle;
+  else if (handle_len == sizeof (handle_tid))
+    handle_tid = * (const thread_t *) thread_handle;
+  else
     error (_("Thread handle size mismatch: %d vs %zu (from libthread_db)"),
           handle_len, sizeof (handle_tid));
 
-  handle_tid = * (const thread_t *) thread_handle;
-
   for (thread_info *tp : inf->non_exited_threads ())
     {
       thread_db_thread_info *priv = get_thread_db_thread_info (tp);
 
       if (priv != NULL && handle_tid == priv->tid)
-        return tp;
+       return tp;
     }
 
   return NULL;
 }
 
+/* Return the thread handle associated the thread_info pointer TP.  */
+
+gdb::byte_vector
+thread_db_target::thread_info_to_thread_handle (struct thread_info *tp)
+{
+  thread_db_thread_info *priv = get_thread_db_thread_info (tp);
+
+  if (priv == NULL)
+    return gdb::byte_vector ();
+
+  int handle_size = sizeof (priv->tid);
+  gdb::byte_vector rv (handle_size);
+
+  memcpy (rv.data (), &priv->tid, handle_size);
+
+  return rv;
+}
+
 /* Get the address of the thread local variable in load module LM which
    is stored at OFFSET within the thread local storage for thread PTID.  */
 
@@ -1711,9 +1750,10 @@ thread_db_target::get_thread_local_address (ptid_t ptid,
                                            CORE_ADDR offset)
 {
   struct thread_info *thread_info;
-
+  process_stratum_target *beneath
+    = as_process_stratum_target (this->beneath ());
   /* Find the matching thread.  */
-  thread_info = find_thread_ptid (ptid);
+  thread_info = find_thread_ptid (beneath, ptid);
 
   /* We may not have discovered the thread yet.  */
   if (thread_info != NULL && thread_info->priv == NULL)
@@ -1723,7 +1763,7 @@ thread_db_target::get_thread_local_address (ptid_t ptid,
     {
       td_err_e err;
       psaddr_t address;
-      thread_db_info *info = get_thread_db_info (ptid.pid ());
+      thread_db_info *info = get_thread_db_info (beneath, ptid.pid ());
       thread_db_thread_info *priv = get_thread_db_thread_info (thread_info);
 
       /* Finally, get the address of the variable.  */
@@ -1765,44 +1805,45 @@ thread_db_target::get_thread_local_address (ptid_t ptid,
          /* Now, if libthread_db provided the initialization image's
             address, we *could* try to build a non-lvalue value from
             the initialization image.  */
-        throw_error (TLS_NOT_ALLOCATED_YET_ERROR,
-                     _("TLS not allocated yet"));
+       throw_error (TLS_NOT_ALLOCATED_YET_ERROR,
+                    _("TLS not allocated yet"));
 #endif
 
       /* Something else went wrong.  */
       if (err != TD_OK)
-        throw_error (TLS_GENERIC_ERROR,
-                     (("%s")), thread_db_err_str (err));
+       throw_error (TLS_GENERIC_ERROR,
+                    (("%s")), thread_db_err_str (err));
 
       /* Cast assuming host == target.  Joy.  */
       /* Do proper sign extension for the target.  */
-      gdb_assert (exec_bfd);
-      return (bfd_get_sign_extend_vma (exec_bfd) > 0
+      gdb_assert (current_program_space->exec_bfd ());
+      return (bfd_get_sign_extend_vma (current_program_space->exec_bfd ()) > 0
              ? (CORE_ADDR) (intptr_t) address
              : (CORE_ADDR) (uintptr_t) address);
     }
 
-  return beneath ()->get_thread_local_address (ptid, lm, offset);
+  return beneath->get_thread_local_address (ptid, lm, offset);
 }
 
 /* Implement the to_get_ada_task_ptid target method for this target.  */
 
 ptid_t
-thread_db_target::get_ada_task_ptid (long lwp, long thread)
+thread_db_target::get_ada_task_ptid (long lwp, ULONGEST thread)
 {
   /* NPTL uses a 1:1 model, so the LWP id suffices.  */
-  return ptid_t (inferior_ptid.pid (), lwp, 0);
+  return ptid_t (inferior_ptid.pid (), lwp);
 }
 
 void
 thread_db_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
-  struct thread_db_info *info;
+  process_stratum_target *beneath
+    = as_process_stratum_target (this->beneath ());
 
-  if (ptid == minus_one_ptid)
-    info = get_thread_db_info (inferior_ptid.pid ());
-  else
-    info = get_thread_db_info (ptid.pid ());
+  thread_db_info *info
+    = get_thread_db_info (beneath, (ptid == minus_one_ptid
+                                   ? inferior_ptid.pid ()
+                                   : ptid.pid ()));
 
   /* This workaround is only needed for child fork lwps stopped in a
      PTRACE_O_TRACEFORK event.  When the inferior is resumed, the
@@ -1810,7 +1851,7 @@ thread_db_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
   if (info)
     info->need_stale_parent_threads_check = 0;
 
-  beneath ()->resume (ptid, step, signo);
+  beneath->resume (ptid, step, signo);
 }
 
 /* std::sort helper function for info_auto_load_libthread_db, sort the
@@ -1903,7 +1944,8 @@ info_auto_load_libthread_db (const char *args, int from_tty)
        ui_out_emit_tuple tuple_emitter (uiout, NULL);
 
        info = array[i];
-       uiout->field_string ("filename", info->filename);
+       uiout->field_string ("filename", info->filename,
+                            file_name_style.style ());
 
        std::string pids;
        while (i < array.size () && strcmp (info->filename,
@@ -1915,7 +1957,7 @@ info_auto_load_libthread_db (const char *args, int from_tty)
            i++;
          }
 
-       uiout->field_string ("pids", pids.c_str ());
+       uiout->field_string ("pids", pids);
 
        uiout->text ("\n");
       }
@@ -1936,15 +1978,17 @@ maintenance_check_libthread_db (const char *args, int from_tty)
   if (inferior_pid == 0)
     error (_("No inferior running"));
 
-  info = get_thread_db_info (inferior_pid);
+  info = get_thread_db_info (current_inferior ()->process_target (),
+                            inferior_pid);
   if (info == NULL)
     error (_("No libthread_db loaded"));
 
   check_thread_db (info, true);
 }
 
+void _initialize_thread_db ();
 void
-_initialize_thread_db (void)
+_initialize_thread_db ()
 {
   /* Defer loading of libthread_db.so until inferior is running.
      This allows gdb to load correct libthread_db for a given
@@ -1952,8 +1996,6 @@ _initialize_thread_db (void)
      and until there is a running inferior, we can't tell which
      libthread_db is the correct one to load.  */
 
-  libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH);
-
   add_setshow_optional_filename_cmd ("libthread-db-search-path",
                                     class_support,
                                     &libthread_db_search_path, _("\
@@ -1983,7 +2025,7 @@ Show whether auto-loading inferior specific libthread_db is enabled."), _("\
 If enabled, libthread_db will be searched in 'set libthread-db-search-path'\n\
 locations to load libthread_db compatible with the inferior.\n\
 Standard system libthread_db still gets loaded even with this option off.\n\
-This options has security implications for untrusted inferiors."),
+This option has security implications for untrusted inferiors."),
                           NULL, show_auto_load_thread_db,
                           auto_load_set_cmdlist_get (),
                           auto_load_show_cmdlist_get ());
@@ -2011,10 +2053,11 @@ as they are loaded."),
                           &maintenance_show_cmdlist);
 
   /* Add ourselves to objfile event chain.  */
-  gdb::observers::new_objfile.attach (thread_db_new_objfile);
+  gdb::observers::new_objfile.attach (thread_db_new_objfile, "linux-thread-db");
 
   /* Add ourselves to inferior_created event chain.
      This is needed to handle debugging statically linked programs where
      the new_objfile observer won't get called for libpthread.  */
-  gdb::observers::inferior_created.attach (thread_db_inferior_created);
+  gdb::observers::inferior_created.attach (thread_db_inferior_created,
+                                          "linux-thread-db");
 }