1 /* This code can be linked into minix servers that are compiled
3 * Author: Anton Kuijsten
15 #include <minix/syslib.h>
16 #include <minix/gcov.h>
18 static int grant
, pos
; /* data-buffer pointer from user space tool */
19 static int gcov_enable
=0; /* nothing will be done with gcov-data if zero */
20 static int gcov_buff_sz
; /* size of user space buffer */
21 static FILE gcov_file
; /* used as fopen() return value. */
22 static int gcov_opened
;
24 /* copies <size> bytes from <ptr> to <gcov_buff> */
25 static void add_buff(void *ptr
, int size
)
28 assert(pos
<= gcov_buff_sz
);
30 if(pos
+size
> gcov_buff_sz
) {
31 size
= pos
- gcov_buff_sz
;
34 r
= sys_safecopyto(VFS_PROC_NR
, grant
, pos
, (vir_bytes
)ptr
, size
);
37 printf("libsys: gcov: safecopy failed (%d)\n", r
);
42 assert(pos
<= gcov_buff_sz
);
45 /* easy wrapper for add_buff */
46 static void add_int(int value
)
48 add_buff((void *) &value
, sizeof(int));
51 /* These functions are meant to replace standard file
52 * system calls (fopen, etc)
55 FILE *_gcov_fopen(char *name
, char *mode
)
57 if(!gcov_enable
) return NULL
;
61 /* write information to buffer */
63 add_int(strlen(name
)+1);
64 add_buff(name
, strlen(name
)+1);
68 /* return dummy FILE *. */
73 size_t _gcov_fread(void *ptr
, size_t itemsize
, size_t nitems
, FILE *stream
)
78 size_t _gcov_fwrite(void *ptr
, size_t itemsize
, size_t nitems
, FILE *stream
)
80 int size
= itemsize
* nitems
;
82 if(!gcov_enable
) return -1;
84 /* only have one file open at a time to ensure writes go
88 assert(stream
== &gcov_file
);
90 /* write information to buffer */
91 add_int(GCOVOP_WRITE
);
98 int _gcov_fclose(FILE *stream
)
100 if(!gcov_enable
) return EOF
;
102 add_int(GCOVOP_CLOSE
);
108 int _gcov_fseek(FILE *stream
, long offset
, int ptrname
)
113 char *_gcov_getenv(const char *name
)
118 int gcov_flush(cp_grant_id_t grantid
, int bufsize
)
120 /* Initialize global state. */
123 gcov_buff_sz
= bufsize
;
124 assert(!gcov_enable
);
125 assert(!gcov_opened
);
129 * This function is not always available, but there is a do-nothing
130 * version in libc so that executables can be linked even without
131 * this code ever being activated.
135 /* Mark the end of the data, stop. */
137 assert(!gcov_opened
);
141 /* Return number of bytes used in buffer. */
145 /* This function can be called to perform the copying.
146 * It sends its own reply message and can thus be
147 * registered as a SEF * callback.
149 int do_gcov_flush_impl(message
*msg
)
152 memset(&replymsg
, 0, sizeof(replymsg
));
154 assert(msg
->m_type
== COMMON_REQ_GCOV_DATA
);
155 assert(msg
->m_source
== VFS_PROC_NR
);
157 replymsg
.m_type
= gcov_flush(msg
->GCOV_GRANT
, msg
->GCOV_BUFF_SZ
);
158 return send(msg
->m_source
, &replymsg
);