* expression.h (parse_expression_in_context): Delete prototype.
[deliverable/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
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 (char *args, int from_tty)
148 {
149 deprecated_child_ops.to_attach (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 (char *args, int from_tty)
164 {
165 deprecated_child_ops.to_detach (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 #if 0
184 if (pid != -1)
185 {
186 pid = thread_to_lwp (pid, -2);
187 if (pid == -2) /* Inactive thread */
188 error (_("This version of Solaris can't start inactive threads."));
189 }
190 #endif
191
192 deprecated_child_ops.to_resume (ptid, step, signo);
193
194 cached_thread = 0;
195
196 do_cleanups (old_chain);
197 }
198
199 /* Wait for any threads to stop. We may have to convert PID from a thread id
200 to a LWP id, and vice versa on the way out. */
201
202 static ptid_t
203 hpux_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
204 {
205 ptid_t rtnval;
206 struct cleanup *old_chain;
207
208 old_chain = save_inferior_ptid ();
209
210 inferior_ptid = main_ptid;
211
212 if (!ptid_equal (ptid, minus_one_ptid))
213 ptid = main_ptid;
214
215 rtnval = deprecated_child_ops.to_wait (ptid, ourstatus);
216
217 rtnval = find_active_thread ();
218
219 do_cleanups (old_chain);
220
221 return rtnval;
222 }
223
224 static char regmap[] =
225 {
226 -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
227 28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
228 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
229
230 /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
231 -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
232
233 /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
234 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
235
236 /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
237 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
238
239 -1, -1, -1, -1, /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
240 144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
241 -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
242 -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
243 136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
244 104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
245 72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
246 -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
247 -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
248 };
249
250 static void
251 hpux_thread_fetch_registers (struct regcache *regcache, int regno)
252 {
253 struct gdbarch *gdbarch = get_regcache_arch (regcache);
254 cma__t_int_tcb tcb, *tcb_ptr;
255 struct cleanup *old_chain;
256 int i;
257 int first_regno, last_regno;
258
259 tcb_ptr = find_tcb (inferior_ptid);
260
261 old_chain = save_inferior_ptid ();
262
263 inferior_ptid = main_ptid;
264
265 if (tcb_ptr->state == cma__c_state_running)
266 {
267 deprecated_child_ops.to_fetch_registers (regcache, regno);
268
269 do_cleanups (old_chain);
270
271 return;
272 }
273
274 if (regno == -1)
275 {
276 first_regno = 0;
277 last_regno = gdbarch_num_regs (gdbarch) - 1;
278 }
279 else
280 {
281 first_regno = regno;
282 last_regno = regno;
283 }
284
285 for (regno = first_regno; regno <= last_regno; regno++)
286 {
287 if (regmap[regno] == -1)
288 deprecated_child_ops.to_fetch_registers (regcache, regno);
289 else
290 {
291 unsigned char buf[MAX_REGISTER_SIZE];
292 CORE_ADDR sp;
293
294 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
295
296 if (regno == HPPA_FLAGS_REGNUM)
297 /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
298 memset (buf, '\000', register_size (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 (gdbarch, regno));
303 else
304 read_memory (sp + regmap[regno], buf,
305 register_size (gdbarch, regno));
306
307 regcache_raw_supply (regcache, regno, buf);
308 }
309 }
310
311 do_cleanups (old_chain);
312 }
313
314 static void
315 hpux_thread_store_registers (struct regcache *regcache, int regno)
316 {
317 struct gdbarch *gdbarch = get_regcache_arch (regcache);
318 cma__t_int_tcb tcb, *tcb_ptr;
319 struct cleanup *old_chain;
320 int i;
321 int first_regno, last_regno;
322
323 tcb_ptr = find_tcb (inferior_ptid);
324
325 old_chain = save_inferior_ptid ();
326
327 inferior_ptid = main_ptid;
328
329 if (tcb_ptr->state == cma__c_state_running)
330 {
331 deprecated_child_ops.to_store_registers (regcache, regno);
332
333 do_cleanups (old_chain);
334
335 return;
336 }
337
338 if (regno == -1)
339 {
340 first_regno = 0;
341 last_regno = gdbarch_num_regs (gdbarch) - 1;
342 }
343 else
344 {
345 first_regno = regno;
346 last_regno = regno;
347 }
348
349 for (regno = first_regno; regno <= last_regno; regno++)
350 {
351 if (regmap[regno] == -1)
352 deprecated_child_ops.to_store_registers (regcache, regno);
353 else
354 {
355 unsigned char buf[MAX_REGISTER_SIZE];
356 CORE_ADDR sp;
357
358 sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
359
360 if (regno == HPPA_FLAGS_REGNUM)
361 deprecated_child_ops.to_store_registers (regcache, regno); /* Let lower layer handle this... */
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, dowrite, attribs, target);
414
415 do_cleanups (old_chain);
416
417 return retval;
418 }
419
420 /* Print status information about what we're accessing. */
421
422 static void
423 hpux_thread_files_info (struct target_ops *ignore)
424 {
425 deprecated_child_ops.to_files_info (ignore);
426 }
427
428 static void
429 hpux_thread_kill_inferior (void)
430 {
431 deprecated_child_ops.to_kill ();
432 }
433
434 static void
435 hpux_thread_notice_signals (ptid_t ptid)
436 {
437 deprecated_child_ops.to_notice_signals (ptid);
438 }
439
440 /* Fork an inferior process, and start debugging it with /proc. */
441
442 static void
443 hpux_thread_create_inferior (char *exec_file, char *allargs, char **env,
444 int from_tty)
445 {
446 deprecated_child_ops.to_create_inferior (exec_file, allargs, env, from_tty);
447
448 if (hpux_thread_active)
449 {
450 main_ptid = inferior_ptid;
451
452 push_target (&hpux_thread_ops);
453
454 inferior_ptid = find_active_thread ();
455
456 add_thread (inferior_ptid);
457 }
458 }
459
460 /* This routine is called whenever a new symbol table is read in, or when all
461 symbol tables are removed. libthread_db can only be initialized when it
462 finds the right variables in libthread.so. Since it's a shared library,
463 those variables don't show up until the library gets mapped and the symbol
464 table is read in. */
465
466 static void
467 hpux_thread_new_objfile (struct objfile *objfile)
468 {
469 struct minimal_symbol *ms;
470
471 if (!objfile)
472 {
473 hpux_thread_active = 0;
474 return;
475 }
476
477 ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile);
478
479 if (!ms)
480 return;
481
482 P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms);
483
484 ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile);
485
486 if (!ms)
487 return;
488
489 P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms);
490
491 hpux_thread_active = 1;
492 }
493
494 /* Clean up after the inferior dies. */
495
496 static void
497 hpux_thread_mourn_inferior (void)
498 {
499 deprecated_child_ops.to_mourn_inferior ();
500 }
501
502 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
503
504 static int
505 hpux_thread_can_run (void)
506 {
507 return child_suppress_run;
508 }
509
510 static int
511 hpux_thread_alive (ptid_t ptid)
512 {
513 return 1;
514 }
515
516 static void
517 hpux_thread_stop (void)
518 {
519 deprecated_child_ops.to_stop ();
520 }
521 \f
522 /* Convert a pid to printable form. */
523
524 char *
525 hpux_pid_to_str (ptid_t ptid)
526 {
527 static char buf[100];
528 int pid = PIDGET (ptid);
529
530 sprintf (buf, "Thread %ld", ptid_get_tid (ptid));
531
532 return buf;
533 }
534 \f
535 static void
536 init_hpux_thread_ops (void)
537 {
538 hpux_thread_ops.to_shortname = "hpux-threads";
539 hpux_thread_ops.to_longname = "HPUX threads and pthread.";
540 hpux_thread_ops.to_doc = "HPUX threads and pthread support.";
541 hpux_thread_ops.to_open = hpux_thread_open;
542 hpux_thread_ops.to_attach = hpux_thread_attach;
543 hpux_thread_ops.to_detach = hpux_thread_detach;
544 hpux_thread_ops.to_resume = hpux_thread_resume;
545 hpux_thread_ops.to_wait = hpux_thread_wait;
546 hpux_thread_ops.to_fetch_registers = hpux_thread_fetch_registers;
547 hpux_thread_ops.to_store_registers = hpux_thread_store_registers;
548 hpux_thread_ops.to_prepare_to_store = hpux_thread_prepare_to_store;
549 hpux_thread_ops.deprecated_xfer_memory = hpux_thread_xfer_memory;
550 hpux_thread_ops.to_files_info = hpux_thread_files_info;
551 hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
552 hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
553 hpux_thread_ops.to_terminal_init = terminal_init_inferior;
554 hpux_thread_ops.to_terminal_inferior = terminal_inferior;
555 hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
556 hpux_thread_ops.to_terminal_save_ours = terminal_save_ours;
557 hpux_thread_ops.to_terminal_ours = terminal_ours;
558 hpux_thread_ops.to_terminal_info = child_terminal_info;
559 hpux_thread_ops.to_kill = hpux_thread_kill_inferior;
560 hpux_thread_ops.to_create_inferior = hpux_thread_create_inferior;
561 hpux_thread_ops.to_mourn_inferior = hpux_thread_mourn_inferior;
562 hpux_thread_ops.to_can_run = hpux_thread_can_run;
563 hpux_thread_ops.to_notice_signals = hpux_thread_notice_signals;
564 hpux_thread_ops.to_thread_alive = hpux_thread_alive;
565 hpux_thread_ops.to_stop = hpux_thread_stop;
566 hpux_thread_ops.to_stratum = process_stratum;
567 hpux_thread_ops.to_has_all_memory = 1;
568 hpux_thread_ops.to_has_memory = 1;
569 hpux_thread_ops.to_has_stack = 1;
570 hpux_thread_ops.to_has_registers = 1;
571 hpux_thread_ops.to_has_execution = 1;
572 hpux_thread_ops.to_magic = OPS_MAGIC;
573 }
574
575 void
576 _initialize_hpux_thread (void)
577 {
578 init_hpux_thread_ops ();
579 add_target (&hpux_thread_ops);
580
581 child_suppress_run = 1;
582 /* Hook into new_objfile notification. */
583 observer_attach_new_objfile (hpux_thread_new_objfile);
584 }
This page took 0.04587 seconds and 4 git commands to generate.