* linux-nat.c (linux_nat_wait): Adjust.
[binutils-gdb.git] / gdb / hpux-thread.c
1 /* Low level interface for debugging HPUX/DCE threads for GDB, the GNU
2 debugger.
3
4 Copyright (C) 1996, 1998, 1999, 2000, 2001, 2004, 2007, 2008, 2009
5 Free Software Foundation, Inc.
6
7 This file is part of GDB.
8
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.
13
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.
18
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/>. */
21
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.
25
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.
31
32 */
33
34 #include "defs.h"
35
36 #define _CMA_NOWRAPPERS_
37
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"
50
51 extern int child_suppress_run;
52
53 extern void _initialize_hpux_thread (void);
54
55 struct string_map
56 {
57 int num;
58 char *str;
59 };
60
61 static int hpux_thread_active = 0;
62
63 static ptid_t main_ptid; /* Real process ID */
64
65 static CORE_ADDR P_cma__g_known_threads;
66 static CORE_ADDR P_cma__g_current_thread;
67
68 static void hpux_thread_resume (ptid_t ptid, int step,
69 enum target_signal signo);
70
71 static void init_hpux_thread_ops (void);
72
73 static struct target_ops hpux_thread_ops;
74 \f
75 static ptid_t find_active_thread (void);
76
77 static int cached_thread;
78 static cma__t_int_tcb cached_tcb;
79
80 static ptid_t
81 find_active_thread (void)
82 {
83 static cma__t_int_tcb tcb;
84 CORE_ADDR tcb_ptr;
85
86 read_memory ((CORE_ADDR) P_cma__g_current_thread,
87 (char *) &tcb_ptr,
88 sizeof tcb_ptr);
89
90 read_memory (tcb_ptr, (char *) &tcb, sizeof tcb);
91
92 return (ptid_build (PIDGET (main_ptid), 0,
93 cma_thread_get_unique (&tcb.prolog.client_thread)));
94 }
95
96 static cma__t_int_tcb *find_tcb (ptid_t ptid);
97
98 static cma__t_int_tcb *
99 find_tcb (ptid_t ptid)
100 {
101 cma__t_known_object queue_header;
102 cma__t_queue *queue_ptr;
103 int thread = ptid_get_tid (ptid);
104
105 if (thread == cached_thread)
106 return &cached_tcb;
107
108 read_memory ((CORE_ADDR) P_cma__g_known_threads,
109 (char *) &queue_header,
110 sizeof queue_header);
111
112 for (queue_ptr = queue_header.queue.flink;
113 queue_ptr != (cma__t_queue *) P_cma__g_known_threads;
114 queue_ptr = cached_tcb.threads.flink)
115 {
116 cma__t_int_tcb *tcb_ptr;
117
118 tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb);
119
120 read_memory ((CORE_ADDR) tcb_ptr, (char *) &cached_tcb, sizeof cached_tcb);
121
122 if (cached_tcb.header.type == cma__c_obj_tcb)
123 if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread)
124 {
125 cached_thread = thread;
126 return &cached_tcb;
127 }
128 }
129
130 error (_("Can't find TCB %d"), thread);
131 return NULL;
132 }
133 \f
134 /* Most target vector functions from here on actually just pass through to
135 inftarg.c, as they don't need to do anything specific for threads. */
136
137 static void
138 hpux_thread_open (char *arg, int from_tty)
139 {
140 deprecated_child_ops.to_open (arg, from_tty);
141 }
142
143 /* Attach to process PID, then initialize for debugging it
144 and wait for the trace-trap that results from attaching. */
145
146 static void
147 hpux_thread_attach (struct target_ops *ops, char *args, int from_tty)
148 {
149 deprecated_child_ops.to_attach (&deprecated_child_ops, args, from_tty);
150
151 /* XXX - might want to iterate over all the threads and register them. */
152 }
153
154 /* Take a program previously attached to and detaches it.
155 The program resumes execution and will no longer stop
156 on signals, etc. We'd better not have left any breakpoints
157 in the program or it'll die when it hits one. For this
158 to work, it may be necessary for the process to have been
159 previously attached. It *might* work if the program was
160 started via the normal ptrace (PTRACE_TRACEME). */
161
162 static void
163 hpux_thread_detach (struct target_ops *ops, char *args, int from_tty)
164 {
165 deprecated_child_ops.to_detach (&deprecated_child_ops, args, from_tty);
166 }
167
168 /* Resume execution of process PID. If STEP is nozero, then
169 just single step it. If SIGNAL is nonzero, restart it with that
170 signal activated. We may have to convert pid from a thread-id to an LWP id
171 for procfs. */
172
173 static void
174 hpux_thread_resume (ptid_t ptid, int step, enum target_signal signo)
175 {
176 struct cleanup *old_chain;
177
178 old_chain = save_inferior_ptid ();
179
180 ptid = main_ptid;
181 inferior_ptid = main_ptid;
182
183 deprecated_child_ops.to_resume (ptid, step, signo);
184
185 cached_thread = 0;
186
187 do_cleanups (old_chain);
188 }
189
190 /* Wait for any threads to stop. We may have to convert PID from a thread id
191 to a LWP id, and vice versa on the way out. */
192
193 static ptid_t
194 hpux_thread_wait (struct target_ops *ops,
195 ptid_t ptid, struct target_waitstatus *ourstatus)
196 {
197 ptid_t rtnval;
198 struct cleanup *old_chain;
199
200 old_chain = save_inferior_ptid ();
201
202 inferior_ptid = main_ptid;
203
204 if (!ptid_equal (ptid, minus_one_ptid))
205 ptid = main_ptid;
206
207 rtnval = deprecated_child_ops.to_wait (&deprecated_child_ops,
208 ptid, ourstatus);
209
210 rtnval = find_active_thread ();
211
212 do_cleanups (old_chain);
213
214 return rtnval;
215 }
216
217 static char regmap[] =
218 {
219 -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
220 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
221 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
222
223 /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
224 -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
225
226 /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
227 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
228
229 /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
230 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
231
232 -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
233 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
234 -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
235 -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
236 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
237 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
238 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
239 -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
240 -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
241 };
242
243 static void
244 hpux_thread_fetch_registers (struct regcache *regcache, int regno)
245 {
246 struct gdbarch *gdbarch = get_regcache_arch (regcache);
247 cma__t_int_tcb tcb, *tcb_ptr;
248 struct cleanup *old_chain;
249 int i;
250 int first_regno, last_regno;
251
252 tcb_ptr = find_tcb (inferior_ptid);
253
254 old_chain = save_inferior_ptid ();
255
256 inferior_ptid = main_ptid;
257
258 if (tcb_ptr->state == cma__c_state_running)
259 {
260 deprecated_child_ops.to_fetch_registers (regcache, regno);
261
262 do_cleanups (old_chain);
263
264 return;
265 }
266
267 if (regno == -1)
268 {
269 first_regno = 0;
270 last_regno = gdbarch_num_regs (gdbarch) - 1;
271 }
272 else
273 {
274 first_regno = regno;
275 last_regno = regno;
276 }
277
278 for (regno = first_regno; regno <= last_regno; regno++)
279 {
280 if (regmap[regno] == -1)
281 deprecated_child_ops.to_fetch_registers (regcache, regno);
282 else
283 {
284 unsigned char buf[MAX_REGISTER_SIZE];
285 CORE_ADDR sp;
286
287 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
288
289 if (regno == HPPA_FLAGS_REGNUM)
290 /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
291 memset (buf, '\000', register_size (gdbarch, regno));
292 else if (regno == HPPA_SP_REGNUM)
293 store_unsigned_integer (buf, sizeof sp, sp);
294 else if (regno == HPPA_PCOQ_HEAD_REGNUM)
295 read_memory (sp - 20, buf, register_size (gdbarch, regno));
296 else
297 read_memory (sp + regmap[regno], buf,
298 register_size (gdbarch, regno));
299
300 regcache_raw_supply (regcache, regno, buf);
301 }
302 }
303
304 do_cleanups (old_chain);
305 }
306
307 static void
308 hpux_thread_store_registers (struct regcache *regcache, int regno)
309 {
310 struct gdbarch *gdbarch = get_regcache_arch (regcache);
311 cma__t_int_tcb tcb, *tcb_ptr;
312 struct cleanup *old_chain;
313 int i;
314 int first_regno, last_regno;
315
316 tcb_ptr = find_tcb (inferior_ptid);
317
318 old_chain = save_inferior_ptid ();
319
320 inferior_ptid = main_ptid;
321
322 if (tcb_ptr->state == cma__c_state_running)
323 {
324 deprecated_child_ops.to_store_registers (regcache, regno);
325
326 do_cleanups (old_chain);
327
328 return;
329 }
330
331 if (regno == -1)
332 {
333 first_regno = 0;
334 last_regno = gdbarch_num_regs (gdbarch) - 1;
335 }
336 else
337 {
338 first_regno = regno;
339 last_regno = regno;
340 }
341
342 for (regno = first_regno; regno <= last_regno; regno++)
343 {
344 if (regmap[regno] == -1)
345 deprecated_child_ops.to_store_registers (regcache, regno);
346 else
347 {
348 unsigned char buf[MAX_REGISTER_SIZE];
349 CORE_ADDR sp;
350
351 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
352
353 if (regno == HPPA_FLAGS_REGNUM)
354 deprecated_child_ops.to_store_registers (regcache, regno); /* Let lower layer handle this... */
355 else if (regno == HPPA_SP_REGNUM)
356 {
357 regcache_raw_collect (regcache, regno, buf);
358 write_memory ((CORE_ADDR) &tcb_ptr->static_ctx.sp, buf,
359 register_size (gdbarch, regno));
360 tcb_ptr->static_ctx.sp
361 = (cma__t_hppa_regs *) ((CORE_ADDR) buf + 160);
362 }
363 else if (regno == HPPA_PCOQ_HEAD_REGNUM)
364 {
365 regcache_raw_collect (regcache, regno, buf);
366 write_memory (sp - 20, buf,
367 register_size (gdbarch, regno));
368 }
369 else
370 {
371 regcache_raw_collect (regcache, regno, buf);
372 write_memory (sp + regmap[regno], buf,
373 register_size (gdbarch, regno));
374 }
375 }
376 }
377
378 do_cleanups (old_chain);
379 }
380
381 /* Get ready to modify the registers array. On machines which store
382 individual registers, this doesn't need to do anything. On machines
383 which store all the registers in one fell swoop, this makes sure
384 that registers contains all the registers from the program being
385 debugged. */
386
387 static void
388 hpux_thread_prepare_to_store (struct regcache *regcache)
389 {
390 deprecated_child_ops.to_prepare_to_store (regcache);
391 }
392
393 static int
394 hpux_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
395 int dowrite, struct mem_attrib *attribs,
396 struct target_ops *target)
397 {
398 int retval;
399 struct cleanup *old_chain;
400
401 old_chain = save_inferior_ptid ();
402
403 inferior_ptid = main_ptid;
404
405 retval =
406 deprecated_child_ops.deprecated_xfer_memory (memaddr, myaddr, len, dowrite, attribs, target);
407
408 do_cleanups (old_chain);
409
410 return retval;
411 }
412
413 /* Print status information about what we're accessing. */
414
415 static void
416 hpux_thread_files_info (struct target_ops *ignore)
417 {
418 deprecated_child_ops.to_files_info (ignore);
419 }
420
421 static void
422 hpux_thread_kill_inferior (void)
423 {
424 deprecated_child_ops.to_kill ();
425 }
426
427 static void
428 hpux_thread_notice_signals (ptid_t ptid)
429 {
430 deprecated_child_ops.to_notice_signals (ptid);
431 }
432
433 /* Fork an inferior process, and start debugging it with /proc. */
434
435 static void
436 hpux_thread_create_inferior (struct target_ops *ops, char *exec_file,
437 char *allargs, char **env, int from_tty)
438 {
439 deprecated_child_ops.to_create_inferior (&deprecated_child_ops,
440 exec_file, allargs, env, from_tty);
441
442 if (hpux_thread_active)
443 {
444 main_ptid = inferior_ptid;
445
446 push_target (&hpux_thread_ops);
447
448 inferior_ptid = find_active_thread ();
449
450 add_thread (inferior_ptid);
451 }
452 }
453
454 /* This routine is called whenever a new symbol table is read in, or when all
455 symbol tables are removed. libthread_db can only be initialized when it
456 finds the right variables in libthread.so. Since it's a shared library,
457 those variables don't show up until the library gets mapped and the symbol
458 table is read in. */
459
460 static void
461 hpux_thread_new_objfile (struct objfile *objfile)
462 {
463 struct minimal_symbol *ms;
464
465 if (!objfile)
466 {
467 hpux_thread_active = 0;
468 return;
469 }
470
471 ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile);
472
473 if (!ms)
474 return;
475
476 P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms);
477
478 ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile);
479
480 if (!ms)
481 return;
482
483 P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms);
484
485 hpux_thread_active = 1;
486 }
487
488 /* Clean up after the inferior dies. */
489
490 static void
491 hpux_thread_mourn_inferior (void)
492 {
493 deprecated_child_ops.to_mourn_inferior (&deprecated_child_ops);
494 }
495
496 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
497
498 static int
499 hpux_thread_can_run (void)
500 {
501 return child_suppress_run;
502 }
503
504 static int
505 hpux_thread_alive (ptid_t ptid)
506 {
507 return 1;
508 }
509
510 static void
511 hpux_thread_stop (ptid_t ptid)
512 {
513 deprecated_child_ops.to_stop (ptid);
514 }
515 \f
516 /* Convert a pid to printable form. */
517
518 char *
519 hpux_pid_to_str (ptid_t ptid)
520 {
521 static char buf[100];
522 int pid = PIDGET (ptid);
523
524 sprintf (buf, "Thread %ld", ptid_get_tid (ptid));
525
526 return buf;
527 }
528 \f
529 static void
530 init_hpux_thread_ops (void)
531 {
532 hpux_thread_ops.to_shortname = "hpux-threads";
533 hpux_thread_ops.to_longname = "HPUX threads and pthread.";
534 hpux_thread_ops.to_doc = "HPUX threads and pthread support.";
535 hpux_thread_ops.to_open = hpux_thread_open;
536 hpux_thread_ops.to_attach = hpux_thread_attach;
537 hpux_thread_ops.to_detach = hpux_thread_detach;
538 hpux_thread_ops.to_resume = hpux_thread_resume;
539 hpux_thread_ops.to_wait = hpux_thread_wait;
540 hpux_thread_ops.to_fetch_registers = hpux_thread_fetch_registers;
541 hpux_thread_ops.to_store_registers = hpux_thread_store_registers;
542 hpux_thread_ops.to_prepare_to_store = hpux_thread_prepare_to_store;
543 hpux_thread_ops.deprecated_xfer_memory = hpux_thread_xfer_memory;
544 hpux_thread_ops.to_files_info = hpux_thread_files_info;
545 hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
546 hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
547 hpux_thread_ops.to_terminal_init = terminal_init_inferior;
548 hpux_thread_ops.to_terminal_inferior = terminal_inferior;
549 hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
550 hpux_thread_ops.to_terminal_save_ours = terminal_save_ours;
551 hpux_thread_ops.to_terminal_ours = terminal_ours;
552 hpux_thread_ops.to_terminal_info = child_terminal_info;
553 hpux_thread_ops.to_kill = hpux_thread_kill_inferior;
554 hpux_thread_ops.to_create_inferior = hpux_thread_create_inferior;
555 hpux_thread_ops.to_mourn_inferior = hpux_thread_mourn_inferior;
556 hpux_thread_ops.to_can_run = hpux_thread_can_run;
557 hpux_thread_ops.to_notice_signals = hpux_thread_notice_signals;
558 hpux_thread_ops.to_thread_alive = hpux_thread_alive;
559 hpux_thread_ops.to_stop = hpux_thread_stop;
560 hpux_thread_ops.to_stratum = process_stratum;
561 hpux_thread_ops.to_has_all_memory = 1;
562 hpux_thread_ops.to_has_memory = 1;
563 hpux_thread_ops.to_has_stack = 1;
564 hpux_thread_ops.to_has_registers = 1;
565 hpux_thread_ops.to_has_execution = 1;
566 hpux_thread_ops.to_magic = OPS_MAGIC;
567 }
568
569 void
570 _initialize_hpux_thread (void)
571 {
572 init_hpux_thread_ops ();
573 add_target (&hpux_thread_ops);
574
575 child_suppress_run = 1;
576 /* Hook into new_objfile notification. */
577 observer_attach_new_objfile (hpux_thread_new_objfile);
578 }