]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/bsd-uthread.c
gdb: rename struct shobj -> struct solib
[thirdparty/binutils-gdb.git] / gdb / bsd-uthread.c
CommitLineData
82f5c14f
MK
1/* BSD user-level threads support.
2
1d506c26 3 Copyright (C) 2005-2024 Free Software Foundation, Inc.
82f5c14f
MK
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
82f5c14f
MK
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
82f5c14f
MK
19
20#include "defs.h"
21#include "gdbcore.h"
22#include "gdbthread.h"
23#include "inferior.h"
24#include "objfiles.h"
76727919 25#include "observable.h"
82f5c14f 26#include "regcache.h"
5ebc08b0 27#include "solib.h"
82f5c14f
MK
28#include "solist.h"
29#include "symfile.h"
30#include "target.h"
31
bf31fd38 32#include "gdbsupport/gdb_obstack.h"
4de283e4
TT
33
34#include "bsd-uthread.h"
35
d9f719f1
PA
36static const target_info bsd_uthread_target_info = {
37 "bsd-uthreads",
38 N_("BSD user-level threads"),
39 N_("BSD user-level threads")
40};
41
f6ac5f3d
PA
42struct bsd_uthread_target final : public target_ops
43{
d9f719f1
PA
44 const target_info &info () const override
45 { return bsd_uthread_target_info; }
f6ac5f3d 46
66b4deae
PA
47 strata stratum () const override { return thread_stratum; }
48
f6ac5f3d
PA
49 void close () override;
50
51 void mourn_inferior () override;
52
53 void fetch_registers (struct regcache *, int) override;
54 void store_registers (struct regcache *, int) override;
55
b60cea74 56 ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
f6ac5f3d
PA
57 void resume (ptid_t, int, enum gdb_signal) override;
58
57810aa7 59 bool thread_alive (ptid_t ptid) override;
f6ac5f3d
PA
60
61 void update_thread_list () override;
62
63 const char *extra_thread_info (struct thread_info *) override;
64
a068643d 65 std::string pid_to_str (ptid_t) override;
f6ac5f3d
PA
66};
67
68static bsd_uthread_target bsd_uthread_ops;
82f5c14f
MK
69\f
70
71/* Architecture-specific operations. */
72
82f5c14f
MK
73struct bsd_uthread_ops
74{
75 /* Supply registers for an inactive thread to a register cache. */
cb275538 76 void (*supply_uthread)(struct regcache *, int, CORE_ADDR) = nullptr;
82f5c14f
MK
77
78 /* Collect registers for an inactive thread from a register cache. */
cb275538 79 void (*collect_uthread)(const struct regcache *, int, CORE_ADDR) = nullptr;
82f5c14f
MK
80};
81
cb275538
TT
82/* Per-architecture data key. */
83static const registry<gdbarch>::key<struct bsd_uthread_ops> bsd_uthread_data;
82f5c14f 84
cb275538
TT
85static struct bsd_uthread_ops *
86get_bsd_uthread (struct gdbarch *gdbarch)
87{
88 struct bsd_uthread_ops *ops = bsd_uthread_data.get (gdbarch);
89 if (ops == nullptr)
90 ops = bsd_uthread_data.emplace (gdbarch);
82f5c14f
MK
91 return ops;
92}
93
94/* Set the function that supplies registers from an inactive thread
95 for architecture GDBARCH to SUPPLY_UTHREAD. */
96
97void
98bsd_uthread_set_supply_uthread (struct gdbarch *gdbarch,
99 void (*supply_uthread) (struct regcache *,
100 int, CORE_ADDR))
101{
cb275538 102 struct bsd_uthread_ops *ops = get_bsd_uthread (gdbarch);
9a3c8263 103
82f5c14f
MK
104 ops->supply_uthread = supply_uthread;
105}
106
107/* Set the function that collects registers for an inactive thread for
108 architecture GDBARCH to SUPPLY_UTHREAD. */
109
110void
111bsd_uthread_set_collect_uthread (struct gdbarch *gdbarch,
112 void (*collect_uthread) (const struct regcache *,
113 int, CORE_ADDR))
114{
cb275538 115 struct bsd_uthread_ops *ops = get_bsd_uthread (gdbarch);
9a3c8263 116
82f5c14f
MK
117 ops->collect_uthread = collect_uthread;
118}
119
120/* Magic number to help recognize a valid thread structure. */
121#define BSD_UTHREAD_PTHREAD_MAGIC 0xd09ba115
122
123/* Check whether the thread structure at ADDR is valid. */
124
125static void
126bsd_uthread_check_magic (CORE_ADDR addr)
127{
99d9c3b9 128 bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
e17a4113 129 ULONGEST magic = read_memory_unsigned_integer (addr, 4, byte_order);
82f5c14f
MK
130
131 if (magic != BSD_UTHREAD_PTHREAD_MAGIC)
8a3fe4f8 132 error (_("Bad magic"));
82f5c14f
MK
133}
134
135/* Thread states. */
136#define BSD_UTHREAD_PS_RUNNING 0
137#define BSD_UTHREAD_PS_DEAD 18
138
b021a221 139/* Address of the pointer to the thread structure for the running
82f5c14f
MK
140 thread. */
141static CORE_ADDR bsd_uthread_thread_run_addr;
142
143/* Address of the list of all threads. */
144static CORE_ADDR bsd_uthread_thread_list_addr;
145
146/* Offsets of various "interesting" bits in the thread structure. */
147static int bsd_uthread_thread_state_offset = -1;
148static int bsd_uthread_thread_next_offset = -1;
149static int bsd_uthread_thread_ctx_offset;
150
151/* Name of shared threads library. */
98107b0b 152static std::string bsd_uthread_solib_name;
82f5c14f 153
33b5899f 154/* Non-zero if the thread stratum implemented by this module is active. */
82f5c14f
MK
155static int bsd_uthread_active;
156
157static CORE_ADDR
158bsd_uthread_lookup_address (const char *name, struct objfile *objfile)
159{
3b7344d5 160 struct bound_minimal_symbol sym;
82f5c14f
MK
161
162 sym = lookup_minimal_symbol (name, NULL, objfile);
3b7344d5 163 if (sym.minsym)
4aeddc50 164 return sym.value_address ();
82f5c14f
MK
165
166 return 0;
167}
168
169static int
170bsd_uthread_lookup_offset (const char *name, struct objfile *objfile)
171{
99d9c3b9 172 bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
82f5c14f
MK
173 CORE_ADDR addr;
174
175 addr = bsd_uthread_lookup_address (name, objfile);
176 if (addr == 0)
177 return 0;
178
e17a4113 179 return read_memory_unsigned_integer (addr, 4, byte_order);
82f5c14f
MK
180}
181
ff7da468
UW
182static CORE_ADDR
183bsd_uthread_read_memory_address (CORE_ADDR addr)
184{
99d9c3b9
SM
185 type *ptr_type
186 = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
ff7da468
UW
187 return read_memory_typed_address (addr, ptr_type);
188}
189
82f5c14f
MK
190/* If OBJFILE contains the symbols corresponding to one of the
191 supported user-level threads libraries, activate the thread stratum
192 implemented by this module. */
193
194static int
195bsd_uthread_activate (struct objfile *objfile)
196{
99d9c3b9 197 gdbarch *gdbarch = current_inferior ()->arch ();
cb275538 198 struct bsd_uthread_ops *ops = get_bsd_uthread (gdbarch);
82f5c14f
MK
199
200 /* Skip if the thread stratum has already been activated. */
201 if (bsd_uthread_active)
202 return 0;
203
204 /* There's no point in enabling this module if no
205 architecture-specific operations are provided. */
206 if (!ops->supply_uthread)
207 return 0;
208
209 bsd_uthread_thread_run_addr =
210 bsd_uthread_lookup_address ("_thread_run", objfile);
211 if (bsd_uthread_thread_run_addr == 0)
212 return 0;
213
214 bsd_uthread_thread_list_addr =
215 bsd_uthread_lookup_address ("_thread_list", objfile);
216 if (bsd_uthread_thread_list_addr == 0)
217 return 0;
218
219 bsd_uthread_thread_state_offset =
220 bsd_uthread_lookup_offset ("_thread_state_offset", objfile);
221 if (bsd_uthread_thread_state_offset == 0)
222 return 0;
223
224 bsd_uthread_thread_next_offset =
225 bsd_uthread_lookup_offset ("_thread_next_offset", objfile);
226 if (bsd_uthread_thread_next_offset == 0)
227 return 0;
228
229 bsd_uthread_thread_ctx_offset =
230 bsd_uthread_lookup_offset ("_thread_ctx_offset", objfile);
231
02980c56 232 current_inferior ()->push_target (&bsd_uthread_ops);
82f5c14f
MK
233 bsd_uthread_active = 1;
234 return 1;
235}
236
39540081 237/* Cleanup due to deactivation. */
82f5c14f 238
f6ac5f3d
PA
239void
240bsd_uthread_target::close ()
82f5c14f 241{
82f5c14f 242 bsd_uthread_active = 0;
82f5c14f
MK
243 bsd_uthread_thread_run_addr = 0;
244 bsd_uthread_thread_list_addr = 0;
245 bsd_uthread_thread_state_offset = 0;
246 bsd_uthread_thread_next_offset = 0;
247 bsd_uthread_thread_ctx_offset = 0;
98107b0b 248 bsd_uthread_solib_name.clear ();
82f5c14f
MK
249}
250
39540081
PA
251/* Deactivate the thread stratum implemented by this module. */
252
253static void
254bsd_uthread_deactivate (void)
255{
256 /* Skip if the thread stratum has already been deactivated. */
257 if (!bsd_uthread_active)
258 return;
259
fadf6add 260 current_inferior ()->unpush_target (&bsd_uthread_ops);
39540081
PA
261}
262
63807e1d 263static void
a0ff652f 264bsd_uthread_inferior_created (inferior *inf)
82f5c14f
MK
265{
266 bsd_uthread_activate (NULL);
267}
268
269/* Likely candidates for the threads library. */
27087b7f 270static const char * const bsd_uthread_solib_names[] =
82f5c14f
MK
271{
272 "/usr/lib/libc_r.so", /* FreeBSD */
273 "/usr/lib/libpthread.so", /* OpenBSD */
274 NULL
275};
276
63807e1d 277static void
7b323785 278bsd_uthread_solib_loaded (solib &so)
82f5c14f 279{
27087b7f 280 const char * const *names = bsd_uthread_solib_names;
82f5c14f
MK
281
282 for (names = bsd_uthread_solib_names; *names; names++)
283 {
bb86ab83 284 if (startswith (so.so_original_name, *names))
82f5c14f 285 {
048d532d 286 solib_read_symbols (so, 0);
82f5c14f 287
bb86ab83 288 if (bsd_uthread_activate (so.objfile))
82f5c14f 289 {
bb86ab83 290 bsd_uthread_solib_name = so.so_original_name;
82f5c14f
MK
291 return;
292 }
293 }
294 }
295}
296
63807e1d 297static void
7b323785 298bsd_uthread_solib_unloaded (program_space *pspace, const solib &so)
82f5c14f 299{
98107b0b 300 if (bsd_uthread_solib_name.empty ())
82f5c14f
MK
301 return;
302
98107b0b 303 if (so.so_original_name == bsd_uthread_solib_name)
82f5c14f
MK
304 bsd_uthread_deactivate ();
305}
306
f6ac5f3d
PA
307void
308bsd_uthread_target::mourn_inferior ()
82f5c14f 309{
d6ca69cd 310 beneath ()->mourn_inferior ();
82f5c14f
MK
311 bsd_uthread_deactivate ();
312}
313
f6ac5f3d
PA
314void
315bsd_uthread_target::fetch_registers (struct regcache *regcache, int regnum)
82f5c14f 316{
ac7936df 317 struct gdbarch *gdbarch = regcache->arch ();
cb275538 318 struct bsd_uthread_ops *uthread_ops = get_bsd_uthread (gdbarch);
222312d3 319 ptid_t ptid = regcache->ptid ();
cc6bcb54 320 CORE_ADDR addr = ptid.tid ();
82f5c14f 321 CORE_ADDR active_addr;
2989a365 322 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
317cd492
SM
323
324 /* We are doing operations (e.g. reading memory) that rely on
325 inferior_ptid. */
326 inferior_ptid = ptid;
82f5c14f
MK
327
328 /* Always fetch the appropriate registers from the layer beneath. */
d6ca69cd 329 beneath ()->fetch_registers (regcache, regnum);
82f5c14f
MK
330
331 /* FIXME: That might have gotten us more than we asked for. Make
332 sure we overwrite all relevant registers with values from the
333 thread structure. This can go once we fix the underlying target. */
334 regnum = -1;
335
ff7da468 336 active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
82f5c14f
MK
337 if (addr != 0 && addr != active_addr)
338 {
339 bsd_uthread_check_magic (addr);
28439f5e
PA
340 uthread_ops->supply_uthread (regcache, regnum,
341 addr + bsd_uthread_thread_ctx_offset);
82f5c14f
MK
342 }
343}
344
f6ac5f3d
PA
345void
346bsd_uthread_target::store_registers (struct regcache *regcache, int regnum)
82f5c14f 347{
ac7936df 348 struct gdbarch *gdbarch = regcache->arch ();
cb275538 349 struct bsd_uthread_ops *uthread_ops = get_bsd_uthread (gdbarch);
222312d3 350 ptid_t ptid = regcache->ptid ();
cc6bcb54 351 CORE_ADDR addr = ptid.tid ();
82f5c14f 352 CORE_ADDR active_addr;
2989a365 353 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
317cd492
SM
354
355 /* We are doing operations (e.g. reading memory) that rely on
356 inferior_ptid. */
357 inferior_ptid = ptid;
82f5c14f 358
ff7da468 359 active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
82f5c14f
MK
360 if (addr != 0 && addr != active_addr)
361 {
362 bsd_uthread_check_magic (addr);
28439f5e
PA
363 uthread_ops->collect_uthread (regcache, regnum,
364 addr + bsd_uthread_thread_ctx_offset);
82f5c14f
MK
365 }
366 else
367 {
368 /* Updating the thread that is currently running; pass the
dda83cd7 369 request to the layer beneath. */
d6ca69cd 370 beneath ()->store_registers (regcache, regnum);
82f5c14f
MK
371 }
372}
373
f6ac5f3d
PA
374ptid_t
375bsd_uthread_target::wait (ptid_t ptid, struct target_waitstatus *status,
b60cea74 376 target_wait_flags options)
82f5c14f 377{
99d9c3b9 378 bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
82f5c14f 379 CORE_ADDR addr;
5b6d1e4f
PA
380 process_stratum_target *beneath
381 = as_process_stratum_target (this->beneath ());
82f5c14f
MK
382
383 /* Pass the request to the layer beneath. */
5b6d1e4f 384 ptid = beneath->wait (ptid, status, options);
82f5c14f 385
a4e7b2e7
MK
386 /* If the process is no longer alive, there's no point in figuring
387 out the thread ID. It will fail anyway. */
183be222
SM
388 if (status->kind () == TARGET_WAITKIND_SIGNALLED
389 || status->kind () == TARGET_WAITKIND_EXITED)
a4e7b2e7
MK
390 return ptid;
391
82f5c14f
MK
392 /* Fetch the corresponding thread ID, and augment the returned
393 process ID with it. */
ff7da468 394 addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
82f5c14f
MK
395 if (addr != 0)
396 {
df80278b 397 gdb_byte buf[4];
82f5c14f
MK
398
399 /* FIXME: For executables linked statically with the threads
dda83cd7
SM
400 library, we end up here before the program has actually been
401 executed. In that case ADDR will be garbage since it has
402 been read from the wrong virtual memory image. */
82f5c14f
MK
403 if (target_read_memory (addr, buf, 4) == 0)
404 {
e17a4113 405 ULONGEST magic = extract_unsigned_integer (buf, 4, byte_order);
82f5c14f 406 if (magic == BSD_UTHREAD_PTHREAD_MAGIC)
e99b03dc 407 ptid = ptid_t (ptid.pid (), 0, addr);
82f5c14f
MK
408 }
409 }
410
fb5e7258
PA
411 /* If INFERIOR_PTID doesn't have a tid member yet, and we now have a
412 ptid with tid set, then ptid is still the initial thread of
413 the process. Notify GDB core about it. */
cc6bcb54 414 if (inferior_ptid.tid () == 0
5b6d1e4f
PA
415 && ptid.tid () != 0 && !in_thread_list (beneath, ptid))
416 thread_change_ptid (beneath, inferior_ptid, ptid);
fb5e7258
PA
417
418 /* Don't let the core see a ptid without a corresponding thread. */
9213a6d7 419 thread_info *thread = beneath->find_thread (ptid);
00431a78 420 if (thread == NULL || thread->state == THREAD_EXITED)
5b6d1e4f 421 add_thread (beneath, ptid);
82f5c14f
MK
422
423 return ptid;
424}
425
f6ac5f3d
PA
426void
427bsd_uthread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
82f5c14f
MK
428{
429 /* Pass the request to the layer beneath. */
d6ca69cd 430 beneath ()->resume (ptid, step, sig);
82f5c14f
MK
431}
432
57810aa7 433bool
f6ac5f3d 434bsd_uthread_target::thread_alive (ptid_t ptid)
82f5c14f 435{
99d9c3b9 436 bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
cc6bcb54 437 CORE_ADDR addr = ptid.tid ();
82f5c14f
MK
438
439 if (addr != 0)
440 {
441 int offset = bsd_uthread_thread_state_offset;
442 ULONGEST state;
443
444 bsd_uthread_check_magic (addr);
445
e17a4113 446 state = read_memory_unsigned_integer (addr + offset, 4, byte_order);
82f5c14f 447 if (state == BSD_UTHREAD_PS_DEAD)
57810aa7 448 return false;
82f5c14f
MK
449 }
450
d6ca69cd 451 return beneath ()->thread_alive (ptid);
82f5c14f
MK
452}
453
f6ac5f3d
PA
454void
455bsd_uthread_target::update_thread_list ()
82f5c14f 456{
e99b03dc 457 pid_t pid = inferior_ptid.pid ();
82f5c14f
MK
458 int offset = bsd_uthread_thread_next_offset;
459 CORE_ADDR addr;
460
e8032dde
PA
461 prune_threads ();
462
ff7da468 463 addr = bsd_uthread_read_memory_address (bsd_uthread_thread_list_addr);
82f5c14f
MK
464 while (addr != 0)
465 {
fd79271b 466 ptid_t ptid = ptid_t (pid, 0, addr);
82f5c14f 467
5b6d1e4f
PA
468 process_stratum_target *proc_target
469 = as_process_stratum_target (this->beneath ());
9213a6d7 470 thread_info *thread = proc_target->find_thread (ptid);
00431a78 471 if (thread == nullptr || thread->state == THREAD_EXITED)
757f359d
PA
472 {
473 /* If INFERIOR_PTID doesn't have a tid member yet, then ptid
474 is still the initial thread of the process. Notify GDB
475 core about it. */
cc6bcb54 476 if (inferior_ptid.tid () == 0)
5b6d1e4f 477 thread_change_ptid (proc_target, inferior_ptid, ptid);
757f359d 478 else
5b6d1e4f 479 add_thread (proc_target, ptid);
757f359d 480 }
82f5c14f 481
ff7da468 482 addr = bsd_uthread_read_memory_address (addr + offset);
82f5c14f
MK
483 }
484}
485
486/* Possible states a thread can be in. */
27087b7f 487static const char * const bsd_uthread_state[] =
82f5c14f
MK
488{
489 "RUNNING",
490 "SIGTHREAD",
491 "MUTEX_WAIT",
492 "COND_WAIT",
493 "FDLR_WAIT",
494 "FDLW_WAIT",
495 "FDR_WAIT",
496 "FDW_WAIT",
497 "FILE_WAIT",
498 "POLL_WAIT",
499 "SELECT_WAIT",
500 "SLEEP_WAIT",
501 "WAIT_WAIT",
502 "SIGSUSPEND",
503 "SIGWAIT",
504 "SPINBLOCK",
505 "JOIN",
506 "SUSPENDED",
507 "DEAD",
508 "DEADLOCK"
509};
510
511/* Return a string describing th state of the thread specified by
512 INFO. */
513
f6ac5f3d
PA
514const char *
515bsd_uthread_target::extra_thread_info (thread_info *info)
82f5c14f 516{
99d9c3b9 517 bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
cc6bcb54 518 CORE_ADDR addr = info->ptid.tid ();
82f5c14f
MK
519
520 if (addr != 0)
521 {
522 int offset = bsd_uthread_thread_state_offset;
523 ULONGEST state;
524
e17a4113 525 state = read_memory_unsigned_integer (addr + offset, 4, byte_order);
82f5c14f
MK
526 if (state < ARRAY_SIZE (bsd_uthread_state))
527 return bsd_uthread_state[state];
528 }
529
530 return NULL;
531}
532
a068643d 533std::string
f6ac5f3d 534bsd_uthread_target::pid_to_str (ptid_t ptid)
82f5c14f 535{
cc6bcb54 536 if (ptid.tid () != 0)
96bbe3ef
TT
537 return string_printf ("process %d, thread 0x%s",
538 ptid.pid (),
539 phex_nz (ptid.tid (), sizeof (ULONGEST)));
82f5c14f
MK
540
541 return normal_pid_to_str (ptid);
542}
543
6c265988 544void _initialize_bsd_uthread ();
82f5c14f 545void
6c265988 546_initialize_bsd_uthread ()
82f5c14f 547{
c90e7d63
SM
548 gdb::observers::inferior_created.attach (bsd_uthread_inferior_created,
549 "bsd-uthread");
550 gdb::observers::solib_loaded.attach (bsd_uthread_solib_loaded,
551 "bsd-uthread");
552 gdb::observers::solib_unloaded.attach (bsd_uthread_solib_unloaded,
553 "bsd-uthread");
82f5c14f 554}