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