2004-08-10 Michael Chastain <mec.gnu@mindspring.com>
[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
9ad7bec7
JB
625/* Search through the list of all kernel threads for the thread
626 that has stopped on a SIGTRAP signal, and return its TID.
627 Return 0 if none found. */
628
629static pthdb_tid_t
630get_signaled_thread (void)
631{
632 struct thrdsinfo64 thrinf;
633 pthdb_tid_t ktid = 0;
634 int result = 0;
635
636 /* getthrds(3) isn't prototyped in any AIX 4.3.3 #include file. */
637 extern int getthrds (pid_t, struct thrdsinfo64 *,
638 int, pthdb_tid_t *, int);
639
640 while (1)
641 {
642 if (getthrds (PIDGET (inferior_ptid), &thrinf,
643 sizeof (thrinf), &ktid, 1) != 1)
644 break;
645
646 if (thrinf.ti_cursig == SIGTRAP)
647 return thrinf.ti_tid;
648 }
649
650 /* Didn't find any thread stopped on a SIGTRAP signal. */
651 return 0;
652}
653
c11d79f2
KB
654/* Synchronize GDB's thread list with libpthdebug's.
655
656 There are some benefits of doing this every time the inferior stops:
657
0fe7bf7b
MS
658 - allows users to run thread-specific commands without needing to
659 run "info threads" first
c11d79f2
KB
660
661 - helps pthdb_tid_pthread() work properly (see "libpthdebug
662 peculiarities" at the top of this module)
663
0fe7bf7b
MS
664 - simplifies the demands placed on libpthdebug, which seems to
665 have difficulty with certain call patterns */
c11d79f2
KB
666
667static void
668sync_threadlists (void)
669{
670 int cmd, status, infpid;
671 int pcount, psize, pi, gcount, gi;
672 struct pd_thread *pbuf;
673 struct thread_info **gbuf, **g, *thread;
674 pthdb_pthread_t pdtid;
675 pthread_t pthid;
676 pthdb_tid_t tid;
c11d79f2 677
0fe7bf7b 678 /* Accumulate an array of libpthdebug threads sorted by pthread id. */
c11d79f2
KB
679
680 pcount = 0;
681 psize = 1;
682 pbuf = (struct pd_thread *) xmalloc (psize * sizeof *pbuf);
683
684 for (cmd = PTHDB_LIST_FIRST;; cmd = PTHDB_LIST_NEXT)
685 {
686 status = pthdb_pthread (pd_session, &pdtid, cmd);
687 if (status != PTHDB_SUCCESS || pdtid == PTHDB_INVALID_PTHREAD)
688 break;
689
690 status = pthdb_pthread_ptid (pd_session, pdtid, &pthid);
691 if (status != PTHDB_SUCCESS || pthid == PTHDB_INVALID_PTID)
692 continue;
693
694 if (pcount == psize)
695 {
696 psize *= 2;
0fe7bf7b
MS
697 pbuf = (struct pd_thread *) xrealloc (pbuf,
698 psize * sizeof *pbuf);
c11d79f2
KB
699 }
700 pbuf[pcount].pdtid = pdtid;
701 pbuf[pcount].pthid = pthid;
702 pcount++;
703 }
704
705 for (pi = 0; pi < pcount; pi++)
706 {
707 status = pthdb_pthread_tid (pd_session, pbuf[pi].pdtid, &tid);
708 if (status != PTHDB_SUCCESS)
709 tid = PTHDB_INVALID_TID;
710 pbuf[pi].tid = tid;
711 }
712
713 qsort (pbuf, pcount, sizeof *pbuf, pcmp);
714
0fe7bf7b 715 /* Accumulate an array of GDB threads sorted by pid. */
c11d79f2
KB
716
717 gcount = 0;
718 iterate_over_threads (giter_count, &gcount);
719 g = gbuf = (struct thread_info **) xmalloc (gcount * sizeof *gbuf);
720 iterate_over_threads (giter_accum, &g);
721 qsort (gbuf, gcount, sizeof *gbuf, gcmp);
722
0fe7bf7b 723 /* Apply differences between the two arrays to GDB's thread list. */
c11d79f2
KB
724
725 infpid = PIDGET (inferior_ptid);
726 for (pi = gi = 0; pi < pcount || gi < gcount;)
727 {
c11d79f2 728 if (pi == pcount)
c11d79f2 729 {
42cc437f 730 delete_thread (gbuf[gi]->ptid);
c11d79f2
KB
731 gi++;
732 }
42cc437f 733 else if (gi == gcount)
c11d79f2 734 {
42cc437f 735 thread = add_thread (BUILD_THREAD (pbuf[pi].pthid, infpid));
c11d79f2 736 thread->private = xmalloc (sizeof (struct private_thread_info));
42cc437f
KB
737 thread->private->pdtid = pbuf[pi].pdtid;
738 thread->private->tid = pbuf[pi].tid;
c11d79f2
KB
739 pi++;
740 }
42cc437f
KB
741 else
742 {
743 ptid_t pptid, gptid;
744 int cmp_result;
745
746 pptid = BUILD_THREAD (pbuf[pi].pthid, infpid);
747 gptid = gbuf[gi]->ptid;
748 pdtid = pbuf[pi].pdtid;
749 tid = pbuf[pi].tid;
c11d79f2 750
42cc437f
KB
751 cmp_result = ptid_cmp (pptid, gptid);
752
753 if (cmp_result == 0)
754 {
755 gbuf[gi]->private->pdtid = pdtid;
756 gbuf[gi]->private->tid = tid;
757 pi++;
758 gi++;
759 }
760 else if (cmp_result > 0)
761 {
762 delete_thread (gptid);
763 gi++;
764 }
765 else
766 {
767 thread = add_thread (pptid);
768 thread->private = xmalloc (sizeof (struct private_thread_info));
769 thread->private->pdtid = pdtid;
770 thread->private->tid = tid;
771 pi++;
772 }
773 }
c11d79f2
KB
774 }
775
776 xfree (pbuf);
777 xfree (gbuf);
778}
779
9ad7bec7
JB
780/* Iterate_over_threads() callback for locating a thread, using
781 the TID of its associated kernel thread. */
c11d79f2
KB
782
783static int
9ad7bec7 784iter_tid (struct thread_info *thread, void *tidp)
c11d79f2 785{
9ad7bec7 786 const pthdb_tid_t tid = *(pthdb_tid_t *)tidp;
c11d79f2 787
9ad7bec7 788 return (thread->private->tid == tid);
c11d79f2
KB
789}
790
0fe7bf7b
MS
791/* Synchronize libpthdebug's state with the inferior and with GDB,
792 generate a composite process/thread <pid> for the current thread,
793 set inferior_ptid to <pid> if SET_INFPID, and return <pid>. */
c11d79f2
KB
794
795static ptid_t
796pd_update (int set_infpid)
797{
798 int status;
799 ptid_t ptid;
9ad7bec7
JB
800 pthdb_tid_t tid;
801 struct thread_info *thread = NULL;
c11d79f2
KB
802
803 if (!pd_active)
804 return inferior_ptid;
805
806 status = pthdb_session_update (pd_session);
807 if (status != PTHDB_SUCCESS)
808 return inferior_ptid;
809
810 sync_threadlists ();
811
0fe7bf7b 812 /* Define "current thread" as one that just received a trap signal. */
c11d79f2 813
9ad7bec7
JB
814 tid = get_signaled_thread ();
815 if (tid != 0)
816 thread = iterate_over_threads (iter_tid, &tid);
c11d79f2
KB
817 if (!thread)
818 ptid = inferior_ptid;
819 else
820 {
821 ptid = thread->ptid;
822 if (set_infpid)
823 inferior_ptid = ptid;
824 }
825 return ptid;
826}
827
0fe7bf7b
MS
828/* Try to start debugging threads in the current process.
829 If successful and SET_INFPID, set inferior_ptid to reflect the
830 current thread. */
c11d79f2
KB
831
832static ptid_t
833pd_activate (int set_infpid)
834{
835 int status;
836
837 status = pthdb_session_init (PD_USER, arch64 ? PEM_64BIT : PEM_32BIT,
0fe7bf7b
MS
838 PTHDB_FLAG_REGS, &pd_callbacks,
839 &pd_session);
c11d79f2
KB
840 if (status != PTHDB_SUCCESS)
841 {
842 return inferior_ptid;
843 }
844 pd_active = 1;
845 return pd_update (set_infpid);
846}
847
0fe7bf7b 848/* Undo the effects of pd_activate(). */
c11d79f2
KB
849
850static void
851pd_deactivate (void)
852{
853 if (!pd_active)
854 return;
855 pthdb_session_destroy (pd_session);
856
857 pid_to_prc (&inferior_ptid);
858 pd_active = 0;
859}
860
0fe7bf7b
MS
861/* An object file has just been loaded. Check whether the current
862 application is pthreaded, and if so, prepare for thread debugging. */
c11d79f2
KB
863
864static void
865pd_enable (void)
866{
867 int status;
868 char *stub_name;
869 struct minimal_symbol *ms;
870
0fe7bf7b 871 /* Don't initialize twice. */
c11d79f2
KB
872 if (pd_able)
873 return;
874
0fe7bf7b 875 /* Check application word size. */
3acba339 876 arch64 = register_size (current_gdbarch, 0) == 8;
c11d79f2 877
0fe7bf7b 878 /* Check whether the application is pthreaded. */
c11d79f2 879 stub_name = NULL;
0fe7bf7b
MS
880 status = pthdb_session_pthreaded (PD_USER, PTHDB_FLAG_REGS,
881 &pd_callbacks, &stub_name);
882 if ((status != PTHDB_SUCCESS &&
883 status != PTHDB_NOT_PTHREADED) || !stub_name)
c11d79f2
KB
884 return;
885
0fe7bf7b 886 /* Set a breakpoint on the returned stub function. */
c11d79f2
KB
887 if (!(ms = lookup_minimal_symbol (stub_name, NULL, NULL)))
888 return;
889 pd_brk_addr = SYMBOL_VALUE_ADDRESS (ms);
890 if (!create_thread_event_breakpoint (pd_brk_addr))
891 return;
892
0fe7bf7b 893 /* Prepare for thread debugging. */
206d3d3c
KB
894 base_target = current_target;
895 push_target (&aix_thread_ops);
c11d79f2
KB
896 pd_able = 1;
897
0fe7bf7b
MS
898 /* If we're debugging a core file or an attached inferior, the
899 pthread library may already have been initialized, so try to
900 activate thread debugging. */
c11d79f2
KB
901 pd_activate (1);
902}
903
0fe7bf7b 904/* Undo the effects of pd_enable(). */
c11d79f2
KB
905
906static void
907pd_disable (void)
908{
909 if (!pd_able)
910 return;
911 if (pd_active)
912 pd_deactivate ();
913 pd_able = 0;
206d3d3c 914 unpush_target (&aix_thread_ops);
c11d79f2
KB
915}
916
9a4105ab 917/* deprecated_target_new_objfile_hook callback.
c11d79f2 918
0fe7bf7b
MS
919 If OBJFILE is non-null, check whether a threaded application is
920 being debugged, and if so, prepare for thread debugging.
c11d79f2 921
0fe7bf7b 922 If OBJFILE is null, stop debugging threads. */
c11d79f2
KB
923
924static void
925new_objfile (struct objfile *objfile)
926{
927 if (objfile)
928 pd_enable ();
929 else
930 pd_disable ();
931
932 if (target_new_objfile_chain)
933 target_new_objfile_chain (objfile);
934}
935
0fe7bf7b 936/* Attach to process specified by ARGS. */
c11d79f2
KB
937
938static void
206d3d3c 939aix_thread_attach (char *args, int from_tty)
c11d79f2 940{
206d3d3c 941 base_target.to_attach (args, from_tty);
c11d79f2
KB
942 pd_activate (1);
943}
944
206d3d3c 945/* Detach from the process attached to by aix_thread_attach(). */
c11d79f2
KB
946
947static void
206d3d3c 948aix_thread_detach (char *args, int from_tty)
c11d79f2 949{
6c0c456d 950 pd_disable ();
206d3d3c 951 base_target.to_detach (args, from_tty);
c11d79f2
KB
952}
953
954/* Tell the inferior process to continue running thread PID if != -1
0fe7bf7b 955 and all threads otherwise. */
c11d79f2
KB
956
957static void
206d3d3c 958aix_thread_resume (ptid_t ptid, int step, enum target_signal sig)
c11d79f2
KB
959{
960 struct thread_info *thread;
961 pthdb_tid_t tid[2];
962
963 if (!PD_TID (ptid))
14fa3751
KB
964 {
965 struct cleanup *cleanup = save_inferior_ptid ();
966 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
206d3d3c 967 base_target.to_resume (ptid, step, sig);
14fa3751
KB
968 do_cleanups (cleanup);
969 }
c11d79f2
KB
970 else
971 {
972 thread = find_thread_pid (ptid);
973 if (!thread)
0fe7bf7b
MS
974 error ("aix-thread resume: unknown pthread %ld",
975 TIDGET (ptid));
c11d79f2
KB
976
977 tid[0] = thread->private->tid;
978 if (tid[0] == PTHDB_INVALID_TID)
0fe7bf7b
MS
979 error ("aix-thread resume: no tid for pthread %ld",
980 TIDGET (ptid));
c11d79f2
KB
981 tid[1] = 0;
982
983 if (arch64)
0fe7bf7b 984 ptrace64aix (PTT_CONTINUE, tid[0], 1,
206d3d3c 985 target_signal_to_host (sig), (int *) tid);
c11d79f2
KB
986 else
987 ptrace32 (PTT_CONTINUE, tid[0], (int *) 1,
206d3d3c 988 target_signal_to_host (sig), (int *) tid);
c11d79f2
KB
989 }
990}
991
0fe7bf7b
MS
992/* Wait for thread/process ID if != -1 or for any thread otherwise.
993 If an error occurs, return -1, else return the pid of the stopped
994 thread. */
c11d79f2
KB
995
996static ptid_t
206d3d3c 997aix_thread_wait (ptid_t ptid, struct target_waitstatus *status)
c11d79f2 998{
14fa3751
KB
999 struct cleanup *cleanup = save_inferior_ptid ();
1000
c11d79f2 1001 pid_to_prc (&ptid);
14fa3751
KB
1002
1003 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
206d3d3c 1004 ptid = base_target.to_wait (ptid, status);
14fa3751
KB
1005 do_cleanups (cleanup);
1006
c11d79f2
KB
1007 if (PIDGET (ptid) == -1)
1008 return pid_to_ptid (-1);
1009
0fe7bf7b 1010 /* Check whether libpthdebug might be ready to be initialized. */
c11d79f2
KB
1011 if (!pd_active && status->kind == TARGET_WAITKIND_STOPPED &&
1012 status->value.sig == TARGET_SIGNAL_TRAP &&
1013 read_pc_pid (ptid) - DECR_PC_AFTER_BREAK == pd_brk_addr)
1014 return pd_activate (0);
1015
1016 return pd_update (0);
1017}
1018
0fe7bf7b 1019/* Record that the 64-bit general-purpose registers contain VALS. */
c11d79f2
KB
1020
1021static void
1022supply_gprs64 (uint64_t *vals)
1023{
cdf2c5f5 1024 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c11d79f2
KB
1025 int regno;
1026
063715bf 1027 for (regno = 0; regno < ppc_num_gprs; regno++)
23a6d369
AC
1028 regcache_raw_supply (current_regcache, tdep->ppc_gp0_regnum + regno,
1029 (char *) (vals + regno));
c11d79f2
KB
1030}
1031
0fe7bf7b 1032/* Record that 32-bit register REGNO contains VAL. */
c11d79f2
KB
1033
1034static void
1035supply_reg32 (int regno, uint32_t val)
1036{
23a6d369 1037 regcache_raw_supply (current_regcache, regno, (char *) &val);
c11d79f2
KB
1038}
1039
0fe7bf7b 1040/* Record that the floating-point registers contain VALS. */
c11d79f2
KB
1041
1042static void
1043supply_fprs (double *vals)
1044{
366f009f 1045 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c11d79f2
KB
1046 int regno;
1047
383f0f5b
JB
1048 /* This function should never be called on architectures without
1049 floating-point registers. */
552e377b 1050 gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
383f0f5b 1051
063715bf 1052 for (regno = 0; regno < ppc_num_fprs; regno++)
23a6d369
AC
1053 regcache_raw_supply (current_regcache, regno + tdep->ppc_fp0_regnum,
1054 (char *) (vals + regno));
c11d79f2
KB
1055}
1056
f1a91342
KB
1057/* Predicate to test whether given register number is a "special" register. */
1058static int
1059special_register_p (int regno)
1060{
1061 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1062
1063 return regno == PC_REGNUM
1064 || regno == tdep->ppc_ps_regnum
1065 || regno == tdep->ppc_cr_regnum
1066 || regno == tdep->ppc_lr_regnum
1067 || regno == tdep->ppc_ctr_regnum
1068 || regno == tdep->ppc_xer_regnum
383f0f5b 1069 || (tdep->ppc_fpscr_regnum >= 0 && regno == tdep->ppc_fpscr_regnum)
f1a91342
KB
1070 || (tdep->ppc_mq_regnum >= 0 && regno == tdep->ppc_mq_regnum);
1071}
1072
1073
0fe7bf7b
MS
1074/* Record that the special registers contain the specified 64-bit and
1075 32-bit values. */
c11d79f2
KB
1076
1077static void
1078supply_sprs64 (uint64_t iar, uint64_t msr, uint32_t cr,
0e061eef
KB
1079 uint64_t lr, uint64_t ctr, uint32_t xer,
1080 uint32_t fpscr)
c11d79f2 1081{
f1a91342
KB
1082 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1083
23a6d369
AC
1084 regcache_raw_supply (current_regcache, PC_REGNUM, (char *) &iar);
1085 regcache_raw_supply (current_regcache, tdep->ppc_ps_regnum, (char *) &msr);
1086 regcache_raw_supply (current_regcache, tdep->ppc_cr_regnum, (char *) &cr);
1087 regcache_raw_supply (current_regcache, tdep->ppc_lr_regnum, (char *) &lr);
1088 regcache_raw_supply (current_regcache, tdep->ppc_ctr_regnum, (char *) &ctr);
1089 regcache_raw_supply (current_regcache, tdep->ppc_xer_regnum, (char *) &xer);
383f0f5b 1090 if (tdep->ppc_fpscr_regnum >= 0)
23a6d369
AC
1091 regcache_raw_supply (current_regcache, tdep->ppc_fpscr_regnum,
1092 (char *) &fpscr);
c11d79f2
KB
1093}
1094
0fe7bf7b
MS
1095/* Record that the special registers contain the specified 32-bit
1096 values. */
c11d79f2
KB
1097
1098static void
1099supply_sprs32 (uint32_t iar, uint32_t msr, uint32_t cr,
0e061eef
KB
1100 uint32_t lr, uint32_t ctr, uint32_t xer,
1101 uint32_t fpscr)
c11d79f2 1102{
f1a91342
KB
1103 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1104
23a6d369
AC
1105 regcache_raw_supply (current_regcache, PC_REGNUM, (char *) &iar);
1106 regcache_raw_supply (current_regcache, tdep->ppc_ps_regnum, (char *) &msr);
1107 regcache_raw_supply (current_regcache, tdep->ppc_cr_regnum, (char *) &cr);
1108 regcache_raw_supply (current_regcache, tdep->ppc_lr_regnum, (char *) &lr);
1109 regcache_raw_supply (current_regcache, tdep->ppc_ctr_regnum, (char *) &ctr);
1110 regcache_raw_supply (current_regcache, tdep->ppc_xer_regnum, (char *) &xer);
383f0f5b 1111 if (tdep->ppc_fpscr_regnum >= 0)
23a6d369
AC
1112 regcache_raw_supply (current_regcache, tdep->ppc_fpscr_regnum,
1113 (char *) &fpscr);
c11d79f2
KB
1114}
1115
1116/* Fetch all registers from pthread PDTID, which doesn't have a kernel
1117 thread.
1118
0fe7bf7b
MS
1119 There's no way to query a single register from a non-kernel
1120 pthread, so there's no need for a single-register version of this
1121 function. */
c11d79f2
KB
1122
1123static void
206d3d3c 1124fetch_regs_user_thread (pthdb_pthread_t pdtid)
c11d79f2 1125{
cdf2c5f5 1126 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c11d79f2
KB
1127 int status, i;
1128 pthdb_context_t ctx;
1129
8e2c28d4 1130 if (debug_aix_thread)
206d3d3c
KB
1131 fprintf_unfiltered (gdb_stdlog,
1132 "fetch_regs_user_thread %lx\n", (long) pdtid);
c11d79f2
KB
1133 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1134 if (status != PTHDB_SUCCESS)
14fa3751
KB
1135 error ("aix-thread: fetch_registers: pthdb_pthread_context returned %s",
1136 pd_status2str (status));
c11d79f2 1137
0fe7bf7b 1138 /* General-purpose registers. */
c11d79f2
KB
1139
1140 if (arch64)
1141 supply_gprs64 (ctx.gpr);
1142 else
063715bf 1143 for (i = 0; i < ppc_num_gprs; i++)
cdf2c5f5 1144 supply_reg32 (tdep->ppc_gp0_regnum + i, ctx.gpr[i]);
c11d79f2 1145
0fe7bf7b 1146 /* Floating-point registers. */
c11d79f2 1147
552e377b 1148 if (ppc_floating_point_unit_p (current_gdbarch))
383f0f5b 1149 supply_fprs (ctx.fpr);
c11d79f2 1150
0fe7bf7b 1151 /* Special registers. */
c11d79f2
KB
1152
1153 if (arch64)
0e061eef
KB
1154 supply_sprs64 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer,
1155 ctx.fpscr);
c11d79f2 1156 else
0e061eef
KB
1157 supply_sprs32 (ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr, ctx.xer,
1158 ctx.fpscr);
c11d79f2
KB
1159}
1160
0fe7bf7b
MS
1161/* Fetch register REGNO if != -1 or all registers otherwise from
1162 kernel thread TID.
c11d79f2 1163
0fe7bf7b
MS
1164 AIX provides a way to query all of a kernel thread's GPRs, FPRs, or
1165 SPRs, but there's no way to query individual registers within those
1166 groups. Therefore, if REGNO != -1, this function fetches an entire
1167 group.
c11d79f2 1168
0fe7bf7b
MS
1169 Unfortunately, kernel thread register queries often fail with
1170 EPERM, indicating that the thread is in kernel space. This breaks
1171 backtraces of threads other than the current one. To make that
1172 breakage obvious without throwing an error to top level (which is
1173 bad e.g. during "info threads" output), zero registers that can't
1174 be retrieved. */
c11d79f2
KB
1175
1176static void
206d3d3c 1177fetch_regs_kernel_thread (int regno, pthdb_tid_t tid)
c11d79f2 1178{
366f009f 1179 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
063715bf
JB
1180 uint64_t gprs64[ppc_num_gprs];
1181 uint32_t gprs32[ppc_num_gprs];
1182 double fprs[ppc_num_fprs];
c11d79f2
KB
1183 struct ptxsprs sprs64;
1184 struct ptsprs sprs32;
1185 int i;
1186
8e2c28d4
KB
1187 if (debug_aix_thread)
1188 fprintf_unfiltered (gdb_stdlog,
206d3d3c
KB
1189 "fetch_regs_kernel_thread tid=%lx regno=%d arch64=%d\n",
1190 (long) tid, regno, arch64);
c11d79f2 1191
0fe7bf7b 1192 /* General-purpose registers. */
daf6dc85
JB
1193 if (regno == -1
1194 || (tdep->ppc_gp0_regnum <= regno
1195 && regno < tdep->ppc_gp0_regnum + ppc_num_gprs))
c11d79f2
KB
1196 {
1197 if (arch64)
1198 {
0fe7bf7b
MS
1199 if (!ptrace64aix (PTT_READ_GPRS, tid,
1200 (unsigned long) gprs64, 0, NULL))
c11d79f2
KB
1201 memset (gprs64, 0, sizeof (gprs64));
1202 supply_gprs64 (gprs64);
1203 }
1204 else
1205 {
1206 if (!ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL))
1207 memset (gprs32, 0, sizeof (gprs32));
063715bf 1208 for (i = 0; i < ppc_num_gprs; i++)
cdf2c5f5 1209 supply_reg32 (tdep->ppc_gp0_regnum + i, gprs32[i]);
c11d79f2
KB
1210 }
1211 }
1212
0fe7bf7b 1213 /* Floating-point registers. */
c11d79f2 1214
383f0f5b
JB
1215 if (ppc_floating_point_unit_p (current_gdbarch)
1216 && (regno == -1
1217 || (regno >= tdep->ppc_fp0_regnum
1218 && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
c11d79f2
KB
1219 {
1220 if (!ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL))
1221 memset (fprs, 0, sizeof (fprs));
1222 supply_fprs (fprs);
1223 }
1224
0fe7bf7b 1225 /* Special-purpose registers. */
c11d79f2 1226
f1a91342 1227 if (regno == -1 || special_register_p (regno))
c11d79f2
KB
1228 {
1229 if (arch64)
1230 {
0fe7bf7b
MS
1231 if (!ptrace64aix (PTT_READ_SPRS, tid,
1232 (unsigned long) &sprs64, 0, NULL))
c11d79f2
KB
1233 memset (&sprs64, 0, sizeof (sprs64));
1234 supply_sprs64 (sprs64.pt_iar, sprs64.pt_msr, sprs64.pt_cr,
0e061eef
KB
1235 sprs64.pt_lr, sprs64.pt_ctr, sprs64.pt_xer,
1236 sprs64.pt_fpscr);
c11d79f2
KB
1237 }
1238 else
1239 {
f1a91342
KB
1240 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1241
c11d79f2
KB
1242 if (!ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL))
1243 memset (&sprs32, 0, sizeof (sprs32));
1244 supply_sprs32 (sprs32.pt_iar, sprs32.pt_msr, sprs32.pt_cr,
0e061eef
KB
1245 sprs32.pt_lr, sprs32.pt_ctr, sprs32.pt_xer,
1246 sprs32.pt_fpscr);
c11d79f2 1247
f1a91342 1248 if (tdep->ppc_mq_regnum >= 0)
23a6d369
AC
1249 regcache_raw_supply (current_regcache, tdep->ppc_mq_regnum,
1250 (char *) &sprs32.pt_mq);
c11d79f2
KB
1251 }
1252 }
1253}
1254
1255/* Fetch register REGNO if != -1 or all registers otherwise in the
0fe7bf7b 1256 thread/process specified by inferior_ptid. */
c11d79f2
KB
1257
1258static void
206d3d3c 1259aix_thread_fetch_registers (int regno)
c11d79f2
KB
1260{
1261 struct thread_info *thread;
1262 pthdb_tid_t tid;
1263
1264 if (!PD_TID (inferior_ptid))
206d3d3c 1265 base_target.to_fetch_registers (regno);
c11d79f2
KB
1266 else
1267 {
1268 thread = find_thread_pid (inferior_ptid);
1269 tid = thread->private->tid;
1270
1271 if (tid == PTHDB_INVALID_TID)
206d3d3c 1272 fetch_regs_user_thread (thread->private->pdtid);
c11d79f2 1273 else
206d3d3c 1274 fetch_regs_kernel_thread (regno, tid);
c11d79f2
KB
1275 }
1276}
1277
61c5da0b
KB
1278/* Store the gp registers into an array of uint32_t or uint64_t. */
1279
1280static void
1281fill_gprs64 (uint64_t *vals)
1282{
366f009f 1283 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
61c5da0b
KB
1284 int regno;
1285
daf6dc85
JB
1286 for (regno = 0; regno < ppc_num_gprs; regno++)
1287 if (register_cached (tdep->ppc_gp0_regnum + regno))
822c9732
AC
1288 regcache_raw_collect (current_regcache, tdep->ppc_gp0_regnum + regno,
1289 vals + regno);
61c5da0b
KB
1290}
1291
1292static void
1293fill_gprs32 (uint32_t *vals)
1294{
366f009f 1295 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
61c5da0b
KB
1296 int regno;
1297
daf6dc85
JB
1298 for (regno = 0; regno < ppc_num_gprs; regno++)
1299 if (register_cached (tdep->ppc_gp0_regnum + regno))
822c9732
AC
1300 regcache_raw_collect (current_regcache, tdep->ppc_gp0_regnum + regno,
1301 vals + regno);
61c5da0b
KB
1302}
1303
1304/* Store the floating point registers into a double array. */
1305static void
1306fill_fprs (double *vals)
1307{
366f009f 1308 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
61c5da0b
KB
1309 int regno;
1310
383f0f5b
JB
1311 /* This function should never be called on architectures without
1312 floating-point registers. */
552e377b 1313 gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
383f0f5b 1314
366f009f
JB
1315 for (regno = tdep->ppc_fp0_regnum;
1316 regno < tdep->ppc_fp0_regnum + ppc_num_fprs;
1317 regno++)
cbe92db4 1318 if (register_cached (regno))
822c9732 1319 regcache_raw_collect (current_regcache, regno, vals + regno);
61c5da0b
KB
1320}
1321
c11d79f2 1322/* Store the special registers into the specified 64-bit and 32-bit
0fe7bf7b 1323 locations. */
c11d79f2
KB
1324
1325static void
1326fill_sprs64 (uint64_t *iar, uint64_t *msr, uint32_t *cr,
0e061eef
KB
1327 uint64_t *lr, uint64_t *ctr, uint32_t *xer,
1328 uint32_t *fpscr)
c11d79f2 1329{
f1a91342
KB
1330 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1331
1332 /* Verify that the size of the size of the IAR buffer is the
1333 same as the raw size of the PC (in the register cache). If
1334 they're not, then either GDB has been built incorrectly, or
1335 there's some other kind of internal error. To be really safe,
1336 we should check all of the sizes. */
3acba339 1337 gdb_assert (sizeof (*iar) == register_size (current_gdbarch, PC_REGNUM));
f1a91342
KB
1338
1339 if (register_cached (PC_REGNUM))
822c9732 1340 regcache_raw_collect (current_regcache, PC_REGNUM, iar);
f1a91342 1341 if (register_cached (tdep->ppc_ps_regnum))
822c9732 1342 regcache_raw_collect (current_regcache, tdep->ppc_ps_regnum, msr);
f1a91342 1343 if (register_cached (tdep->ppc_cr_regnum))
822c9732 1344 regcache_raw_collect (current_regcache, tdep->ppc_cr_regnum, cr);
f1a91342 1345 if (register_cached (tdep->ppc_lr_regnum))
822c9732 1346 regcache_raw_collect (current_regcache, tdep->ppc_lr_regnum, lr);
f1a91342 1347 if (register_cached (tdep->ppc_ctr_regnum))
822c9732 1348 regcache_raw_collect (current_regcache, tdep->ppc_ctr_regnum, ctr);
f1a91342 1349 if (register_cached (tdep->ppc_xer_regnum))
822c9732 1350 regcache_raw_collect (current_regcache, tdep->ppc_xer_regnum, xer);
383f0f5b
JB
1351 if (tdep->ppc_fpscr_regnum >= 0
1352 && register_cached (tdep->ppc_fpscr_regnum))
822c9732 1353 regcache_raw_collect (current_regcache, tdep->ppc_fpscr_regnum, fpscr);
61c5da0b
KB
1354}
1355
1356static void
1357fill_sprs32 (unsigned long *iar, unsigned long *msr, unsigned long *cr,
0e061eef
KB
1358 unsigned long *lr, unsigned long *ctr, unsigned long *xer,
1359 unsigned long *fpscr)
61c5da0b 1360{
f1a91342
KB
1361 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1362
1363 /* Verify that the size of the size of the IAR buffer is the
1364 same as the raw size of the PC (in the register cache). If
1365 they're not, then either GDB has been built incorrectly, or
1366 there's some other kind of internal error. To be really safe,
1367 we should check all of the sizes.
61c5da0b 1368
f1a91342 1369 If this assert() fails, the most likely reason is that GDB was
61c5da0b
KB
1370 built incorrectly. In order to make use of many of the header
1371 files in /usr/include/sys, GDB needs to be configured so that
1372 sizeof (long) == 4). */
3acba339 1373 gdb_assert (sizeof (*iar) == register_size (current_gdbarch, PC_REGNUM));
f1a91342
KB
1374
1375 if (register_cached (PC_REGNUM))
822c9732 1376 regcache_raw_collect (current_regcache, PC_REGNUM, iar);
f1a91342 1377 if (register_cached (tdep->ppc_ps_regnum))
822c9732 1378 regcache_raw_collect (current_regcache, tdep->ppc_ps_regnum, msr);
f1a91342 1379 if (register_cached (tdep->ppc_cr_regnum))
822c9732 1380 regcache_raw_collect (current_regcache, tdep->ppc_cr_regnum, cr);
f1a91342 1381 if (register_cached (tdep->ppc_lr_regnum))
822c9732 1382 regcache_raw_collect (current_regcache, tdep->ppc_lr_regnum, lr);
f1a91342 1383 if (register_cached (tdep->ppc_ctr_regnum))
822c9732 1384 regcache_raw_collect (current_regcache, tdep->ppc_ctr_regnum, ctr);
f1a91342 1385 if (register_cached (tdep->ppc_xer_regnum))
822c9732 1386 regcache_raw_collect (current_regcache, tdep->ppc_xer_regnum, xer);
383f0f5b
JB
1387 if (tdep->ppc_fpscr_regnum >= 0
1388 && register_cached (tdep->ppc_fpscr_regnum))
822c9732 1389 regcache_raw_collect (current_regcache, tdep->ppc_fpscr_regnum, fpscr);
c11d79f2
KB
1390}
1391
1392/* Store all registers into pthread PDTID, which doesn't have a kernel
1393 thread.
1394
0fe7bf7b
MS
1395 It's possible to store a single register into a non-kernel pthread,
1396 but I doubt it's worth the effort. */
c11d79f2
KB
1397
1398static void
206d3d3c 1399store_regs_user_thread (pthdb_pthread_t pdtid)
c11d79f2 1400{
cdf2c5f5 1401 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c11d79f2
KB
1402 int status, i;
1403 pthdb_context_t ctx;
61c5da0b
KB
1404 uint32_t int32;
1405 uint64_t int64;
1406 double dbl;
c11d79f2 1407
8e2c28d4 1408 if (debug_aix_thread)
0fe7bf7b 1409 fprintf_unfiltered (gdb_stdlog,
206d3d3c 1410 "store_regs_user_thread %lx\n", (long) pdtid);
c11d79f2 1411
0fe7bf7b
MS
1412 /* Retrieve the thread's current context for its non-register
1413 values. */
c11d79f2
KB
1414 status = pthdb_pthread_context (pd_session, pdtid, &ctx);
1415 if (status != PTHDB_SUCCESS)
14fa3751
KB
1416 error ("aix-thread: store_registers: pthdb_pthread_context returned %s",
1417 pd_status2str (status));
c11d79f2 1418
61c5da0b 1419 /* Collect general-purpose register values from the regcache. */
c11d79f2 1420
063715bf 1421 for (i = 0; i < ppc_num_gprs; i++)
cdf2c5f5 1422 if (register_cached (tdep->ppc_gp0_regnum + i))
cbe92db4
KB
1423 {
1424 if (arch64)
1425 {
822c9732
AC
1426 regcache_raw_collect (current_regcache, tdep->ppc_gp0_regnum + i,
1427 (void *) &int64);
cbe92db4
KB
1428 ctx.gpr[i] = int64;
1429 }
1430 else
1431 {
822c9732
AC
1432 regcache_raw_collect (current_regcache, tdep->ppc_gp0_regnum + i,
1433 (void *) &int32);
cbe92db4
KB
1434 ctx.gpr[i] = int32;
1435 }
1436 }
c11d79f2 1437
61c5da0b 1438 /* Collect floating-point register values from the regcache. */
552e377b 1439 if (ppc_floating_point_unit_p (current_gdbarch))
383f0f5b 1440 fill_fprs (ctx.fpr);
c11d79f2 1441
61c5da0b
KB
1442 /* Special registers (always kept in ctx as 64 bits). */
1443 if (arch64)
1444 {
0e061eef
KB
1445 fill_sprs64 (&ctx.iar, &ctx.msr, &ctx.cr, &ctx.lr, &ctx.ctr, &ctx.xer,
1446 &ctx.fpscr);
61c5da0b
KB
1447 }
1448 else
1449 {
1450 /* Problem: ctx.iar etc. are 64 bits, but raw_registers are 32.
1451 Solution: use 32-bit temp variables. (The assert() in fill_sprs32()
1452 will fail if the size of an unsigned long is incorrect. If this
1453 happens, GDB needs to be reconfigured so that longs are 32-bits.) */
0e061eef
KB
1454 unsigned long tmp_iar, tmp_msr, tmp_cr, tmp_lr, tmp_ctr, tmp_xer,
1455 tmp_fpscr;
61c5da0b 1456
0e061eef
KB
1457 fill_sprs32 (&tmp_iar, &tmp_msr, &tmp_cr, &tmp_lr, &tmp_ctr, &tmp_xer,
1458 &tmp_fpscr);
f1a91342 1459 if (register_cached (PC_REGNUM))
cbe92db4 1460 ctx.iar = tmp_iar;
f1a91342 1461 if (register_cached (tdep->ppc_ps_regnum))
cbe92db4 1462 ctx.msr = tmp_msr;
f1a91342 1463 if (register_cached (tdep->ppc_cr_regnum))
cbe92db4 1464 ctx.cr = tmp_cr;
f1a91342 1465 if (register_cached (tdep->ppc_lr_regnum))
cbe92db4 1466 ctx.lr = tmp_lr;
f1a91342 1467 if (register_cached (tdep->ppc_ctr_regnum))
cbe92db4 1468 ctx.ctr = tmp_ctr;
f1a91342 1469 if (register_cached (tdep->ppc_xer_regnum))
cbe92db4 1470 ctx.xer = tmp_xer;
0e061eef
KB
1471 if (register_cached (tdep->ppc_xer_regnum))
1472 ctx.fpscr = tmp_fpscr;
61c5da0b 1473 }
c11d79f2
KB
1474
1475 status = pthdb_pthread_setcontext (pd_session, pdtid, &ctx);
1476 if (status != PTHDB_SUCCESS)
14fa3751
KB
1477 error ("aix-thread: store_registers: pthdb_pthread_setcontext returned %s",
1478 pd_status2str (status));
c11d79f2
KB
1479}
1480
0fe7bf7b
MS
1481/* Store register REGNO if != -1 or all registers otherwise into
1482 kernel thread TID.
c11d79f2 1483
0fe7bf7b
MS
1484 AIX provides a way to set all of a kernel thread's GPRs, FPRs, or
1485 SPRs, but there's no way to set individual registers within those
1486 groups. Therefore, if REGNO != -1, this function stores an entire
1487 group. */
c11d79f2
KB
1488
1489static void
206d3d3c 1490store_regs_kernel_thread (int regno, pthdb_tid_t tid)
c11d79f2 1491{
366f009f 1492 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
063715bf
JB
1493 uint64_t gprs64[ppc_num_gprs];
1494 uint32_t gprs32[ppc_num_gprs];
1495 double fprs[ppc_num_fprs];
c11d79f2 1496 struct ptxsprs sprs64;
61c5da0b
KB
1497 struct ptsprs sprs32;
1498 int i;
c11d79f2 1499
8e2c28d4 1500 if (debug_aix_thread)
206d3d3c
KB
1501 fprintf_unfiltered (gdb_stdlog,
1502 "store_regs_kernel_thread tid=%lx regno=%d\n",
1503 (long) tid, regno);
c11d79f2 1504
0fe7bf7b 1505 /* General-purpose registers. */
daf6dc85
JB
1506 if (regno == -1
1507 || (tdep->ppc_gp0_regnum <= regno
1508 && regno < tdep->ppc_gp0_regnum + ppc_num_fprs))
c11d79f2 1509 {
c11d79f2 1510 if (arch64)
61c5da0b 1511 {
cbe92db4
KB
1512 /* Pre-fetch: some regs may not be in the cache. */
1513 ptrace64aix (PTT_READ_GPRS, tid, (unsigned long) gprs64, 0, NULL);
61c5da0b
KB
1514 fill_gprs64 (gprs64);
1515 ptrace64aix (PTT_WRITE_GPRS, tid, (unsigned long) gprs64, 0, NULL);
1516 }
c11d79f2 1517 else
61c5da0b 1518 {
cbe92db4
KB
1519 /* Pre-fetch: some regs may not be in the cache. */
1520 ptrace32 (PTT_READ_GPRS, tid, gprs32, 0, NULL);
61c5da0b
KB
1521 fill_gprs32 (gprs32);
1522 ptrace32 (PTT_WRITE_GPRS, tid, gprs32, 0, NULL);
1523 }
c11d79f2
KB
1524 }
1525
0fe7bf7b 1526 /* Floating-point registers. */
c11d79f2 1527
383f0f5b
JB
1528 if (ppc_floating_point_unit_p (current_gdbarch)
1529 && (regno == -1
1530 || (regno >= tdep->ppc_fp0_regnum
1531 && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
c11d79f2 1532 {
cbe92db4
KB
1533 /* Pre-fetch: some regs may not be in the cache. */
1534 ptrace32 (PTT_READ_FPRS, tid, (int *) fprs, 0, NULL);
61c5da0b
KB
1535 fill_fprs (fprs);
1536 ptrace32 (PTT_WRITE_FPRS, tid, (int *) fprs, 0, NULL);
c11d79f2
KB
1537 }
1538
0fe7bf7b 1539 /* Special-purpose registers. */
c11d79f2 1540
f1a91342 1541 if (regno == -1 || special_register_p (regno))
c11d79f2
KB
1542 {
1543 if (arch64)
1544 {
cbe92db4 1545 /* Pre-fetch: some registers won't be in the cache. */
0fe7bf7b
MS
1546 ptrace64aix (PTT_READ_SPRS, tid,
1547 (unsigned long) &sprs64, 0, NULL);
c11d79f2 1548 fill_sprs64 (&sprs64.pt_iar, &sprs64.pt_msr, &sprs64.pt_cr,
0e061eef
KB
1549 &sprs64.pt_lr, &sprs64.pt_ctr, &sprs64.pt_xer,
1550 &sprs64.pt_fpscr);
0fe7bf7b
MS
1551 ptrace64aix (PTT_WRITE_SPRS, tid,
1552 (unsigned long) &sprs64, 0, NULL);
c11d79f2
KB
1553 }
1554 else
1555 {
cbe92db4 1556 /* Pre-fetch: some registers won't be in the cache. */
c11d79f2
KB
1557 ptrace32 (PTT_READ_SPRS, tid, (int *) &sprs32, 0, NULL);
1558
61c5da0b 1559 fill_sprs32 (&sprs32.pt_iar, &sprs32.pt_msr, &sprs32.pt_cr,
0e061eef
KB
1560 &sprs32.pt_lr, &sprs32.pt_ctr, &sprs32.pt_xer,
1561 &sprs32.pt_fpscr);
c11d79f2 1562
f1a91342
KB
1563 if (tdep->ppc_mq_regnum >= 0)
1564 if (register_cached (tdep->ppc_mq_regnum))
822c9732
AC
1565 regcache_raw_collect (current_regcache, tdep->ppc_mq_regnum,
1566 &sprs32.pt_mq);
c11d79f2
KB
1567
1568 ptrace32 (PTT_WRITE_SPRS, tid, (int *) &sprs32, 0, NULL);
1569 }
1570 }
1571}
1572
0fe7bf7b
MS
1573/* Store gdb's current view of the register set into the
1574 thread/process specified by inferior_ptid. */
c11d79f2
KB
1575
1576static void
206d3d3c 1577aix_thread_store_registers (int regno)
c11d79f2
KB
1578{
1579 struct thread_info *thread;
1580 pthdb_tid_t tid;
1581
1582 if (!PD_TID (inferior_ptid))
206d3d3c 1583 base_target.to_store_registers (regno);
c11d79f2
KB
1584 else
1585 {
1586 thread = find_thread_pid (inferior_ptid);
1587 tid = thread->private->tid;
1588
1589 if (tid == PTHDB_INVALID_TID)
206d3d3c 1590 store_regs_user_thread (thread->private->pdtid);
c11d79f2 1591 else
206d3d3c 1592 store_regs_kernel_thread (regno, tid);
c11d79f2
KB
1593 }
1594}
1595
0fe7bf7b
MS
1596/* Transfer LEN bytes of memory from GDB address MYADDR to target
1597 address MEMADDR if WRITE and vice versa otherwise. */
c11d79f2
KB
1598
1599static int
206d3d3c
KB
1600aix_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
1601 struct mem_attrib *attrib,
1602 struct target_ops *target)
c11d79f2
KB
1603{
1604 int n;
14fa3751
KB
1605 struct cleanup *cleanup = save_inferior_ptid ();
1606
1607 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
206d3d3c
KB
1608 n = base_target.to_xfer_memory (memaddr, myaddr, len,
1609 write, attrib, &base_target);
14fa3751 1610 do_cleanups (cleanup);
c11d79f2 1611
c11d79f2
KB
1612 return n;
1613}
1614
0fe7bf7b 1615/* Kill and forget about the inferior process. */
c11d79f2
KB
1616
1617static void
206d3d3c 1618aix_thread_kill (void)
c11d79f2 1619{
14fa3751
KB
1620 struct cleanup *cleanup = save_inferior_ptid ();
1621
1622 inferior_ptid = pid_to_ptid (PIDGET (inferior_ptid));
206d3d3c 1623 base_target.to_kill ();
14fa3751 1624 do_cleanups (cleanup);
c11d79f2
KB
1625}
1626
0fe7bf7b 1627/* Clean up after the inferior exits. */
c11d79f2
KB
1628
1629static void
206d3d3c 1630aix_thread_mourn_inferior (void)
c11d79f2
KB
1631{
1632 pd_deactivate ();
206d3d3c 1633 base_target.to_mourn_inferior ();
c11d79f2
KB
1634}
1635
0fe7bf7b 1636/* Return whether thread PID is still valid. */
c11d79f2
KB
1637
1638static int
206d3d3c 1639aix_thread_thread_alive (ptid_t ptid)
c11d79f2
KB
1640{
1641 if (!PD_TID (ptid))
206d3d3c 1642 return base_target.to_thread_alive (ptid);
c11d79f2 1643
0fe7bf7b
MS
1644 /* We update the thread list every time the child stops, so all
1645 valid threads should be in the thread list. */
c11d79f2
KB
1646 return in_thread_list (ptid);
1647}
1648
0fe7bf7b
MS
1649/* Return a printable representation of composite PID for use in
1650 "info threads" output. */
c11d79f2
KB
1651
1652static char *
206d3d3c 1653aix_thread_pid_to_str (ptid_t ptid)
c11d79f2
KB
1654{
1655 static char *ret = NULL;
1656
1657 if (!PD_TID (ptid))
206d3d3c 1658 return base_target.to_pid_to_str (ptid);
c11d79f2
KB
1659
1660 /* Free previous return value; a new one will be allocated by
b435e160 1661 xstrprintf(). */
c11d79f2
KB
1662 xfree (ret);
1663
b435e160 1664 ret = xstrprintf ("Thread %ld", ptid_get_tid (ptid));
c11d79f2
KB
1665 return ret;
1666}
1667
0fe7bf7b
MS
1668/* Return a printable representation of extra information about
1669 THREAD, for use in "info threads" output. */
c11d79f2
KB
1670
1671static char *
206d3d3c 1672aix_thread_extra_thread_info (struct thread_info *thread)
c11d79f2
KB
1673{
1674 struct ui_file *buf;
1675 int status;
1676 pthdb_pthread_t pdtid;
1677 pthdb_tid_t tid;
1678 pthdb_state_t state;
1679 pthdb_suspendstate_t suspendstate;
1680 pthdb_detachstate_t detachstate;
1681 int cancelpend;
1682 long length;
1683 static char *ret = NULL;
1684
1685 if (!PD_TID (thread->ptid))
1686 return NULL;
1687
1688 buf = mem_fileopen ();
1689
1690 pdtid = thread->private->pdtid;
1691 tid = thread->private->tid;
1692
1693 if (tid != PTHDB_INVALID_TID)
1694 fprintf_unfiltered (buf, "tid %d", tid);
1695
1696 status = pthdb_pthread_state (pd_session, pdtid, &state);
1697 if (status != PTHDB_SUCCESS)
1698 state = PST_NOTSUP;
1699 fprintf_unfiltered (buf, ", %s", state2str (state));
1700
0fe7bf7b
MS
1701 status = pthdb_pthread_suspendstate (pd_session, pdtid,
1702 &suspendstate);
c11d79f2
KB
1703 if (status == PTHDB_SUCCESS && suspendstate == PSS_SUSPENDED)
1704 fprintf_unfiltered (buf, ", suspended");
1705
0fe7bf7b
MS
1706 status = pthdb_pthread_detachstate (pd_session, pdtid,
1707 &detachstate);
c11d79f2
KB
1708 if (status == PTHDB_SUCCESS && detachstate == PDS_DETACHED)
1709 fprintf_unfiltered (buf, ", detached");
1710
1711 pthdb_pthread_cancelpend (pd_session, pdtid, &cancelpend);
1712 if (status == PTHDB_SUCCESS && cancelpend)
1713 fprintf_unfiltered (buf, ", cancel pending");
1714
1715 ui_file_write (buf, "", 1);
1716
1717 xfree (ret); /* Free old buffer. */
1718
1719 ret = ui_file_xstrdup (buf, &length);
1720 ui_file_delete (buf);
1721
1722 return ret;
1723}
1724
206d3d3c 1725/* Initialize target aix_thread_ops. */
c11d79f2
KB
1726
1727static void
206d3d3c 1728init_aix_thread_ops (void)
c11d79f2 1729{
206d3d3c
KB
1730 aix_thread_ops.to_shortname = "aix-threads";
1731 aix_thread_ops.to_longname = "AIX pthread support";
1732 aix_thread_ops.to_doc = "AIX pthread support";
1733
1734 aix_thread_ops.to_attach = aix_thread_attach;
1735 aix_thread_ops.to_detach = aix_thread_detach;
1736 aix_thread_ops.to_resume = aix_thread_resume;
1737 aix_thread_ops.to_wait = aix_thread_wait;
1738 aix_thread_ops.to_fetch_registers = aix_thread_fetch_registers;
1739 aix_thread_ops.to_store_registers = aix_thread_store_registers;
1740 aix_thread_ops.to_xfer_memory = aix_thread_xfer_memory;
1741 /* No need for aix_thread_ops.to_create_inferior, because we activate thread
0fe7bf7b 1742 debugging when the inferior reaches pd_brk_addr. */
206d3d3c
KB
1743 aix_thread_ops.to_kill = aix_thread_kill;
1744 aix_thread_ops.to_mourn_inferior = aix_thread_mourn_inferior;
1745 aix_thread_ops.to_thread_alive = aix_thread_thread_alive;
1746 aix_thread_ops.to_pid_to_str = aix_thread_pid_to_str;
1747 aix_thread_ops.to_extra_thread_info = aix_thread_extra_thread_info;
1748 aix_thread_ops.to_stratum = thread_stratum;
1749 aix_thread_ops.to_magic = OPS_MAGIC;
c11d79f2
KB
1750}
1751
1752/* Module startup initialization function, automagically called by
0fe7bf7b 1753 init.c. */
c11d79f2
KB
1754
1755void
1756_initialize_aix_thread (void)
1757{
206d3d3c
KB
1758 init_aix_thread_ops ();
1759 add_target (&aix_thread_ops);
c11d79f2 1760
0fe7bf7b 1761 /* Notice when object files get loaded and unloaded. */
9a4105ab
AC
1762 target_new_objfile_chain = deprecated_target_new_objfile_hook;
1763 deprecated_target_new_objfile_hook = new_objfile;
8e2c28d4 1764
cb1a6d5f
AC
1765 deprecated_add_show_from_set
1766 (add_set_cmd ("aix-thread", no_class, var_zinteger,
1767 (char *) &debug_aix_thread,
1768 "Set debugging of AIX thread module.\n"
1769 "Enables printf debugging output.\n",
1770 &setdebuglist),
1771 &showdebuglist);
c11d79f2 1772}
This page took 0.256918 seconds and 4 git commands to generate.