1 /* Low level interface for debugging HPUX/DCE threads for GDB, the GNU
4 Copyright 1996, 1998, 1999, 2000, 2001, 2004 Free Software
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 /* This module implements a sort of half target that sits between the
25 machine-independent parts of GDB and the ptrace interface (infptrace.c) to
26 provide access to the HPUX user-mode thread implementation.
28 HPUX threads are true user-mode threads, which are invoked via the cma_*
29 and pthread_* (DCE and Posix respectivly) interfaces. These are mostly
30 implemented in user-space, with all thread context kept in various
31 structures that live in the user's heap. For the most part, the kernel has
32 no knowlege of these threads.
38 #define _CMA_NOWRAPPERS_
40 #include <cma_tcb_defs.h>
41 #include <cma_deb_core.h>
42 #include "gdbthread.h"
50 #include "hppa-tdep.h"
52 extern int child_suppress_run
;
54 extern void _initialize_hpux_thread (void);
62 static int hpux_thread_active
= 0;
64 static ptid_t main_ptid
; /* Real process ID */
66 static CORE_ADDR P_cma__g_known_threads
;
67 static CORE_ADDR P_cma__g_current_thread
;
69 static void hpux_thread_resume (ptid_t ptid
, int step
,
70 enum target_signal signo
);
72 static void init_hpux_thread_ops (void);
74 static struct target_ops hpux_thread_ops
;
76 static ptid_t
find_active_thread (void);
78 static int cached_thread
;
79 static cma__t_int_tcb cached_tcb
;
82 find_active_thread (void)
84 static cma__t_int_tcb tcb
;
87 read_memory ((CORE_ADDR
) P_cma__g_current_thread
,
91 read_memory (tcb_ptr
, (char *) &tcb
, sizeof tcb
);
93 return (ptid_build (PIDGET (main_ptid
), 0,
94 cma_thread_get_unique (&tcb
.prolog
.client_thread
)));
97 static cma__t_int_tcb
*find_tcb (ptid_t ptid
);
99 static cma__t_int_tcb
*
100 find_tcb (ptid_t ptid
)
102 cma__t_known_object queue_header
;
103 cma__t_queue
*queue_ptr
;
104 int thread
= ptid_get_tid (ptid
);
106 if (thread
== cached_thread
)
109 read_memory ((CORE_ADDR
) P_cma__g_known_threads
,
110 (char *) &queue_header
,
111 sizeof queue_header
);
113 for (queue_ptr
= queue_header
.queue
.flink
;
114 queue_ptr
!= (cma__t_queue
*) P_cma__g_known_threads
;
115 queue_ptr
= cached_tcb
.threads
.flink
)
117 cma__t_int_tcb
*tcb_ptr
;
119 tcb_ptr
= cma__base (queue_ptr
, threads
, cma__t_int_tcb
);
121 read_memory ((CORE_ADDR
) tcb_ptr
, (char *) &cached_tcb
, sizeof cached_tcb
);
123 if (cached_tcb
.header
.type
== cma__c_obj_tcb
)
124 if (cma_thread_get_unique (&cached_tcb
.prolog
.client_thread
) == thread
)
126 cached_thread
= thread
;
131 error (_("Can't find TCB %d"), thread
);
135 /* Most target vector functions from here on actually just pass through to
136 inftarg.c, as they don't need to do anything specific for threads. */
139 hpux_thread_open (char *arg
, int from_tty
)
141 deprecated_child_ops
.to_open (arg
, from_tty
);
144 /* Attach to process PID, then initialize for debugging it
145 and wait for the trace-trap that results from attaching. */
148 hpux_thread_attach (char *args
, int from_tty
)
150 deprecated_child_ops
.to_attach (args
, from_tty
);
152 /* XXX - might want to iterate over all the threads and register them. */
155 /* Take a program previously attached to and detaches it.
156 The program resumes execution and will no longer stop
157 on signals, etc. We'd better not have left any breakpoints
158 in the program or it'll die when it hits one. For this
159 to work, it may be necessary for the process to have been
160 previously attached. It *might* work if the program was
161 started via the normal ptrace (PTRACE_TRACEME). */
164 hpux_thread_detach (char *args
, int from_tty
)
166 deprecated_child_ops
.to_detach (args
, from_tty
);
169 /* Resume execution of process PID. If STEP is nozero, then
170 just single step it. If SIGNAL is nonzero, restart it with that
171 signal activated. We may have to convert pid from a thread-id to an LWP id
175 hpux_thread_resume (ptid_t ptid
, int step
, enum target_signal signo
)
177 struct cleanup
*old_chain
;
179 old_chain
= save_inferior_ptid ();
182 inferior_ptid
= main_ptid
;
187 pid
= thread_to_lwp (pid
, -2);
188 if (pid
== -2) /* Inactive thread */
189 error (_("This version of Solaris can't start inactive threads."));
193 deprecated_child_ops
.to_resume (ptid
, step
, signo
);
197 do_cleanups (old_chain
);
200 /* Wait for any threads to stop. We may have to convert PID from a thread id
201 to a LWP id, and vice versa on the way out. */
204 hpux_thread_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
207 struct cleanup
*old_chain
;
209 old_chain
= save_inferior_ptid ();
211 inferior_ptid
= main_ptid
;
213 if (!ptid_equal (ptid
, minus_one_ptid
))
216 rtnval
= deprecated_child_ops
.to_wait (ptid
, ourstatus
);
218 rtnval
= find_active_thread ();
220 do_cleanups (old_chain
);
225 static char regmap
[] =
227 -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
228 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
229 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
231 /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
232 -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
234 /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
235 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
237 /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
238 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
240 -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
241 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
242 -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
243 -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
244 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
245 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
246 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
247 -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
248 -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
252 hpux_thread_fetch_registers (int regno
)
254 cma__t_int_tcb tcb
, *tcb_ptr
;
255 struct cleanup
*old_chain
;
257 int first_regno
, last_regno
;
259 tcb_ptr
= find_tcb (inferior_ptid
);
261 old_chain
= save_inferior_ptid ();
263 inferior_ptid
= main_ptid
;
265 if (tcb_ptr
->state
== cma__c_state_running
)
267 deprecated_child_ops
.to_fetch_registers (regno
);
269 do_cleanups (old_chain
);
277 last_regno
= NUM_REGS
- 1;
285 for (regno
= first_regno
; regno
<= last_regno
; regno
++)
287 if (regmap
[regno
] == -1)
288 deprecated_child_ops
.to_fetch_registers (regno
);
291 unsigned char buf
[MAX_REGISTER_SIZE
];
294 sp
= (CORE_ADDR
) tcb_ptr
->static_ctx
.sp
- 160;
296 if (regno
== HPPA_FLAGS_REGNUM
)
297 /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
298 memset (buf
, '\000', register_size (current_gdbarch
, regno
));
299 else if (regno
== HPPA_SP_REGNUM
)
300 store_unsigned_integer (buf
, sizeof sp
, sp
);
301 else if (regno
== HPPA_PCOQ_HEAD_REGNUM
)
302 read_memory (sp
- 20, buf
, register_size (current_gdbarch
, regno
));
304 read_memory (sp
+ regmap
[regno
], buf
, register_size (current_gdbarch
, regno
));
306 regcache_raw_supply (current_regcache
, regno
, buf
);
310 do_cleanups (old_chain
);
314 hpux_thread_store_registers (int regno
)
316 cma__t_int_tcb tcb
, *tcb_ptr
;
317 struct cleanup
*old_chain
;
319 int first_regno
, last_regno
;
321 tcb_ptr
= find_tcb (inferior_ptid
);
323 old_chain
= save_inferior_ptid ();
325 inferior_ptid
= main_ptid
;
327 if (tcb_ptr
->state
== cma__c_state_running
)
329 deprecated_child_ops
.to_store_registers (regno
);
331 do_cleanups (old_chain
);
339 last_regno
= NUM_REGS
- 1;
347 for (regno
= first_regno
; regno
<= last_regno
; regno
++)
349 if (regmap
[regno
] == -1)
350 deprecated_child_ops
.to_store_registers (regno
);
353 unsigned char buf
[MAX_REGISTER_SIZE
];
356 sp
= (CORE_ADDR
) tcb_ptr
->static_ctx
.sp
- 160;
358 if (regno
== HPPA_FLAGS_REGNUM
)
359 deprecated_child_ops
.to_store_registers (regno
); /* Let lower layer handle this... */
360 else if (regno
== HPPA_SP_REGNUM
)
362 regcache_raw_read (current_regcache
, regno
, buf
);
363 write_memory ((CORE_ADDR
) &tcb_ptr
->static_ctx
.sp
, buf
,
364 register_size (current_gdbarch
, regno
));
365 tcb_ptr
->static_ctx
.sp
366 = (cma__t_hppa_regs
*) ((CORE_ADDR
) buf
+ 160);
368 else if (regno
== HPPA_PCOQ_HEAD_REGNUM
)
370 regcache_raw_read (current_regcache
, regno
, buf
);
371 write_memory (sp
- 20, buf
,
372 register_size (current_gdbarch
, regno
));
376 regcache_raw_read (current_regcache
, regno
, buf
);
377 write_memory (sp
+ regmap
[regno
], buf
,
378 register_size (current_gdbarch
, regno
));
383 do_cleanups (old_chain
);
386 /* Get ready to modify the registers array. On machines which store
387 individual registers, this doesn't need to do anything. On machines
388 which store all the registers in one fell swoop, this makes sure
389 that registers contains all the registers from the program being
393 hpux_thread_prepare_to_store (void)
395 deprecated_child_ops
.to_prepare_to_store ();
399 hpux_thread_xfer_memory (CORE_ADDR memaddr
, char *myaddr
, int len
,
400 int dowrite
, struct mem_attrib
*attribs
,
401 struct target_ops
*target
)
404 struct cleanup
*old_chain
;
406 old_chain
= save_inferior_ptid ();
408 inferior_ptid
= main_ptid
;
411 deprecated_child_ops
.deprecated_xfer_memory (memaddr
, myaddr
, len
, dowrite
, attribs
, target
);
413 do_cleanups (old_chain
);
418 /* Print status information about what we're accessing. */
421 hpux_thread_files_info (struct target_ops
*ignore
)
423 deprecated_child_ops
.to_files_info (ignore
);
427 hpux_thread_kill_inferior (void)
429 deprecated_child_ops
.to_kill ();
433 hpux_thread_notice_signals (ptid_t ptid
)
435 deprecated_child_ops
.to_notice_signals (ptid
);
438 /* Fork an inferior process, and start debugging it with /proc. */
441 hpux_thread_create_inferior (char *exec_file
, char *allargs
, char **env
,
444 deprecated_child_ops
.to_create_inferior (exec_file
, allargs
, env
, from_tty
);
446 if (hpux_thread_active
)
448 main_ptid
= inferior_ptid
;
450 push_target (&hpux_thread_ops
);
452 inferior_ptid
= find_active_thread ();
454 add_thread (inferior_ptid
);
458 /* This routine is called whenever a new symbol table is read in, or when all
459 symbol tables are removed. libthread_db can only be initialized when it
460 finds the right variables in libthread.so. Since it's a shared library,
461 those variables don't show up until the library gets mapped and the symbol
464 /* This new_objfile event is now managed by a chained function pointer.
465 * It is the callee's responsability to call the next client on the chain.
468 /* Saved pointer to previous owner of the new_objfile event. */
469 static void (*target_new_objfile_chain
) (struct objfile
*);
472 hpux_thread_new_objfile (struct objfile
*objfile
)
474 struct minimal_symbol
*ms
;
478 hpux_thread_active
= 0;
482 ms
= lookup_minimal_symbol ("cma__g_known_threads", NULL
, objfile
);
487 P_cma__g_known_threads
= SYMBOL_VALUE_ADDRESS (ms
);
489 ms
= lookup_minimal_symbol ("cma__g_current_thread", NULL
, objfile
);
494 P_cma__g_current_thread
= SYMBOL_VALUE_ADDRESS (ms
);
496 hpux_thread_active
= 1;
498 /* Call predecessor on chain, if any. */
499 if (target_new_objfile_chain
)
500 target_new_objfile_chain (objfile
);
503 /* Clean up after the inferior dies. */
506 hpux_thread_mourn_inferior (void)
508 deprecated_child_ops
.to_mourn_inferior ();
511 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
514 hpux_thread_can_run (void)
516 return child_suppress_run
;
520 hpux_thread_alive (ptid_t ptid
)
526 hpux_thread_stop (void)
528 deprecated_child_ops
.to_stop ();
531 /* Convert a pid to printable form. */
534 hpux_pid_to_str (ptid_t ptid
)
536 static char buf
[100];
537 int pid
= PIDGET (ptid
);
539 sprintf (buf
, "Thread %ld", ptid_get_tid (ptid
));
545 init_hpux_thread_ops (void)
547 hpux_thread_ops
.to_shortname
= "hpux-threads";
548 hpux_thread_ops
.to_longname
= "HPUX threads and pthread.";
549 hpux_thread_ops
.to_doc
= "HPUX threads and pthread support.";
550 hpux_thread_ops
.to_open
= hpux_thread_open
;
551 hpux_thread_ops
.to_attach
= hpux_thread_attach
;
552 hpux_thread_ops
.to_detach
= hpux_thread_detach
;
553 hpux_thread_ops
.to_resume
= hpux_thread_resume
;
554 hpux_thread_ops
.to_wait
= hpux_thread_wait
;
555 hpux_thread_ops
.to_fetch_registers
= hpux_thread_fetch_registers
;
556 hpux_thread_ops
.to_store_registers
= hpux_thread_store_registers
;
557 hpux_thread_ops
.to_prepare_to_store
= hpux_thread_prepare_to_store
;
558 hpux_thread_ops
.deprecated_xfer_memory
= hpux_thread_xfer_memory
;
559 hpux_thread_ops
.to_files_info
= hpux_thread_files_info
;
560 hpux_thread_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
561 hpux_thread_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
562 hpux_thread_ops
.to_terminal_init
= terminal_init_inferior
;
563 hpux_thread_ops
.to_terminal_inferior
= terminal_inferior
;
564 hpux_thread_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
565 hpux_thread_ops
.to_terminal_save_ours
= terminal_save_ours
;
566 hpux_thread_ops
.to_terminal_ours
= terminal_ours
;
567 hpux_thread_ops
.to_terminal_info
= child_terminal_info
;
568 hpux_thread_ops
.to_kill
= hpux_thread_kill_inferior
;
569 hpux_thread_ops
.to_create_inferior
= hpux_thread_create_inferior
;
570 hpux_thread_ops
.to_mourn_inferior
= hpux_thread_mourn_inferior
;
571 hpux_thread_ops
.to_can_run
= hpux_thread_can_run
;
572 hpux_thread_ops
.to_notice_signals
= hpux_thread_notice_signals
;
573 hpux_thread_ops
.to_thread_alive
= hpux_thread_alive
;
574 hpux_thread_ops
.to_stop
= hpux_thread_stop
;
575 hpux_thread_ops
.to_stratum
= process_stratum
;
576 hpux_thread_ops
.to_has_all_memory
= 1;
577 hpux_thread_ops
.to_has_memory
= 1;
578 hpux_thread_ops
.to_has_stack
= 1;
579 hpux_thread_ops
.to_has_registers
= 1;
580 hpux_thread_ops
.to_has_execution
= 1;
581 hpux_thread_ops
.to_magic
= OPS_MAGIC
;
585 _initialize_hpux_thread (void)
587 init_hpux_thread_ops ();
588 add_target (&hpux_thread_ops
);
590 child_suppress_run
= 1;
591 /* Hook into new_objfile notification. */
592 target_new_objfile_chain
= deprecated_target_new_objfile_hook
;
593 deprecated_target_new_objfile_hook
= hpux_thread_new_objfile
;