gas: Update commit 4780e5e4933
[binutils-gdb.git] / gdbserver / linux-low.h
index 5dcddc41aaacd7475c966acb4bf084ec60a645ca..05067ffc6e6fa3c7d50277b94245118ecaa57a49 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal interfaces for the GNU/Linux specific target code for gdbserver.
-   Copyright (C) 2002-2020 Free Software Foundation, Inc.
+   Copyright (C) 2002-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -31,6 +31,8 @@
 #include "target/waitstatus.h" /* For enum target_stop_reason.  */
 #include "tracepoint.h"
 
+#include <list>
+
 #define PTRACE_XFER_TYPE long
 
 #ifdef HAVE_LINUX_REGSETS
@@ -129,105 +131,6 @@ struct process_info_private
 
 struct lwp_info;
 
-struct linux_target_ops
-{
-  /* 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 *);
-
-  /* Hook to support target specific qSupported.  */
-  void (*process_qsupported) (char **, int count);
-
-  /* Returns true if the low target supports tracepoints.  */
-  int (*supports_tracepoints) (void);
-
-  /* Fill ADDRP with the thread area address of LWPID.  Returns 0 on
-     success, -1 on failure.  */
-  int (*get_thread_area) (int lwpid, CORE_ADDR *addrp);
-
-  /* Install a fast tracepoint jump pad.  See target.h for
-     comments.  */
-  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);
-
-  /* Return the bytecode operations vector for the current inferior.
-     Returns NULL if bytecode compilation is not supported.  */
-  struct emit_ops *(*emit_ops) (void);
-
-  /* Return the minimum length of an instruction that can be safely overwritten
-     for use as a fast tracepoint.  */
-  int (*get_min_fast_tracepoint_insn_len) (void);
-
-  /* Returns true if the low target supports range stepping.  */
-  int (*supports_range_stepping) (void);
-
-  /* See target.h.  */
-  int (*supports_hardware_single_step) (void);
-
-  /* Fill *SYSNO with the syscall nr trapped.  Only to be called when
-     inferior is stopped due to SYSCALL_SIGTRAP.  */
-  void (*get_syscall_trapinfo) (struct regcache *regcache, int *sysno);
-
-  /* See target.h.  */
-  int (*get_ipa_tdesc_idx) (void);
-};
-
-extern struct linux_target_ops the_low_target;
-
 /* Target ops definitions for a Linux target.  */
 
 class linux_process_target : public process_stratum_target
@@ -254,7 +157,7 @@ public:
   void resume (thread_resume *resume_info, size_t n) override;
 
   ptid_t wait (ptid_t ptid, target_waitstatus *status,
-              int options) override;
+              target_wait_flags options) override;
 
   void fetch_registers (regcache *regcache, int regno) override;
 
@@ -279,8 +182,6 @@ public:
   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;
 
@@ -349,10 +250,6 @@ public:
                    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;
@@ -367,26 +264,6 @@ public:
 
   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;
@@ -415,7 +292,7 @@ public:
 
   bool supports_pid_to_exec_file () override;
 
-  char *pid_to_exec_file (int pid) override;
+  const char *pid_to_exec_file (int pid) override;
 
   bool supports_multifs () override;
 
@@ -436,8 +313,6 @@ public:
 
   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;
@@ -451,10 +326,10 @@ private:
      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);
+  /* Do low-level handling of the event, and check if this is an event we want
+     to report.  Is so, store it as a pending status in the lwp_info structure
+     corresponding to LWPID.  */
+  void 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:
@@ -481,7 +356,7 @@ private:
 
   /* Wait for process, returns status.  */
   ptid_t wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
-                int target_options);
+                target_wait_flags 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,
@@ -511,6 +386,12 @@ private:
      events.  */
   void complete_ongoing_step_over ();
 
+  /* Finish a step-over.  Reinsert the breakpoint we had uninserted in
+     start_step_over, if still there, and delete any single-step
+     breakpoints we've set, on non hardware single-step targets.
+     Return true if step over finished.  */
+  bool finish_step_over (lwp_info *lwp);
+
   /* 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.  */
@@ -629,9 +510,83 @@ private:
      or can't single step.  */
   int single_step (lwp_info* lwp);
 
