* aix-thread.c (ptrace_check): Eliminate goto.
[deliverable/binutils-gdb.git] / gdb / aix-thread.c
CommitLineData
c11d79f2
KB
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"
8e2c28d4 49#include "gdbcmd.h"
c11d79f2
KB
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. */
8e2c28d4 67static int debug_aix_thread;
c11d79f2
KB
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
113struct 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
120struct 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
128static 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
134static struct target_ops base_ops;
135
136/* Address of the function that libpthread will call when libpthdebug is
137 ready to be initialized. */
138
139static CORE_ADDR pd_brk_addr;
140
141/* Whether the current application is debuggable by pthdb. */
142
143static int pd_able = 0;
144
145/* Whether a threaded application is being debugged. */
146
147static int pd_active = 0;
148
149/* Whether the current architecture is 64-bit. Only valid when pd_able is
150 true. */
151
152static int arch64;
153
154/* Saved pointer to previous owner of target_new_objfile_hook. */
155
156static void (*target_new_objfile_chain)(struct objfile *);
157
158/* Forward declarations for pthdb callbacks. */
159
160static int pdc_symbol_addrs (pthdb_user_t, pthdb_symbol_t *, int);
161static int pdc_read_data (pthdb_user_t, void *, pthdb_addr_t, size_t);
162static int pdc_write_data (pthdb_user_t, void *, pthdb_addr_t, size_t);
163static int pdc_read_regs (pthdb_user_t user, pthdb_tid_t tid,
164 unsigned long long flags, pthdb_context_t *context);
165static int pdc_write_regs (pthdb_user_t user, pthdb_tid_t tid,
166 unsigned long long flags, pthdb_context_t *context);
167static int pdc_alloc (pthdb_user_t, size_t, void **);
168static int pdc_realloc (pthdb_user_t, void *, size_t, void **);
169static int pdc_dealloc (pthdb_user_t, void *);
170
171/* pthdb callbacks. */
172
173static 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
187static pthdb_session_t pd_session;
188
c11d79f2
KB
189/* Return a printable representation of pthdebug function return STATUS. */
190
191static char *
192pd_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
235static int
236ptrace_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)
42cc437f
KB
252 {
253 if (debug_aix_thread)
254 fprintf_unfiltered (gdb_stdlog, "ptrace (%d, %d) = %d (errno = %d)",
255 req, id, ret, errno);
256 return ret == -1 ? 0 : 1;
257 }
c11d79f2
KB
258 break;
259 }
260 error ("aix-thread: ptrace (%d, %d) returned %d (errno = %d %s)",
261 req, id, ret, errno, strerror (errno));
42cc437f 262 return 0; /* not reached. */
c11d79f2
KB
263}
264
265/* Call ptracex(REQ, ID, ADDR, DATA, BUF). Return success. */
266
267static int
268ptrace64aix (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
276static int
277ptrace32 (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
285static void
286pid_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
298static int
299pdc_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
8e2c28d4
KB
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);
c11d79f2
KB
309
310 for (i = 0; i < count; i++)
311 {
312 name = symbols[i].name;
8e2c28d4
KB
313 if (debug_aix_thread)
314 fprintf_unfiltered (gdb_stdlog, " symbols[%d].name = \"%s\"", i, name);
c11d79f2
KB
315
316 if (!*name)
317 symbols[i].addr = 0;
318 else
319 {
320 if (!(ms = lookup_minimal_symbol (name, NULL, NULL)))
321 {
8e2c28d4
KB
322 if (debug_aix_thread)
323 fprintf_unfiltered (gdb_stdlog, " returning PDC_FAILURE");
c11d79f2
KB
324 return PDC_FAILURE;
325 }
326 symbols[i].addr = SYMBOL_VALUE_ADDRESS (ms);
327 }
8e2c28d4
KB
328 if (debug_aix_thread)
329 fprintf_unfiltered (gdb_stdlog, " symbols[%d].addr = 0x%llx",
330 i, symbols[i].addr);
c11d79f2 331 }
8e2c28d4
KB
332 if (debug_aix_thread)
333 fprintf_unfiltered (gdb_stdlog, " returning PDC_SUCCESS");
c11d79f2
KB
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. */
342static int
343pdc_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
8e2c28d4
KB
359 if (debug_aix_thread)
360 fprintf_unfiltered (gdb_stdlog, "pdc_read_regs tid=%d flags=%llx\n",
361 (int)tid, flags);
c11d79f2
KB
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. */
410static int
411pdc_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
8e2c28d4
KB
422 if (debug_aix_thread)
423 fprintf_unfiltered (gdb_stdlog, "pdc_write_regs tid=%d flags=%llx\n",
424 (int)tid, flags);
c11d79f2
KB
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
458static int
459pdc_read_data (pthdb_user_t user, void *buf, pthdb_addr_t addr, size_t len)
460{
461 int status, ret;
462
8e2c28d4
KB
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);
c11d79f2
KB
467
468 status = target_read_memory (addr, buf, len);
469 ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
470
8e2c28d4
KB
471 if (debug_aix_thread)
472 fprintf_unfiltered (gdb_stdlog, " status=%d, returning %s", status,
473 pd_status2str (ret));
c11d79f2
KB
474 return ret;
475}
476
477/* pthdb callback: write LEN bytes from BUF to process ADDR. */
478
479static int
480pdc_write_data (pthdb_user_t user, void *buf, pthdb_addr_t addr, size_t len)
481{
482 int status, ret;
483
8e2c28d4
KB
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);
c11d79f2
KB
488
489 status = target_write_memory (addr, buf, len);
490 ret = status == 0 ? PDC_SUCCESS : PDC_FAILURE;
491
8e2c28d4
KB
492 if (debug_aix_thread)
493 fprintf_unfiltered (gdb_stdlog, " status=%d, returning %s", status,
494 pd_status2str (ret));
c11d79f2
KB
495 return ret;
496}
497
498/* pthdb callback: allocate a LEN-byte buffer and store a pointer to it in
499 BUFP. */
500
501static int
502pdc_alloc (pthdb_user_t user, size_t len, void **bufp)
503{
8e2c28d4
KB
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);
c11d79f2 508 *bufp = xmalloc (len);
8e2c28d4
KB
509 if (debug_aix_thread)
510 fprintf_unfiltered (gdb_stdlog, " malloc returned 0x%lx", (long) *bufp);
c11d79f2
KB
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
520static int
521pdc_realloc (pthdb_user_t user, void *buf, size_t len, void **bufp)
522{
8e2c28d4
KB
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);
c11d79f2 527 *bufp = realloc (buf, len);
8e2c28d4
KB
528 if (debug_aix_thread)
529 fprintf_unfiltered (gdb_stdlog, " realloc returned 0x%lx", (long) *bufp);
c11d79f2
KB
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
536static int
537pdc_dealloc (pthdb_user_t user, void *buf)
538{
8e2c28d4
KB
539 if (debug_aix_thread)
540 fprintf_unfiltered (gdb_stdlog, "pdc_free (user = %ld, buf = 0x%lx)", user,
541 (long) buf);
c11d79f2
KB
542 xfree (buf);
543 return PDC_SUCCESS;
544}
545
546/* Return a printable representation of pthread STATE. */
547
548static char *
549state2str (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
564static int
565pcmp (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
574static int
575giter_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
583static int
584giter_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 */
592static int
593ptid_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
615static int
616gcmp (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
636static void
637sync_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;
c11d79f2
KB
646
647 /* Accumulate an array of libpthdebug threads sorted by pthread id. */
648
649 pcount = 0;
650 psize = 1;
651 pbuf = (struct pd_thread *) xmalloc (psize * sizeof *pbuf);
652
653 for (cmd = PTHDB_LIST_FIRST;; cmd = PTHDB_LIST_NEXT)
654 {
655 status = pthdb_pthread (pd_session, &pdtid, cmd);
656 if (status != PTHDB_SUCCESS || pdtid == PTHDB_INVALID_PTHREAD)
657 break;
658
659 status = pthdb_pthread_ptid (pd_session, pdtid, &pthid);
660 if (status != PTHDB_SUCCESS || pthid == PTHDB_INVALID_PTID)
661 continue;
662
663 if (pcount == psize)
664 {
665 psize *= 2;
666 pbuf = (struct pd_thread *) xrealloc (pbuf, psize * sizeof *pbuf);
667 }
668 pbuf[pcount].pdtid = pdtid;
669 pbuf[pcount].pthid = pthid;
670 pcount++;
671 }
672
673 for (pi = 0; pi < pcount; pi++)
674 {
675 status = pthdb_pthread_tid (pd_session, pbuf[pi].pdtid, &tid);
676 if (status != PTHDB_SUCCESS)
677 tid = PTHDB_INVALID_TID;
678 pbuf[pi].tid = tid;
679 }
680
681 qsort (pbuf, pcount, sizeof *pbuf, pcmp);
682
683 /* Accumulate an array of GDB threads sorted by pid. */
684
685 gcount = 0;
686 iterate_over_threads (giter_count, &gcount);
687 g = gbuf = (struct thread_info **) xmalloc (gcount * sizeof *gbuf);
688 iterate_over_threads (giter_accum, &g);
689 qsort (gbuf, gcount, sizeof *gbuf, gcmp);
690
691 /* Apply differences between the two arrays to GDB's thread list. */
692
693 infpid = PIDGET (inferior_ptid);
694 for (pi = gi = 0; pi < pcount || gi < gcount;)
695 {
c11d79f2 696 if (pi == pcount)
c11d79f2 697 {
42cc437f 698 delete_thread (gbuf[gi]->ptid);
c11d79f2
KB
699 gi++;
700 }
42cc437f 701 else if (gi == gcount)
c11d79f2 702 {
42cc437f 703 thread = add_thread (BUILD_THREAD (pbuf[pi].pthid, infpid));
c11d79f2 704 thread->private = xmalloc (sizeof (struct private_thread_info));
42cc437f
KB
705 thread->private->pdtid = pbuf[pi].pdtid;
706 thread->private->tid = pbuf[pi].tid;
c11d79f2
KB
707 pi++;
708 }
42cc437f
KB
709 else
710 {
711 ptid_t pptid, gptid;
712 int cmp_result;
713
714 pptid = BUILD_THREAD (pbuf[pi].pthid, infpid);
715 gptid = gbuf[gi]->ptid;
716 pdtid = pbuf[pi].pdtid;
717 tid = pbuf[pi].tid;
c11d79f2 718
42cc437f
KB
719 cmp_result = ptid_cmp (pptid, gptid);
720
721 if (cmp_result == 0)
722 {
723 gbuf[gi]->private->pdtid = pdtid;
724 gbuf[gi]->private->tid = tid;
725 pi++;
726 gi++;
727 }
728 else if (cmp_result > 0)
729 {
730 delete_thread (gptid);
731 gi++;
732 }
733 else
734 {
735 thread = add_thread (pptid);
736 thread->private = xmalloc (sizeof (struct private_thread_info));
737 thread->private->pdtid = pdtid;
738 thread->private->tid = tid;
739 pi++;
740 }
741 }
c11d79f2
KB
742 }
743
744 xfree (pbuf);
745 xfree (gbuf);
746}
747
748/* iterate_over_threads() callback for locating a thread whose kernel thread
749 just received a trap signal. */
750
751static int
752iter_trap (struct thread_info *thread, void *unused)
753{
754 struct thrdsinfo64 thrinf;
755 pthdb_tid_t tid;
756
757 /* getthrds(3) isn't prototyped in any AIX 4.3.3 #include file. */
758 extern int getthrds (pid_t, struct thrdsinfo64 *, int, pthdb_tid_t *, int);
759
760 tid = thread->private->tid;
761 if (tid == PTHDB_INVALID_TID)
762 return 0;
763
764 if (getthrds (PIDGET (inferior_ptid), &thrinf, sizeof (thrinf), &tid, 1) != 1)
765 return 0;
766
767 return thrinf.ti_cursig == SIGTRAP;
768}
769
770/* Synchronize libpthdebug's state with the inferior and with GDB, generate a
771 composite process/thread <pid> for the current thread, set inferior_ptid to
772 <pid> if SET_INFPID, and return <pid>. */
773
774static ptid_t
775pd_update (int set_infpid)
776{
777 int status;
778 ptid_t ptid;
779 struct thread_info *thread;
780
781 if (!pd_active)
782 return inferior_ptid;
783
784 status = pthdb_session_update (pd_session);
785 if (status != PTHDB_SUCCESS)
786 return inferior_ptid;
787
788 sync_threadlists ();
789
790 /* Define "current thread" as one that just received a trap signal. */
791
792 thread = iterate_over_threads (iter_trap, NULL);
793 if (!thread)
794 ptid = inferior_ptid;
795 else
796 {
797 ptid = thread->ptid;
798 if (set_infpid)
799 inferior_ptid = ptid;
800 }
801 return ptid;
802}
803
804/* Try to start debugging threads in the current process. If successful and
805 SET_INFPID, set inferior_ptid to reflect the current thread. */
806
807static ptid_t
808pd_activate (int set_infpid)
809{
810 int status;
811
812 status = pthdb_session_init (PD_USER, arch64 ? PEM_64BIT : PEM_32BIT,
813 PTHDB_FLAG_REGS, &pd_callbacks, &pd_session);
814 if (status != PTHDB_SUCCESS)
815 {
816 return inferior_ptid;
817 }
818 pd_active = 1;
819 return pd_update (set_infpid);
820}
821
822/* Undo the effects of pd_activate(). */
823
824static void
825pd_deactivate (void)
826{
827 if (!pd_active)
828 return;
829 pthdb_session_destroy (pd_session);
830
831 pid_to_prc (&inferior_ptid);
832 pd_active = 0;
833}
834
835/* An object file has just been loaded. Check whether the current application
836 is pthreaded, and if so, prepare for thread debugging. */
837
838static void
839pd_enable (void)
840{
841 int status;
842 char *stub_name;
843 struct minimal_symbol *ms;
844
845 /* Don't initialize twice. */
846 if (pd_able)
847 return;
848
849 /* Check application word size. */
850 arch64 = REGISTER_RAW_SIZE (0) == 8;
851
852 /* Check whether the application is pthreaded. */
853 stub_name = NULL;
854 status = pthdb_session_pthreaded (PD_USER, PTHDB_FLAG_REGS, &pd_callbacks,
855 &stub_name);
856 if ((status != PTHDB_SUCCESS && status != PTHDB_NOT_PTHREADED) || !stub_name)
857 return;
858
859 /* Set a breakpoint on the returned stub function. */
860 if (!(ms = lookup_minimal_symbol (stub_name, NULL, NULL)))
861 return;
862 pd_brk_addr = SYMBOL_VALUE_ADDRESS (ms);
863 if (!create_thread_event_breakpoint (pd_brk_addr))
864 return;
865
866 /* Prepare for thread debugging. */
867 base_ops = current_target;
868 push_target (&ops);
869 pd_able = 1;
870
871 /* If we're debugging a core file or an attached inferior, the pthread
872 library may already have been initialized, so try to activate thread
873 debugging. */
874 pd_activate (1);
875}
876
877/* Undo the effects of pd_enable(). */
878
879static void
880pd_disable (void)
881{
882 if (!pd_able)
883 return;
884 if (pd_active)
885 pd_deactivate ();
886 pd_able = 0;
887 unpush_target (&ops);
888}
889
890/* target_new_objfile_hook callback.
891
892 If OBJFILE is non-null, check whether a threaded application is being
893 debugged, and if so, prepare for thread debugging.
894
895 If OBJFILE is null, stop debugging threads. */
896
897static void
898new_objfile (struct objfile *objfile)
899{
900 if (objfile)
901 pd_enable ();
902 else
903 pd_disable ();
904
905 if (target_new_objfile_chain)
906 target_new_objfile_chain (objfile);
907}
908
909/* Attach to process specified by ARGS. */
910
911static void
912ops_attach (char *args, int from_tty)
913{
914 base_ops.to_attach (args, from_tty);
915 pd_activate (1);
916}
917
918/* Detach from the process attached to by ops_attach(). */
919
920static void
921ops_detach (char *args, int from_tty)
922{
923 pd_deactivate ();
924 base_ops.to_detach (args, from_tty);
925}
926
927/* Tell the inferior process to continue running thread PID if != -1
928 and all threads otherwise. */
929
930static void
931ops_resume (ptid_t ptid, int step, enum target_signal sig)
932{
933 struct thread_info *thread;
934 pthdb_tid_t tid[2];
935
936 if (!PD_TID (ptid))
937 CALL_BASE (base_ops.to_resume (ptid, step, sig));
938 else
939 {
940 thread = find_thread_pid (ptid);
941 if (!thread)
942 error ("aix-thread resume: unknown pthread %ld", TIDGET (ptid));
943
944 tid[0] = thread->private->tid;
945 if (tid[0] == PTHDB_INVALID_TID)
946 error ("aix-thread resume: no tid for pthread %ld", TIDGET (ptid));
947 tid[1] = 0;
948
949 if (arch64)
950 ptrace64aix (PTT_CONTINUE, tid[0], 1, target_signal_to_host (sig), (int *)tid);
951 else
952 ptrace32 (PTT_CONTINUE, tid[0], (int *) 1,
953 target_signal_to_host (sig), (int *)tid);
954 }
955}
956
957/* Wait for thread/process ID if != -1 or for any thread otherwise. If an
958 error occurs, return -1, else return the pid of the stopped thread. */
959
960static ptid_t
961ops_wait (ptid_t ptid, struct target_waitstatus *status)
962{
963 pid_to_prc (&ptid);
964 CALL_BASE (ptid = base_ops.to_wait (ptid, status));
965 if (PIDGET (ptid) == -1)
966 return pid_to_ptid (-1);
967
968 /* Check whether libpthdebug might be ready to be initialized. */
969 if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED &&
970 status->value.sig == TARGET_SIGNAL_TRAP &&
971 read_pc_pid (ptid) - DECR_PC_AFTER_BREAK == pd_brk_addr)
972 return pd_activate (0);
973
974 return pd_update (0);
975}
976
977/* Record that the 64-bit general-purpose registers contain VALS. */
978
979static void
980supply_gprs64 (uint64_t *vals)
981{
982 int regno;
983
984 for (regno = 0; regno < 32; regno++)
985 supply_register (regno, (char *) (vals + regno));
986}
987
988/* Record that 32-bit register REGNO contains VAL. */
989
990static void
991supply_reg32 (int regno, uint32_t val)
992{
993 supply_register (regno, (char *) &val);
994}
995
996/* Record that the floating-point registers contain VALS. */
997
998static void
999supply_fprs (double *vals)
1000{
1001 int regno;
1002
1003 for (regno = 0; regno < 32; regno++)
1004 supply_register (regno + FP0_REGNUM, (char *) (vals + regno));
1005}
1006
1007/* Record that the special registers contain the specified 64-bit and 32-bit
1008 values. */
1009
1010static void
1011supply_sprs64 (uint64_t iar, uint64_t msr, uint32_t cr,
1012 uint64_t lr, uint64_t ctr, uint32_t xer)
1013{
1014 int regno = FIRST_UISA_SP_REGNUM;
1015 supply_register (regno, (char *) &iar);
1016 supply_register (regno + 1, (char *) &msr);
1017 supply_register (regno + 2, (char *) &cr);
1018 supply_register (regno + 3, (char *) &lr);
1019 supply_register (regno + 4, (char *) &ctr);
1020 supply_register (regno + 5, (char *) &xer);
1021}
1022
1023/* Record that the special registers contain the specified 32-bit values. */
1024
1025static void
1026supply_sprs32 (uint32_t iar, uint32_t msr, uint32_t cr,
1027 uint32_t lr, uint32_t ctr, uint32_t xer)
1028{
1029 int regno = FIRST_UISA_SP_REGNUM;
1030 supply_register (regno, (char *) &iar);
1031 supply_register (regno + 1, (char *) &msr);
1032 supply_register (regno + 2, (char *) &cr);
1033 supply_register (regno + 3, (char *) &lr);
1034 supply_register (regno + 4, (char *) &ctr);
1035 supply_register (regno + 5, (char *) &xer);
1036}
1037
1038/* Fetch all registers from pthread PDTID, which doesn't have a kernel
1039 thread.
1040
1041 There's no way to query a single register from a non-kernel pthread,
1042 so there's no need for a single-register version of this function. */
1043
1044static void
1045fetch_regs_lib (pthdb_pthread_t pdtid)
1046{
1047 int status, i;
1048 pthdb_context_t ctx;
1049
8e2c28d4
KB
1050 if (debug_aix_thread)
1051 fprintf_unfiltered (gdb_stdlog, "fetch_regs_lib %lx\n", (long)pdtid);
c11d79f2
KB
1052 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1053 if (status != PTHDB_SUCCESS)
1054 PD_ERROR ("fetch_registers: pthdb_pthread_context", status);
1055
1056 /* General-purpose registers. */
1057
1058 if (arch64)
1059 supply_gprs64 (ctx.gpr);
1060 else
1061 for (i = 0; i < 32; i++)
1062 supply_reg32 (i, ctx.gpr[i]);
1063
1064 /* Floating-point registers. */
1065
1066 supply_fprs (ctx.fpr);
1067
1068 /* Special registers. */
1069
1070 if (arch64)
1071 supply_sprs64 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer);
1072 else
1073 supply_sprs32 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer);
1074}
1075
1076/* Fetch register REGNO if != -1 or all registers otherwise from kernel thread
1077 TID.
1078
1079 AIX provides a way to query all of a kernel thread's GPRs, FPRs, or SPRs,
1080 but there's no way to query individual registers within those groups.
1081 Therefore, if REGNO != -1, this function fetches an entire group.
1082
1083 Unfortunately, kernel thread register queries often fail with EPERM,
1084 indicating that the thread is in kernel space. This breaks backtraces of
1085 threads other than the current one. To make that breakage obvious without
1086 throwing an error to top level (which is bad e.g. during "info threads"
1087 output), zero registers that can't be retrieved. */
1088
1089static void
1090fetch_regs_kern (int regno, pthdb_tid_t tid)
1091{
1092 uint64_t gprs64[32];
1093 uint32_t gprs32[32];
1094 double fprs[32];
1095 struct ptxsprs sprs64;
1096 struct ptsprs sprs32;
1097 int i;
1098
8e2c28d4
KB
1099 if (debug_aix_thread)
1100 fprintf_unfiltered (gdb_stdlog,
1101 "fetch_regs_kern tid=%lx regno=%d arch64=%d\n",
1102 (long)tid, regno, arch64);
c11d79f2
KB
1103
1104 /* General-purpose registers. */
1105 if (regno == -1 || regno < FP0_REGNUM)
1106 {
1107 if (arch64)
1108 {
1109 if (!ptrace64aix (PTT_READ_GPRS, tid, (unsigned long) gprs64, 0, NULL))
1110 memset (gprs64, 0, sizeof (gprs64));
1111 supply_gprs64 (gprs64);
1112 }
1113 else
1114 {
1115 if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
1116 memset (gprs32, 0, sizeof (gprs32));
1117 for (i = 0; i < 32; i++)
1118 supply_reg32 (i, gprs32[i]);
1119 }
1120 }
1121
1122 /* Floating-point registers. */
1123
1124 if (regno == -1 || (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM))
1125 {
1126 if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
1127 memset (fprs, 0, sizeof (fprs));
1128 supply_fprs (fprs);
1129 }
1130
1131 /* Special-purpose registers. */
1132
1133 if (regno == -1 || (regno > FPLAST_REGNUM && regno <= LAST_UISA_SP_REGNUM))
1134 {
1135 if (arch64)
1136 {
1137 if (!ptrace64aix (PTT_READ_SPRS, tid, (unsigned long) &sprs64, 0, NULL))
1138 memset (&sprs64, 0, sizeof (sprs64));
1139 supply_sprs64 (sprs64.pt_iar, sprs64.pt_msr, sprs64.pt_cr,
1140 sprs64.pt_lr, sprs64.pt_ctr, sprs64.pt_xer);
1141 }
1142 else
1143 {
1144 if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
1145 memset (&sprs32, 0, sizeof (sprs32));
1146 supply_sprs32 (sprs32.pt_iar, sprs32.pt_msr, sprs32.pt_cr,
1147 sprs32.pt_lr, sprs32.pt_ctr, sprs32.pt_xer);
1148
1149 if (REGISTER_RAW_SIZE (LAST_UISA_SP_REGNUM))
1150 supply_register (LAST_UISA_SP_REGNUM, (char *) &sprs32.pt_mq);
1151 }
1152 }
1153}
1154
1155/* Fetch register REGNO if != -1 or all registers otherwise in the
1156 thread/process specified by inferior_ptid. */
1157
1158static void
1159ops_fetch_registers (int regno)
1160{
1161 struct thread_info *thread;
1162 pthdb_tid_t tid;
1163
1164 if (!PD_TID (inferior_ptid))
1165 base_ops.to_fetch_registers (regno);
1166 else
1167 {
1168 thread = find_thread_pid (inferior_ptid);
1169 tid = thread->private->tid;
1170
1171 if (tid == PTHDB_INVALID_TID)
1172 fetch_regs_lib (thread->private->pdtid);
1173 else
1174 fetch_regs_kern (regno, tid);
1175 }
1176}
1177
1178/* Store the special registers into the specified 64-bit and 32-bit
1179 locations. */
1180
1181static void
1182fill_sprs64 (uint64_t *iar, uint64_t *msr, uint32_t *cr,
1183 uint64_t *lr, uint64_t *ctr, uint32_t *xer)
1184{
1185 int regno = FIRST_UISA_SP_REGNUM;
1186 *iar = read_register (regno);
1187 *msr = read_register (regno + 1);
1188 *cr = read_register (regno + 2);
1189 *lr = read_register (regno + 3);
1190 *ctr = read_register (regno + 4);
1191 *xer = read_register (regno + 5);
1192}
1193
1194/* Store all registers into pthread PDTID, which doesn't have a kernel
1195 thread.
1196
1197 It's possible to store a single register into a non-kernel pthread, but I
1198 doubt it's worth the effort. */
1199
1200static void
1201store_regs_lib (pthdb_pthread_t pdtid)
1202{
1203 int status, i;
1204 pthdb_context_t ctx;
1205
8e2c28d4
KB
1206 if (debug_aix_thread)
1207 fprintf_unfiltered (gdb_stdlog, "store_regs_lib %lx\n", (long)pdtid);
c11d79f2
KB
1208
1209 /* Retrieve the thread's current context for its non-register values. */
1210 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1211 if (status != PTHDB_SUCCESS)
1212 PD_ERROR ("store_registers: pthdb_pthread_context", status);
1213
1214 /* General-purpose registers. */
1215
1216 for (i = 0; i < 32; i++)
1217 ctx.gpr[i] = read_register (i);
1218
1219 /* Floating-point registers. */
1220
1221 for (i = 0; i < 32; i++)
1222 ctx.fpr[i] = *(double *) &registers[REGISTER_BYTE (FP0_REGNUM + i)];
1223
1224 /* Special registers. */
1225
1226 fill_sprs64 (&ctx.iar, &ctx.msr, &ctx.cr, &ctx.lr, &ctx.ctr, &ctx.xer);
1227
1228 status = pthdb_pthread_setcontext (pd_session, pdtid, &ctx);
1229 if (status != PTHDB_SUCCESS)
1230 PD_ERROR ("store_registers: pthdb_pthread_setcontext", status);
1231}
1232
1233/* Store register REGNO if != -1 or all registers otherwise into kernel
1234 thread TID.
1235
1236 AIX provides a way to set all of a kernel thread's GPRs, FPRs, or SPRs, but
1237 there's no way to set individual registers within those groups. Therefore,
1238 if REGNO != -1, this function stores an entire group. */
1239
1240static void
1241store_regs_kern (int regno, pthdb_tid_t tid)
1242{
1243 struct ptxsprs sprs64;
1244 struct ptsprs sprs32;
1245 char *regp;
1246
8e2c28d4
KB
1247 if (debug_aix_thread)
1248 fprintf_unfiltered (gdb_stdlog, "store_regs_kern tid=%lx regno=%d\n",
1249 (long)tid, regno);
c11d79f2
KB
1250
1251 /* General-purpose registers. */
1252 if (regno == -1 || regno < FP0_REGNUM)
1253 {
1254 regp = &registers[REGISTER_BYTE (0)];
1255 if (arch64)
1256 ptrace64aix (PTT_WRITE_GPRS, tid, (unsigned long) regp, 0, NULL);
1257 else
1258 ptrace32 (PTT_WRITE_GPRS, tid, (int *) regp, 0, NULL);
1259 }
1260
1261 /* Floating-point registers. */
1262
1263 if (regno == -1 || (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM))
1264 {
1265 regp = &registers[REGISTER_BYTE (FP0_REGNUM)];
1266 ptrace32 (PTT_WRITE_FPRS, tid, (int *) regp, 0, NULL);
1267 }
1268
1269 /* Special-purpose registers. */
1270
1271 if (regno == -1 || (regno > FPLAST_REGNUM && regno <= LAST_UISA_SP_REGNUM))
1272 {
1273 if (arch64)
1274 {
1275 ptrace64aix (PTT_READ_SPRS, tid, (unsigned long) &sprs64, 0, NULL);
1276 fill_sprs64 (&sprs64.pt_iar, &sprs64.pt_msr, &sprs64.pt_cr,
1277 &sprs64.pt_lr, &sprs64.pt_ctr, &sprs64.pt_xer);
1278 ptrace64aix (PTT_WRITE_SPRS, tid, (unsigned long) &sprs64, 0, NULL);
1279 }
1280 else
1281 {
1282 ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL);
1283
1284 regno = FIRST_UISA_SP_REGNUM;
1285 sprs32.pt_iar = read_register (regno);
1286 sprs32.pt_msr = read_register (regno + 1);
1287 sprs32.pt_cr = read_register (regno + 2);
1288 sprs32.pt_lr = read_register (regno + 3);
1289 sprs32.pt_ctr = read_register (regno + 4);
1290 sprs32.pt_xer = read_register (regno + 5);
1291
1292 if (REGISTER_RAW_SIZE (LAST_UISA_SP_REGNUM))
1293 sprs32.pt_mq = read_register (LAST_UISA_SP_REGNUM);
1294
1295 ptrace32 (PTT_WRITE_SPRS, tid, (int *) &sprs32, 0, NULL);
1296 }
1297 }
1298}
1299
1300/* Store gdb's current view of the register set into the thread/process
1301 specified by inferior_ptid. */
1302
1303static void
1304ops_store_registers (int regno)
1305{
1306 struct thread_info *thread;
1307 pthdb_tid_t tid;
1308
1309 if (!PD_TID (inferior_ptid))
1310 base_ops.to_store_registers (regno);
1311 else
1312 {
1313 thread = find_thread_pid (inferior_ptid);
1314 tid = thread->private->tid;
1315
1316 if (tid == PTHDB_INVALID_TID)
1317 store_regs_lib (thread->private->pdtid);
1318 else
1319 store_regs_kern (regno, tid);
1320 }
1321}
1322
1323/* Prepare to modify the registers array. */
1324
1325static void
1326ops_prepare_to_store (void)
1327{
1328 if (!PD_TID (inferior_ptid))
1329 base_ops.to_prepare_to_store ();
1330 else
1331 read_register_bytes (0, NULL, REGISTER_BYTES);
1332}
1333
1334/* Transfer LEN bytes of memory from GDB address MYADDR to target address
1335 MEMADDR if WRITE and vice versa otherwise. */
1336
1337static int
1338ops_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
1339 struct mem_attrib *attrib,
1340 struct target_ops *target)
1341{
1342 int n;
1343
1344 CALL_BASE (n = base_ops.to_xfer_memory (memaddr, myaddr, len, write,
1345 attrib, &base_ops));
1346 return n;
1347}
1348
1349/* Kill and forget about the inferior process. */
1350
1351static void
1352ops_kill (void)
1353{
1354 CALL_BASE (base_ops.to_kill ());
1355}
1356
1357/* Clean up after the inferior exits. */
1358
1359static void
1360ops_mourn_inferior (void)
1361{
1362 pd_deactivate ();
1363 base_ops.to_mourn_inferior ();
1364}
1365
1366/* Return whether thread PID is still valid. */
1367
1368static int
1369ops_thread_alive (ptid_t ptid)
1370{
1371 if (!PD_TID (ptid))
1372 return base_ops.to_thread_alive (ptid);
1373
1374 /* We update the thread list every time the child stops, so all valid
1375 threads should be in the thread list. */
1376 return in_thread_list (ptid);
1377}
1378
1379/* Return a printable representation of composite PID for use in "info
1380 threads" output. */
1381
1382static char *
1383ops_pid_to_str (ptid_t ptid)
1384{
1385 static char *ret = NULL;
1386
1387 if (!PD_TID (ptid))
1388 return base_ops.to_pid_to_str (ptid);
1389
1390 /* Free previous return value; a new one will be allocated by
1391 xasprintf(). */
1392 xfree (ret);
1393
1394 xasprintf (&ret, "Thread %ld", ptid_get_tid (ptid));
1395 return ret;
1396}
1397
1398/* Return a printable representation of extra information about THREAD, for
1399 use in "info threads" output. */
1400
1401static char *
1402ops_extra_thread_info (struct thread_info *thread)
1403{
1404 struct ui_file *buf;
1405 int status;
1406 pthdb_pthread_t pdtid;
1407 pthdb_tid_t tid;
1408 pthdb_state_t state;
1409 pthdb_suspendstate_t suspendstate;
1410 pthdb_detachstate_t detachstate;
1411 int cancelpend;
1412 long length;
1413 static char *ret = NULL;
1414
1415 if (!PD_TID (thread->ptid))
1416 return NULL;
1417
1418 buf = mem_fileopen ();
1419
1420 pdtid = thread->private->pdtid;
1421 tid = thread->private->tid;
1422
1423 if (tid != PTHDB_INVALID_TID)
1424 fprintf_unfiltered (buf, "tid %d", tid);
1425
1426 status = pthdb_pthread_state (pd_session, pdtid, &state);
1427 if (status != PTHDB_SUCCESS)
1428 state = PST_NOTSUP;
1429 fprintf_unfiltered (buf, ", %s", state2str (state));
1430
1431 status = pthdb_pthread_suspendstate (pd_session, pdtid, &suspendstate);
1432 if (status == PTHDB_SUCCESS && suspendstate == PSS_SUSPENDED)
1433 fprintf_unfiltered (buf, ", suspended");
1434
1435 status = pthdb_pthread_detachstate (pd_session, pdtid, &detachstate);
1436 if (status == PTHDB_SUCCESS && detachstate == PDS_DETACHED)
1437 fprintf_unfiltered (buf, ", detached");
1438
1439 pthdb_pthread_cancelpend (pd_session, pdtid, &cancelpend);
1440 if (status == PTHDB_SUCCESS && cancelpend)
1441 fprintf_unfiltered (buf, ", cancel pending");
1442
1443 ui_file_write (buf, "", 1);
1444
1445 xfree (ret); /* Free old buffer. */
1446
1447 ret = ui_file_xstrdup (buf, &length);
1448 ui_file_delete (buf);
1449
1450 return ret;
1451}
1452
1453/* Initialize target ops. */
1454
1455static void
1456init_ops (void)
1457{
1458 ops.to_shortname = "aix-threads";
1459 ops.to_longname = "AIX pthread support";
1460 ops.to_doc = "AIX pthread support";
1461
1462 ops.to_attach = ops_attach;
1463 ops.to_detach = ops_detach;
1464 ops.to_resume = ops_resume;
1465 ops.to_wait = ops_wait;
1466 ops.to_fetch_registers = ops_fetch_registers;
1467 ops.to_store_registers = ops_store_registers;
1468 ops.to_prepare_to_store = ops_prepare_to_store;
1469 ops.to_xfer_memory = ops_xfer_memory;
1470 /* No need for ops.to_create_inferior, because we activate thread debugging
1471 when the inferior reaches pd_brk_addr. */
1472 ops.to_kill = ops_kill;
1473 ops.to_mourn_inferior = ops_mourn_inferior;
1474 ops.to_thread_alive = ops_thread_alive;
1475 ops.to_pid_to_str = ops_pid_to_str;
1476 ops.to_extra_thread_info = ops_extra_thread_info;
1477 ops.to_stratum = thread_stratum;
1478 ops.to_magic = OPS_MAGIC;
1479}
1480
1481/* Module startup initialization function, automagically called by
1482 init.c. */
1483
1484void
1485_initialize_aix_thread (void)
1486{
1487 init_ops ();
1488 add_target (&ops);
1489
1490 /* Notice when object files get loaded and unloaded. */
1491 target_new_objfile_chain = target_new_objfile_hook;
1492 target_new_objfile_hook = new_objfile;
8e2c28d4
KB
1493
1494 add_show_from_set (add_set_cmd ("aix-thread", no_class, var_zinteger,
1495 (char *) &debug_aix_thread,
1496 "Set debugging of AIX thread module.\n"
1497 "Enables printf debugging output.\n",
1498 &setdebuglist),
1499 &showdebuglist);
c11d79f2 1500}
This page took 0.096506 seconds and 4 git commands to generate.