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