forked from Stichting-MINIX-Research-Foundation/minix
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgcov.c
More file actions
161 lines (127 loc) · 3.37 KB
/
Copy pathgcov.c
File metadata and controls
161 lines (127 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* This code can be linked into minix servers that are compiled
* with gcc gcov flags.
* Author: Anton Kuijsten
*/
#include <lib.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
#include <minix/syslib.h>
#include <minix/gcov.h>
static int grant, pos; /* data-buffer pointer from user space tool */
static int gcov_enable=0; /* nothing will be done with gcov-data if zero */
static int gcov_buff_sz; /* size of user space buffer */
static FILE gcov_file; /* used as fopen() return value. */
static int gcov_opened;
/* copies <size> bytes from <ptr> to <gcov_buff> */
static void add_buff(void *ptr, int size)
{
int r;
assert(pos <= gcov_buff_sz);
if(pos+size > gcov_buff_sz) {
size = pos - gcov_buff_sz;
}
r = sys_safecopyto(VFS_PROC_NR, grant, pos, (vir_bytes)ptr, size);
if(r) {
printf("libsys: gcov: safecopy failed (%d)\n", r);
}
pos += size;
assert(pos <= gcov_buff_sz);
}
/* easy wrapper for add_buff */
static void add_int(int value)
{
add_buff((void *) &value, sizeof(int));
}
/* These functions are meant to replace standard file
* system calls (fopen, etc)
*/
FILE *_gcov_fopen(char *name, char *mode)
{
if(!gcov_enable) return NULL;
assert(!gcov_opened);
/* write information to buffer */
add_int(GCOVOP_OPEN);
add_int(strlen(name)+1);
add_buff(name, strlen(name)+1);
gcov_opened = 1;
/* return dummy FILE *. */
return &gcov_file;
}
size_t _gcov_fread(void *ptr, size_t itemsize, size_t nitems, FILE *stream)
{
return 0;
}
size_t _gcov_fwrite(void *ptr, size_t itemsize, size_t nitems, FILE *stream)
{
int size = itemsize * nitems;
if(!gcov_enable) return -1;
/* only have one file open at a time to ensure writes go
* to the right place.
*/
assert(gcov_opened);
assert(stream == &gcov_file);
/* write information to buffer */
add_int(GCOVOP_WRITE);
add_int(size);
add_buff(ptr, size);
return nitems;
}
int _gcov_fclose(FILE *stream)
{
if(!gcov_enable) return EOF;
add_int(GCOVOP_CLOSE);
assert(gcov_opened);
gcov_opened = 0;
return 0;
}
int _gcov_fseek(FILE *stream, long offset, int ptrname)
{
return 0;
}
char *_gcov_getenv(const char *name)
{
return NULL;
}
int gcov_flush(cp_grant_id_t grantid, int bufsize)
{
/* Initialize global state. */
pos=0;
grant = grantid;
gcov_buff_sz = bufsize;
assert(!gcov_enable);
assert(!gcov_opened);
gcov_enable = 1;
/* Trigger copying.
* This function is not always available, but there is a do-nothing
* version in libc so that executables can be linked even without
* this code ever being activated.
*/
__gcov_flush();
/* Mark the end of the data, stop. */
add_int(GCOVOP_END);
assert(!gcov_opened);
assert(gcov_enable);
gcov_enable = 0;
/* Return number of bytes used in buffer. */
return pos;
}
/* This function can be called to perform the copying.
* It sends its own reply message and can thus be
* registered as a SEF * callback.
*/
int do_gcov_flush_impl(message *msg)
{
message replymsg;
memset(&replymsg, 0, sizeof(replymsg));
assert(msg->m_type == COMMON_REQ_GCOV_DATA);
assert(msg->m_source == VFS_PROC_NR);
replymsg.m_type = gcov_flush(msg->m_lc_vfs_gcov.grant,
msg->m_lc_vfs_gcov.buff_sz);
return ipc_send(msg->m_source, &replymsg);
}