xref: /minix3/minix/servers/vfs/gcov.c (revision 3ac58492b3d3709bad0ae9c60a137f63a90960b7)
1433d6423SLionel Sambuc 
2*3ac58492SDavid van Moolenbroek #include <string.h>
3*3ac58492SDavid van Moolenbroek 
4433d6423SLionel Sambuc #include "fs.h"
5433d6423SLionel Sambuc #include "file.h"
6433d6423SLionel Sambuc 
7433d6423SLionel Sambuc /*===========================================================================*
8433d6423SLionel Sambuc  *				do_gcov_flush				     *
9433d6423SLionel Sambuc  *===========================================================================*/
do_gcov_flush(void)10*3ac58492SDavid van Moolenbroek int do_gcov_flush(void)
11433d6423SLionel Sambuc {
12433d6423SLionel Sambuc /* A userland tool has requested the gcov data from another
13433d6423SLionel Sambuc  * process (possibly vfs itself). Grant the target process
14433d6423SLionel Sambuc  * access to the supplied buffer, and perform the call that
15433d6423SLionel Sambuc  * makes the target copy its buffer to the caller (incl vfs
16433d6423SLionel Sambuc  * itself).
17433d6423SLionel Sambuc  */
18*3ac58492SDavid van Moolenbroek   char label[LABEL_MAX];
19*3ac58492SDavid van Moolenbroek   vir_bytes labeladdr, buf;
20*3ac58492SDavid van Moolenbroek   size_t labellen, size;
21*3ac58492SDavid van Moolenbroek   endpoint_t endpt;
22433d6423SLionel Sambuc   cp_grant_id_t grantid;
23*3ac58492SDavid van Moolenbroek   int r;
24433d6423SLionel Sambuc   message m;
25433d6423SLionel Sambuc 
26*3ac58492SDavid van Moolenbroek   /*
27*3ac58492SDavid van Moolenbroek    * Something as sensitive as system service coverage information must be
28*3ac58492SDavid van Moolenbroek    * call to the target service, and so it is not impossible to deadlock the
29*3ac58492SDavid van Moolenbroek    * system with this call.
30433d6423SLionel Sambuc    */
31433d6423SLionel Sambuc   if (!super_user) return(EPERM);
32433d6423SLionel Sambuc 
33*3ac58492SDavid van Moolenbroek   labeladdr = job_m_in.m_lc_vfs_gcov.label;
34*3ac58492SDavid van Moolenbroek   labellen = job_m_in.m_lc_vfs_gcov.labellen;
35*3ac58492SDavid van Moolenbroek   buf = job_m_in.m_lc_vfs_gcov.buf;
36*3ac58492SDavid van Moolenbroek   size = job_m_in.m_lc_vfs_gcov.buflen;
37*3ac58492SDavid van Moolenbroek 
38*3ac58492SDavid van Moolenbroek   /* Retrieve and look up the target label. */
39*3ac58492SDavid van Moolenbroek   if (labellen >= sizeof(label))
40*3ac58492SDavid van Moolenbroek 	return EINVAL;
41*3ac58492SDavid van Moolenbroek   if ((r = sys_datacopy_wrapper(who_e, labeladdr, SELF, (vir_bytes)label,
42*3ac58492SDavid van Moolenbroek     labellen)) != OK)
43*3ac58492SDavid van Moolenbroek 	return r;
44*3ac58492SDavid van Moolenbroek   label[labellen - 1] = '\0';
45*3ac58492SDavid van Moolenbroek 
46*3ac58492SDavid van Moolenbroek   if ((r = ds_retrieve_label_endpt(label, &endpt)) != OK)
47*3ac58492SDavid van Moolenbroek 	return r;
48*3ac58492SDavid van Moolenbroek 
49*3ac58492SDavid van Moolenbroek   /* Hack: init is the only non-system process with a valid label. */
50*3ac58492SDavid van Moolenbroek   if (endpt == INIT_PROC_NR)
51*3ac58492SDavid van Moolenbroek 	return ENOENT;
52433d6423SLionel Sambuc 
53433d6423SLionel Sambuc   /* Grant target process to requestor's buffer. */
54*3ac58492SDavid van Moolenbroek   if ((grantid = cpf_grant_magic(endpt, who_e, buf, size, CPF_WRITE)) < 0) {
55433d6423SLionel Sambuc 	printf("VFS: gcov_flush: grant failed\n");
56433d6423SLionel Sambuc 	return(ENOMEM);
57433d6423SLionel Sambuc   }
58433d6423SLionel Sambuc 
59*3ac58492SDavid van Moolenbroek   if (endpt == VFS_PROC_NR) {
60433d6423SLionel Sambuc 	/* Request is for VFS itself. */
61*3ac58492SDavid van Moolenbroek 	r = gcov_flush(VFS_PROC_NR, grantid, size);
62433d6423SLionel Sambuc   } else {
63433d6423SLionel Sambuc 	/* Perform generic GCOV request. */
64*3ac58492SDavid van Moolenbroek 	memset(&m, 0, sizeof(m));
65*3ac58492SDavid van Moolenbroek 	m.m_vfs_lsys_gcov.grant = grantid;
66*3ac58492SDavid van Moolenbroek 	m.m_vfs_lsys_gcov.size = size;
67*3ac58492SDavid van Moolenbroek 	r = _taskcall(endpt, COMMON_REQ_GCOV_DATA, &m);
68433d6423SLionel Sambuc   }
69433d6423SLionel Sambuc 
70433d6423SLionel Sambuc   cpf_revoke(grantid);
71433d6423SLionel Sambuc 
72433d6423SLionel Sambuc   return(r);
73433d6423SLionel Sambuc }
74