1.1 --- a/patches/gdb/6.3/710-debian_thread-db-multiple-libraries.patch Tue Aug 14 19:32:22 2007 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,593 +0,0 @@
1.4 -Support loading two libthread_db DSOs. In this case, the LinuxThreads
1.5 -and NPTL ones.
1.6 -
1.7 -Index: gdb-6.3/gdb/thread-db.c
1.8 -===================================================================
1.9 ---- gdb-6.3.orig/gdb/thread-db.c 2004-11-10 10:46:24.000000000 -0500
1.10 -+++ gdb-6.3/gdb/thread-db.c 2004-11-10 11:22:34.858812426 -0500
1.11 -@@ -79,53 +79,63 @@ static td_thragent_t *thread_agent;
1.12 -
1.13 - /* Pointers to the libthread_db functions. */
1.14 -
1.15 --static td_err_e (*td_init_p) (void);
1.16 -+struct thread_db_pointers
1.17 -+{
1.18 -+ const char *filename;
1.19 -+
1.20 -+ td_err_e (*td_init_p) (void);
1.21 -
1.22 --static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
1.23 -- td_thragent_t **ta);
1.24 --static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
1.25 -- td_thrhandle_t *__th);
1.26 --static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
1.27 -- lwpid_t lwpid, td_thrhandle_t *th);
1.28 --static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
1.29 -- td_thr_iter_f *callback, void *cbdata_p,
1.30 -- td_thr_state_e state, int ti_pri,
1.31 -- sigset_t *ti_sigmask_p,
1.32 -- unsigned int ti_user_flags);
1.33 --static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
1.34 -- td_event_e event, td_notify_t *ptr);
1.35 --static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
1.36 -- td_thr_events_t *event);
1.37 --static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
1.38 -- td_event_msg_t *msg);
1.39 --
1.40 --static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
1.41 --static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
1.42 -- td_thrinfo_t *infop);
1.43 --static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
1.44 -- gdb_prfpregset_t *regset);
1.45 --static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
1.46 -- prgregset_t gregs);
1.47 --static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
1.48 -- const gdb_prfpregset_t *fpregs);
1.49 --static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
1.50 -- prgregset_t gregs);
1.51 --static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
1.52 -- int event);
1.53 --
1.54 --static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
1.55 -- void *map_address,
1.56 -- size_t offset, void **address);
1.57 -+ td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
1.58 -+ td_thragent_t **ta);
1.59 -+ td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
1.60 -+ td_thrhandle_t *__th);
1.61 -+ td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
1.62 -+ lwpid_t lwpid, td_thrhandle_t *th);
1.63 -+
1.64 -+ td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
1.65 -+ td_thr_iter_f *callback, void *cbdata_p,
1.66 -+ td_thr_state_e state, int ti_pri,
1.67 -+ sigset_t *ti_sigmask_p,
1.68 -+ unsigned int ti_user_flags);
1.69 -+ td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
1.70 -+ td_event_e event, td_notify_t *ptr);
1.71 -+ td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
1.72 -+ td_thr_events_t *event);
1.73 -+ td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
1.74 -+ td_event_msg_t *msg);
1.75 -+
1.76 -+ td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
1.77 -+ td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
1.78 -+ td_thrinfo_t *infop);
1.79 -+ td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
1.80 -+ gdb_prfpregset_t *regset);
1.81 -+ td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
1.82 -+ prgregset_t gregs);
1.83 -+ td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
1.84 -+ const gdb_prfpregset_t *fpregs);
1.85 -+ td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
1.86 -+ prgregset_t gregs);
1.87 -+ td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
1.88 -+ int event);
1.89 -+
1.90 -+ td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
1.91 -+ void *map_address,
1.92 -+ size_t offset, void **address);
1.93 -+
1.94 -+ struct thread_db_pointers *next;
1.95 -+};
1.96 -
1.97 - /* Location of the thread creation event breakpoint. The code at this
1.98 - location in the child process will be called by the pthread library
1.99 - whenever a new thread is created. By setting a special breakpoint
1.100 - at this location, GDB can detect when a new thread is created. We
1.101 - obtain this location via the td_ta_event_addr call. */
1.102 --static CORE_ADDR td_create_bp_addr;
1.103 -+CORE_ADDR td_create_bp_addr;
1.104 -
1.105 - /* Location of the thread death event breakpoint. */
1.106 --static CORE_ADDR td_death_bp_addr;
1.107 -+CORE_ADDR td_death_bp_addr;
1.108 -+
1.109 -+static struct thread_db_pointers *current_pointers, *all_pointers;
1.110 -
1.111 - /* Prototypes for local functions. */
1.112 - static void thread_db_find_new_threads (void);
1.113 -@@ -262,7 +272,7 @@ thread_get_info_callback (const td_thrha
1.114 - struct thread_info *thread_info;
1.115 - ptid_t thread_ptid;
1.116 -
1.117 -- err = td_thr_get_info_p (thp, &ti);
1.118 -+ err = current_pointers->td_thr_get_info_p (thp, &ti);
1.119 - if (err != TD_OK)
1.120 - error ("thread_get_info_callback: cannot get thread info: %s",
1.121 - thread_db_err_str (err));
1.122 -@@ -316,8 +326,9 @@ thread_db_map_id2thr (struct thread_info
1.123 - if (thread_info->private->th_valid)
1.124 - return;
1.125 -
1.126 -- err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
1.127 -- &thread_info->private->th);
1.128 -+ err = current_pointers->td_ta_map_id2thr_p (thread_agent,
1.129 -+ GET_THREAD (thread_info->ptid),
1.130 -+ &thread_info->private->th);
1.131 - if (err != TD_OK)
1.132 - {
1.133 - if (fatal)
1.134 -@@ -340,8 +351,8 @@ thread_db_get_info (struct thread_info *
1.135 - if (!thread_info->private->th_valid)
1.136 - thread_db_map_id2thr (thread_info, 1);
1.137 -
1.138 -- err =
1.139 -- td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
1.140 -+ err = current_pointers->td_thr_get_info_p (&thread_info->private->th,
1.141 -+ &thread_info->private->ti);
1.142 - if (err != TD_OK)
1.143 - error ("thread_db_get_info: cannot get thread info: %s",
1.144 - thread_db_err_str (err));
1.145 -@@ -365,7 +376,8 @@ thread_from_lwp (ptid_t ptid)
1.146 -
1.147 - gdb_assert (is_lwp (ptid));
1.148 -
1.149 -- err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
1.150 -+ err = current_pointers->td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid),
1.151 -+ &th);
1.152 - if (err != TD_OK)
1.153 - error ("Cannot find user-level thread for LWP %ld: %s",
1.154 - GET_LWP (ptid), thread_db_err_str (err));
1.155 -@@ -420,85 +432,102 @@ verbose_dlsym (void *handle, const char
1.156 - return sym;
1.157 - }
1.158 -
1.159 --static int
1.160 --thread_db_load (void)
1.161 -+static struct thread_db_pointers *
1.162 -+thread_db_load (const char *name)
1.163 - {
1.164 -+ struct thread_db_pointers *ptrs;
1.165 -+ Dl_info info;
1.166 - void *handle;
1.167 - td_err_e err;
1.168 -
1.169 -- handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
1.170 -+ ptrs = xcalloc (1, sizeof (struct thread_db_pointers));
1.171 -+
1.172 -+ handle = dlopen (name, RTLD_NOW);
1.173 - if (handle == NULL)
1.174 - {
1.175 -- fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
1.176 -- LIBTHREAD_DB_SO, dlerror ());
1.177 -- fprintf_filtered (gdb_stderr,
1.178 -- "GDB will not be able to debug pthreads.\n\n");
1.179 -+ if (all_pointers == NULL)
1.180 -+ {
1.181 -+ fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
1.182 -+ name, dlerror ());
1.183 -+ fprintf_filtered (gdb_stderr,
1.184 -+ "GDB will not be able to debug pthreads.\n\n");
1.185 -+ }
1.186 - return 0;
1.187 - }
1.188 -
1.189 - /* Initialize pointers to the dynamic library functions we will use.
1.190 - Essential functions first. */
1.191 -
1.192 -- td_init_p = verbose_dlsym (handle, "td_init");
1.193 -- if (td_init_p == NULL)
1.194 -+ ptrs->td_init_p = verbose_dlsym (handle, "td_init");
1.195 -+ if (ptrs->td_init_p == NULL)
1.196 - return 0;
1.197 -
1.198 -- td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
1.199 -- if (td_ta_new_p == NULL)
1.200 -+ ptrs->td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
1.201 -+ if (ptrs->td_ta_new_p == NULL)
1.202 - return 0;
1.203 -
1.204 -- td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
1.205 -- if (td_ta_map_id2thr_p == NULL)
1.206 -+ ptrs->td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
1.207 -+ if (ptrs->td_ta_map_id2thr_p == NULL)
1.208 - return 0;
1.209 -
1.210 -- td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
1.211 -- if (td_ta_map_lwp2thr_p == NULL)
1.212 -+ ptrs->td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
1.213 -+ if (ptrs->td_ta_map_lwp2thr_p == NULL)
1.214 - return 0;
1.215 -
1.216 -- td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
1.217 -- if (td_ta_thr_iter_p == NULL)
1.218 -+ ptrs->td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
1.219 -+ if (ptrs->td_ta_thr_iter_p == NULL)
1.220 - return 0;
1.221 -
1.222 -- td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
1.223 -- if (td_thr_validate_p == NULL)
1.224 -+ ptrs->td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
1.225 -+ if (ptrs->td_thr_validate_p == NULL)
1.226 - return 0;
1.227 -
1.228 -- td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
1.229 -- if (td_thr_get_info_p == NULL)
1.230 -+ ptrs->td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
1.231 -+ if (ptrs->td_thr_get_info_p == NULL)
1.232 - return 0;
1.233 -
1.234 -- td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
1.235 -- if (td_thr_getfpregs_p == NULL)
1.236 -+ ptrs->td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
1.237 -+ if (ptrs->td_thr_getfpregs_p == NULL)
1.238 - return 0;
1.239 -
1.240 -- td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
1.241 -- if (td_thr_getgregs_p == NULL)
1.242 -+ ptrs->td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
1.243 -+ if (ptrs->td_thr_getgregs_p == NULL)
1.244 - return 0;
1.245 -
1.246 -- td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
1.247 -- if (td_thr_setfpregs_p == NULL)
1.248 -+ ptrs->td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
1.249 -+ if (ptrs->td_thr_setfpregs_p == NULL)
1.250 - return 0;
1.251 -
1.252 -- td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
1.253 -- if (td_thr_setgregs_p == NULL)
1.254 -+ ptrs->td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
1.255 -+ if (ptrs->td_thr_setgregs_p == NULL)
1.256 - return 0;
1.257 -
1.258 - /* Initialize the library. */
1.259 -- err = td_init_p ();
1.260 -+ err = ptrs->td_init_p ();
1.261 - if (err != TD_OK)
1.262 - {
1.263 - warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
1.264 -+ xfree (ptrs);
1.265 - return 0;
1.266 - }
1.267 -
1.268 - /* These are not essential. */
1.269 -- td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
1.270 -- td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
1.271 -- td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
1.272 -- td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
1.273 -- td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
1.274 -+ ptrs->td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
1.275 -+ ptrs->td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
1.276 -+ ptrs->td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
1.277 -+ ptrs->td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
1.278 -+ ptrs->td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
1.279 -+
1.280 -+ if (dladdr (ptrs->td_ta_new_p, &info) != 0)
1.281 -+ ptrs->filename = info.dli_fname;
1.282 -+
1.283 -+ /* Try dlinfo? */
1.284 -+
1.285 -+ if (ptrs->filename == NULL)
1.286 -+ /* Paranoid - don't let a NULL path slip through. */
1.287 -+ ptrs->filename = name;
1.288 -
1.289 -- return 1;
1.290 -+ return ptrs;
1.291 - }
1.292 -
1.293 - static td_err_e
1.294 -@@ -508,7 +537,7 @@ enable_thread_event (td_thragent_t *thre
1.295 - td_err_e err;
1.296 -
1.297 - /* Get the breakpoint address for thread EVENT. */
1.298 -- err = td_ta_event_addr_p (thread_agent, event, ¬ify);
1.299 -+ err = current_pointers->td_ta_event_addr_p (thread_agent, event, ¬ify);
1.300 - if (err != TD_OK)
1.301 - return err;
1.302 -
1.303 -@@ -534,8 +563,10 @@ enable_thread_event_reporting (void)
1.304 -
1.305 - /* We cannot use the thread event reporting facility if these
1.306 - functions aren't available. */
1.307 -- if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
1.308 -- || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
1.309 -+ if (current_pointers->td_ta_event_addr_p == NULL
1.310 -+ || current_pointers->td_ta_set_event_p == NULL
1.311 -+ || current_pointers->td_ta_event_getmsg_p == NULL
1.312 -+ || current_pointers->td_thr_event_enable_p == NULL)
1.313 - return;
1.314 -
1.315 - /* Set the process wide mask saying which events we're interested in. */
1.316 -@@ -552,7 +583,7 @@ enable_thread_event_reporting (void)
1.317 - #endif
1.318 - td_event_addset (&events, TD_DEATH);
1.319 -
1.320 -- err = td_ta_set_event_p (thread_agent, &events);
1.321 -+ err = current_pointers->td_ta_set_event_p (thread_agent, &events);
1.322 - if (err != TD_OK)
1.323 - {
1.324 - warning ("Unable to set global thread event mask: %s",
1.325 -@@ -592,7 +623,7 @@ disable_thread_event_reporting (void)
1.326 - /* Set the process wide mask saying we aren't interested in any
1.327 - events anymore. */
1.328 - td_event_emptyset (&events);
1.329 -- td_ta_set_event_p (thread_agent, &events);
1.330 -+ current_pointers->td_ta_set_event_p (thread_agent, &events);
1.331 -
1.332 - /* Delete thread event breakpoints, if any. */
1.333 - remove_thread_event_breakpoints ();
1.334 -@@ -635,7 +666,6 @@ check_thread_signals (void)
1.335 - static void
1.336 - check_for_thread_db (void)
1.337 - {
1.338 -- td_err_e err;
1.339 - static int already_loaded;
1.340 -
1.341 - /* First time through, report that libthread_db was successfuly
1.342 -@@ -644,19 +674,8 @@ check_for_thread_db (void)
1.343 -
1.344 - if (!already_loaded)
1.345 - {
1.346 -- Dl_info info;
1.347 -- const char *library = NULL;
1.348 -- if (dladdr ((*td_ta_new_p), &info) != 0)
1.349 -- library = info.dli_fname;
1.350 --
1.351 -- /* Try dlinfo? */
1.352 --
1.353 -- if (library == NULL)
1.354 -- /* Paranoid - don't let a NULL path slip through. */
1.355 -- library = LIBTHREAD_DB_SO;
1.356 --
1.357 - printf_unfiltered ("Using host libthread_db library \"%s\".\n",
1.358 -- library);
1.359 -+ all_pointers->filename);
1.360 - already_loaded = 1;
1.361 - }
1.362 -
1.363 -@@ -674,28 +693,34 @@ check_for_thread_db (void)
1.364 - proc_handle.pid = GET_PID (inferior_ptid);
1.365 -
1.366 - /* Now attempt to open a connection to the thread library. */
1.367 -- err = td_ta_new_p (&proc_handle, &thread_agent);
1.368 -- switch (err)
1.369 -+ for (current_pointers = all_pointers;
1.370 -+ current_pointers != NULL;
1.371 -+ current_pointers = current_pointers->next)
1.372 - {
1.373 -- case TD_NOLIBTHREAD:
1.374 -- /* No thread library was detected. */
1.375 -- break;
1.376 --
1.377 -- case TD_OK:
1.378 -- printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
1.379 -+ td_err_e err;
1.380 -+ err = current_pointers->td_ta_new_p (&proc_handle, &thread_agent);
1.381 -+ switch (err)
1.382 -+ {
1.383 -+ case TD_NOLIBTHREAD:
1.384 -+ /* No thread library was detected. */
1.385 -+ break;
1.386 -
1.387 -- /* The thread library was detected. Activate the thread_db target. */
1.388 -- push_target (&thread_db_ops);
1.389 -- using_thread_db = 1;
1.390 -+ case TD_OK:
1.391 -+ printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
1.392 -
1.393 -- enable_thread_event_reporting ();
1.394 -- thread_db_find_new_threads ();
1.395 -- break;
1.396 -+ /* The thread library was detected. Activate the thread_db target. */
1.397 -+ push_target (&thread_db_ops);
1.398 -+ using_thread_db = 1;
1.399 -+
1.400 -+ enable_thread_event_reporting ();
1.401 -+ thread_db_find_new_threads ();
1.402 -+ return;
1.403 -
1.404 -- default:
1.405 -- warning ("Cannot initialize thread debugging library: %s",
1.406 -- thread_db_err_str (err));
1.407 -- break;
1.408 -+ default:
1.409 -+ warning ("Cannot initialize thread debugging library: %s",
1.410 -+ thread_db_err_str (err));
1.411 -+ break;
1.412 -+ }
1.413 - }
1.414 - }
1.415 -
1.416 -@@ -766,7 +791,7 @@ attach_thread (ptid_t ptid, const td_thr
1.417 - #endif
1.418 -
1.419 - /* Enable thread event reporting for this thread. */
1.420 -- err = td_thr_event_enable_p (th_p, 1);
1.421 -+ err = current_pointers->td_thr_event_enable_p (th_p, 1);
1.422 - if (err != TD_OK)
1.423 - error ("Cannot enable thread event reporting for %s: %s",
1.424 - target_pid_to_str (ptid), thread_db_err_str (err));
1.425 -@@ -892,7 +917,7 @@ check_event (ptid_t ptid)
1.426 -
1.427 - do
1.428 - {
1.429 -- err = td_ta_event_getmsg_p (thread_agent, &msg);
1.430 -+ err = current_pointers->td_ta_event_getmsg_p (thread_agent, &msg);
1.431 - if (err != TD_OK)
1.432 - {
1.433 - if (err == TD_NOMSG)
1.434 -@@ -902,7 +927,7 @@ check_event (ptid_t ptid)
1.435 - thread_db_err_str (err));
1.436 - }
1.437 -
1.438 -- err = td_thr_get_info_p (msg.th_p, &ti);
1.439 -+ err = current_pointers->td_thr_get_info_p (msg.th_p, &ti);
1.440 - if (err != TD_OK)
1.441 - error ("Cannot get thread info: %s", thread_db_err_str (err));
1.442 -
1.443 -@@ -1015,12 +1040,14 @@ thread_db_fetch_registers (int regno)
1.444 - thread_info = find_thread_pid (inferior_ptid);
1.445 - thread_db_map_id2thr (thread_info, 1);
1.446 -
1.447 -- err = td_thr_getgregs_p (&thread_info->private->th, gregset);
1.448 -+ err = current_pointers->td_thr_getgregs_p (&thread_info->private->th,
1.449 -+ gregset);
1.450 - if (err != TD_OK)
1.451 - error ("Cannot fetch general-purpose registers for thread %ld: %s",
1.452 - (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1.453 -
1.454 -- err = td_thr_getfpregs_p (&thread_info->private->th, &fpregset);
1.455 -+ err = current_pointers->td_thr_getfpregs_p (&thread_info->private->th,
1.456 -+ &fpregset);
1.457 - if (err != TD_OK)
1.458 - error ("Cannot get floating-point registers for thread %ld: %s",
1.459 - (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1.460 -@@ -1062,11 +1089,13 @@ thread_db_store_registers (int regno)
1.461 - fill_gregset ((gdb_gregset_t *) gregset, -1);
1.462 - fill_fpregset (&fpregset, -1);
1.463 -
1.464 -- err = td_thr_setgregs_p (&thread_info->private->th, gregset);
1.465 -+ err = current_pointers->td_thr_setgregs_p (&thread_info->private->th,
1.466 -+ gregset);
1.467 - if (err != TD_OK)
1.468 - error ("Cannot store general-purpose registers for thread %ld: %s",
1.469 - (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1.470 -- err = td_thr_setfpregs_p (&thread_info->private->th, &fpregset);
1.471 -+ err = current_pointers->td_thr_setfpregs_p (&thread_info->private->th,
1.472 -+ &fpregset);
1.473 - if (err != TD_OK)
1.474 - error ("Cannot store floating-point registers for thread %ld: %s",
1.475 - (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
1.476 -@@ -1136,15 +1165,14 @@ thread_db_thread_alive (ptid_t ptid)
1.477 - if (!thread_info->private->th_valid)
1.478 - return 0;
1.479 -
1.480 -- err = td_thr_validate_p (&thread_info->private->th);
1.481 -+ err = current_pointers->td_thr_validate_p (&thread_info->private->th);
1.482 - if (err != TD_OK)
1.483 - return 0;
1.484 -
1.485 - if (!thread_info->private->ti_valid)
1.486 - {
1.487 -- err =
1.488 -- td_thr_get_info_p (&thread_info->private->th,
1.489 -- &thread_info->private->ti);
1.490 -+ err = current_pointers->td_thr_get_info_p
1.491 -+ (&thread_info->private->th, &thread_info->private->ti);
1.492 - if (err != TD_OK)
1.493 - return 0;
1.494 - thread_info->private->ti_valid = 1;
1.495 -@@ -1170,7 +1198,7 @@ find_new_threads_callback (const td_thrh
1.496 - td_err_e err;
1.497 - ptid_t ptid;
1.498 -
1.499 -- err = td_thr_get_info_p (th_p, &ti);
1.500 -+ err = current_pointers->td_thr_get_info_p (th_p, &ti);
1.501 - if (err != TD_OK)
1.502 - error ("find_new_threads_callback: cannot get thread info: %s",
1.503 - thread_db_err_str (err));
1.504 -@@ -1192,9 +1220,10 @@ thread_db_find_new_threads (void)
1.505 - td_err_e err;
1.506 -
1.507 - /* Iterate over all user-space threads to discover new threads. */
1.508 -- err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
1.509 -- TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1.510 -- TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1.511 -+ err = current_pointers->td_ta_thr_iter_p
1.512 -+ (thread_agent, find_new_threads_callback, NULL,
1.513 -+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1.514 -+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1.515 - if (err != TD_OK)
1.516 - error ("Cannot find new threads: %s", thread_db_err_str (err));
1.517 - }
1.518 -@@ -1257,7 +1286,7 @@ thread_db_get_thread_local_address (ptid
1.519 - struct thread_info *thread_info;
1.520 -
1.521 - /* glibc doesn't provide the needed interface. */
1.522 -- if (!td_thr_tls_get_addr_p)
1.523 -+ if (!current_pointers->td_thr_tls_get_addr_p)
1.524 - error ("Cannot find thread-local variables in this thread library.");
1.525 -
1.526 - /* Get the address of the link map for this objfile. */
1.527 -@@ -1279,8 +1308,8 @@ thread_db_get_thread_local_address (ptid
1.528 - thread_db_map_id2thr (thread_info, 1);
1.529 -
1.530 - /* Finally, get the address of the variable. */
1.531 -- err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *) lm,
1.532 -- offset, &address);
1.533 -+ err = current_pointers->td_thr_tls_get_addr_p
1.534 -+ (&thread_info->private->th, (void *) lm, offset, &address);
1.535 -
1.536 - #ifdef THREAD_DB_HAS_TD_NOTALLOC
1.537 - /* The memory hasn't been allocated, yet. */
1.538 -@@ -1360,17 +1389,49 @@ init_thread_db_ops (void)
1.539 - void
1.540 - _initialize_thread_db (void)
1.541 - {
1.542 -+ struct thread_db_pointers *ptrs;
1.543 -+ const char *p;
1.544 -+
1.545 - /* Only initialize the module if we can load libthread_db. */
1.546 -- if (thread_db_load ())
1.547 -- {
1.548 -- init_thread_db_ops ();
1.549 -- add_target (&thread_db_ops);
1.550 -+ ptrs = thread_db_load (LIBTHREAD_DB_SO);
1.551 -+ if (ptrs == NULL)
1.552 -+ return;
1.553 -+
1.554 -+ all_pointers = ptrs;
1.555 -
1.556 -- /* Add ourselves to objfile event chain. */
1.557 -- target_new_objfile_chain = deprecated_target_new_objfile_hook;
1.558 -- deprecated_target_new_objfile_hook = thread_db_new_objfile;
1.559 -+ /* Some GNU/Linux systems have more than one binary-compatible copy
1.560 -+ of libthread_db. If we can find a second one, load that too.
1.561 -+ The inferior may force the use of a different threading package
1.562 -+ than we expect. Our guess for the location is somewhat hokey:
1.563 -+ strip out anything between /lib (or /lib64) and LIBTHREAD_DB_SO.
1.564 -+ If we loaded the NPTL libthread_db by default, this may find us
1.565 -+ the LinuxThreads copy. */
1.566 -+ p = strrchr (ptrs->filename, '/');
1.567 -+ while (p != NULL && p > ptrs->filename)
1.568 -+ {
1.569 -+ const char *component;
1.570 -
1.571 -- /* Register ourselves for the new inferior observer. */
1.572 -- observer_attach_inferior_created (check_for_thread_db_observer);
1.573 -+ component = memrchr (ptrs->filename, '/', p - ptrs->filename);
1.574 -+ if (component != NULL && strncmp (component, "/lib", 4) == 0)
1.575 -+ {
1.576 -+ char *new_name = xmalloc (p - ptrs->filename + 2
1.577 -+ + strlen (LIBTHREAD_DB_SO));
1.578 -+ memcpy (new_name, ptrs->filename, p - ptrs->filename + 1);
1.579 -+ strcpy (new_name + (p - ptrs->filename) + 1, LIBTHREAD_DB_SO);
1.580 -+ ptrs->next = thread_db_load (new_name);
1.581 -+ xfree (new_name);
1.582 -+ break;
1.583 -+ }
1.584 -+ p = component;
1.585 - }
1.586 -+
1.587 -+ init_thread_db_ops ();
1.588 -+ add_target (&thread_db_ops);
1.589 -+
1.590 -+ /* Add ourselves to objfile event chain. */
1.591 -+ target_new_objfile_chain = deprecated_target_new_objfile_hook;
1.592 -+ deprecated_target_new_objfile_hook = thread_db_new_objfile;
1.593 -+
1.594 -+ /* Register ourselves for the new inferior observer. */
1.595 -+ observer_attach_inferior_created (check_for_thread_db_observer);
1.596 - }