root/kernel/gcov/clang.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. llvm_gcov_init
  2. llvm_gcda_start_file
  3. llvm_gcda_emit_function
  4. llvm_gcda_emit_arcs
  5. llvm_gcda_summary_info
  6. llvm_gcda_end_file
  7. gcov_info_filename
  8. gcov_info_version
  9. gcov_info_next
  10. gcov_info_link
  11. gcov_info_unlink
  12. gcov_info_within_module
  13. gcov_info_reset
  14. gcov_info_is_compatible
  15. gcov_info_add
  16. gcov_fn_info_dup
  17. gcov_info_dup
  18. gcov_info_free
  19. store_gcov_u32
  20. store_gcov_u64
  21. convert_to_gcda
  22. gcov_iter_new
  23. gcov_iter_free
  24. gcov_iter_get_info
  25. gcov_iter_start
  26. gcov_iter_next
  27. gcov_iter_write

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2019 Google, Inc.
   4  * modified from kernel/gcov/gcc_4_7.c
   5  *
   6  * This software is licensed under the terms of the GNU General Public
   7  * License version 2, as published by the Free Software Foundation, and
   8  * may be copied, distributed, and modified under those terms.
   9  *
  10  * This program is distributed in the hope that it will be useful,
  11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  * GNU General Public License for more details.
  14  *
  15  *
  16  * LLVM uses profiling data that's deliberately similar to GCC, but has a
  17  * very different way of exporting that data.  LLVM calls llvm_gcov_init() once
  18  * per module, and provides a couple of callbacks that we can use to ask for
  19  * more data.
  20  *
  21  * We care about the "writeout" callback, which in turn calls back into
  22  * compiler-rt/this module to dump all the gathered coverage data to disk:
  23  *
  24  *    llvm_gcda_start_file()
  25  *      llvm_gcda_emit_function()
  26  *      llvm_gcda_emit_arcs()
  27  *      llvm_gcda_emit_function()
  28  *      llvm_gcda_emit_arcs()
  29  *      [... repeats for each function ...]
  30  *    llvm_gcda_summary_info()
  31  *    llvm_gcda_end_file()
  32  *
  33  * This design is much more stateless and unstructured than gcc's, and is
  34  * intended to run at process exit.  This forces us to keep some local state
  35  * about which module we're dealing with at the moment.  On the other hand, it
  36  * also means we don't depend as much on how LLVM represents profiling data
  37  * internally.
  38  *
  39  * See LLVM's lib/Transforms/Instrumentation/GCOVProfiling.cpp for more
  40  * details on how this works, particularly GCOVProfiler::emitProfileArcs(),
  41  * GCOVProfiler::insertCounterWriteout(), and
  42  * GCOVProfiler::insertFlush().
  43  */
  44 
  45 #define pr_fmt(fmt)     "gcov: " fmt
  46 
  47 #include <linux/kernel.h>
  48 #include <linux/list.h>
  49 #include <linux/printk.h>
  50 #include <linux/ratelimit.h>
  51 #include <linux/seq_file.h>
  52 #include <linux/slab.h>
  53 #include <linux/vmalloc.h>
  54 #include "gcov.h"
  55 
  56 typedef void (*llvm_gcov_callback)(void);
  57 
  58 struct gcov_info {
  59         struct list_head head;
  60 
  61         const char *filename;
  62         unsigned int version;
  63         u32 checksum;
  64 
  65         struct list_head functions;
  66 };
  67 
  68 struct gcov_fn_info {
  69         struct list_head head;
  70 
  71         u32 ident;
  72         u32 checksum;
  73         u8 use_extra_checksum;
  74         u32 cfg_checksum;
  75 
  76         u32 num_counters;
  77         u64 *counters;
  78         const char *function_name;
  79 };
  80 
  81 static struct gcov_info *current_info;
  82 
  83 static LIST_HEAD(clang_gcov_list);
  84 
  85 void llvm_gcov_init(llvm_gcov_callback writeout, llvm_gcov_callback flush)
  86 {
  87         struct gcov_info *info = kzalloc(sizeof(*info), GFP_KERNEL);
  88 
  89         if (!info)
  90                 return;
  91 
  92         INIT_LIST_HEAD(&info->head);
  93         INIT_LIST_HEAD(&info->functions);
  94 
  95         mutex_lock(&gcov_lock);
  96 
  97         list_add_tail(&info->head, &clang_gcov_list);
  98         current_info = info;
  99         writeout();
 100         current_info = NULL;
 101         if (gcov_events_enabled)
 102                 gcov_event(GCOV_ADD, info);
 103 
 104         mutex_unlock(&gcov_lock);
 105 }
 106 EXPORT_SYMBOL(llvm_gcov_init);
 107 
 108 void llvm_gcda_start_file(const char *orig_filename, const char version[4],
 109                 u32 checksum)
 110 {
 111         current_info->filename = orig_filename;
 112         memcpy(&current_info->version, version, sizeof(current_info->version));
 113         current_info->checksum = checksum;
 114 }
 115 EXPORT_SYMBOL(llvm_gcda_start_file);
 116 
 117 void llvm_gcda_emit_function(u32 ident, const char *function_name,
 118                 u32 func_checksum, u8 use_extra_checksum, u32 cfg_checksum)
 119 {
 120         struct gcov_fn_info *info = kzalloc(sizeof(*info), GFP_KERNEL);
 121 
 122         if (!info)
 123                 return;
 124 
 125         INIT_LIST_HEAD(&info->head);
 126         info->ident = ident;
 127         info->checksum = func_checksum;
 128         info->use_extra_checksum = use_extra_checksum;
 129         info->cfg_checksum = cfg_checksum;
 130         if (function_name)
 131                 info->function_name = kstrdup(function_name, GFP_KERNEL);
 132 
 133         list_add_tail(&info->head, &current_info->functions);
 134 }
 135 EXPORT_SYMBOL(llvm_gcda_emit_function);
 136 
 137 void llvm_gcda_emit_arcs(u32 num_counters, u64 *counters)
 138 {
 139         struct gcov_fn_info *info = list_last_entry(&current_info->functions,
 140                         struct gcov_fn_info, head);
 141 
 142         info->num_counters = num_counters;
 143         info->counters = counters;
 144 }
 145 EXPORT_SYMBOL(llvm_gcda_emit_arcs);
 146 
 147 void llvm_gcda_summary_info(void)
 148 {
 149 }
 150 EXPORT_SYMBOL(llvm_gcda_summary_info);
 151 
 152 void llvm_gcda_end_file(void)
 153 {
 154 }
 155 EXPORT_SYMBOL(llvm_gcda_end_file);
 156 
 157 /**
 158  * gcov_info_filename - return info filename
 159  * @info: profiling data set
 160  */
 161 const char *gcov_info_filename(struct gcov_info *info)
 162 {
 163         return info->filename;
 164 }
 165 
 166 /**
 167  * gcov_info_version - return info version
 168  * @info: profiling data set
 169  */
 170 unsigned int gcov_info_version(struct gcov_info *info)
 171 {
 172         return info->version;
 173 }
 174 
 175 /**
 176  * gcov_info_next - return next profiling data set
 177  * @info: profiling data set
 178  *
 179  * Returns next gcov_info following @info or first gcov_info in the chain if
 180  * @info is %NULL.
 181  */
 182 struct gcov_info *gcov_info_next(struct gcov_info *info)
 183 {
 184         if (!info)
 185                 return list_first_entry_or_null(&clang_gcov_list,
 186                                 struct gcov_info, head);
 187         if (list_is_last(&info->head, &clang_gcov_list))
 188                 return NULL;
 189         return list_next_entry(info, head);
 190 }
 191 
 192 /**
 193  * gcov_info_link - link/add profiling data set to the list
 194  * @info: profiling data set
 195  */
 196 void gcov_info_link(struct gcov_info *info)
 197 {
 198         list_add_tail(&info->head, &clang_gcov_list);
 199 }
 200 
 201 /**
 202  * gcov_info_unlink - unlink/remove profiling data set from the list
 203  * @prev: previous profiling data set
 204  * @info: profiling data set
 205  */
 206 void gcov_info_unlink(struct gcov_info *prev, struct gcov_info *info)
 207 {
 208         /* Generic code unlinks while iterating. */
 209         __list_del_entry(&info->head);
 210 }
 211 
 212 /**
 213  * gcov_info_within_module - check if a profiling data set belongs to a module
 214  * @info: profiling data set
 215  * @mod: module
 216  *
 217  * Returns true if profiling data belongs module, false otherwise.
 218  */
 219 bool gcov_info_within_module(struct gcov_info *info, struct module *mod)
 220 {
 221         return within_module((unsigned long)info->filename, mod);
 222 }
 223 
 224 /* Symbolic links to be created for each profiling data file. */
 225 const struct gcov_link gcov_link[] = {
 226         { OBJ_TREE, "gcno" },   /* Link to .gcno file in $(objtree). */
 227         { 0, NULL},
 228 };
 229 
 230 /**
 231  * gcov_info_reset - reset profiling data to zero
 232  * @info: profiling data set
 233  */
 234 void gcov_info_reset(struct gcov_info *info)
 235 {
 236         struct gcov_fn_info *fn;
 237 
 238         list_for_each_entry(fn, &info->functions, head)
 239                 memset(fn->counters, 0,
 240                                 sizeof(fn->counters[0]) * fn->num_counters);
 241 }
 242 
 243 /**
 244  * gcov_info_is_compatible - check if profiling data can be added
 245  * @info1: first profiling data set
 246  * @info2: second profiling data set
 247  *
 248  * Returns non-zero if profiling data can be added, zero otherwise.
 249  */
 250 int gcov_info_is_compatible(struct gcov_info *info1, struct gcov_info *info2)
 251 {
 252         struct gcov_fn_info *fn_ptr1 = list_first_entry_or_null(
 253                         &info1->functions, struct gcov_fn_info, head);
 254         struct gcov_fn_info *fn_ptr2 = list_first_entry_or_null(
 255                         &info2->functions, struct gcov_fn_info, head);
 256 
 257         if (info1->checksum != info2->checksum)
 258                 return false;
 259         if (!fn_ptr1)
 260                 return fn_ptr1 == fn_ptr2;
 261         while (!list_is_last(&fn_ptr1->head, &info1->functions) &&
 262                 !list_is_last(&fn_ptr2->head, &info2->functions)) {
 263                 if (fn_ptr1->checksum != fn_ptr2->checksum)
 264                         return false;
 265                 if (fn_ptr1->use_extra_checksum != fn_ptr2->use_extra_checksum)
 266                         return false;
 267                 if (fn_ptr1->use_extra_checksum &&
 268                         fn_ptr1->cfg_checksum != fn_ptr2->cfg_checksum)
 269                         return false;
 270                 fn_ptr1 = list_next_entry(fn_ptr1, head);
 271                 fn_ptr2 = list_next_entry(fn_ptr2, head);
 272         }
 273         return list_is_last(&fn_ptr1->head, &info1->functions) &&
 274                 list_is_last(&fn_ptr2->head, &info2->functions);
 275 }
 276 
 277 /**
 278  * gcov_info_add - add up profiling data
 279  * @dest: profiling data set to which data is added
 280  * @source: profiling data set which is added
 281  *
 282  * Adds profiling counts of @source to @dest.
 283  */
 284 void gcov_info_add(struct gcov_info *dst, struct gcov_info *src)
 285 {
 286         struct gcov_fn_info *dfn_ptr;
 287         struct gcov_fn_info *sfn_ptr = list_first_entry_or_null(&src->functions,
 288                         struct gcov_fn_info, head);
 289 
 290         list_for_each_entry(dfn_ptr, &dst->functions, head) {
 291                 u32 i;
 292 
 293                 for (i = 0; i < sfn_ptr->num_counters; i++)
 294                         dfn_ptr->counters[i] += sfn_ptr->counters[i];
 295         }
 296 }
 297 
 298 static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn)
 299 {
 300         size_t cv_size; /* counter values size */
 301         struct gcov_fn_info *fn_dup = kmemdup(fn, sizeof(*fn),
 302                         GFP_KERNEL);
 303         if (!fn_dup)
 304                 return NULL;
 305         INIT_LIST_HEAD(&fn_dup->head);
 306 
 307         fn_dup->function_name = kstrdup(fn->function_name, GFP_KERNEL);
 308         if (!fn_dup->function_name)
 309                 goto err_name;
 310 
 311         cv_size = fn->num_counters * sizeof(fn->counters[0]);
 312         fn_dup->counters = vmalloc(cv_size);
 313         if (!fn_dup->counters)
 314                 goto err_counters;
 315         memcpy(fn_dup->counters, fn->counters, cv_size);
 316 
 317         return fn_dup;
 318 
 319 err_counters:
 320         kfree(fn_dup->function_name);
 321 err_name:
 322         kfree(fn_dup);
 323         return NULL;
 324 }
 325 
 326 /**
 327  * gcov_info_dup - duplicate profiling data set
 328  * @info: profiling data set to duplicate
 329  *
 330  * Return newly allocated duplicate on success, %NULL on error.
 331  */
 332 struct gcov_info *gcov_info_dup(struct gcov_info *info)
 333 {
 334         struct gcov_info *dup;
 335         struct gcov_fn_info *fn;
 336 
 337         dup = kmemdup(info, sizeof(*dup), GFP_KERNEL);
 338         if (!dup)
 339                 return NULL;
 340         INIT_LIST_HEAD(&dup->head);
 341         INIT_LIST_HEAD(&dup->functions);
 342         dup->filename = kstrdup(info->filename, GFP_KERNEL);
 343         if (!dup->filename)
 344                 goto err;
 345 
 346         list_for_each_entry(fn, &info->functions, head) {
 347                 struct gcov_fn_info *fn_dup = gcov_fn_info_dup(fn);
 348 
 349                 if (!fn_dup)
 350                         goto err;
 351                 list_add_tail(&fn_dup->head, &dup->functions);
 352         }
 353 
 354         return dup;
 355 
 356 err:
 357         gcov_info_free(dup);
 358         return NULL;
 359 }
 360 
 361 /**
 362  * gcov_info_free - release memory for profiling data set duplicate
 363  * @info: profiling data set duplicate to free
 364  */
 365 void gcov_info_free(struct gcov_info *info)
 366 {
 367         struct gcov_fn_info *fn, *tmp;
 368 
 369         list_for_each_entry_safe(fn, tmp, &info->functions, head) {
 370                 kfree(fn->function_name);
 371                 vfree(fn->counters);
 372                 list_del(&fn->head);
 373                 kfree(fn);
 374         }
 375         kfree(info->filename);
 376         kfree(info);
 377 }
 378 
 379 #define ITER_STRIDE     PAGE_SIZE
 380 
 381 /**
 382  * struct gcov_iterator - specifies current file position in logical records
 383  * @info: associated profiling data
 384  * @buffer: buffer containing file data
 385  * @size: size of buffer
 386  * @pos: current position in file
 387  */
 388 struct gcov_iterator {
 389         struct gcov_info *info;
 390         void *buffer;
 391         size_t size;
 392         loff_t pos;
 393 };
 394 
 395 /**
 396  * store_gcov_u32 - store 32 bit number in gcov format to buffer
 397  * @buffer: target buffer or NULL
 398  * @off: offset into the buffer
 399  * @v: value to be stored
 400  *
 401  * Number format defined by gcc: numbers are recorded in the 32 bit
 402  * unsigned binary form of the endianness of the machine generating the
 403  * file. Returns the number of bytes stored. If @buffer is %NULL, doesn't
 404  * store anything.
 405  */
 406 static size_t store_gcov_u32(void *buffer, size_t off, u32 v)
 407 {
 408         u32 *data;
 409 
 410         if (buffer) {
 411                 data = buffer + off;
 412                 *data = v;
 413         }
 414 
 415         return sizeof(*data);
 416 }
 417 
 418 /**
 419  * store_gcov_u64 - store 64 bit number in gcov format to buffer
 420  * @buffer: target buffer or NULL
 421  * @off: offset into the buffer
 422  * @v: value to be stored
 423  *
 424  * Number format defined by gcc: numbers are recorded in the 32 bit
 425  * unsigned binary form of the endianness of the machine generating the
 426  * file. 64 bit numbers are stored as two 32 bit numbers, the low part
 427  * first. Returns the number of bytes stored. If @buffer is %NULL, doesn't store
 428  * anything.
 429  */
 430 static size_t store_gcov_u64(void *buffer, size_t off, u64 v)
 431 {
 432         u32 *data;
 433 
 434         if (buffer) {
 435                 data = buffer + off;
 436 
 437                 data[0] = (v & 0xffffffffUL);
 438                 data[1] = (v >> 32);
 439         }
 440 
 441         return sizeof(*data) * 2;
 442 }
 443 
 444 /**
 445  * convert_to_gcda - convert profiling data set to gcda file format
 446  * @buffer: the buffer to store file data or %NULL if no data should be stored
 447  * @info: profiling data set to be converted
 448  *
 449  * Returns the number of bytes that were/would have been stored into the buffer.
 450  */
 451 static size_t convert_to_gcda(char *buffer, struct gcov_info *info)
 452 {
 453         struct gcov_fn_info *fi_ptr;
 454         size_t pos = 0;
 455 
 456         /* File header. */
 457         pos += store_gcov_u32(buffer, pos, GCOV_DATA_MAGIC);
 458         pos += store_gcov_u32(buffer, pos, info->version);
 459         pos += store_gcov_u32(buffer, pos, info->checksum);
 460 
 461         list_for_each_entry(fi_ptr, &info->functions, head) {
 462                 u32 i;
 463                 u32 len = 2;
 464 
 465                 if (fi_ptr->use_extra_checksum)
 466                         len++;
 467 
 468                 pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION);
 469                 pos += store_gcov_u32(buffer, pos, len);
 470                 pos += store_gcov_u32(buffer, pos, fi_ptr->ident);
 471                 pos += store_gcov_u32(buffer, pos, fi_ptr->checksum);
 472                 if (fi_ptr->use_extra_checksum)
 473                         pos += store_gcov_u32(buffer, pos, fi_ptr->cfg_checksum);
 474 
 475                 pos += store_gcov_u32(buffer, pos, GCOV_TAG_COUNTER_BASE);
 476                 pos += store_gcov_u32(buffer, pos, fi_ptr->num_counters * 2);
 477                 for (i = 0; i < fi_ptr->num_counters; i++)
 478                         pos += store_gcov_u64(buffer, pos, fi_ptr->counters[i]);
 479         }
 480 
 481         return pos;
 482 }
 483 
 484 /**
 485  * gcov_iter_new - allocate and initialize profiling data iterator
 486  * @info: profiling data set to be iterated
 487  *
 488  * Return file iterator on success, %NULL otherwise.
 489  */
 490 struct gcov_iterator *gcov_iter_new(struct gcov_info *info)
 491 {
 492         struct gcov_iterator *iter;
 493 
 494         iter = kzalloc(sizeof(struct gcov_iterator), GFP_KERNEL);
 495         if (!iter)
 496                 goto err_free;
 497 
 498         iter->info = info;
 499         /* Dry-run to get the actual buffer size. */
 500         iter->size = convert_to_gcda(NULL, info);
 501         iter->buffer = vmalloc(iter->size);
 502         if (!iter->buffer)
 503                 goto err_free;
 504 
 505         convert_to_gcda(iter->buffer, info);
 506 
 507         return iter;
 508 
 509 err_free:
 510         kfree(iter);
 511         return NULL;
 512 }
 513 
 514 
 515 /**
 516  * gcov_iter_get_info - return profiling data set for given file iterator
 517  * @iter: file iterator
 518  */
 519 void gcov_iter_free(struct gcov_iterator *iter)
 520 {
 521         vfree(iter->buffer);
 522         kfree(iter);
 523 }
 524 
 525 /**
 526  * gcov_iter_get_info - return profiling data set for given file iterator
 527  * @iter: file iterator
 528  */
 529 struct gcov_info *gcov_iter_get_info(struct gcov_iterator *iter)
 530 {
 531         return iter->info;
 532 }
 533 
 534 /**
 535  * gcov_iter_start - reset file iterator to starting position
 536  * @iter: file iterator
 537  */
 538 void gcov_iter_start(struct gcov_iterator *iter)
 539 {
 540         iter->pos = 0;
 541 }
 542 
 543 /**
 544  * gcov_iter_next - advance file iterator to next logical record
 545  * @iter: file iterator
 546  *
 547  * Return zero if new position is valid, non-zero if iterator has reached end.
 548  */
 549 int gcov_iter_next(struct gcov_iterator *iter)
 550 {
 551         if (iter->pos < iter->size)
 552                 iter->pos += ITER_STRIDE;
 553 
 554         if (iter->pos >= iter->size)
 555                 return -EINVAL;
 556 
 557         return 0;
 558 }
 559 
 560 /**
 561  * gcov_iter_write - write data for current pos to seq_file
 562  * @iter: file iterator
 563  * @seq: seq_file handle
 564  *
 565  * Return zero on success, non-zero otherwise.
 566  */
 567 int gcov_iter_write(struct gcov_iterator *iter, struct seq_file *seq)
 568 {
 569         size_t len;
 570 
 571         if (iter->pos >= iter->size)
 572                 return -EINVAL;
 573 
 574         len = ITER_STRIDE;
 575         if (iter->pos + len > iter->size)
 576                 len = iter->size - iter->pos;
 577 
 578         seq_write(seq, iter->buffer + iter->pos, len);
 579 
 580         return 0;
 581 }

/* [<][>][^][v][top][bottom][index][help] */