* abug-rom.c: Config file for the older style ABug monitor thatg
[deliverable/binutils-gdb.git] / gdb / sol-thread.c
CommitLineData
8fc2b417
SG
1/* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
2 Copyright 1996 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20
21#include "defs.h"
22
23#ifdef gregset_t
24#undef gregset_t
25#endif
26
27#ifdef fpregset_t
28#undef fpregset_t
29#endif
30
31#include "/usr/include/thread.h"
32#include <proc_service.h>
33#include <thread_db.h>
34#include "thread.h"
35#include "target.h"
36#include "inferior.h"
37#include <fcntl.h>
38#include <unistd.h>
39#include <sys/stat.h>
40
41static void sol_thread_resume PARAMS ((int pid, int step,
42 enum target_signal signo));
43
44extern struct target_ops sol_thread_ops; /* Forward declaration */
45
46extern int procfs_suppress_run;
47
48struct ps_prochandle
49{
50 pid_t pid;
51};
52
53static struct ps_prochandle main_ph;
54static td_thragent_t *main_ta;
55
56static int sol_thread_active = 0;
57
58\f
59
60extern struct target_ops procfs_ops;
61
62/* Convert thread_id to an LWP id. */
63
64static int thread_to_lwp PARAMS ((int thread_id, int default_lwp));
65
66static int
67thread_to_lwp (thread_id, default_lwp)
68 int thread_id;
69 int default_lwp;
70{
71 td_thrinfo_t ti;
72 td_thrhandle_t th;
73 td_err_e val;
74 int pid;
75 int lwp;
76
77 if (!(thread_id & 0x80000000))
78 return thread_id; /* It's already an LWP id */
79
80 /* It's a thread. Convert to lwp */
81
82 pid = thread_id & 0xffff;
83 thread_id = (thread_id >> 16) & 0x7fff;
84
85 val = td_ta_map_id2thr (main_ta, thread_id, &th);
86 if (val != TD_OK)
87 error ("thread_to_lwp: td_ta_map_id2thr %d", val);
88
89 val = td_thr_get_info (&th, &ti);
90
91 if (val != TD_OK)
92 error ("thread_to_lwp: td_thr_get_info: %d", val);
93
94 if (ti.ti_state != TD_THR_ACTIVE)
95 {
96 if (default_lwp != -1)
97 return default_lwp;
98 error ("thread_to_lwp: thread state not active: %d", ti.ti_state);
99 }
100
101 lwp = (ti.ti_lid << 16) | pid;
102
103 return lwp;
104}
105
106/* Convert an LWP id to a thread. */
107
108static int lwp_to_thread PARAMS ((int lwp));
109
110static int
111lwp_to_thread (lwp)
112 int lwp;
113{
114 td_thrinfo_t ti;
115 td_thrhandle_t th;
116 td_err_e val;
117 int pid;
118 int thread_id;
119
120 if (lwp & 0x80000000)
121 return lwp; /* It's already a thread id */
122
123 /* It's an lwp. Convert it to a thread id. */
124
125 pid = lwp & 0xffff;
126 lwp = (lwp >> 16) & 0xffff;
127
128 val = td_ta_map_lwp2thr (main_ta, lwp, &th);
129 if (val != TD_OK)
130 error ("lwp_to_thread: td_thr_get_info: %d.", val);
131
132 val = td_thr_get_info (&th, &ti);
133
134 if (val != TD_OK)
135 error ("lwp_to_thread: td_thr_get_info: %d.", val);
136
137 thread_id = (ti.ti_tid << 16) | pid | 0x80000000;
138
139 return thread_id;
140}
141
142
143/* ARGSUSED */
144static void
145sol_thread_open (arg, from_tty)
146 char *arg;
147 int from_tty;
148{
149 procfs_ops.to_open (arg, from_tty);
150}
151
152/* Attach to process PID, then initialize for debugging it
153 and wait for the trace-trap that results from attaching. */
154
155static void
156sol_thread_attach (args, from_tty)
157 char *args;
158 int from_tty;
159{
160 procfs_ops.to_attach (args, from_tty);
161
162 /* XXX - might want to iterate over all the threads and register them. */
163}
164
165/* Take a program previously attached to and detaches it.
166 The program resumes execution and will no longer stop
167 on signals, etc. We'd better not have left any breakpoints
168 in the program or it'll die when it hits one. For this
169 to work, it may be necessary for the process to have been
170 previously attached. It *might* work if the program was
171 started via the normal ptrace (PTRACE_TRACEME). */
172
173static void
174sol_thread_detach (args, from_tty)
175 char *args;
176 int from_tty;
177{
178 procfs_ops.to_detach (args, from_tty);
179}
180
181/* Resume execution of process PID. If STEP is nozero, then
182 just single step it. If SIGNAL is nonzero, restart it with that
183 signal activated. */
184
185static void
186sol_thread_resume (pid, step, signo)
187 int pid;
188 int step;
189 enum target_signal signo;
190{
191 int save_pid;
192
193 save_pid = inferior_pid;
194
195 inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid);
196
197 if (pid != -1)
198 pid = thread_to_lwp (pid, -1);
199
200 procfs_ops.to_resume (pid, step, signo);
201
202 inferior_pid = save_pid;
203}
204
205/* Wait for any LWPs to stop */
206
207static int
208sol_thread_wait (pid, ourstatus)
209 int pid;
210 struct target_waitstatus *ourstatus;
211{
212 int statval;
213 int rtnval;
214 int save_pid;
215
216 if (!sol_thread_active)
217 return procfs_ops.to_wait (pid, ourstatus);
218
219 save_pid = inferior_pid;
220
221 inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid);
222
223 if (pid != -1)
224 pid = thread_to_lwp (pid, -1);
225
226 rtnval = procfs_ops.to_wait (pid, ourstatus);
227
228 if (rtnval != save_pid
229 && !in_thread_list (rtnval))
230 {
231 fprintf_unfiltered (gdb_stderr, "[New %s]\n",
232 target_pid_to_str (rtnval));
233 add_thread (rtnval);
234 }
235
236 inferior_pid = save_pid; /* XXX need to make a cleanup for this in case of error */
237
238 /* During process initialization, we may get here without the thread package
239 being initialized, since that can only happen after we've found the shared
240 libs. */
241
242 /* Map the LWP of interest back to the appropriate thread ID */
243
244 rtnval = lwp_to_thread (rtnval);
245
246 return rtnval;
247}
248
249static void
250sol_thread_fetch_registers (regno)
251 int regno;
252{
253 thread_t thread;
254 td_thrhandle_t thandle;
255 td_err_e val;
256 prgregset_t regset;
257 prfpregset_t fpregset;
258 int xregsize;
259 caddr_t xregset;
260
261 if (!sol_thread_active
262 || !(inferior_pid & 0x80000000))
263 {
264 procfs_ops.to_fetch_registers (regno);
265 return;
266 }
267
268 /* Convert inferior_pid into a td_thrhandle_t */
269
270 thread = (inferior_pid >> 16) & 0x7fff;
271
272 if (thread == 0)
273 error ("sol_thread_fetch_registers: thread == 0");
274
275 val = td_ta_map_id2thr (main_ta, thread, &thandle);
276 if (val != TD_OK)
277 error ("sol_thread_fetch_registers: td_ta_map_id2thr: %d", val);
278
279 /* Get the integer regs */
280
281 val = td_thr_getgregs (&thandle, regset);
282 if (val == TD_OK)
283 supply_gregset (regset);
284 else if (val == TD_PARTIALREG)
285 {
286 /* For the sparc, only i0->i7, l0->l7, pc and sp are saved by a thread
287 context switch. */
288
289 supply_gregset (regset); /* This is not entirely correct, as it sets
290 the valid bits for the o, g, ps, y, npc,
291 wim and tbr. That should be harmless
292 though, as the context switch routine
293 doesn't need to save them. */
294 }
295 else
296 error ("sol_thread_fetch_registers: td_thr_getgregs %d", val);
297
298 /* And, now the fp regs */
299
300 val = td_thr_getfpregs (&thandle, &fpregset);
301 if (val == TD_OK)
302 supply_fpregset (&fpregset);
303 else if (val != TD_NOFPREGS)
304 error ("sol_thread_fetch_registers: td_thr_getfpregs %d", val);
305
306#if 0
307/* thread_db doesn't seem to handle this right */
308 val = td_thr_getxregsize (&thandle, &xregsize);
309 if (val != TD_OK && val != TD_NOXREGS)
310 error ("sol_thread_fetch_registers: td_thr_getxregsize %d", val);
311
312 if (val == TD_OK)
313 {
314 xregset = alloca (xregsize);
315 val = td_thr_getxregs (&thandle, xregset);
316 if (val != TD_OK)
317 error ("sol_thread_fetch_registers: td_thr_getxregs %d", val);
318 }
319#endif
320}
321
322static void
323sol_thread_store_registers (regno)
324 int regno;
325{
326 thread_t thread;
327 td_thrhandle_t thandle;
328 td_err_e val;
329 prgregset_t regset;
330 prfpregset_t fpregset;
331 int xregsize;
332 caddr_t xregset;
333
334 if (!sol_thread_active
335 || !(inferior_pid & 0x80000000))
336 {
337 procfs_ops.to_store_registers (regno);
338 return;
339 }
340
341 /* Convert inferior_pid into a td_thrhandle_t */
342
343 thread = (inferior_pid >> 16) & 0x7fff;
344
345 val = td_ta_map_id2thr (main_ta, thread, &thandle);
346 if (val != TD_OK)
347 error ("sol_thread_store_registers: td_ta_map_id2thr %d", val);
348
349 if (regno != -1)
350 { /* Not writing all the regs */
351 val = td_thr_getgregs (&thandle, regset);
352 if (val != TD_OK)
353 error ("sol_thread_store_registers: td_thr_getgregs %d", val);
354 val = td_thr_getfpregs (&thandle, &fpregset);
355 if (val != TD_OK)
356 error ("sol_thread_store_registers: td_thr_getfpregs %d", val);
357
358#if 0
359/* thread_db doesn't seem to handle this right */
360 val = td_thr_getxregsize (&thandle, &xregsize);
361 if (val != TD_OK && val != TD_NOXREGS)
362 error ("sol_thread_store_registers: td_thr_getxregsize %d", val);
363
364 if (val == TD_OK)
365 {
366 xregset = alloca (xregsize);
367 val = td_thr_getxregs (&thandle, xregset);
368 if (val != TD_OK)
369 error ("sol_thread_store_registers: td_thr_getxregs %d", val);
370 }
371#endif
372 }
373
374 fill_gregset (regset, regno);
375 fill_fpregset (&fpregset, regno);
376
377 val = td_thr_setgregs (&thandle, regset);
378 if (val != TD_OK)
379 error ("sol_thread_store_registers: td_thr_setgregs %d", val);
380 val = td_thr_setfpregs (&thandle, &fpregset);
381 if (val != TD_OK)
382 error ("sol_thread_store_registers: td_thr_setfpregs %d", val);
383
384#if 0
385/* thread_db doesn't seem to handle this right */
386 val = td_thr_getxregsize (&thandle, &xregsize);
387 if (val != TD_OK && val != TD_NOXREGS)
388 error ("sol_thread_store_registers: td_thr_getxregsize %d", val);
389
390 /* Should probably do something about writing the xregs here, but what are
391 they? */
392#endif
393}
394
395/* Get ready to modify the registers array. On machines which store
396 individual registers, this doesn't need to do anything. On machines
397 which store all the registers in one fell swoop, this makes sure
398 that registers contains all the registers from the program being
399 debugged. */
400
401static void
402sol_thread_prepare_to_store ()
403{
404 procfs_ops.to_prepare_to_store ();
405}
406
407static int
408sol_thread_xfer_memory (memaddr, myaddr, len, dowrite, target)
409 CORE_ADDR memaddr;
410 char *myaddr;
411 int len;
412 int dowrite;
413 struct target_ops *target; /* ignored */
414{
415 int retval;
416 int save_pid;
417
418 save_pid = inferior_pid;
419
420 if (inferior_pid & 0x80000000)
421 inferior_pid = main_ph.pid; /* It's a thread. Convert to lwp */
422
423 retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target);
424
425 inferior_pid = save_pid;
426
427 return retval;
428}
429
430/* Print status information about what we're accessing. */
431
432static void
433sol_thread_files_info (ignore)
434 struct target_ops *ignore;
435{
436 procfs_ops.to_files_info (ignore);
437}
438
439static void
440sol_thread_kill_inferior ()
441{
442 procfs_ops.to_kill ();
443}
444
445static void
446sol_thread_notice_signals (pid)
447 int pid;
448{
449 procfs_ops.to_notice_signals (pid);
450}
451
452void target_new_objfile PARAMS ((struct objfile *objfile));
453
454/* Fork an inferior process, and start debugging it with /proc. */
455
456static void
457sol_thread_create_inferior (exec_file, allargs, env)
458 char *exec_file;
459 char *allargs;
460 char **env;
461{
462 procfs_ops.to_create_inferior (exec_file, allargs, env);
463
464 if (sol_thread_active)
465 {
466 td_thrhandle_t thandle;
467 td_err_e val;
468 td_thrinfo_t ti;
469
470 main_ph.pid = inferior_pid; /* Save for xfer_memory */
471
472 push_target (&sol_thread_ops);
473
474 inferior_pid = lwp_to_thread (inferior_pid);
475
476 add_thread (inferior_pid);
477 }
478}
479
480/* This routine is called whenever a new symbol table is read in, or when all
481 symbol tables are removed. */
482
483void
484sol_thread_new_objfile (objfile)
485 struct objfile *objfile;
486{
487 td_err_e val;
488
489 if (!objfile)
490 {
491 sol_thread_active = 0;
492
493 return;
494 }
495
496 /* Now, initialize the thread debugging library. This needs to be done after
497 the shared libraries are located because it needs information from the
498 user's thread library. */
499
500 val = td_init ();
501 if (val != TD_OK)
502 error ("target_new_objfile: td_init: %d", val);
503
504 val = td_ta_new (&main_ph, &main_ta);
505 if (val == TD_NOLIBTHREAD)
506 return;
507 else if (val != TD_OK)
508 error ("target_new_objfile: td_ta_new: %d", val);
509
510 sol_thread_active = 1;
511}
512
513/* Clean up after the inferior dies. */
514
515static void
516sol_thread_mourn_inferior ()
517{
518 procfs_ops.to_mourn_inferior ();
519}
520
521/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
522static int
523sol_thread_can_run ()
524{
525 return procfs_suppress_run;
526}
527
528int
529sol_thread_alive (pid)
530 int pid;
531{
532 return 1;
533}
534
535void
536sol_thread_stop ()
537{
538 procfs_ops.to_stop ();
539}
540
541/* Service routines we must supply to libthread_db */
542
543struct lwp_map
544{
545 struct lwp_map *next;
546 pid_t pid;
547 lwpid_t lwp;
548 int lwpfd;
549};
550
551#if 0
552struct lwp_map *lwp_map;
553
554/* Create a /proc file descriptor for the given LWPID */
555
556static ps_err_e
557get_lwp_fd (const struct ps_prochandle *ph, const lwpid_t lwpid, int *fd)
558{
559 struct lwp_map *lp;
560
561 for (lp = lwp_map; lp; lp = lp->next)
562 if (lp->pid = ph->pid
563 && lp->lwp == lwpid)
564 {
565 *fd = lp->lwpfd;
566
567 return PS_OK;
568 }
569
570 lp = xmalloc (sizeof (struct lwp_map));
571
572 if ((lp->lwpfd = ioctl (ph->fd, PIOCOPENLWP, &lwpid)) < 0)
573 {
574 print_sys_errmsg ("get_lwp_fd (): PIOCOPENLWP", errno);
575 return PS_BADLID;
576 }
577
578 lp->pid = ph->pid;
579 lp->lwp = lwpid;
580 lp->next = lwp_map;
581 lwp_map = lp;
582
583 *fd = lp->lwpfd;
584
585 return PS_OK;
586}
587#endif
588
589ps_err_e
590ps_pstop (const struct ps_prochandle *ph)
591{
592#if 0
593 if (ioctl (ph->fd, PIOCSTOP, NULL))
594 {
595 print_sys_errmsg ("ps_pstop (): PIOCSTOP", errno);
596 return PS_ERR;
597 }
598#endif
599 return PS_OK;
600}
601
602ps_err_e
603ps_pcontinue (const struct ps_prochandle *ph)
604{
605#if 0
606 if (ioctl (ph->fd, PIOCRUN, NULL))
607 {
608 print_sys_errmsg ("ps_pcontinue (): PIOCRUN", errno);
609 return PS_ERR;
610 }
611#endif
612 return PS_OK;
613}
614
615ps_err_e
616ps_lstop (const struct ps_prochandle *ph, lwpid_t lwpid)
617{
618 int lwp_fd;
619 ps_err_e val;
620
621#if 0
622 val = get_lwp_fd (ph, lwpid, &lwp_fd);
623 if (val != PS_OK)
624 return val;
625
626 if (ioctl (lwp_fd, PIOCSTOP, NULL))
627 {
628 print_sys_errmsg ("ps_lstop (): PIOCSTOP", errno);
629 return PS_ERR;
630 }
631#endif
632
633 return PS_OK;
634}
635
636ps_err_e
637ps_lcontinue (const struct ps_prochandle *ph, lwpid_t lwpid)
638{
639 int lwp_fd;
640 ps_err_e val;
641
642#if 0
643 val = get_lwp_fd (ph, lwpid, &lwp_fd);
644 if (val != PS_OK)
645 return val;
646
647 if (ioctl (lwp_fd, PIOCRUN, NULL))
648 {
649 print_sys_errmsg ("ps_lcontinue (): PIOCRUN", errno);
650 return PS_ERR;
651 }
652#endif
653
654 return PS_OK;
655}
656
657ps_err_e
658ps_pglobal_lookup (const struct ps_prochandle *ph, const char *ld_object_name,
659 const char *ld_symbol_name, paddr_t *ld_symbol_addr)
660{
661 struct minimal_symbol *ms;
662
663 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
664
665 if (!ms)
666 return PS_NOSYM;
667
668 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
669
670 return PS_OK;
671}
672
673static ps_err_e
674rw_common (int dowrite, const struct ps_prochandle *ph, paddr_t addr,
675 char *buf, int size)
676{
677 int save_pid;
678
679 save_pid = inferior_pid;
680
681 if (inferior_pid & 0x80000000)
682 inferior_pid = main_ph.pid; /* It's a thread. Convert to lwp */
683
684 while (size > 0)
685 {
686 int cc;
687
688 cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, &procfs_ops);
689
690 if (cc < 0)
691 {
692 if (dowrite == 0)
693 print_sys_errmsg ("ps_pdread (): read", errno);
694 else
695 print_sys_errmsg ("ps_pdread (): write", errno);
696
697 inferior_pid = save_pid;
698
699 return PS_ERR;
700 }
701 size -= cc;
702 buf += cc;
703 }
704
705 inferior_pid = save_pid;
706
707 return PS_OK;
708}
709
710ps_err_e
711ps_pdread (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
712{
713 return rw_common (0, ph, addr, buf, size);
714}
715
716ps_err_e
717ps_pdwrite (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
718{
719 return rw_common (1, ph, addr, buf, size);
720}
721
722ps_err_e
723ps_ptread (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
724{
725 return rw_common (0, ph, addr, buf, size);
726}
727
728ps_err_e
729ps_ptwrite (const struct ps_prochandle *ph, paddr_t addr, char *buf, int size)
730{
731 return rw_common (1, ph, addr, buf, size);
732}
733
734ps_err_e
735ps_lgetregs (const struct ps_prochandle *ph, lwpid_t lwpid,
736 prgregset_t gregset)
737{
738 int save_pid;
739
740 save_pid = inferior_pid;
741
742 inferior_pid = (lwpid << 16) | (inferior_pid & 0xffff);
743
744 procfs_ops.to_fetch_registers (-1);
745 fill_gregset (gregset, -1);
746
747 inferior_pid = save_pid;
748
749 return PS_OK;
750}
751
752ps_err_e
753ps_lsetregs (const struct ps_prochandle *ph, lwpid_t lwpid,
754 const prgregset_t gregset)
755{
756 int save_pid;
757
758 save_pid = inferior_pid;
759
760 inferior_pid = (lwpid << 16) | (inferior_pid & 0xffff);
761
762 supply_gregset (gregset);
763 procfs_ops.to_store_registers (-1);
764
765 inferior_pid = save_pid;
766
767 return PS_OK;
768}
769
770void
771ps_plog (const char *fmt, ...)
772{
773 va_list args;
774
775 va_start (args, fmt);
776
777 vfprintf_filtered (gdb_stderr, fmt, args);
778}
779
780ps_err_e
781ps_lgetxregsize (const struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize)
782{
783 int lwp_fd;
784 int regsize;
785 ps_err_e val;
786
787#if 0
788 val = get_lwp_fd (ph, lwpid, &lwp_fd);
789 if (val != PS_OK)
790 return val;
791
792 if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
793 {
794 if (errno == EINVAL)
795 return PS_NOFREGS; /* XXX Wrong code, but this is the closest
796 thing in proc_service.h */
797
798 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
799 return PS_ERR;
800 }
801#endif
802
803 return PS_OK;
804}
805
806ps_err_e
807ps_lgetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
808{
809 int lwp_fd;
810 ps_err_e val;
811
812#if 0
813 val = get_lwp_fd (ph, lwpid, &lwp_fd);
814 if (val != PS_OK)
815 return val;
816
817 if (ioctl (lwp_fd, PIOCGXREG, xregset))
818 {
819 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
820 return PS_ERR;
821 }
822#endif
823
824 return PS_OK;
825}
826
827ps_err_e
828ps_lsetxregs (const struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
829{
830 int lwp_fd;
831 ps_err_e val;
832
833#if 0
834 val = get_lwp_fd (ph, lwpid, &lwp_fd);
835 if (val != PS_OK)
836 return val;
837
838 if (ioctl (lwp_fd, PIOCSXREG, xregset))
839 {
840 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
841 return PS_ERR;
842 }
843#endif
844
845 return PS_OK;
846}
847
848ps_err_e
849ps_lgetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
850 prfpregset_t *fpregset)
851{
852 int save_pid;
853
854 save_pid = inferior_pid;
855
856 inferior_pid = (lwpid << 16) | (inferior_pid & 0xffff);
857
858 procfs_ops.to_fetch_registers (-1);
859 fill_fpregset (fpregset, -1);
860
861 inferior_pid = save_pid;
862
863 return PS_OK;
864}
865
866ps_err_e
867ps_lsetfpregs (const struct ps_prochandle *ph, lwpid_t lwpid,
868 const prfpregset_t *fpregset)
869{
870 int save_pid;
871
872 save_pid = inferior_pid;
873
874 inferior_pid = (lwpid << 16) | (inferior_pid & 0xffff);
875
876 supply_gregset (fpregset);
877 procfs_ops.to_store_registers (-1);
878
879 inferior_pid = save_pid;
880
881 return PS_OK;
882}
883\f
884char *
885solaris_pid_to_str (pid)
886 int pid;
887{
888 static char buf[100];
889
890 if (pid & 0x80000000)
891 {
892 int lwp;
893
894 lwp = thread_to_lwp (pid, -2);
895
896 if (lwp != -2)
897 sprintf (buf, "Thread %d (LWP %d)", (pid >> 16) & 0x7fff,
898 (lwp >> 16) & 0xffff);
899 else
900 sprintf (buf, "Thread %d ", (pid >> 16) & 0x7fff);
901 }
902 else
903 sprintf (buf, "LWP %d ", (pid >> 16) & 0xffff);
904
905 return buf;
906}
907\f
908struct target_ops sol_thread_ops = {
909 "solaris-threads", /* to_shortname */
910 "Solaris threads and pthread.", /* to_longname */
911 "Solaris threads and pthread support.", /* to_doc */
912 sol_thread_open, /* to_open */
913 0, /* to_close */
914 sol_thread_attach, /* to_attach */
915 sol_thread_detach, /* to_detach */
916 sol_thread_resume, /* to_resume */
917 sol_thread_wait, /* to_wait */
918 sol_thread_fetch_registers, /* to_fetch_registers */
919 sol_thread_store_registers, /* to_store_registers */
920 sol_thread_prepare_to_store, /* to_prepare_to_store */
921 sol_thread_xfer_memory, /* to_xfer_memory */
922 sol_thread_files_info, /* to_files_info */
923 memory_insert_breakpoint, /* to_insert_breakpoint */
924 memory_remove_breakpoint, /* to_remove_breakpoint */
925 terminal_init_inferior, /* to_terminal_init */
926 terminal_inferior, /* to_terminal_inferior */
927 terminal_ours_for_output, /* to_terminal_ours_for_output */
928 terminal_ours, /* to_terminal_ours */
929 child_terminal_info, /* to_terminal_info */
930 sol_thread_kill_inferior, /* to_kill */
931 0, /* to_load */
932 0, /* to_lookup_symbol */
933 sol_thread_create_inferior, /* to_create_inferior */
934 sol_thread_mourn_inferior, /* to_mourn_inferior */
935 sol_thread_can_run, /* to_can_run */
936 sol_thread_notice_signals, /* to_notice_signals */
937 sol_thread_alive, /* to_thread_alive */
938 sol_thread_stop, /* to_stop */
939 process_stratum, /* to_stratum */
940 0, /* to_next */
941 1, /* to_has_all_memory */
942 1, /* to_has_memory */
943 1, /* to_has_stack */
944 1, /* to_has_registers */
945 1, /* to_has_execution */
946 0, /* sections */
947 0, /* sections_end */
948 OPS_MAGIC /* to_magic */
949};
950
951void
952_initialize_sol_thread ()
953{
954 add_target (&sol_thread_ops);
955
956 procfs_suppress_run = 1;
957}
This page took 0.057423 seconds and 4 git commands to generate.