build system refactoring in preparation for allowing packages to do host-build steps
[openwrt/openwrt.git] / toolchain / gdb / patches / 710-debian_thread-db-multiple-libraries.patch
1 Support loading two libthread_db DSOs. In this case, the LinuxThreads
2 and NPTL ones.
3
4 Index: gdb-6.3/gdb/thread-db.c
5 ===================================================================
6 --- gdb-6.3.orig/gdb/thread-db.c 2004-11-10 10:46:24.000000000 -0500
7 +++ gdb-6.3/gdb/thread-db.c 2004-11-10 11:22:34.858812426 -0500
8 @@ -79,53 +79,63 @@ static td_thragent_t *thread_agent;
9
10 /* Pointers to the libthread_db functions. */
11
12 -static td_err_e (*td_init_p) (void);
13 +struct thread_db_pointers
14 +{
15 + const char *filename;
16 +
17 + td_err_e (*td_init_p) (void);
18
19 -static td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
20 - td_thragent_t **ta);
21 -static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
22 - td_thrhandle_t *__th);
23 -static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
24 - lwpid_t lwpid, td_thrhandle_t *th);
25 -static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
26 - td_thr_iter_f *callback, void *cbdata_p,
27 - td_thr_state_e state, int ti_pri,
28 - sigset_t *ti_sigmask_p,
29 - unsigned int ti_user_flags);
30 -static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
31 - td_event_e event, td_notify_t *ptr);
32 -static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
33 - td_thr_events_t *event);
34 -static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
35 - td_event_msg_t *msg);
36 -
37 -static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
38 -static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
39 - td_thrinfo_t *infop);
40 -static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
41 - gdb_prfpregset_t *regset);
42 -static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
43 - prgregset_t gregs);
44 -static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
45 - const gdb_prfpregset_t *fpregs);
46 -static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
47 - prgregset_t gregs);
48 -static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
49 - int event);
50 -
51 -static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
52 - void *map_address,
53 - size_t offset, void **address);
54 + td_err_e (*td_ta_new_p) (struct ps_prochandle * ps,
55 + td_thragent_t **ta);
56 + td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
57 + td_thrhandle_t *__th);
58 + td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta,
59 + lwpid_t lwpid, td_thrhandle_t *th);
60 +
61 + td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
62 + td_thr_iter_f *callback, void *cbdata_p,
63 + td_thr_state_e state, int ti_pri,
64 + sigset_t *ti_sigmask_p,
65 + unsigned int ti_user_flags);
66 + td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
67 + td_event_e event, td_notify_t *ptr);
68 + td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
69 + td_thr_events_t *event);
70 + td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
71 + td_event_msg_t *msg);
72 +
73 + td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
74 + td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
75 + td_thrinfo_t *infop);
76 + td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
77 + gdb_prfpregset_t *regset);
78 + td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
79 + prgregset_t gregs);
80 + td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
81 + const gdb_prfpregset_t *fpregs);
82 + td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
83 + prgregset_t gregs);
84 + td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th,
85 + int event);
86 +
87 + td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
88 + void *map_address,
89 + size_t offset, void **address);
90 +
91 + struct thread_db_pointers *next;
92 +};
93
94 /* Location of the thread creation event breakpoint. The code at this
95 location in the child process will be called by the pthread library
96 whenever a new thread is created. By setting a special breakpoint
97 at this location, GDB can detect when a new thread is created. We
98 obtain this location via the td_ta_event_addr call. */
99 -static CORE_ADDR td_create_bp_addr;
100 +CORE_ADDR td_create_bp_addr;
101
102 /* Location of the thread death event breakpoint. */
103 -static CORE_ADDR td_death_bp_addr;
104 +CORE_ADDR td_death_bp_addr;
105 +
106 +static struct thread_db_pointers *current_pointers, *all_pointers;
107
108 /* Prototypes for local functions. */
109 static void thread_db_find_new_threads (void);
110 @@ -262,7 +272,7 @@ thread_get_info_callback (const td_thrha
111 struct thread_info *thread_info;
112 ptid_t thread_ptid;
113
114 - err = td_thr_get_info_p (thp, &ti);
115 + err = current_pointers->td_thr_get_info_p (thp, &ti);
116 if (err != TD_OK)
117 error ("thread_get_info_callback: cannot get thread info: %s",
118 thread_db_err_str (err));
119 @@ -316,8 +326,9 @@ thread_db_map_id2thr (struct thread_info
120 if (thread_info->private->th_valid)
121 return;
122
123 - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
124 - &thread_info->private->th);
125 + err = current_pointers->td_ta_map_id2thr_p (thread_agent,
126 + GET_THREAD (thread_info->ptid),
127 + &thread_info->private->th);
128 if (err != TD_OK)
129 {
130 if (fatal)
131 @@ -340,8 +351,8 @@ thread_db_get_info (struct thread_info *
132 if (!thread_info->private->th_valid)
133 thread_db_map_id2thr (thread_info, 1);
134
135 - err =
136 - td_thr_get_info_p (&thread_info->private->th, &thread_info->private->ti);
137 + err = current_pointers->td_thr_get_info_p (&thread_info->private->th,
138 + &thread_info->private->ti);
139 if (err != TD_OK)
140 error ("thread_db_get_info: cannot get thread info: %s",
141 thread_db_err_str (err));
142 @@ -365,7 +376,8 @@ thread_from_lwp (ptid_t ptid)
143
144 gdb_assert (is_lwp (ptid));
145
146 - err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
147 + err = current_pointers->td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid),
148 + &th);
149 if (err != TD_OK)
150 error ("Cannot find user-level thread for LWP %ld: %s",
151 GET_LWP (ptid), thread_db_err_str (err));
152 @@ -420,85 +432,102 @@ verbose_dlsym (void *handle, const char
153 return sym;
154 }
155
156 -static int
157 -thread_db_load (void)
158 +static struct thread_db_pointers *
159 +thread_db_load (const char *name)
160 {
161 + struct thread_db_pointers *ptrs;
162 + Dl_info info;
163 void *handle;
164 td_err_e err;
165
166 - handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
167 + ptrs = xcalloc (1, sizeof (struct thread_db_pointers));
168 +
169 + handle = dlopen (name, RTLD_NOW);
170 if (handle == NULL)
171 {
172 - fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
173 - LIBTHREAD_DB_SO, dlerror ());
174 - fprintf_filtered (gdb_stderr,
175 - "GDB will not be able to debug pthreads.\n\n");
176 + if (all_pointers == NULL)
177 + {
178 + fprintf_filtered (gdb_stderr, "\n\ndlopen failed on '%s' - %s\n",
179 + name, dlerror ());
180 + fprintf_filtered (gdb_stderr,
181 + "GDB will not be able to debug pthreads.\n\n");
182 + }
183 return 0;
184 }
185
186 /* Initialize pointers to the dynamic library functions we will use.
187 Essential functions first. */
188
189 - td_init_p = verbose_dlsym (handle, "td_init");
190 - if (td_init_p == NULL)
191 + ptrs->td_init_p = verbose_dlsym (handle, "td_init");
192 + if (ptrs->td_init_p == NULL)
193 return 0;
194
195 - td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
196 - if (td_ta_new_p == NULL)
197 + ptrs->td_ta_new_p = verbose_dlsym (handle, "td_ta_new");
198 + if (ptrs->td_ta_new_p == NULL)
199 return 0;
200
201 - td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
202 - if (td_ta_map_id2thr_p == NULL)
203 + ptrs->td_ta_map_id2thr_p = verbose_dlsym (handle, "td_ta_map_id2thr");
204 + if (ptrs->td_ta_map_id2thr_p == NULL)
205 return 0;
206
207 - td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
208 - if (td_ta_map_lwp2thr_p == NULL)
209 + ptrs->td_ta_map_lwp2thr_p = verbose_dlsym (handle, "td_ta_map_lwp2thr");
210 + if (ptrs->td_ta_map_lwp2thr_p == NULL)
211 return 0;
212
213 - td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
214 - if (td_ta_thr_iter_p == NULL)
215 + ptrs->td_ta_thr_iter_p = verbose_dlsym (handle, "td_ta_thr_iter");
216 + if (ptrs->td_ta_thr_iter_p == NULL)
217 return 0;
218
219 - td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
220 - if (td_thr_validate_p == NULL)
221 + ptrs->td_thr_validate_p = verbose_dlsym (handle, "td_thr_validate");
222 + if (ptrs->td_thr_validate_p == NULL)
223 return 0;
224
225 - td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
226 - if (td_thr_get_info_p == NULL)
227 + ptrs->td_thr_get_info_p = verbose_dlsym (handle, "td_thr_get_info");
228 + if (ptrs->td_thr_get_info_p == NULL)
229 return 0;
230
231 - td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
232 - if (td_thr_getfpregs_p == NULL)
233 + ptrs->td_thr_getfpregs_p = verbose_dlsym (handle, "td_thr_getfpregs");
234 + if (ptrs->td_thr_getfpregs_p == NULL)
235 return 0;
236
237 - td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
238 - if (td_thr_getgregs_p == NULL)
239 + ptrs->td_thr_getgregs_p = verbose_dlsym (handle, "td_thr_getgregs");
240 + if (ptrs->td_thr_getgregs_p == NULL)
241 return 0;
242
243 - td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
244 - if (td_thr_setfpregs_p == NULL)
245 + ptrs->td_thr_setfpregs_p = verbose_dlsym (handle, "td_thr_setfpregs");
246 + if (ptrs->td_thr_setfpregs_p == NULL)
247 return 0;
248
249 - td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
250 - if (td_thr_setgregs_p == NULL)
251 + ptrs->td_thr_setgregs_p = verbose_dlsym (handle, "td_thr_setgregs");
252 + if (ptrs->td_thr_setgregs_p == NULL)
253 return 0;
254
255 /* Initialize the library. */
256 - err = td_init_p ();
257 + err = ptrs->td_init_p ();
258 if (err != TD_OK)
259 {
260 warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
261 + xfree (ptrs);
262 return 0;
263 }
264
265 /* These are not essential. */
266 - td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
267 - td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
268 - td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
269 - td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
270 - td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
271 + ptrs->td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
272 + ptrs->td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
273 + ptrs->td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
274 + ptrs->td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
275 + ptrs->td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
276 +
277 + if (dladdr (ptrs->td_ta_new_p, &info) != 0)
278 + ptrs->filename = info.dli_fname;
279 +
280 + /* Try dlinfo? */
281 +
282 + if (ptrs->filename == NULL)
283 + /* Paranoid - don't let a NULL path slip through. */
284 + ptrs->filename = name;
285
286 - return 1;
287 + return ptrs;
288 }
289
290 static td_err_e
291 @@ -508,7 +537,7 @@ enable_thread_event (td_thragent_t *thre
292 td_err_e err;
293
294 /* Get the breakpoint address for thread EVENT. */
295 - err = td_ta_event_addr_p (thread_agent, event, &notify);
296 + err = current_pointers->td_ta_event_addr_p (thread_agent, event, &notify);
297 if (err != TD_OK)
298 return err;
299
300 @@ -534,8 +563,10 @@ enable_thread_event_reporting (void)
301
302 /* We cannot use the thread event reporting facility if these
303 functions aren't available. */
304 - if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
305 - || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
306 + if (current_pointers->td_ta_event_addr_p == NULL
307 + || current_pointers->td_ta_set_event_p == NULL
308 + || current_pointers->td_ta_event_getmsg_p == NULL
309 + || current_pointers->td_thr_event_enable_p == NULL)
310 return;
311
312 /* Set the process wide mask saying which events we're interested in. */
313 @@ -552,7 +583,7 @@ enable_thread_event_reporting (void)
314 #endif
315 td_event_addset (&events, TD_DEATH);
316
317 - err = td_ta_set_event_p (thread_agent, &events);
318 + err = current_pointers->td_ta_set_event_p (thread_agent, &events);
319 if (err != TD_OK)
320 {
321 warning ("Unable to set global thread event mask: %s",
322 @@ -592,7 +623,7 @@ disable_thread_event_reporting (void)
323 /* Set the process wide mask saying we aren't interested in any
324 events anymore. */
325 td_event_emptyset (&events);
326 - td_ta_set_event_p (thread_agent, &events);
327 + current_pointers->td_ta_set_event_p (thread_agent, &events);
328
329 /* Delete thread event breakpoints, if any. */
330 remove_thread_event_breakpoints ();
331 @@ -635,7 +666,6 @@ check_thread_signals (void)
332 static void
333 check_for_thread_db (void)
334 {
335 - td_err_e err;
336 static int already_loaded;
337
338 /* First time through, report that libthread_db was successfuly
339 @@ -644,19 +674,8 @@ check_for_thread_db (void)
340
341 if (!already_loaded)
342 {
343 - Dl_info info;
344 - const char *library = NULL;
345 - if (dladdr ((*td_ta_new_p), &info) != 0)
346 - library = info.dli_fname;
347 -
348 - /* Try dlinfo? */
349 -
350 - if (library == NULL)
351 - /* Paranoid - don't let a NULL path slip through. */
352 - library = LIBTHREAD_DB_SO;
353 -
354 printf_unfiltered ("Using host libthread_db library \"%s\".\n",
355 - library);
356 + all_pointers->filename);
357 already_loaded = 1;
358 }
359
360 @@ -674,28 +693,34 @@ check_for_thread_db (void)
361 proc_handle.pid = GET_PID (inferior_ptid);
362
363 /* Now attempt to open a connection to the thread library. */
364 - err = td_ta_new_p (&proc_handle, &thread_agent);
365 - switch (err)
366 + for (current_pointers = all_pointers;
367 + current_pointers != NULL;
368 + current_pointers = current_pointers->next)
369 {
370 - case TD_NOLIBTHREAD:
371 - /* No thread library was detected. */
372 - break;
373 -
374 - case TD_OK:
375 - printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
376 + td_err_e err;
377 + err = current_pointers->td_ta_new_p (&proc_handle, &thread_agent);
378 + switch (err)
379 + {
380 + case TD_NOLIBTHREAD:
381 + /* No thread library was detected. */
382 + break;
383
384 - /* The thread library was detected. Activate the thread_db target. */
385 - push_target (&thread_db_ops);
386 - using_thread_db = 1;
387 + case TD_OK:
388 + printf_unfiltered ("[Thread debugging using libthread_db enabled]\n");
389
390 - enable_thread_event_reporting ();
391 - thread_db_find_new_threads ();
392 - break;
393 + /* The thread library was detected. Activate the thread_db target. */
394 + push_target (&thread_db_ops);
395 + using_thread_db = 1;
396 +
397 + enable_thread_event_reporting ();
398 + thread_db_find_new_threads ();
399 + return;
400
401 - default:
402 - warning ("Cannot initialize thread debugging library: %s",
403 - thread_db_err_str (err));
404 - break;
405 + default:
406 + warning ("Cannot initialize thread debugging library: %s",
407 + thread_db_err_str (err));
408 + break;
409 + }
410 }
411 }
412
413 @@ -766,7 +791,7 @@ attach_thread (ptid_t ptid, const td_thr
414 #endif
415
416 /* Enable thread event reporting for this thread. */
417 - err = td_thr_event_enable_p (th_p, 1);
418 + err = current_pointers->td_thr_event_enable_p (th_p, 1);
419 if (err != TD_OK)
420 error ("Cannot enable thread event reporting for %s: %s",
421 target_pid_to_str (ptid), thread_db_err_str (err));
422 @@ -892,7 +917,7 @@ check_event (ptid_t ptid)
423
424 do
425 {
426 - err = td_ta_event_getmsg_p (thread_agent, &msg);
427 + err = current_pointers->td_ta_event_getmsg_p (thread_agent, &msg);
428 if (err != TD_OK)
429 {
430 if (err == TD_NOMSG)
431 @@ -902,7 +927,7 @@ check_event (ptid_t ptid)
432 thread_db_err_str (err));
433 }
434
435 - err = td_thr_get_info_p (msg.th_p, &ti);
436 + err = current_pointers->td_thr_get_info_p (msg.th_p, &ti);
437 if (err != TD_OK)
438 error ("Cannot get thread info: %s", thread_db_err_str (err));
439
440 @@ -1015,12 +1040,14 @@ thread_db_fetch_registers (int regno)
441 thread_info = find_thread_pid (inferior_ptid);
442 thread_db_map_id2thr (thread_info, 1);
443
444 - err = td_thr_getgregs_p (&thread_info->private->th, gregset);
445 + err = current_pointers->td_thr_getgregs_p (&thread_info->private->th,
446 + gregset);
447 if (err != TD_OK)
448 error ("Cannot fetch general-purpose registers for thread %ld: %s",
449 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
450
451 - err = td_thr_getfpregs_p (&thread_info->private->th, &fpregset);
452 + err = current_pointers->td_thr_getfpregs_p (&thread_info->private->th,
453 + &fpregset);
454 if (err != TD_OK)
455 error ("Cannot get floating-point registers for thread %ld: %s",
456 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
457 @@ -1062,11 +1089,13 @@ thread_db_store_registers (int regno)
458 fill_gregset ((gdb_gregset_t *) gregset, -1);
459 fill_fpregset (&fpregset, -1);
460
461 - err = td_thr_setgregs_p (&thread_info->private->th, gregset);
462 + err = current_pointers->td_thr_setgregs_p (&thread_info->private->th,
463 + gregset);
464 if (err != TD_OK)
465 error ("Cannot store general-purpose registers for thread %ld: %s",
466 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
467 - err = td_thr_setfpregs_p (&thread_info->private->th, &fpregset);
468 + err = current_pointers->td_thr_setfpregs_p (&thread_info->private->th,
469 + &fpregset);
470 if (err != TD_OK)
471 error ("Cannot store floating-point registers for thread %ld: %s",
472 (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
473 @@ -1136,15 +1165,14 @@ thread_db_thread_alive (ptid_t ptid)
474 if (!thread_info->private->th_valid)
475 return 0;
476
477 - err = td_thr_validate_p (&thread_info->private->th);
478 + err = current_pointers->td_thr_validate_p (&thread_info->private->th);
479 if (err != TD_OK)
480 return 0;
481
482 if (!thread_info->private->ti_valid)
483 {
484 - err =
485 - td_thr_get_info_p (&thread_info->private->th,
486 - &thread_info->private->ti);
487 + err = current_pointers->td_thr_get_info_p
488 + (&thread_info->private->th, &thread_info->private->ti);
489 if (err != TD_OK)
490 return 0;
491 thread_info->private->ti_valid = 1;
492 @@ -1170,7 +1198,7 @@ find_new_threads_callback (const td_thrh
493 td_err_e err;
494 ptid_t ptid;
495
496 - err = td_thr_get_info_p (th_p, &ti);
497 + err = current_pointers->td_thr_get_info_p (th_p, &ti);
498 if (err != TD_OK)
499 error ("find_new_threads_callback: cannot get thread info: %s",
500 thread_db_err_str (err));
501 @@ -1192,9 +1220,10 @@ thread_db_find_new_threads (void)
502 td_err_e err;
503
504 /* Iterate over all user-space threads to discover new threads. */
505 - err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
506 - TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
507 - TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
508 + err = current_pointers->td_ta_thr_iter_p
509 + (thread_agent, find_new_threads_callback, NULL,
510 + TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
511 + TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
512 if (err != TD_OK)
513 error ("Cannot find new threads: %s", thread_db_err_str (err));
514 }
515 @@ -1257,7 +1286,7 @@ thread_db_get_thread_local_address (ptid
516 struct thread_info *thread_info;
517
518 /* glibc doesn't provide the needed interface. */
519 - if (!td_thr_tls_get_addr_p)
520 + if (!current_pointers->td_thr_tls_get_addr_p)
521 error ("Cannot find thread-local variables in this thread library.");
522
523 /* Get the address of the link map for this objfile. */
524 @@ -1279,8 +1308,8 @@ thread_db_get_thread_local_address (ptid
525 thread_db_map_id2thr (thread_info, 1);
526
527 /* Finally, get the address of the variable. */
528 - err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *) lm,
529 - offset, &address);
530 + err = current_pointers->td_thr_tls_get_addr_p
531 + (&thread_info->private->th, (void *) lm, offset, &address);
532
533 #ifdef THREAD_DB_HAS_TD_NOTALLOC
534 /* The memory hasn't been allocated, yet. */
535 @@ -1360,17 +1389,49 @@ init_thread_db_ops (void)
536 void
537 _initialize_thread_db (void)
538 {
539 + struct thread_db_pointers *ptrs;
540 + const char *p;
541 +
542 /* Only initialize the module if we can load libthread_db. */
543 - if (thread_db_load ())
544 - {
545 - init_thread_db_ops ();
546 - add_target (&thread_db_ops);
547 + ptrs = thread_db_load (LIBTHREAD_DB_SO);
548 + if (ptrs == NULL)
549 + return;
550 +
551 + all_pointers = ptrs;
552
553 - /* Add ourselves to objfile event chain. */
554 - target_new_objfile_chain = deprecated_target_new_objfile_hook;
555 - deprecated_target_new_objfile_hook = thread_db_new_objfile;
556 + /* Some GNU/Linux systems have more than one binary-compatible copy
557 + of libthread_db. If we can find a second one, load that too.
558 + The inferior may force the use of a different threading package
559 + than we expect. Our guess for the location is somewhat hokey:
560 + strip out anything between /lib (or /lib64) and LIBTHREAD_DB_SO.
561 + If we loaded the NPTL libthread_db by default, this may find us
562 + the LinuxThreads copy. */
563 + p = strrchr (ptrs->filename, '/');
564 + while (p != NULL && p > ptrs->filename)
565 + {
566 + const char *component;
567
568 - /* Register ourselves for the new inferior observer. */
569 - observer_attach_inferior_created (check_for_thread_db_observer);
570 + component = memrchr (ptrs->filename, '/', p - ptrs->filename);
571 + if (component != NULL && strncmp (component, "/lib", 4) == 0)
572 + {
573 + char *new_name = xmalloc (p - ptrs->filename + 2
574 + + strlen (LIBTHREAD_DB_SO));
575 + memcpy (new_name, ptrs->filename, p - ptrs->filename + 1);
576 + strcpy (new_name + (p - ptrs->filename) + 1, LIBTHREAD_DB_SO);
577 + ptrs->next = thread_db_load (new_name);
578 + xfree (new_name);
579 + break;
580 + }
581 + p = component;
582 }
583 +
584 + init_thread_db_ops ();
585 + add_target (&thread_db_ops);
586 +
587 + /* Add ourselves to objfile event chain. */
588 + target_new_objfile_chain = deprecated_target_new_objfile_hook;
589 + deprecated_target_new_objfile_hook = thread_db_new_objfile;
590 +
591 + /* Register ourselves for the new inferior observer. */
592 + observer_attach_inferior_created (check_for_thread_db_observer);
593 }