gcov-io.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. /* File format for coverage information
  2. Copyright (C) 1996-2015 Free Software Foundation, Inc.
  3. Contributed by Bob Manson <manson@cygnus.com>.
  4. Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
  5. This file is part of GCC.
  6. GCC is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU General Public License as published by the Free
  8. Software Foundation; either version 3, or (at your option) any later
  9. version.
  10. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. for more details.
  14. Under Section 7 of GPL version 3, you are granted additional
  15. permissions described in the GCC Runtime Library Exception, version
  16. 3.1, as published by the Free Software Foundation.
  17. You should have received a copy of the GNU General Public License and
  18. a copy of the GCC Runtime Library Exception along with this program;
  19. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  20. <http://www.gnu.org/licenses/>. */
  21. /* Routines declared in gcov-io.h. This file should be #included by
  22. another source file, after having #included gcov-io.h. */
  23. #if !IN_GCOV
  24. static void gcov_write_block (unsigned);
  25. static gcov_unsigned_t *gcov_write_words (unsigned);
  26. #endif
  27. static const gcov_unsigned_t *gcov_read_words (unsigned);
  28. #if !IN_LIBGCOV
  29. static void gcov_allocate (unsigned);
  30. #endif
  31. /* Optimum number of gcov_unsigned_t's read from or written to disk. */
  32. #define GCOV_BLOCK_SIZE (1 << 10)
  33. struct gcov_var
  34. {
  35. FILE *file;
  36. gcov_position_t start; /* Position of first byte of block */
  37. unsigned offset; /* Read/write position within the block. */
  38. unsigned length; /* Read limit in the block. */
  39. unsigned overread; /* Number of words overread. */
  40. int error; /* < 0 overflow, > 0 disk error. */
  41. int mode; /* < 0 writing, > 0 reading */
  42. #if IN_LIBGCOV
  43. /* Holds one block plus 4 bytes, thus all coverage reads & writes
  44. fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
  45. to and from the disk. libgcov never backtracks and only writes 4
  46. or 8 byte objects. */
  47. gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
  48. #else
  49. int endian; /* Swap endianness. */
  50. /* Holds a variable length block, as the compiler can write
  51. strings and needs to backtrack. */
  52. size_t alloc;
  53. gcov_unsigned_t *buffer;
  54. #endif
  55. } gcov_var;
  56. /* Save the current position in the gcov file. */
  57. /* We need to expose this function when compiling for gcov-tool. */
  58. #ifndef IN_GCOV_TOOL
  59. static inline
  60. #endif
  61. gcov_position_t
  62. gcov_position (void)
  63. {
  64. gcov_nonruntime_assert (gcov_var.mode > 0);
  65. return gcov_var.start + gcov_var.offset;
  66. }
  67. /* Return nonzero if the error flag is set. */
  68. /* We need to expose this function when compiling for gcov-tool. */
  69. #ifndef IN_GCOV_TOOL
  70. static inline
  71. #endif
  72. int
  73. gcov_is_error (void)
  74. {
  75. return gcov_var.file ? gcov_var.error : 1;
  76. }
  77. #if IN_LIBGCOV
  78. /* Move to beginning of file and initialize for writing. */
  79. GCOV_LINKAGE inline void
  80. gcov_rewrite (void)
  81. {
  82. gcov_var.mode = -1;
  83. gcov_var.start = 0;
  84. gcov_var.offset = 0;
  85. fseek (gcov_var.file, 0L, SEEK_SET);
  86. }
  87. #endif
  88. static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
  89. {
  90. #if !IN_LIBGCOV
  91. if (gcov_var.endian)
  92. {
  93. value = (value >> 16) | (value << 16);
  94. value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff);
  95. }
  96. #endif
  97. return value;
  98. }
  99. /* Open a gcov file. NAME is the name of the file to open and MODE
  100. indicates whether a new file should be created, or an existing file
  101. opened. If MODE is >= 0 an existing file will be opened, if
  102. possible, and if MODE is <= 0, a new file will be created. Use
  103. MODE=0 to attempt to reopen an existing file and then fall back on
  104. creating a new one. If MODE < 0, the file will be opened in
  105. read-only mode. Otherwise it will be opened for modification.
  106. Return zero on failure, >0 on opening an existing file and <0 on
  107. creating a new one. */
  108. GCOV_LINKAGE int
  109. #if IN_LIBGCOV
  110. gcov_open (const char *name)
  111. #else
  112. gcov_open (const char *name, int mode)
  113. #endif
  114. {
  115. #if IN_LIBGCOV
  116. const int mode = 0;
  117. #endif
  118. #if GCOV_LOCKED
  119. struct flock s_flock;
  120. int fd;
  121. s_flock.l_whence = SEEK_SET;
  122. s_flock.l_start = 0;
  123. s_flock.l_len = 0; /* Until EOF. */
  124. s_flock.l_pid = getpid ();
  125. #endif
  126. gcov_nonruntime_assert (!gcov_var.file);
  127. gcov_var.start = 0;
  128. gcov_var.offset = gcov_var.length = 0;
  129. gcov_var.overread = -1u;
  130. gcov_var.error = 0;
  131. #if !IN_LIBGCOV
  132. gcov_var.endian = 0;
  133. #endif
  134. #if GCOV_LOCKED
  135. if (mode > 0)
  136. {
  137. /* Read-only mode - acquire a read-lock. */
  138. s_flock.l_type = F_RDLCK;
  139. /* pass mode (ignored) for compatibility */
  140. fd = open (name, O_RDONLY, S_IRUSR | S_IWUSR);
  141. }
  142. else if (mode < 0)
  143. {
  144. /* Write mode - acquire a write-lock. */
  145. s_flock.l_type = F_WRLCK;
  146. fd = open (name, O_RDWR | O_CREAT | O_TRUNC, 0666);
  147. }
  148. else /* mode == 0 */
  149. {
  150. /* Read-Write mode - acquire a write-lock. */
  151. s_flock.l_type = F_WRLCK;
  152. fd = open (name, O_RDWR | O_CREAT, 0666);
  153. }
  154. if (fd < 0)
  155. return 0;
  156. while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR)
  157. continue;
  158. gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
  159. if (!gcov_var.file)
  160. {
  161. close (fd);
  162. return 0;
  163. }
  164. if (mode > 0)
  165. gcov_var.mode = 1;
  166. else if (mode == 0)
  167. {
  168. struct stat st;
  169. if (fstat (fd, &st) < 0)
  170. {
  171. fclose (gcov_var.file);
  172. gcov_var.file = 0;
  173. return 0;
  174. }
  175. if (st.st_size != 0)
  176. gcov_var.mode = 1;
  177. else
  178. gcov_var.mode = mode * 2 + 1;
  179. }
  180. else
  181. gcov_var.mode = mode * 2 + 1;
  182. #else
  183. if (mode >= 0)
  184. gcov_var.file = fopen (name, (mode > 0) ? "rb" : "r+b");
  185. if (gcov_var.file)
  186. gcov_var.mode = 1;
  187. else if (mode <= 0)
  188. {
  189. gcov_var.file = fopen (name, "w+b");
  190. if (gcov_var.file)
  191. gcov_var.mode = mode * 2 + 1;
  192. }
  193. if (!gcov_var.file)
  194. return 0;
  195. #endif
  196. setbuf (gcov_var.file, (char *)0);
  197. return 1;
  198. }
  199. /* Close the current gcov file. Flushes data to disk. Returns nonzero
  200. on failure or error flag set. */
  201. GCOV_LINKAGE int
  202. gcov_close (void)
  203. {
  204. if (gcov_var.file)
  205. {
  206. #if !IN_GCOV
  207. if (gcov_var.offset && gcov_var.mode < 0)
  208. gcov_write_block (gcov_var.offset);
  209. #endif
  210. fclose (gcov_var.file);
  211. gcov_var.file = 0;
  212. gcov_var.length = 0;
  213. }
  214. #if !IN_LIBGCOV
  215. free (gcov_var.buffer);
  216. gcov_var.alloc = 0;
  217. gcov_var.buffer = 0;
  218. #endif
  219. gcov_var.mode = 0;
  220. return gcov_var.error;
  221. }
  222. #if !IN_LIBGCOV
  223. /* Check if MAGIC is EXPECTED. Use it to determine endianness of the
  224. file. Returns +1 for same endian, -1 for other endian and zero for
  225. not EXPECTED. */
  226. GCOV_LINKAGE int
  227. gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected)
  228. {
  229. if (magic == expected)
  230. return 1;
  231. magic = (magic >> 16) | (magic << 16);
  232. magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff);
  233. if (magic == expected)
  234. {
  235. gcov_var.endian = 1;
  236. return -1;
  237. }
  238. return 0;
  239. }
  240. #endif
  241. #if !IN_LIBGCOV
  242. static void
  243. gcov_allocate (unsigned length)
  244. {
  245. size_t new_size = gcov_var.alloc;
  246. if (!new_size)
  247. new_size = GCOV_BLOCK_SIZE;
  248. new_size += length;
  249. new_size *= 2;
  250. gcov_var.alloc = new_size;
  251. gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2);
  252. }
  253. #endif
  254. #if !IN_GCOV
  255. /* Write out the current block, if needs be. */
  256. static void
  257. gcov_write_block (unsigned size)
  258. {
  259. if (fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1)
  260. gcov_var.error = 1;
  261. gcov_var.start += size;
  262. gcov_var.offset -= size;
  263. }
  264. /* Allocate space to write BYTES bytes to the gcov file. Return a
  265. pointer to those bytes, or NULL on failure. */
  266. static gcov_unsigned_t *
  267. gcov_write_words (unsigned words)
  268. {
  269. gcov_unsigned_t *result;
  270. gcov_nonruntime_assert (gcov_var.mode < 0);
  271. #if IN_LIBGCOV
  272. if (gcov_var.offset >= GCOV_BLOCK_SIZE)
  273. {
  274. gcov_write_block (GCOV_BLOCK_SIZE);
  275. if (gcov_var.offset)
  276. {
  277. memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
  278. }
  279. }
  280. #else
  281. if (gcov_var.offset + words > gcov_var.alloc)
  282. gcov_allocate (gcov_var.offset + words);
  283. #endif
  284. result = &gcov_var.buffer[gcov_var.offset];
  285. gcov_var.offset += words;
  286. return result;
  287. }
  288. /* Write unsigned VALUE to coverage file. Sets error flag
  289. appropriately. */
  290. GCOV_LINKAGE void
  291. gcov_write_unsigned (gcov_unsigned_t value)
  292. {
  293. gcov_unsigned_t *buffer = gcov_write_words (1);
  294. buffer[0] = value;
  295. }
  296. /* Write counter VALUE to coverage file. Sets error flag
  297. appropriately. */
  298. #if IN_LIBGCOV
  299. GCOV_LINKAGE void
  300. gcov_write_counter (gcov_type value)
  301. {
  302. gcov_unsigned_t *buffer = gcov_write_words (2);
  303. buffer[0] = (gcov_unsigned_t) value;
  304. if (sizeof (value) > sizeof (gcov_unsigned_t))
  305. buffer[1] = (gcov_unsigned_t) (value >> 32);
  306. else
  307. buffer[1] = 0;
  308. }
  309. #endif /* IN_LIBGCOV */
  310. #if !IN_LIBGCOV
  311. /* Write STRING to coverage file. Sets error flag on file
  312. error, overflow flag on overflow */
  313. GCOV_LINKAGE void
  314. gcov_write_string (const char *string)
  315. {
  316. unsigned length = 0;
  317. unsigned alloc = 0;
  318. gcov_unsigned_t *buffer;
  319. if (string)
  320. {
  321. length = strlen (string);
  322. alloc = (length + 4) >> 2;
  323. }
  324. buffer = gcov_write_words (1 + alloc);
  325. buffer[0] = alloc;
  326. buffer[alloc] = 0;
  327. memcpy (&buffer[1], string, length);
  328. }
  329. #endif
  330. #if !IN_LIBGCOV
  331. /* Write a tag TAG and reserve space for the record length. Return a
  332. value to be used for gcov_write_length. */
  333. GCOV_LINKAGE gcov_position_t
  334. gcov_write_tag (gcov_unsigned_t tag)
  335. {
  336. gcov_position_t result = gcov_var.start + gcov_var.offset;
  337. gcov_unsigned_t *buffer = gcov_write_words (2);
  338. buffer[0] = tag;
  339. buffer[1] = 0;
  340. return result;
  341. }
  342. /* Write a record length using POSITION, which was returned by
  343. gcov_write_tag. The current file position is the end of the
  344. record, and is restored before returning. Returns nonzero on
  345. overflow. */
  346. GCOV_LINKAGE void
  347. gcov_write_length (gcov_position_t position)
  348. {
  349. unsigned offset;
  350. gcov_unsigned_t length;
  351. gcov_unsigned_t *buffer;
  352. gcov_nonruntime_assert (gcov_var.mode < 0);
  353. gcov_nonruntime_assert (position + 2 <= gcov_var.start + gcov_var.offset);
  354. gcov_nonruntime_assert (position >= gcov_var.start);
  355. offset = position - gcov_var.start;
  356. length = gcov_var.offset - offset - 2;
  357. buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset];
  358. buffer[1] = length;
  359. if (gcov_var.offset >= GCOV_BLOCK_SIZE)
  360. gcov_write_block (gcov_var.offset);
  361. }
  362. #else /* IN_LIBGCOV */
  363. /* Write a tag TAG and length LENGTH. */
  364. GCOV_LINKAGE void
  365. gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
  366. {
  367. gcov_unsigned_t *buffer = gcov_write_words (2);
  368. buffer[0] = tag;
  369. buffer[1] = length;
  370. }
  371. /* Write a summary structure to the gcov file. Return nonzero on
  372. overflow. */
  373. GCOV_LINKAGE void
  374. gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
  375. {
  376. unsigned ix, h_ix, bv_ix, h_cnt = 0;
  377. const struct gcov_ctr_summary *csum;
  378. unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE];
  379. /* Count number of non-zero histogram entries, and fill in a bit vector
  380. of non-zero indices. The histogram is only currently computed for arc
  381. counters. */
  382. for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
  383. histo_bitvector[bv_ix] = 0;
  384. csum = &summary->ctrs[GCOV_COUNTER_ARCS];
  385. for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
  386. {
  387. if (csum->histogram[h_ix].num_counters > 0)
  388. {
  389. histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32);
  390. h_cnt++;
  391. }
  392. }
  393. gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt));
  394. gcov_write_unsigned (summary->checksum);
  395. for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
  396. {
  397. gcov_write_unsigned (csum->num);
  398. gcov_write_unsigned (csum->runs);
  399. gcov_write_counter (csum->sum_all);
  400. gcov_write_counter (csum->run_max);
  401. gcov_write_counter (csum->sum_max);
  402. if (ix != GCOV_COUNTER_ARCS)
  403. {
  404. for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
  405. gcov_write_unsigned (0);
  406. continue;
  407. }
  408. for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
  409. gcov_write_unsigned (histo_bitvector[bv_ix]);
  410. for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
  411. {
  412. if (!csum->histogram[h_ix].num_counters)
  413. continue;
  414. gcov_write_unsigned (csum->histogram[h_ix].num_counters);
  415. gcov_write_counter (csum->histogram[h_ix].min_value);
  416. gcov_write_counter (csum->histogram[h_ix].cum_value);
  417. }
  418. }
  419. }
  420. #endif /* IN_LIBGCOV */
  421. #endif /*!IN_GCOV */
  422. /* Return a pointer to read BYTES bytes from the gcov file. Returns
  423. NULL on failure (read past EOF). */
  424. static const gcov_unsigned_t *
  425. gcov_read_words (unsigned words)
  426. {
  427. const gcov_unsigned_t *result;
  428. unsigned excess = gcov_var.length - gcov_var.offset;
  429. gcov_nonruntime_assert (gcov_var.mode > 0);
  430. if (excess < words)
  431. {
  432. gcov_var.start += gcov_var.offset;
  433. if (excess)
  434. {
  435. #if IN_LIBGCOV
  436. memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4);
  437. #else
  438. memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset,
  439. excess * 4);
  440. #endif
  441. }
  442. gcov_var.offset = 0;
  443. gcov_var.length = excess;
  444. #if IN_LIBGCOV
  445. excess = GCOV_BLOCK_SIZE;
  446. #else
  447. if (gcov_var.length + words > gcov_var.alloc)
  448. gcov_allocate (gcov_var.length + words);
  449. excess = gcov_var.alloc - gcov_var.length;
  450. #endif
  451. excess = fread (gcov_var.buffer + gcov_var.length,
  452. 1, excess << 2, gcov_var.file) >> 2;
  453. gcov_var.length += excess;
  454. if (gcov_var.length < words)
  455. {
  456. gcov_var.overread += words - gcov_var.length;
  457. gcov_var.length = 0;
  458. return 0;
  459. }
  460. }
  461. result = &gcov_var.buffer[gcov_var.offset];
  462. gcov_var.offset += words;
  463. return result;
  464. }
  465. /* Read unsigned value from a coverage file. Sets error flag on file
  466. error, overflow flag on overflow */
  467. GCOV_LINKAGE gcov_unsigned_t
  468. gcov_read_unsigned (void)
  469. {
  470. gcov_unsigned_t value;
  471. const gcov_unsigned_t *buffer = gcov_read_words (1);
  472. if (!buffer)
  473. return 0;
  474. value = from_file (buffer[0]);
  475. return value;
  476. }
  477. /* Read counter value from a coverage file. Sets error flag on file
  478. error, overflow flag on overflow */
  479. GCOV_LINKAGE gcov_type
  480. gcov_read_counter (void)
  481. {
  482. gcov_type value;
  483. const gcov_unsigned_t *buffer = gcov_read_words (2);
  484. if (!buffer)
  485. return 0;
  486. value = from_file (buffer[0]);
  487. if (sizeof (value) > sizeof (gcov_unsigned_t))
  488. value |= ((gcov_type) from_file (buffer[1])) << 32;
  489. else if (buffer[1])
  490. gcov_var.error = -1;
  491. return value;
  492. }
  493. /* We need to expose the below function when compiling for gcov-tool. */
  494. #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
  495. /* Read string from coverage file. Returns a pointer to a static
  496. buffer, or NULL on empty string. You must copy the string before
  497. calling another gcov function. */
  498. GCOV_LINKAGE const char *
  499. gcov_read_string (void)
  500. {
  501. unsigned length = gcov_read_unsigned ();
  502. if (!length)
  503. return 0;
  504. return (const char *) gcov_read_words (length);
  505. }
  506. #endif
  507. GCOV_LINKAGE void
  508. gcov_read_summary (struct gcov_summary *summary)
  509. {
  510. unsigned ix, h_ix, bv_ix, h_cnt = 0;
  511. struct gcov_ctr_summary *csum;
  512. unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE];
  513. unsigned cur_bitvector;
  514. summary->checksum = gcov_read_unsigned ();
  515. for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
  516. {
  517. csum->num = gcov_read_unsigned ();
  518. csum->runs = gcov_read_unsigned ();
  519. csum->sum_all = gcov_read_counter ();
  520. csum->run_max = gcov_read_counter ();
  521. csum->sum_max = gcov_read_counter ();
  522. memset (csum->histogram, 0,
  523. sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
  524. for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
  525. {
  526. histo_bitvector[bv_ix] = gcov_read_unsigned ();
  527. #if IN_LIBGCOV
  528. /* When building libgcov we don't include system.h, which includes
  529. hwint.h (where popcount_hwi is declared). However, libgcov.a
  530. is built by the bootstrapped compiler and therefore the builtins
  531. are always available. */
  532. h_cnt += __builtin_popcount (histo_bitvector[bv_ix]);
  533. #else
  534. h_cnt += popcount_hwi (histo_bitvector[bv_ix]);
  535. #endif
  536. }
  537. bv_ix = 0;
  538. h_ix = 0;
  539. cur_bitvector = 0;
  540. while (h_cnt--)
  541. {
  542. /* Find the index corresponding to the next entry we will read in.
  543. First find the next non-zero bitvector and re-initialize
  544. the histogram index accordingly, then right shift and increment
  545. the index until we find a set bit. */
  546. while (!cur_bitvector)
  547. {
  548. h_ix = bv_ix * 32;
  549. if (bv_ix >= GCOV_HISTOGRAM_BITVECTOR_SIZE)
  550. gcov_error ("corrupted profile info: summary histogram "
  551. "bitvector is corrupt");
  552. cur_bitvector = histo_bitvector[bv_ix++];
  553. }
  554. while (!(cur_bitvector & 0x1))
  555. {
  556. h_ix++;
  557. cur_bitvector >>= 1;
  558. }
  559. if (h_ix >= GCOV_HISTOGRAM_SIZE)
  560. gcov_error ("corrupted profile info: summary histogram "
  561. "index is corrupt");
  562. csum->histogram[h_ix].num_counters = gcov_read_unsigned ();
  563. csum->histogram[h_ix].min_value = gcov_read_counter ();
  564. csum->histogram[h_ix].cum_value = gcov_read_counter ();
  565. /* Shift off the index we are done with and increment to the
  566. corresponding next histogram entry. */
  567. cur_bitvector >>= 1;
  568. h_ix++;
  569. }
  570. }
  571. }
  572. /* We need to expose the below function when compiling for gcov-tool. */
  573. #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
  574. /* Reset to a known position. BASE should have been obtained from
  575. gcov_position, LENGTH should be a record length. */
  576. GCOV_LINKAGE void
  577. gcov_sync (gcov_position_t base, gcov_unsigned_t length)
  578. {
  579. gcov_nonruntime_assert (gcov_var.mode > 0);
  580. base += length;
  581. if (base - gcov_var.start <= gcov_var.length)
  582. gcov_var.offset = base - gcov_var.start;
  583. else
  584. {
  585. gcov_var.offset = gcov_var.length = 0;
  586. fseek (gcov_var.file, base << 2, SEEK_SET);
  587. gcov_var.start = ftell (gcov_var.file) >> 2;
  588. }
  589. }
  590. #endif
  591. #if IN_LIBGCOV
  592. /* Move to a given position in a gcov file. */
  593. GCOV_LINKAGE void
  594. gcov_seek (gcov_position_t base)
  595. {
  596. if (gcov_var.offset)
  597. gcov_write_block (gcov_var.offset);
  598. fseek (gcov_var.file, base << 2, SEEK_SET);
  599. gcov_var.start = ftell (gcov_var.file) >> 2;
  600. }
  601. #endif
  602. #if IN_GCOV > 0
  603. /* Return the modification time of the current gcov file. */
  604. GCOV_LINKAGE time_t
  605. gcov_time (void)
  606. {
  607. struct stat status;
  608. if (fstat (fileno (gcov_var.file), &status))
  609. return 0;
  610. else
  611. return status.st_mtime;
  612. }
  613. #endif /* IN_GCOV */
  614. #if !IN_GCOV
  615. /* Determine the index into histogram for VALUE. */
  616. #if IN_LIBGCOV
  617. static unsigned
  618. #else
  619. GCOV_LINKAGE unsigned
  620. #endif
  621. gcov_histo_index (gcov_type value)
  622. {
  623. gcov_type_unsigned v = (gcov_type_unsigned)value;
  624. unsigned r = 0;
  625. unsigned prev2bits = 0;
  626. /* Find index into log2 scale histogram, where each of the log2
  627. sized buckets is divided into 4 linear sub-buckets for better
  628. focus in the higher buckets. */
  629. /* Find the place of the most-significant bit set. */
  630. if (v > 0)
  631. {
  632. #if IN_LIBGCOV
  633. /* When building libgcov we don't include system.h, which includes
  634. hwint.h (where floor_log2 is declared). However, libgcov.a
  635. is built by the bootstrapped compiler and therefore the builtins
  636. are always available. */
  637. r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v);
  638. #else
  639. /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT
  640. that is 64 bits and gcov_type_unsigned is 64 bits. */
  641. r = floor_log2 (v);
  642. #endif
  643. }
  644. /* If at most the 2 least significant bits are set (value is
  645. 0 - 3) then that value is our index into the lowest set of
  646. four buckets. */
  647. if (r < 2)
  648. return (unsigned)value;
  649. gcov_nonruntime_assert (r < 64);
  650. /* Find the two next most significant bits to determine which
  651. of the four linear sub-buckets to select. */
  652. prev2bits = (v >> (r - 2)) & 0x3;
  653. /* Finally, compose the final bucket index from the log2 index and
  654. the next 2 bits. The minimum r value at this point is 2 since we
  655. returned above if r was 2 or more, so the minimum bucket at this
  656. point is 4. */
  657. return (r - 1) * 4 + prev2bits;
  658. }
  659. /* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in
  660. the same relative order in both histograms, and are matched up
  661. and merged in reverse order. Each counter is assigned an equal portion of
  662. its entry's original cumulative counter value when computing the
  663. new merged cum_value. */
  664. static void gcov_histogram_merge (gcov_bucket_type *tgt_histo,
  665. gcov_bucket_type *src_histo)
  666. {
  667. int src_i, tgt_i, tmp_i = 0;
  668. unsigned src_num, tgt_num, merge_num;
  669. gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum;
  670. gcov_type merge_min;
  671. gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE];
  672. int src_done = 0;
  673. memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
  674. /* Assume that the counters are in the same relative order in both
  675. histograms. Walk the histograms from largest to smallest entry,
  676. matching up and combining counters in order. */
  677. src_num = 0;
  678. src_cum = 0;
  679. src_i = GCOV_HISTOGRAM_SIZE - 1;
  680. for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--)
  681. {
  682. tgt_num = tgt_histo[tgt_i].num_counters;
  683. tgt_cum = tgt_histo[tgt_i].cum_value;
  684. /* Keep going until all of the target histogram's counters at this
  685. position have been matched and merged with counters from the
  686. source histogram. */
  687. while (tgt_num > 0 && !src_done)
  688. {
  689. /* If this is either the first time through this loop or we just
  690. exhausted the previous non-zero source histogram entry, look
  691. for the next non-zero source histogram entry. */
  692. if (!src_num)
  693. {
  694. /* Locate the next non-zero entry. */
  695. while (src_i >= 0 && !src_histo[src_i].num_counters)
  696. src_i--;
  697. /* If source histogram has fewer counters, then just copy over the
  698. remaining target counters and quit. */
  699. if (src_i < 0)
  700. {
  701. tmp_histo[tgt_i].num_counters += tgt_num;
  702. tmp_histo[tgt_i].cum_value += tgt_cum;
  703. if (!tmp_histo[tgt_i].min_value ||
  704. tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value)
  705. tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value;
  706. while (--tgt_i >= 0)
  707. {
  708. tmp_histo[tgt_i].num_counters
  709. += tgt_histo[tgt_i].num_counters;
  710. tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value;
  711. if (!tmp_histo[tgt_i].min_value ||
  712. tgt_histo[tgt_i].min_value
  713. < tmp_histo[tgt_i].min_value)
  714. tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value;
  715. }
  716. src_done = 1;
  717. break;
  718. }
  719. src_num = src_histo[src_i].num_counters;
  720. src_cum = src_histo[src_i].cum_value;
  721. }
  722. /* The number of counters to merge on this pass is the minimum
  723. of the remaining counters from the current target and source
  724. histogram entries. */
  725. merge_num = tgt_num;
  726. if (src_num < merge_num)
  727. merge_num = src_num;
  728. /* The merged min_value is the sum of the min_values from target
  729. and source. */
  730. merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value;
  731. /* Compute the portion of source and target entries' cum_value
  732. that will be apportioned to the counters being merged.
  733. The total remaining cum_value from each entry is divided
  734. equally among the counters from that histogram entry if we
  735. are not merging all of them. */
  736. merge_src_cum = src_cum;
  737. if (merge_num < src_num)
  738. merge_src_cum = merge_num * src_cum / src_num;
  739. merge_tgt_cum = tgt_cum;
  740. if (merge_num < tgt_num)
  741. merge_tgt_cum = merge_num * tgt_cum / tgt_num;
  742. /* The merged cum_value is the sum of the source and target
  743. components. */
  744. merge_cum = merge_src_cum + merge_tgt_cum;
  745. /* Update the remaining number of counters and cum_value left
  746. to be merged from this source and target entry. */
  747. src_cum -= merge_src_cum;
  748. tgt_cum -= merge_tgt_cum;
  749. src_num -= merge_num;
  750. tgt_num -= merge_num;
  751. /* The merged counters get placed in the new merged histogram
  752. at the entry for the merged min_value. */
  753. tmp_i = gcov_histo_index (merge_min);
  754. gcov_nonruntime_assert (tmp_i < GCOV_HISTOGRAM_SIZE);
  755. tmp_histo[tmp_i].num_counters += merge_num;
  756. tmp_histo[tmp_i].cum_value += merge_cum;
  757. if (!tmp_histo[tmp_i].min_value ||
  758. merge_min < tmp_histo[tmp_i].min_value)
  759. tmp_histo[tmp_i].min_value = merge_min;
  760. /* Ensure the search for the next non-zero src_histo entry starts
  761. at the next smallest histogram bucket. */
  762. if (!src_num)
  763. src_i--;
  764. }
  765. }
  766. gcov_nonruntime_assert (tgt_i < 0);
  767. /* In the case where there were more counters in the source histogram,
  768. accumulate the remaining unmerged cumulative counter values. Add
  769. those to the smallest non-zero target histogram entry. Otherwise,
  770. the total cumulative counter values in the histogram will be smaller
  771. than the sum_all stored in the summary, which will complicate
  772. computing the working set information from the histogram later on. */
  773. if (src_num)
  774. src_i--;
  775. while (src_i >= 0)
  776. {
  777. src_cum += src_histo[src_i].cum_value;
  778. src_i--;
  779. }
  780. /* At this point, tmp_i should be the smallest non-zero entry in the
  781. tmp_histo. */
  782. gcov_nonruntime_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE
  783. && tmp_histo[tmp_i].num_counters > 0);
  784. tmp_histo[tmp_i].cum_value += src_cum;
  785. /* Finally, copy the merged histogram into tgt_histo. */
  786. memcpy (tgt_histo, tmp_histo,
  787. sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
  788. }
  789. #endif /* !IN_GCOV */
  790. /* This is used by gcov-dump (IN_GCOV == -1) and in the compiler
  791. (!IN_GCOV && !IN_LIBGCOV). */
  792. #if IN_GCOV <= 0 && !IN_LIBGCOV
  793. /* Compute the working set information from the counter histogram in
  794. the profile summary. This is an array of information corresponding to a
  795. range of percentages of the total execution count (sum_all), and includes
  796. the number of counters required to cover that working set percentage and
  797. the minimum counter value in that working set. */
  798. GCOV_LINKAGE void
  799. compute_working_sets (const struct gcov_ctr_summary *summary,
  800. gcov_working_set_t *gcov_working_sets)
  801. {
  802. gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS];
  803. gcov_type ws_cum_hotness_incr;
  804. gcov_type cum, tmp_cum;
  805. const gcov_bucket_type *histo_bucket;
  806. unsigned ws_ix, c_num, count;
  807. int h_ix;
  808. /* Compute the amount of sum_all that the cumulative hotness grows
  809. by in each successive working set entry, which depends on the
  810. number of working set entries. */
  811. ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS;
  812. /* Next fill in an array of the cumulative hotness values corresponding
  813. to each working set summary entry we are going to compute below.
  814. Skip 0% statistics, which can be extrapolated from the
  815. rest of the summary data. */
  816. cum = ws_cum_hotness_incr;
  817. for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS;
  818. ws_ix++, cum += ws_cum_hotness_incr)
  819. working_set_cum_values[ws_ix] = cum;
  820. /* The last summary entry is reserved for (roughly) 99.9% of the
  821. working set. Divide by 1024 so it becomes a shift, which gives
  822. almost exactly 99.9%. */
  823. working_set_cum_values[NUM_GCOV_WORKING_SETS-1]
  824. = summary->sum_all - summary->sum_all/1024;
  825. /* Next, walk through the histogram in decending order of hotness
  826. and compute the statistics for the working set summary array.
  827. As histogram entries are accumulated, we check to see which
  828. working set entries have had their expected cum_value reached
  829. and fill them in, walking the working set entries in increasing
  830. size of cum_value. */
  831. ws_ix = 0; /* The current entry into the working set array. */
  832. cum = 0; /* The current accumulated counter sum. */
  833. count = 0; /* The current accumulated count of block counters. */
  834. for (h_ix = GCOV_HISTOGRAM_SIZE - 1;
  835. h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--)
  836. {
  837. histo_bucket = &summary->histogram[h_ix];
  838. /* If we haven't reached the required cumulative counter value for
  839. the current working set percentage, simply accumulate this histogram
  840. entry into the running sums and continue to the next histogram
  841. entry. */
  842. if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix])
  843. {
  844. cum += histo_bucket->cum_value;
  845. count += histo_bucket->num_counters;
  846. continue;
  847. }
  848. /* If adding the current histogram entry's cumulative counter value
  849. causes us to exceed the current working set size, then estimate
  850. how many of this histogram entry's counter values are required to
  851. reach the working set size, and fill in working set entries
  852. as we reach their expected cumulative value. */
  853. for (c_num = 0, tmp_cum = cum;
  854. c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS;
  855. c_num++)
  856. {
  857. count++;
  858. /* If we haven't reached the last histogram entry counter, add
  859. in the minimum value again. This will underestimate the
  860. cumulative sum so far, because many of the counter values in this
  861. entry may have been larger than the minimum. We could add in the
  862. average value every time, but that would require an expensive
  863. divide operation. */
  864. if (c_num + 1 < histo_bucket->num_counters)
  865. tmp_cum += histo_bucket->min_value;
  866. /* If we have reached the last histogram entry counter, then add
  867. in the entire cumulative value. */
  868. else
  869. tmp_cum = cum + histo_bucket->cum_value;
  870. /* Next walk through successive working set entries and fill in
  871. the statistics for any whose size we have reached by accumulating
  872. this histogram counter. */
  873. while (ws_ix < NUM_GCOV_WORKING_SETS
  874. && tmp_cum >= working_set_cum_values[ws_ix])
  875. {
  876. gcov_working_sets[ws_ix].num_counters = count;
  877. gcov_working_sets[ws_ix].min_counter
  878. = histo_bucket->min_value;
  879. ws_ix++;
  880. }
  881. }
  882. /* Finally, update the running cumulative value since we were
  883. using a temporary above. */
  884. cum += histo_bucket->cum_value;
  885. }
  886. gcov_nonruntime_assert (ws_ix == NUM_GCOV_WORKING_SETS);
  887. }
  888. #endif /* IN_GCOV <= 0 && !IN_LIBGCOV */