X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Flinux-low.h;h=8eaad3e42cfa422936069305f8657d22ea77fc82;hb=d9311bfaf572cf14af577a66e79c51c491553552;hp=4dd3c9c2c2b1be982f5b44f82d44df3257c512d2;hpb=c2d6af84da44465f30e3bb487721128dfe03d0e4;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h index 4dd3c9c2c2..8eaad3e42c 100644 --- a/gdb/gdbserver/linux-low.h +++ b/gdb/gdbserver/linux-low.h @@ -1,5 +1,5 @@ /* Internal interfaces for the GNU/Linux specific target code for gdbserver. - Copyright (C) 2002-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2015 Free Software Foundation, Inc. This file is part of GDB. @@ -16,14 +16,17 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "gdb_thread_db.h" +#include "nat/linux-nat.h" +#include "nat/gdb_thread_db.h" #include #include "gdbthread.h" #include "gdb_proc_service.h" -#define PTRACE_ARG3_TYPE void * -#define PTRACE_ARG4_TYPE void * +/* Included for ptrace type definitions. */ +#include "nat/linux-ptrace.h" +#include "target/waitstatus.h" /* For enum target_stop_reason. */ + #define PTRACE_XFER_TYPE long #ifdef HAVE_LINUX_REGSETS @@ -35,6 +38,11 @@ enum regset_type { EXTENDED_REGS, }; +/* The arch's regsets array initializer must be terminated with a NULL + regset. */ +#define NULL_REGSET \ + { 0, 0, 0, -1, (enum regset_type) -1, NULL, NULL } + struct regset_info { int get_request, set_request; @@ -46,9 +54,61 @@ struct regset_info 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 +/* 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 { /* Arch-specific additions. */ @@ -69,14 +129,7 @@ struct linux_target_ops /* Architecture-specific setup. */ void (*arch_setup) (void); - int num_regs; - int *regmap; - - /* 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; + 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 @@ -93,17 +146,27 @@ struct linux_target_ops CORE_ADDR (*get_pc) (struct regcache *regcache); void (*set_pc) (struct regcache *regcache, CORE_ADDR newpc); - const unsigned char *breakpoint; - int breakpoint_len; - CORE_ADDR (*breakpoint_reinsert_addr) (void); + + /* See target.h for details. */ + int (*breakpoint_kind_from_pc) (CORE_ADDR *pcptr); + + /* 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. */ + VEC (CORE_ADDR) *(*get_next_pcs) (CORE_ADDR pc, 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 (*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); @@ -128,13 +191,16 @@ struct linux_target_ops /* Hook to call when a new thread is detected. If extra per-thread architecture-specific data is needed, allocate it here. */ - struct arch_lwp_info * (*new_thread) (void); + void (*new_thread) (struct 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) (const char *); + void (*process_qsupported) (char **, int count); /* Returns true if the low target supports tracepoints. */ int (*supports_tracepoints) (void); @@ -168,23 +234,33 @@ struct linux_target_ops /* Returns true if the low target supports range stepping. */ int (*supports_range_stepping) (void); + + /* See target.h. */ + int (*breakpoint_kind_from_current_state) (CORE_ADDR *pcptr); + + /* See target.h. */ + int (*supports_hardware_single_step) (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 @@ -202,16 +278,18 @@ struct lwp_info event already received in a wait()). */ int stopped; - /* If this flag is set, the lwp is known to be dead already (exit - event already received in a wait(), and is cached in - status_pending). */ - int dead; - /* When stopped is set, the last wait status recorded for this lwp. */ int last_status; - /* When stopped is set, this is where the lwp stopped, with - decr_pc_after_break already accounted for. */ + /* If WAITSTATUS->KIND != TARGET_WAITKIND_IGNORE, the waitstatus for + this LWP's last event, to pass to GDB without any further + processing. This is used to store extended ptrace event + information or exit status until it can be reported to GDB. */ + struct target_waitstatus waitstatus; + + /* 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; /* If this flag is set, STATUS_PENDING is a waitstatus that has not yet @@ -219,9 +297,9 @@ struct lwp_info int status_pending_p; int status_pending; - /* STOPPED_BY_WATCHPOINT is non-zero if this LWP stopped with a data - watchpoint trap. */ - int stopped_by_watchpoint; + /* The reason the LWP last stopped, if we need to track it + (breakpoint, watchpoint, etc.) */ + enum target_stop_reason stop_reason; /* On architectures where it is possible to know the data address of a triggered watchpoint, STOPPED_DATA_ADDRESS is non-zero, and @@ -286,19 +364,28 @@ struct lwp_info 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); -void linux_attach_lwp (unsigned long pid); +/* Attach to PTID. Returns 0 on success, non-zero otherwise (an + errno). */ +int linux_attach_lwp (ptid_t ptid); + struct lwp_info *find_lwp_pid (ptid_t ptid); -void linux_stop_lwp (struct lwp_info *lwp); +/* For linux_stop_lwp see nat/linux-nat.h. */ + +#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); +int thread_db_init (void); void thread_db_detach (struct process_info *); void thread_db_mourn (struct process_info *); int thread_db_handle_monitor_command (char *); int thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset, CORE_ADDR load_module, CORE_ADDR *address); int thread_db_look_up_one_symbol (const char *name, CORE_ADDR *addrp); + +extern int have_ptrace_getregset;