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