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