* config/tc-arm.c (arm_cpus): Add entry for ARM Cortex-M0.
[binutils-gdb.git] / gdb / hpux-thread.c
blobbdc547d97bbdf033790bfad3378982047932ad7a
1 /* Low level interface for debugging HPUX/DCE threads for GDB, the GNU
2 debugger.
4 Copyright (C) 1996, 1998, 1999, 2000, 2001, 2004, 2007, 2008, 2009
5 Free Software Foundation, Inc.
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 3 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, see <http://www.gnu.org/licenses/>. */
22 /* This module implements a sort of half target that sits between the
23 machine-independent parts of GDB and the ptrace interface (infptrace.c) to
24 provide access to the HPUX user-mode thread implementation.
26 HPUX threads are true user-mode threads, which are invoked via the cma_*
27 and pthread_* (DCE and Posix respectivly) interfaces. These are mostly
28 implemented in user-space, with all thread context kept in various
29 structures that live in the user's heap. For the most part, the kernel has
30 no knowlege of these threads.
34 #include "defs.h"
36 #define _CMA_NOWRAPPERS_
38 #include <cma_tcb_defs.h>
39 #include <cma_deb_core.h>
40 #include "gdbthread.h"
41 #include "target.h"
42 #include "inferior.h"
43 #include "regcache.h"
44 #include <fcntl.h>
45 #include <string.h>
46 #include "gdb_stat.h"
47 #include "gdbcore.h"
48 #include "hppa-tdep.h"
49 #include "observer.h"
51 extern int child_suppress_run;
53 extern void _initialize_hpux_thread (void);
55 struct string_map
57 int num;
58 char *str;
61 static int hpux_thread_active = 0;
63 static ptid_t main_ptid; /* Real process ID */
65 static CORE_ADDR P_cma__g_known_threads;
66 static CORE_ADDR P_cma__g_current_thread;
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;
77 static ptid_t
78 find_active_thread (void)
80 static cma__t_int_tcb tcb;
81 CORE_ADDR tcb_ptr;
83 read_memory ((CORE_ADDR) P_cma__g_current_thread,
84 (char *) &tcb_ptr,
85 sizeof tcb_ptr);
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)
103 return &cached_tcb;
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;
123 return &cached_tcb;
127 error (_("Can't find TCB %d"), thread);
128 return NULL;
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. */
134 static void
135 hpux_thread_open (char *arg, int from_tty)
137 deprecated_child_ops.to_open (arg, from_tty);
140 /* Attach to process PID, then initialize for debugging it
141 and wait for the trace-trap that results from attaching. */
143 static void
144 hpux_thread_attach (struct target_ops *ops, char *args, int from_tty)
146 deprecated_child_ops.to_attach (&deprecated_child_ops, args, from_tty);
148 /* XXX - might want to iterate over all the threads and register them. */
151 /* Take a program previously attached to and detaches it.
152 The program resumes execution and will no longer stop
153 on signals, etc. We'd better not have left any breakpoints
154 in the program or it'll die when it hits one. For this
155 to work, it may be necessary for the process to have been
156 previously attached. It *might* work if the program was
157 started via the normal ptrace (PTRACE_TRACEME). */
159 static void
160 hpux_thread_detach (struct target_ops *ops, char *args, int from_tty)
162 deprecated_child_ops.to_detach (&deprecated_child_ops, args, from_tty);
165 /* Resume execution of process PID. If STEP is nozero, then
166 just single step it. If SIGNAL is nonzero, restart it with that
167 signal activated. We may have to convert pid from a thread-id to an LWP id
168 for procfs. */
170 static void
171 hpux_thread_resume (struct target_ops *ops,
172 ptid_t ptid, int step, enum target_signal signo)
174 struct cleanup *old_chain;
176 old_chain = save_inferior_ptid ();
178 ptid = main_ptid;
179 inferior_ptid = main_ptid;
181 deprecated_child_ops.to_resume (&deprecated_child_ops, ptid, step, signo);
183 cached_thread = 0;
185 do_cleanups (old_chain);
188 /* Wait for any threads to stop. We may have to convert PID from a thread id
189 to a LWP id, and vice versa on the way out. */
191 static ptid_t
192 hpux_thread_wait (struct target_ops *ops,
193 ptid_t ptid, struct target_waitstatus *ourstatus)
195 ptid_t rtnval;
196 struct cleanup *old_chain;
198 old_chain = save_inferior_ptid ();
200 inferior_ptid = main_ptid;
202 if (!ptid_equal (ptid, minus_one_ptid))
203 ptid = main_ptid;
205 rtnval = deprecated_child_ops.to_wait (&deprecated_child_ops,
206 ptid, ourstatus);
208 rtnval = find_active_thread ();
210 do_cleanups (old_chain);
212 return rtnval;
215 static char regmap[] =
217 -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
218 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
219 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
221 /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
222 -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
224 /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
225 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
227 /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
228 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
230 -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
231 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
232 -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
233 -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
234 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
235 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
236 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
237 -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
238 -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
241 static void
242 hpux_thread_fetch_registers (struct target_ops *ops,
243 struct regcache *regcache, int regno)
245 struct gdbarch *gdbarch = get_regcache_arch (regcache);
246 cma__t_int_tcb tcb, *tcb_ptr;
247 struct cleanup *old_chain;
248 int i;
249 int first_regno, last_regno;
251 tcb_ptr = find_tcb (inferior_ptid);
253 old_chain = save_inferior_ptid ();
255 inferior_ptid = main_ptid;
257 if (tcb_ptr->state == cma__c_state_running)
259 deprecated_child_ops.to_fetch_registers (&deprecated_child_ops,
260 regcache, regno);
262 do_cleanups (old_chain);
264 return;
267 if (regno == -1)
269 first_regno = 0;
270 last_regno = gdbarch_num_regs (gdbarch) - 1;
272 else
274 first_regno = regno;
275 last_regno = regno;
278 for (regno = first_regno; regno <= last_regno; regno++)
280 if (regmap[regno] == -1)
281 deprecated_child_ops.to_fetch_registers (&deprecated_child_ops,
282 regcache, regno);
283 else
285 unsigned char buf[MAX_REGISTER_SIZE];
286 CORE_ADDR sp;
288 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
290 if (regno == HPPA_FLAGS_REGNUM)
291 /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
292 memset (buf, '\000', register_size (gdbarch, regno));
293 else if (regno == HPPA_SP_REGNUM)
294 store_unsigned_integer (buf, sizeof sp, sp);
295 else if (regno == HPPA_PCOQ_HEAD_REGNUM)
296 read_memory (sp - 20, buf, register_size (gdbarch, regno));
297 else
298 read_memory (sp + regmap[regno], buf,
299 register_size (gdbarch, regno));
301 regcache_raw_supply (regcache, regno, buf);
305 do_cleanups (old_chain);
308 static void
309 hpux_thread_store_registers (struct target_ops *ops,
310 struct regcache *regcache, int regno)
312 struct gdbarch *gdbarch = get_regcache_arch (regcache);
313 cma__t_int_tcb tcb, *tcb_ptr;
314 struct cleanup *old_chain;
315 int i;
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 deprecated_child_ops.to_store_registers (&deprecated_child_ops,
327 regcache, regno);
329 do_cleanups (old_chain);
331 return;
334 if (regno == -1)
336 first_regno = 0;
337 last_regno = gdbarch_num_regs (gdbarch) - 1;
339 else
341 first_regno = regno;
342 last_regno = regno;
345 for (regno = first_regno; regno <= last_regno; regno++)
347 if (regmap[regno] == -1)
348 deprecated_child_ops.to_store_registers (regcache, regno);
349 else
351 unsigned char buf[MAX_REGISTER_SIZE];
352 CORE_ADDR sp;
354 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
356 if (regno == HPPA_FLAGS_REGNUM)
358 /* Let lower layer handle this... */
359 deprecated_child_ops.to_store_registers
360 (&deprecated_child_ops, regcache, regno);
362 else if (regno == HPPA_SP_REGNUM)
364 regcache_raw_collect (regcache, regno, buf);
365 write_memory ((CORE_ADDR) &tcb_ptr->static_ctx.sp, buf,
366 register_size (gdbarch, regno));
367 tcb_ptr->static_ctx.sp
368 = (cma__t_hppa_regs *) ((CORE_ADDR) buf + 160);
370 else if (regno == HPPA_PCOQ_HEAD_REGNUM)
372 regcache_raw_collect (regcache, regno, buf);
373 write_memory (sp - 20, buf,
374 register_size (gdbarch, regno));
376 else
378 regcache_raw_collect (regcache, regno, buf);
379 write_memory (sp + regmap[regno], buf,
380 register_size (gdbarch, regno));
385 do_cleanups (old_chain);
388 /* Get ready to modify the registers array. On machines which store
389 individual registers, this doesn't need to do anything. On machines
390 which store all the registers in one fell swoop, this makes sure
391 that registers contains all the registers from the program being
392 debugged. */
394 static void
395 hpux_thread_prepare_to_store (struct regcache *regcache)
397 deprecated_child_ops.to_prepare_to_store (regcache);
400 static int
401 hpux_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
402 int dowrite, struct mem_attrib *attribs,
403 struct target_ops *target)
405 int retval;
406 struct cleanup *old_chain;
408 old_chain = save_inferior_ptid ();
410 inferior_ptid = main_ptid;
412 retval =
413 deprecated_child_ops.deprecated_xfer_memory (memaddr, myaddr, len, dowrite, attribs, target);
415 do_cleanups (old_chain);
417 return retval;
420 /* Print status information about what we're accessing. */
422 static void
423 hpux_thread_files_info (struct target_ops *ignore)
425 deprecated_child_ops.to_files_info (ignore);
428 static void
429 hpux_thread_kill_inferior (struct target_ops *ops)
431 deprecated_child_ops.to_kill (&deprecated_child_ops);
434 static void
435 hpux_thread_notice_signals (ptid_t ptid)
437 deprecated_child_ops.to_notice_signals (ptid);
440 /* Fork an inferior process, and start debugging it with /proc. */
442 static void
443 hpux_thread_create_inferior (struct target_ops *ops, char *exec_file,
444 char *allargs, char **env, int from_tty)
446 deprecated_child_ops.to_create_inferior (&deprecated_child_ops,
447 exec_file, allargs, env, from_tty);
449 if (hpux_thread_active)
451 main_ptid = inferior_ptid;
453 push_target (&hpux_thread_ops);
455 inferior_ptid = find_active_thread ();
457 add_thread (inferior_ptid);
461 /* This routine is called whenever a new symbol table is read in, or when all
462 symbol tables are removed. libthread_db can only be initialized when it
463 finds the right variables in libthread.so. Since it's a shared library,
464 those variables don't show up until the library gets mapped and the symbol
465 table is read in. */
467 static void
468 hpux_thread_new_objfile (struct objfile *objfile)
470 struct minimal_symbol *ms;
472 if (!objfile)
474 hpux_thread_active = 0;
475 return;
478 ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile);
480 if (!ms)
481 return;
483 P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms);
485 ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile);
487 if (!ms)
488 return;
490 P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms);
492 hpux_thread_active = 1;
495 /* Clean up after the inferior dies. */
497 static void
498 hpux_thread_mourn_inferior (void)
500 deprecated_child_ops.to_mourn_inferior (&deprecated_child_ops);
503 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
505 static int
506 hpux_thread_can_run (void)
508 return child_suppress_run;
511 static int
512 hpux_thread_alive (struct target_ops *ops, ptid_t ptid)
514 return 1;
517 static void
518 hpux_thread_stop (ptid_t ptid)
520 deprecated_child_ops.to_stop (ptid);
523 /* Convert a pid to printable form. */
525 char *
526 hpux_pid_to_str (ptid_t ptid)
528 static char buf[100];
529 int pid = PIDGET (ptid);
531 sprintf (buf, "Thread %ld", ptid_get_tid (ptid));
533 return buf;
536 static void
537 init_hpux_thread_ops (void)
539 hpux_thread_ops.to_shortname = "hpux-threads";
540 hpux_thread_ops.to_longname = "HPUX threads and pthread.";
541 hpux_thread_ops.to_doc = "HPUX threads and pthread support.";
542 hpux_thread_ops.to_open = hpux_thread_open;
543 hpux_thread_ops.to_attach = hpux_thread_attach;
544 hpux_thread_ops.to_detach = hpux_thread_detach;
545 hpux_thread_ops.to_resume = hpux_thread_resume;
546 hpux_thread_ops.to_wait = hpux_thread_wait;
547 hpux_thread_ops.to_fetch_registers = hpux_thread_fetch_registers;
548 hpux_thread_ops.to_store_registers = hpux_thread_store_registers;
549 hpux_thread_ops.to_prepare_to_store = hpux_thread_prepare_to_store;
550 hpux_thread_ops.deprecated_xfer_memory = hpux_thread_xfer_memory;
551 hpux_thread_ops.to_files_info = hpux_thread_files_info;
552 hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
553 hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
554 hpux_thread_ops.to_terminal_init = terminal_init_inferior;
555 hpux_thread_ops.to_terminal_inferior = terminal_inferior;
556 hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
557 hpux_thread_ops.to_terminal_save_ours = terminal_save_ours;
558 hpux_thread_ops.to_terminal_ours = terminal_ours;
559 hpux_thread_ops.to_terminal_info = child_terminal_info;
560 hpux_thread_ops.to_kill = hpux_thread_kill_inferior;
561 hpux_thread_ops.to_create_inferior = hpux_thread_create_inferior;
562 hpux_thread_ops.to_mourn_inferior = hpux_thread_mourn_inferior;
563 hpux_thread_ops.to_can_run = hpux_thread_can_run;
564 hpux_thread_ops.to_notice_signals = hpux_thread_notice_signals;
565 hpux_thread_ops.to_thread_alive = hpux_thread_alive;
566 hpux_thread_ops.to_stop = hpux_thread_stop;
567 hpux_thread_ops.to_stratum = process_stratum;
568 hpux_thread_ops.to_has_all_memory = 1;
569 hpux_thread_ops.to_has_memory = 1;
570 hpux_thread_ops.to_has_stack = 1;
571 hpux_thread_ops.to_has_registers = 1;
572 hpux_thread_ops.to_has_execution = 1;
573 hpux_thread_ops.to_magic = OPS_MAGIC;
576 void
577 _initialize_hpux_thread (void)
579 init_hpux_thread_ops ();
580 add_target (&hpux_thread_ops);
582 child_suppress_run = 1;
583 /* Hook into new_objfile notification. */
584 observer_attach_new_objfile (hpux_thread_new_objfile);