+  /* Return true if THREAD is doing hardware single step.  */
+  bool maybe_hw_step (thread_info *thread);
+
   /* 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);
+
+  /* Returns true if THREAD is stopped in a jump pad, and we can't
+     move it out, because we need to report the stop event to GDB.  For
+     example, if the user puts a breakpoint in the jump pad, it's
+     because she wants to debug it.  */
+  bool stuck_in_jump_pad (thread_info *thread);
+
+  /* Convenience wrapper.  Returns information about LWP's fast tracepoint
+     collection status.  */
+  fast_tpoint_collect_result linux_fast_tracepoint_collecting
+    (lwp_info *lwp, fast_tpoint_collect_status *status);
+
+  /* This function should only be called if LWP got a SYSCALL_SIGTRAP.
+     Fill *SYSNO with the syscall nr trapped.  */
+  void get_syscall_trapinfo (lwp_info *lwp, int *sysno);
+
+  /* Returns true if GDB is interested in the event_child syscall.
+     Only to be called when stopped reason is SYSCALL_SIGTRAP.  */
+  bool gdb_catch_this_syscall (lwp_info *event_child);
+
 protected:
   /* The architecture-specific "low" methods are listed below.  */
 
@@ -667,6 +622,72 @@ protected:
   /* 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);
+
+  /* Hook to call prior to resuming a thread.  */
+  virtual void low_prepare_to_resume (lwp_info *lwp);
+
+  /* Fill ADDRP with the thread area address of LWPID.  Returns 0 on
+     success, -1 on failure.  */
+  virtual int low_get_thread_area (int lwpid, CORE_ADDR *addrp);
+
+  /* Returns true if the low target supports range stepping.  */
+  virtual bool low_supports_range_stepping ();
+
+  /* Return true if the target supports catch syscall.  Such targets
+     override the low_get_syscall_trapinfo method below.  */
+  virtual bool low_supports_catch_syscall ();
+
+  /* Fill *SYSNO with the syscall nr trapped.  Only to be called when
+     inferior is stopped due to SYSCALL_SIGTRAP.  */
+  virtual void low_get_syscall_trapinfo (regcache *regcache, int *sysno);
+
   /* How many bytes the PC should be decremented after a break.  */
   virtual int low_decr_pc_after_break ();
 };
@@ -676,6 +697,18 @@ 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)
 
+/* Information about a signal that is to be delivered to a thread.  */
+
+struct pending_signal
+{
+  pending_signal (int signal)
+    : signal {signal}
+  {};
+
+  int signal;
+  siginfo_t info;
+};
+
 /* This struct is recorded in the target_data field of struct thread_info.
 
    On linux ``all_threads'' is keyed by the LWP ID, which we use as the
@@ -689,7 +722,7 @@ extern linux_process_target *the_linux_target;
 struct lwp_info
 {
   /* Backlink to the parent object.  */
-  struct thread_info *thread;
+  struct thread_info *thread = nullptr;
 
   /* If this flag is set, the next SIGSTOP will be ignored (the
      process will be immediately resumed).  This means that either we
@@ -697,25 +730,25 @@ struct lwp_info
      (so the SIGSTOP is still pending), or that we stopped the
      inferior implicitly via PTRACE_ATTACH and have not waited for it
      yet.  */
-  int stop_expected;
+  int stop_expected = 0;
 
   /* When this is true, we shall not try to resume this thread, even
      if last_resume_kind isn't resume_stop.  */
-  int suspended;
+  int suspended = 0;
 
   /* If this flag is set, the lwp is known to be stopped right now (stop
      event already received in a wait()).  */
-  int stopped;
+  int stopped = 0;
 
   /* Signal whether we are in a SYSCALL_ENTRY or
      in a SYSCALL_RETURN event.
      Values:
      - TARGET_WAITKIND_SYSCALL_ENTRY
      - TARGET_WAITKIND_SYSCALL_RETURN */
-  enum target_waitkind syscall_state;
+  enum target_waitkind syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY;
 
   /* When stopped is set, the last wait status recorded for this lwp.  */
-  int last_status;
+  int last_status = 0;
 
   /* If WAITSTATUS->KIND != TARGET_WAITKIND_IGNORE, the waitstatus for
      this LWP's last event, to pass to GDB without any further
@@ -727,81 +760,81 @@ struct lwp_info
      the parent fork event is not reported to higher layers.  Used to
      avoid wildcard vCont actions resuming a fork child before GDB is
      notified about the parent's fork event.  */
