OSDN Git Service

* config/arm/arm-protos.h (arm_gen_return_addr_mask): New
[pf3gnuchains/gcc-fork.git] / gcc / gcov-io.h
1 /* Machine-independent I/O routines for gcov.
2    Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
3    Contributed by Bob Manson <manson@cygnus.com>.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #ifndef GCC_GCOV_IO_H
23 #define GCC_GCOV_IO_H
24 #include <stdio.h>
25 #include <sys/types.h>
26
27 static int __fetch_long PARAMS ((long *, char *, size_t))
28         ATTRIBUTE_UNUSED;
29 static int __read_long  PARAMS ((long *, FILE *, size_t))
30         ATTRIBUTE_UNUSED;
31 static int __write_long PARAMS ((long, FILE *, size_t))
32         ATTRIBUTE_UNUSED;
33 static int __fetch_gcov_type PARAMS ((gcov_type *, char *, size_t))
34         ATTRIBUTE_UNUSED;
35 static int __store_gcov_type PARAMS ((gcov_type, char *, size_t))
36         ATTRIBUTE_UNUSED;
37 static int __read_gcov_type  PARAMS ((gcov_type *, FILE *, size_t))
38         ATTRIBUTE_UNUSED;
39 static int __write_gcov_type PARAMS ((gcov_type, FILE *, size_t))
40         ATTRIBUTE_UNUSED;
41 static int __write_gcov_string PARAMS ((const char *, size_t, FILE*, long))
42         ATTRIBUTE_UNUSED;
43 static int __read_gcov_string PARAMS ((char *, size_t, FILE*, long))
44         ATTRIBUTE_UNUSED;
45
46 /* These routines only work for signed values.  */
47
48 /* Store a portable representation of VALUE in DEST using BYTES*8-1 bits.
49    Return a non-zero value if VALUE requires more than BYTES*8-1 bits
50    to store.  */
51
52 static int
53 __store_gcov_type (value, dest, bytes)
54      gcov_type value;
55      char *dest;
56      size_t bytes;
57 {
58   int upper_bit = (value < 0 ? 128 : 0);
59   size_t i;
60
61   if (value < 0)
62     {
63       gcov_type oldvalue = value;
64       value = -value;
65       if (oldvalue != -value)
66         return 1;
67     }
68
69   for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
70     dest[i] = value & (i == (bytes - 1) ? 127 : 255);
71     value = value / 256;
72   }
73
74   if (value && value != -1)
75     return 1;
76
77   for(; i < bytes ; i++)
78     dest[i] = 0;
79   dest[bytes - 1] |= upper_bit;
80   return 0;
81 }
82
83 /* Retrieve a quantity containing BYTES*8-1 bits from SOURCE and store
84    the result in DEST. Returns a non-zero value if the value in SOURCE
85    will not fit in DEST.  */
86
87 static int
88 __fetch_gcov_type (dest, source, bytes)
89      gcov_type *dest;
90      char *source;
91      size_t bytes;
92 {
93   gcov_type value = 0;
94   int i;
95
96   for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
97     if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
98       return 1;
99
100   for (; i >= 0; i--)
101     value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
102
103   if ((source[bytes - 1] & 128) && (value > 0))
104     value = - value;
105
106   *dest = value;
107   return 0;
108 }
109
110 static int
111 __fetch_long (dest, source, bytes)
112      long *dest;
113      char *source;
114      size_t bytes;
115 {
116   long value = 0;
117   int i;
118
119   for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
120     if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
121       return 1;
122
123   for (; i >= 0; i--)
124     value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
125
126   if ((source[bytes - 1] & 128) && (value > 0))
127     value = - value;
128
129   *dest = value;
130   return 0;
131 }
132
133 /* Write a BYTES*8-bit quantity to FILE, portably. Returns a non-zero
134    value if the write fails, or if VALUE can't be stored in BYTES*8
135    bits.
136
137    Note that VALUE may not actually be large enough to hold BYTES*8
138    bits, but BYTES characters will be written anyway.
139
140    BYTES may be a maximum of 10.  */
141
142 static int
143 __write_gcov_type (value, file, bytes)
144      gcov_type value;
145      FILE *file;
146      size_t bytes;
147 {
148   char c[10];
149
150   if (bytes > 10 || __store_gcov_type (value, c, bytes))
151     return 1;
152   else
153     return fwrite(c, 1, bytes, file) != bytes;
154 }
155
156 static int
157 __write_long (value, file, bytes)
158      long value;
159      FILE *file;
160      size_t bytes;
161 {
162   char c[10];
163
164   if (bytes > 10 || __store_gcov_type ((gcov_type)value, c, bytes))
165     return 1;
166   else
167     return fwrite(c, 1, bytes, file) != bytes;
168 }
169
170 /* Read a quantity containing BYTES bytes from FILE, portably. Return
171    a non-zero value if the read fails or if the value will not fit
172    in DEST.
173
174    Note that DEST may not be large enough to hold all of the requested
175    data, but the function will read BYTES characters anyway.
176
177    BYTES may be a maximum of 10.  */
178
179 static int
180 __read_gcov_type (dest, file, bytes)
181      gcov_type *dest;
182      FILE *file;
183      size_t bytes;
184 {
185   char c[10];
186
187   if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
188     return 1;
189   else
190     return __fetch_gcov_type (dest, c, bytes);
191 }
192
193 static int
194 __read_long (dest, file, bytes)
195      long *dest;
196      FILE *file;
197      size_t bytes;
198 {
199   char c[10];
200
201   if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
202     return 1;
203   else
204     return __fetch_long (dest, c, bytes);
205 }
206
207
208 /* Writes string in gcov format.  */
209
210 static int
211 __write_gcov_string (string, length, file, delim)
212      const char *string;
213      size_t length;
214      FILE *file;
215      long delim;
216 {
217   size_t temp = length + 1;
218
219   /* delimiter */
220   if (__write_long (delim, file, 4) != 0)
221     return 1;
222
223   if (__write_long (length, file, 4) != 0)
224     return 1;
225
226   if (fwrite (string, temp, 1, file) != 1)
227     return 1;
228
229   temp &= 3;
230
231   if (temp)
232     {
233       char c[4];
234
235       c[0] = c[1] = c[2] = c[3] = 0;
236
237       if (fwrite (c, sizeof (char), 4 - temp, file) != 4 - temp)
238         return 1;
239     }
240
241   if (__write_long (delim, file, 4) != 0)
242     return 1;
243
244   return 0;
245 }
246
247 /* Reads string in gcov format.  */
248
249
250 static int
251 __read_gcov_string (string, max_length, file, delim)
252      char *string;
253      size_t max_length;
254      FILE *file;
255      long delim;
256 {
257   long delim_from_file;
258   long length;
259   long read_length;
260   long tmp;
261
262   if (__read_long (&delim_from_file, file, 4) != 0)
263     return 1;
264
265   if (delim_from_file != delim)
266     return 1;
267
268   if (__read_long (&length, file, 4) != 0)
269     return 1;
270
271   if (length > (long) max_length)
272     read_length = max_length;
273   else
274     read_length = length;
275
276   tmp = (((length + 1) - 1) / 4 + 1) * 4;
277   /* This is the size occupied by the string in the file */
278
279   if (fread (string, read_length, 1, file) != 1)
280     return 1;
281
282   string[read_length] = 0;
283
284   if (fseek (file, tmp - read_length, SEEK_CUR) < 0)
285     return 1;
286
287   if (__read_long (&delim_from_file, file, 4) != 0)
288     return 1;
289
290   if (delim_from_file != delim)
291     return 1;
292
293   return 0;
294 }
295
296
297 #endif /* ! GCC_GCOV_IO_H */