1 /* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
2 Copyright 1996 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 /* Undefine gregset_t and fpregset_t to avoid conflict with defs in xm file. */
33 #include <proc_service.h>
34 #include <thread_db.h>
35 #include "gdbthread.h"
42 extern struct target_ops sol_thread_ops
; /* Forward declaration */
44 extern int procfs_suppress_run
;
45 extern struct target_ops procfs_ops
; /* target vector for procfs.c */
47 extern void supply_gregset
PARAMS ((const prgregset_t
));
48 extern void fill_gregset
PARAMS ((prgregset_t
, int));
49 extern void supply_fpregset
PARAMS ((const prfpregset_t
));
50 extern void fill_fpregset
PARAMS ((prfpregset_t
, int));
63 static struct ps_prochandle main_ph
;
64 static td_thragent_t
*main_ta
;
65 static int sol_thread_active
= 0;
67 static struct cleanup
* save_inferior_pid
PARAMS ((void));
68 static void restore_inferior_pid
PARAMS ((int pid
));
69 static char *td_err_string
PARAMS ((td_err_e errcode
));
70 static char *td_state_string
PARAMS ((td_thr_state_e statecode
));
71 static int thread_to_lwp
PARAMS ((int thread_id
, int default_lwp
));
72 static void sol_thread_resume
PARAMS ((int pid
, int step
,
73 enum target_signal signo
));
74 static int lwp_to_thread
PARAMS ((int lwp
));
76 #define THREAD_FLAG 0x80000000
77 #define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0)
78 #define is_lwp(ARG) (((ARG) & THREAD_FLAG) == 0)
79 #define GET_LWP(LWP_ID) (TIDGET(LWP_ID))
80 #define GET_THREAD(THREAD_ID) (((THREAD_ID) >> 16) & 0x7fff)
81 #define BUILD_LWP(LWP_ID, PID) ((LWP_ID) << 16 | (PID))
82 #define BUILD_THREAD(THREAD_ID, PID) (THREAD_FLAG | BUILD_LWP (THREAD_ID, PID))
88 td_err_string - Convert a thread_db error code to a string
92 char * td_err_string (errcode)
96 Return the thread_db error string associated with errcode. If errcode
97 is unknown, then return a message.
102 td_err_string (errcode
)
105 static struct string_map
107 {TD_OK
, "generic \"call succeeded\""},
108 {TD_ERR
, "generic error."},
109 {TD_NOTHR
, "no thread can be found to satisfy query"},
110 {TD_NOSV
, "no synch. variable can be found to satisfy query"},
111 {TD_NOLWP
, "no lwp can be found to satisfy query"},
112 {TD_BADPH
, "invalid process handle"},
113 {TD_BADTH
, "invalid thread handle"},
114 {TD_BADSH
, "invalid synchronization handle"},
115 {TD_BADTA
, "invalid thread agent"},
116 {TD_BADKEY
, "invalid key"},
117 {TD_NOMSG
, "td_thr_event_getmsg() called when there was no message"},
118 {TD_NOFPREGS
, "FPU register set not available for given thread"},
119 {TD_NOLIBTHREAD
, "application not linked with libthread"},
120 {TD_NOEVENT
, "requested event is not supported"},
121 {TD_NOCAPAB
, "capability not available"},
122 {TD_DBERR
, "Debugger service failed"},
123 {TD_NOAPLIC
, "Operation not applicable to"},
124 {TD_NOTSD
, "No thread specific data for this thread"},
125 {TD_MALLOC
, "Malloc failed"},
126 {TD_PARTIALREG
, "Only part of register set was writen/read"},
127 {TD_NOXREGS
, "X register set not available for given thread"}
129 const int td_err_size
= sizeof td_err_table
/ sizeof (struct string_map
);
133 for (i
= 0; i
< td_err_size
; i
++)
134 if (td_err_table
[i
].num
== errcode
)
135 return td_err_table
[i
].str
;
137 sprintf (buf
, "Unknown thread_db error code: %d", errcode
);
146 td_state_string - Convert a thread_db state code to a string
150 char * td_state_string (statecode)
154 Return the thread_db state string associated with statecode. If
155 statecode is unknown, then return a message.
160 td_state_string (statecode
)
161 td_thr_state_e statecode
;
163 static struct string_map
164 td_thr_state_table
[] = {
165 {TD_THR_ANY_STATE
, "any state"},
166 {TD_THR_UNKNOWN
, "unknown"},
167 {TD_THR_STOPPED
, "stopped"},
169 {TD_THR_ACTIVE
, "active"},
170 {TD_THR_ZOMBIE
, "zombie"},
171 {TD_THR_SLEEP
, "sleep"},
172 {TD_THR_STOPPED_ASLEEP
, "stopped asleep"}
174 const int td_thr_state_table_size
= sizeof td_thr_state_table
/ sizeof (struct string_map
);
178 for (i
= 0; i
< td_thr_state_table_size
; i
++)
179 if (td_thr_state_table
[i
].num
== statecode
)
180 return td_thr_state_table
[i
].str
;
182 sprintf (buf
, "Unknown thread_db state code: %d", statecode
);
191 thread_to_lwp - Convert a Posix or Solaris thread id to a LWP id.
195 int thread_to_lwp (thread_id, default_lwp)
199 This function converts a Posix or Solaris thread id to a lightweight
200 process id. If thread_id is non-existent, that's an error. If it's
201 an inactive thread, then we return default_lwp.
205 This function probably shouldn't call error()...
210 thread_to_lwp (thread_id
, default_lwp
)
220 if (is_lwp (thread_id
))
221 return thread_id
; /* It's already an LWP id */
223 /* It's a thread. Convert to lwp */
225 pid
= PIDGET (thread_id
);
226 thread_id
= GET_THREAD(thread_id
);
228 val
= td_ta_map_id2thr (main_ta
, thread_id
, &th
);
230 error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val
));
232 val
= td_thr_get_info (&th
, &ti
);
235 error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val
));
237 if (ti
.ti_state
!= TD_THR_ACTIVE
)
239 if (default_lwp
!= -1)
241 error ("thread_to_lwp: thread state not active: %s",
242 td_state_string (ti
.ti_state
));
245 lwp
= BUILD_LWP (ti
.ti_lid
, pid
);
250 /* Convert an LWP id to a thread. */
263 return lwp
; /* It's already a thread id */
265 /* It's an lwp. Convert it to a thread id. */
270 val
= td_ta_map_lwp2thr (main_ta
, lwp
, &th
);
272 error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val
));
274 val
= td_thr_get_info (&th
, &ti
);
277 error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val
));
279 thread_id
= BUILD_THREAD (ti
.ti_tid
, pid
);
284 static struct cleanup
*
287 return make_cleanup (restore_inferior_pid
, inferior_pid
);
291 restore_inferior_pid (pid
)
299 sol_thread_open (arg
, from_tty
)
303 procfs_ops
.to_open (arg
, from_tty
);
306 /* Attach to process PID, then initialize for debugging it
307 and wait for the trace-trap that results from attaching. */
310 sol_thread_attach (args
, from_tty
)
314 procfs_ops
.to_attach (args
, from_tty
);
316 /* XXX - might want to iterate over all the threads and register them. */
319 /* Take a program previously attached to and detaches it.
320 The program resumes execution and will no longer stop
321 on signals, etc. We'd better not have left any breakpoints
322 in the program or it'll die when it hits one. For this
323 to work, it may be necessary for the process to have been
324 previously attached. It *might* work if the program was
325 started via the normal ptrace (PTRACE_TRACEME). */
328 sol_thread_detach (args
, from_tty
)
332 procfs_ops
.to_detach (args
, from_tty
);
335 /* Resume execution of process PID. If STEP is nozero, then
336 just single step it. If SIGNAL is nonzero, restart it with that
340 sol_thread_resume (pid
, step
, signo
)
343 enum target_signal signo
;
345 struct cleanup
*old_chain
;
347 old_chain
= save_inferior_pid ();
349 inferior_pid
= thread_to_lwp (inferior_pid
, main_ph
.pid
);
352 pid
= thread_to_lwp (pid
, -1);
354 procfs_ops
.to_resume (pid
, step
, signo
);
356 do_cleanups (old_chain
);
359 /* Wait for any LWPs to stop */
362 sol_thread_wait (pid
, ourstatus
)
364 struct target_waitstatus
*ourstatus
;
368 struct cleanup
*old_chain
;
370 if (!sol_thread_active
)
371 return procfs_ops
.to_wait (pid
, ourstatus
);
373 save_pid
= inferior_pid
;
374 old_chain
= save_inferior_pid ();
376 inferior_pid
= thread_to_lwp (inferior_pid
, main_ph
.pid
);
379 pid
= thread_to_lwp (pid
, -1);
381 rtnval
= procfs_ops
.to_wait (pid
, ourstatus
);
383 if (rtnval
!= save_pid
384 && !in_thread_list (rtnval
))
386 fprintf_unfiltered (gdb_stderr
, "[New %s]\n",
387 target_pid_to_str (rtnval
));
391 /* During process initialization, we may get here without the thread package
392 being initialized, since that can only happen after we've found the shared
395 /* Map the LWP of interest back to the appropriate thread ID */
397 rtnval
= lwp_to_thread (rtnval
);
399 do_cleanups (old_chain
);
405 sol_thread_fetch_registers (regno
)
409 td_thrhandle_t thandle
;
412 prfpregset_t fpregset
;
418 if (!sol_thread_active
419 || is_lwp (inferior_pid
))
421 procfs_ops
.to_fetch_registers (regno
);
425 /* Convert inferior_pid into a td_thrhandle_t */
427 thread
= GET_THREAD (inferior_pid
);
430 error ("sol_thread_fetch_registers: thread == 0");
432 val
= td_ta_map_id2thr (main_ta
, thread
, &thandle
);
434 error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s",
435 td_err_string (val
));
437 /* Get the integer regs */
439 val
= td_thr_getgregs (&thandle
, regset
);
441 supply_gregset (regset
);
442 else if (val
== TD_PARTIALREG
)
444 /* For the sparc, only i0->i7, l0->l7, pc and sp are saved by a thread
447 supply_gregset (regset
); /* This is not entirely correct, as it sets
448 the valid bits for the o, g, ps, y, npc,
449 wim and tbr. That should be harmless
450 though, as the context switch routine
451 doesn't need to save them. */
454 error ("sol_thread_fetch_registers: td_thr_getgregs %s",
455 td_err_string (val
));
457 /* And, now the fp regs */
459 val
= td_thr_getfpregs (&thandle
, &fpregset
);
461 supply_fpregset (fpregset
);
462 else if (val
!= TD_NOFPREGS
)
463 error ("sol_thread_fetch_registers: td_thr_getfpregs %s",
464 td_err_string (val
));
467 /* thread_db doesn't seem to handle this right */
468 val
= td_thr_getxregsize (&thandle
, &xregsize
);
469 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
470 error ("sol_thread_fetch_registers: td_thr_getxregsize %s",
471 td_err_string (val
));
475 xregset
= alloca (xregsize
);
476 val
= td_thr_getxregs (&thandle
, xregset
);
478 error ("sol_thread_fetch_registers: td_thr_getxregs %s",
479 td_err_string (val
));
485 sol_thread_store_registers (regno
)
489 td_thrhandle_t thandle
;
492 prfpregset_t fpregset
;
498 if (!sol_thread_active
499 || is_lwp (inferior_pid
))
501 procfs_ops
.to_store_registers (regno
);
505 /* Convert inferior_pid into a td_thrhandle_t */
507 thread
= GET_THREAD (inferior_pid
);
509 val
= td_ta_map_id2thr (main_ta
, thread
, &thandle
);
511 error ("sol_thread_store_registers: td_ta_map_id2thr %s",
512 td_err_string (val
));
515 { /* Not writing all the regs */
516 val
= td_thr_getgregs (&thandle
, regset
);
518 error ("sol_thread_store_registers: td_thr_getgregs %s",
519 td_err_string (val
));
520 val
= td_thr_getfpregs (&thandle
, &fpregset
);
522 error ("sol_thread_store_registers: td_thr_getfpregs %s",
523 td_err_string (val
));
526 /* thread_db doesn't seem to handle this right */
527 val
= td_thr_getxregsize (&thandle
, &xregsize
);
528 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
529 error ("sol_thread_store_registers: td_thr_getxregsize %s",
530 td_err_string (val
));
534 xregset
= alloca (xregsize
);
535 val
= td_thr_getxregs (&thandle
, xregset
);
537 error ("sol_thread_store_registers: td_thr_getxregs %s",
538 td_err_string (val
));
543 fill_gregset (regset
, regno
);
544 fill_fpregset (fpregset
, regno
);
546 val
= td_thr_setgregs (&thandle
, regset
);
548 error ("sol_thread_store_registers: td_thr_setgregs %s",
549 td_err_string (val
));
550 val
= td_thr_setfpregs (&thandle
, &fpregset
);
552 error ("sol_thread_store_registers: td_thr_setfpregs %s",
553 td_err_string (val
));
556 /* thread_db doesn't seem to handle this right */
557 val
= td_thr_getxregsize (&thandle
, &xregsize
);
558 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
559 error ("sol_thread_store_registers: td_thr_getxregsize %s",
560 td_err_string (val
));
562 /* Should probably do something about writing the xregs here, but what are
567 /* Get ready to modify the registers array. On machines which store
568 individual registers, this doesn't need to do anything. On machines
569 which store all the registers in one fell swoop, this makes sure
570 that registers contains all the registers from the program being
574 sol_thread_prepare_to_store ()
576 procfs_ops
.to_prepare_to_store ();
580 sol_thread_xfer_memory (memaddr
, myaddr
, len
, dowrite
, target
)
585 struct target_ops
*target
; /* ignored */
588 struct cleanup
*old_chain
;
590 old_chain
= save_inferior_pid ();
592 if (is_thread (inferior_pid
))
593 inferior_pid
= main_ph
.pid
; /* It's a thread. Convert to lwp */
595 retval
= procfs_ops
.to_xfer_memory (memaddr
, myaddr
, len
, dowrite
, target
);
597 do_cleanups (old_chain
);
602 /* Print status information about what we're accessing. */
605 sol_thread_files_info (ignore
)
606 struct target_ops
*ignore
;
608 procfs_ops
.to_files_info (ignore
);
612 sol_thread_kill_inferior ()
614 procfs_ops
.to_kill ();
618 sol_thread_notice_signals (pid
)
621 procfs_ops
.to_notice_signals (pid
);
624 void target_new_objfile
PARAMS ((struct objfile
*objfile
));
626 /* Fork an inferior process, and start debugging it with /proc. */
629 sol_thread_create_inferior (exec_file
, allargs
, env
)
634 procfs_ops
.to_create_inferior (exec_file
, allargs
, env
);
636 if (sol_thread_active
)
638 main_ph
.pid
= inferior_pid
; /* Save for xfer_memory */
640 push_target (&sol_thread_ops
);
642 inferior_pid
= lwp_to_thread (inferior_pid
);
644 add_thread (inferior_pid
);
648 /* This routine is called whenever a new symbol table is read in, or when all
649 symbol tables are removed. */
652 sol_thread_new_objfile (objfile
)
653 struct objfile
*objfile
;
659 sol_thread_active
= 0;
664 /* Now, initialize the thread debugging library. This needs to be done after
665 the shared libraries are located because it needs information from the
666 user's thread library. */
670 error ("target_new_objfile: td_init: %s", td_err_string (val
));
672 val
= td_ta_new (&main_ph
, &main_ta
);
673 if (val
== TD_NOLIBTHREAD
)
675 else if (val
!= TD_OK
)
676 error ("target_new_objfile: td_ta_new: %s", td_err_string (val
));
678 sol_thread_active
= 1;
681 /* Clean up after the inferior dies. */
684 sol_thread_mourn_inferior ()
686 procfs_ops
.to_mourn_inferior ();
689 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
691 sol_thread_can_run ()
693 return procfs_suppress_run
;
697 sol_thread_alive (pid
)
706 procfs_ops
.to_stop ();
709 /* Service routines we must supply to libthread_db */
713 struct lwp_map
*next
;
720 ps_pstop (const struct ps_prochandle
*ph
)
726 ps_pcontinue (const struct ps_prochandle
*ph
)
732 ps_lstop (const struct ps_prochandle
*ph
, lwpid_t lwpid
)
738 ps_lcontinue (const struct ps_prochandle
*ph
, lwpid_t lwpid
)
744 ps_pglobal_lookup (const struct ps_prochandle
*ph
, const char *ld_object_name
,
745 const char *ld_symbol_name
, paddr_t
*ld_symbol_addr
)
747 struct minimal_symbol
*ms
;
749 ms
= lookup_minimal_symbol (ld_symbol_name
, NULL
, NULL
);
754 *ld_symbol_addr
= SYMBOL_VALUE_ADDRESS (ms
);
760 rw_common (int dowrite
, const struct ps_prochandle
*ph
, paddr_t addr
,
763 struct cleanup
*old_chain
;
765 old_chain
= save_inferior_pid ();
767 if (is_thread (inferior_pid
))
768 inferior_pid
= main_ph
.pid
; /* It's a thread. Convert to lwp */
774 cc
= procfs_ops
.to_xfer_memory (addr
, buf
, size
, dowrite
, &procfs_ops
);
779 print_sys_errmsg ("ps_pdread (): read", errno
);
781 print_sys_errmsg ("ps_pdread (): write", errno
);
783 do_cleanups (old_chain
);
791 do_cleanups (old_chain
);
797 ps_pdread (const struct ps_prochandle
*ph
, paddr_t addr
, char *buf
, int size
)
799 return rw_common (0, ph
, addr
, buf
, size
);
803 ps_pdwrite (const struct ps_prochandle
*ph
, paddr_t addr
, char *buf
, int size
)
805 return rw_common (1, ph
, addr
, buf
, size
);
809 ps_ptread (const struct ps_prochandle
*ph
, paddr_t addr
, char *buf
, int size
)
811 return rw_common (0, ph
, addr
, buf
, size
);
815 ps_ptwrite (const struct ps_prochandle
*ph
, paddr_t addr
, char *buf
, int size
)
817 return rw_common (1, ph
, addr
, buf
, size
);
821 ps_lgetregs (const struct ps_prochandle
*ph
, lwpid_t lwpid
,
824 struct cleanup
*old_chain
;
826 old_chain
= save_inferior_pid ();
828 inferior_pid
= BUILD_LWP (lwpid
, PIDGET (inferior_pid
));
830 procfs_ops
.to_fetch_registers (-1);
831 fill_gregset (gregset
, -1);
833 do_cleanups (old_chain
);
839 ps_lsetregs (const struct ps_prochandle
*ph
, lwpid_t lwpid
,
840 const prgregset_t gregset
)
842 struct cleanup
*old_chain
;
844 old_chain
= save_inferior_pid ();
846 inferior_pid
= BUILD_LWP (lwpid
, PIDGET (inferior_pid
));
848 supply_gregset (gregset
);
849 procfs_ops
.to_store_registers (-1);
851 do_cleanups (old_chain
);
857 ps_plog (const char *fmt
, ...)
861 va_start (args
, fmt
);
863 vfprintf_filtered (gdb_stderr
, fmt
, args
);
867 ps_lgetxregsize (const struct ps_prochandle
*ph
, lwpid_t lwpid
, int *xregsize
)
874 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
878 if (ioctl (lwp_fd
, PIOCGXREGSIZE
, ®size
))
881 return PS_NOFREGS
; /* XXX Wrong code, but this is the closest
882 thing in proc_service.h */
884 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno
);
893 ps_lgetxregs (const struct ps_prochandle
*ph
, lwpid_t lwpid
, caddr_t xregset
)
899 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
903 if (ioctl (lwp_fd
, PIOCGXREG
, xregset
))
905 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno
);
914 ps_lsetxregs (const struct ps_prochandle
*ph
, lwpid_t lwpid
, caddr_t xregset
)
920 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
924 if (ioctl (lwp_fd
, PIOCSXREG
, xregset
))
926 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno
);
935 ps_lgetfpregs (const struct ps_prochandle
*ph
, lwpid_t lwpid
,
936 prfpregset_t
*fpregset
)
938 struct cleanup
*old_chain
;
940 old_chain
= save_inferior_pid ();
942 inferior_pid
= BUILD_LWP (lwpid
, PIDGET (inferior_pid
));
944 procfs_ops
.to_fetch_registers (-1);
945 fill_fpregset (*fpregset
, -1);
947 do_cleanups (old_chain
);
953 ps_lsetfpregs (const struct ps_prochandle
*ph
, lwpid_t lwpid
,
954 const prfpregset_t
*fpregset
)
956 struct cleanup
*old_chain
;
958 old_chain
= save_inferior_pid ();
960 inferior_pid
= BUILD_LWP (lwpid
, PIDGET (inferior_pid
));
962 supply_fpregset (*fpregset
);
963 procfs_ops
.to_store_registers (-1);
965 do_cleanups (old_chain
);
971 solaris_pid_to_str (pid
)
974 static char buf
[100];
980 lwp
= thread_to_lwp (pid
, -2);
983 sprintf (buf
, "Thread %d (LWP %d)", GET_THREAD (pid
), GET_LWP (lwp
));
985 sprintf (buf
, "Thread %d ", GET_THREAD (pid
));
988 sprintf (buf
, "LWP %d ", GET_LWP (pid
));
993 struct target_ops sol_thread_ops
= {
994 "solaris-threads", /* to_shortname */
995 "Solaris threads and pthread.", /* to_longname */
996 "Solaris threads and pthread support.", /* to_doc */
997 sol_thread_open
, /* to_open */
999 sol_thread_attach
, /* to_attach */
1000 sol_thread_detach
, /* to_detach */
1001 sol_thread_resume
, /* to_resume */
1002 sol_thread_wait
, /* to_wait */
1003 sol_thread_fetch_registers
, /* to_fetch_registers */
1004 sol_thread_store_registers
, /* to_store_registers */
1005 sol_thread_prepare_to_store
, /* to_prepare_to_store */
1006 sol_thread_xfer_memory
, /* to_xfer_memory */
1007 sol_thread_files_info
, /* to_files_info */
1008 memory_insert_breakpoint
, /* to_insert_breakpoint */
1009 memory_remove_breakpoint
, /* to_remove_breakpoint */
1010 terminal_init_inferior
, /* to_terminal_init */
1011 terminal_inferior
, /* to_terminal_inferior */
1012 terminal_ours_for_output
, /* to_terminal_ours_for_output */
1013 terminal_ours
, /* to_terminal_ours */
1014 child_terminal_info
, /* to_terminal_info */
1015 sol_thread_kill_inferior
, /* to_kill */
1017 0, /* to_lookup_symbol */
1018 sol_thread_create_inferior
, /* to_create_inferior */
1019 sol_thread_mourn_inferior
, /* to_mourn_inferior */
1020 sol_thread_can_run
, /* to_can_run */
1021 sol_thread_notice_signals
, /* to_notice_signals */
1022 sol_thread_alive
, /* to_thread_alive */
1023 sol_thread_stop
, /* to_stop */
1024 process_stratum
, /* to_stratum */
1026 1, /* to_has_all_memory */
1027 1, /* to_has_memory */
1028 1, /* to_has_stack */
1029 1, /* to_has_registers */
1030 1, /* to_has_execution */
1032 0, /* sections_end */
1033 OPS_MAGIC
/* to_magic */
1037 _initialize_sol_thread ()
1039 add_target (&sol_thread_ops
);
1041 procfs_suppress_run
= 1;