* aix-thread.c (gdbcmd.h): Include.
[deliverable/binutils-gdb.git] / gdb / aix-thread.c
1 /* Low level interface for debugging AIX 4.3+ pthreads.
2
3 Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
4 Written by Nick Duffek <nsd@redhat.com>.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23
24 /* This module uses the libpthdebug.a library provided by AIX 4.3+ for
25 debugging pthread applications.
26
27 Some name prefix conventions:
28 pthdb_ provided by libpthdebug.a
29 pdc_ callbacks that this module provides to libpthdebug.a
30 pd_ variables or functions interfacing with libpthdebug.a
31
32 libpthdebug peculiarities:
33
34 - pthdb_ptid_pthread() is prototyped in <sys/pthdebug.h>, but it's not
35 documented, and after several calls it stops working and causes other
36 libpthdebug functions to fail.
37
38 - pthdb_tid_pthread() doesn't always work after pthdb_session_update(),
39 but it does work after cycling through all threads using
40 pthdb_pthread().
41
42 */
43
44 #include "defs.h"
45 #include "gdbthread.h"
46 #include "target.h"
47 #include "inferior.h"
48 #include "regcache.h"
49 #include "gdbcmd.h"
50
51 #if 0
52 #include "coff/internal.h" /* for libcoff.h */
53 #include "bfd/libcoff.h" /* for xcoff_data */
54 #endif
55
56 #include <procinfo.h>
57 #include <sys/types.h>
58 #include <sys/ptrace.h>
59 #include <sys/reg.h>
60 #if 0
61 #include <pthread.h>
62 #endif
63 #include <sched.h>
64 #include <sys/pthdebug.h>
65
66 /* Whether to emit debugging output. */
67 static int debug_aix_thread;
68
69 /* in AIX 5.1, functions use pthdb_tid_t instead of tid_t */
70 #ifndef PTHDB_VERSION_3
71 #define pthdb_tid_t tid_t
72 #endif
73
74 /* Return whether to treat PID as a debuggable thread id. */
75
76 #define PD_TID(ptid) (pd_active && ptid_get_tid (ptid) != 0)
77
78 /* Build a thread ptid. */
79 #define BUILD_THREAD(TID, PID) ptid_build (PID, 0, TID)
80
81 /* Build and lwp ptid. */
82 #define BUILD_LWP(LWP, PID) MERGEPID (PID, LWP)
83
84 /* Call error() with a message indicating that libpthdebug FUNC failed with
85 STATUS. */
86
87 #define PD_ERROR(func, status) \
88 error ("aix-thread: %s returned %s", func, pd_status2str (status))
89
90 /* pthdb_user_t value that we pass to pthdb functions. 0 causes
91 PTHDB_BAD_USER errors, so use 1. */
92
93 #define PD_USER 1
94
95 /* Success and failure values returned by pthdb callbacks. */
96
97 #define PDC_SUCCESS PTHDB_SUCCESS
98 #define PDC_FAILURE PTHDB_CALLBACK
99
100 /* Convert composite process/thread inferior_ptid to a process id, evaluate
101 base_ops function CALL, and then restore inferior_ptid. */
102
103 #define CALL_BASE(call) \
104 do { \
105 struct cleanup *cleanup = save_inferior_ptid (); \
106 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid)); \
107 call; \
108 do_cleanups (cleanup); \
109 } while (0)
110
111 /* Private data attached to each element in GDB's thread list. */
112
113 struct private_thread_info {
114 pthdb_pthread_t pdtid; /* thread's libpthdebug id */
115 pthdb_tid_t tid; /* kernel thread id */
116 };
117
118 /* Information about a thread of which libpthdebug is aware. */
119
120 struct pd_thread {
121 pthdb_pthread_t pdtid;
122 pthread_t pthid;
123 pthdb_tid_t tid;
124 };
125
126 /* This module's target-specific operations, active while pd_able is true. */
127
128 static struct target_ops ops;
129
130 /* Copy of the target over which ops is pushed. This is
131 more convenient than a pointer to child_ops or core_ops, because
132 they lack current_target's default callbacks. */
133
134 static struct target_ops base_ops;
135
136 /* Address of the function that libpthread will call when libpthdebug is
137 ready to be initialized. */
138
139 static CORE_ADDR pd_brk_addr;
140
141 /* Whether the current application is debuggable by pthdb. */
142
143 static int pd_able = 0;
144
145 /* Whether a threaded application is being debugged. */
146
147 static int pd_active = 0;
148
149 /* Whether the current architecture is 64-bit. Only valid when pd_able is
150 true. */
151
152 static int arch64;
153
154 /* Saved pointer to previous owner of target_new_objfile_hook. */
155
156 static void (*target_new_objfile_chain)(struct objfile *);
157
158 /* Forward declarations for pthdb callbacks. */
159
160 static int pdc_symbol_addrs (pthdb_user_t, pthdb_symbol_t *, int);
161 static int pdc_read_data (pthdb_user_t, void *, pthdb_addr_t, size_t);
162 static int pdc_write_data (pthdb_user_t, void *, pthdb_addr_t, size_t);
163 static int pdc_read_regs (pthdb_user_t user, pthdb_tid_t tid,
164 unsigned long long flags, pthdb_context_t *context);
165 static int pdc_write_regs (pthdb_user_t user, pthdb_tid_t tid,
166 unsigned long long flags, pthdb_context_t *context);
167 static int pdc_alloc (pthdb_user_t, size_t, void **);
168 static int pdc_realloc (pthdb_user_t, void *, size_t, void **);
169 static int pdc_dealloc (pthdb_user_t, void *);
170
171 /* pthdb callbacks. */
172
173 static pthdb_callbacks_t pd_callbacks = {
174 pdc_symbol_addrs,
175 pdc_read_data,
176 pdc_write_data,
177 pdc_read_regs,
178 pdc_write_regs,
179 pdc_alloc,
180 pdc_realloc,
181 pdc_dealloc,
182 NULL
183 };
184
185 /* Current pthdb session. */
186
187 static pthdb_session_t pd_session;
188
189 /* Return a printable representation of pthdebug function return STATUS. */
190
191 static char *
192 pd_status2str (int status)
193 {
194 switch (status)
195 {
196 case PTHDB_SUCCESS: return "SUCCESS";
197 case PTHDB_NOSYS: return "NOSYS";
198 case PTHDB_NOTSUP: return "NOTSUP";
199 case PTHDB_BAD_VERSION: return "BAD_VERSION";
200 case PTHDB_BAD_USER: return "BAD_USER";
201 case PTHDB_BAD_SESSION: return "BAD_SESSION";
202 case PTHDB_BAD_MODE: return "BAD_MODE";
203 case PTHDB_BAD_FLAGS: return "BAD_FLAGS";
204 case PTHDB_BAD_CALLBACK: return "BAD_CALLBACK";
205 case PTHDB_BAD_POINTER: return "BAD_POINTER";
206 case PTHDB_BAD_CMD: return "BAD_CMD";
207 case PTHDB_BAD_PTHREAD: return "BAD_PTHREAD";
208 case PTHDB_BAD_ATTR: return "BAD_ATTR";
209 case PTHDB_BAD_MUTEX: return "BAD_MUTEX";
210 case PTHDB_BAD_MUTEXATTR: return "BAD_MUTEXATTR";
211 case PTHDB_BAD_COND: return "BAD_COND";
212 case PTHDB_BAD_CONDATTR: return "BAD_CONDATTR";
213 case PTHDB_BAD_RWLOCK: return "BAD_RWLOCK";
214 case PTHDB_BAD_RWLOCKATTR: return "BAD_RWLOCKATTR";
215 case PTHDB_BAD_KEY: return "BAD_KEY";
216 case PTHDB_BAD_PTID: return "BAD_PTID";
217 case PTHDB_BAD_TID: return "BAD_TID";
218 case PTHDB_CALLBACK: return "CALLBACK";
219 case PTHDB_CONTEXT: return "CONTEXT";
220 case PTHDB_HELD: return "HELD";
221 case PTHDB_NOT_HELD: return "NOT_HELD";
222 case PTHDB_MEMORY: return "MEMORY";
223 case PTHDB_NOT_PTHREADED: return "NOT_PTHREADED";
224 case PTHDB_SYMBOL: return "SYMBOL";
225 case PTHDB_NOT_AVAIL: return "NOT_AVAIL";
226 case PTHDB_INTERNAL: return "INTERNAL";
227 default: return "UNKNOWN";
228 }
229 }
230
231 /* A call to ptrace(REQ, ID, ...) just returned RET. Check for exceptional
232 conditions and either return nonlocally or else return 1 for success and 0
233 for failure. */
234
235 static int
236 ptrace_check (int req, int id, int ret)
237 {
238 if (ret == 0 && !errno)
239 return 1;
240
241 /* According to ptrace(2), ptrace may fail with EPERM if "the Identifier
242 parameter corresponds to a kernel thread which is stopped in kernel mode
243 and whose computational state cannot be read or written." This happens
244 quite often with register reads. */
245
246 switch (req)
247 {
248 case PTT_READ_GPRS:
249 case PTT_READ_FPRS:
250 case PTT_READ_SPRS:
251 if (ret == -1 && errno == EPERM)
252 goto strange;
253 break;
254 }
255 error ("aix-thread: ptrace (%d, %d) returned %d (errno = %d %s)",
256 req, id, ret, errno, strerror (errno));
257
258 strange:
259 if (debug_aix_thread)
260 fprintf_unfiltered (gdb_stdlog, "ptrace (%d, %d) = %d (errno = %d)",
261 req, id, ret, errno);
262 return ret == -1 ? 0 : 1;
263 }
264
265 /* Call ptracex(REQ, ID, ADDR, DATA, BUF). Return success. */
266
267 static int
268 ptrace64aix (int req, int id, long long addr, int data, int *buf)
269 {
270 errno = 0;
271 return ptrace_check (req, id, ptracex (req, id, addr, data, buf));
272 }
273
274 /* Call ptrace(REQ, ID, ADDR, DATA, BUF). Return success. */
275
276 static int
277 ptrace32 (int req, int id, int *addr, int data, int *buf)
278 {
279 errno = 0;
280 return ptrace_check (req, id, ptrace (req, id, (int *)addr, data, buf));
281 }
282
283 /* If *PIDP is a composite process/thread id, convert it to a process id. */
284
285 static void
286 pid_to_prc (ptid_t *ptidp)
287 {
288 ptid_t ptid;
289
290 ptid = *ptidp;
291 if (PD_TID (ptid))
292 *ptidp = pid_to_ptid (PIDGET (ptid));
293 }
294
295 /* pthdb callback: for <i> from 0 to COUNT, set SYMBOLS[<i>].addr to the
296 address of SYMBOLS[<i>].name. */
297
298 static int
299 pdc_symbol_addrs (pthdb_user_t user, pthdb_symbol_t *symbols, int count)
300 {
301 struct minimal_symbol *ms;
302 int i;
303 char *name;
304
305 if (debug_aix_thread)
306 fprintf_unfiltered (gdb_stdlog,
307 "pdc_symbol_addrs (user = %ld, symbols = 0x%lx, count = %d)",
308 user, (long) symbols, count);
309
310 for (i = 0; i < count; i++)
311 {
312 name = symbols[i].name;
313 if (debug_aix_thread)
314 fprintf_unfiltered (gdb_stdlog, " symbols[%d].name = \"%s\"", i, name);
315
316 if (!*name)
317 symbols[i].addr = 0;
318 else
319 {
320 if (!(ms = lookup_minimal_symbol (name, NULL, NULL)))
321 {
322 if (debug_aix_thread)
323 fprintf_unfiltered (gdb_stdlog, " returning PDC_FAILURE");
324 return PDC_FAILURE;
325 }
326 symbols[i].addr = SYMBOL_VALUE_ADDRESS (ms);
327 }
328 if (debug_aix_thread)
329 fprintf_unfiltered (gdb_stdlog, " symbols[%d].addr = 0x%llx",
330 i, symbols[i].addr);
331 }
332 if (debug_aix_thread)
333 fprintf_unfiltered (gdb_stdlog, " returning PDC_SUCCESS");
334 return PDC_SUCCESS;
335 }
336
337 /* Read registers call back function should be able to read the context */
338 /* information of a debuggee kernel thread from an active process or from */
339 /* a core file. The information should be formatted in context64 form for */
340 /* both 32-bit and 64-bit process. If successful return 0, else non-zero */
341 /* is returned. */
342 static int
343 pdc_read_regs (pthdb_user_t user,
344 pthdb_tid_t tid,
345 unsigned long long flags,
346 pthdb_context_t *context)
347 {
348 /* this function doesn't appear to be used, so we could probably just */
349 /* return 0 here. HOWEVER, if it is not defined, the OS will complain */
350 /* and several thread debug functions will fail. In case this is needed, */
351 /* I have implemented what I think it should do, however this code is */
352 /* untested. */
353 uint64_t gprs64[32];
354 uint32_t gprs32[32];
355 double fprs[32];
356 struct ptxsprs sprs64;
357 struct ptsprs sprs32;
358
359 if (debug_aix_thread)
360 fprintf_unfiltered (gdb_stdlog, "pdc_read_regs tid=%d flags=%llx\n",
361 (int)tid, flags);
362
363 /* General-purpose registers. */
364 if (flags & PTHDB_FLAG_GPRS)
365 {
366 if (arch64)
367 {
368 if (!ptrace64aix (PTT_READ_GPRS, tid, (unsigned long) gprs64, 0, NULL))
369 memset (gprs64, 0, sizeof (gprs64));
370 memcpy (context->gpr, gprs64, sizeof(gprs64));
371 }
372 else
373 {
374 if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
375 memset (gprs32, 0, sizeof (gprs32));
376 memcpy (context->gpr, gprs32, sizeof(gprs32));
377 }
378 }
379
380 /* Floating-point registers. */
381 if (flags & PTHDB_FLAG_FPRS)
382 {
383 if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
384 memset (fprs, 0, sizeof (fprs));
385 memcpy (context->fpr, fprs, sizeof(fprs));
386 }
387
388 /* Special-purpose registers. */
389 if (flags & PTHDB_FLAG_SPRS)
390 {
391 if (arch64)
392 {
393 if (!ptrace64aix (PTT_READ_SPRS, tid, (unsigned long) &sprs64, 0, NULL))
394 memset (&sprs64, 0, sizeof (sprs64));
395 memcpy (&context->msr, &sprs64, sizeof(sprs64));
396 }
397 else
398 {
399 if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
400 memset (&sprs32, 0, sizeof (sprs32));
401 memcpy (&context->msr, &sprs32, sizeof(sprs32));
402 }
403 }
404 return 0;
405 }
406
407 /* Write register function should be able to write requested context */
408 /* information to specified debuggee's kernel thread id. If successful */
409 /* return 0, else non-zero is returned. */
410 static int
411 pdc_write_regs (pthdb_user_t user,
412 pthdb_tid_t tid,
413 unsigned long long flags,
414 pthdb_context_t *context)
415 {
416 /* this function doesn't appear to be used, so we could probably just */
417 /* return 0 here. HOWEVER, if it is not defined, the OS will complain */
418 /* and several thread debug functions will fail. In case this is needed, */
419 /* I have implemented what I think it should do, however this code is */
420 /* untested. */
421
422 if (debug_aix_thread)
423 fprintf_unfiltered (gdb_stdlog, "pdc_write_regs tid=%d flags=%llx\n",
424 (int)tid, flags);
425
426 /* General-purpose registers. */
427 if (flags & PTHDB_FLAG_GPRS)
428 {
429 if (arch64)
430 ptrace64aix (PTT_WRITE_GPRS, tid, (unsigned long)context->gpr, 0, NULL);
431 else
432 ptrace32 (PTT_WRITE_GPRS, tid, (int *)context->gpr, 0, NULL);
433 }
434
435 /* Floating-point registers. */
436 if (flags & PTHDB_FLAG_FPRS)
437 {
438 ptrace32 (PTT_WRITE_FPRS, tid, (int *)context->fpr, 0, NULL);
439 }
440
441 /* Special-purpose registers. */
442 if (flags & PTHDB_FLAG_SPRS)
443 {
444 if (arch64)
445 {
446 ptrace64aix (PTT_WRITE_SPRS, tid, (unsigned long) &context->msr, 0, NULL);
447 }
448 else
449 {
450 ptrace32 (PTT_WRITE_SPRS, tid, (int *)&context->msr, 0, NULL);
451 }
452 }
453 return 0;
454 }
455
456 /* pthdb callback: read LEN bytes from process ADDR into BUF. */
457
458 static int
459 pdc_read_data (pthdb_user_t user, void *buf, pthdb_addr_t addr, size_t len)
460 {
461 int status, ret;
462
463 if (debug_aix_thread)
464 fprintf_unfiltered (gdb_stdlog,
465 "pdc_read_data (user = %ld, buf = 0x%lx, addr = 0x%llx, len = %ld)",
466 user, (long) buf, addr, len);
467
468 status = target_read_memory (addr, buf, len);
469 ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
470
471 if (debug_aix_thread)
472 fprintf_unfiltered (gdb_stdlog, " status=%d, returning %s", status,
473 pd_status2str (ret));
474 return ret;
475 }
476
477 /* pthdb callback: write LEN bytes from BUF to process ADDR. */
478
479 static int
480 pdc_write_data (pthdb_user_t user, void *buf, pthdb_addr_t addr, size_t len)
481 {
482 int status, ret;
483
484 if (debug_aix_thread)
485 fprintf_unfiltered (gdb_stdlog,
486 "pdc_write_data (user = %ld, buf = 0x%lx, addr = 0x%llx, len = %ld)",
487 user, (long) buf, addr, len);
488
489 status = target_write_memory (addr, buf, len);
490 ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
491
492 if (debug_aix_thread)
493 fprintf_unfiltered (gdb_stdlog, " status=%d, returning %s", status,
494 pd_status2str (ret));
495 return ret;
496 }
497
498 /* pthdb callback: allocate a LEN-byte buffer and store a pointer to it in
499 BUFP. */
500
501 static int
502 pdc_alloc (pthdb_user_t user, size_t len, void **bufp)
503 {
504 if (debug_aix_thread)
505 fprintf_unfiltered (gdb_stdlog,
506 "pdc_alloc (user = %ld, len = %ld, bufp = 0x%lx)",
507 user, len, (long) bufp);
508 *bufp = xmalloc (len);
509 if (debug_aix_thread)
510 fprintf_unfiltered (gdb_stdlog, " malloc returned 0x%lx", (long) *bufp);
511 /* Note: xmalloc() can't return 0; therefore PDC_FAILURE will never be
512 returned. */
513 return *bufp ? PDC_SUCCESS : PDC_FAILURE;
514 }
515
516 /* pthdb callback: reallocate BUF, which was allocated by the alloc or realloc
517 callback, so that it contains LEN bytes, and store a pointer to the result
518 in BUFP. */
519
520 static int
521 pdc_realloc (pthdb_user_t user, void *buf, size_t len, void **bufp)
522 {
523 if (debug_aix_thread)
524 fprintf_unfiltered (gdb_stdlog,
525 "pdc_realloc (user = %ld, buf = 0x%lx, len = %ld, bufp = 0x%lx)",
526 user, (long) buf, len, (long) bufp);
527 *bufp = realloc (buf, len);
528 if (debug_aix_thread)
529 fprintf_unfiltered (gdb_stdlog, " realloc returned 0x%lx", (long) *bufp);
530 return *bufp ? PDC_SUCCESS : PDC_FAILURE;
531 }
532
533 /* pthdb callback: free BUF, which was allocated by the alloc or realloc
534 callback. */
535
536 static int
537 pdc_dealloc (pthdb_user_t user, void *buf)
538 {
539 if (debug_aix_thread)
540 fprintf_unfiltered (gdb_stdlog, "pdc_free (user = %ld, buf = 0x%lx)", user,
541 (long) buf);
542 xfree (buf);
543 return PDC_SUCCESS;
544 }
545
546 /* Return a printable representation of pthread STATE. */
547
548 static char *
549 state2str (pthdb_state_t state)
550 {
551 switch (state)
552 {
553 case PST_IDLE: return "idle"; /* being created */
554 case PST_RUN: return "running"; /* running */
555 case PST_SLEEP: return "sleeping"; /* awaiting an event */
556 case PST_READY: return "ready"; /* runnable */
557 case PST_TERM: return "finished"; /* awaiting a join/detach */
558 default: return "unknown";
559 }
560 }
561
562 /* qsort() comparison function for sorting pd_thread structs by pthid. */
563
564 static int
565 pcmp (const void *p1v, const void *p2v)
566 {
567 struct pd_thread *p1 = (struct pd_thread *) p1v;
568 struct pd_thread *p2 = (struct pd_thread *) p2v;
569 return p1->pthid < p2->pthid ? -1 : p1->pthid > p2->pthid;
570 }
571
572 /* iterate_over_threads() callback for counting GDB threads. */
573
574 static int
575 giter_count (struct thread_info *thread, void *countp)
576 {
577 (*(int *) countp)++;
578 return 0;
579 }
580
581 /* iterate_over_threads() callback for accumulating GDB thread pids. */
582
583 static int
584 giter_accum (struct thread_info *thread, void *bufp)
585 {
586 **(struct thread_info ***) bufp = thread;
587 (*(struct thread_info ***) bufp)++;
588 return 0;
589 }
590
591 /* ptid comparison function */
592 static int
593 ptid_cmp (ptid_t ptid1, ptid_t ptid2)
594 {
595 int pid1, pid2;
596
597 if (ptid_get_pid (ptid1) < ptid_get_pid (ptid2))
598 return -1;
599 else if (ptid_get_pid (ptid1) > ptid_get_pid (ptid2))
600 return 1;
601 else if (ptid_get_tid (ptid1) < ptid_get_tid (ptid2))
602 return -1;
603 else if (ptid_get_tid (ptid1) > ptid_get_tid (ptid2))
604 return 1;
605 else if (ptid_get_lwp (ptid1) < ptid_get_lwp (ptid2))
606 return -1;
607 else if (ptid_get_lwp (ptid1) > ptid_get_lwp (ptid2))
608 return 1;
609 else
610 return 0;
611 }
612
613 /* qsort() comparison function for sorting thread_info structs by pid. */
614
615 static int
616 gcmp (const void *t1v, const void *t2v)
617 {
618 struct thread_info *t1 = *(struct thread_info **) t1v;
619 struct thread_info *t2 = *(struct thread_info **) t2v;
620 return ptid_cmp (t1->ptid, t2->ptid);
621 }
622
623 /* Synchronize GDB's thread list with libpthdebug's.
624
625 There are some benefits of doing this every time the inferior stops:
626
627 - allows users to run thread-specific commands without needing to run
628 "info threads" first
629
630 - helps pthdb_tid_pthread() work properly (see "libpthdebug
631 peculiarities" at the top of this module)
632
633 - simplifies the demands placed on libpthdebug, which seems to have
634 difficulty with certain call patterns */
635
636 static void
637 sync_threadlists (void)
638 {
639 int cmd, status, infpid;
640 int pcount, psize, pi, gcount, gi;
641 struct pd_thread *pbuf;
642 struct thread_info **gbuf, **g, *thread;
643 pthdb_pthread_t pdtid;
644 pthread_t pthid;
645 pthdb_tid_t tid;
646 ptid_t pptid, gptid;
647
648 /* Accumulate an array of libpthdebug threads sorted by pthread id. */
649
650 pcount = 0;
651 psize = 1;
652 pbuf = (struct pd_thread *) xmalloc (psize * sizeof *pbuf);
653
654 for (cmd = PTHDB_LIST_FIRST;; cmd = PTHDB_LIST_NEXT)
655 {
656 status = pthdb_pthread (pd_session, &pdtid, cmd);
657 if (status != PTHDB_SUCCESS || pdtid == PTHDB_INVALID_PTHREAD)
658 break;
659
660 status = pthdb_pthread_ptid (pd_session, pdtid, &pthid);
661 if (status != PTHDB_SUCCESS || pthid == PTHDB_INVALID_PTID)
662 continue;
663
664 if (pcount == psize)
665 {
666 psize *= 2;
667 pbuf = (struct pd_thread *) xrealloc (pbuf, psize * sizeof *pbuf);
668 }
669 pbuf[pcount].pdtid = pdtid;
670 pbuf[pcount].pthid = pthid;
671 pcount++;
672 }
673
674 for (pi = 0; pi < pcount; pi++)
675 {
676 status = pthdb_pthread_tid (pd_session, pbuf[pi].pdtid, &tid);
677 if (status != PTHDB_SUCCESS)
678 tid = PTHDB_INVALID_TID;
679 pbuf[pi].tid = tid;
680 }
681
682 qsort (pbuf, pcount, sizeof *pbuf, pcmp);
683
684 /* Accumulate an array of GDB threads sorted by pid. */
685
686 gcount = 0;
687 iterate_over_threads (giter_count, &gcount);
688 g = gbuf = (struct thread_info **) xmalloc (gcount * sizeof *gbuf);
689 iterate_over_threads (giter_accum, &g);
690 qsort (gbuf, gcount, sizeof *gbuf, gcmp);
691
692 /* Apply differences between the two arrays to GDB's thread list. */
693
694 infpid = PIDGET (inferior_ptid);
695 for (pi = gi = 0; pi < pcount || gi < gcount;)
696 {
697 pptid = BUILD_THREAD (pbuf[pi].pthid, infpid);
698 gptid = gbuf[gi]->ptid;
699 pdtid = pbuf[pi].pdtid;
700 tid = pbuf[pi].tid;
701
702 if (pi == pcount)
703 goto del;
704 if (gi == gcount)
705 goto add;
706
707 if (ptid_equal (pptid, gptid))
708 {
709 gbuf[gi]->private->pdtid = pdtid;
710 gbuf[gi]->private->tid = tid;
711 pi++;
712 gi++;
713 }
714 else if (ptid_cmp (pptid, gptid) > 0)
715 {
716 del:
717 delete_thread (gptid);
718 gi++;
719 }
720 else
721 {
722 add:
723 thread = add_thread (pptid);
724 thread->private = xmalloc (sizeof (struct private_thread_info));
725 thread->private->pdtid = pdtid;
726 thread->private->tid = tid;
727 pi++;
728 }
729
730 }
731
732 xfree (pbuf);
733 xfree (gbuf);
734 }
735
736 /* iterate_over_threads() callback for locating a thread whose kernel thread
737 just received a trap signal. */
738
739 static int
740 iter_trap (struct thread_info *thread, void *unused)
741 {
742 struct thrdsinfo64 thrinf;
743 pthdb_tid_t tid;
744
745 /* getthrds(3) isn't prototyped in any AIX 4.3.3 #include file. */
746 extern int getthrds (pid_t, struct thrdsinfo64 *, int, pthdb_tid_t *, int);
747
748 tid = thread->private->tid;
749 if (tid == PTHDB_INVALID_TID)
750 return 0;
751
752 if (getthrds (PIDGET (inferior_ptid), &thrinf, sizeof (thrinf), &tid, 1) != 1)
753 return 0;
754
755 return thrinf.ti_cursig == SIGTRAP;
756 }
757
758 /* Synchronize libpthdebug's state with the inferior and with GDB, generate a
759 composite process/thread <pid> for the current thread, set inferior_ptid to
760 <pid> if SET_INFPID, and return <pid>. */
761
762 static ptid_t
763 pd_update (int set_infpid)
764 {
765 int status;
766 ptid_t ptid;
767 struct thread_info *thread;
768
769 if (!pd_active)
770 return inferior_ptid;
771
772 status = pthdb_session_update (pd_session);
773 if (status != PTHDB_SUCCESS)
774 return inferior_ptid;
775
776 sync_threadlists ();
777
778 /* Define "current thread" as one that just received a trap signal. */
779
780 thread = iterate_over_threads (iter_trap, NULL);
781 if (!thread)
782 ptid = inferior_ptid;
783 else
784 {
785 ptid = thread->ptid;
786 if (set_infpid)
787 inferior_ptid = ptid;
788 }
789 return ptid;
790 }
791
792 /* Try to start debugging threads in the current process. If successful and
793 SET_INFPID, set inferior_ptid to reflect the current thread. */
794
795 static ptid_t
796 pd_activate (int set_infpid)
797 {
798 int status;
799
800 status = pthdb_session_init (PD_USER, arch64 ? PEM_64BIT : PEM_32BIT,
801 PTHDB_FLAG_REGS, &pd_callbacks, &pd_session);
802 if (status != PTHDB_SUCCESS)
803 {
804 return inferior_ptid;
805 }
806 pd_active = 1;
807 return pd_update (set_infpid);
808 }
809
810 /* Undo the effects of pd_activate(). */
811
812 static void
813 pd_deactivate (void)
814 {
815 if (!pd_active)
816 return;
817 pthdb_session_destroy (pd_session);
818
819 pid_to_prc (&inferior_ptid);
820 pd_active = 0;
821 }
822
823 /* An object file has just been loaded. Check whether the current application
824 is pthreaded, and if so, prepare for thread debugging. */
825
826 static void
827 pd_enable (void)
828 {
829 int status;
830 char *stub_name;
831 struct minimal_symbol *ms;
832
833 /* Don't initialize twice. */
834 if (pd_able)
835 return;
836
837 /* Check application word size. */
838 arch64 = REGISTER_RAW_SIZE (0) == 8;
839
840 /* Check whether the application is pthreaded. */
841 stub_name = NULL;
842 status = pthdb_session_pthreaded (PD_USER, PTHDB_FLAG_REGS, &pd_callbacks,
843 &stub_name);
844 if ((status != PTHDB_SUCCESS && status != PTHDB_NOT_PTHREADED) || !stub_name)
845 return;
846
847 /* Set a breakpoint on the returned stub function. */
848 if (!(ms = lookup_minimal_symbol (stub_name, NULL, NULL)))
849 return;
850 pd_brk_addr = SYMBOL_VALUE_ADDRESS (ms);
851 if (!create_thread_event_breakpoint (pd_brk_addr))
852 return;
853
854 /* Prepare for thread debugging. */
855 base_ops = current_target;
856 push_target (&ops);
857 pd_able = 1;
858
859 /* If we're debugging a core file or an attached inferior, the pthread
860 library may already have been initialized, so try to activate thread
861 debugging. */
862 pd_activate (1);
863 }
864
865 /* Undo the effects of pd_enable(). */
866
867 static void
868 pd_disable (void)
869 {
870 if (!pd_able)
871 return;
872 if (pd_active)
873 pd_deactivate ();
874 pd_able = 0;
875 unpush_target (&ops);
876 }
877
878 /* target_new_objfile_hook callback.
879
880 If OBJFILE is non-null, check whether a threaded application is being
881 debugged, and if so, prepare for thread debugging.
882
883 If OBJFILE is null, stop debugging threads. */
884
885 static void
886 new_objfile (struct objfile *objfile)
887 {
888 if (objfile)
889 pd_enable ();
890 else
891 pd_disable ();
892
893 if (target_new_objfile_chain)
894 target_new_objfile_chain (objfile);
895 }
896
897 /* Attach to process specified by ARGS. */
898
899 static void
900 ops_attach (char *args, int from_tty)
901 {
902 base_ops.to_attach (args, from_tty);
903 pd_activate (1);
904 }
905
906 /* Detach from the process attached to by ops_attach(). */
907
908 static void
909 ops_detach (char *args, int from_tty)
910 {
911 pd_deactivate ();
912 base_ops.to_detach (args, from_tty);
913 }
914
915 /* Tell the inferior process to continue running thread PID if != -1
916 and all threads otherwise. */
917
918 static void
919 ops_resume (ptid_t ptid, int step, enum target_signal sig)
920 {
921 struct thread_info *thread;
922 pthdb_tid_t tid[2];
923
924 if (!PD_TID (ptid))
925 CALL_BASE (base_ops.to_resume (ptid, step, sig));
926 else
927 {
928 thread = find_thread_pid (ptid);
929 if (!thread)
930 error ("aix-thread resume: unknown pthread %ld", TIDGET (ptid));
931
932 tid[0] = thread->private->tid;
933 if (tid[0] == PTHDB_INVALID_TID)
934 error ("aix-thread resume: no tid for pthread %ld", TIDGET (ptid));
935 tid[1] = 0;
936
937 if (arch64)
938 ptrace64aix (PTT_CONTINUE, tid[0], 1, target_signal_to_host (sig), (int *)tid);
939 else
940 ptrace32 (PTT_CONTINUE, tid[0], (int *) 1,
941 target_signal_to_host (sig), (int *)tid);
942 }
943 }
944
945 /* Wait for thread/process ID if != -1 or for any thread otherwise. If an
946 error occurs, return -1, else return the pid of the stopped thread. */
947
948 static ptid_t
949 ops_wait (ptid_t ptid, struct target_waitstatus *status)
950 {
951 pid_to_prc (&ptid);
952 CALL_BASE (ptid = base_ops.to_wait (ptid, status));
953 if (PIDGET (ptid) == -1)
954 return pid_to_ptid (-1);
955
956 /* Check whether libpthdebug might be ready to be initialized. */
957 if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED &&
958 status->value.sig == TARGET_SIGNAL_TRAP &&
959 read_pc_pid (ptid) - DECR_PC_AFTER_BREAK == pd_brk_addr)
960 return pd_activate (0);
961
962 return pd_update (0);
963 }
964
965 /* Record that the 64-bit general-purpose registers contain VALS. */
966
967 static void
968 supply_gprs64 (uint64_t *vals)
969 {
970 int regno;
971
972 for (regno = 0; regno < 32; regno++)
973 supply_register (regno, (char *) (vals + regno));
974 }
975
976 /* Record that 32-bit register REGNO contains VAL. */
977
978 static void
979 supply_reg32 (int regno, uint32_t val)
980 {
981 supply_register (regno, (char *) &val);
982 }
983
984 /* Record that the floating-point registers contain VALS. */
985
986 static void
987 supply_fprs (double *vals)
988 {
989 int regno;
990
991 for (regno = 0; regno < 32; regno++)
992 supply_register (regno + FP0_REGNUM, (char *) (vals + regno));
993 }
994
995 /* Record that the special registers contain the specified 64-bit and 32-bit
996 values. */
997
998 static void
999 supply_sprs64 (uint64_t iar, uint64_t msr, uint32_t cr,
1000 uint64_t lr, uint64_t ctr, uint32_t xer)
1001 {
1002 int regno = FIRST_UISA_SP_REGNUM;
1003 supply_register (regno, (char *) &iar);
1004 supply_register (regno + 1, (char *) &msr);
1005 supply_register (regno + 2, (char *) &cr);
1006 supply_register (regno + 3, (char *) &lr);
1007 supply_register (regno + 4, (char *) &ctr);
1008 supply_register (regno + 5, (char *) &xer);
1009 }
1010
1011 /* Record that the special registers contain the specified 32-bit values. */
1012
1013 static void
1014 supply_sprs32 (uint32_t iar, uint32_t msr, uint32_t cr,
1015 uint32_t lr, uint32_t ctr, uint32_t xer)
1016 {
1017 int regno = FIRST_UISA_SP_REGNUM;
1018 supply_register (regno, (char *) &iar);
1019 supply_register (regno + 1, (char *) &msr);
1020 supply_register (regno + 2, (char *) &cr);
1021 supply_register (regno + 3, (char *) &lr);
1022 supply_register (regno + 4, (char *) &ctr);
1023 supply_register (regno + 5, (char *) &xer);
1024 }
1025
1026 /* Fetch all registers from pthread PDTID, which doesn't have a kernel
1027 thread.
1028
1029 There's no way to query a single register from a non-kernel pthread,
1030 so there's no need for a single-register version of this function. */
1031
1032 static void
1033 fetch_regs_lib (pthdb_pthread_t pdtid)
1034 {
1035 int status, i;
1036 pthdb_context_t ctx;
1037
1038 if (debug_aix_thread)
1039 fprintf_unfiltered (gdb_stdlog, "fetch_regs_lib %lx\n", (long)pdtid);
1040 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1041 if (status != PTHDB_SUCCESS)
1042 PD_ERROR ("fetch_registers: pthdb_pthread_context", status);
1043
1044 /* General-purpose registers. */
1045
1046 if (arch64)
1047 supply_gprs64 (ctx.gpr);
1048 else
1049 for (i = 0; i < 32; i++)
1050 supply_reg32 (i, ctx.gpr[i]);
1051
1052 /* Floating-point registers. */
1053
1054 supply_fprs (ctx.fpr);
1055
1056 /* Special registers. */
1057
1058 if (arch64)
1059 supply_sprs64 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer);
1060 else
1061 supply_sprs32 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer);
1062 }
1063
1064 /* Fetch register REGNO if != -1 or all registers otherwise from kernel thread
1065 TID.
1066
1067 AIX provides a way to query all of a kernel thread's GPRs, FPRs, or SPRs,
1068 but there's no way to query individual registers within those groups.
1069 Therefore, if REGNO != -1, this function fetches an entire group.
1070
1071 Unfortunately, kernel thread register queries often fail with EPERM,
1072 indicating that the thread is in kernel space. This breaks backtraces of
1073 threads other than the current one. To make that breakage obvious without
1074 throwing an error to top level (which is bad e.g. during "info threads"
1075 output), zero registers that can't be retrieved. */
1076
1077 static void
1078 fetch_regs_kern (int regno, pthdb_tid_t tid)
1079 {
1080 uint64_t gprs64[32];
1081 uint32_t gprs32[32];
1082 double fprs[32];
1083 struct ptxsprs sprs64;
1084 struct ptsprs sprs32;
1085 int i;
1086
1087 if (debug_aix_thread)
1088 fprintf_unfiltered (gdb_stdlog,
1089 "fetch_regs_kern tid=%lx regno=%d arch64=%d\n",
1090 (long)tid, regno, arch64);
1091
1092 /* General-purpose registers. */
1093 if (regno == -1 || regno < FP0_REGNUM)
1094 {
1095 if (arch64)
1096 {
1097 if (!ptrace64aix (PTT_READ_GPRS, tid, (unsigned long) gprs64, 0, NULL))
1098 memset (gprs64, 0, sizeof (gprs64));
1099 supply_gprs64 (gprs64);
1100 }
1101 else
1102 {
1103 if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
1104 memset (gprs32, 0, sizeof (gprs32));
1105 for (i = 0; i < 32; i++)
1106 supply_reg32 (i, gprs32[i]);
1107 }
1108 }
1109
1110 /* Floating-point registers. */
1111
1112 if (regno == -1 || (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM))
1113 {
1114 if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
1115 memset (fprs, 0, sizeof (fprs));
1116 supply_fprs (fprs);
1117 }
1118
1119 /* Special-purpose registers. */
1120
1121 if (regno == -1 || (regno > FPLAST_REGNUM && regno <= LAST_UISA_SP_REGNUM))
1122 {
1123 if (arch64)
1124 {
1125 if (!ptrace64aix (PTT_READ_SPRS, tid, (unsigned long) &sprs64, 0, NULL))
1126 memset (&sprs64, 0, sizeof (sprs64));
1127 supply_sprs64 (sprs64.pt_iar, sprs64.pt_msr, sprs64.pt_cr,
1128 sprs64.pt_lr, sprs64.pt_ctr, sprs64.pt_xer);
1129 }
1130 else
1131 {
1132 if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
1133 memset (&sprs32, 0, sizeof (sprs32));
1134 supply_sprs32 (sprs32.pt_iar, sprs32.pt_msr, sprs32.pt_cr,
1135 sprs32.pt_lr, sprs32.pt_ctr, sprs32.pt_xer);
1136
1137 if (REGISTER_RAW_SIZE (LAST_UISA_SP_REGNUM))
1138 supply_register (LAST_UISA_SP_REGNUM, (char *) &sprs32.pt_mq);
1139 }
1140 }
1141 }
1142
1143 /* Fetch register REGNO if != -1 or all registers otherwise in the
1144 thread/process specified by inferior_ptid. */
1145
1146 static void
1147 ops_fetch_registers (int regno)
1148 {
1149 struct thread_info *thread;
1150 pthdb_tid_t tid;
1151
1152 if (!PD_TID (inferior_ptid))
1153 base_ops.to_fetch_registers (regno);
1154 else
1155 {
1156 thread = find_thread_pid (inferior_ptid);
1157 tid = thread->private->tid;
1158
1159 if (tid == PTHDB_INVALID_TID)
1160 fetch_regs_lib (thread->private->pdtid);
1161 else
1162 fetch_regs_kern (regno, tid);
1163 }
1164 }
1165
1166 /* Store the special registers into the specified 64-bit and 32-bit
1167 locations. */
1168
1169 static void
1170 fill_sprs64 (uint64_t *iar, uint64_t *msr, uint32_t *cr,
1171 uint64_t *lr, uint64_t *ctr, uint32_t *xer)
1172 {
1173 int regno = FIRST_UISA_SP_REGNUM;
1174 *iar = read_register (regno);
1175 *msr = read_register (regno + 1);
1176 *cr = read_register (regno + 2);
1177 *lr = read_register (regno + 3);
1178 *ctr = read_register (regno + 4);
1179 *xer = read_register (regno + 5);
1180 }
1181
1182 /* Store all registers into pthread PDTID, which doesn't have a kernel
1183 thread.
1184
1185 It's possible to store a single register into a non-kernel pthread, but I
1186 doubt it's worth the effort. */
1187
1188 static void
1189 store_regs_lib (pthdb_pthread_t pdtid)
1190 {
1191 int status, i;
1192 pthdb_context_t ctx;
1193
1194 if (debug_aix_thread)
1195 fprintf_unfiltered (gdb_stdlog, "store_regs_lib %lx\n", (long)pdtid);
1196
1197 /* Retrieve the thread's current context for its non-register values. */
1198 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1199 if (status != PTHDB_SUCCESS)
1200 PD_ERROR ("store_registers: pthdb_pthread_context", status);
1201
1202 /* General-purpose registers. */
1203
1204 for (i = 0; i < 32; i++)
1205 ctx.gpr[i] = read_register (i);
1206
1207 /* Floating-point registers. */
1208
1209 for (i = 0; i < 32; i++)
1210 ctx.fpr[i] = *(double *) &registers[REGISTER_BYTE (FP0_REGNUM + i)];
1211
1212 /* Special registers. */
1213
1214 fill_sprs64 (&ctx.iar, &ctx.msr, &ctx.cr, &ctx.lr, &ctx.ctr, &ctx.xer);
1215
1216 status = pthdb_pthread_setcontext (pd_session, pdtid, &ctx);
1217 if (status != PTHDB_SUCCESS)
1218 PD_ERROR ("store_registers: pthdb_pthread_setcontext", status);
1219 }
1220
1221 /* Store register REGNO if != -1 or all registers otherwise into kernel
1222 thread TID.
1223
1224 AIX provides a way to set all of a kernel thread's GPRs, FPRs, or SPRs, but
1225 there's no way to set individual registers within those groups. Therefore,
1226 if REGNO != -1, this function stores an entire group. */
1227
1228 static void
1229 store_regs_kern (int regno, pthdb_tid_t tid)
1230 {
1231 struct ptxsprs sprs64;
1232 struct ptsprs sprs32;
1233 char *regp;
1234
1235 if (debug_aix_thread)
1236 fprintf_unfiltered (gdb_stdlog, "store_regs_kern tid=%lx regno=%d\n",
1237 (long)tid, regno);
1238
1239 /* General-purpose registers. */
1240 if (regno == -1 || regno < FP0_REGNUM)
1241 {
1242 regp = &registers[REGISTER_BYTE (0)];
1243 if (arch64)
1244 ptrace64aix (PTT_WRITE_GPRS, tid, (unsigned long) regp, 0, NULL);
1245 else
1246 ptrace32 (PTT_WRITE_GPRS, tid, (int *) regp, 0, NULL);
1247 }
1248
1249 /* Floating-point registers. */
1250
1251 if (regno == -1 || (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM))
1252 {
1253 regp = &registers[REGISTER_BYTE (FP0_REGNUM)];
1254 ptrace32 (PTT_WRITE_FPRS, tid, (int *) regp, 0, NULL);
1255 }
1256
1257 /* Special-purpose registers. */
1258
1259 if (regno == -1 || (regno > FPLAST_REGNUM && regno <= LAST_UISA_SP_REGNUM))
1260 {
1261 if (arch64)
1262 {
1263 ptrace64aix (PTT_READ_SPRS, tid, (unsigned long) &sprs64, 0, NULL);
1264 fill_sprs64 (&sprs64.pt_iar, &sprs64.pt_msr, &sprs64.pt_cr,
1265 &sprs64.pt_lr, &sprs64.pt_ctr, &sprs64.pt_xer);
1266 ptrace64aix (PTT_WRITE_SPRS, tid, (unsigned long) &sprs64, 0, NULL);
1267 }
1268 else
1269 {
1270 ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL);
1271
1272 regno = FIRST_UISA_SP_REGNUM;
1273 sprs32.pt_iar = read_register (regno);
1274 sprs32.pt_msr = read_register (regno + 1);
1275 sprs32.pt_cr = read_register (regno + 2);
1276 sprs32.pt_lr = read_register (regno + 3);
1277 sprs32.pt_ctr = read_register (regno + 4);
1278 sprs32.pt_xer = read_register (regno + 5);
1279
1280 if (REGISTER_RAW_SIZE (LAST_UISA_SP_REGNUM))
1281 sprs32.pt_mq = read_register (LAST_UISA_SP_REGNUM);
1282
1283 ptrace32 (PTT_WRITE_SPRS, tid, (int *) &sprs32, 0, NULL);
1284 }
1285 }
1286 }
1287
1288 /* Store gdb's current view of the register set into the thread/process
1289 specified by inferior_ptid. */
1290
1291 static void
1292 ops_store_registers (int regno)
1293 {
1294 struct thread_info *thread;
1295 pthdb_tid_t tid;
1296
1297 if (!PD_TID (inferior_ptid))
1298 base_ops.to_store_registers (regno);
1299 else
1300 {
1301 thread = find_thread_pid (inferior_ptid);
1302 tid = thread->private->tid;
1303
1304 if (tid == PTHDB_INVALID_TID)
1305 store_regs_lib (thread->private->pdtid);
1306 else
1307 store_regs_kern (regno, tid);
1308 }
1309 }
1310
1311 /* Prepare to modify the registers array. */
1312
1313 static void
1314 ops_prepare_to_store (void)
1315 {
1316 if (!PD_TID (inferior_ptid))
1317 base_ops.to_prepare_to_store ();
1318 else
1319 read_register_bytes (0, NULL, REGISTER_BYTES);
1320 }
1321
1322 /* Transfer LEN bytes of memory from GDB address MYADDR to target address
1323 MEMADDR if WRITE and vice versa otherwise. */
1324
1325 static int
1326 ops_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
1327 struct mem_attrib *attrib,
1328 struct target_ops *target)
1329 {
1330 int n;
1331
1332 CALL_BASE (n = base_ops.to_xfer_memory (memaddr, myaddr, len, write,
1333 attrib, &base_ops));
1334 return n;
1335 }
1336
1337 /* Kill and forget about the inferior process. */
1338
1339 static void
1340 ops_kill (void)
1341 {
1342 CALL_BASE (base_ops.to_kill ());
1343 }
1344
1345 /* Clean up after the inferior exits. */
1346
1347 static void
1348 ops_mourn_inferior (void)
1349 {
1350 pd_deactivate ();
1351 base_ops.to_mourn_inferior ();
1352 }
1353
1354 /* Return whether thread PID is still valid. */
1355
1356 static int
1357 ops_thread_alive (ptid_t ptid)
1358 {
1359 if (!PD_TID (ptid))
1360 return base_ops.to_thread_alive (ptid);
1361
1362 /* We update the thread list every time the child stops, so all valid
1363 threads should be in the thread list. */
1364 return in_thread_list (ptid);
1365 }
1366
1367 /* Return a printable representation of composite PID for use in "info
1368 threads" output. */
1369
1370 static char *
1371 ops_pid_to_str (ptid_t ptid)
1372 {
1373 static char *ret = NULL;
1374
1375 if (!PD_TID (ptid))
1376 return base_ops.to_pid_to_str (ptid);
1377
1378 /* Free previous return value; a new one will be allocated by
1379 xasprintf(). */
1380 xfree (ret);
1381
1382 xasprintf (&ret, "Thread %ld", ptid_get_tid (ptid));
1383 return ret;
1384 }
1385
1386 /* Return a printable representation of extra information about THREAD, for
1387 use in "info threads" output. */
1388
1389 static char *
1390 ops_extra_thread_info (struct thread_info *thread)
1391 {
1392 struct ui_file *buf;
1393 int status;
1394 pthdb_pthread_t pdtid;
1395 pthdb_tid_t tid;
1396 pthdb_state_t state;
1397 pthdb_suspendstate_t suspendstate;
1398 pthdb_detachstate_t detachstate;
1399 int cancelpend;
1400 long length;
1401 static char *ret = NULL;
1402
1403 if (!PD_TID (thread->ptid))
1404 return NULL;
1405
1406 buf = mem_fileopen ();
1407
1408 pdtid = thread->private->pdtid;
1409 tid = thread->private->tid;
1410
1411 if (tid != PTHDB_INVALID_TID)
1412 fprintf_unfiltered (buf, "tid %d", tid);
1413
1414 status = pthdb_pthread_state (pd_session, pdtid, &state);
1415 if (status != PTHDB_SUCCESS)
1416 state = PST_NOTSUP;
1417 fprintf_unfiltered (buf, ", %s", state2str (state));
1418
1419 status = pthdb_pthread_suspendstate (pd_session, pdtid, &suspendstate);
1420 if (status == PTHDB_SUCCESS && suspendstate == PSS_SUSPENDED)
1421 fprintf_unfiltered (buf, ", suspended");
1422
1423 status = pthdb_pthread_detachstate (pd_session, pdtid, &detachstate);
1424 if (status == PTHDB_SUCCESS && detachstate == PDS_DETACHED)
1425 fprintf_unfiltered (buf, ", detached");
1426
1427 pthdb_pthread_cancelpend (pd_session, pdtid, &cancelpend);
1428 if (status == PTHDB_SUCCESS && cancelpend)
1429 fprintf_unfiltered (buf, ", cancel pending");
1430
1431 ui_file_write (buf, "", 1);
1432
1433 xfree (ret); /* Free old buffer. */
1434
1435 ret = ui_file_xstrdup (buf, &length);
1436 ui_file_delete (buf);
1437
1438 return ret;
1439 }
1440
1441 /* Initialize target ops. */
1442
1443 static void
1444 init_ops (void)
1445 {
1446 ops.to_shortname = "aix-threads";
1447 ops.to_longname = "AIX pthread support";
1448 ops.to_doc = "AIX pthread support";
1449
1450 ops.to_attach = ops_attach;
1451 ops.to_detach = ops_detach;
1452 ops.to_resume = ops_resume;
1453 ops.to_wait = ops_wait;
1454 ops.to_fetch_registers = ops_fetch_registers;
1455 ops.to_store_registers = ops_store_registers;
1456 ops.to_prepare_to_store = ops_prepare_to_store;
1457 ops.to_xfer_memory = ops_xfer_memory;
1458 /* No need for ops.to_create_inferior, because we activate thread debugging
1459 when the inferior reaches pd_brk_addr. */
1460 ops.to_kill = ops_kill;
1461 ops.to_mourn_inferior = ops_mourn_inferior;
1462 ops.to_thread_alive = ops_thread_alive;
1463 ops.to_pid_to_str = ops_pid_to_str;
1464 ops.to_extra_thread_info = ops_extra_thread_info;
1465 ops.to_stratum = thread_stratum;
1466 ops.to_magic = OPS_MAGIC;
1467 }
1468
1469 /* Module startup initialization function, automagically called by
1470 init.c. */
1471
1472 void
1473 _initialize_aix_thread (void)
1474 {
1475 init_ops ();
1476 add_target (&ops);
1477
1478 /* Notice when object files get loaded and unloaded. */
1479 target_new_objfile_chain = target_new_objfile_hook;
1480 target_new_objfile_hook = new_objfile;
1481
1482 add_show_from_set (add_set_cmd ("aix-thread", no_class, var_zinteger,
1483 (char *) &debug_aix_thread,
1484 "Set debugging of AIX thread module.\n"
1485 "Enables printf debugging output.\n",
1486 &setdebuglist),
1487 &showdebuglist);
1488 }
This page took 0.061292 seconds and 4 git commands to generate.