/* Internal interfaces for the GNU/Linux specific target code for gdbserver.
- Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#ifdef HAVE_THREAD_DB_H
-#include <thread_db.h>
-#endif
+#include "nat/gdb_thread_db.h"
+#include <signal.h>
+#include "gdbthread.h"
#include "gdb_proc_service.h"
+/* Included for ptrace type definitions. */
+#include "nat/linux-ptrace.h"
+
+#define PTRACE_XFER_TYPE long
+
#ifdef HAVE_LINUX_REGSETS
typedef void (*regset_fill_func) (struct regcache *, void *);
typedef void (*regset_store_func) (struct regcache *, const void *);
regset_fill_func fill_function;
regset_store_func store_function;
};
-extern struct regset_info target_regsets[];
+
+/* Aggregation of all the supported regsets of a given
+ architecture/mode. */
+
+struct regsets_info
+{
+ /* The regsets array. */
+ struct regset_info *regsets;
+
+ /* The number of regsets in the REGSETS array. */
+ int num_regsets;
+
+ /* If we get EIO on a regset, do not try it again. Note the set of
+ supported regsets may depend on processor mode on biarch
+ machines. This is a (lazily allocated) array holding one boolean
+ byte (0/1) per regset, with each element corresponding to the
+ regset in the REGSETS array above at the same offset. */
+ char *disabled_regsets;
+};
+
#endif
-struct siginfo;
+/* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+
+struct usrregs_info
+{
+ /* The number of registers accessible. */
+ int num_regs;
+
+ /* The registers map. */
+ int *regmap;
+};
+
+/* All info needed to access an architecture/mode's registers. */
+
+struct regs_info
+{
+ /* Regset support bitmap: 1 for registers that are transferred as a part
+ of a regset, 0 for ones that need to be handled individually. This
+ can be NULL if all registers are transferred with regsets or regsets
+ are not supported. */
+ unsigned char *regset_bitmap;
+
+ /* Info used when accessing registers with PTRACE_PEEKUSER /
+ PTRACE_POKEUSER. This can be NULL if all registers are
+ transferred with regsets .*/
+ struct usrregs_info *usrregs;
+
+#ifdef HAVE_LINUX_REGSETS
+ /* Info used when accessing registers with regsets. */
+ struct regsets_info *regsets_info;
+#endif
+};
struct process_info_private
{
/* libthread_db-specific additions. Not NULL if this process has loaded
thread_db, and it is active. */
struct thread_db *thread_db;
+
+ /* &_r_debug. 0 if not yet determined. -1 if no PT_DYNAMIC in Phdrs. */
+ CORE_ADDR r_debug;
+
+ /* This flag is true iff we've just created or attached to the first
+ LWP of this process but it has not stopped yet. As soon as it
+ does, we need to call the low target's arch_setup callback. */
+ int new_inferior;
};
struct lwp_info;
/* Architecture-specific setup. */
void (*arch_setup) (void);
- int num_regs;
- int *regmap;
+ const struct regs_info *(*regs_info) (void);
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
+ example by backends that have read-only registers with hardcoded
+ values (e.g., IA64's gr0/fr0/fr1). Returns true if register
+ REGNO was supplied, false if not, and we should fallback to the
+ standard ptrace methods. */
+ int (*fetch_register) (struct regcache *regcache, int regno);
+
CORE_ADDR (*get_pc) (struct regcache *regcache);
void (*set_pc) (struct regcache *regcache, CORE_ADDR newpc);
const unsigned char *breakpoint;
/* Breakpoint and watchpoint related functions. See target.h for
comments. */
- int (*insert_point) (char type, CORE_ADDR addr, int len);
- int (*remove_point) (char type, CORE_ADDR addr, int len);
+ 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);
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) (struct siginfo *native, void *inf, int direction);
+ int (*siginfo_fixup) (siginfo_t *native, void *inf, int direction);
/* Hook to call when a new process is created or attached to.
If extra per-process architecture-specific data is needed,
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);
+ 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);
};
extern struct linux_target_ops the_low_target;
-#define ptid_of(proc) ((proc)->head.id)
-#define pid_of(proc) ptid_get_pid ((proc)->head.id)
-#define lwpid_of(proc) ptid_get_lwp ((proc)->head.id)
+#define get_thread_lwp(thr) ((struct lwp_info *) (inferior_target_data (thr)))
+#define get_lwp_thread(lwp) ((lwp)->thread)
+
+/* 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
+ GDB protocol representation of the thread ID. Threads also have
+ a "process ID" (poorly named) which is (presently) the same as the
+ LWP ID.
-#define get_lwp(inf) ((struct lwp_info *)(inf))
-#define get_thread_lwp(thr) (get_lwp (inferior_target_data (thr)))
-#define get_lwp_thread(proc) ((struct thread_info *) \
- find_inferior_id (&all_threads, \
- get_lwp (proc)->head.id))
+ There is also ``all_processes'' is keyed by the "overall process ID",
+ which GNU/Linux calls tgid, "thread group ID". */
struct lwp_info
{
- struct inferior_list_entry head;
+ /* Backlink to the parent object. */
+ struct thread_info *thread;
/* If this flag is set, the next SIGSTOP will be ignored (the
process will be immediately resumed). This means that either we
level on this process was a single-step. */
int stepping;
+ /* 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 */
+
/* 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;
stepping over later when it is resumed. */
int need_step_over;
+#ifdef USE_THREAD_DB
int thread_known;
-#ifdef HAVE_THREAD_DB_H
/* The thread handle, used for e.g. TLS access. Only valid if
THREAD_KNOWN is set. */
td_thrhandle_t th;
struct arch_lwp_info *arch_private;
};
-extern struct inferior_list all_lwps;
+int linux_pid_exe_is_elf_64_file (int pid, unsigned int *machine);
+
+/* Attach to PTID. Returns 0 on success, non-zero otherwise (an
+ errno). */
+int linux_attach_lwp (ptid_t ptid);
-char *linux_child_pid_to_exec_file (int pid);
-int elf_64_file_p (const char *file);
+/* Return the reason an attach failed, in string form. ERR is the
+ error returned by linux_attach_lwp (an errno). This string should
+ be copied into a buffer by the client if the string will not be
+ immediately used, or if it must persist. */
+char *linux_attach_fail_reason_string (ptid_t ptid, int err);
-void linux_attach_lwp (unsigned long pid);
struct lwp_info *find_lwp_pid (ptid_t ptid);
+void linux_stop_lwp (struct lwp_info *lwp);
+
+#ifdef HAVE_LINUX_REGSETS
+void initialize_regsets_info (struct regsets_info *regsets_info);
+#endif
+
+void initialize_low_arch (void);
/* From thread-db.c */
int thread_db_init (int use_events);