1 /* Low level interface for debugging HPUX/DCE threads for GDB, the GNU debugger.
2 Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* This module implements a sort of half target that sits between the
22 machine-independent parts of GDB and the ptrace interface (infptrace.c) to
23 provide access to the HPUX user-mode thread implementation.
25 HPUX threads are true user-mode threads, which are invoked via the cma_*
26 and pthread_* (DCE and Posix respectivly) interfaces. These are mostly
27 implemented in user-space, with all thread context kept in various
28 structures that live in the user's heap. For the most part, the kernel has
29 no knowlege of these threads.
35 #define _CMA_NOWRAPPERS_
37 #include <cma_tcb_defs.h>
38 #include <cma_deb_core.h>
39 #include "gdbthread.h"
47 extern int child_suppress_run;
48 extern struct target_ops child_ops; /* target vector for inftarg.c */
50 extern void _initialize_hpux_thread (void);
58 static int hpux_thread_active = 0;
60 static ptid_t main_ptid; /* Real process ID */
62 static CORE_ADDR P_cma__g_known_threads;
63 static CORE_ADDR P_cma__g_current_thread;
65 static void hpux_thread_resume (ptid_t ptid, int step,
66 enum target_signal signo);
68 static void init_hpux_thread_ops (void);
70 static struct target_ops hpux_thread_ops;
72 static ptid_t find_active_thread (void);
74 static int cached_thread;
75 static cma__t_int_tcb cached_tcb;
78 find_active_thread (void)
80 static cma__t_int_tcb tcb;
83 read_memory ((CORE_ADDR) P_cma__g_current_thread,
87 read_memory (tcb_ptr, (char *) &tcb, sizeof tcb);
89 return (ptid_build (PIDGET (main_ptid), 0,
90 cma_thread_get_unique (&tcb.prolog.client_thread)));
93 static cma__t_int_tcb *find_tcb (ptid_t ptid);
95 static cma__t_int_tcb *
96 find_tcb (ptid_t ptid)
98 cma__t_known_object queue_header;
99 cma__t_queue *queue_ptr;
100 int thread = ptid_get_tid (ptid);
102 if (thread == cached_thread)
105 read_memory ((CORE_ADDR) P_cma__g_known_threads,
106 (char *) &queue_header,
107 sizeof queue_header);
109 for (queue_ptr = queue_header.queue.flink;
110 queue_ptr != (cma__t_queue *) P_cma__g_known_threads;
111 queue_ptr = cached_tcb.threads.flink)
113 cma__t_int_tcb *tcb_ptr;
115 tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb);
117 read_memory ((CORE_ADDR) tcb_ptr, (char *) &cached_tcb, sizeof cached_tcb);
119 if (cached_tcb.header.type == cma__c_obj_tcb)
120 if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread)
122 cached_thread = thread;
127 error ("Can't find TCB %d", thread);
131 /* Most target vector functions from here on actually just pass through to
132 inftarg.c, as they don't need to do anything specific for threads. */
136 hpux_thread_open (char *arg, int from_tty)
138 child_ops.to_open (arg, from_tty);
141 /* Attach to process PID, then initialize for debugging it
142 and wait for the trace-trap that results from attaching. */
145 hpux_thread_attach (char *args, int from_tty)
147 child_ops.to_attach (args, from_tty);
149 /* XXX - might want to iterate over all the threads and register them. */
152 /* Take a program previously attached to and detaches it.
153 The program resumes execution and will no longer stop
154 on signals, etc. We'd better not have left any breakpoints
155 in the program or it'll die when it hits one. For this
156 to work, it may be necessary for the process to have been
157 previously attached. It *might* work if the program was
158 started via the normal ptrace (PTRACE_TRACEME). */
161 hpux_thread_detach (char *args, int from_tty)
163 child_ops.to_detach (args, from_tty);
166 /* Resume execution of process PID. If STEP is nozero, then
167 just single step it. If SIGNAL is nonzero, restart it with that
168 signal activated. We may have to convert pid from a thread-id to an LWP id
172 hpux_thread_resume (ptid_t ptid, int step, enum target_signal signo)
174 struct cleanup *old_chain;
176 old_chain = save_inferior_ptid ();
179 inferior_ptid = main_ptid;
184 pid = thread_to_lwp (pid, -2);
185 if (pid == -2) /* Inactive thread */
186 error ("This version of Solaris can't start inactive threads.");
190 child_ops.to_resume (ptid, step, signo);
194 do_cleanups (old_chain);
197 /* Wait for any threads to stop. We may have to convert PID from a thread id
198 to a LWP id, and vice versa on the way out. */
201 hpux_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
204 struct cleanup *old_chain;
206 old_chain = save_inferior_ptid ();
208 inferior_ptid = main_ptid;
210 if (!ptid_equal (ptid, minus_one_ptid))
213 rtnval = child_ops.to_wait (ptid, ourstatus);
215 rtnval = find_active_thread ();
217 do_cleanups (old_chain);
222 static char regmap[NUM_REGS] =
224 -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
225 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
226 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
228 /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
229 -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
231 /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
232 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
234 /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
235 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
237 -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
238 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
239 -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
240 -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
241 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
242 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
243 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
244 -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
245 -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
249 hpux_thread_fetch_registers (int regno)
251 cma__t_int_tcb tcb, *tcb_ptr;
252 struct cleanup *old_chain;
254 int first_regno, last_regno;
256 tcb_ptr = find_tcb (inferior_ptid);
258 old_chain = save_inferior_ptid ();
260 inferior_ptid = main_ptid;
262 if (tcb_ptr->state == cma__c_state_running)
264 child_ops.to_fetch_registers (regno);
266 do_cleanups (old_chain);
274 last_regno = NUM_REGS - 1;
282 for (regno = first_regno; regno <= last_regno; regno++)
284 if (regmap[regno] == -1)
285 child_ops.to_fetch_registers (regno);
288 unsigned char buf[MAX_REGISTER_SIZE];
291 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
293 if (regno == FLAGS_REGNUM)
294 /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
295 memset (buf, '\000', REGISTER_RAW_SIZE (regno));
296 else if (regno == SP_REGNUM)
297 store_address (buf, sizeof sp, sp);
298 else if (regno == PC_REGNUM)
299 read_memory (sp - 20, buf, REGISTER_RAW_SIZE (regno));
301 read_memory (sp + regmap[regno], buf, REGISTER_RAW_SIZE (regno));
303 supply_register (regno, buf);
307 do_cleanups (old_chain);
311 hpux_thread_store_registers (int regno)
313 cma__t_int_tcb tcb, *tcb_ptr;
314 struct cleanup *old_chain;
316 int first_regno, last_regno;
318 tcb_ptr = find_tcb (inferior_ptid);
320 old_chain = save_inferior_ptid ();
322 inferior_ptid = main_ptid;
324 if (tcb_ptr->state == cma__c_state_running)
326 child_ops.to_store_registers (regno);
328 do_cleanups (old_chain);
336 last_regno = NUM_REGS - 1;
344 for (regno = first_regno; regno <= last_regno; regno++)
346 if (regmap[regno] == -1)
347 child_ops.to_store_registers (regno);
350 unsigned char buf[MAX_REGISTER_SIZE];
353 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
355 if (regno == FLAGS_REGNUM)
356 child_ops.to_store_registers (regno); /* Let lower layer handle this... */
357 else if (regno == SP_REGNUM)
359 write_memory ((CORE_ADDR) & tcb_ptr->static_ctx.sp,
360 &deprecated_registers[REGISTER_BYTE (regno)],
361 REGISTER_RAW_SIZE (regno));
362 tcb_ptr->static_ctx.sp = (cma__t_hppa_regs *)
363 (extract_address (&deprecated_registers[REGISTER_BYTE (regno)],
364 REGISTER_RAW_SIZE (regno)) + 160);
366 else if (regno == PC_REGNUM)
367 write_memory (sp - 20,
368 &deprecated_registers[REGISTER_BYTE (regno)],
369 REGISTER_RAW_SIZE (regno));
371 write_memory (sp + regmap[regno],
372 &deprecated_registers[REGISTER_BYTE (regno)],
373 REGISTER_RAW_SIZE (regno));
377 do_cleanups (old_chain);
380 /* Get ready to modify the registers array. On machines which store
381 individual registers, this doesn't need to do anything. On machines
382 which store all the registers in one fell swoop, this makes sure
383 that registers contains all the registers from the program being
387 hpux_thread_prepare_to_store (void)
389 child_ops.to_prepare_to_store ();
393 hpux_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
394 int dowrite, struct mem_attrib *attribs,
395 struct target_ops *target)
398 struct cleanup *old_chain;
400 old_chain = save_inferior_ptid ();
402 inferior_ptid = main_ptid;
405 child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, attribs, target);
407 do_cleanups (old_chain);
412 /* Print status information about what we're accessing. */
415 hpux_thread_files_info (struct target_ops *ignore)
417 child_ops.to_files_info (ignore);
421 hpux_thread_kill_inferior (void)
423 child_ops.to_kill ();
427 hpux_thread_notice_signals (ptid_t ptid)
429 child_ops.to_notice_signals (ptid);
432 /* Fork an inferior process, and start debugging it with /proc. */
435 hpux_thread_create_inferior (char *exec_file, char *allargs, char **env)
437 child_ops.to_create_inferior (exec_file, allargs, env);
439 if (hpux_thread_active)
441 main_ptid = inferior_ptid;
443 push_target (&hpux_thread_ops);
445 inferior_ptid = find_active_thread ();
447 add_thread (inferior_ptid);
451 /* This routine is called whenever a new symbol table is read in, or when all
452 symbol tables are removed. libthread_db can only be initialized when it
453 finds the right variables in libthread.so. Since it's a shared library,
454 those variables don't show up until the library gets mapped and the symbol
457 /* This new_objfile event is now managed by a chained function pointer.
458 * It is the callee's responsability to call the next client on the chain.
461 /* Saved pointer to previous owner of the new_objfile event. */
462 static void (*target_new_objfile_chain) (struct objfile *);
465 hpux_thread_new_objfile (struct objfile *objfile)
467 struct minimal_symbol *ms;
471 hpux_thread_active = 0;
475 ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile);
480 P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms);
482 ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile);
487 P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms);
489 hpux_thread_active = 1;
491 /* Call predecessor on chain, if any. */
492 if (target_new_objfile_chain)
493 target_new_objfile_chain (objfile);
496 /* Clean up after the inferior dies. */
499 hpux_thread_mourn_inferior (void)
501 child_ops.to_mourn_inferior ();
504 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
507 hpux_thread_can_run (void)
509 return child_suppress_run;
513 hpux_thread_alive (ptid_t ptid)
519 hpux_thread_stop (void)
521 child_ops.to_stop ();
524 /* Convert a pid to printable form. */
527 hpux_pid_to_str (ptid_t ptid)
529 static char buf[100];
530 int pid = PIDGET (ptid);
532 sprintf (buf, "Thread %ld", ptid_get_tid (ptid));
538 init_hpux_thread_ops (void)
540 hpux_thread_ops.to_shortname = "hpux-threads";
541 hpux_thread_ops.to_longname = "HPUX threads and pthread.";
542 hpux_thread_ops.to_doc = "HPUX threads and pthread support.";
543 hpux_thread_ops.to_open = hpux_thread_open;
544 hpux_thread_ops.to_attach = hpux_thread_attach;
545 hpux_thread_ops.to_detach = hpux_thread_detach;
546 hpux_thread_ops.to_resume = hpux_thread_resume;
547 hpux_thread_ops.to_wait = hpux_thread_wait;
548 hpux_thread_ops.to_fetch_registers = hpux_thread_fetch_registers;
549 hpux_thread_ops.to_store_registers = hpux_thread_store_registers;
550 hpux_thread_ops.to_prepare_to_store = hpux_thread_prepare_to_store;
551 hpux_thread_ops.to_xfer_memory = hpux_thread_xfer_memory;
552 hpux_thread_ops.to_files_info = hpux_thread_files_info;
553 hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
554 hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
555 hpux_thread_ops.to_terminal_init = terminal_init_inferior;
556 hpux_thread_ops.to_terminal_inferior = terminal_inferior;
557 hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
558 hpux_thread_ops.to_terminal_save_ours = terminal_save_ours;
559 hpux_thread_ops.to_terminal_ours = terminal_ours;
560 hpux_thread_ops.to_terminal_info = child_terminal_info;
561 hpux_thread_ops.to_kill = hpux_thread_kill_inferior;
562 hpux_thread_ops.to_create_inferior = hpux_thread_create_inferior;
563 hpux_thread_ops.to_mourn_inferior = hpux_thread_mourn_inferior;
564 hpux_thread_ops.to_can_run = hpux_thread_can_run;
565 hpux_thread_ops.to_notice_signals = hpux_thread_notice_signals;
566 hpux_thread_ops.to_thread_alive = hpux_thread_alive;
567 hpux_thread_ops.to_stop = hpux_thread_stop;
568 hpux_thread_ops.to_stratum = process_stratum;
569 hpux_thread_ops.to_has_all_memory = 1;
570 hpux_thread_ops.to_has_memory = 1;
571 hpux_thread_ops.to_has_stack = 1;
572 hpux_thread_ops.to_has_registers = 1;
573 hpux_thread_ops.to_has_execution = 1;
574 hpux_thread_ops.to_magic = OPS_MAGIC;
578 _initialize_hpux_thread (void)
580 init_hpux_thread_ops ();
581 add_target (&hpux_thread_ops);
583 child_suppress_run = 1;
584 /* Hook into new_objfile notification. */
585 target_new_objfile_chain = target_new_objfile_hook;
586 target_new_objfile_hook = hpux_thread_new_objfile;