__aeabi_ldivmod: fix sign logic
[minix.git] / lib / libsys / gcov.c
blobbb9b4a8d526e84503a12435f10d7a56236719445
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/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)
27 int r;
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);
36 if(r) {
37 printf("libsys: gcov: safecopy failed (%d)\n", r);
40 pos += size;
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;
59 assert(!gcov_opened);
61 /* write information to buffer */
62 add_int(GCOVOP_OPEN);
63 add_int(strlen(name)+1);
64 add_buff(name, strlen(name)+1);
66 gcov_opened = 1;
68 /* return dummy FILE *. */
69 return &gcov_file;
73 size_t _gcov_fread(void *ptr, size_t itemsize, size_t nitems, FILE *stream)
75 return 0;
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
85 * to the right place.
87 assert(gcov_opened);
88 assert(stream == &gcov_file);
90 /* write information to buffer */
91 add_int(GCOVOP_WRITE);
92 add_int(size);
93 add_buff(ptr, size);
95 return nitems;
98 int _gcov_fclose(FILE *stream)
100 if(!gcov_enable) return EOF;
102 add_int(GCOVOP_CLOSE);
103 assert(gcov_opened);
104 gcov_opened = 0;
105 return 0;
108 int _gcov_fseek(FILE *stream, long offset, int ptrname)
110 return 0;
113 char *_gcov_getenv(const char *name)
115 return NULL;
118 int gcov_flush(cp_grant_id_t grantid, int bufsize)
120 /* Initialize global state. */
121 pos=0;
122 grant = grantid;
123 gcov_buff_sz = bufsize;
124 assert(!gcov_enable);
125 assert(!gcov_opened);
126 gcov_enable = 1;
128 /* Trigger copying.
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.
133 __gcov_flush();
135 /* Mark the end of the data, stop. */
136 add_int(GCOVOP_END);
137 assert(!gcov_opened);
138 assert(gcov_enable);
139 gcov_enable = 0;
141 /* Return number of bytes used in buffer. */
142 return pos;
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)
151 message replymsg;
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);