1 1.1 christos /* Native-dependent code for FreeBSD. 2 1.1 christos 3 1.11 christos Copyright (C) 2004-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.12 christos #ifndef GDB_FBSD_NAT_H 21 1.12 christos #define GDB_FBSD_NAT_H 22 1.1 christos 23 1.11 christos #include <optional> 24 1.8 christos #include "inf-ptrace.h" 25 1.10 christos #include "regcache.h" 26 1.10 christos #include "regset.h" 27 1.9 christos #include <osreldate.h> 28 1.8 christos #include <sys/proc.h> 29 1.8 christos 30 1.11 christos #include <list> 31 1.11 christos 32 1.9 christos /* FreeBSD kernels 11.3 and later report valid si_code values for 33 1.9 christos SIGTRAP on all architectures. Older FreeBSD kernels that supported 34 1.9 christos TRAP_BRKPT did not report valid values for MIPS and sparc64. Even 35 1.9 christos older kernels without TRAP_BRKPT support did not report valid 36 1.9 christos values on any architecture. */ 37 1.9 christos #if (__FreeBSD_kernel_version >= 1102502) || (__FreeBSD_version >= 1102502) 38 1.9 christos # define USE_SIGTRAP_SIGINFO 39 1.9 christos #elif defined(TRAP_BRKPT) 40 1.8 christos # if !defined(__mips__) && !defined(__sparc64__) 41 1.8 christos # define USE_SIGTRAP_SIGINFO 42 1.8 christos # endif 43 1.8 christos #endif 44 1.8 christos 45 1.8 christos /* A prototype FreeBSD target. */ 46 1.8 christos 47 1.8 christos class fbsd_nat_target : public inf_ptrace_target 48 1.8 christos { 49 1.8 christos public: 50 1.10 christos const char *pid_to_exec_file (int pid) override; 51 1.8 christos 52 1.8 christos int find_memory_regions (find_memory_region_ftype func, void *data) override; 53 1.8 christos 54 1.8 christos bool info_proc (const char *, enum info_proc_what) override; 55 1.8 christos 56 1.8 christos enum target_xfer_status xfer_partial (enum target_object object, 57 1.8 christos const char *annex, 58 1.8 christos gdb_byte *readbuf, 59 1.8 christos const gdb_byte *writebuf, 60 1.8 christos ULONGEST offset, ULONGEST len, 61 1.8 christos ULONGEST *xfered_len) override; 62 1.8 christos 63 1.8 christos bool thread_alive (ptid_t ptid) override; 64 1.9 christos std::string pid_to_str (ptid_t) override; 65 1.8 christos 66 1.8 christos #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME 67 1.8 christos const char *thread_name (struct thread_info *) override; 68 1.8 christos #endif 69 1.8 christos 70 1.8 christos void update_thread_list () override; 71 1.8 christos 72 1.10 christos bool can_async_p () override; 73 1.10 christos 74 1.10 christos void async (bool) override; 75 1.10 christos 76 1.8 christos thread_control_capabilities get_thread_control_capabilities () override 77 1.8 christos { return tc_schedlock; } 78 1.8 christos 79 1.10 christos void create_inferior (const char *, const std::string &, 80 1.10 christos char **, int) override; 81 1.10 christos 82 1.11 christos void attach (const char *, int) override; 83 1.11 christos 84 1.11 christos void detach (inferior *, int) override; 85 1.11 christos 86 1.11 christos void kill () override; 87 1.11 christos 88 1.11 christos void mourn_inferior () override; 89 1.11 christos 90 1.8 christos void resume (ptid_t, int, enum gdb_signal) override; 91 1.8 christos 92 1.10 christos ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override; 93 1.8 christos 94 1.8 christos void post_attach (int) override; 95 1.8 christos 96 1.8 christos #ifdef USE_SIGTRAP_SIGINFO 97 1.8 christos bool supports_stopped_by_sw_breakpoint () override; 98 1.8 christos bool stopped_by_sw_breakpoint () override; 99 1.8 christos #endif 100 1.8 christos 101 1.11 christos void follow_exec (inferior *, ptid_t, const char *) override; 102 1.11 christos 103 1.8 christos #ifdef TDP_RFPPWAIT 104 1.10 christos void follow_fork (inferior *, ptid_t, target_waitkind, bool, bool) override; 105 1.8 christos 106 1.8 christos int insert_fork_catchpoint (int) override; 107 1.8 christos int remove_fork_catchpoint (int) override; 108 1.8 christos 109 1.8 christos int insert_vfork_catchpoint (int) override; 110 1.8 christos int remove_vfork_catchpoint (int) override; 111 1.8 christos #endif 112 1.8 christos 113 1.8 christos int insert_exec_catchpoint (int) override; 114 1.8 christos int remove_exec_catchpoint (int) override; 115 1.8 christos 116 1.8 christos #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE 117 1.8 christos int set_syscall_catchpoint (int, bool, int, gdb::array_view<const int>) 118 1.8 christos override; 119 1.8 christos #endif 120 1.9 christos 121 1.9 christos bool supports_multi_process () override; 122 1.10 christos 123 1.10 christos bool supports_disable_randomization () override; 124 1.10 christos 125 1.10 christos /* Methods meant to be overridden by arch-specific target 126 1.10 christos classes. */ 127 1.10 christos 128 1.10 christos virtual void low_new_fork (ptid_t parent, pid_t child) 129 1.10 christos {} 130 1.10 christos 131 1.10 christos /* The method to call, if any, when a thread is destroyed. */ 132 1.10 christos virtual void low_delete_thread (thread_info *) 133 1.10 christos {} 134 1.10 christos 135 1.10 christos /* Hook to call prior to resuming a thread. */ 136 1.10 christos virtual void low_prepare_to_resume (thread_info *) 137 1.10 christos {} 138 1.10 christos 139 1.10 christos protected: 140 1.10 christos 141 1.10 christos void post_startup_inferior (ptid_t) override; 142 1.10 christos 143 1.10 christos private: 144 1.10 christos ptid_t wait_1 (ptid_t, struct target_waitstatus *, target_wait_flags); 145 1.10 christos 146 1.11 christos void resume_one_process (ptid_t, int, enum gdb_signal); 147 1.11 christos 148 1.11 christos void stop_process (inferior *); 149 1.11 christos 150 1.10 christos /* Helper routines for use in fetch_registers and store_registers in 151 1.10 christos subclasses. These routines fetch and store a single set of 152 1.10 christos registers described by REGSET. The REGSET's 'regmap' field must 153 1.10 christos point to an array of 'struct regcache_map_entry'. The valid 154 1.10 christos register numbers in the register map are relative to REGBASE. 155 1.10 christos 156 1.10 christos FETCH_OP is a ptrace operation to fetch the set of registers from 157 1.10 christos a native thread. STORE_OP is a ptrace operation to store the set 158 1.10 christos of registers to a native thread. 159 1.10 christos 160 1.10 christos The caller must provide storage for the set of registers in REGS, 161 1.10 christos and SIZE is the size of the storage. 162 1.10 christos 163 1.10 christos Returns true if the register set was transferred due to a 164 1.10 christos matching REGNUM. */ 165 1.10 christos 166 1.10 christos bool fetch_register_set (struct regcache *regcache, int regnum, int fetch_op, 167 1.10 christos const struct regset *regset, int regbase, void *regs, 168 1.10 christos size_t size); 169 1.10 christos 170 1.10 christos bool store_register_set (struct regcache *regcache, int regnum, int fetch_op, 171 1.10 christos int store_op, const struct regset *regset, 172 1.10 christos int regbase, void *regs, size_t size); 173 1.10 christos 174 1.10 christos /* Helper routines which use PT_GETREGSET and PT_SETREGSET for the 175 1.10 christos specified NOTE instead of regset-specific fetch and store 176 1.10 christos ops. */ 177 1.10 christos 178 1.10 christos bool fetch_regset (struct regcache *regcache, int regnum, int note, 179 1.10 christos const struct regset *regset, int regbase, void *regs, 180 1.10 christos size_t size); 181 1.10 christos 182 1.10 christos bool store_regset (struct regcache *regcache, int regnum, int note, 183 1.10 christos const struct regset *regset, int regbase, void *regs, 184 1.10 christos size_t size); 185 1.10 christos 186 1.10 christos protected: 187 1.10 christos /* Wrapper versions of the above helpers which accept a register set 188 1.10 christos type such as 'struct reg' or 'struct fpreg'. */ 189 1.10 christos 190 1.10 christos template <class Regset> 191 1.10 christos bool fetch_register_set (struct regcache *regcache, int regnum, int fetch_op, 192 1.10 christos const struct regset *regset, int regbase = 0) 193 1.10 christos { 194 1.10 christos Regset regs; 195 1.10 christos return fetch_register_set (regcache, regnum, fetch_op, regset, regbase, 196 1.10 christos ®s, sizeof (regs)); 197 1.10 christos } 198 1.10 christos 199 1.10 christos template <class Regset> 200 1.10 christos bool store_register_set (struct regcache *regcache, int regnum, int fetch_op, 201 1.10 christos int store_op, const struct regset *regset, 202 1.10 christos int regbase = 0) 203 1.10 christos { 204 1.10 christos Regset regs; 205 1.10 christos return store_register_set (regcache, regnum, fetch_op, store_op, regset, 206 1.10 christos regbase, ®s, sizeof (regs)); 207 1.10 christos } 208 1.10 christos 209 1.10 christos /* Helper routine for use in read_description in subclasses. This 210 1.10 christos routine checks if the register set for the specified NOTE is 211 1.10 christos present for a given PTID. If the register set is present, the 212 1.10 christos the size of the register set is returned. If the register set is 213 1.10 christos not present, zero is returned. */ 214 1.10 christos 215 1.10 christos size_t have_regset (ptid_t ptid, int note); 216 1.10 christos 217 1.10 christos /* Wrapper versions of the PT_GETREGSET and PT_REGSET helpers which 218 1.10 christos accept a register set type. */ 219 1.10 christos 220 1.10 christos template <class Regset> 221 1.10 christos bool fetch_regset (struct regcache *regcache, int regnum, int note, 222 1.10 christos const struct regset *regset, int regbase = 0) 223 1.10 christos { 224 1.10 christos Regset regs; 225 1.10 christos return fetch_regset (regcache, regnum, note, regset, regbase, ®s, 226 1.10 christos sizeof (regs)); 227 1.10 christos } 228 1.10 christos 229 1.10 christos template <class Regset> 230 1.10 christos bool store_regset (struct regcache *regcache, int regnum, int note, 231 1.10 christos const struct regset *regset, int regbase = 0) 232 1.10 christos { 233 1.10 christos Regset regs; 234 1.10 christos return store_regset (regcache, regnum, note, regset, regbase, ®s, 235 1.10 christos sizeof (regs)); 236 1.10 christos } 237 1.11 christos 238 1.11 christos private: 239 1.11 christos /* If an event is triggered asynchronously (fake vfork_done events) 240 1.11 christos or occurs when the core is not expecting it, a pending event is 241 1.11 christos created. This event is then returned by a future call to the 242 1.11 christos target wait method. */ 243 1.11 christos 244 1.11 christos struct pending_event 245 1.11 christos { 246 1.11 christos pending_event (const ptid_t &_ptid, const target_waitstatus &_status) : 247 1.11 christos ptid (_ptid), status (_status) {} 248 1.11 christos 249 1.11 christos ptid_t ptid; 250 1.11 christos target_waitstatus status; 251 1.11 christos }; 252 1.11 christos 253 1.11 christos /* Add a new pending event to the list. */ 254 1.11 christos 255 1.11 christos void add_pending_event (const ptid_t &ptid, const target_waitstatus &status); 256 1.11 christos 257 1.11 christos /* Return true if there is a pending event matching FILTER. */ 258 1.11 christos 259 1.11 christos bool have_pending_event (ptid_t filter); 260 1.11 christos 261 1.11 christos /* Check if there is a pending event for a resumed process matching 262 1.11 christos FILTER. If there is a matching event, the event is removed from 263 1.11 christos the pending list and returned. */ 264 1.11 christos 265 1.11 christos std::optional<pending_event> take_pending_event (ptid_t filter); 266 1.11 christos 267 1.11 christos /* List of pending events. */ 268 1.11 christos 269 1.11 christos std::list<pending_event> m_pending_events; 270 1.11 christos 271 1.11 christos /* If this thread has a pending fork event, there is a child process 272 1.11 christos GDB is attached to that the core of GDB doesn't know about. 273 1.11 christos Detach from it. */ 274 1.11 christos 275 1.11 christos void detach_fork_children (thread_info *tp); 276 1.11 christos 277 1.11 christos /* Detach from any child processes associated with pending fork events 278 1.11 christos for a stopped process. Returns true if the process has terminated 279 1.11 christos and false if it is still alive. */ 280 1.11 christos 281 1.11 christos bool detach_fork_children (inferior *inf); 282 1.8 christos }; 283 1.1 christos 284 1.10 christos /* Fetch the signal information for PTID and store it in *SIGINFO. 285 1.10 christos Return true if successful. */ 286 1.10 christos bool fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo); 287 1.10 christos 288 1.12 christos #endif /* GDB_FBSD_NAT_H */ 289