-  struct lwp_info *fork_relative;
+  struct lwp_info *fork_relative = nullptr;
 
   /* When stopped is set, this is where the lwp last stopped, with
      decr_pc_after_break already accounted for.  If the LWP is
      running, this is the address at which the lwp was resumed.  */
-  CORE_ADDR stop_pc;
+  CORE_ADDR stop_pc = 0;
 
   /* If this flag is set, STATUS_PENDING is a waitstatus that has not yet
      been reported.  */
-  int status_pending_p;
-  int status_pending;
+  int status_pending_p = 0;
+  int status_pending = 0;
 
   /* The reason the LWP last stopped, if we need to track it
      (breakpoint, watchpoint, etc.)  */
-  enum target_stop_reason stop_reason;
+  enum target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON;
 
   /* On architectures where it is possible to know the data address of
      a triggered watchpoint, STOPPED_DATA_ADDRESS is non-zero, and
      contains such data address.  Only valid if STOPPED_BY_WATCHPOINT
      is true.  */
-  CORE_ADDR stopped_data_address;
+  CORE_ADDR stopped_data_address = 0;
 
   /* If this is non-zero, it is a breakpoint to be reinserted at our next
      stop (SIGTRAP stops only).  */
-  CORE_ADDR bp_reinsert;
+  CORE_ADDR bp_reinsert = 0;
 
   /* If this flag is set, the last continue operation at the ptrace
      level on this process was a single-step.  */
-  int stepping;
+  int stepping = 0;
 
   /* Range to single step within.  This is a copy of the step range
      passed along the last resume request.  See 'struct
      thread_resume'.  */
-  CORE_ADDR step_range_start /* Inclusive */
-  CORE_ADDR step_range_end;    /* Exclusive */
+  CORE_ADDR step_range_start = 0; /* Inclusive */
+  CORE_ADDR step_range_end = 0; /* Exclusive */
 
   /* If this flag is set, we need to set the event request flags the
      next time we see this LWP stop.  */
-  int must_set_ptrace_flags;
+  int must_set_ptrace_flags = 0;
 
-  /* If this is non-zero, it points to a chain of signals which need to
-     be delivered to this process.  */
-  struct pending_signals *pending_signals;
+  /* A chain of signals that need to be delivered to this process.  */
+  std::list<pending_signal> pending_signals;
 
   /* A link used when resuming.  It is initialized from the resume request,
      and then processed and cleared in linux_resume_one_lwp.  */
-  struct thread_resume *resume;
+  struct thread_resume *resume = nullptr;
 
   /* Information bout this lwp's fast tracepoint collection status (is it
      currently stopped in the jump pad, and if so, before or at/after the
      relocated instruction).  Normally, we won't care about this, but we will
      if a signal arrives to this lwp while it is collecting.  */
-  fast_tpoint_collect_result collecting_fast_tracepoint;
+  fast_tpoint_collect_result collecting_fast_tracepoint
+    = fast_tpoint_collect_result::not_collecting;
 
-  /* If this is non-zero, it points to a chain of signals which need
-     to be reported to GDB.  These were deferred because the thread
-     was doing a fast tracepoint collect when they arrived.  */
-  struct pending_signals *pending_signals_to_report;
+  /* A chain of signals that need to be reported to GDB.  These were
+     deferred because the thread was doing a fast tracepoint collect
+     when they arrived.  */
+  std::list<pending_signal> pending_signals_to_report;
 
   /* When collecting_fast_tracepoint is first found to be 1, we insert
      a exit-jump-pad-quickly breakpoint.  This is it.  */
-  struct breakpoint *exit_jump_pad_bkpt;
+  struct breakpoint *exit_jump_pad_bkpt = nullptr;
 
 #ifdef USE_THREAD_DB
-  int thread_known;
+  int thread_known = 0;
   /* The thread handle, used for e.g. TLS access.  Only valid if
      THREAD_KNOWN is set.  */
-  td_thrhandle_t th;
+  td_thrhandle_t th {};
 
   /* The pthread_t handle.  */
-  thread_t thread_handle;
+  thread_t thread_handle {};
 #endif
 
   /* Arch-specific additions.  */
-  struct arch_lwp_info *arch_private;
+  struct arch_lwp_info *arch_private = nullptr;
 };
 
 int linux_pid_exe_is_elf_64_file (int pid, unsigned int *machine);