etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libsys / gcov.c
blobae3857e50015883c54b9c62adb51dff97212f54a
1 /* This code can be linked into minix servers that are compiled
2 * with gcc gcov flags.
3 * Author: Anton Kuijsten
4 */
6 #include <lib.h>
7 #include <stdio.h>
8 #include <sys/types.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14 #include <assert.h>
15 #include <minix/syslib.h>
16 #include <minix/sysutil.h>
17 #include <minix/gcov.h>
19 static endpoint_t endpt = NONE; /* endpoint of requesting service, or NONE */
20 static cp_grant_id_t grant; /* grant to write results into during request */
21 static int pos; /* data-buffer pointer from user space tool */
22 static int gcov_enable=0; /* nothing will be done with gcov-data if zero */
23 static int gcov_buff_sz; /* size of user space buffer */
24 static FILE gcov_file; /* used as fopen() return value. */
25 static int gcov_opened;
27 /* copies <size> bytes from <ptr> to <gcov_buff> */
28 static void add_buff(const void *ptr, int size)
30 int r;
32 assert(endpt != NONE);
33 assert(pos <= gcov_buff_sz);
35 if(pos+size > gcov_buff_sz) {
36 size = pos - gcov_buff_sz;
39 r = sys_safecopyto(endpt, grant, pos, (vir_bytes)ptr, size);
41 if(r) {
42 printf("libsys: gcov: safecopy failed (%d)\n", r);
45 pos += size;
47 assert(pos <= gcov_buff_sz);
50 /* easy wrapper for add_buff */
51 static void add_int(int value)
53 add_buff((void *) &value, sizeof(int));
56 /* These functions are meant to replace standard file
57 * system calls (fopen, etc)
60 FILE *_gcov_fopen(const char *name, const char *mode)
62 if(!gcov_enable) return NULL;
64 assert(!gcov_opened);
66 /* write information to buffer */
67 add_int(GCOVOP_OPEN);
68 add_int(strlen(name)+1);
69 add_buff(name, strlen(name)+1);
71 gcov_opened = 1;
73 /* return dummy FILE *. */
74 return &gcov_file;
78 size_t _gcov_fread(void *ptr, size_t itemsize, size_t nitems, FILE *stream)
80 return 0;
83 size_t _gcov_fwrite(const void *ptr, size_t itemsize, size_t nitems,
84 FILE *stream)
86 int size = itemsize * nitems;
88 if(!gcov_enable) return -1;
90 /* only have one file open at a time to ensure writes go
91 * to the right place.
93 assert(gcov_opened);
94 assert(stream == &gcov_file);
96 /* write information to buffer */
97 add_int(GCOVOP_WRITE);
98 add_int(size);
99 add_buff(ptr, size);
101 return nitems;
104 int _gcov_fclose(FILE *stream)
106 if(!gcov_enable) return EOF;
108 add_int(GCOVOP_CLOSE);
109 assert(gcov_opened);
110 gcov_opened = 0;
111 return 0;
114 int _gcov_fseek(FILE *stream, long offset, int ptrname)
116 return 0;
119 char *_gcov_getenv(const char *name)
121 return NULL;
124 int gcov_flush(endpoint_t ep, cp_grant_id_t grantid, size_t bufsize)
126 /* Initialize global state. */
127 pos=0;
128 endpt = ep;
129 grant = grantid;
130 gcov_buff_sz = bufsize;
131 assert(!gcov_enable);
132 assert(!gcov_opened);
133 gcov_enable = 1;
135 /* Trigger copying.
136 * This function is not always available, but there is a do-nothing
137 * version in libc so that executables can be linked even without
138 * this code ever being activated.
140 __gcov_flush();
142 /* Mark the end of the data, stop. */
143 add_int(GCOVOP_END);
144 assert(!gcov_opened);
145 assert(gcov_enable);
146 gcov_enable = 0;
147 endpt = NONE;
149 /* Return number of bytes used in buffer. */
150 return pos;
153 /* This function can be called to perform the copying.
154 * It sends its own reply message and can thus be
155 * registered as a SEF * callback.
157 int do_gcov_flush_impl(message *msg)
159 message replymsg;
160 memset(&replymsg, 0, sizeof(replymsg));
162 assert(msg->m_type == COMMON_REQ_GCOV_DATA);
164 replymsg.m_type = gcov_flush(msg->m_source, msg->m_vfs_lsys_gcov.grant,
165 msg->m_vfs_lsys_gcov.size);
166 return ipc_send(msg->m_source, &replymsg);