struct linux_target_ops
{
- /* See target.h for details. */
- const gdb_byte *(*sw_breakpoint_from_kind) (int kind, int *size);
-
- /* Find the next possible PCs after the current instruction executes. */
- std::vector<CORE_ADDR> (*get_next_pcs) (struct regcache *regcache);
-
- int decr_pc_after_break;
- int (*breakpoint_at) (CORE_ADDR pc);
-
- /* Breakpoint and watchpoint related functions. See target.h for
- comments. */
- int (*supports_z_point_type) (char z_type);
- int (*insert_point) (enum raw_bkpt_type type, CORE_ADDR addr,
- int size, struct raw_breakpoint *bp);
- int (*remove_point) (enum raw_bkpt_type type, CORE_ADDR addr,
- int size, struct raw_breakpoint *bp);
-
- int (*stopped_by_watchpoint) (void);
- CORE_ADDR (*stopped_data_address) (void);
-
- /* Hooks to reformat register data for PEEKUSR/POKEUSR (in particular
- for registers smaller than an xfer unit). */
- void (*collect_ptrace_register) (struct regcache *regcache,
- int regno, char *buf);
- void (*supply_ptrace_register) (struct regcache *regcache,
- int regno, const char *buf);
-
- /* Hook to convert from target format to ptrace format and back.
- Returns true if any conversion was done; false otherwise.
- If DIRECTION is 1, then copy from INF to NATIVE.
- If DIRECTION is 0, copy from NATIVE to INF. */
- int (*siginfo_fixup) (siginfo_t *native, gdb_byte *inf, int direction);
-
- /* Hook to call when a new process is created or attached to.
- If extra per-process architecture-specific data is needed,
- allocate it here. */
- struct arch_process_info * (*new_process) (void);
-
- /* Hook to call when a process is being deleted. If extra per-process
- architecture-specific data is needed, delete it here. */
- void (*delete_process) (struct arch_process_info *info);
-
- /* Hook to call when a new thread is detected.
- If extra per-thread architecture-specific data is needed,
- allocate it here. */
- void (*new_thread) (struct lwp_info *);
-
- /* Hook to call when a thread is being deleted. If extra per-thread
- architecture-specific data is needed, delete it here. */
- void (*delete_thread) (struct arch_lwp_info *);
-
- /* Hook to call, if any, when a new fork is attached. */
- void (*new_fork) (struct process_info *parent, struct process_info *child);
-
/* Hook to call prior to resuming a thread. */
void (*prepare_to_resume) (struct lwp_info *);
int read_auxv (CORE_ADDR offset, unsigned char *myaddr,
unsigned int len) override;
- bool supports_z_point_type (char z_type) override;
-
int insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
int size, raw_breakpoint *bp) override;
ssize_t multifs_readlink (int pid, const char *filename, char *buf,
size_t bufsiz) override;
- const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
-
const char *thread_name (ptid_t thread) override;
#if USE_THREAD_DB
int *handle_len) override;
#endif
- bool supports_software_single_step () override;
-
bool supports_catch_syscall () override;
int get_ipa_tdesc_idx () override;
/* Install breakpoints for software single stepping. */
void install_software_single_step_breakpoints (lwp_info *lwp);
+ /* Fetch the possibly triggered data watchpoint info and store it in
+ CHILD.
+
+ On some archs, like x86, that use debug registers to set
+ watchpoints, it's possible that the way to know which watched
+ address trapped, is to check the register that is used to select
+ which address to watch. Problem is, between setting the watchpoint
+ and reading back which data address trapped, the user may change
+ the set of watchpoints, and, as a consequence, GDB changes the
+ debug registers in the inferior. To avoid reading back a stale
+ stopped-data-address when that happens, we cache in LP the fact
+ that a watchpoint trapped, and the corresponding data address, as
+ soon as we see CHILD stop with a SIGTRAP. If GDB changes the debug
+ registers meanwhile, we have the cached data we can rely on. */
+ bool check_stopped_by_watchpoint (lwp_info *child);
+
+ /* Convert a native/host siginfo object, into/from the siginfo in the
+ layout of the inferiors' architecture. */
+ void siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo,
+ int direction);
+
+ /* Add a process to the common process list, and set its private
+ data. */
+ process_info *add_linux_process (int pid, int attached);
+
+ /* Add a new thread. */
+ lwp_info *add_lwp (ptid_t ptid);
+
+ /* Delete a thread. */
+ void delete_lwp (lwp_info *lwp);
+
+public: /* Make this public because it's used from outside. */
+ /* Attach to an inferior process. Returns 0 on success, ERRNO on
+ error. */
+ int attach_lwp (ptid_t ptid);
+
+private: /* Back to private. */
+ /* Detach from LWP. */
+ void detach_one_lwp (lwp_info *lwp);
+
+ /* Detect zombie thread group leaders, and "exit" them. We can't
+ reap their exits until all other threads in the group have
+ exited. */
+ void check_zombie_leaders ();
+
+ /* Convenience function that is called when the kernel reports an exit
+ event. This decides whether to report the event to GDB as a
+ process exit event, a thread exit event, or to suppress the
+ event. */
+ ptid_t filter_exit_event (lwp_info *event_child,
+ target_waitstatus *ourstatus);
+
protected:
/* The architecture-specific "low" methods are listed below. */
virtual CORE_ADDR low_get_pc (regcache *regcache);
virtual void low_set_pc (regcache *regcache, CORE_ADDR newpc);
+
+ /* Find the next possible PCs after the current instruction executes.
+ Targets that override this method should also override
+ 'supports_software_single_step' to return true. */
+ virtual std::vector<CORE_ADDR> low_get_next_pcs (regcache *regcache);
+
+ /* Return true if there is a breakpoint at PC. */
+ virtual bool low_breakpoint_at (CORE_ADDR pc) = 0;
+
+ /* Breakpoint and watchpoint related functions. See target.h for
+ comments. */
+ virtual int low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
+ int size, raw_breakpoint *bp);
+
+ virtual int low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
+ int size, raw_breakpoint *bp);
+
+ virtual bool low_stopped_by_watchpoint ();
+
+ virtual CORE_ADDR low_stopped_data_address ();
+
+ /* Hooks to reformat register data for PEEKUSR/POKEUSR (in particular
+ for registers smaller than an xfer unit). */
+ virtual void low_collect_ptrace_register (regcache *regcache, int regno,
+ char *buf);
+
+ virtual void low_supply_ptrace_register (regcache *regcache, int regno,
+ const char *buf);
+
+ /* Hook to convert from target format to ptrace format and back.
+ Returns true if any conversion was done; false otherwise.
+ If DIRECTION is 1, then copy from INF to NATIVE.
+ If DIRECTION is 0, copy from NATIVE to INF. */
+ virtual bool low_siginfo_fixup (siginfo_t *native, gdb_byte *inf,
+ int direction);
+
+ /* Hook to call when a new process is created or attached to.
+ If extra per-process architecture-specific data is needed,
+ allocate it here. */
+ virtual arch_process_info *low_new_process ();
+
+ /* Hook to call when a process is being deleted. If extra per-process
+ architecture-specific data is needed, delete it here. */
+ virtual void low_delete_process (arch_process_info *info);
+
+ /* Hook to call when a new thread is detected.
+ If extra per-thread architecture-specific data is needed,
+ allocate it here. */
+ virtual void low_new_thread (lwp_info *);
+
+ /* Hook to call when a thread is being deleted. If extra per-thread
+ architecture-specific data is needed, delete it here. */
+ virtual void low_delete_thread (arch_lwp_info *);
+
+ /* Hook to call, if any, when a new fork is attached. */
+ virtual void low_new_fork (process_info *parent, process_info *child);
+
+ /* How many bytes the PC should be decremented after a break. */
+ virtual int low_decr_pc_after_break ();
};
extern linux_process_target *the_linux_target;