blob: 8185e704f9065afdee7598e3c054a84e59ae2645 [file] [log] [blame]
sewardj8eb8bab2015-07-21 14:44:28 +00001/*--------------------------------------------------------------------*/
2/*--- Implementation of vgdb invoker subsystem on Solaris */
3/* via /proc filesystem and control messages. ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2014-2017 Ivo Raisr <ivosh@ivosh.net>
sewardj8eb8bab2015-07-21 14:44:28 +000011
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/* This module implements vgdb-invoker subsystem as per vgdb.h
31 on Solaris. It differs significantly from the other ptrace-based
32 implementation found in vgdb-invoker-ptrace.c. However the goal
33 is the same - to work on the following scenario:
34
35 - A valgrind process (referred to also as an inferior process)
36 is remotely debugged with gdb.
37 - All threads of the inferior process are stuck in blocking
38 syscalls.
39 - Therefore no thread can process packets received from gdb.
40
41 When module vgdb.c detects this situation then it calls
42 function invoker_invoke_gdbserver() within the context of
43 invoke_gdbserver_in_valgrind_thread thread. The steps of
44 interaction between vgdb and m_gdbserver module are as follows:
45
46 1. Function invoker_invoke_gdbserver() attaches to the inferior
47 process and stops all threads.
48 2. It gets registers of the first thread and modifies them
49 and the stack so that a call to "invoke_gdbserver" function
50 is arranged along with a function parameter.
51 3. Then it creates an agent thread within the inferior process
52 with these modified registers and waits until the agent thread
53 exits.
54 4. Meanwhile in the inferior process function
55 VG_(invoke_gdbserver)() is invoked within the context of the
56 agent thread; all other threads are still stopped.
57 5. The agent thread processes packets from gdb relayed by vgdb.
58 6. Eventually processing is finished and the agent thread exits
59 in function give_control_back_to_vgdb().
60 7. vgdb then detaches from the inferior process and thus resumes
61 all the stopped threads.
62 */
63
64#include "vgdb.h"
65
66#include <assert.h>
67#include <errno.h>
68#include <string.h>
69
70typedef Addr CORE_ADDR;
71
72typedef struct {
73 long cmd;
74 union {
75 long flags;
76 prgregset_t regs;
77 } arg;
78} ctl_t;
79
80/* Process control file /proc/<pid>/ctl.
81 Once this file is closed, PR_RLC flag takes effect and
82 inferior process resumes automatically. */
83static int ctl_fd = -1;
84
85/* Copy LEN bytes of data from vgdb memory at MYADDR
86 to valgrind memory at MEMADDR.
87 On failure (cannot write the valgrind memory)
88 returns the value of errno. */
89static int write_memory(pid_t pid, CORE_ADDR memaddr,
90 const void *myaddr, size_t len)
91{
92 char procname[PATH_MAX];
93 snprintf(procname, sizeof(procname), "/proc/%d/as", pid);
94
95 /* Open the process address-space file. */
96 int as_fd = open(procname, O_WRONLY, 0);
97 if (as_fd < 0) {
98 int error = errno;
99 ERROR(error, "Failed to open %s.\n", procname);
100 return error;
101 }
102
103 if (debuglevel >= 1) {
104 DEBUG(1, "Writing bytes '");
105 size_t i;
106 for (i = 0; i < len; i++)
107 PDEBUG(1, "%02x", ((const unsigned char *) myaddr)[i]);
108 PDEBUG(1, "' to address %#lx.\n", memaddr);
109 }
110
111 ssize_t written = pwrite(as_fd, myaddr, len, memaddr);
112 if ((written < 0) || (written != len)) {
113 int error = errno;
114 ERROR(error, "Failed to write to file %s, memory block of %zu"
115 " bytes at %#lx to %#lx.\n",
116 procname, len, (Addr) myaddr, memaddr);
117 close(as_fd);
118 return error;
119 }
120
121 DEBUG(1, "Written ok.\n");
122 close(as_fd);
123 return 0;
124}
125
126/* Attaches to a process identified by pid and stops all threads. */
127static Bool attach(pid_t pid)
128{
129 char procname[PATH_MAX];
130 snprintf(procname, sizeof(procname), "/proc/%d/ctl", pid);
131
132 DEBUG(1, "Attaching to pid %d.\n", pid);
133
134 /* Open the process control file. */
135 ctl_fd = open(procname, O_WRONLY, 0);
136 if (ctl_fd < 0) {
137 ERROR(errno, "Failed to open %s.\n", procname);
138 return False;
139 }
140
141 DEBUG(1, "Setting run-on-last-close-flag (PR_RLC) to pid %d.\n", pid);
142
143 /* Set run-on-last-close flag. */
144 ctl_t ctl;
145 ctl.cmd = PCSET;
146 ctl.arg.flags = PR_RLC;
147 size_t bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.flags);
148 ssize_t written = write(ctl_fd, (void *) &ctl, bytes);
149 if ((written < 0) || (written != bytes)) {
150 ERROR(errno, "Failed to write to ctl_fd: PCSET + PR_RLC.\n");
151 return False;
152 }
153
154 DEBUG(1, "Stopping process %d.\n", pid);
155
156 /* Stop the whole process - all threads. */
157 ctl.cmd = PCSTOP;
158 bytes = sizeof(ctl.cmd);
159 written = write(ctl_fd, (void *) &ctl, bytes);
160 if ((written < 0) || (written != bytes)) {
161 ERROR(errno, "Failed to write to ctl_fd: PCSTOP.\n");
162 return False;
163 }
164
165 DEBUG(1, "Process %d stopped.\n", pid);
166
167 /* Now confirm it is actually the case. */
168 snprintf(procname, sizeof(procname), "/proc/%d/status", pid);
169 int status_fd = open(procname, O_RDONLY, 0);
170 if (status_fd < 0) {
171 ERROR(errno, "Failed to open %s.\n", procname);
172 return False;
173 }
174
175 pstatus_t pstatus;
176 bytes = read(status_fd, &pstatus, sizeof(pstatus));
177 if ((bytes < 0) || (bytes != sizeof(pstatus))) {
178 ERROR(errno, "Failed to read from %s.\n", procname);
179 close(status_fd);
180 return False;
181 }
182
183 if (pstatus.pr_flags & PR_RLC) {
184 DEBUG(2, "Process %d has run-on-last-close flag set. Good.\n", pid);
185 } else {
186 ERROR(0, "Process %d does not have run-on-last-close flag set!\n", pid);
187 close(status_fd);
188 return False;
189 }
190
191 if (pstatus.pr_lwp.pr_flags & PR_STOPPED) {
192 DEBUG(3, "Process %d seems to be stopped. Good.\n", pid);
193 } else {
194 ERROR(0, "Process %d is not stopped!\n", pid);
195 close(status_fd);
196 return False;
197 }
198
199 close(status_fd);
200 return True;
201}
202
203static void detach(pid_t pid)
204{
205 if (ctl_fd != -1) {
206 close(ctl_fd);
207 ctl_fd = -1;
208 }
209
210 DEBUG(1, "Detached from pid %d.\n", pid);
211}
212
213/* Gets the registers of the first thread. */
214static Bool get_regs(pid_t pid, prgregset_t *regs)
215{
216 char procname[PATH_MAX];
217 snprintf(procname, sizeof(procname), "/proc/%d/lwp/1/lwpstatus", pid);
218
219 DEBUG(1, "Getting registers from the first thread of process %d.\n", pid);
220
221 /* Open the first thread's status file. */
222 int status_fd = open(procname, O_RDONLY, 0);
223 if (status_fd < 0) {
224 ERROR(errno, "Failed to open file %s.\n", procname);
225 return False;
226 }
227
228 lwpstatus_t status;
229 ssize_t bytes = read(status_fd, &status, sizeof(status));
230 if ((bytes < 0) || (bytes != sizeof(status))) {
231 ERROR(errno, "Failed to read from %s.\n", procname);
232 close(status_fd);
233 return False;
234 }
235
236 DEBUG(3, "Registers of thread %d from process %d: ", status.pr_lwpid, pid);
237 unsigned int i;
238 for (i = 0; i < _NGREG; i++) {
239 PDEBUG(3, "%u: %#lx, ", i, (unsigned long) status.pr_reg[i]);
240 }
241 PDEBUG(3, "\n");
242
243 memcpy(regs, &status.pr_reg, sizeof(prgregset_t));
244 close(status_fd);
245 return True;
246}
247
248/* Modifies the register set so that a new stack frame is created
249 for "invoke_gdbserver" function with an extra argument.
250 The argument is written to the stack of the first thread.
251 */
252static Bool setup_stack_frame(pid_t pid, prgregset_t *regs)
253{
254 DEBUG(1, "Setting up new stack frame of process %d.\n", pid);
255
256 /* A specific int value is passed to invoke_gdbserver(), to check
257 everything goes according to the plan. */
258 const int check = 0x8BADF00D; // ate bad food.
259
260 /* A bad return address will be pushed on the stack.
261 Function invoke_gdbserver() cannot return. If it ever returns,
262 a NULL address pushed on the stack should ensure this is
263 detected. */
264 const Addr bad_return = 0;
265
266#if defined(VGA_x86)
267 Addr sp = (*regs)[UESP];
268#elif defined(VGA_amd64)
269 Addr sp = (*regs)[REG_RSP];
270#else
271 I_die_here : (sp) architecture missing in vgdb-invoker-solaris.c
272#endif
273
274 if (shared32 != NULL) {
275 /* vgdb speaking with a 32bit executable. */
276#if defined(VGA_x86) || defined(VGA_amd64)
277 const size_t regsize = 4;
278
279 /* Push check argument on the stack - according to C/ia32 ABI. */
280 sp = sp - regsize;
281 DEBUG(1, "Pushing check argument to process %d memory.\n", pid);
282 assert(regsize == sizeof(check));
283 int error = write_memory(pid, sp, &check, regsize);
284 if (error != 0) {
285 ERROR(error, "Failed to push check argument to process %d memory.\n",
286 pid);
287 detach(pid);
288 return False;
289 }
290
291 sp = sp - regsize;
292 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
293 pid);
294 /* Note that even for a 64 bits vgdb, only 4 bytes
295 of NULL bad_return are written. */
296 error = write_memory(pid, sp, &bad_return, regsize);
297 if (error != 0) {
298 ERROR(error, "Failed to push bad_return return address to process %d "
299 "memory.\n", pid);
300 detach(pid);
301 return False;
302 }
303
304#if defined(VGA_x86)
305 /* Set EBP, ESP, EIP to invoke gdbserver.
306 vgdb is 32bits, speaking with a 32bits process. */
307 (*regs)[EBP] = sp; // bp set to sp
308 (*regs)[UESP] = sp;
309 (*regs)[EIP] = shared32->invoke_gdbserver;
310#elif defined(VGA_amd64)
311 /* Set RBP, RSP, RIP to invoke gdbserver.
312 vgdb is 64bits, speaking with a 32bits process. */
313 (*regs)[REG_RBP] = sp; // bp set to sp
314 (*regs)[REG_RSP] = sp;
315 (*regs)[REG_RIP] = shared32->invoke_gdbserver;
316#else
317 I_die_here : not x86 or amd64 in x86/amd64 section/
318#endif
319
320#else
321 I_die_here : architecture missing in vgdb-invoker-solaris.c
322#endif
323
324 } else if (shared64 != NULL) {
325#if defined(VGA_x86)
326 assert(0); /* 64bits process with a 32bits vgdb - no way */
327#elif defined(VGA_amd64)
328 /* 64bits vgdb speaking with a 64 bit process. */
329 const int regsize = 8;
330
331 /* Give check argument in rdi - according to C/amd64 ABI. */
332 (*regs)[REG_RDI] = check;
333
334 /* Push return address on stack: return to breakaddr. */
335 sp = sp - regsize;
336 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
337 pid);
338 int error = write_memory(pid, sp, &bad_return,
339 sizeof(bad_return));
340 if (error != 0) {
341 ERROR(error, "Failed to push bad_return return address to process %d "
342 "memory.\n", pid);
343 detach(pid);
344 return False;
345 }
346
347 /* set RBP, RSP, RIP to invoke gdbserver */
348 (*regs)[REG_RBP] = sp; // bp set to sp
349 (*regs)[REG_RSP] = sp;
350 (*regs)[REG_RIP] = shared64->invoke_gdbserver;
351#else
352 I_die_here: architecture missing in vgdb-invoker-solaris.c
353#endif
354 } else {
355 assert(0);
356 }
357
358 DEBUG(1, "New stack frame set up for process %d.\n", pid);
359 return True;
360}
361
362/* Creates and starts an agent thread within the inferior process.
363 The agent thread is created stopped and with its held signal set
364 (the signal mask) having all signals except SIGKILL and SIGSTOP
365 blocked. All these signals need to remain blocked while the agent
366 thread is running because valgrind syscall/signal machinery expects
367 that (remember: all valgrind threads are blocked in VgTs_WaitSys
368 - that is the reason why we are invoking the agent, after all).
369 It is necessary to resume the agent thread afterwards.
370 */
371static Bool invoke_agent(pid_t pid, prgregset_t *regs, id_t *agent_lwpid)
372{
373 assert(ctl_fd != -1);
374
375 DEBUG(1, "Creating an agent thread within process %d.\n", pid);
376
377 /* Create the agent thread. */
378 ctl_t ctl;
379 ctl.cmd = PCAGENT;
380 memcpy(&ctl.arg.regs, regs, sizeof(prgregset_t));
381 size_t bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.regs);
382 ssize_t written = write(ctl_fd, (void *) &ctl, bytes);
383 if ((written < 0) || (written != bytes)) {
384 ERROR(errno, "Failed to write to ctl_fd: PCAGENT.\n");
385 return False;
386 }
387
388 DEBUG(1, "Obtaining agent thread lwpid for process %d.\n", pid);
389
390 char procname[PATH_MAX];
391 snprintf(procname, sizeof(procname),
392 "/proc/%d/lwp/agent/lwpstatus", pid);
393
394 int status_fd = open(procname, O_RDONLY, 0);
395 if (status_fd < 0) {
396 /* Operation failed but there is no way to get rid of the agent
397 thread from outside. We are doomed... */
398 ERROR(errno, "Failed to open file %s.\n", procname);
399 return False;
400 }
401
402 lwpstatus_t status;
403 bytes = read(status_fd, &status, sizeof(status));
404 if ((bytes < 0) || (bytes != sizeof(status))) {
405 ERROR(errno, "Failed to read from %s.\n", procname);
406 close(status_fd);
407 return False;
408 }
409
410 close(status_fd);
411 *agent_lwpid = status.pr_lwpid;
412
413 snprintf(procname, sizeof(procname),
414 "/proc/%d/lwp/agent/lwpctl", pid);
415
416 int agent_ctl_fd = open(procname, O_WRONLY, 0);
417 if (agent_ctl_fd < 0) {
418 /* Resuming failed but there is no way to get rid of the agent
419 thread from outside. We are doomed... */
420 ERROR(errno, "Failed to open file %s.\n", procname);
421 return False;
422 }
423
424 DEBUG(1, "Resuming the agent thread for process %d.\n", pid);
425
426 /* Resume the agent thread. */
427 ctl.cmd = PCRUN;
428 ctl.arg.flags = 0;
429 bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.flags);
430 written = write(agent_ctl_fd, (void *) &ctl, bytes);
431 if ((written < 0) || (written != bytes)) {
432 /* Resuming failed but there is no way to get rid of the agent
433 thread from outside. We are doomed... */
434 ERROR(errno, "Failed to write to agent_ctl_fd: PCRUN 0.\n");
435 close(agent_ctl_fd);
436 return False;
437 }
438
439 DEBUG(1, "Agent thread lwpid %d now running within process %d.\n",
440 *agent_lwpid, pid);
441 close(agent_ctl_fd);
442 return True;
443}
444
445/* Waits until the agent thread running inside the inferior
446 process exits. */
447static Bool wait_for_agent_exit(pid_t pid, id_t agent_lwpid)
448{
449 char procname[PATH_MAX];
450 snprintf(procname, sizeof(procname), "/proc/%d/lwp/agent/lwpctl", pid);
451
452 int agent_ctl_fd = open(procname, O_WRONLY, 0);
453 if (agent_ctl_fd < 0) {
454 if (errno == ENOENT) {
455 DEBUG(1, "Agent control file %s no longer exists. This means "
456 "agent thread %d exited meanwhile.\n",
457 procname, agent_lwpid);
458 return True;
459 }
460 ERROR(errno, "Failed to open agent control file %s.\n", procname);
461 return False;
462 }
463
464 DEBUG(1, "Waiting for agent thread %d to exit.\n", agent_lwpid);
465
466 /* Wait until the agent thread stops. This covers also the case
467 when the thread exited. */
468 ctl_t ctl;
469 ctl.cmd = PCWSTOP;
470 size_t bytes = sizeof(ctl.cmd);
471 ssize_t written = write(agent_ctl_fd, (void *) &ctl, bytes);
472 if ((written < 0) || (written != bytes)) {
473 if (errno == ENOENT) {
474 DEBUG(1, "Agent thread lwpid %d has now exited in process %d.\n",
475 agent_lwpid, pid);
476 } else {
477 ERROR(errno, "Failed to write to agent_ctl_fd: PCWSTOP.\n");
478 close(agent_ctl_fd);
479 return False;
480 }
481 }
482
483 close(agent_ctl_fd);
484 return True;
485}
486
487Bool invoker_invoke_gdbserver(pid_t pid)
488{
489 if (attach(pid) != True) {
490 return False;
491 }
492
493 prgregset_t regs;
494 if (get_regs(pid, &regs) != True) {
495 detach(pid);
496 return False;
497 }
498
499 if (setup_stack_frame(pid, &regs) != True) {
500 detach(pid);
501 return False;
502 }
503
504 id_t agent_lwpid;
505 if (invoke_agent(pid, &regs, &agent_lwpid) != True) {
506 detach(pid);
507 return False;
508 }
509
510 if (wait_for_agent_exit(pid, agent_lwpid) != True) {
511 detach(pid);
512 return False;
513 }
514
515 detach(pid);
516 return True;
517}
518
519void invoker_cleanup_restore_and_detach(void *v_pid)
520{
521 detach(*(int *) v_pid);
522}
523
524void invoker_restrictions_msg(void)
525{
526}
527
528void invoker_valgrind_dying(void)
529{
530}