1 /* This code can be linked into minix servers that are compiled
3 * Author: Anton Kuijsten
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
)
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
);
42 printf("libsys: gcov: safecopy failed (%d)\n", r
);
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
;
66 /* write information to buffer */
68 add_int(strlen(name
)+1);
69 add_buff(name
, strlen(name
)+1);
73 /* return dummy FILE *. */
78 size_t _gcov_fread(void *ptr
, size_t itemsize
, size_t nitems
, FILE *stream
)
83 size_t _gcov_fwrite(const void *ptr
, size_t itemsize
, size_t nitems
,
86 int size
= itemsize
* nitems
;
88 if(!gcov_enable
) return -1;
90 /* only have one file open at a time to ensure writes go
94 assert(stream
== &gcov_file
);
96 /* write information to buffer */
97 add_int(GCOVOP_WRITE
);
104 int _gcov_fclose(FILE *stream
)
106 if(!gcov_enable
) return EOF
;
108 add_int(GCOVOP_CLOSE
);
114 int _gcov_fseek(FILE *stream
, long offset
, int ptrname
)
119 char *_gcov_getenv(const char *name
)
124 int gcov_flush(endpoint_t ep
, cp_grant_id_t grantid
, size_t bufsize
)
126 /* Initialize global state. */
130 gcov_buff_sz
= bufsize
;
131 assert(!gcov_enable
);
132 assert(!gcov_opened
);
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.
142 /* Mark the end of the data, stop. */
144 assert(!gcov_opened
);
149 /* Return number of bytes used in buffer. */
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
)
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
);