X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Ffbsd-nat.h;h=7016cc0242aecee255e07c2154a7e17b3243db0f;hb=038805cf977f130d343704c10c7873b556daa314;hp=edb05f883773919733494bbd325d9b48168b3cf1;hpb=3666a04883754298b03884222206bfe756fbc520;p=binutils-gdb.git diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h index edb05f88377..7016cc0242a 100644 --- a/gdb/fbsd-nat.h +++ b/gdb/fbsd-nat.h @@ -1,6 +1,6 @@ /* Native-dependent code for FreeBSD. - Copyright (C) 2004-2021 Free Software Foundation, Inc. + Copyright (C) 2004-2023 Free Software Foundation, Inc. This file is part of GDB. @@ -20,10 +20,15 @@ #ifndef FBSD_NAT_H #define FBSD_NAT_H +#include "gdbsupport/gdb_optional.h" #include "inf-ptrace.h" +#include "regcache.h" +#include "regset.h" #include #include +#include + /* FreeBSD kernels 11.3 and later report valid si_code values for SIGTRAP on all architectures. Older FreeBSD kernels that supported TRAP_BRKPT did not report valid values for MIPS and sparc64. Even @@ -42,7 +47,7 @@ class fbsd_nat_target : public inf_ptrace_target { public: - char *pid_to_exec_file (int pid) override; + const char *pid_to_exec_file (int pid) override; int find_memory_regions (find_memory_region_ftype func, void *data) override; @@ -64,14 +69,28 @@ public: void update_thread_list () override; + bool can_async_p () override; + + void async (bool) override; + thread_control_capabilities get_thread_control_capabilities () override { return tc_schedlock; } + void create_inferior (const char *, const std::string &, + char **, int) override; + + void attach (const char *, int) override; + + void detach (inferior *, int) override; + + void kill () override; + + void mourn_inferior () override; + void resume (ptid_t, int, enum gdb_signal) override; ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override; - void post_startup_inferior (ptid_t) override; void post_attach (int) override; #ifdef USE_SIGTRAP_SIGINFO @@ -79,8 +98,10 @@ public: bool stopped_by_sw_breakpoint () override; #endif + void follow_exec (inferior *, ptid_t, const char *) override; + #ifdef TDP_RFPPWAIT - bool follow_fork (bool, bool) override; + void follow_fork (inferior *, ptid_t, target_waitkind, bool, bool) override; int insert_fork_catchpoint (int) override; int remove_fork_catchpoint (int) override; @@ -98,6 +119,170 @@ public: #endif bool supports_multi_process () override; + + bool supports_disable_randomization () override; + + /* Methods meant to be overridden by arch-specific target + classes. */ + + virtual void low_new_fork (ptid_t parent, pid_t child) + {} + + /* The method to call, if any, when a thread is destroyed. */ + virtual void low_delete_thread (thread_info *) + {} + + /* Hook to call prior to resuming a thread. */ + virtual void low_prepare_to_resume (thread_info *) + {} + +protected: + + void post_startup_inferior (ptid_t) override; + +private: + ptid_t wait_1 (ptid_t, struct target_waitstatus *, target_wait_flags); + + void resume_one_process (ptid_t, int, enum gdb_signal); + + void stop_process (inferior *); + + /* Helper routines for use in fetch_registers and store_registers in + subclasses. These routines fetch and store a single set of + registers described by REGSET. The REGSET's 'regmap' field must + point to an array of 'struct regcache_map_entry'. The valid + register numbers in the register map are relative to REGBASE. + + FETCH_OP is a ptrace operation to fetch the set of registers from + a native thread. STORE_OP is a ptrace operation to store the set + of registers to a native thread. + + The caller must provide storage for the set of registers in REGS, + and SIZE is the size of the storage. + + Returns true if the register set was transferred due to a + matching REGNUM. */ + + bool fetch_register_set (struct regcache *regcache, int regnum, int fetch_op, + const struct regset *regset, int regbase, void *regs, + size_t size); + + bool store_register_set (struct regcache *regcache, int regnum, int fetch_op, + int store_op, const struct regset *regset, + int regbase, void *regs, size_t size); + + /* Helper routines which use PT_GETREGSET and PT_SETREGSET for the + specified NOTE instead of regset-specific fetch and store + ops. */ + + bool fetch_regset (struct regcache *regcache, int regnum, int note, + const struct regset *regset, int regbase, void *regs, + size_t size); + + bool store_regset (struct regcache *regcache, int regnum, int note, + const struct regset *regset, int regbase, void *regs, + size_t size); + +protected: + /* Wrapper versions of the above helpers which accept a register set + type such as 'struct reg' or 'struct fpreg'. */ + + template + bool fetch_register_set (struct regcache *regcache, int regnum, int fetch_op, + const struct regset *regset, int regbase = 0) + { + Regset regs; + return fetch_register_set (regcache, regnum, fetch_op, regset, regbase, + ®s, sizeof (regs)); + } + + template + bool store_register_set (struct regcache *regcache, int regnum, int fetch_op, + int store_op, const struct regset *regset, + int regbase = 0) + { + Regset regs; + return store_register_set (regcache, regnum, fetch_op, store_op, regset, + regbase, ®s, sizeof (regs)); + } + + /* Helper routine for use in read_description in subclasses. This + routine checks if the register set for the specified NOTE is + present for a given PTID. If the register set is present, the + the size of the register set is returned. If the register set is + not present, zero is returned. */ + + size_t have_regset (ptid_t ptid, int note); + + /* Wrapper versions of the PT_GETREGSET and PT_REGSET helpers which + accept a register set type. */ + + template + bool fetch_regset (struct regcache *regcache, int regnum, int note, + const struct regset *regset, int regbase = 0) + { + Regset regs; + return fetch_regset (regcache, regnum, note, regset, regbase, ®s, + sizeof (regs)); + } + + template + bool store_regset (struct regcache *regcache, int regnum, int note, + const struct regset *regset, int regbase = 0) + { + Regset regs; + return store_regset (regcache, regnum, note, regset, regbase, ®s, + sizeof (regs)); + } + +private: + /* If an event is triggered asynchronously (fake vfork_done events) + or occurs when the core is not expecting it, a pending event is + created. This event is then returned by a future call to the + target wait method. */ + + struct pending_event + { + pending_event (const ptid_t &_ptid, const target_waitstatus &_status) : + ptid (_ptid), status (_status) {} + + ptid_t ptid; + target_waitstatus status; + }; + + /* Add a new pending event to the list. */ + + void add_pending_event (const ptid_t &ptid, const target_waitstatus &status); + + /* Return true if there is a pending event matching FILTER. */ + + bool have_pending_event (ptid_t filter); + + /* Check if there is a pending event for a resumed process matching + FILTER. If there is a matching event, the event is removed from + the pending list and returned. */ + + gdb::optional take_pending_event (ptid_t filter); + + /* List of pending events. */ + + std::list m_pending_events; + + /* If this thread has a pending fork event, there is a child process + GDB is attached to that the core of GDB doesn't know about. + Detach from it. */ + + void detach_fork_children (thread_info *tp); + + /* Detach from any child processes associated with pending fork events + for a stopped process. Returns true if the process has terminated + and false if it is still alive. */ + + bool detach_fork_children (inferior *inf); }; +/* Fetch the signal information for PTID and store it in *SIGINFO. + Return true if successful. */ +bool fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo); + #endif /* fbsd-nat.h */