X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Ftarget.h;h=bbb056733e29b20d6177ac8ea14ee19990e5e2d7;hb=582511be69deb0e9d52efd6d51f860b6bee02a64;hp=0e4b12774728cc840ea11602e0b95e94870caea4;hpb=cdbfd4198ec38a42766a578d4058bd752d25011c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h index 0e4b127747..bbb056733e 100644 --- a/gdb/gdbserver/target.h +++ b/gdb/gdbserver/target.h @@ -1,6 +1,5 @@ /* Target operations for the remote server for GDB. - Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2002-2015 Free Software Foundation, Inc. Contributed by MontaVista Software. @@ -22,19 +21,16 @@ #ifndef TARGET_H #define TARGET_H -/* Ways to "resume" a thread. */ +#include "target/target.h" +#include "target/resume.h" +#include "target/wait.h" +#include "target/waitstatus.h" +#include "mem-break.h" -enum resume_kind -{ - /* Thread should continue. */ - resume_continue, - - /* Thread should single-step. */ - resume_step, - - /* Thread should be stopped. */ - resume_stop -}; +struct emit_ops; +struct btrace_target_info; +struct buffer; +struct process_info; /* This structure describes how to resume a particular thread (or all threads) based on the client's request. If thread is -1, then this @@ -51,60 +47,19 @@ struct thread_resume /* If non-zero, send this signal when we resume, or to stop the thread. If stopping a thread, and this is 0, the target should stop the thread however it best decides to (e.g., SIGSTOP on - linux; SuspendThread on win32). */ + linux; SuspendThread on win32). This is a host signal value (not + enum gdb_signal). */ int sig; -}; -/* Generally, what has the program done? */ -enum target_waitkind - { - /* The program has exited. The exit status is in - value.integer. */ - TARGET_WAITKIND_EXITED, - - /* The program has stopped with a signal. Which signal is in - value.sig. */ - TARGET_WAITKIND_STOPPED, - - /* The program has terminated with a signal. Which signal is in - value.sig. */ - TARGET_WAITKIND_SIGNALLED, - - /* The program is letting us know that it dynamically loaded - something. */ - TARGET_WAITKIND_LOADED, - - /* The program has exec'ed a new executable file. The new file's - pathname is pointed to by value.execd_pathname. */ - TARGET_WAITKIND_EXECD, - - /* Nothing of interest to GDB happened, but we stopped anyway. */ - TARGET_WAITKIND_SPURIOUS, - - /* An event has occurred, but we should wait again. In this case, - we want to go back to the event loop and wait there for another - event from the inferior. */ - TARGET_WAITKIND_IGNORE - }; - -struct target_waitstatus - { - enum target_waitkind kind; - - /* Forked child pid, execd pathname, exit status or signal number. */ - union - { - int integer; - enum target_signal sig; - ptid_t related_pid; - char *execd_pathname; - } - value; - }; - -/* Options that can be passed to target_ops->wait. */ - -#define TARGET_WNOHANG 1 + /* Range to single step within. Valid only iff KIND is resume_step. + + Single-step once, and then continuing stepping as long as the + thread stops in this range. (If the range is empty + [STEP_RANGE_START == STEP_RANGE_END], then this is a single-step + request.) */ + CORE_ADDR step_range_start; /* Inclusive */ + CORE_ADDR step_range_end; /* Exclusive */ +}; struct target_ops { @@ -138,6 +93,10 @@ struct target_ops int (*detach) (int pid); + /* The inferior process has died. Do what is right. */ + + void (*mourn) (struct process_info *proc); + /* Wait for inferior PID to exit. */ void (*join) (int pid); @@ -166,13 +125,30 @@ struct target_ops If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */ - void (*fetch_registers) (int regno); + void (*fetch_registers) (struct regcache *regcache, int regno); /* Store registers to the inferior process. If REGNO is -1, store all registers; otherwise, store at least REGNO. */ - void (*store_registers) (int regno); + void (*store_registers) (struct regcache *regcache, int regno); + + /* Prepare to read or write memory from the inferior process. + Targets use this to do what is necessary to get the state of the + inferior such that it is possible to access memory. + + This should generally only be called from client facing routines, + such as gdb_read_memory/gdb_write_memory, or the GDB breakpoint + insertion routine. + + Like `read_memory' and `write_memory' below, returns 0 on success + and errno on failure. */ + + int (*prepare_to_access_memory) (void); + + /* Undo the effects of prepare_to_access_memory. */ + + void (*done_accessing_memory) (void); /* Read memory from the inferior process. This should generally be called through read_inferior_memory, which handles breakpoint shadowing. @@ -213,17 +189,23 @@ struct target_ops int (*read_auxv) (CORE_ADDR offset, unsigned char *myaddr, unsigned int len); - /* Insert and remove a break or watchpoint. - Returns 0 on success, -1 on failure and 1 on unsupported. - The type is coded as follows: + /* Returns true if GDB Z breakpoint type TYPE is supported, false + otherwise. The type is coded as follows: '0' - software-breakpoint '1' - hardware-breakpoint '2' - write watchpoint '3' - read watchpoint - '4' - access watchpoint */ + '4' - access watchpoint + */ + int (*supports_z_point_type) (char z_type); + + /* Insert and remove a break or watchpoint. + Returns 0 on success, -1 on failure and 1 on unsupported. */ - int (*insert_point) (char type, CORE_ADDR addr, int len); - int (*remove_point) (char type, CORE_ADDR addr, int len); + 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); /* Returns 1 if target was stopped due to a watchpoint hit, 0 otherwise. */ @@ -283,6 +265,114 @@ struct target_ops /* If not NULL, target-specific routine to process monitor command. Returns 1 if handled, or 0 to perform default processing. */ int (*handle_monitor_command) (char *); + + /* Returns the core given a thread, or -1 if not known. */ + int (*core_of_thread) (ptid_t); + + /* Read loadmaps. Read LEN bytes at OFFSET into a buffer at MYADDR. */ + int (*read_loadmap) (const char *annex, CORE_ADDR offset, + unsigned char *myaddr, unsigned int len); + + /* Target specific qSupported support. */ + void (*process_qsupported) (const char *); + + /* Return 1 if the target supports tracepoints, 0 (or leave the + callback NULL) otherwise. */ + int (*supports_tracepoints) (void); + + /* Read PC from REGCACHE. */ + CORE_ADDR (*read_pc) (struct regcache *regcache); + + /* Write PC to REGCACHE. */ + void (*write_pc) (struct regcache *regcache, CORE_ADDR pc); + + /* Return true if THREAD is known to be stopped now. */ + int (*thread_stopped) (struct thread_info *thread); + + /* Read Thread Information Block address. */ + int (*get_tib_address) (ptid_t ptid, CORE_ADDR *address); + + /* Pause all threads. If FREEZE, arrange for any resume attempt to + be ignored until an unpause_all call unfreezes threads again. + There can be nested calls to pause_all, so a freeze counter + should be maintained. */ + void (*pause_all) (int freeze); + + /* Unpause all threads. Threads that hadn't been resumed by the + client should be left stopped. Basically a pause/unpause call + pair should not end up resuming threads that were stopped before + the pause call. */ + void (*unpause_all) (int unfreeze); + + /* Stabilize all threads. That is, force them out of jump pads. */ + void (*stabilize_threads) (void); + + /* Install a fast tracepoint jump pad. TPOINT is the address of the + tracepoint internal object as used by the IPA agent. TPADDR is + the address of tracepoint. COLLECTOR is address of the function + the jump pad redirects to. LOCKADDR is the address of the jump + pad lock object. ORIG_SIZE is the size in bytes of the + instruction at TPADDR. JUMP_ENTRY points to the address of the + jump pad entry, and on return holds the address past the end of + the created jump pad. If a trampoline is created by the function, + then TRAMPOLINE and TRAMPOLINE_SIZE return the address and size of + the trampoline, else they remain unchanged. JJUMP_PAD_INSN is a + buffer containing a copy of the instruction at TPADDR. + ADJUST_INSN_ADDR and ADJUST_INSN_ADDR_END are output parameters that + return the address range where the instruction at TPADDR was relocated + to. If an error occurs, the ERR may be used to pass on an error + message. */ + 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); + + /* Returns true if the target supports disabling randomization. */ + int (*supports_disable_randomization) (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); + + /* Read solib info on SVR4 platforms. */ + int (*qxfer_libraries_svr4) (const char *annex, unsigned char *readbuf, + unsigned const char *writebuf, + CORE_ADDR offset, int len); + + /* Return true if target supports debugging agent. */ + int (*supports_agent) (void); + + /* Check whether the target supports branch tracing. */ + int (*supports_btrace) (struct target_ops *); + + /* Enable branch tracing for @ptid and allocate a branch trace target + information struct for reading and for disabling branch trace. */ + struct btrace_target_info *(*enable_btrace) (ptid_t ptid); + + /* Disable branch tracing. + Returns zero on success, non-zero otherwise. */ + int (*disable_btrace) (struct btrace_target_info *tinfo); + + /* Read branch trace data into buffer. We use an int to specify the type + to break a cyclic dependency. + Return 0 on success; print an error message into BUFFER and return -1, + otherwise. */ + int (*read_btrace) (struct btrace_target_info *, struct buffer *, int type); + + /* Return true if target supports range stepping. */ + int (*supports_range_stepping) (void); }; extern struct target_ops *the_target; @@ -295,20 +385,22 @@ void set_target_ops (struct target_ops *); #define myattach(pid) \ (*the_target->attach) (pid) -#define kill_inferior(pid) \ - (*the_target->kill) (pid) +int kill_inferior (int); #define detach_inferior(pid) \ (*the_target->detach) (pid) +#define mourn_inferior(PROC) \ + (*the_target->mourn) (PROC) + #define mythread_alive(pid) \ (*the_target->thread_alive) (pid) -#define fetch_inferior_registers(regno) \ - (*the_target->fetch_registers) (regno) +#define fetch_inferior_registers(regcache, regno) \ + (*the_target->fetch_registers) (regcache, regno) -#define store_inferior_registers(regno) \ - (*the_target->store_registers) (regno) +#define store_inferior_registers(regcache, regno) \ + (*the_target->store_registers) (regcache, regno) #define join_inferior(pid) \ (*the_target->join) (pid) @@ -323,6 +415,97 @@ void set_target_ops (struct target_ops *); (the_target->supports_multi_process ? \ (*the_target->supports_multi_process) () : 0) +#define target_process_qsupported(query) \ + do \ + { \ + if (the_target->process_qsupported) \ + the_target->process_qsupported (query); \ + } while (0) + +#define target_supports_tracepoints() \ + (the_target->supports_tracepoints \ + ? (*the_target->supports_tracepoints) () : 0) + +#define target_supports_fast_tracepoints() \ + (the_target->install_fast_tracepoint_jump_pad != NULL) + +#define target_get_min_fast_tracepoint_insn_len() \ + (the_target->get_min_fast_tracepoint_insn_len \ + ? (*the_target->get_min_fast_tracepoint_insn_len) () : 0) + +#define thread_stopped(thread) \ + (*the_target->thread_stopped) (thread) + +#define pause_all(freeze) \ + do \ + { \ + if (the_target->pause_all) \ + (*the_target->pause_all) (freeze); \ + } while (0) + +#define unpause_all(unfreeze) \ + do \ + { \ + if (the_target->unpause_all) \ + (*the_target->unpause_all) (unfreeze); \ + } while (0) + +#define stabilize_threads() \ + do \ + { \ + if (the_target->stabilize_threads) \ + (*the_target->stabilize_threads) (); \ + } while (0) + +#define install_fast_tracepoint_jump_pad(tpoint, tpaddr, \ + collector, lockaddr, \ + orig_size, \ + jump_entry, \ + trampoline, trampoline_size, \ + jjump_pad_insn, \ + jjump_pad_insn_size, \ + adjusted_insn_addr, \ + adjusted_insn_addr_end, \ + err) \ + (*the_target->install_fast_tracepoint_jump_pad) (tpoint, tpaddr, \ + collector,lockaddr, \ + orig_size, jump_entry, \ + trampoline, \ + trampoline_size, \ + jjump_pad_insn, \ + jjump_pad_insn_size, \ + adjusted_insn_addr, \ + adjusted_insn_addr_end, \ + err) + +#define target_emit_ops() \ + (the_target->emit_ops ? (*the_target->emit_ops) () : NULL) + +#define target_supports_disable_randomization() \ + (the_target->supports_disable_randomization ? \ + (*the_target->supports_disable_randomization) () : 0) + +#define target_supports_agent() \ + (the_target->supports_agent ? \ + (*the_target->supports_agent) () : 0) + +#define target_supports_btrace() \ + (the_target->supports_btrace \ + ? (*the_target->supports_btrace) (the_target) : 0) + +#define target_enable_btrace(ptid) \ + (*the_target->enable_btrace) (ptid) + +#define target_disable_btrace(tinfo) \ + (*the_target->disable_btrace) (tinfo) + +#define target_read_btrace(tinfo, buffer, type) \ + (*the_target->read_btrace) (tinfo, buffer, type) + +#define target_supports_range_stepping() \ + (the_target->supports_range_stepping ? \ + (*the_target->supports_range_stepping) () : 0) + /* Start non-stop mode, returns 0 on success, -1 on failure. */ int start_non_stop (int nonstop); @@ -330,12 +513,28 @@ int start_non_stop (int nonstop); ptid_t mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options, int connected_wait); +#define prepare_to_access_memory() \ + (the_target->prepare_to_access_memory \ + ? (*the_target->prepare_to_access_memory) () \ + : 0) + +#define done_accessing_memory() \ + do \ + { \ + if (the_target->done_accessing_memory) \ + (*the_target->done_accessing_memory) (); \ + } while (0) + +#define target_core_of_thread(ptid) \ + (the_target->core_of_thread ? (*the_target->core_of_thread) (ptid) \ + : -1) + int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len); int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len); -void set_desired_inferior (int id); +void set_desired_thread (int id); const char *target_pid_to_str (ptid_t);