gcc_3_4.c 14 KB

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