Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-2.6] / kernel / gcov / gcc_3_4.c
1 /*
2  *  This code provides functions to handle gcc's profiling data format
3  *  introduced with gcc 3.4. Future versions of gcc may change the gcov
4  *  format (as happened before), so all format-specific information needs
5  *  to be kept modular and easily exchangeable.
6  *
7  *  This file is based on gcc-internal definitions. Functions and data
8  *  structures are defined to be compatible with gcc counterparts.
9  *  For a better understanding, refer to gcc source: gcc/gcov-io.h.
10  *
11  *    Copyright IBM Corp. 2009
12  *    Author(s): Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
13  *
14  *    Uses gcc-internal data definitions.
15  */
16
17 #include <linux/errno.h>
18 #include <linux/slab.h>
19 #include <linux/string.h>
20 #include <linux/seq_file.h>
21 #include <linux/vmalloc.h>
22 #include "gcov.h"
23
24 /* Symbolic links to be created for each profiling data file. */
25 const struct gcov_link gcov_link[] = {
26         { OBJ_TREE, "gcno" },   /* Link to .gcno file in $(objtree). */
27         { 0, NULL},
28 };
29
30 /*
31  * Determine whether a counter is active. Based on gcc magic. Doesn't change
32  * at run-time.
33  */
34 static int counter_active(struct gcov_info *info, unsigned int type)
35 {
36         return (1 << type) & info->ctr_mask;
37 }
38
39 /* Determine number of active counters. Based on gcc magic. */
40 static unsigned int num_counter_active(struct gcov_info *info)
41 {
42         unsigned int i;
43         unsigned int result = 0;
44
45         for (i = 0; i < GCOV_COUNTERS; i++) {
46                 if (counter_active(info, i))
47                         result++;
48         }
49         return result;
50 }
51
52 /**
53  * gcov_info_reset - reset profiling data to zero
54  * @info: profiling data set
55  */
56 void gcov_info_reset(struct gcov_info *info)
57 {
58         unsigned int active = num_counter_active(info);
59         unsigned int i;
60
61         for (i = 0; i < active; i++) {
62                 memset(info->counts[i].values, 0,
63                        info->counts[i].num * sizeof(gcov_type));
64         }
65 }
66
67 /**
68  * gcov_info_is_compatible - check if profiling data can be added
69  * @info1: first profiling data set
70  * @info2: second profiling data set
71  *
72  * Returns non-zero if profiling data can be added, zero otherwise.
73  */
74 int gcov_info_is_compatible(struct gcov_info *info1, struct gcov_info *info2)
75 {
76         return (info1->stamp == info2->stamp);
77 }
78
79 /**
80  * gcov_info_add - add up profiling data
81  * @dest: profiling data set to which data is added
82  * @source: profiling data set which is added
83  *
84  * Adds profiling counts of @source to @dest.
85  */
86 void gcov_info_add(struct gcov_info *dest, struct gcov_info *source)
87 {
88         unsigned int i;
89         unsigned int j;
90
91         for (i = 0; i < num_counter_active(dest); i++) {
92                 for (j = 0; j < dest->counts[i].num; j++) {
93                         dest->counts[i].values[j] +=
94                                 source->counts[i].values[j];
95                 }
96         }
97 }
98
99 /* Get size of function info entry. Based on gcc magic. */
100 static size_t get_fn_size(struct gcov_info *info)
101 {
102         size_t size;
103
104         size = sizeof(struct gcov_fn_info) + num_counter_active(info) *
105                sizeof(unsigned int);
106         if (__alignof__(struct gcov_fn_info) > sizeof(unsigned int))
107                 size = ALIGN(size, __alignof__(struct gcov_fn_info));
108         return size;
109 }
110
111 /* Get address of function info entry. Based on gcc magic. */
112 static struct gcov_fn_info *get_fn_info(struct gcov_info *info, unsigned int fn)
113 {
114         return (struct gcov_fn_info *)
115                 ((char *) info->functions + fn * get_fn_size(info));
116 }
117
118 /**
119  * gcov_info_dup - duplicate profiling data set
120  * @info: profiling data set to duplicate
121  *
122  * Return newly allocated duplicate on success, %NULL on error.
123  */
124 struct gcov_info *gcov_info_dup(struct gcov_info *info)
125 {
126         struct gcov_info *dup;
127         unsigned int i;
128         unsigned int active;
129
130         /* Duplicate gcov_info. */
131         active = num_counter_active(info);
132         dup = kzalloc(sizeof(struct gcov_info) +
133                       sizeof(struct gcov_ctr_info) * active, GFP_KERNEL);
134         if (!dup)
135                 return NULL;
136         dup->version            = info->version;
137         dup->stamp              = info->stamp;
138         dup->n_functions        = info->n_functions;
139         dup->ctr_mask           = info->ctr_mask;
140         /* Duplicate filename. */
141         dup->filename           = kstrdup(info->filename, GFP_KERNEL);
142         if (!dup->filename)
143                 goto err_free;
144         /* Duplicate table of functions. */
145         dup->functions = kmemdup(info->functions, info->n_functions *
146                                  get_fn_size(info), GFP_KERNEL);
147         if (!dup->functions)
148                 goto err_free;
149         /* Duplicate counter arrays. */
150         for (i = 0; i < active ; i++) {
151                 struct gcov_ctr_info *ctr = &info->counts[i];
152                 size_t size = ctr->num * sizeof(gcov_type);
153
154                 dup->counts[i].num = ctr->num;
155                 dup->counts[i].merge = ctr->merge;
156                 dup->counts[i].values = vmalloc(size);
157                 if (!dup->counts[i].values)
158                         goto err_free;
159                 memcpy(dup->counts[i].values, ctr->values, size);
160         }
161         return dup;
162
163 err_free:
164         gcov_info_free(dup);
165         return NULL;
166 }
167
168 /**
169  * gcov_info_free - release memory for profiling data set duplicate
170  * @info: profiling data set duplicate to free
171  */
172 void gcov_info_free(struct gcov_info *info)
173 {
174         unsigned int active = num_counter_active(info);
175         unsigned int i;
176
177         for (i = 0; i < active ; i++)
178                 vfree(info->counts[i].values);
179         kfree(info->functions);
180         kfree(info->filename);
181         kfree(info);
182 }
183
184 /**
185  * struct type_info - iterator helper array
186  * @ctr_type: counter type
187  * @offset: index of the first value of the current function for this type
188  *
189  * This array is needed to convert the in-memory data format into the in-file
190  * data format:
191  *
192  * In-memory:
193  *   for each counter type
194  *     for each function
195  *       values
196  *
197  * In-file:
198  *   for each function
199  *     for each counter type
200  *       values
201  *
202  * See gcc source gcc/gcov-io.h for more information on data organization.
203  */
204 struct type_info {
205         int ctr_type;
206         unsigned int offset;
207 };
208
209 /**
210  * struct gcov_iterator - specifies current file position in logical records
211  * @info: associated profiling data
212  * @record: record type
213  * @function: function number
214  * @type: counter type
215  * @count: index into values array
216  * @num_types: number of counter types
217  * @type_info: helper array to get values-array offset for current function
218  */
219 struct gcov_iterator {
220         struct gcov_info *info;
221
222         int record;
223         unsigned int function;
224         unsigned int type;
225         unsigned int count;
226
227         int num_types;
228         struct type_info type_info[0];
229 };
230
231 static struct gcov_fn_info *get_func(struct gcov_iterator *iter)
232 {
233         return get_fn_info(iter->info, iter->function);
234 }
235
236 static struct type_info *get_type(struct gcov_iterator *iter)
237 {
238         return &iter->type_info[iter->type];
239 }
240
241 /**
242  * gcov_iter_new - allocate and initialize profiling data iterator
243  * @info: profiling data set to be iterated
244  *
245  * Return file iterator on success, %NULL otherwise.
246  */
247 struct gcov_iterator *gcov_iter_new(struct gcov_info *info)
248 {
249         struct gcov_iterator *iter;
250
251         iter = kzalloc(sizeof(struct gcov_iterator) +
252                        num_counter_active(info) * sizeof(struct type_info),
253                        GFP_KERNEL);
254         if (iter)
255                 iter->info = info;
256
257         return iter;
258 }
259
260 /**
261  * gcov_iter_free - release memory for iterator
262  * @iter: file iterator to free
263  */
264 void gcov_iter_free(struct gcov_iterator *iter)
265 {
266         kfree(iter);
267 }
268
269 /**
270  * gcov_iter_get_info - return profiling data set for given file iterator
271  * @iter: file iterator
272  */
273 struct gcov_info *gcov_iter_get_info(struct gcov_iterator *iter)
274 {
275         return iter->info;
276 }
277
278 /**
279  * gcov_iter_start - reset file iterator to starting position
280  * @iter: file iterator
281  */
282 void gcov_iter_start(struct gcov_iterator *iter)
283 {
284         int i;
285
286         iter->record = 0;
287         iter->function = 0;
288         iter->type = 0;
289         iter->count = 0;
290         iter->num_types = 0;
291         for (i = 0; i < GCOV_COUNTERS; i++) {
292                 if (counter_active(iter->info, i)) {
293                         iter->type_info[iter->num_types].ctr_type = i;
294                         iter->type_info[iter->num_types++].offset = 0;
295                 }
296         }
297 }
298
299 /* Mapping of logical record number to actual file content. */
300 #define RECORD_FILE_MAGIC       0
301 #define RECORD_GCOV_VERSION     1
302 #define RECORD_TIME_STAMP       2
303 #define RECORD_FUNCTION_TAG     3
304 #define RECORD_FUNCTON_TAG_LEN  4
305 #define RECORD_FUNCTION_IDENT   5
306 #define RECORD_FUNCTION_CHECK   6
307 #define RECORD_COUNT_TAG        7
308 #define RECORD_COUNT_LEN        8
309 #define RECORD_COUNT            9
310
311 /**
312  * gcov_iter_next - advance file iterator to next logical record
313  * @iter: file iterator
314  *
315  * Return zero if new position is valid, non-zero if iterator has reached end.
316  */
317 int gcov_iter_next(struct gcov_iterator *iter)
318 {
319         switch (iter->record) {
320         case RECORD_FILE_MAGIC:
321         case RECORD_GCOV_VERSION:
322         case RECORD_FUNCTION_TAG:
323         case RECORD_FUNCTON_TAG_LEN:
324         case RECORD_FUNCTION_IDENT:
325         case RECORD_COUNT_TAG:
326                 /* Advance to next record */
327                 iter->record++;
328                 break;
329         case RECORD_COUNT:
330                 /* Advance to next count */
331                 iter->count++;
332                 /* fall through */
333         case RECORD_COUNT_LEN:
334                 if (iter->count < get_func(iter)->n_ctrs[iter->type]) {
335                         iter->record = 9;
336                         break;
337                 }
338                 /* Advance to next counter type */
339                 get_type(iter)->offset += iter->count;
340                 iter->count = 0;
341                 iter->type++;
342                 /* fall through */
343         case RECORD_FUNCTION_CHECK:
344                 if (iter->type < iter->num_types) {
345                         iter->record = 7;
346                         break;
347                 }
348                 /* Advance to next function */
349                 iter->type = 0;
350                 iter->function++;
351                 /* fall through */
352         case RECORD_TIME_STAMP:
353                 if (iter->function < iter->info->n_functions)
354                         iter->record = 3;
355                 else
356                         iter->record = -1;
357                 break;
358         }
359         /* Check for EOF. */
360         if (iter->record == -1)
361                 return -EINVAL;
362         else
363                 return 0;
364 }
365
366 /**
367  * seq_write_gcov_u32 - write 32 bit number in gcov format to seq_file
368  * @seq: seq_file handle
369  * @v: value to be stored
370  *
371  * Number format defined by gcc: numbers are recorded in the 32 bit
372  * unsigned binary form of the endianness of the machine generating the
373  * file.
374  */
375 static int seq_write_gcov_u32(struct seq_file *seq, u32 v)
376 {
377         return seq_write(seq, &v, sizeof(v));
378 }
379
380 /**
381  * seq_write_gcov_u64 - write 64 bit number in gcov format to seq_file
382  * @seq: seq_file handle
383  * @v: value to be stored
384  *
385  * Number format defined by gcc: numbers are recorded in the 32 bit
386  * unsigned binary form of the endianness of the machine generating the
387  * file. 64 bit numbers are stored as two 32 bit numbers, the low part
388  * first.
389  */
390 static int seq_write_gcov_u64(struct seq_file *seq, u64 v)
391 {
392         u32 data[2];
393
394         data[0] = (v & 0xffffffffUL);
395         data[1] = (v >> 32);
396         return seq_write(seq, data, sizeof(data));
397 }
398
399 /**
400  * gcov_iter_write - write data for current pos to seq_file
401  * @iter: file iterator
402  * @seq: seq_file handle
403  *
404  * Return zero on success, non-zero otherwise.
405  */
406 int gcov_iter_write(struct gcov_iterator *iter, struct seq_file *seq)
407 {
408         int rc = -EINVAL;
409
410         switch (iter->record) {
411         case RECORD_FILE_MAGIC:
412                 rc = seq_write_gcov_u32(seq, GCOV_DATA_MAGIC);
413                 break;
414         case RECORD_GCOV_VERSION:
415                 rc = seq_write_gcov_u32(seq, iter->info->version);
416                 break;
417         case RECORD_TIME_STAMP:
418                 rc = seq_write_gcov_u32(seq, iter->info->stamp);
419                 break;
420         case RECORD_FUNCTION_TAG:
421                 rc = seq_write_gcov_u32(seq, GCOV_TAG_FUNCTION);
422                 break;
423         case RECORD_FUNCTON_TAG_LEN:
424                 rc = seq_write_gcov_u32(seq, 2);
425                 break;
426         case RECORD_FUNCTION_IDENT:
427                 rc = seq_write_gcov_u32(seq, get_func(iter)->ident);
428                 break;
429         case RECORD_FUNCTION_CHECK:
430                 rc = seq_write_gcov_u32(seq, get_func(iter)->checksum);
431                 break;
432         case RECORD_COUNT_TAG:
433                 rc = seq_write_gcov_u32(seq,
434                         GCOV_TAG_FOR_COUNTER(get_type(iter)->ctr_type));
435                 break;
436         case RECORD_COUNT_LEN:
437                 rc = seq_write_gcov_u32(seq,
438                                 get_func(iter)->n_ctrs[iter->type] * 2);
439                 break;
440         case RECORD_COUNT:
441                 rc = seq_write_gcov_u64(seq,
442                         iter->info->counts[iter->type].
443                                 values[iter->count + get_type(iter)->offset]);
444                 break;
445         }
446         return rc;
447 }