gcc_3_4.c 11 KB

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