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