+/* Subroutine of try_thread_db_load_from_pdir to simplify it.
+ Try loading libthread_db in directory(OBJ)/SUBDIR.
+ SUBDIR may be NULL. It may also be something like "../lib64".
+ The result is true for success. */
+
+static bool
+try_thread_db_load_from_pdir_1 (struct objfile *obj, const char *subdir)
+{
+ const char *obj_name = objfile_name (obj);
+
+ if (obj_name[0] != '/')
+ {
+ warning (_("Expected absolute pathname for libpthread in the"
+ " inferior, but got %ps."),
+ styled_string (file_name_style.style (), obj_name));
+ return false;
+ }
+
+ std::string path = obj_name;
+ size_t cp = path.rfind ('/');
+ /* This should at minimum hit the first character. */
+ gdb_assert (cp != std::string::npos);
+ path.resize (cp + 1);
+ if (subdir != NULL)
+ path = path + subdir + "/";
+ path += LIBTHREAD_DB_SO;
+
+ return try_thread_db_load (path.c_str (), true);
+}
+
+/* Handle $pdir in libthread-db-search-path.
+ Look for libthread_db in directory(libpthread)/SUBDIR.
+ SUBDIR may be NULL. It may also be something like "../lib64".
+ The result is true for success. */
+
+static bool
+try_thread_db_load_from_pdir (const char *subdir)
+{
+ if (!auto_load_thread_db)
+ return false;
+
+ for (objfile *obj : current_program_space->objfiles ())
+ if (libpthread_name_p (objfile_name (obj)))
+ {
+ if (try_thread_db_load_from_pdir_1 (obj, subdir))
+ return true;
+
+ /* We may have found the separate-debug-info version of
+ libpthread, and it may live in a directory without a matching
+ libthread_db. */
+ if (obj->separate_debug_objfile_backlink != NULL)
+ return try_thread_db_load_from_pdir_1 (obj->separate_debug_objfile_backlink,
+ subdir);
+
+ return false;
+ }
+
+ return false;
+}
+
+/* Handle $sdir in libthread-db-search-path.
+ Look for libthread_db in the system dirs, or wherever a plain
+ dlopen(file_without_path) will look.
+ The result is true for success. */
+
+static bool
+try_thread_db_load_from_sdir (void)
+{
+ 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 bool
+try_thread_db_load_from_dir (const char *dir, size_t dir_len)
+{
+ if (!auto_load_thread_db)
+ return false;
+
+ std::string path = std::string (dir, dir_len) + "/" + LIBTHREAD_DB_SO;
+
+ return try_thread_db_load (path.c_str (), true);
+}