1 /* Low level interface for debugging AIX 4.3+ pthreads.
3 Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
4 Written by Nick Duffek <nsd@redhat.com>.
6 This file is part of GDB.
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.
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.
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. */
24 /* This module uses the libpthdebug.a library provided by AIX 4.3+ for
25 debugging pthread applications.
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
32 libpthdebug peculiarities:
34 - pthdb_ptid_pthread() is prototyped in <sys/pthdebug.h>, but
35 it's not documented, and after several calls it stops working
36 and causes other libpthdebug functions to fail.
38 - pthdb_tid_pthread() doesn't always work after
39 pthdb_session_update(), but it does work after cycling through
40 all threads using pthdb_pthread().
45 #include "gdbthread.h"
52 #include "coff/internal.h" /* for libcoff.h */
53 #include "bfd/libcoff.h" /* for xcoff_data */
57 #include <sys/types.h>
58 #include <sys/ptrace.h>
64 #include <sys/pthdebug.h>
66 /* Whether to emit debugging output. */
67 static int debug_aix_thread;
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
74 /* Return whether to treat PID as a debuggable thread id. */
76 #define PD_TID(ptid) (pd_active && ptid_get_tid (ptid) != 0)
78 /* Build a thread ptid. */
79 #define BUILD_THREAD(TID, PID) ptid_build (PID, 0, TID)
81 /* Build and lwp ptid. */
82 #define BUILD_LWP(LWP, PID) MERGEPID (PID, LWP)
84 /* pthdb_user_t value that we pass to pthdb functions. 0 causes
85 PTHDB_BAD_USER errors, so use 1. */
89 /* Success and failure values returned by pthdb callbacks. */
91 #define PDC_SUCCESS PTHDB_SUCCESS
92 #define PDC_FAILURE PTHDB_CALLBACK
94 /* Private data attached to each element in GDB's thread list. */
96 struct private_thread_info {
97 pthdb_pthread_t pdtid; /* thread's libpthdebug id */
98 pthdb_tid_t tid; /* kernel thread id */
101 /* Information about a thread of which libpthdebug is aware. */
104 pthdb_pthread_t pdtid;
109 /* This module's target-specific operations, active while pd_able is true. */
111 static struct target_ops ops;
113 /* Copy of the target over which ops is pushed.
114 This is more convenient than a pointer to child_ops or core_ops,
115 because they lack current_target's default callbacks. */
117 static struct target_ops base_ops;
119 /* Address of the function that libpthread will call when libpthdebug
120 is ready to be initialized. */
122 static CORE_ADDR pd_brk_addr;
124 /* Whether the current application is debuggable by pthdb. */
126 static int pd_able = 0;
128 /* Whether a threaded application is being debugged. */
130 static int pd_active = 0;
132 /* Whether the current architecture is 64-bit.
133 Only valid when pd_able is true. */
137 /* Saved pointer to previous owner of target_new_objfile_hook. */
139 static void (*target_new_objfile_chain)(struct objfile *);
141 /* Forward declarations for pthdb callbacks. */
143 static int pdc_symbol_addrs (pthdb_user_t, pthdb_symbol_t *, int);
144 static int pdc_read_data (pthdb_user_t, void *, pthdb_addr_t, size_t);
145 static int pdc_write_data (pthdb_user_t, void *, pthdb_addr_t, size_t);
146 static int pdc_read_regs (pthdb_user_t user, pthdb_tid_t tid,
147 unsigned long long flags,
148 pthdb_context_t *context);
149 static int pdc_write_regs (pthdb_user_t user, pthdb_tid_t tid,
150 unsigned long long flags,
151 pthdb_context_t *context);
152 static int pdc_alloc (pthdb_user_t, size_t, void **);
153 static int pdc_realloc (pthdb_user_t, void *, size_t, void **);
154 static int pdc_dealloc (pthdb_user_t, void *);
156 /* pthdb callbacks. */
158 static pthdb_callbacks_t pd_callbacks = {
170 /* Current pthdb session. */
172 static pthdb_session_t pd_session;
174 /* Return a printable representation of pthdebug function return
178 pd_status2str (int status)
182 case PTHDB_SUCCESS: return "SUCCESS";
183 case PTHDB_NOSYS: return "NOSYS";
184 case PTHDB_NOTSUP: return "NOTSUP";
185 case PTHDB_BAD_VERSION: return "BAD_VERSION";
186 case PTHDB_BAD_USER: return "BAD_USER";
187 case PTHDB_BAD_SESSION: return "BAD_SESSION";
188 case PTHDB_BAD_MODE: return "BAD_MODE";
189 case PTHDB_BAD_FLAGS: return "BAD_FLAGS";
190 case PTHDB_BAD_CALLBACK: return "BAD_CALLBACK";
191 case PTHDB_BAD_POINTER: return "BAD_POINTER";
192 case PTHDB_BAD_CMD: return "BAD_CMD";
193 case PTHDB_BAD_PTHREAD: return "BAD_PTHREAD";
194 case PTHDB_BAD_ATTR: return "BAD_ATTR";
195 case PTHDB_BAD_MUTEX: return "BAD_MUTEX";
196 case PTHDB_BAD_MUTEXATTR: return "BAD_MUTEXATTR";
197 case PTHDB_BAD_COND: return "BAD_COND";
198 case PTHDB_BAD_CONDATTR: return "BAD_CONDATTR";
199 case PTHDB_BAD_RWLOCK: return "BAD_RWLOCK";
200 case PTHDB_BAD_RWLOCKATTR: return "BAD_RWLOCKATTR";
201 case PTHDB_BAD_KEY: return "BAD_KEY";
202 case PTHDB_BAD_PTID: return "BAD_PTID";
203 case PTHDB_BAD_TID: return "BAD_TID";
204 case PTHDB_CALLBACK: return "CALLBACK";
205 case PTHDB_CONTEXT: return "CONTEXT";
206 case PTHDB_HELD: return "HELD";
207 case PTHDB_NOT_HELD: return "NOT_HELD";
208 case PTHDB_MEMORY: return "MEMORY";
209 case PTHDB_NOT_PTHREADED: return "NOT_PTHREADED";
210 case PTHDB_SYMBOL: return "SYMBOL";
211 case PTHDB_NOT_AVAIL: return "NOT_AVAIL";
212 case PTHDB_INTERNAL: return "INTERNAL";
213 default: return "UNKNOWN";
217 /* A call to ptrace(REQ, ID, ...) just returned RET. Check for
218 exceptional conditions and either return nonlocally or else return
219 1 for success and 0 for failure. */
222 ptrace_check (int req, int id, int ret)
224 if (ret == 0 && !errno)
227 /* According to ptrace(2), ptrace may fail with EPERM if "the
228 Identifier parameter corresponds to a kernel thread which is
229 stopped in kernel mode and whose computational state cannot be
230 read or written." This happens quite often with register reads. */
237 if (ret == -1 && errno == EPERM)
239 if (debug_aix_thread)
240 fprintf_unfiltered (gdb_stdlog,
241 "ptrace (%d, %d) = %d (errno = %d)",
242 req, id, ret, errno);
243 return ret == -1 ? 0 : 1;
247 error ("aix-thread: ptrace (%d, %d) returned %d (errno = %d %s)",
248 req, id, ret, errno, safe_strerror (errno));
249 return 0; /* Not reached. */
252 /* Call ptracex (REQ, ID, ADDR, DATA, BUF). Return success. */
255 ptrace64aix (int req, int id, long long addr, int data, int *buf)
258 return ptrace_check (req, id, ptracex (req, id, addr, data, buf));
261 /* Call ptrace (REQ, ID, ADDR, DATA, BUF). Return success. */
264 ptrace32 (int req, int id, int *addr, int data, int *buf)
267 return ptrace_check (req, id,
268 ptrace (req, id, (int *)addr, data, buf));
271 /* If *PIDP is a composite process/thread id, convert it to a
275 pid_to_prc (ptid_t *ptidp)
281 *ptidp = pid_to_ptid (PIDGET (ptid));
284 /* pthdb callback: for <i> from 0 to COUNT, set SYMBOLS[<i>].addr to
285 the address of SYMBOLS[<i>].name. */
288 pdc_symbol_addrs (pthdb_user_t user, pthdb_symbol_t *symbols, int count)
290 struct minimal_symbol *ms;
294 if (debug_aix_thread)
295 fprintf_unfiltered (gdb_stdlog,
296 "pdc_symbol_addrs (user = %ld, symbols = 0x%lx, count = %d)",
297 user, (long) symbols, count);
299 for (i = 0; i < count; i++)
301 name = symbols[i].name;
302 if (debug_aix_thread)
303 fprintf_unfiltered (gdb_stdlog,
304 " symbols[%d].name = \"%s\"", i, name);
310 if (!(ms = lookup_minimal_symbol (name, NULL, NULL)))
312 if (debug_aix_thread)
313 fprintf_unfiltered (gdb_stdlog, " returning PDC_FAILURE");
316 symbols[i].addr = SYMBOL_VALUE_ADDRESS (ms);
318 if (debug_aix_thread)
319 fprintf_unfiltered (gdb_stdlog, " symbols[%d].addr = 0x%llx",
322 if (debug_aix_thread)
323 fprintf_unfiltered (gdb_stdlog, " returning PDC_SUCCESS");
327 /* Read registers call back function should be able to read the
328 context information of a debuggee kernel thread from an active
329 process or from a core file. The information should be formatted
330 in context64 form for both 32-bit and 64-bit process.
331 If successful return 0, else non-zero is returned. */
334 pdc_read_regs (pthdb_user_t user,
336 unsigned long long flags,
337 pthdb_context_t *context)
339 /* This function doesn't appear to be used, so we could probably
340 just return 0 here. HOWEVER, if it is not defined, the OS will
341 complain and several thread debug functions will fail. In case
342 this is needed, I have implemented what I think it should do,
343 however this code is untested. */
348 struct ptxsprs sprs64;
349 struct ptsprs sprs32;
351 if (debug_aix_thread)
352 fprintf_unfiltered (gdb_stdlog, "pdc_read_regs tid=%d flags=%llx\n",
355 /* General-purpose registers. */
356 if (flags & PTHDB_FLAG_GPRS)
360 if (!ptrace64aix (PTT_READ_GPRS, tid,
361 (unsigned long) gprs64, 0, NULL))
362 memset (gprs64, 0, sizeof (gprs64));
363 memcpy (context->gpr, gprs64, sizeof(gprs64));
367 if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
368 memset (gprs32, 0, sizeof (gprs32));
369 memcpy (context->gpr, gprs32, sizeof(gprs32));
373 /* Floating-point registers. */
374 if (flags & PTHDB_FLAG_FPRS)
376 if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
377 memset (fprs, 0, sizeof (fprs));
378 memcpy (context->fpr, fprs, sizeof(fprs));
381 /* Special-purpose registers. */
382 if (flags & PTHDB_FLAG_SPRS)
386 if (!ptrace64aix (PTT_READ_SPRS, tid,
387 (unsigned long) &sprs64, 0, NULL))
388 memset (&sprs64, 0, sizeof (sprs64));
389 memcpy (&context->msr, &sprs64, sizeof(sprs64));
393 if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
394 memset (&sprs32, 0, sizeof (sprs32));
395 memcpy (&context->msr, &sprs32, sizeof(sprs32));
401 /* Write register function should be able to write requested context
402 information to specified debuggee's kernel thread id.
403 If successful return 0, else non-zero is returned. */
406 pdc_write_regs (pthdb_user_t user,
408 unsigned long long flags,
409 pthdb_context_t *context)
411 /* This function doesn't appear to be used, so we could probably
412 just return 0 here. HOWEVER, if it is not defined, the OS will
413 complain and several thread debug functions will fail. In case
414 this is needed, I have implemented what I think it should do,
415 however this code is untested. */
417 if (debug_aix_thread)
418 fprintf_unfiltered (gdb_stdlog, "pdc_write_regs tid=%d flags=%llx\n",
421 /* General-purpose registers. */
422 if (flags & PTHDB_FLAG_GPRS)
425 ptrace64aix (PTT_WRITE_GPRS, tid,
426 (unsigned long)context->gpr, 0, NULL);
428 ptrace32 (PTT_WRITE_GPRS, tid, (int *)context->gpr, 0, NULL);
431 /* Floating-point registers. */
432 if (flags & PTHDB_FLAG_FPRS)
434 ptrace32 (PTT_WRITE_FPRS, tid, (int *)context->fpr, 0, NULL);
437 /* Special-purpose registers. */
438 if (flags & PTHDB_FLAG_SPRS)
442 ptrace64aix (PTT_WRITE_SPRS, tid,
443 (unsigned long) &context->msr, 0, NULL);
447 ptrace32 (PTT_WRITE_SPRS, tid, (int *)&context->msr, 0, NULL);
453 /* pthdb callback: read LEN bytes from process ADDR into BUF. */
456 pdc_read_data (pthdb_user_t user, void *buf,
457 pthdb_addr_t addr, size_t len)
461 if (debug_aix_thread)
462 fprintf_unfiltered (gdb_stdlog,
463 "pdc_read_data (user = %ld, buf = 0x%lx, addr = 0x%llx, len = %ld)",
464 user, (long) buf, addr, len);
466 status = target_read_memory (addr, buf, len);
467 ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
469 if (debug_aix_thread)
470 fprintf_unfiltered (gdb_stdlog, " status=%d, returning %s",
471 status, pd_status2str (ret));
475 /* pthdb callback: write LEN bytes from BUF to process ADDR. */
478 pdc_write_data (pthdb_user_t user, void *buf,
479 pthdb_addr_t addr, size_t len)
483 if (debug_aix_thread)
484 fprintf_unfiltered (gdb_stdlog,
485 "pdc_write_data (user = %ld, buf = 0x%lx, addr = 0x%llx, len = %ld)",
486 user, (long) buf, addr, len);
488 status = target_write_memory (addr, buf, len);
489 ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
491 if (debug_aix_thread)
492 fprintf_unfiltered (gdb_stdlog, " status=%d, returning %s", status,
493 pd_status2str (ret));
497 /* pthdb callback: allocate a LEN-byte buffer and store a pointer to it
501 pdc_alloc (pthdb_user_t user, size_t len, void **bufp)
503 if (debug_aix_thread)
504 fprintf_unfiltered (gdb_stdlog,
505 "pdc_alloc (user = %ld, len = %ld, bufp = 0x%lx)",
506 user, len, (long) bufp);
507 *bufp = xmalloc (len);
508 if (debug_aix_thread)
509 fprintf_unfiltered (gdb_stdlog,
510 " malloc returned 0x%lx", (long) *bufp);
512 /* Note: xmalloc() can't return 0; therefore PDC_FAILURE will never
515 return *bufp ? PDC_SUCCESS : PDC_FAILURE;
518 /* pthdb callback: reallocate BUF, which was allocated by the alloc or
519 realloc callback, so that it contains LEN bytes, and store a
520 pointer to the result in BUFP. */
523 pdc_realloc (pthdb_user_t user, void *buf, size_t len, void **bufp)
525 if (debug_aix_thread)
526 fprintf_unfiltered (gdb_stdlog,
527 "pdc_realloc (user = %ld, buf = 0x%lx, len = %ld, bufp = 0x%lx)",
528 user, (long) buf, len, (long) bufp);
529 *bufp = xrealloc (buf, len);
530 if (debug_aix_thread)
531 fprintf_unfiltered (gdb_stdlog,
532 " realloc returned 0x%lx", (long) *bufp);
533 return *bufp ? PDC_SUCCESS : PDC_FAILURE;
536 /* pthdb callback: free BUF, which was allocated by the alloc or
540 pdc_dealloc (pthdb_user_t user, void *buf)
542 if (debug_aix_thread)
543 fprintf_unfiltered (gdb_stdlog,
544 "pdc_free (user = %ld, buf = 0x%lx)", user,
550 /* Return a printable representation of pthread STATE. */
553 state2str (pthdb_state_t state)
557 case PST_IDLE: return "idle"; /* being created */
558 case PST_RUN: return "running"; /* running */
559 case PST_SLEEP: return "sleeping"; /* awaiting an event */
560 case PST_READY: return "ready"; /* runnable */
561 case PST_TERM: return "finished"; /* awaiting a join/detach */
562 default: return "unknown";
566 /* qsort() comparison function for sorting pd_thread structs by pthid. */
569 pcmp (const void *p1v, const void *p2v)
571 struct pd_thread *p1 = (struct pd_thread *) p1v;
572 struct pd_thread *p2 = (struct pd_thread *) p2v;
573 return p1->pthid < p2->pthid ? -1 : p1->pthid > p2->pthid;
576 /* iterate_over_threads() callback for counting GDB threads. */
579 giter_count (struct thread_info *thread, void *countp)
585 /* iterate_over_threads() callback for accumulating GDB thread pids. */
588 giter_accum (struct thread_info *thread, void *bufp)
590 **(struct thread_info ***) bufp = thread;
591 (*(struct thread_info ***) bufp)++;
595 /* ptid comparison function */
598 ptid_cmp (ptid_t ptid1, ptid_t ptid2)
602 if (ptid_get_pid (ptid1) < ptid_get_pid (ptid2))
604 else if (ptid_get_pid (ptid1) > ptid_get_pid (ptid2))
606 else if (ptid_get_tid (ptid1) < ptid_get_tid (ptid2))
608 else if (ptid_get_tid (ptid1) > ptid_get_tid (ptid2))
610 else if (ptid_get_lwp (ptid1) < ptid_get_lwp (ptid2))
612 else if (ptid_get_lwp (ptid1) > ptid_get_lwp (ptid2))
618 /* qsort() comparison function for sorting thread_info structs by pid. */
621 gcmp (const void *t1v, const void *t2v)
623 struct thread_info *t1 = *(struct thread_info **) t1v;
624 struct thread_info *t2 = *(struct thread_info **) t2v;
625 return ptid_cmp (t1->ptid, t2->ptid);
628 /* Synchronize GDB's thread list with libpthdebug's.
630 There are some benefits of doing this every time the inferior stops:
632 - allows users to run thread-specific commands without needing to
633 run "info threads" first
635 - helps pthdb_tid_pthread() work properly (see "libpthdebug
636 peculiarities" at the top of this module)
638 - simplifies the demands placed on libpthdebug, which seems to
639 have difficulty with certain call patterns */
642 sync_threadlists (void)
644 int cmd, status, infpid;
645 int pcount, psize, pi, gcount, gi;
646 struct pd_thread *pbuf;
647 struct thread_info **gbuf, **g, *thread;
648 pthdb_pthread_t pdtid;
652 /* Accumulate an array of libpthdebug threads sorted by pthread id. */
656 pbuf = (struct pd_thread *) xmalloc (psize * sizeof *pbuf);
658 for (cmd = PTHDB_LIST_FIRST;; cmd = PTHDB_LIST_NEXT)
660 status = pthdb_pthread (pd_session, &pdtid, cmd);
661 if (status != PTHDB_SUCCESS || pdtid == PTHDB_INVALID_PTHREAD)
664 status = pthdb_pthread_ptid (pd_session, pdtid, &pthid);
665 if (status != PTHDB_SUCCESS || pthid == PTHDB_INVALID_PTID)
671 pbuf = (struct pd_thread *) xrealloc (pbuf,
672 psize * sizeof *pbuf);
674 pbuf[pcount].pdtid = pdtid;
675 pbuf[pcount].pthid = pthid;
679 for (pi = 0; pi < pcount; pi++)
681 status = pthdb_pthread_tid (pd_session, pbuf[pi].pdtid, &tid);
682 if (status != PTHDB_SUCCESS)
683 tid = PTHDB_INVALID_TID;
687 qsort (pbuf, pcount, sizeof *pbuf, pcmp);
689 /* Accumulate an array of GDB threads sorted by pid. */
692 iterate_over_threads (giter_count, &gcount);
693 g = gbuf = (struct thread_info **) xmalloc (gcount * sizeof *gbuf);
694 iterate_over_threads (giter_accum, &g);
695 qsort (gbuf, gcount, sizeof *gbuf, gcmp);
697 /* Apply differences between the two arrays to GDB's thread list. */
699 infpid = PIDGET (inferior_ptid);
700 for (pi = gi = 0; pi < pcount || gi < gcount;)
704 delete_thread (gbuf[gi]->ptid);
707 else if (gi == gcount)
709 thread = add_thread (BUILD_THREAD (pbuf[pi].pthid, infpid));
710 thread->private = xmalloc (sizeof (struct private_thread_info));
711 thread->private->pdtid = pbuf[pi].pdtid;
712 thread->private->tid = pbuf[pi].tid;
720 pptid = BUILD_THREAD (pbuf[pi].pthid, infpid);
721 gptid = gbuf[gi]->ptid;
722 pdtid = pbuf[pi].pdtid;
725 cmp_result = ptid_cmp (pptid, gptid);
729 gbuf[gi]->private->pdtid = pdtid;
730 gbuf[gi]->private->tid = tid;
734 else if (cmp_result > 0)
736 delete_thread (gptid);
741 thread = add_thread (pptid);
742 thread->private = xmalloc (sizeof (struct private_thread_info));
743 thread->private->pdtid = pdtid;
744 thread->private->tid = tid;
754 /* Iterate_over_threads() callback for locating a thread whose kernel
755 thread just received a trap signal. */
758 iter_trap (struct thread_info *thread, void *unused)
760 struct thrdsinfo64 thrinf;
763 /* getthrds(3) isn't prototyped in any AIX 4.3.3 #include file. */
764 extern int getthrds (pid_t, struct thrdsinfo64 *,
765 int, pthdb_tid_t *, int);
767 tid = thread->private->tid;
768 if (tid == PTHDB_INVALID_TID)
771 if (getthrds (PIDGET (inferior_ptid), &thrinf,
772 sizeof (thrinf), &tid, 1) != 1)
775 return thrinf.ti_cursig == SIGTRAP;
778 /* Synchronize libpthdebug's state with the inferior and with GDB,
779 generate a composite process/thread <pid> for the current thread,
780 set inferior_ptid to <pid> if SET_INFPID, and return <pid>. */
783 pd_update (int set_infpid)
787 struct thread_info *thread;
790 return inferior_ptid;
792 status = pthdb_session_update (pd_session);
793 if (status != PTHDB_SUCCESS)
794 return inferior_ptid;
798 /* Define "current thread" as one that just received a trap signal. */
800 thread = iterate_over_threads (iter_trap, NULL);
802 ptid = inferior_ptid;
807 inferior_ptid = ptid;
812 /* Try to start debugging threads in the current process.
813 If successful and SET_INFPID, set inferior_ptid to reflect the
817 pd_activate (int set_infpid)
821 status = pthdb_session_init (PD_USER, arch64 ? PEM_64BIT : PEM_32BIT,
822 PTHDB_FLAG_REGS, &pd_callbacks,
824 if (status != PTHDB_SUCCESS)
826 return inferior_ptid;
829 return pd_update (set_infpid);
832 /* Undo the effects of pd_activate(). */
839 pthdb_session_destroy (pd_session);
841 pid_to_prc (&inferior_ptid);
845 /* An object file has just been loaded. Check whether the current
846 application is pthreaded, and if so, prepare for thread debugging. */
853 struct minimal_symbol *ms;
855 /* Don't initialize twice. */
859 /* Check application word size. */
860 arch64 = REGISTER_RAW_SIZE (0) == 8;
862 /* Check whether the application is pthreaded. */
864 status = pthdb_session_pthreaded (PD_USER, PTHDB_FLAG_REGS,
865 &pd_callbacks, &stub_name);
866 if ((status != PTHDB_SUCCESS &&
867 status != PTHDB_NOT_PTHREADED) || !stub_name)
870 /* Set a breakpoint on the returned stub function. */
871 if (!(ms = lookup_minimal_symbol (stub_name, NULL, NULL)))
873 pd_brk_addr = SYMBOL_VALUE_ADDRESS (ms);
874 if (!create_thread_event_breakpoint (pd_brk_addr))
877 /* Prepare for thread debugging. */
878 base_ops = current_target;
882 /* If we're debugging a core file or an attached inferior, the
883 pthread library may already have been initialized, so try to
884 activate thread debugging. */
888 /* Undo the effects of pd_enable(). */
898 unpush_target (&ops);
901 /* target_new_objfile_hook callback.
903 If OBJFILE is non-null, check whether a threaded application is
904 being debugged, and if so, prepare for thread debugging.
906 If OBJFILE is null, stop debugging threads. */
909 new_objfile (struct objfile *objfile)
916 if (target_new_objfile_chain)
917 target_new_objfile_chain (objfile);
920 /* Attach to process specified by ARGS. */
923 ops_attach (char *args, int from_tty)
925 base_ops.to_attach (args, from_tty);
929 /* Detach from the process attached to by ops_attach(). */
932 ops_detach (char *args, int from_tty)
935 base_ops.to_detach (args, from_tty);
938 /* Tell the inferior process to continue running thread PID if != -1
939 and all threads otherwise. */
942 ops_resume (ptid_t ptid, int step, enum target_signal sig)
944 struct thread_info *thread;
949 struct cleanup *cleanup = save_inferior_ptid ();
950 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
951 base_ops.to_resume (ptid, step, sig);
952 do_cleanups (cleanup);
956 thread = find_thread_pid (ptid);
958 error ("aix-thread resume: unknown pthread %ld",
961 tid[0] = thread->private->tid;
962 if (tid[0] == PTHDB_INVALID_TID)
963 error ("aix-thread resume: no tid for pthread %ld",
968 ptrace64aix (PTT_CONTINUE, tid[0], 1,
969 target_signal_to_host (sig), (int *)tid);
971 ptrace32 (PTT_CONTINUE, tid[0], (int *) 1,
972 target_signal_to_host (sig), (int *)tid);
976 /* Wait for thread/process ID if != -1 or for any thread otherwise.
977 If an error occurs, return -1, else return the pid of the stopped
981 ops_wait (ptid_t ptid, struct target_waitstatus *status)
983 struct cleanup *cleanup = save_inferior_ptid ();
987 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
988 ptid = base_ops.to_wait (ptid, status);
989 do_cleanups (cleanup);
991 if (PIDGET (ptid) == -1)
992 return pid_to_ptid (-1);
994 /* Check whether libpthdebug might be ready to be initialized. */
995 if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED &&
996 status->value.sig == TARGET_SIGNAL_TRAP &&
997 read_pc_pid (ptid) - DECR_PC_AFTER_BREAK == pd_brk_addr)
998 return pd_activate (0);
1000 return pd_update (0);
1003 /* Record that the 64-bit general-purpose registers contain VALS. */
1006 supply_gprs64 (uint64_t *vals)
1010 for (regno = 0; regno < 32; regno++)
1011 supply_register (regno, (char *) (vals + regno));
1014 /* Record that 32-bit register REGNO contains VAL. */
1017 supply_reg32 (int regno, uint32_t val)
1019 supply_register (regno, (char *) &val);
1022 /* Record that the floating-point registers contain VALS. */
1025 supply_fprs (double *vals)
1029 for (regno = 0; regno < 32; regno++)
1030 supply_register (regno + FP0_REGNUM, (char *) (vals + regno));
1033 /* Record that the special registers contain the specified 64-bit and
1037 supply_sprs64 (uint64_t iar, uint64_t msr, uint32_t cr,
1038 uint64_t lr, uint64_t ctr, uint32_t xer)
1040 int regno = FIRST_UISA_SP_REGNUM;
1041 supply_register (regno, (char *) &iar);
1042 supply_register (regno + 1, (char *) &msr);
1043 supply_register (regno + 2, (char *) &cr);
1044 supply_register (regno + 3, (char *) &lr);
1045 supply_register (regno + 4, (char *) &ctr);
1046 supply_register (regno + 5, (char *) &xer);
1049 /* Record that the special registers contain the specified 32-bit
1053 supply_sprs32 (uint32_t iar, uint32_t msr, uint32_t cr,
1054 uint32_t lr, uint32_t ctr, uint32_t xer)
1056 int regno = FIRST_UISA_SP_REGNUM;
1057 supply_register (regno, (char *) &iar);
1058 supply_register (regno + 1, (char *) &msr);
1059 supply_register (regno + 2, (char *) &cr);
1060 supply_register (regno + 3, (char *) &lr);
1061 supply_register (regno + 4, (char *) &ctr);
1062 supply_register (regno + 5, (char *) &xer);
1065 /* Fetch all registers from pthread PDTID, which doesn't have a kernel
1068 There's no way to query a single register from a non-kernel
1069 pthread, so there's no need for a single-register version of this
1073 fetch_regs_lib (pthdb_pthread_t pdtid)
1076 pthdb_context_t ctx;
1078 if (debug_aix_thread)
1079 fprintf_unfiltered (gdb_stdlog, "fetch_regs_lib %lx\n", (long)pdtid);
1080 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1081 if (status != PTHDB_SUCCESS)
1082 error ("aix-thread: fetch_registers: pthdb_pthread_context returned %s",
1083 pd_status2str (status));
1085 /* General-purpose registers. */
1088 supply_gprs64 (ctx.gpr);
1090 for (i = 0; i < 32; i++)
1091 supply_reg32 (i, ctx.gpr[i]);
1093 /* Floating-point registers. */
1095 supply_fprs (ctx.fpr);
1097 /* Special registers. */
1100 supply_sprs64 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer);
1102 supply_sprs32 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer);
1105 /* Fetch register REGNO if != -1 or all registers otherwise from
1108 AIX provides a way to query all of a kernel thread's GPRs, FPRs, or
1109 SPRs, but there's no way to query individual registers within those
1110 groups. Therefore, if REGNO != -1, this function fetches an entire
1113 Unfortunately, kernel thread register queries often fail with
1114 EPERM, indicating that the thread is in kernel space. This breaks
1115 backtraces of threads other than the current one. To make that
1116 breakage obvious without throwing an error to top level (which is
1117 bad e.g. during "info threads" output), zero registers that can't
1121 fetch_regs_kern (int regno, pthdb_tid_t tid)
1123 uint64_t gprs64[32];
1124 uint32_t gprs32[32];
1126 struct ptxsprs sprs64;
1127 struct ptsprs sprs32;
1130 if (debug_aix_thread)
1131 fprintf_unfiltered (gdb_stdlog,
1132 "fetch_regs_kern tid=%lx regno=%d arch64=%d\n",
1133 (long)tid, regno, arch64);
1135 /* General-purpose registers. */
1136 if (regno == -1 || regno < FP0_REGNUM)
1140 if (!ptrace64aix (PTT_READ_GPRS, tid,
1141 (unsigned long) gprs64, 0, NULL))
1142 memset (gprs64, 0, sizeof (gprs64));
1143 supply_gprs64 (gprs64);
1147 if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
1148 memset (gprs32, 0, sizeof (gprs32));
1149 for (i = 0; i < 32; i++)
1150 supply_reg32 (i, gprs32[i]);
1154 /* Floating-point registers. */
1156 if (regno == -1 || (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM))
1158 if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
1159 memset (fprs, 0, sizeof (fprs));
1163 /* Special-purpose registers. */
1166 (regno > FPLAST_REGNUM && regno <= LAST_UISA_SP_REGNUM))
1170 if (!ptrace64aix (PTT_READ_SPRS, tid,
1171 (unsigned long) &sprs64, 0, NULL))
1172 memset (&sprs64, 0, sizeof (sprs64));
1173 supply_sprs64 (sprs64.pt_iar, sprs64.pt_msr, sprs64.pt_cr,
1174 sprs64.pt_lr, sprs64.pt_ctr, sprs64.pt_xer);
1178 if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
1179 memset (&sprs32, 0, sizeof (sprs32));
1180 supply_sprs32 (sprs32.pt_iar, sprs32.pt_msr, sprs32.pt_cr,
1181 sprs32.pt_lr, sprs32.pt_ctr, sprs32.pt_xer);
1183 if (REGISTER_RAW_SIZE (LAST_UISA_SP_REGNUM))
1184 supply_register (LAST_UISA_SP_REGNUM, (char *) &sprs32.pt_mq);
1189 /* Fetch register REGNO if != -1 or all registers otherwise in the
1190 thread/process specified by inferior_ptid. */
1193 ops_fetch_registers (int regno)
1195 struct thread_info *thread;
1198 if (!PD_TID (inferior_ptid))
1199 base_ops.to_fetch_registers (regno);
1202 thread = find_thread_pid (inferior_ptid);
1203 tid = thread->private->tid;
1205 if (tid == PTHDB_INVALID_TID)
1206 fetch_regs_lib (thread->private->pdtid);
1208 fetch_regs_kern (regno, tid);
1212 /* Store the special registers into the specified 64-bit and 32-bit
1216 fill_sprs64 (uint64_t *iar, uint64_t *msr, uint32_t *cr,
1217 uint64_t *lr, uint64_t *ctr, uint32_t *xer)
1219 int regno = FIRST_UISA_SP_REGNUM;
1220 *iar = read_register (regno);
1221 *msr = read_register (regno + 1);
1222 *cr = read_register (regno + 2);
1223 *lr = read_register (regno + 3);
1224 *ctr = read_register (regno + 4);
1225 *xer = read_register (regno + 5);
1228 /* Store all registers into pthread PDTID, which doesn't have a kernel
1231 It's possible to store a single register into a non-kernel pthread,
1232 but I doubt it's worth the effort. */
1235 store_regs_lib (pthdb_pthread_t pdtid)
1238 pthdb_context_t ctx;
1240 if (debug_aix_thread)
1241 fprintf_unfiltered (gdb_stdlog,
1242 "store_regs_lib %lx\n", (long)pdtid);
1244 /* Retrieve the thread's current context for its non-register
1246 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1247 if (status != PTHDB_SUCCESS)
1248 error ("aix-thread: store_registers: pthdb_pthread_context returned %s",
1249 pd_status2str (status));
1251 /* General-purpose registers. */
1253 for (i = 0; i < 32; i++)
1254 ctx.gpr[i] = read_register (i);
1256 /* Floating-point registers. */
1258 for (i = 0; i < 32; i++)
1259 ctx.fpr[i] = *(double *) ®isters[REGISTER_BYTE (FP0_REGNUM + i)];
1261 /* Special registers. */
1263 fill_sprs64 (&ctx.iar, &ctx.msr, &ctx.cr, &ctx.lr, &ctx.ctr, &ctx.xer);
1265 status = pthdb_pthread_setcontext (pd_session, pdtid, &ctx);
1266 if (status != PTHDB_SUCCESS)
1267 error ("aix-thread: store_registers: pthdb_pthread_setcontext returned %s",
1268 pd_status2str (status));
1271 /* Store register REGNO if != -1 or all registers otherwise into
1274 AIX provides a way to set all of a kernel thread's GPRs, FPRs, or
1275 SPRs, but there's no way to set individual registers within those
1276 groups. Therefore, if REGNO != -1, this function stores an entire
1280 store_regs_kern (int regno, pthdb_tid_t tid)
1282 struct ptxsprs sprs64;
1283 struct ptsprs sprs32;
1286 if (debug_aix_thread)
1287 fprintf_unfiltered (gdb_stdlog, "store_regs_kern tid=%lx regno=%d\n",
1290 /* General-purpose registers. */
1291 if (regno == -1 || regno < FP0_REGNUM)
1293 regp = ®isters[REGISTER_BYTE (0)];
1295 ptrace64aix (PTT_WRITE_GPRS, tid, (unsigned long) regp, 0, NULL);
1297 ptrace32 (PTT_WRITE_GPRS, tid, (int *) regp, 0, NULL);
1300 /* Floating-point registers. */
1302 if (regno == -1 || (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM))
1304 regp = ®isters[REGISTER_BYTE (FP0_REGNUM)];
1305 ptrace32 (PTT_WRITE_FPRS, tid, (int *) regp, 0, NULL);
1308 /* Special-purpose registers. */
1311 (regno > FPLAST_REGNUM && regno <= LAST_UISA_SP_REGNUM))
1315 ptrace64aix (PTT_READ_SPRS, tid,
1316 (unsigned long) &sprs64, 0, NULL);
1317 fill_sprs64 (&sprs64.pt_iar, &sprs64.pt_msr, &sprs64.pt_cr,
1318 &sprs64.pt_lr, &sprs64.pt_ctr, &sprs64.pt_xer);
1319 ptrace64aix (PTT_WRITE_SPRS, tid,
1320 (unsigned long) &sprs64, 0, NULL);
1324 ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL);
1326 regno = FIRST_UISA_SP_REGNUM;
1327 sprs32.pt_iar = read_register (regno);
1328 sprs32.pt_msr = read_register (regno + 1);
1329 sprs32.pt_cr = read_register (regno + 2);
1330 sprs32.pt_lr = read_register (regno + 3);
1331 sprs32.pt_ctr = read_register (regno + 4);
1332 sprs32.pt_xer = read_register (regno + 5);
1334 if (REGISTER_RAW_SIZE (LAST_UISA_SP_REGNUM))
1335 sprs32.pt_mq = read_register (LAST_UISA_SP_REGNUM);
1337 ptrace32 (PTT_WRITE_SPRS, tid, (int *) &sprs32, 0, NULL);
1342 /* Store gdb's current view of the register set into the
1343 thread/process specified by inferior_ptid. */
1346 ops_store_registers (int regno)
1348 struct thread_info *thread;
1351 if (!PD_TID (inferior_ptid))
1352 base_ops.to_store_registers (regno);
1355 thread = find_thread_pid (inferior_ptid);
1356 tid = thread->private->tid;
1358 if (tid == PTHDB_INVALID_TID)
1359 store_regs_lib (thread->private->pdtid);
1361 store_regs_kern (regno, tid);
1365 /* Prepare to modify the registers array. */
1368 ops_prepare_to_store (void)
1370 if (!PD_TID (inferior_ptid))
1371 base_ops.to_prepare_to_store ();
1373 read_register_bytes (0, NULL, REGISTER_BYTES);
1376 /* Transfer LEN bytes of memory from GDB address MYADDR to target
1377 address MEMADDR if WRITE and vice versa otherwise. */
1380 ops_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
1381 struct mem_attrib *attrib,
1382 struct target_ops *target)
1385 struct cleanup *cleanup = save_inferior_ptid ();
1387 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
1388 n = base_ops.to_xfer_memory (memaddr, myaddr, len,
1389 write, attrib, &base_ops);
1390 do_cleanups (cleanup);
1395 /* Kill and forget about the inferior process. */
1400 struct cleanup *cleanup = save_inferior_ptid ();
1402 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
1403 base_ops.to_kill ();
1404 do_cleanups (cleanup);
1407 /* Clean up after the inferior exits. */
1410 ops_mourn_inferior (void)
1413 base_ops.to_mourn_inferior ();
1416 /* Return whether thread PID is still valid. */
1419 ops_thread_alive (ptid_t ptid)
1422 return base_ops.to_thread_alive (ptid);
1424 /* We update the thread list every time the child stops, so all
1425 valid threads should be in the thread list. */
1426 return in_thread_list (ptid);
1429 /* Return a printable representation of composite PID for use in
1430 "info threads" output. */
1433 ops_pid_to_str (ptid_t ptid)
1435 static char *ret = NULL;
1438 return base_ops.to_pid_to_str (ptid);
1440 /* Free previous return value; a new one will be allocated by
1444 xasprintf (&ret, "Thread %ld", ptid_get_tid (ptid));
1448 /* Return a printable representation of extra information about
1449 THREAD, for use in "info threads" output. */
1452 ops_extra_thread_info (struct thread_info *thread)
1454 struct ui_file *buf;
1456 pthdb_pthread_t pdtid;
1458 pthdb_state_t state;
1459 pthdb_suspendstate_t suspendstate;
1460 pthdb_detachstate_t detachstate;
1463 static char *ret = NULL;
1465 if (!PD_TID (thread->ptid))
1468 buf = mem_fileopen ();
1470 pdtid = thread->private->pdtid;
1471 tid = thread->private->tid;
1473 if (tid != PTHDB_INVALID_TID)
1474 fprintf_unfiltered (buf, "tid %d", tid);
1476 status = pthdb_pthread_state (pd_session, pdtid, &state);
1477 if (status != PTHDB_SUCCESS)
1479 fprintf_unfiltered (buf, ", %s", state2str (state));
1481 status = pthdb_pthread_suspendstate (pd_session, pdtid,
1483 if (status == PTHDB_SUCCESS && suspendstate == PSS_SUSPENDED)
1484 fprintf_unfiltered (buf, ", suspended");
1486 status = pthdb_pthread_detachstate (pd_session, pdtid,
1488 if (status == PTHDB_SUCCESS && detachstate == PDS_DETACHED)
1489 fprintf_unfiltered (buf, ", detached");
1491 pthdb_pthread_cancelpend (pd_session, pdtid, &cancelpend);
1492 if (status == PTHDB_SUCCESS && cancelpend)
1493 fprintf_unfiltered (buf, ", cancel pending");
1495 ui_file_write (buf, "", 1);
1497 xfree (ret); /* Free old buffer. */
1499 ret = ui_file_xstrdup (buf, &length);
1500 ui_file_delete (buf);
1505 /* Initialize target ops. */
1510 ops.to_shortname = "aix-threads";
1511 ops.to_longname = "AIX pthread support";
1512 ops.to_doc = "AIX pthread support";
1514 ops.to_attach = ops_attach;
1515 ops.to_detach = ops_detach;
1516 ops.to_resume = ops_resume;
1517 ops.to_wait = ops_wait;
1518 ops.to_fetch_registers = ops_fetch_registers;
1519 ops.to_store_registers = ops_store_registers;
1520 ops.to_prepare_to_store = ops_prepare_to_store;
1521 ops.to_xfer_memory = ops_xfer_memory;
1522 /* No need for ops.to_create_inferior, because we activate thread
1523 debugging when the inferior reaches pd_brk_addr. */
1524 ops.to_kill = ops_kill;
1525 ops.to_mourn_inferior = ops_mourn_inferior;
1526 ops.to_thread_alive = ops_thread_alive;
1527 ops.to_pid_to_str = ops_pid_to_str;
1528 ops.to_extra_thread_info = ops_extra_thread_info;
1529 ops.to_stratum = thread_stratum;
1530 ops.to_magic = OPS_MAGIC;
1533 /* Module startup initialization function, automagically called by
1537 _initialize_aix_thread (void)
1542 /* Notice when object files get loaded and unloaded. */
1543 target_new_objfile_chain = target_new_objfile_hook;
1544 target_new_objfile_hook = new_objfile;
1546 add_show_from_set (add_set_cmd ("aix-thread", no_class, var_zinteger,
1547 (char *) &debug_aix_thread,
1548 "Set debugging of AIX thread module.\n"
1549 "Enables printf debugging output.\n",