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