29 #include <sys/types.h> 30 #include <sys/procfs.h> 31 #include <sys/ptrace.h> 32 #include <sys/signal.h> 33 #include <sys/sysctl.h> 35 #ifdef HAVE_KINFO_GETVMMAP 53 static char buf[PATH_MAX];
56 #ifdef KERN_PROC_PATHNAME 62 mib[2] = KERN_PROC_PATHNAME;
65 if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
70 len = readlink (
name, buf, PATH_MAX - 1);
80 #ifdef HAVE_KINFO_GETVMMAP 86 void operator() (T *ptr)
const {
free (ptr); }
98 struct kinfo_vmentry *kve;
102 std::unique_ptr<struct kinfo_vmentry, free_deleter<struct kinfo_vmentry>>
103 vmentl (kinfo_getvmmap (
pid, &nitems));
107 for (i = 0, kve = vmentl.get (); i < nitems; i++, kve++)
110 if (!(kve->kve_protection & KVME_PROT_READ)
111 || kve->kve_flags & KVME_FLAG_NOCOREDUMP)
115 if (kve->kve_type != KVME_TYPE_DEFAULT
116 && kve->kve_type != KVME_TYPE_VNODE
117 && kve->kve_type != KVME_TYPE_SWAP
118 && kve->kve_type != KVME_TYPE_PHYS)
121 size = kve->kve_end - kve->kve_start;
125 "Save segment, %ld bytes at %s (%c%c%c)\n",
128 kve->kve_protection & KVME_PROT_READ ?
'r' :
'-',
129 kve->kve_protection & KVME_PROT_WRITE ?
'w' :
'-',
130 kve->kve_protection & KVME_PROT_EXEC ?
'x' :
'-');
135 func (kve->kve_start,
size, kve->kve_protection & KVME_PROT_READ,
136 kve->kve_protection & KVME_PROT_WRITE,
137 kve->kve_protection & KVME_PROT_EXEC, 1, obfd);
148 int resident, privateresident;
156 if (fgets (buf,
sizeof buf, mapfile) != NULL)
157 ret = sscanf (buf,
"%lx %lx %d %d %lx %s", start, end,
158 &resident, &privateresident, &obj, protection);
160 return (ret != 0 && ret != EOF);
172 unsigned long start, end,
size;
174 int read, write, exec;
177 gdb_file_up mapfile (fopen (mapfilename.c_str (),
"r"));
179 error (
_(
"Couldn't open %s."), mapfilename.c_str ());
183 "Reading memory regions from %s\n", mapfilename.c_str ());
190 read = (strchr (protection,
'r') != 0);
191 write = (strchr (protection,
'w') != 0);
192 exec = (strchr (protection,
'x') != 0);
197 "Save segment, %ld bytes at %s (%c%c%c)\n",
213 #ifdef KERN_PROC_AUXV 246 union sigval32 si_value;
283 return sizeof (
struct siginfo32);
285 return sizeof (siginfo_t);
293 fbsd_convert_siginfo (siginfo_t *si)
302 struct siginfo32 si32;
304 si32.si_signo = si->si_signo;
305 si32.si_errno = si->si_errno;
306 si32.si_code = si->si_code;
307 si32.si_pid = si->si_pid;
308 si32.si_uid = si->si_uid;
309 si32.si_status = si->si_status;
310 si32.si_addr = (uintptr_t) si->si_addr;
315 #
if _BYTE_ORDER == _BIG_ENDIAN
316 if (si->si_value.sival_int == 0)
317 si32.si_value.sival_ptr = (uintptr_t) si->si_value.sival_ptr;
319 si32.si_value.sival_int = si->si_value.sival_int;
321 si32.si_value.sival_int = si->si_value.sival_int;
326 si32._reason.__spare__.__spare1__ = si->_reason.__spare__.__spare1__;
327 for (
int i = 0; i < 7; i++)
328 si32._reason.__spare__.__spare2__[i] = si->_reason.__spare__.__spare2__[i];
329 switch (si->si_signo) {
334 si32.si_trapno = si->si_trapno;
337 switch (si->si_code) {
339 si32.si_timerid = si->si_timerid;
340 si32.si_overrun = si->si_overrun;
343 si32.si_mqd = si->si_mqd;
347 memcpy(si, &si32,
sizeof (si32));
356 const char *annex,
gdb_byte *readbuf,
367 struct ptrace_lwpinfo pl;
371 if (writebuf != NULL)
377 siginfo_size = fbsd_siginfo_size ();
378 if (
offset > siginfo_size)
387 fbsd_convert_siginfo (&pl.pl_siginfo);
388 if (
offset + len > siginfo_size)
389 len = siginfo_size -
offset;
403 if (writebuf != NULL)
407 mib[2] = KERN_PROC_AUXV;
417 buf_storage.resize (buflen);
418 buf = buf_storage.data ();
420 if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
427 memcpy (readbuf, buf +
offset, buflen);
432 *xfered_len = buflen;
445 static int debug_fbsd_lwp;
447 static void (*super_resume) (
struct target_ops *,
457 show_fbsd_lwp_debug (
struct ui_file *file,
int from_tty,
463 #if defined(TDP_RFPPWAIT) || defined(HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME) 468 fbsd_fetch_kinfo_proc (pid_t
pid,
struct kinfo_proc *kp)
476 mib[2] = KERN_PROC_PID;
478 if (sysctl (mib, 4, kp, &len, NULL, 0) == -1)
517 struct ptrace_lwpinfo pl;
522 #ifdef PL_FLAG_EXITED 523 if (pl.pl_flags & PL_FLAG_EXITED)
552 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME 559 struct ptrace_lwpinfo pl;
560 struct kinfo_proc kp;
563 static char buf[
sizeof pl.pl_tdname + 1];
568 fbsd_fetch_kinfo_proc (
pid, &kp);
569 if (
ptrace (PT_LWPINFO,
lwp, (caddr_t) &pl,
sizeof pl) == -1)
571 if (strcmp (kp.ki_comm, pl.pl_tdname) == 0)
573 xsnprintf (buf,
sizeof buf,
"%s", pl.pl_tdname);
592 fbsd_enable_proc_events (pid_t
pid)
594 #ifdef PT_GET_EVENT_MASK 598 sizeof (events)) == -1)
600 events |= PTRACE_FORK | PTRACE_LWP;
602 events |= PTRACE_VFORK;
605 sizeof (events)) == -1)
626 fbsd_add_threads (pid_t
pid)
631 nlwps =
ptrace (PT_GETNUMLWPS,
pid, NULL, 0);
637 nlwps =
ptrace (PT_GETLWPLIST,
pid, (caddr_t) lwps.get (), nlwps);
641 for (i = 0; i < nlwps; i++)
648 struct ptrace_lwpinfo pl;
652 if (
ptrace (PT_LWPINFO, lwps[i], (caddr_t) &pl,
sizeof pl) == -1)
654 if (pl.pl_flags & PL_FLAG_EXITED)
659 "FLWP: adding thread for LWP %u\n",
669 fbsd_update_thread_list (
struct target_ops *ops)
716 static std::list<ptid_t> fbsd_pending_children;
724 fbsd_pending_children.push_front (
pid);
731 fbsd_is_child_pending (pid_t
pid)
733 for (
auto it = fbsd_pending_children.begin ();
734 it != fbsd_pending_children.end (); it++)
735 if (it->pid () ==
pid)
738 fbsd_pending_children.erase (it);
745 static std::forward_list<ptid_t> fbsd_pending_vfork_done;
752 fbsd_pending_vfork_done.push_front (
pid);
758 fbsd_is_vfork_done_pending (pid_t
pid)
760 for (
auto it = fbsd_pending_vfork_done.begin ();
761 it != fbsd_pending_vfork_done.end (); it++)
762 if (it->pid () ==
pid)
771 fbsd_next_vfork_done (
void)
773 if (!fbsd_pending_vfork_done.empty ())
775 ptid_t ptid = fbsd_pending_vfork_done.front ();
776 fbsd_pending_vfork_done.pop_front ();
788 ptid_t ptid,
int step,
enum gdb_signal signo)
790 #if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK) 798 if (fbsd_is_vfork_done_pending (
pid))
804 "FLWP: fbsd_resume for ptid (%d, %ld, %ld)\n",
821 request = PT_SUSPEND;
843 super_resume (ops,
ptid, step, signo);
860 wptid = fbsd_next_vfork_done ();
867 wptid = super_wait (ops,
ptid, ourstatus, target_options);
870 struct ptrace_lwpinfo pl;
875 if (
ptrace (PT_LWPINFO,
pid, (caddr_t) &pl,
sizeof pl) == -1)
881 if (pl.pl_flags & PL_FLAG_EXITED)
891 "FLWP: deleting thread for LWP %u\n",
914 "FLWP: using LWP %u for first thread\n",
920 if (pl.pl_flags & PL_FLAG_BORN)
930 "FLWP: adding thread for LWP %u\n",
940 if (pl.pl_flags & PL_FLAG_FORKED)
943 struct kinfo_proc kp;
948 child = pl.pl_child_pid;
951 if (pl.pl_flags & PL_FLAG_VFORKED)
956 child_ptid = fbsd_is_child_pending (child);
965 if (
ptrace (PT_LWPINFO, child, (caddr_t)&pl,
sizeof pl) == -1)
969 child_ptid =
ptid_build (child, pl.pl_lwpid, 0);
978 fbsd_fetch_kinfo_proc (child, &kp);
979 if (kp.ki_flag & P_PPWAIT)
987 if (pl.pl_flags & PL_FLAG_CHILD)
992 fbsd_remember_child (wptid);
997 if (pl.pl_flags & PL_FLAG_VFORK_DONE)
1006 if (pl.pl_flags & PL_FLAG_EXEC)
1022 if (pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)
1023 && ourstatus->
value.
sig == SIGTRAP)
1025 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE 1030 if (pl.pl_flags & PL_FLAG_SCE)
1058 fbsd_follow_fork (
struct target_ops *ops,
int follow_child,
1072 #ifndef PTRACE_VFORK 1106 fbsd_insert_fork_catchpoint (
struct target_ops *
self,
int pid)
1112 fbsd_remove_fork_catchpoint (
struct target_ops *
self,
int pid)
1118 fbsd_insert_vfork_catchpoint (
struct target_ops *
self,
int pid)
1124 fbsd_remove_vfork_catchpoint (
struct target_ops *
self,
int pid)
1143 fbsd_enable_proc_events (
pid);
1144 fbsd_add_threads (
pid);
1152 fbsd_insert_exec_catchpoint (
struct target_ops *
self,
int pid)
1158 fbsd_remove_exec_catchpoint (
struct target_ops *
self,
int pid)
1164 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE 1166 fbsd_set_syscall_catchpoint (
struct target_ops *
self,
int pid,
bool needed,
1184 #ifdef KERN_PROC_AUXV 1191 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME 1213 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE 1225 &debug_fbsd_lwp,
_(
"\ 1226 Set debugging of FreeBSD lwp module."),
_(
"\ 1227 Show debugging of FreeBSD lwp module."),
_(
"\ 1228 Enables printf debugging output."),
1230 &show_fbsd_lwp_debug,
struct gdbarch * target_gdbarch(void)
void add_target(struct target_ops *t)
ssize_t read(int fd, void *buf, size_t count)
static int fbsd_find_memory_regions(struct target_ops *self, find_memory_region_ftype func, void *obfd)
constexpr long lwp() const
struct thread_info * add_thread(ptid_t ptid)
int catch_syscall_enabled(void)
static target_xfer_partial_ftype * super_xfer_partial
struct frame_info * get_current_frame(void)
int(* to_find_memory_regions)(struct target_ops *, find_memory_region_ftype func, void *data) TARGET_DEFAULT_FUNC(dummy_find_memory_regions)
int ptid_get_pid(const ptid_t &ptid)
void delete_thread(ptid_t)
void fbsd_nat_add_target(struct target_ops *t)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
int(* to_follow_fork)(struct target_ops *, int, int) TARGET_DEFAULT_FUNC(default_follow_fork)
struct thread_info * inferior_thread(void)
int(* to_set_syscall_catchpoint)(struct target_ops *, int, bool, int, gdb::array_view< const int >) TARGET_DEFAULT_RETURN(1)
const char *(* to_pid_to_str)(struct target_ops *, ptid_t) TARGET_DEFAULT_FUNC(default_pid_to_str)
union target_waitstatus::@174 value
int gdbarch_long_bit(struct gdbarch *gdbarch)
const char * paddress(struct gdbarch *gdbarch, CORE_ADDR addr)
int(* to_remove_exec_catchpoint)(struct target_ops *, int) TARGET_DEFAULT_RETURN(1)
ptid_t ptid_build(int pid, long lwp, long tid)
const char * normal_pid_to_str(ptid_t ptid)
int in_thread_list(ptid_t ptid)
int(* to_remove_fork_catchpoint)(struct target_ops *, int) TARGET_DEFAULT_RETURN(1)
std::unique_ptr< FILE, gdb_file_deleter > gdb_file_up
std::unique_ptr< T, xfree_deleter< T > > unique_xmalloc_ptr
void fprintf_filtered(struct ui_file *stream, const char *format,...)
long ptid_get_tid(const ptid_t &ptid)
int(* to_remove_vfork_catchpoint)(struct target_ops *, int) TARGET_DEFAULT_RETURN(1)
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
void(* to_resume)(struct target_ops *, ptid_t, int TARGET_DEBUG_PRINTER(target_debug_print_step), enum gdb_signal) TARGET_DEFAULT_NORETURN(noprocess())
ptid_t pid_to_ptid(int pid)
int(* to_insert_exec_catchpoint)(struct target_ops *, int) TARGET_DEFAULT_RETURN(1)
int catching_syscall_number(int syscall_number)
struct target_waitstatus pending_follow
void thread_change_ptid(ptid_t old_ptid, ptid_t new_ptid)
int(* to_insert_fork_catchpoint)(struct target_ops *, int) TARGET_DEFAULT_RETURN(1)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
enum target_xfer_status(* to_xfer_partial)(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) TARGET_DEFAULT_RETURN(TARGET_XFER_E_IO)
void printf_unfiltered(const char *format,...)
struct cmd_list_element * setdebuglist
static char * fbsd_pid_to_exec_file(struct target_ops *self, int pid)
long ptid_get_lwp(const ptid_t &ptid)
char *(* to_pid_to_exec_file)(struct target_ops *, int pid) TARGET_DEFAULT_RETURN(NULL)
int ptid_lwp_p(const ptid_t &ptid)
static int fbsd_read_mapping(FILE *mapfile, unsigned long *start, unsigned long *end, char *protection)
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
#define ALL_NON_EXITED_THREADS(T)
int xsnprintf(char *str, size_t size, const char *format,...)
enum target_waitkind kind
constexpr bool lwp_p() const
const char * target_pid_to_str(ptid_t ptid)
void add_setshow_boolean_cmd(const char *name, enum command_class theclass, int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_const_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
void(* to_post_attach)(struct target_ops *, int) TARGET_DEFAULT_IGNORE()
static constexpr ptid_t lwp
void _initialize_fbsd_nat(void)
std::string string_printf(const char *fmt,...)
int ptid_equal(const ptid_t &ptid1, const ptid_t &ptid2)
gdb::def_vector< gdb_byte > byte_vector
void delete_exited_threads(void)
int ptid_match(const ptid_t &ptid, const ptid_t &filter)
unsigned long long ULONGEST
struct cmd_list_element * showdebuglist
int(* to_insert_vfork_catchpoint)(struct target_ops *, int) TARGET_DEFAULT_RETURN(1)
int to_has_thread_control
int(* to_thread_alive)(struct target_ops *, ptid_t ptid) TARGET_DEFAULT_RETURN(0)
void(* to_update_thread_list)(struct target_ops *) TARGET_DEFAULT_IGNORE()
int(* find_memory_region_ftype)(CORE_ADDR addr, unsigned long size, int read, int write, int exec, int modified, void *data)
ptid_t(* to_wait)(struct target_ops *, ptid_t, struct target_waitstatus *, int TARGET_DEBUG_PRINTER(target_debug_print_options)) TARGET_DEFAULT_FUNC(default_target_wait)
void error(const char *fmt,...)
const char *(* to_thread_name)(struct target_ops *, struct thread_info *) TARGET_DEFAULT_RETURN(NULL)
struct gdbarch * get_frame_arch(struct frame_info *this_frame)
void(* to_post_startup_inferior)(struct target_ops *, ptid_t) TARGET_DEFAULT_IGNORE()