struct linux_target_ops
{
- /* Architecture-specific setup. */
- void (*arch_setup) (void);
-
- const struct regs_info *(*regs_info) (void);
+ /* Return 0 if we can fetch/store the register, 1 if we cannot
+ fetch/store the register. */
int (*cannot_fetch_register) (int);
-
- /* Returns 0 if we can store the register, 1 if we can not
- store the register, and 2 if failure to store the register
- is acceptable. */
int (*cannot_store_register) (int);
/* Hook to fetch a register in some non-standard way. Used for
/* Target ops definitions for a Linux target. */
-class linux_process_target : public process_target
+class linux_process_target : public process_stratum_target
{
public:
const std::vector<char *> &program_args) override;
void post_create_inferior () override;
+
+ int attach (unsigned long pid) override;
+
+ int kill (process_info *proc) override;
+
+ int detach (process_info *proc) override;
+
+ void mourn (process_info *proc) override;
+
+ void join (int pid) override;
+
+ bool thread_alive (ptid_t pid) override;
+
+ void resume (thread_resume *resume_info, size_t n) override;
+
+ ptid_t wait (ptid_t ptid, target_waitstatus *status,
+ int options) override;
+
+ void fetch_registers (regcache *regcache, int regno) override;
+
+ void store_registers (regcache *regcache, int regno) override;
+
+ int prepare_to_access_memory () override;
+
+ void done_accessing_memory () override;
+
+ int read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
+ int len) override;
+
+ int write_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
+ int len) override;
+
+ void look_up_symbols () override;
+
+ void request_interrupt () override;
+
+ bool supports_read_auxv () override;
+
+ 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;
+
+ int remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
+ int size, raw_breakpoint *bp) override;
+
+ bool stopped_by_sw_breakpoint () override;
+
+ bool supports_stopped_by_sw_breakpoint () override;
+
+ bool stopped_by_hw_breakpoint () override;
+
+ bool supports_stopped_by_hw_breakpoint () override;
+
+ bool supports_hardware_single_step () override;
+
+ bool stopped_by_watchpoint () override;
+
+ CORE_ADDR stopped_data_address () override;
+
+ bool supports_read_offsets () override;
+
+ int read_offsets (CORE_ADDR *text, CORE_ADDR *data) override;
+
+ bool supports_get_tls_address () override;
+
+ int get_tls_address (thread_info *thread, CORE_ADDR offset,
+ CORE_ADDR load_module, CORE_ADDR *address) override;
+
+ bool supports_qxfer_osdata () override;
+
+ int qxfer_osdata (const char *annex, unsigned char *readbuf,
+ unsigned const char *writebuf,
+ CORE_ADDR offset, int len) override;
+
+ bool supports_qxfer_siginfo () override;
+
+ int qxfer_siginfo (const char *annex, unsigned char *readbuf,
+ unsigned const char *writebuf,
+ CORE_ADDR offset, int len) override;
+
+ bool supports_non_stop () override;
+
+ bool async (bool enable) override;
+
+ int start_non_stop (bool enable) override;
+
+ bool supports_multi_process () override;
+
+ bool supports_fork_events () override;
+
+ bool supports_vfork_events () override;
+
+ bool supports_exec_events () override;
+
+ void handle_new_gdb_connection () override;
+
+ int handle_monitor_command (char *mon) override;
+
+ int core_of_thread (ptid_t ptid) override;
+
+#if defined PT_GETDSBT || defined PTRACE_GETFDPIC
+ bool supports_read_loadmap () override;
+
+ int read_loadmap (const char *annex, CORE_ADDR offset,
+ unsigned char *myaddr, unsigned int len) override;
+#endif
+
+ void process_qsupported (char **features, int count) override;
+
+ bool supports_tracepoints () override;
+
+ CORE_ADDR read_pc (regcache *regcache) override;
+
+ void write_pc (regcache *regcache, CORE_ADDR pc) override;
+
+ bool supports_thread_stopped () override;
+
+ bool thread_stopped (thread_info *thread) override;
+
+ void pause_all (bool freeze) override;
+
+ void unpause_all (bool unfreeze) override;
+
+ void stabilize_threads () override;
+
+ bool supports_fast_tracepoints () override;
+
+ int install_fast_tracepoint_jump_pad (CORE_ADDR tpoint,
+ CORE_ADDR tpaddr,
+ CORE_ADDR collector,
+ CORE_ADDR lockaddr,
+ ULONGEST orig_size,
+ CORE_ADDR *jump_entry,
+ CORE_ADDR *trampoline,
+ ULONGEST *trampoline_size,
+ unsigned char *jjump_pad_insn,
+ ULONGEST *jjump_pad_insn_size,
+ CORE_ADDR *adjusted_insn_addr,
+ CORE_ADDR *adjusted_insn_addr_end,
+ char *err) override;
+
+ int get_min_fast_tracepoint_insn_len () override;
+
+ struct emit_ops *emit_ops () override;
+
+ bool supports_disable_randomization () override;
+
+ bool supports_qxfer_libraries_svr4 () override;
+
+ int qxfer_libraries_svr4 (const char *annex,
+ unsigned char *readbuf,
+ unsigned const char *writebuf,
+ CORE_ADDR offset, int len) override;
+
+ bool supports_agent () override;
+
+#ifdef HAVE_LINUX_BTRACE
+ btrace_target_info *enable_btrace (ptid_t ptid,
+ const btrace_config *conf) override;
+
+ int disable_btrace (btrace_target_info *tinfo) override;
+
+ int read_btrace (btrace_target_info *tinfo, buffer *buf,
+ enum btrace_read_type type) override;
+
+ int read_btrace_conf (const btrace_target_info *tinfo,
+ buffer *buf) override;
+#endif
+
+ bool supports_range_stepping () override;
+
+ bool supports_pid_to_exec_file () override;
+
+ char *pid_to_exec_file (int pid) override;
+
+ bool supports_multifs () override;
+
+ int multifs_open (int pid, const char *filename, int flags,
+ mode_t mode) override;
+
+ int multifs_unlink (int pid, const char *filename) override;
+
+ ssize_t multifs_readlink (int pid, const char *filename, char *buf,
+ size_t bufsiz) override;
+
+ int breakpoint_kind_from_pc (CORE_ADDR *pcptr) override;
+
+ const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
+
+ int breakpoint_kind_from_current_state (CORE_ADDR *pcptr) override;
+
+ const char *thread_name (ptid_t thread) override;
+
+#if USE_THREAD_DB
+ bool thread_handle (ptid_t ptid, gdb_byte **handle,
+ int *handle_len) override;
+#endif
+
+ bool supports_software_single_step () override;
+
+ bool supports_catch_syscall () override;
+
+ int get_ipa_tdesc_idx () override;
+
+ /* Return the information to access registers. This has public
+ visibility because proc-service uses it. */
+ virtual const regs_info *get_regs_info () = 0;
+
+private:
+
+ /* Handle a GNU/Linux extended wait response. If we see a clone,
+ fork, or vfork event, we need to add the new LWP to our list
+ (and return 0 so as not to report the trap to higher layers).
+ If we see an exec event, we will modify ORIG_EVENT_LWP to point
+ to a new LWP representing the new program. */
+ int handle_extended_wait (lwp_info **orig_event_lwp, int wstat);
+
+ /* Do low-level handling of the event, and check if we should go on
+ and pass it to caller code. Return the affected lwp if we are, or
+ NULL otherwise. */
+ lwp_info *filter_event (int lwpid, int wstat);
+
+ /* Wait for an event from child(ren) WAIT_PTID, and return any that
+ match FILTER_PTID (leaving others pending). The PTIDs can be:
+ minus_one_ptid, to specify any child; a pid PTID, specifying all
+ lwps of a thread group; or a PTID representing a single lwp. Store
+ the stop status through the status pointer WSTAT. OPTIONS is
+ passed to the waitpid call. Return 0 if no event was found and
+ OPTIONS contains WNOHANG. Return -1 if no unwaited-for children
+ was found. Return the PID of the stopped child otherwise. */
+ int wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
+ int *wstatp, int options);
+
+ /* Wait for an event from child(ren) PTID. PTIDs can be:
+ minus_one_ptid, to specify any child; a pid PTID, specifying all
+ lwps of a thread group; or a PTID representing a single lwp. Store
+ the stop status through the status pointer WSTAT. OPTIONS is
+ passed to the waitpid call. Return 0 if no event was found and
+ OPTIONS contains WNOHANG. Return -1 if no unwaited-for children
+ was found. Return the PID of the stopped child otherwise. */
+ int wait_for_event (ptid_t ptid, int *wstatp, int options);
+
+ /* Wait for all children to stop for the SIGSTOPs we just queued. */
+ void wait_for_sigstop ();
+
+ /* Wait for process, returns status. */
+ ptid_t wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
+ int target_options);
+
+ /* Stop all lwps that aren't stopped yet, except EXCEPT, if not NULL.
+ If SUSPEND, then also increase the suspend count of every LWP,
+ except EXCEPT. */
+ void stop_all_lwps (int suspend, lwp_info *except);
+
+ /* Stopped LWPs that the client wanted to be running, that don't have
+ pending statuses, are set to run again, except for EXCEPT, if not
+ NULL. This undoes a stop_all_lwps call. */
+ void unstop_all_lwps (int unsuspend, lwp_info *except);
+
+ /* Start a step-over operation on LWP. When LWP stopped at a
+ breakpoint, to make progress, we need to remove the breakpoint out
+ of the way. If we let other threads run while we do that, they may
+ pass by the breakpoint location and miss hitting it. To avoid
+ that, a step-over momentarily stops all threads while LWP is
+ single-stepped by either hardware or software while the breakpoint
+ is temporarily uninserted from the inferior. When the single-step
+ finishes, we reinsert the breakpoint, and let all threads that are
+ supposed to be running, run again. */
+ void start_step_over (lwp_info *lwp);
+
+ /* If there's a step over in progress, wait until all threads stop
+ (that is, until the stepping thread finishes its step), and
+ unsuspend all lwps. The stepping thread ends with its status
+ pending, which is processed later when we get back to processing
+ events. */
+ void complete_ongoing_step_over ();
+
+ /* When we finish a step-over, set threads running again. If there's
+ another thread that may need a step-over, now's the time to start
+ it. Eventually, we'll move all threads past their breakpoints. */
+ void proceed_all_lwps ();
+
+ /* The reason we resume in the caller, is because we want to be able
+ to pass lwp->status_pending as WSTAT, and we need to clear
+ status_pending_p before resuming, otherwise, resume_one_lwp
+ refuses to resume. */
+ bool maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat);
+
+ /* Move THREAD out of the jump pad. */
+ void move_out_of_jump_pad (thread_info *thread);
+
+ /* Call low_arch_setup on THREAD. */
+ void arch_setup_thread (thread_info *thread);
+
+protected:
+ /* The architecture-specific "low" methods are listed below. */
+
+ /* Architecture-specific setup for the current thread. */
+ virtual void low_arch_setup () = 0;
};
+extern linux_process_target *the_linux_target;
+
#define get_thread_lwp(thr) ((struct lwp_info *) (thread_target_data (thr)))
#define get_lwp_thread(lwp) ((lwp)->thread)