• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- Handle remote gdb protocol.             pub_core_gdbserver.h ---*/
4 /*--------------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2011-2013 Philippe Waroquiers
11 
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of the
15    License, or (at your option) any later version.
16 
17    This program is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25    02111-1307, USA.
26 
27    The GNU General Public License is contained in the file COPYING.
28 */
29 
30 #ifndef __PUB_CORE_GDBSERVER_H
31 #define __PUB_CORE_GDBSERVER_H
32 
33 #include "pub_tool_gdbserver.h"
34 #include "pub_core_options.h"
35 #include "pub_core_threadstate.h"   // VgSchedReturnCode
36 
37 /* Return the default path prefix for the named pipes (FIFOs) used by vgdb/gdb
38    to communicate with valgrind */
39 HChar* VG_(vgdb_prefix_default)(void);
40 
41 // After a fork or after an exec, call the below to (possibly) terminate
42 // the previous gdbserver and then activate a new gdbserver
43 // before any guest code execution, to e.g. allow the user to set
44 // breakpoints before execution.
45 // If VG_(clo_vgdb) == No, the below has no effect.
46 void VG_(gdbserver_prerun_action) (ThreadId tid);
47 
48 // True if the initialisation of gdbserver was done,
49 // i.e. VG_(gdbserver_prerun_action) was called.
50 Bool VG_(gdbserver_init_done) (void);
51 
52 // True if gdbserver should stop execution for the specified stop at reason
53 Bool VG_(gdbserver_stop_at) (VgdbStopAt stopat);
54 
55 // True if there is some activity from vgdb
56 // If it returns True, then extern void VG_(gdbserver) can be called
57 // to handle this incoming vgdb request.
58 extern Bool VG_(gdbserver_activity) (ThreadId tid);
59 
60 // If connected to GDB, VG_(gdbserver_exit) reports to GDB that the process
61 // is about to exit.
62 // gdbserver is then stopped (using VG_(gdbserver) (0))
63 void VG_(gdbserver_exit) (ThreadId tid, VgSchedReturnCode tids_schedretcode);
64 
65 /* On systems that defines PR_SET_PTRACER, verify if ptrace_scope is
66    is permissive enough for vgdb or --db-attach=yes.
67    Otherwise, call set_ptracer.
68    This is especially aimed at Ubuntu >= 10.10 which has added
69    the ptrace_scope context. */
70 void VG_(set_ptracer)(void);
71 
72 /* Called by low level to insert or remove a break or watch point.
73    Break or watch point implementation is done using help from the tool.
74    break point support implies some (small) specific instrumentation
75    taken in charge for all tools by m_translate.c.
76 
77    Write/read/access watchpoint can only be provided by tools which are
78    tracking addressability and/or accessibility of memory
79    (so typically memcheck can provide it). Note that memcheck addressability
80    bits do not differentiate between read and write accessibility.
81    However, when accessing unaddressable byte, memcheck can differentiate
82    reads from write, thereby providing read/write or access watchpoints.
83 
84    Note that gdbserver assumes that software breakpoint is supported
85    (as this will be done by re-instrumenting the code).
86    Note that len is ignored for sofware breakpoints. hardware_breakpoint
87    are not supported.
88 
89    Returns True if the point has properly been inserted or removed
90    Returns False otherwise. */
91 Bool VG_(gdbserver_point) (PointKind kind, Bool insert,
92                            Addr addr, int len);
93 
94 /* True if there is a breakpoint at addr. */
95 Bool VG_(has_gdbserver_breakpoint) (Addr addr);
96 
97 /* Entry point invoked by vgdb when it uses ptrace to cause a gdbserver
98    invocation. A magic value is passed by vgdb in check as a verification
99    that the call has been properly pushed by vgdb. */
100 extern void VG_(invoke_gdbserver) ( int check );
101 
102 // To be called by core (m_signals.c) before delivering a signal.
103 // Returns False if gdb user asks to not pass the signal to the client.
104 // Returns True if signal must be passed to the client, either because
105 // no gdb is connected, or gdb instructs to pass the signal.
106 // Note that if the below returns True, the signal might
107 // still be ignored if this is the action desired by the
108 // guest program. Using GDB, the user can also modify the signal to be
109 // reported (e.g. changing the signo to pass to the guest).
110 // If this function returns True, m_signals.c should deliver the signal
111 // info as modified by VG_(gdbserver_report_signal).
112 // If this function returns False, no signal should be reported.
113 extern Bool VG_(gdbserver_report_signal) (vki_siginfo_t *info, ThreadId tid);
114 
115 // If no gdb is connected yet, wait for a gdb to connect and report
116 // this (supposedly) fatal signal.
117 // If a gdb is already connected, this does nothing (as normally
118 // the signal was already reported to the already connected gdb).
119 extern void VG_(gdbserver_report_fatal_signal) (const vki_siginfo_t *info,
120                                                 ThreadId tid);
121 
122 /* Entry point invoked by scheduler.c to execute the request
123    VALGRIND_CLIENT_MONITOR_COMMAND.
124    Returns True if command was not recognised. */
125 extern Bool VG_(client_monitor_command) (HChar* cmd);
126 
127 /* software_breakpoint, single step and jump support ------------------------*/
128 /* VG_(instrument_for_gdbserver_if_needed) allows to do "standard and easy"
129    instrumentation for gdbserver.
130    VG_(instrument_for_gdbserver_if_needed) does the following:
131       * checks if gdbserver instrumentation is needed for vge.
132       * if no gdbserver instrumentation needed,
133            returns sb_in
134       * otherwise
135         It will instrument sb_in to allow gdbserver to properly
136         handle breakpoints and single_stepping in sb_in.
137         All the target jumps of sb_in will also be invalidated
138         if these are not yet instrumented for gdbserver.
139         This allows to have single_step working, using a lazily
140         translation of the blocks which are being single stepped
141         in.
142 
143    The typical usage of this function is to call it on the block
144    instrumented by the tool instrument function i.e. :
145      return VG_(instrument_for_gdbserver_if_needed) (sb_out,
146                                                      layout,
147                                                      vge,
148                                                      gWordTy,
149                                                      hWordTy);
150    where sb_out is the block instrumented by the tool.
151 
152    If the block contains a call to a dirty helper that indirectly
153    calls gdbserver, then this dirty helper can (indirectly) change
154    the IP. This implies to jump to this IP after the call to
155    gdbserver. */
156 extern IRSB* VG_(instrument_for_gdbserver_if_needed)
157      (IRSB* sb_in,                   /* block to be instrumented */
158       const VexGuestLayout* layout,
159       const VexGuestExtents* vge,
160       IRType gWordTy, IRType hWordTy);
161 
162 /* reason for which gdbserver connection must be finished */
163 typedef
164    enum {
165       orderly_finish,
166       reset_after_error,
167       reset_after_fork} FinishReason;
168 
169 /* output various gdbserver statistics and status. */
170 extern void VG_(gdbserver_status_output)(void);
171 
172 /* Shared structure between vgdb and the process running
173    under valgrind.
174    We define two variants: a 32 bit and a 64 bit.
175    The valgrind process will use the appropriate size,
176    according to the architecture.
177    vgdb will use what the valgrind process is using. */
178 /* The below takes care that sizes will be 32 or 64 bits,
179    whatever the architecture. A.o., vgdb.c cannot use directly
180    the types from pub_core_threadstate.h as we want vgdb.c to
181    be independent of the arch it is debugging in case of bi-arch
182    Valgrind (e.g. x86 and amd64). So, the valgrind process must
183    give all the needed info/offset to vgdb in the below structure. */
184 
185 typedef
186    struct {
187       // nr of bytes vgdb has written to valgrind
188       volatile int written_by_vgdb;
189       // nr of bytes seen by valgrind
190       volatile int seen_by_valgrind;
191 
192       // address at which gdbserver can be invoked
193       Addr32 invoke_gdbserver;
194 
195       // address of VG_(threads) and various sizes
196       // and offset needed by vgdb.
197       Addr32 threads;
198       int vg_n_threads;
199       int sizeof_ThreadState;
200       int offset_status;
201       int offset_lwpid;
202 
203       // PID of the vgdb that last connected to the Valgrind gdbserver.
204       // It will be set by vgdb after connecting.
205       int vgdb_pid;
206    } VgdbShared32;
207 
208 /* Same as VgdbShared32 but for 64 bits arch. */
209 typedef
210    struct {
211       volatile int written_by_vgdb;
212       volatile int seen_by_valgrind;
213 
214       Addr64 invoke_gdbserver;
215 
216       Addr64 threads;
217       int vg_n_threads;
218       int sizeof_ThreadState;
219       int offset_status;
220       int offset_lwpid;
221 
222       int vgdb_pid;
223    } VgdbShared64;
224 
225 // The below typedef makes the life of valgrind easier.
226 // vgdb must however work explicitely with the specific 32 or 64 bits version.
227 
228 #if VEX_HOST_WORDSIZE == 8
229 typedef VgdbShared64 VgdbShared;
230 #elif VEX_HOST_WORDSIZE == 4
231 typedef VgdbShared32 VgdbShared;
232 #else
233 # error "unexpected wordsize"
234 #endif
235 
236 
237 #endif   // __PUB_CORE_GDBSERVER_H
238 /*--------------------------------------------------------------------*/
239 /*--- end                                                          ---*/
240 /*--------------------------------------------------------------------*/
241